summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@nokia.com>2009-11-19 09:58:03 +0100
committerPaul Olav Tvete <paul.tvete@nokia.com>2009-11-19 09:58:03 +0100
commit879e2ea7d15510ec5f94d6d7a005b157b115f69f (patch)
tree73aedd0bffe7ab39387229a9417aa50cecbbf0aa /src/gui
parent8fc2eec5b3282665f76f1e0313a03608bf4e7bc1 (diff)
parent80cd617b05ad3e647c87dc063d40cde0617344ca (diff)
Merge remote branch 'origin/4.6' into lighthouse
Conflicts: configure src/plugins/graphicssystems/graphicssystems.pro
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp10
-rw-r--r--src/gui/accessible/qaccessible.h12
-rw-r--r--src/gui/accessible/qaccessible2.cpp24
-rw-r--r--src/gui/accessible/qaccessible2.h29
-rw-r--r--src/gui/accessible/qaccessible_mac.mm5
-rw-r--r--src/gui/animation/qguivariantanimation.cpp8
-rw-r--r--src/gui/dialogs/qcolordialog_mac.mm30
-rw-r--r--src/gui/dialogs/qerrormessage.cpp13
-rw-r--r--src/gui/dialogs/qfiledialog.cpp57
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm16
-rw-r--r--src/gui/dialogs/qfiledialog_p.h4
-rw-r--r--src/gui/dialogs/qfiledialog_win.cpp6
-rw-r--r--src/gui/dialogs/qfscompleter_p.h4
-rw-r--r--src/gui/dialogs/qprintdialog_mac.mm4
-rw-r--r--src/gui/dialogs/qprintdialog_unix.cpp11
-rw-r--r--src/gui/dialogs/qprintdialog_win.cpp2
-rw-r--r--src/gui/dialogs/qprintpreviewdialog.cpp6
-rw-r--r--src/gui/dialogs/qprogressdialog.cpp2
-rw-r--r--src/gui/dialogs/qwizard.cpp4
-rw-r--r--src/gui/dialogs/qwizard_win.cpp2
-rw-r--r--src/gui/effects/qgraphicseffect.cpp879
-rw-r--r--src/gui/effects/qgraphicseffect.h183
-rw-r--r--src/gui/effects/qgraphicseffect_p.h97
-rw-r--r--src/gui/egl/egl.pri12
-rw-r--r--src/gui/egl/qegl.cpp7
-rw-r--r--src/gui/egl/qegl_p.h5
-rw-r--r--src/gui/egl/qegl_qws.cpp3
-rw-r--r--src/gui/egl/qeglproperties.cpp4
-rw-r--r--src/gui/embedded/directfb.pri2
-rw-r--r--src/gui/embedded/qdecorationdefault_qws.cpp2
-rw-r--r--src/gui/embedded/qdecorationwindows_qws.cpp2
-rw-r--r--src/gui/embedded/qscreen_qws.cpp18
-rw-r--r--src/gui/embedded/qscreen_qws.h3
-rw-r--r--src/gui/embedded/qwscursor_qws.cpp2
-rw-r--r--src/gui/graphicsview/qgraph_p.h16
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp216
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.h4
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp2166
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h309
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.cpp30
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp282
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h12
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h102
-rw-r--r--src/gui/graphicsview/qgraphicslayout_p.h51
-rw-r--r--src/gui/graphicsview/qgraphicslinearlayout.cpp17
-rw-r--r--src/gui/graphicsview/qgraphicslinearlayout.h2
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.cpp15
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp465
-rw-r--r--src/gui/graphicsview/qgraphicsscene.h1
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h19
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp68
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicstransform.cpp8
-rw-r--r--src/gui/graphicsview/qgraphicstransform.h2
-rw-r--r--src/gui/graphicsview/qgraphicstransform_p.h3
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp56
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp29
-rw-r--r--src/gui/graphicsview/qgraphicswidget.h4
-rw-r--r--src/gui/graphicsview/qgridlayoutengine_p.h25
-rw-r--r--src/gui/graphicsview/qsimplex_p.cpp113
-rw-r--r--src/gui/graphicsview/qsimplex_p.h38
-rw-r--r--src/gui/image/qbitmap.cpp2
-rw-r--r--src/gui/image/qbmphandler.cpp22
-rw-r--r--src/gui/image/qicon.cpp2
-rw-r--r--src/gui/image/qicon_p.h3
-rw-r--r--src/gui/image/qiconloader.cpp16
-rw-r--r--src/gui/image/qiconloader_p.h3
-rw-r--r--src/gui/image/qimage.cpp163
-rw-r--r--src/gui/image/qimage.h9
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks.cpp54
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks_p.h21
-rw-r--r--src/gui/image/qnativeimage.cpp10
-rw-r--r--src/gui/image/qpixmap.cpp129
-rw-r--r--src/gui/image/qpixmap.h3
-rw-r--r--src/gui/image/qpixmap_mac.cpp34
-rw-r--r--src/gui/image/qpixmap_mac_p.h2
-rw-r--r--src/gui/image/qpixmap_qws.cpp15
-rw-r--r--src/gui/image/qpixmap_raster.cpp30
-rw-r--r--src/gui/image/qpixmap_raster_p.h2
-rw-r--r--src/gui/image/qpixmap_s60.cpp92
-rw-r--r--src/gui/image/qpixmap_s60_p.h2
-rw-r--r--src/gui/image/qpixmap_win.cpp3
-rw-r--r--src/gui/image/qpixmap_x11.cpp43
-rw-r--r--src/gui/image/qpixmap_x11_p.h3
-rw-r--r--src/gui/image/qpixmapcache.cpp1
-rw-r--r--src/gui/image/qpixmapdata.cpp28
-rw-r--r--src/gui/image/qpixmapdata_p.h12
-rw-r--r--src/gui/image/qpixmapfilter.cpp116
-rw-r--r--src/gui/image/qpixmapfilter_p.h15
-rw-r--r--src/gui/image/qpnghandler.cpp12
-rw-r--r--src/gui/image/qppmhandler.cpp6
-rw-r--r--src/gui/image/qxbmhandler.cpp2
-rw-r--r--src/gui/image/qxpmhandler.cpp2
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h17
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp137
-rw-r--r--src/gui/inputmethod/qinputcontext.cpp14
-rw-r--r--src/gui/inputmethod/qinputcontext.h13
-rw-r--r--src/gui/inputmethod/qmacinputcontext_mac.cpp6
-rw-r--r--src/gui/inputmethod/qwininputcontext_win.cpp25
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp10
-rw-r--r--src/gui/itemviews/qabstractitemview.h3
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h4
-rw-r--r--src/gui/itemviews/qdirmodel.cpp2
-rw-r--r--src/gui/itemviews/qfileiconprovider.cpp24
-rw-r--r--src/gui/itemviews/qheaderview.cpp4
-rw-r--r--src/gui/itemviews/qitemdelegate.cpp4
-rw-r--r--src/gui/itemviews/qitemselectionmodel.cpp10
-rw-r--r--src/gui/itemviews/qlistview.cpp175
-rw-r--r--src/gui/itemviews/qlistview_p.h13
-rw-r--r--src/gui/itemviews/qlistwidget.cpp31
-rw-r--r--src/gui/itemviews/qlistwidget_p.h3
-rw-r--r--src/gui/itemviews/qstyleditemdelegate.cpp2
-rw-r--r--src/gui/itemviews/qtableview.cpp52
-rw-r--r--src/gui/itemviews/qtableview_p.h6
-rw-r--r--src/gui/itemviews/qtablewidget.cpp4
-rw-r--r--src/gui/itemviews/qtreeview.cpp109
-rw-r--r--src/gui/itemviews/qtreeview_p.h9
-rw-r--r--src/gui/itemviews/qtreewidget.cpp11
-rw-r--r--src/gui/kernel/kernel.pri1
-rw-r--r--src/gui/kernel/qaction.cpp30
-rw-r--r--src/gui/kernel/qaction_p.h2
-rw-r--r--src/gui/kernel/qactiongroup.cpp14
-rw-r--r--src/gui/kernel/qapplication.cpp133
-rw-r--r--src/gui/kernel/qapplication.h16
-rw-r--r--src/gui/kernel/qapplication_mac.mm74
-rw-r--r--src/gui/kernel/qapplication_p.h11
-rw-r--r--src/gui/kernel/qapplication_s60.cpp365
-rw-r--r--src/gui/kernel/qapplication_win.cpp42
-rw-r--r--src/gui/kernel/qapplication_x11.cpp24
-rw-r--r--src/gui/kernel/qclipboard.cpp4
-rw-r--r--src/gui/kernel/qclipboard_mac.cpp2
-rw-r--r--src/gui/kernel/qclipboard_s60.cpp2
-rw-r--r--src/gui/kernel/qclipboard_win.cpp4
-rw-r--r--src/gui/kernel/qclipboard_x11.cpp9
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac.mm11
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac_p.h1
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm65
-rw-r--r--src/gui/kernel/qcocoawindowdelegate_mac.mm35
-rw-r--r--src/gui/kernel/qcocoawindowdelegate_mac_p.h3
-rw-r--r--src/gui/kernel/qcursor_s60.cpp2
-rw-r--r--src/gui/kernel/qcursor_win.cpp8
-rw-r--r--src/gui/kernel/qdesktopwidget.cpp66
-rw-r--r--src/gui/kernel/qdesktopwidget.h6
-rw-r--r--src/gui/kernel/qdesktopwidget_mac.mm13
-rw-r--r--src/gui/kernel/qdesktopwidget_s60.cpp2
-rw-r--r--src/gui/kernel/qdesktopwidget_x11.cpp9
-rw-r--r--src/gui/kernel/qdnd_s60.cpp2
-rw-r--r--src/gui/kernel/qevent.cpp284
-rw-r--r--src/gui/kernel/qevent.h24
-rw-r--r--src/gui/kernel/qevent_p.h27
-rw-r--r--src/gui/kernel/qeventdispatcher_mac.mm27
-rw-r--r--src/gui/kernel/qeventdispatcher_s60.cpp2
-rw-r--r--src/gui/kernel/qeventdispatcher_s60_p.h2
-rw-r--r--src/gui/kernel/qgesture.cpp443
-rw-r--r--src/gui/kernel/qgesture.h90
-rw-r--r--src/gui/kernel/qgesture_p.h63
-rw-r--r--src/gui/kernel/qgesturemanager.cpp699
-rw-r--r--src/gui/kernel/qgesturemanager_p.h48
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp104
-rw-r--r--src/gui/kernel/qgesturerecognizer.h29
-rw-r--r--src/gui/kernel/qguiplatformplugin.cpp10
-rw-r--r--src/gui/kernel/qkeymapper_s60.cpp2
-rw-r--r--src/gui/kernel/qkeymapper_win.cpp4
-rw-r--r--src/gui/kernel/qkeymapper_x11.cpp286
-rw-r--r--src/gui/kernel/qkeysequence.cpp194
-rw-r--r--src/gui/kernel/qlayout.cpp32
-rw-r--r--src/gui/kernel/qlayout.h3
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac.mm65
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac_p.h13
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp46
-rw-r--r--src/gui/kernel/qsoftkeymanager_p.h3
-rw-r--r--src/gui/kernel/qsound_s60.cpp96
-rw-r--r--src/gui/kernel/qstandardgestures.cpp522
-rw-r--r--src/gui/kernel/qstandardgestures_p.h43
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm19
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h4
-rw-r--r--src/gui/kernel/qt_s60_p.h41
-rw-r--r--src/gui/kernel/qt_x11_p.h3
-rw-r--r--src/gui/kernel/qwidget.cpp271
-rw-r--r--src/gui/kernel/qwidget.h15
-rw-r--r--src/gui/kernel/qwidget_mac.mm58
-rw-r--r--src/gui/kernel/qwidget_p.h87
-rw-r--r--src/gui/kernel/qwidget_qws.cpp3
-rw-r--r--src/gui/kernel/qwidget_s60.cpp193
-rw-r--r--src/gui/kernel/qwidget_win.cpp53
-rw-r--r--src/gui/kernel/qwidget_wince.cpp20
-rw-r--r--src/gui/kernel/qwidget_x11.cpp73
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win.cpp33
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win_p.h9
-rw-r--r--src/gui/kernel/symbian.pri3
-rw-r--r--src/gui/math3d/qgenericmatrix.cpp106
-rw-r--r--src/gui/math3d/qgenericmatrix.h37
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp355
-rw-r--r--src/gui/math3d/qmatrix4x4.h56
-rw-r--r--src/gui/math3d/qquaternion.cpp4
-rw-r--r--src/gui/math3d/qquaternion.h2
-rw-r--r--src/gui/painting/painting.pri1
-rw-r--r--src/gui/painting/qbackingstore.cpp29
-rw-r--r--src/gui/painting/qbackingstore_p.h13
-rw-r--r--src/gui/painting/qblendfunctions.cpp45
-rw-r--r--src/gui/painting/qbrush.cpp24
-rw-r--r--src/gui/painting/qcolormap_qws.cpp2
-rw-r--r--src/gui/painting/qdrawhelper.cpp32
-rw-r--r--src/gui/painting/qmatrix.cpp18
-rw-r--r--src/gui/painting/qmatrix.h3
-rw-r--r--src/gui/painting/qpaintbuffer.cpp95
-rw-r--r--src/gui/painting/qpaintbuffer_p.h5
-rw-r--r--src/gui/painting/qpaintdevice.cpp5
-rw-r--r--src/gui/painting/qpaintdevice.h4
-rw-r--r--src/gui/painting/qpaintdevice.qdoc22
-rw-r--r--src/gui/painting/qpaintengine.h1
-rw-r--r--src/gui/painting/qpaintengine_mac.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp29
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp2
-rw-r--r--src/gui/painting/qpaintengineex.cpp36
-rw-r--r--src/gui/painting/qpaintengineex_p.h6
-rw-r--r--src/gui/painting/qpainter.cpp98
-rw-r--r--src/gui/painting/qpainterpath.cpp35
-rw-r--r--src/gui/painting/qpainterpath_p.h34
-rw-r--r--src/gui/painting/qpathclipper.cpp2
-rw-r--r--src/gui/painting/qpdf.cpp8
-rw-r--r--src/gui/painting/qpen.cpp33
-rw-r--r--src/gui/painting/qprinterinfo_unix.cpp2
-rw-r--r--src/gui/painting/qrasterizer.cpp6
-rw-r--r--src/gui/painting/qregion.cpp41
-rw-r--r--src/gui/painting/qregion.h3
-rw-r--r--src/gui/painting/qregion_s60.cpp2
-rw-r--r--src/gui/painting/qstroker.cpp62
-rw-r--r--src/gui/painting/qstroker_p.h15
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp4
-rw-r--r--src/gui/painting/qtransform.cpp11
-rw-r--r--src/gui/painting/qvectorpath_p.h72
-rw-r--r--src/gui/painting/qwindowsurface_qws.cpp2
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp12
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp2
-rw-r--r--src/gui/painting/qwindowsurface_s60_p.h2
-rw-r--r--src/gui/painting/qwindowsurface_x11.cpp6
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp27
-rw-r--r--src/gui/s60framework/qs60maindocument.cpp2
-rw-r--r--src/gui/s60framework/s60framework.pri11
-rw-r--r--src/gui/s60framework/s60main.rss85
-rw-r--r--src/gui/statemachine/qbasickeyeventtransition.cpp24
-rw-r--r--src/gui/statemachine/qbasickeyeventtransition_p.h6
-rw-r--r--src/gui/statemachine/qbasicmouseeventtransition.cpp24
-rw-r--r--src/gui/statemachine/qbasicmouseeventtransition_p.h8
-rw-r--r--src/gui/statemachine/qguistatemachine.cpp16
-rw-r--r--src/gui/statemachine/qkeyeventtransition.cpp18
-rw-r--r--src/gui/statemachine/qkeyeventtransition.h6
-rw-r--r--src/gui/statemachine/qmouseeventtransition.cpp30
-rw-r--r--src/gui/statemachine/qmouseeventtransition.h10
-rw-r--r--src/gui/styles/gtksymbols.cpp1005
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp5
-rw-r--r--src/gui/styles/qcommonstyle.cpp194
-rw-r--r--src/gui/styles/qcommonstyle_p.h19
-rw-r--r--src/gui/styles/qgtkpainter.cpp72
-rw-r--r--src/gui/styles/qgtkpainter_p.h2
-rw-r--r--src/gui/styles/qgtkstyle.cpp596
-rw-r--r--src/gui/styles/qgtkstyle.h8
-rw-r--r--src/gui/styles/qgtkstyle_p.cpp1083
-rw-r--r--src/gui/styles/qgtkstyle_p.h (renamed from src/gui/styles/gtksymbols_p.h)111
-rw-r--r--src/gui/styles/qmacstyle_mac.mm19
-rw-r--r--src/gui/styles/qmotifstyle.cpp4
-rw-r--r--src/gui/styles/qplastiquestyle.cpp21
-rw-r--r--src/gui/styles/qs60style.cpp477
-rw-r--r--src/gui/styles/qs60style.h8
-rw-r--r--src/gui/styles/qs60style_p.h19
-rw-r--r--src/gui/styles/qs60style_s60.cpp121
-rw-r--r--src/gui/styles/qs60style_simulated.cpp22
-rw-r--r--src/gui/styles/qstyle.cpp4
-rw-r--r--src/gui/styles/qstyle.h2
-rw-r--r--src/gui/styles/qstyleoption.cpp131
-rw-r--r--src/gui/styles/qstyleoption.h22
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp82
-rw-r--r--src/gui/styles/qstylesheetstyle_default.cpp43
-rw-r--r--src/gui/styles/qwindowsmobilestyle.cpp158
-rw-r--r--src/gui/styles/qwindowsmobilestyle_p.h4
-rw-r--r--src/gui/styles/qwindowsstyle.cpp42
-rw-r--r--src/gui/styles/qwindowsstyle_p.h10
-rw-r--r--src/gui/styles/qwindowsvistastyle.cpp55
-rw-r--r--src/gui/styles/qwindowsvistastyle_p.h24
-rw-r--r--src/gui/styles/qwindowsxpstyle.cpp53
-rw-r--r--src/gui/styles/styles.pri4
-rw-r--r--src/gui/symbian/qsymbianevent.cpp143
-rw-r--r--src/gui/symbian/qsymbianevent.h104
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h1
-rw-r--r--src/gui/text/qcssparser.cpp7
-rw-r--r--src/gui/text/qfont.cpp18
-rw-r--r--src/gui/text/qfont_p.h2
-rw-r--r--src/gui/text/qfont_s60.cpp2
-rw-r--r--src/gui/text/qfontdatabase.cpp27
-rw-r--r--src/gui/text/qfontdatabase.h1
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp29
-rw-r--r--src/gui/text/qfontdatabase_win.cpp12
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp109
-rw-r--r--src/gui/text/qfontengine_ft.cpp13
-rw-r--r--src/gui/text/qfontengine_mac.mm78
-rw-r--r--src/gui/text/qfontengine_p.h3
-rw-r--r--src/gui/text/qfontengine_qpf.cpp6
-rw-r--r--src/gui/text/qfontengine_s60.cpp2
-rw-r--r--src/gui/text/qfontengine_s60_p.h2
-rw-r--r--src/gui/text/qfontengine_win.cpp103
-rw-r--r--src/gui/text/qfontinfo.h3
-rw-r--r--src/gui/text/qfontmetrics.cpp49
-rw-r--r--src/gui/text/qfontmetrics.h5
-rw-r--r--src/gui/text/qtextcontrol.cpp70
-rw-r--r--src/gui/text/qtextcontrol_p.h4
-rw-r--r--src/gui/text/qtextcontrol_p_p.h5
-rw-r--r--src/gui/text/qtextdocument.cpp49
-rw-r--r--src/gui/text/qtextdocument.h3
-rw-r--r--src/gui/text/qtextdocument_p.cpp4
-rw-r--r--src/gui/text/qtextdocument_p.h3
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp9
-rw-r--r--src/gui/text/qtextengine.cpp22
-rw-r--r--src/gui/text/qtextengine_mac.cpp80
-rw-r--r--src/gui/text/qtextengine_p.h17
-rw-r--r--src/gui/text/qtextformat.cpp76
-rw-r--r--src/gui/text/qtextformat_p.h4
-rw-r--r--src/gui/text/qtextlayout.cpp76
-rw-r--r--src/gui/text/qtextlayout.h4
-rw-r--r--src/gui/text/text.pri1
-rw-r--r--src/gui/util/qdesktopservices.cpp11
-rw-r--r--src/gui/util/qdesktopservices_mac.cpp9
-rw-r--r--src/gui/util/qdesktopservices_s60.cpp2
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp83
-rw-r--r--src/gui/widgets/qabstractscrollarea.h2
-rw-r--r--src/gui/widgets/qabstractslider.cpp46
-rw-r--r--src/gui/widgets/qcalendarwidget.cpp14
-rw-r--r--src/gui/widgets/qcombobox.cpp115
-rw-r--r--src/gui/widgets/qcombobox.h5
-rw-r--r--src/gui/widgets/qcombobox_p.h6
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp41
-rw-r--r--src/gui/widgets/qdockarealayout.cpp39
-rw-r--r--src/gui/widgets/qdockarealayout_p.h9
-rw-r--r--src/gui/widgets/qdockwidget.cpp17
-rw-r--r--src/gui/widgets/qfontcombobox.cpp13
-rw-r--r--src/gui/widgets/qlabel.cpp38
-rw-r--r--src/gui/widgets/qlabel_p.h2
-rw-r--r--src/gui/widgets/qlcdnumber.cpp50
-rw-r--r--src/gui/widgets/qlcdnumber.h7
-rw-r--r--src/gui/widgets/qlinecontrol.cpp33
-rw-r--r--src/gui/widgets/qlinecontrol_p.h6
-rw-r--r--src/gui/widgets/qlineedit.cpp32
-rw-r--r--src/gui/widgets/qlineedit.h3
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp3
-rw-r--r--src/gui/widgets/qmenu.cpp139
-rw-r--r--src/gui/widgets/qmenu_mac.mm26
-rw-r--r--src/gui/widgets/qmenu_p.h8
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp8
-rw-r--r--src/gui/widgets/qmenubar.cpp42
-rw-r--r--src/gui/widgets/qmenubar_p.h3
-rw-r--r--src/gui/widgets/qplaintextedit.cpp63
-rw-r--r--src/gui/widgets/qprintpreviewwidget.cpp12
-rw-r--r--src/gui/widgets/qprintpreviewwidget.h3
-rw-r--r--src/gui/widgets/qpushbutton.cpp4
-rw-r--r--src/gui/widgets/qsplitter.cpp17
-rw-r--r--src/gui/widgets/qtabbar.cpp19
-rw-r--r--src/gui/widgets/qtabbar_p.h10
-rw-r--r--src/gui/widgets/qtabwidget.cpp16
-rw-r--r--src/gui/widgets/qtextedit.cpp23
-rw-r--r--src/gui/widgets/qtoolbar.cpp18
-rw-r--r--src/gui/widgets/qtoolbar.h1
-rw-r--r--src/gui/widgets/qtoolbararealayout.cpp50
-rw-r--r--src/gui/widgets/qtoolbararealayout_p.h6
-rw-r--r--src/gui/widgets/qtoolbarlayout.cpp5
-rw-r--r--src/gui/widgets/qtoolbarlayout_p.h2
-rw-r--r--src/gui/widgets/qwidgetanimator.cpp9
-rw-r--r--src/gui/widgets/qwidgetanimator_p.h1
367 files changed, 12999 insertions, 7361 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index a527ee73c9..a11ebeabed 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -984,6 +984,16 @@ const QAccessibleInterface *other, int otherChild) const
*/
/*!
+ \fn QAccessibleActionInterface *QAccessibleInterface::actionInterface()
+ \internal
+*/
+
+/*!
+ \fn QAccessibleImageInterface *QAccessibleInterface::imageInterface()
+ \internal
+*/
+
+/*!
\class QAccessibleEvent
\brief The QAccessibleEvent class is used to query addition
accessibility information about complex widgets.
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index 96fe91cbbf..c49305488e 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -310,7 +310,9 @@ namespace QAccessible2
TextInterface,
EditableTextInterface,
ValueInterface,
- TableInterface
+ TableInterface,
+ ActionInterface,
+ ImageInterface
};
}
@@ -319,6 +321,8 @@ class QAccessibleTextInterface;
class QAccessibleEditableTextInterface;
class QAccessibleValueInterface;
class QAccessibleTableInterface;
+class QAccessibleActionInterface;
+class QAccessibleImageInterface;
class Q_GUI_EXPORT QAccessibleInterface : public QAccessible
{
@@ -376,6 +380,12 @@ public:
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)); }
+
private:
QAccessible2Interface *cast_helper(QAccessible2::InterfaceType);
};
diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp
index f7319622be..b878cf12ba 100644
--- a/src/gui/accessible/qaccessible2.cpp
+++ b/src/gui/accessible/qaccessible2.cpp
@@ -108,6 +108,30 @@ QT_BEGIN_NAMESPACE
\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
+*/
+
QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface(
QAccessibleInterface *accessibleInterface)
: iface(accessibleInterface)
diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h
index 328150931d..ba12a7c9f6 100644
--- a/src/gui/accessible/qaccessible2.h
+++ b/src/gui/accessible/qaccessible2.h
@@ -81,6 +81,8 @@ 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; }
#define Q_ACCESSIBLE_OBJECT \
public: \
@@ -95,6 +97,10 @@ inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; }
return qAccessibleValueCastHelper(); \
case QAccessible2::TableInterface: \
return qAccessibleTableCastHelper(); \
+ case QAccessible2::ActionInterface: \
+ return qAccessibleActionCastHelper(); \
+ case QAccessible2::ImageInterface: \
+ return qAccessibleImageCastHelper(); \
} \
return 0; \
} \
@@ -208,6 +214,29 @@ public:
int *columnSpan, bool *isSelected) = 0;
};
+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
diff --git a/src/gui/accessible/qaccessible_mac.mm b/src/gui/accessible/qaccessible_mac.mm
index 9575ad8a8c..030c1a982b 100644
--- a/src/gui/accessible/qaccessible_mac.mm
+++ b/src/gui/accessible/qaccessible_mac.mm
@@ -504,11 +504,6 @@ QAElement::QAElement(const QAElement &element)
}
QAElement::QAElement(HIObjectRef object, int child)
- :elementRef(
-#ifndef QT_MAC_USE_COCOA
- AXUIElementCreateWithHIObjectAndIdentifier(object, child)
-#endif
-)
{
#ifndef QT_MAC_USE_COCOA
if (object == 0) {
diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp
index 0ae79b6a0e..1e9c166b2a 100644
--- a/src/gui/animation/qguivariantanimation.cpp
+++ b/src/gui/animation/qguivariantanimation.cpp
@@ -54,10 +54,10 @@ QT_BEGIN_NAMESPACE
template<> Q_INLINE_TEMPLATE QColor _q_interpolate(const QColor &f,const QColor &t, qreal progress)
{
- return QColor(_q_interpolate(f.red(), t.red(), progress),
- _q_interpolate(f.green(), t.green(), progress),
- _q_interpolate(f.blue(), t.blue(), progress),
- _q_interpolate(f.alpha(), t.alpha(), progress));
+ return QColor(qBound(0,_q_interpolate(f.red(), t.red(), progress),255),
+ qBound(0,_q_interpolate(f.green(), t.green(), progress),255),
+ qBound(0,_q_interpolate(f.blue(), t.blue(), progress),255),
+ qBound(0,_q_interpolate(f.alpha(), t.alpha(), progress),255));
}
template<> Q_INLINE_TEMPLATE QQuaternion _q_interpolate(const QQuaternion &f,const QQuaternion &t, qreal progress)
diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm
index 9e4fdd1d0b..5f074c0d94 100644
--- a/src/gui/dialogs/qcolordialog_mac.mm
+++ b/src/gui/dialogs/qcolordialog_mac.mm
@@ -252,15 +252,20 @@ QT_USE_NAMESPACE
delete mQtColor;
mQtColor = new QColor();
NSColor *color = [mColorPanel color];
- NSString *colorSpace = [color colorSpaceName];
- if (colorSpace == NSDeviceCMYKColorSpace) {
- CGFloat cyan, magenta, yellow, black, alpha;
+ NSString *colorSpaceName = [color colorSpaceName];
+ if (colorSpaceName == NSDeviceCMYKColorSpace) {
+ CGFloat cyan = 0, magenta = 0, yellow = 0, black = 0, alpha = 0;
[color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
mQtColor->setCmykF(cyan, magenta, yellow, black, alpha);
- } else if (colorSpace == NSCalibratedRGBColorSpace || colorSpace == NSDeviceRGBColorSpace) {
- CGFloat red, green, blue, alpha;
+ } else if (colorSpaceName == NSCalibratedRGBColorSpace || colorSpaceName == NSDeviceRGBColorSpace) {
+ CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[color getRed:&red green:&green blue:&blue alpha:&alpha];
mQtColor->setRgbF(red, green, blue, alpha);
+ } else if (colorSpaceName == NSNamedColorSpace) {
+ NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+ CGFloat red = 0, green = 0, blue = 0, alpha = 0;
+ [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
+ mQtColor->setRgbF(red, green, blue, alpha);
} else {
NSColorSpace *colorSpace = [color colorSpace];
if ([colorSpace colorSpaceModel] == NSCMYKColorSpaceModel && [color numberOfComponents] == 5){
@@ -269,7 +274,7 @@ QT_USE_NAMESPACE
mQtColor->setCmykF(components[0], components[1], components[2], components[3], components[4]);
} else {
NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
- CGFloat red, green, blue, alpha;
+ CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
mQtColor->setRgbF(red, green, blue, alpha);
}
@@ -319,7 +324,18 @@ QT_USE_NAMESPACE
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
QMacCocoaAutoReleasePool pool;
mDialogIsExecuting = true;
- [NSApp runModalForWindow:mColorPanel];
+ bool modalEnded = false;
+ while (!modalEnded) {
+ @try {
+ [NSApp runModalForWindow:mColorPanel];
+ modalEnded = true;
+ } @catch (NSException *) {
+ // For some reason, NSColorPanel throws an exception when
+ // clicking on 'SelectedMenuItemColor' from the 'Developer'
+ // palette (tab three).
+ }
+ }
+
QAbstractEventDispatcher::instance()->interrupt();
if (mResultCode == NSCancelButton)
mPriv->colorDialog()->reject();
diff --git a/src/gui/dialogs/qerrormessage.cpp b/src/gui/dialogs/qerrormessage.cpp
index 436ef9473c..762936a725 100644
--- a/src/gui/dialogs/qerrormessage.cpp
+++ b/src/gui/dialogs/qerrormessage.cpp
@@ -245,12 +245,6 @@ QErrorMessage::QErrorMessage(QWidget * parent)
Q_D(QErrorMessage);
QGridLayout * grid = new QGridLayout(this);
d->icon = new QLabel(this);
-#ifdef QT_SOFTKEYS_ENABLED
- d->okAction = new QAction(this);
- d->okAction->setSoftKeyRole(QAction::PositiveSoftKey);
- connect(d->okAction, SIGNAL(triggered()), this, SLOT(accept()));
- addAction(d->okAction);
-#endif
#ifndef QT_NO_MESSAGEBOX
d->icon->setPixmap(QMessageBox::standardIcon(QMessageBox::Information));
d->icon->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
@@ -262,6 +256,13 @@ QErrorMessage::QErrorMessage(QWidget * parent)
d->again->setChecked(true);
grid->addWidget(d->again, 1, 1, Qt::AlignTop);
d->ok = new QPushButton(this);
+#ifdef QT_SOFTKEYS_ENABLED
+ d->okAction = new QAction(d->ok);
+ d->okAction->setSoftKeyRole(QAction::PositiveSoftKey);
+ connect(d->okAction, SIGNAL(triggered()), this, SLOT(accept()));
+ addAction(d->okAction);
+#endif
+
#if defined(Q_WS_WINCE) || defined(Q_WS_S60)
d->ok->setFixedSize(0,0);
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index eab842f989..3b1befde4c 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -777,7 +777,7 @@ void QFileDialog::setDirectory(const QString &directory)
QModelIndex root = d->model->setRootPath(newDirectory);
d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled);
if (root != d->rootIndex()) {
-#ifndef QT_NO_COMPLETER
+#ifndef QT_NO_FSCOMPLETER
if (directory.endsWith(QLatin1Char('/')))
d->completer->setCompletionPrefix(newDirectory);
else
@@ -2177,12 +2177,12 @@ void QFileDialogPrivate::createWidgets()
#ifndef QT_NO_SHORTCUT
qFileDialogUi->fileNameLabel->setBuddy(qFileDialogUi->fileNameEdit);
#endif
-#ifndef QT_NO_COMPLETER
+#ifndef QT_NO_FSCOMPLETER
completer = new QFSCompleter(model, q);
qFileDialogUi->fileNameEdit->setCompleter(completer);
QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
q, SLOT(_q_autoCompleteFileName(QString)));
-#endif // QT_NO_COMPLETER
+#endif // QT_NO_FSCOMPLETER
QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
q, SLOT(_q_updateOkButton()));
@@ -2302,7 +2302,7 @@ void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel)
proxyModel->setSourceModel(d->model);
d->qFileDialogUi->listView->setModel(d->proxyModel);
d->qFileDialogUi->treeView->setModel(d->proxyModel);
-#ifndef QT_NO_COMPLETER
+#ifndef QT_NO_FSCOMPLETER
d->completer->setModel(d->proxyModel);
d->completer->proxyModel = d->proxyModel;
#endif
@@ -2312,7 +2312,7 @@ void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel)
d->proxyModel = 0;
d->qFileDialogUi->listView->setModel(d->model);
d->qFileDialogUi->treeView->setModel(d->model);
-#ifndef QT_NO_COMPLETER
+#ifndef QT_NO_FSCOMPLETER
d->completer->setModel(d->model);
d->completer->sourceModel = d->model;
d->completer->proxyModel = 0;
@@ -3022,12 +3022,6 @@ bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) {
case Qt::Key_Escape:
q->hide();
return true;
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Down:
- case Qt::Key_Up:
- return (QApplication::navigationMode() != Qt::NavigationModeKeypadTabOrder
- && QApplication::navigationMode() != Qt::NavigationModeKeypadDirectional);
-#endif
default:
break;
}
@@ -3145,20 +3139,16 @@ QSize QFileDialogListView::sizeHint() const
void QFileDialogListView::keyPressEvent(QKeyEvent *e)
{
- if (!d_ptr->itemViewKeyboardEvent(e)) {
- QListView::keyPressEvent(e);
- }
#ifdef QT_KEYPAD_NAVIGATION
- else if ((QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
- || QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional)
- && !hasEditFocus()) {
- e->ignore();
- } else {
- e->accept();
+ if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
+ QListView::keyPressEvent(e);
+ return;
}
-#else
+#endif // QT_KEYPAD_NAVIGATION
+
+ if (!d_ptr->itemViewKeyboardEvent(e))
+ QListView::keyPressEvent(e);
e->accept();
-#endif
}
QFileDialogTreeView::QFileDialogTreeView(QWidget *parent) : QTreeView(parent)
@@ -3184,9 +3174,15 @@ void QFileDialogTreeView::init(QFileDialogPrivate *d_pointer)
void QFileDialogTreeView::keyPressEvent(QKeyEvent *e)
{
- if (!d_ptr->itemViewKeyboardEvent(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();
}
@@ -3203,13 +3199,16 @@ QSize QFileDialogTreeView::sizeHint() const
*/
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
-#ifdef QT_KEYPAD_NAVIGATION
- && QApplication::navigationMode() == Qt::NavigationModeNone
-#endif
- )
+ if (key != Qt::Key_Escape)
e->accept();
if (hideOnEsc && (key == Qt::Key_Escape || key == Qt::Key_Return || key == Qt::Key_Enter)) {
e->accept();
@@ -3218,7 +3217,7 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e)
}
}
-#ifndef QT_NO_COMPLETER
+#ifndef QT_NO_FSCOMPLETER
QString QFSCompleter::pathFromIndex(const QModelIndex &index) const
{
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index 8e4c461164..b0e6575766 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -280,6 +280,10 @@ QT_USE_NAMESPACE
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
{
Q_UNUSED(sender);
+
+ if ([filename length] == 0)
+ return NO;
+
QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename);
QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
QString path = info.absolutePath();
@@ -395,9 +399,13 @@ QT_USE_NAMESPACE
- (void)panelSelectionDidChange:(id)sender
{
Q_UNUSED(sender);
- *mCurrentSelection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString([mSavePanel filename]));
- if (mPriv)
- mPriv->QNSOpenSavePanelDelegate_selectionChanged(*mCurrentSelection);
+ if (mPriv) {
+ QString selection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString([mSavePanel filename]));
+ if (selection != mCurrentSelection) {
+ *mCurrentSelection = selection;
+ mPriv->QNSOpenSavePanelDelegate_selectionChanged(selection);
+ }
+ }
}
- (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
@@ -822,8 +830,8 @@ void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMess
|| mode == QFileDialog::ExistingFiles){
// When changing directory, the current selection is cleared if
// we are supposed to be selecting files only:
- fileDialogPrivate->mCurrentSelectionList.clear();
if (!fileDialogPrivate->mCurrentSelection.isEmpty()){
+ fileDialogPrivate->mCurrentSelectionList.clear();
fileDialogPrivate->mCurrentSelection.clear();
emit fileDialogPrivate->q_func()->currentChanged(fileDialogPrivate->mCurrentSelection);
}
diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h
index 32cd397ebf..0e447a34ed 100644
--- a/src/gui/dialogs/qfiledialog_p.h
+++ b/src/gui/dialogs/qfiledialog_p.h
@@ -234,9 +234,9 @@ public:
QStringList watching;
QFileSystemModel *model;
-#ifndef QT_NO_COMPLETER
+#ifndef QT_NO_FSCOMPLETER
QFSCompleter *completer;
-#endif //QT_NO_COMPLETER
+#endif //QT_NO_FSCOMPLETER
QFileDialog::FileMode fileMode;
QFileDialog::AcceptMode acceptMode;
diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp
index b59c28b6ef..d8ae73e062 100644
--- a/src/gui/dialogs/qfiledialog_win.cpp
+++ b/src/gui/dialogs/qfiledialog_win.cpp
@@ -251,10 +251,10 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent,
ofn->nMaxFile = maxLen;
ofn->lpstrInitialDir = (wchar_t*)tInitDir.utf16();
ofn->lpstrTitle = (wchar_t*)tTitle.utf16();
- ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER);
+ ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST);
if (mode == QFileDialog::ExistingFile ||
mode == QFileDialog::ExistingFiles)
- ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
+ ofn->Flags |= (OFN_FILEMUSTEXIST);
if (mode == QFileDialog::ExistingFiles)
ofn->Flags |= (OFN_ALLOWMULTISELECT);
if (!(options & QFileDialog::DontConfirmOverwrite))
@@ -509,7 +509,7 @@ static bool qt_win_set_IFileDialogOptions(IFileDialog *pfd,
DWORD newOptions;
hr = pfd->GetOptions(&newOptions);
if (SUCCEEDED(hr)) {
- newOptions |= (FOS_NOCHANGEDIR | FOS_NOREADONLYRETURN);
+ newOptions |= FOS_NOCHANGEDIR;
if (mode == QFileDialog::ExistingFile ||
mode == QFileDialog::ExistingFiles)
newOptions |= (FOS_FILEMUSTEXIST | FOS_PATHMUSTEXIST);
diff --git a/src/gui/dialogs/qfscompleter_p.h b/src/gui/dialogs/qfscompleter_p.h
index cb1b42747e..1edab2dc81 100644
--- a/src/gui/dialogs/qfscompleter_p.h
+++ b/src/gui/dialogs/qfscompleter_p.h
@@ -56,7 +56,7 @@
#include "qcompleter.h"
#include <QtGui/qfilesystemmodel.h>
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_COMPLETER
+#ifndef QT_NO_FSCOMPLETER
/*!
QCompleter that can deal with QFileSystemModel
@@ -76,7 +76,7 @@ public:
QAbstractProxyModel *proxyModel;
QFileSystemModel *sourceModel;
};
-#endif // QT_NO_COMPLETER
+#endif // QT_NO_FSCOMPLETER
QT_END_NAMESPACE
#endif // QFSCOMPLETOR_P_H
diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/gui/dialogs/qprintdialog_mac.mm
index 667fc406ea..56a065af7b 100644
--- a/src/gui/dialogs/qprintdialog_mac.mm
+++ b/src/gui/dialogs/qprintdialog_mac.mm
@@ -122,6 +122,8 @@ QT_END_NAMESPACE
QT_USE_NAMESPACE
+#ifdef QT_MAC_USE_COCOA
+
@class QCocoaPrintPanelDelegate;
@interface QCocoaPrintPanelDelegate : NSObject {
@@ -197,6 +199,8 @@ QT_USE_NAMESPACE
}
@end
+#endif
+
QT_BEGIN_NAMESPACE
extern void macStartInterceptWindowTitle(QWidget *window);
diff --git a/src/gui/dialogs/qprintdialog_unix.cpp b/src/gui/dialogs/qprintdialog_unix.cpp
index 7daa273785..9d6cd552a2 100644
--- a/src/gui/dialogs/qprintdialog_unix.cpp
+++ b/src/gui/dialogs/qprintdialog_unix.cpp
@@ -696,7 +696,7 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p)
#ifndef QT_NO_FILESYSTEMMODEL
QFileSystemModel *fsm = new QFileSystemModel(widget.filename);
fsm->setRootPath(QDir::homePath());
-#if !defined(QT_NO_COMPLETER) && !defined(QT_NO_FILEDIALOG)
+#if !defined(QT_NO_FSCOMPLETER) && !defined(QT_NO_FILEDIALOG)
widget.filename->setCompleter(new QFSCompleter(fsm, widget.filename));
#endif
#endif
@@ -835,9 +835,6 @@ void QUnixPrintWidgetPrivate::setOptionsPane(QPrintDialogPrivate *pane)
void QUnixPrintWidgetPrivate::_q_btnBrowseClicked()
{
- const int prevPrinter = widget.printers->currentIndex();
- widget.printers->setCurrentIndex(widget.printers->count() - 2); // the pdf one
-
QString filename = widget.filename->text();
#ifndef QT_NO_FILEDIALOG
filename = QFileDialog::getSaveFileName(parent, QPrintDialog::tr("Print To File ..."), filename,
@@ -849,9 +846,11 @@ void QUnixPrintWidgetPrivate::_q_btnBrowseClicked()
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
}
- else
- widget.printers->setCurrentIndex(prevPrinter);
}
void QUnixPrintWidgetPrivate::applyPrinterProperties(QPrinter *p)
diff --git a/src/gui/dialogs/qprintdialog_win.cpp b/src/gui/dialogs/qprintdialog_win.cpp
index 843c4e2815..51e83ac248 100644
--- a/src/gui/dialogs/qprintdialog_win.cpp
+++ b/src/gui/dialogs/qprintdialog_win.cpp
@@ -139,7 +139,7 @@ static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWidget *parent,
if (d->ep->printToFile)
pd->Flags |= PD_PRINTTOFILE;
Q_ASSERT(parent != 0 && parent->testAttribute(Qt::WA_WState_Created));
- pd->hwndOwner = parent->winId();
+ pd->hwndOwner = parent->window()->winId();
pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage());
pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1;
pd->nCopies = d->ep->num_copies;
diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp
index 4cb0c930c4..1f0b51dc20 100644
--- a/src/gui/dialogs/qprintpreviewdialog.cpp
+++ b/src/gui/dialogs/qprintpreviewdialog.cpp
@@ -446,7 +446,7 @@ void QPrintPreviewDialogPrivate::setFitting(bool on)
void QPrintPreviewDialogPrivate::updateNavActions()
{
int curPage = preview->currentPage();
- int numPages = preview->numPages();
+ int numPages = preview->pageCount();
nextPageAction->setEnabled(curPage < numPages);
prevPageAction->setEnabled(curPage > 1);
firstPageAction->setEnabled(curPage > 1);
@@ -458,7 +458,7 @@ void QPrintPreviewDialogPrivate::updatePageNumLabel()
{
Q_Q(QPrintPreviewDialog);
- int numPages = preview->numPages();
+ 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));
@@ -515,7 +515,7 @@ void QPrintPreviewDialogPrivate::_q_navigate(QAction* action)
else if (action == firstPageAction)
preview->setCurrentPage(1);
else if (action == lastPageAction)
- preview->setCurrentPage(preview->numPages());
+ preview->setCurrentPage(preview->pageCount());
updateNavActions();
}
diff --git a/src/gui/dialogs/qprogressdialog.cpp b/src/gui/dialogs/qprogressdialog.cpp
index 5fb10bf110..f5024bb6d7 100644
--- a/src/gui/dialogs/qprogressdialog.cpp
+++ b/src/gui/dialogs/qprogressdialog.cpp
@@ -453,7 +453,7 @@ void QProgressDialog::setCancelButton(QPushButton *cancelButton)
cancelButton->show();
#else
{
- d->cancelAction = new QAction(cancelButton->text(), this);
+ d->cancelAction = new QAction(cancelButton->text(), cancelButton);
d->cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
connect(d->cancelAction, SIGNAL(triggered()), this, SIGNAL(canceled()));
addAction(d->cancelAction);
diff --git a/src/gui/dialogs/qwizard.cpp b/src/gui/dialogs/qwizard.cpp
index 0f6d3535a9..db1c9e9eff 100644
--- a/src/gui/dialogs/qwizard.cpp
+++ b/src/gui/dialogs/qwizard.cpp
@@ -1340,7 +1340,7 @@ bool QWizardPrivate::ensureButton(QWizard::WizardButton which) const
pushButton->setText(buttonDefaultText(wizStyle, which, this));
#ifdef QT_SOFTKEYS_ENABLED
- QAction *softKey = new QAction(pushButton->text(), antiFlickerWidget);
+ QAction *softKey = new QAction(pushButton->text(), pushButton);
QAction::SoftKeyRole softKeyRole;
switch(which) {
case QWizard::NextButton:
@@ -1537,7 +1537,9 @@ void QWizardPrivate::handleAeroStyleChange()
vistaHelper->backButton()->show();
} else {
q->setMouseTracking(true); // ### original value possibly different
+#ifndef QT_NO_CURSOR
q->unsetCursor(); // ### ditto
+#endif
antiFlickerWidget->move(0, 0);
vistaHelper->hideBackButton();
vistaHelper->setTitleBarIconAndCaptionVisible(true);
diff --git a/src/gui/dialogs/qwizard_win.cpp b/src/gui/dialogs/qwizard_win.cpp
index aa38ddcf75..f3f3a4e7f0 100644
--- a/src/gui/dialogs/qwizard_win.cpp
+++ b/src/gui/dialogs/qwizard_win.cpp
@@ -387,10 +387,12 @@ bool QVistaHelper::winEvent(MSG* msg, long* result)
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)
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index ee01fdc129..239e29cd7f 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -65,12 +65,19 @@
\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
- \o QGraphicsPixelizeEffect - pixelizes the item with any pixel size
- \o QGraphicsGrayscaleEffect - renders the item in shades of gray
- \o QGraphicsBloomEffect - applies a blooming / glowing effect
\endlist
- \img graphicseffect-effects.png
+ \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
@@ -79,40 +86,43 @@
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 accepts two arguments: the painter and a pointer to the source
- (QGraphicsEffectSource). The source provides extra context information,
- such as a pointer to the item that is rendering the effect, any cached
- pixmap data, or the device rectangle bounds. For more information, refer to
- the documenation for draw(). To obtain a pointer to the current source,
- simply call source().
+ 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
- sourceBoundingRectChanged() function is called to notify the effects that
- the source's bounding rectangle has changed - e.g., if the source is a
+ 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(),
- QGraphicsEffectSource
+ \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.
- \since 4.6
When a QGraphicsEffect is installed on a QGraphicsItem, for example, this
class will act as a wrapper around QGraphicsItem. Then, calling update() is
@@ -138,20 +148,13 @@ QGraphicsEffectSource::~QGraphicsEffectSource()
{}
/*!
- Returns the bounds of the current painter's device.
-
- This function is useful when you want to draw something in device
- coordinates and ensure the size of the pixmap is not bigger than the size
- of the device.
-
- Calling QGraphicsEffectSource::pixmap(Qt::DeviceCoordinates) always returns
- a pixmap which is bound to the device's size.
+ Returns the bounding rectangle of the source mapped to the given \a system.
- \sa pixmap()
+ \sa draw()
*/
-QRect QGraphicsEffectSource::deviceRect() const
+QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
{
- return d_func()->deviceRect();
+ return d_func()->boundingRect(system);
}
/*!
@@ -159,9 +162,12 @@ QRect QGraphicsEffectSource::deviceRect() const
\sa draw()
*/
-QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
+QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const
{
- return d_func()->boundingRect(system);
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ return d->source->boundingRect(system);
+ return QRectF();
}
/*!
@@ -202,15 +208,45 @@ const QStyleOption *QGraphicsEffectSource::styleOption() const
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 QGraphicsEffectSource::draw(QPainter *painter)
+void QGraphicsEffect::drawSource(QPainter *painter)
{
- d_func()->draw(painter);
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ d->source->draw(painter);
}
/*!
@@ -239,20 +275,99 @@ bool QGraphicsEffectSource::isPixmap() const
}
/*!
+ 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(), deviceRect()
+ \sa QGraphicsEffect::draw(), boundingRect()
*/
-QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
+QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
{
- return d_func()->pixmap(system, offset);
+ Q_D(const QGraphicsEffectSource);
+
+ // Shortcut, no cache for childless pixmap items...
+ const QGraphicsItem *item = graphicsItem();
+ if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
+ return ((QGraphicsPixmapItem *) item)->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 (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.
+
+ \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::invalidateCache(bool effectRectChanged) const
+{
+ if (effectRectChanged && m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect)
+ return;
+ QPixmapCache::remove(m_cacheKey);
}
/*!
@@ -282,9 +397,9 @@ QGraphicsEffect::~QGraphicsEffect()
}
/*!
- Returns the bounding rectangle for this effect, i.e., the bounding
- rectangle of the source, adjusted by any margins applied by the effect
- itself.
+ Returns the effective bounding rectangle for this effect, i.e., the
+ bounding rectangle of the source, adjusted by any margins applied by
+ the effect itself.
\sa boundingRectFor(), updateBoundingRect()
*/
@@ -297,12 +412,13 @@ QRectF QGraphicsEffect::boundingRect() const
}
/*!
- Returns the bounding rectangle for this effect, given the provided source
- \a rect. 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.
+ Returns the effective bounding rectangle for this effect, given the
+ provided \a rect in the source's coordinate space. 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 boundingRect()
+ \sa sourceBoundingRect()
*/
QRectF QGraphicsEffect::boundingRectFor(const QRectF &rect) const
{
@@ -335,8 +451,10 @@ void QGraphicsEffect::setEnabled(bool enable)
return;
d->isEnabled = enable;
- if (d->source)
+ if (d->source) {
d->source->d_func()->effectBoundingRectChanged();
+ d->source->d_func()->invalidateCache();
+ }
emit enabledChanged(enable);
}
@@ -366,6 +484,8 @@ void QGraphicsEffect::update()
}
/*!
+ \internal
+
Returns a pointer to the source, which provides extra context information
that can be useful for the effect.
@@ -385,25 +505,25 @@ QGraphicsEffectSource *QGraphicsEffect::source() const
This function will call update() if this is necessary.
- \sa boundingRectFor(), boundingRect()
+ \sa boundingRectFor(), boundingRect(), sourceBoundingRect()
*/
void QGraphicsEffect::updateBoundingRect()
{
Q_D(QGraphicsEffect);
- if (d->source)
+ if (d->source) {
d->source->d_func()->effectBoundingRectChanged();
+ d->source->d_func()->invalidateCache(true);
+ }
}
/*!
- \fn virtual void QGraphicsEffect::draw(QPainter *painter,
- QGraphicsEffectSource *source) = 0
+ \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.
+ source needs to be drawn.
Reimplement this function in a QGraphicsEffect subclass to provide the
- effect's drawing implementation, using \a painter. The \a source parameter
- is provided for convenience; its value is the same as source().
+ effect's drawing implementation, using \a painter.
For example:
@@ -411,8 +531,6 @@ void QGraphicsEffect::updateBoundingRect()
This function should not be called explicitly by the user, since it is
meant for reimplementation purposes only.
-
- \sa QGraphicsEffectSource
*/
/*!
@@ -428,6 +546,20 @@ void QGraphicsEffect::updateBoundingRect()
*/
/*!
+ \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.
@@ -440,96 +572,6 @@ void QGraphicsEffect::sourceChanged(ChangeFlags flags)
}
/*!
- \class QGraphicsGrayscaleEffect
- \brief The QGraphicsGrayscaleEffect class provides a grayscale effect.
- \since 4.6
-
- A grayscale effect renders the source in shades of gray.
-
- \img graphicseffect-grayscale.png
-
- \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
- QGraphicsColorizeEffect, QGraphicsOpacityEffect
-*/
-
-/*!
- Constructs a new QGraphicsGrayscale instance.
- The \a parent parameter is passed to QGraphicsEffect's constructor.
-*/
-QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate, parent)
-{
-}
-
-/*!
- Destroys the effect.
-*/
-QGraphicsGrayscaleEffect::~QGraphicsGrayscaleEffect()
-{
-}
-
-
-/*!
- \property QGraphicsGrayscaleEffect::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 grayscale.
-*/
-qreal QGraphicsGrayscaleEffect::strength() const
-{
- Q_D(const QGraphicsGrayscaleEffect);
- return d->filter->strength();
-}
-
-void QGraphicsGrayscaleEffect::setStrength(qreal strength)
-{
- Q_D(QGraphicsGrayscaleEffect);
- if (qFuzzyCompare(d->filter->strength(), strength))
- return;
-
- d->filter->setStrength(strength);
- d->opaque = !qFuzzyIsNull(strength);
- update();
- emit strengthChanged(strength);
-}
-
-/*! \fn void QGraphicsGrayscaleEffect::strengthChanged(qreal strength)
- This signal is emitted whenever setStrength() changes the grayscale
- strength property. \a strength contains the new strength value of
- the grayscale effect.
- */
-
-/*!
- \reimp
-*/
-void QGraphicsGrayscaleEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
-{
- Q_D(QGraphicsGrayscaleEffect);
-
- if (!d->opaque) {
- source->draw(painter);
- return;
- }
-
- QPoint offset;
- if (source->isPixmap()) {
- // No point in drawing in device coordinates (pixmap will be scaled anyways).
- const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
- d->filter->draw(painter, offset, pixmap);
- return;
- }
-
- // Draw pixmap in device coordinates to avoid pixmap scaling;
- const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
- d->filter->draw(painter, offset, pixmap);
- painter->setWorldTransform(restoreTransform);
-
-}
-
-/*!
\class QGraphicsColorizeEffect
\brief The QGraphicsColorizeEffect class provides a colorize effect.
\since 4.6
@@ -541,8 +583,7 @@ void QGraphicsGrayscaleEffect::draw(QPainter *painter, QGraphicsEffectSource *so
\img graphicseffect-colorize.png
- \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
- QGraphicsGrayscaleEffect, QGraphicsOpacityEffect
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsOpacityEffect
*/
/*!
@@ -625,25 +666,25 @@ void QGraphicsColorizeEffect::setStrength(qreal strength)
/*!
\reimp
*/
-void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+void QGraphicsColorizeEffect::draw(QPainter *painter)
{
Q_D(QGraphicsColorizeEffect);
if (!d->opaque) {
- source->draw(painter);
+ drawSource(painter);
return;
}
QPoint offset;
- if (source->isPixmap()) {
+ if (sourceIsPixmap()) {
// No point in drawing in device coordinates (pixmap will be scaled anyways).
- const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+ const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad);
d->filter->draw(painter, offset, pixmap);
return;
}
// Draw pixmap in deviceCoordinates to avoid pixmap scaling.
- const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
d->filter->draw(painter, offset, pixmap);
@@ -651,142 +692,43 @@ void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *sou
}
/*!
- \class QGraphicsPixelizeEffect
- \brief The QGraphicsPixelizeEffect class provides a pixelize effect.
+ \class QGraphicsBlurEffect
+ \brief The QGraphicsBlurEffect class provides a blur effect.
\since 4.6
- A pixelize effect renders the source in lower resolution. This effect is
- useful for reducing details, like censorship. The resolution can be
- modified using the setPixelSize() function.
-
- By default, the pixel size is 3.
-
- \img graphicseffect-pixelize.png
+ 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.
- \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsGrayscaleEffect,
- QGraphicsColorizeEffect, QGraphicsOpacityEffect
-*/
+ By default, the blur radius is 5 pixels.
-/*!
- Constructs a new QGraphicsPixelizeEffect instance.
- The \a parent parameter is passed to QGraphicsEffect's constructor.
-*/
-QGraphicsPixelizeEffect::QGraphicsPixelizeEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate, parent)
-{
-}
+ \img graphicseffect-blur.png
-/*!
- Destroys the effect.
+ \sa QGraphicsDropShadowEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
*/
-QGraphicsPixelizeEffect::~QGraphicsPixelizeEffect()
-{
-}
/*!
- \property QGraphicsPixelizeEffect::pixelSize
- \brief the size of a pixel in the effect.
+ \enum QGraphicsBlurEffect::BlurHint
+ \since 4.6
- Setting the pixel size to 2 means two pixels in the source will be used to
- represent one pixel. Using a bigger size results in lower resolution.
+ 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.
- By default, the pixel size is 3.
-*/
-int QGraphicsPixelizeEffect::pixelSize() const
-{
- Q_D(const QGraphicsPixelizeEffect);
- return d->pixelSize;
-}
+ \value PerformanceHint Indicates that rendering performance is the most important factor,
+ at the potential cost of lower quality.
-void QGraphicsPixelizeEffect::setPixelSize(int size)
-{
- Q_D(QGraphicsPixelizeEffect);
- if (d->pixelSize == size)
- return;
+ \value QualityHint Indicates that rendering quality is the most important factor,
+ at the potential cost of lower performance.
- d->pixelSize = size;
- update();
- emit pixelSizeChanged(size);
-}
-
-/*!
- \fn void QGraphicsPixelizeEffect::pixelSizeChanged(int size)
+ \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.
- This signal is emitted whenever the effect's pixel size changes.
- The \a size parameter holds the effect's new pixel size.
+ \sa blurHints(), setBlurHints()
*/
-static inline void pixelize(QImage *image, int pixelSize)
-{
- Q_ASSERT(pixelSize > 0);
- Q_ASSERT(image);
- int width = image->width();
- int height = image->height();
- for (int y = 0; y < height; y += pixelSize) {
- int ys = qMin(height - 1, y + pixelSize / 2);
- QRgb *sbuf = reinterpret_cast<QRgb*>(image->scanLine(ys));
- for (int x = 0; x < width; x += pixelSize) {
- int xs = qMin(width - 1, x + pixelSize / 2);
- QRgb color = sbuf[xs];
- for (int yi = 0; yi < qMin(pixelSize, height - y); ++yi) {
- QRgb *buf = reinterpret_cast<QRgb*>(image->scanLine(y + yi));
- for (int xi = 0; xi < qMin(pixelSize, width - x); ++xi)
- buf[x + xi] = color;
- }
- }
- }
-}
-
-/*!
- \reimp
-*/
-void QGraphicsPixelizeEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
-{
- Q_D(QGraphicsPixelizeEffect);
- if (d->pixelSize <= 0) {
- source->draw(painter);
- return;
- }
-
- QPoint offset;
- if (source->isPixmap()) {
- const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
- QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
- pixelize(&image, d->pixelSize);
- painter->drawImage(offset, image);
- return;
- }
-
- // Draw pixmap in device coordinates to avoid pixmap scaling.
- const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
-
- // pixelize routine
- QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
- pixelize(&image, d->pixelSize);
-
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
- painter->drawImage(offset, image);
- 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 setBlurHint() to choose the quality or performance blur hints.
-
- By default, the blur radius is 5 pixels.
-
- \img graphicseffect-blur.png
-
- \sa QGraphicsDropShadowEffect, QGraphicsPixelizeEffect, QGraphicsGrayscaleEffect,
- QGraphicsColorizeEffect, QGraphicsOpacityEffect
-*/
/*!
Constructs a new QGraphicsBlurEffect instance.
@@ -796,7 +738,7 @@ QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
: QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
{
Q_D(QGraphicsBlurEffect);
- d->filter->setBlurHint(Qt::PerformanceHint);
+ d->filter->setBlurHints(QGraphicsBlurEffect::PerformanceHint);
}
/*!
@@ -815,16 +757,16 @@ QGraphicsBlurEffect::~QGraphicsBlurEffect()
By default, the blur radius is 5 pixels.
*/
-int QGraphicsBlurEffect::blurRadius() const
+qreal QGraphicsBlurEffect::blurRadius() const
{
Q_D(const QGraphicsBlurEffect);
return d->filter->radius();
}
-void QGraphicsBlurEffect::setBlurRadius(int radius)
+void QGraphicsBlurEffect::setBlurRadius(qreal radius)
{
Q_D(QGraphicsBlurEffect);
- if (d->filter->radius() == radius)
+ if (qFuzzyCompare(d->filter->radius(), radius))
return;
d->filter->setRadius(radius);
@@ -833,44 +775,43 @@ void QGraphicsBlurEffect::setBlurRadius(int radius)
}
/*!
- \fn void QGraphicsBlurEffect::blurRadiusChanged(int 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::blurHint
+ \property QGraphicsBlurEffect::blurHints
\brief the blur hint of the effect.
- Use the Qt::PerformanceHint hint to say that you want a faster blur,
- and the Qt::QualityHint hint to say that you prefer a higher quality blur.
-
- When animating the blur radius it's recommended to use Qt::PerformanceHint.
+ 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 Qt::PerformanceHint.
+ By default, the blur hint is PerformanceHint.
*/
-Qt::RenderHint QGraphicsBlurEffect::blurHint() const
+QGraphicsBlurEffect::BlurHints QGraphicsBlurEffect::blurHints() const
{
Q_D(const QGraphicsBlurEffect);
- return d->filter->blurHint();
+ return d->filter->blurHints();
}
-void QGraphicsBlurEffect::setBlurHint(Qt::RenderHint hint)
+void QGraphicsBlurEffect::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
{
Q_D(QGraphicsBlurEffect);
- if (d->filter->blurHint() == hint)
+ if (d->filter->blurHints() == hints)
return;
- d->filter->setBlurHint(hint);
- emit blurHintChanged(hint);
+ d->filter->setBlurHints(hints);
+ emit blurHintsChanged(hints);
}
/*!
- \fn void QGraphicsBlurEffect::blurHintChanged(Qt::RenderHint hint)
+ \fn void QGraphicsBlurEffect::blurHintsChanged(QGraphicsBlurEffect::BlurHints hints)
- This signal is emitted whenever the effect's blur hint changes.
- The \a hint parameter holds the effect's new blur hint.
+ This signal is emitted whenever the effect's blur hints changes.
+ The \a hints parameter holds the effect's new blur hints.
*/
/*!
@@ -885,24 +826,21 @@ QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
/*!
\reimp
*/
-void QGraphicsBlurEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+void QGraphicsBlurEffect::draw(QPainter *painter)
{
Q_D(QGraphicsBlurEffect);
if (d->filter->radius() <= 0) {
- source->draw(painter);
+ drawSource(painter);
return;
}
- QPoint offset;
- if (source->isPixmap()) {
- // No point in drawing in device coordinates (pixmap will be scaled anyways).
- const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
- d->filter->draw(painter, offset, pixmap);
- return;
- }
+ PixmapPadMode mode = PadToEffectiveBoundingRect;
+ if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
+ mode = PadToTransparentBorder;
// Draw pixmap in device coordinates to avoid pixmap scaling.
- const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ QPoint offset;
+ const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
d->filter->draw(painter, offset, pixmap);
@@ -926,8 +864,7 @@ void QGraphicsBlurEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
\img graphicseffect-drop-shadow.png
- \sa QGraphicsBlurEffect, QGraphicsPixelizeEffect, QGraphicsGrayscaleEffect,
- QGraphicsColorizeEffect, QGraphicsOpacityEffect
+ \sa QGraphicsBlurEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
*/
/*!
@@ -977,6 +914,8 @@ void QGraphicsDropShadowEffect::setOffset(const QPointF &offset)
By default, the horizontal shadow offset is 8 pixels.
+
+
\sa yOffset(), offset()
*/
@@ -1007,16 +946,16 @@ void QGraphicsDropShadowEffect::setOffset(const QPointF &offset)
\sa color(), offset().
*/
-int QGraphicsDropShadowEffect::blurRadius() const
+qreal QGraphicsDropShadowEffect::blurRadius() const
{
Q_D(const QGraphicsDropShadowEffect);
return d->filter->blurRadius();
}
-void QGraphicsDropShadowEffect::setBlurRadius(int blurRadius)
+void QGraphicsDropShadowEffect::setBlurRadius(qreal blurRadius)
{
Q_D(QGraphicsDropShadowEffect);
- if (d->filter->blurRadius() == blurRadius)
+ if (qFuzzyCompare(d->filter->blurRadius(), blurRadius))
return;
d->filter->setBlurRadius(blurRadius);
@@ -1025,7 +964,7 @@ void QGraphicsDropShadowEffect::setBlurRadius(int blurRadius)
}
/*!
- \fn void QGraphicsDropShadowEffect::blurRadiusChanged(int 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.
@@ -1076,24 +1015,21 @@ QRectF QGraphicsDropShadowEffect::boundingRectFor(const QRectF &rect) const
/*!
\reimp
*/
-void QGraphicsDropShadowEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+void QGraphicsDropShadowEffect::draw(QPainter *painter)
{
Q_D(QGraphicsDropShadowEffect);
if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) {
- source->draw(painter);
+ drawSource(painter);
return;
}
- QPoint offset;
- if (source->isPixmap()) {
- // No point in drawing in device coordinates (pixmap will be scaled anyways).
- const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
- d->filter->draw(painter, offset, pixmap);
- return;
- }
+ PixmapPadMode mode = PadToEffectiveBoundingRect;
+ if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
+ mode = PadToTransparentBorder;
// Draw pixmap in device coordinates to avoid pixmap scaling.
- const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ QPoint offset;
+ const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
d->filter->draw(painter, offset, pixmap);
@@ -1113,8 +1049,7 @@ void QGraphicsDropShadowEffect::draw(QPainter *painter, QGraphicsEffectSource *s
\img graphicseffect-opacity.png
- \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
- QGraphicsGrayscaleEffect, QGraphicsColorizeEffect
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsColorizeEffect
*/
/*!
@@ -1217,7 +1152,7 @@ void QGraphicsOpacityEffect::setOpacityMask(const QBrush &mask)
/*!
\reimp
*/
-void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+void QGraphicsOpacityEffect::draw(QPainter *painter)
{
Q_D(QGraphicsOpacityEffect);
@@ -1227,302 +1162,42 @@ void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *sour
// Opaque; draw directly without going through a pixmap.
if (d->isFullyOpaque && !d->hasOpacityMask) {
- source->draw(painter);
+ drawSource(painter);
return;
}
- painter->save();
- painter->setOpacity(d->opacity);
-
QPoint offset;
- if (source->isPixmap()) {
- // No point in drawing in device coordinates (pixmap will be scaled anyways).
- if (!d->hasOpacityMask) {
- const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
- painter->drawPixmap(offset, pixmap);
- } else {
- QRect srcBrect = source->boundingRect().toAlignedRect();
- offset = srcBrect.topLeft();
- QPixmap pixmap(srcBrect.size());
- pixmap.fill(Qt::transparent);
+ Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
+ QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad);
+ if (pixmap.isNull())
+ return;
- QPainter pixmapPainter(&pixmap);
- pixmapPainter.setRenderHints(painter->renderHints());
- pixmapPainter.translate(-offset);
- source->draw(&pixmapPainter);
- pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- pixmapPainter.fillRect(srcBrect, d->opacityMask);
- pixmapPainter.end();
+ painter->save();
+ painter->setOpacity(d->opacity);
- painter->drawPixmap(offset, pixmap);
- }
- } else {
- // Draw pixmap in device coordinates to avoid pixmap scaling;
- if (!d->hasOpacityMask) {
- const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
- painter->setWorldTransform(QTransform());
- painter->drawPixmap(offset, pixmap);
- } else {
+ if (d->hasOpacityMask) {
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ if (system == Qt::DeviceCoordinates) {
QTransform worldTransform = painter->worldTransform();
-
- // Calculate source bounding rect in logical and device coordinates.
- QRectF srcBrect = source->boundingRect();
- QRect srcDeviceBrect = worldTransform.mapRect(srcBrect).toAlignedRect();
- srcDeviceBrect &= source->deviceRect();
-
- offset = srcDeviceBrect.topLeft();
- worldTransform *= QTransform::fromTranslate(-srcDeviceBrect.x(), -srcDeviceBrect.y());
-
- QPixmap pixmap(srcDeviceBrect.size());
- pixmap.fill(Qt::transparent);
-
- QPainter pixmapPainter(&pixmap);
- pixmapPainter.setRenderHints(painter->renderHints());
+ worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
pixmapPainter.setWorldTransform(worldTransform);
- source->draw(&pixmapPainter);
- pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- pixmapPainter.fillRect(srcBrect, d->opacityMask);
- pixmapPainter.end();
-
- painter->setWorldTransform(QTransform());
- painter->drawPixmap(offset, pixmap);
+ pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
+ } else {
+ pixmapPainter.translate(-offset);
+ pixmapPainter.fillRect(pixmap.rect(), d->opacityMask);
}
}
- painter->restore();
-}
-
-/*!
- \class QGraphicsBloomEffect
- \brief The QGraphicsBloomEffect class provides a bloom/glow effect.
- \since 4.6
-
- A bloom/glow effect adds fringes of light around bright areas in the source.
-
- \img graphicseffect-bloom.png
-
- \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
- QGraphicsGrayscaleEffect, QGraphicsColorizeEffect
-*/
-
-/*!
- Constructs a new QGraphicsBloomEffect instance.
- The \a parent parameter is passed to QGraphicsEffect's constructor.
-*/
-QGraphicsBloomEffect::QGraphicsBloomEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsBloomEffectPrivate, parent)
-{
- Q_D(QGraphicsBloomEffect);
- for (int i = 0; i < 256; ++i)
- d->colorTable[i] = qMin(i + d->brightness, 255);
-}
-
-/*!
- Destroys the effect.
-*/
-QGraphicsBloomEffect::~QGraphicsBloomEffect()
-{
-}
-
-/*!
- \reimp
-*/
-QRectF QGraphicsBloomEffect::boundingRectFor(const QRectF &rect) const
-{
- Q_D(const QGraphicsBloomEffect);
- const qreal delta = d->blurFilter.radius() * 2;
- return rect.adjusted(-delta, -delta, delta, delta);
-}
-
-/*!
- \property QGraphicsBloomEffect::blurRadius
- \brief the blur radius in pixels 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.
-
- \sa strength(), brightness()
-*/
-int QGraphicsBloomEffect::blurRadius() const
-{
- Q_D(const QGraphicsBloomEffect);
- return d->blurFilter.radius();
-}
-
-void QGraphicsBloomEffect::setBlurRadius(int radius)
-{
- Q_D(QGraphicsBloomEffect);
- if (d->blurFilter.radius() == radius)
- return;
-
- d->blurFilter.setRadius(radius);
- updateBoundingRect();
- emit blurRadiusChanged(radius);
-}
-
-/*!
- \fn void QGraphicsBloomEffect::blurRadiusChanged(int blurRadius)
-
- This signal is emitted whenever the effect's blur radius changes.
- The \a blurRadius parameter holds the effect's new blur radius.
-*/
-
-/*!
- \property QGraphicsBloomEffect::blurHint
- \brief the blur hint of the effect.
-
- Use the Qt::PerformanceHint hint to say that you want a faster blur,
- and the Qt::QualityHint hint to say that you prefer a higher quality blur.
-
- When animating the blur radius it's recommended to use Qt::PerformanceHint.
-
- By default, the blur hint is Qt::PerformanceHint.
-*/
-Qt::RenderHint QGraphicsBloomEffect::blurHint() const
-{
- Q_D(const QGraphicsBloomEffect);
- return d->blurFilter.blurHint();
-}
-
-void QGraphicsBloomEffect::setBlurHint(Qt::RenderHint hint)
-{
- Q_D(QGraphicsBloomEffect);
- if (d->blurFilter.blurHint() == hint)
- return;
-
- d->blurFilter.setBlurHint(hint);
- emit blurHintChanged(hint);
-}
-
-/*!
- \fn void QGraphicsBloomEffect::blurHintChanged(Qt::RenderHint hint)
-
- This signal is emitted whenever the effect's blur hint changes.
- The \a hint parameter holds the effect's new blur hint.
-*/
-
-/*!
- \property QGraphicsBloomEffect::brightness
- \brief the brightness of the glow.
-
- The value should be in the range of 0 to 255, where 0 is dark
- and 255 is bright.
-
- By default, the brightness is 70.
-
- \sa strength(), blurRadius()
-*/
-int QGraphicsBloomEffect::brightness() const
-{
- Q_D(const QGraphicsBloomEffect);
- return d->brightness;
-}
-
-void QGraphicsBloomEffect::setBrightness(int brightness)
-{
- Q_D(QGraphicsBloomEffect);
- brightness = qBound(0, brightness, 255);
- if (d->brightness == brightness)
- return;
-
- d->brightness = brightness;
- for (int i = 0; i < 256; ++i)
- d->colorTable[i] = qMin(i + brightness, 255);
-
- update();
- emit brightnessChanged(brightness);
-}
-
-/*!
- \fn void QGraphicsBloomEffect::brightnessChanged(int brightness)
-
- This signal is emitted whenever the effect's brightness changes.
- The \a brightness parameter holds the effect's new brightness.
-*/
-
-/*!
- \property QGraphicsBloomEffect::strength
- \brief the strength of the effect.
-
- A strength 0.0 equals to no effect, while 1.0 means maximum glow.
-
- By default, the strength is 0.7.
-*/
-qreal QGraphicsBloomEffect::strength() const
-{
- Q_D(const QGraphicsBloomEffect);
- return d->strength;
-}
-
-void QGraphicsBloomEffect::setStrength(qreal strength)
-{
- Q_D(QGraphicsBloomEffect);
- strength = qBound(qreal(0.0), strength, qreal(1.0));
- if (qFuzzyCompare(d->strength, strength))
- return;
+ if (system == Qt::DeviceCoordinates)
+ painter->setWorldTransform(QTransform());
- d->strength = strength;
- update();
- emit strengthChanged(strength);
+ painter->drawPixmap(offset, pixmap);
+ painter->restore();
}
-/*!
- \fn void QGraphicsBloomEffect::strengthChanged(qreal strength)
-
- This signal is emitted whenever the effect's strength changes.
- The \a strength parameter holds the effect's new strength.
-*/
-
-/*!
- \reimp
-*/
-void QGraphicsBloomEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
-{
- Q_D(QGraphicsBloomEffect);
- if (d->strength < 0.001) {
- source->draw(painter);
- return;
- }
-
- const Qt::CoordinateSystem system = source->isPixmap()
- ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
- QPoint offset;
- QPixmap pixmap = source->pixmap(system, &offset);
- QImage result = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
-
- // Blur.
- QPainter blurPainter(&pixmap);
- d->blurFilter.draw(&blurPainter, QPointF(), pixmap);
- blurPainter.end();
-
- // Brighten.
- QImage overlay = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
- const int numBits = overlay.width() * overlay.height();
- QRgb *bits = reinterpret_cast<QRgb *>(overlay.bits());
- for (int i = 0; i < numBits; ++i) {
- const QRgb bit = bits[i];
- bits[i] = qRgba(d->colorTable[qRed(bit)], d->colorTable[qGreen(bit)],
- d->colorTable[qBlue(bit)], qAlpha(bit));
- }
-
- // Composite.
- QPainter compPainter(&result);
- compPainter.setCompositionMode(QPainter::CompositionMode_Overlay);
- compPainter.setOpacity(d->strength);
- compPainter.drawImage(0, 0, overlay);
- compPainter.end();
-
- if (system == Qt::DeviceCoordinates) {
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
- painter->drawImage(offset, result);
- painter->setWorldTransform(restoreTransform);
- } else {
- painter->drawImage(offset, result);
- }
-}
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h
index c5d3ede89c..2257f01383 100644
--- a/src/gui/effects/qgraphicseffect.h
+++ b/src/gui/effects/qgraphicseffect.h
@@ -48,6 +48,7 @@
#include <QtGui/qcolor.h>
#include <QtGui/qbrush.h>
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -59,37 +60,7 @@ class QStyleOption;
class QPainter;
class QPixmap;
-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) 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 QWidget;
- friend class QWidgetPrivate;
-};
+class QGraphicsEffectSource;
class QGraphicsEffectPrivate;
class Q_GUI_EXPORT QGraphicsEffect : public QObject
@@ -106,14 +77,18 @@ public:
};
Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
+ enum PixmapPadMode {
+ NoPad,
+ PadToTransparentBorder,
+ PadToEffectiveBoundingRect
+ };
+
QGraphicsEffect(QObject *parent = 0);
virtual ~QGraphicsEffect();
- virtual QRectF boundingRectFor(const QRectF &rect) const;
+ virtual QRectF boundingRectFor(const QRectF &sourceRect) const;
QRectF boundingRect() const;
- QGraphicsEffectSource *source() const;
-
bool isEnabled() const;
public Q_SLOTS:
@@ -125,10 +100,17 @@ Q_SIGNALS:
protected:
QGraphicsEffect(QGraphicsEffectPrivate &d, QObject *parent = 0);
- virtual void draw(QPainter *painter, QGraphicsEffectSource *source) = 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)
@@ -137,33 +119,12 @@ private:
friend class QGraphicsScenePrivate;
friend class QWidget;
friend class QWidgetPrivate;
-};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsEffect::ChangeFlags)
-class QGraphicsGrayscaleEffectPrivate;
-class Q_GUI_EXPORT QGraphicsGrayscaleEffect: public QGraphicsEffect
-{
- Q_OBJECT
- Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
public:
- QGraphicsGrayscaleEffect(QObject *parent = 0);
- ~QGraphicsGrayscaleEffect();
+ QGraphicsEffectSource *source() const; // internal
- qreal strength() const;
-
-protected:
- void draw(QPainter *painter, QGraphicsEffectSource *source);
-
-public Q_SLOTS:
- void setStrength(qreal strength);
-
-Q_SIGNALS:
- void strengthChanged(qreal strength);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsGrayscaleEffect)
- Q_DISABLE_COPY(QGraphicsGrayscaleEffect)
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsEffect::ChangeFlags)
class QGraphicsColorizeEffectPrivate;
class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect
@@ -187,68 +148,53 @@ Q_SIGNALS:
void strengthChanged(qreal strength);
protected:
- void draw(QPainter *painter, QGraphicsEffectSource *source);
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsColorizeEffect)
Q_DISABLE_COPY(QGraphicsColorizeEffect)
};
-class QGraphicsPixelizeEffectPrivate;
-class Q_GUI_EXPORT QGraphicsPixelizeEffect: public QGraphicsEffect
-{
- Q_OBJECT
- Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize NOTIFY pixelSizeChanged)
-public:
- QGraphicsPixelizeEffect(QObject *parent = 0);
- ~QGraphicsPixelizeEffect();
-
- int pixelSize() const;
-
-public Q_SLOTS:
- void setPixelSize(int pixelSize);
-
-Q_SIGNALS:
- void pixelSizeChanged(int pixelSize);
-
-protected:
- void draw(QPainter *painter, QGraphicsEffectSource *source);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsPixelizeEffect)
- Q_DISABLE_COPY(QGraphicsPixelizeEffect)
-};
-
class QGraphicsBlurEffectPrivate;
class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect
{
Q_OBJECT
- Q_PROPERTY(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
- Q_PROPERTY(Qt::RenderHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged)
+ 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;
- int blurRadius() const;
- Qt::RenderHint blurHint() const;
+ qreal blurRadius() const;
+ BlurHints blurHints() const;
public Q_SLOTS:
- void setBlurRadius(int blurRadius);
- void setBlurHint(Qt::RenderHint hint);
+ void setBlurRadius(qreal blurRadius);
+ void setBlurHints(BlurHints hints);
Q_SIGNALS:
- void blurRadiusChanged(int blurRadius);
- void blurHintChanged(Qt::RenderHint hint);
+ void blurRadiusChanged(qreal blurRadius);
+ void blurHintsChanged(BlurHints hints);
protected:
- void draw(QPainter *painter, QGraphicsEffectSource *source);
+ 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
{
@@ -256,7 +202,7 @@ class Q_GUI_EXPORT QGraphicsDropShadowEffect: public QGraphicsEffect
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(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
+ 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);
@@ -271,7 +217,7 @@ public:
inline qreal yOffset() const
{ return offset().y(); }
- int blurRadius() const;
+ qreal blurRadius() const;
QColor color() const;
public Q_SLOTS:
@@ -289,16 +235,16 @@ public Q_SLOTS:
inline void setYOffset(qreal dy)
{ setOffset(QPointF(xOffset(), dy)); }
- void setBlurRadius(int blurRadius);
+ void setBlurRadius(qreal blurRadius);
void setColor(const QColor &color);
Q_SIGNALS:
void offsetChanged(const QPointF &offset);
- void blurRadiusChanged(int blurRadius);
+ void blurRadiusChanged(qreal blurRadius);
void colorChanged(const QColor &color);
protected:
- void draw(QPainter *painter, QGraphicsEffectSource *source);
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsDropShadowEffect)
@@ -327,54 +273,17 @@ Q_SIGNALS:
void opacityMaskChanged(const QBrush &mask);
protected:
- void draw(QPainter *painter, QGraphicsEffectSource *source);
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsOpacityEffect)
Q_DISABLE_COPY(QGraphicsOpacityEffect)
};
-class QGraphicsBloomEffectPrivate;
-class Q_GUI_EXPORT QGraphicsBloomEffect: public QGraphicsEffect
-{
- Q_OBJECT
- Q_PROPERTY(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
- Q_PROPERTY(Qt::RenderHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged)
- Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
- Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
-public:
- QGraphicsBloomEffect(QObject *parent = 0);
- ~QGraphicsBloomEffect();
-
- QRectF boundingRectFor(const QRectF &rect) const;
- int blurRadius() const;
- Qt::RenderHint blurHint() const;
- int brightness() const;
- qreal strength() const;
-
-public Q_SLOTS:
- void setBlurRadius(int blurRadius);
- void setBlurHint(Qt::RenderHint hint);
- void setBrightness(int brightness);
- void setStrength(qreal strength);
-
-Q_SIGNALS:
- void blurRadiusChanged(int blurRadius);
- void blurHintChanged(Qt::RenderHint hint);
- void brightnessChanged(int brightness);
- void strengthChanged(qreal strength);
-
-protected:
- void draw(QPainter *painter, QGraphicsEffectSource *source);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsBloomEffect)
- Q_DISABLE_COPY(QGraphicsBloomEffect)
-};
-
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
index ff2fb8570e..0011eef5e3 100644
--- a/src/gui/effects/qgraphicseffect_p.h
+++ b/src/gui/effects/qgraphicseffect_p.h
@@ -55,17 +55,60 @@
#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() {}
- virtual ~QGraphicsEffectSourcePrivate() {}
+ QGraphicsEffectSourcePrivate()
+ : QObjectPrivate()
+ , m_cachedSystem(Qt::DeviceCoordinates)
+ , m_cachedMode(QGraphicsEffect::PadToTransparentBorder)
+ {}
+
+ virtual ~QGraphicsEffectSourcePrivate();
virtual void detach() = 0;
virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
virtual QRect deviceRect() const = 0;
@@ -75,11 +118,20 @@ public:
virtual void draw(QPainter *p) = 0;
virtual void update() = 0;
virtual bool isPixmap() const = 0;
- virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0) const = 0;
+ virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0,
+ QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0;
virtual void effectBoundingRectChanged() = 0;
+ void invalidateCache(bool effectRectChanged = false) const;
+
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
@@ -93,6 +145,7 @@ public:
QGraphicsEffect::ChangeFlags flags;
if (source) {
flags |= QGraphicsEffect::SourceDetached;
+ source->d_func()->invalidateCache();
source->d_func()->detach();
delete source;
}
@@ -108,22 +161,6 @@ public:
quint32 padding : 31; // feel free to use
};
-class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsGrayscaleEffect)
-public:
- QGraphicsGrayscaleEffectPrivate()
- : opaque(true)
- {
- filter = new QPixmapColorizeFilter;
- filter->setColor(Qt::black);
- }
- ~QGraphicsGrayscaleEffectPrivate() { delete filter; }
-
- QPixmapColorizeFilter *filter;
- quint32 opaque : 1;
- quint32 padding : 31;
-};
class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate
{
@@ -141,15 +178,6 @@ public:
quint32 padding : 31;
};
-class QGraphicsPixelizeEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsPixelizeEffect)
-public:
- QGraphicsPixelizeEffectPrivate() : pixelSize(3) {}
-
- int pixelSize;
-};
-
class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
@@ -185,19 +213,8 @@ public:
uint hasOpacityMask : 1;
};
-class QGraphicsBloomEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
-public:
- QGraphicsBloomEffectPrivate() : brightness(70), strength(qreal(0.7)) {}
-
- QPixmapBlurFilter blurFilter;
- int colorTable[256];
- int brightness;
- qreal strength;
-};
-
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 7edd47df8b..d681004334 100644
--- a/src/gui/egl/egl.pri
+++ b/src/gui/egl/egl.pri
@@ -1,3 +1,5 @@
+CONFIG += egl
+
HEADERS += \
egl/qegl_p.h \
egl/qeglproperties_p.h
@@ -6,7 +8,7 @@ SOURCES += \
egl/qegl.cpp \
egl/qeglproperties.cpp
-contains(QT_CONFIG, wince*): SOURCES += egl/qegl_wince.cpp
+wince*: SOURCES += egl/qegl_wince.cpp
unix {
embedded {
@@ -23,11 +25,3 @@ unix {
}
}
}
-
-for(p, QMAKE_LIBDIR_EGL) {
- exists($$p):LIBS_PRIVATE += -L$$p
-}
-
-!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
-!isEmpty(QMAKE_LIBS_EGL): LIBS_PRIVATE += $$QMAKE_LIBS_EGL
-!isEmpty(QMAKE_LFLAGS_EGL): LIBS += $$QMAKE_LFLAGS_EGL
diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp
index 840b9d6918..c0e48903ac 100644
--- a/src/gui/egl/qegl.cpp
+++ b/src/gui/egl/qegl.cpp
@@ -61,6 +61,8 @@ QEglContext::QEglContext()
, cfg(0)
, currentSurface(EGL_NO_SURFACE)
, current(false)
+ , ownsContext(true)
+ , sharing(false)
{
}
@@ -173,6 +175,7 @@ bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties
if (apiType == QEgl::OpenGL)
contextProps.setValue(EGL_CONTEXT_CLIENT_VERSION, 2);
#endif
+ sharing = false;
if (shareContext && shareContext->ctx == EGL_NO_CONTEXT)
shareContext = 0;
if (shareContext) {
@@ -180,6 +183,8 @@ bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties
if (ctx == EGL_NO_CONTEXT) {
qWarning() << "QEglContext::createContext(): Could not share context:" << errorString(eglGetError());
shareContext = 0;
+ } else {
+ sharing = true;
}
}
if (ctx == EGL_NO_CONTEXT) {
@@ -206,7 +211,7 @@ void QEglContext::destroySurface(EGLSurface surface)
// Destroy the context. Note: this does not destroy the surface.
void QEglContext::destroy()
{
- if (ctx != EGL_NO_CONTEXT)
+ if (ctx != EGL_NO_CONTEXT && ownsContext)
eglDestroyContext(dpy, ctx);
dpy = EGL_NO_DISPLAY;
ctx = EGL_NO_CONTEXT;
diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h
index dc399daa8e..51bdbbe128 100644
--- a/src/gui/egl/qegl_p.h
+++ b/src/gui/egl/qegl_p.h
@@ -81,6 +81,7 @@ public:
bool isValid() const;
bool isCurrent() const;
+ bool isSharing() const { return sharing; }
QEgl::API api() const { return apiType; }
void setApi(QEgl::API api) { apiType = api; }
@@ -110,7 +111,7 @@ public:
EGLDisplay display() const { return dpy; }
EGLContext context() const { return ctx; }
- void setContext(EGLContext context) { ctx = context; }
+ void setContext(EGLContext context) { ctx = context; ownsContext = false;}
EGLConfig config() const { return cfg; }
void setConfig(EGLConfig config) { cfg = config; }
@@ -131,6 +132,8 @@ private:
EGLConfig cfg;
EGLSurface currentSurface;
bool current;
+ bool ownsContext;
+ bool sharing;
static EGLDisplay getDisplay(QPaintDevice *device);
diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp
index 590b6660b3..df1179aac5 100644
--- a/src/gui/egl/qegl_qws.cpp
+++ b/src/gui/egl/qegl_qws.cpp
@@ -83,7 +83,8 @@ static QScreen *screenForDevice(QPaintDevice *device)
screenNumber = 0;
screen = screen->subScreens()[screenNumber];
}
- while (screen->classId() == QScreen::ProxyClass) {
+ while (screen->classId() == QScreen::ProxyClass ||
+ screen->classId() == QScreen::TransformedClass) {
screen = static_cast<QProxyScreen *>(screen)->screen();
}
return screen;
diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp
index c61e1d3c36..2d37edb6fb 100644
--- a/src/gui/egl/qeglproperties.cpp
+++ b/src/gui/egl/qeglproperties.cpp
@@ -88,8 +88,12 @@ int QEglProperties::value(int name) const
#if defined(EGL_ALPHA_MASK_SIZE)
case EGL_ALPHA_MASK_SIZE: return 0;
#endif
+#if defined(EGL_BIND_TO_TEXTURE_RGB)
case EGL_BIND_TO_TEXTURE_RGB: return EGL_DONT_CARE;
+#endif
+#if defined(EGL_BIND_TO_TEXTURE_RGBA)
case EGL_BIND_TO_TEXTURE_RGBA: return EGL_DONT_CARE;
+#endif
#if defined(EGL_COLOR_BUFFER_TYPE)
case EGL_COLOR_BUFFER_TYPE: return EGL_RGB_BUFFER;
#endif
diff --git a/src/gui/embedded/directfb.pri b/src/gui/embedded/directfb.pri
index fa4dd682dc..84253b5683 100644
--- a/src/gui/embedded/directfb.pri
+++ b/src/gui/embedded/directfb.pri
@@ -1,7 +1,7 @@
# These defines might be necessary if your DirectFB driver doesn't
# support all of the DirectFB API.
#
-#DEFINES += QT_NO_DIRECTFB_SUBSURFACE
+#DEFINES += QT_DIRECTFB_SUBSURFACE
#DEFINES += QT_DIRECTFB_WINDOW_AS_CURSOR
#DEFINES += QT_NO_DIRECTFB_IMAGEPROVIDER
#DEFINES += QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
diff --git a/src/gui/embedded/qdecorationdefault_qws.cpp b/src/gui/embedded/qdecorationdefault_qws.cpp
index 5bc8826179..70389d3786 100644
--- a/src/gui/embedded/qdecorationdefault_qws.cpp
+++ b/src/gui/embedded/qdecorationdefault_qws.cpp
@@ -394,7 +394,7 @@ QPixmap QDecorationDefault::pixmapFor(const QWidget *widget,
*/
int QDecorationDefault::titleBarHeight(const QWidget *)
{
- return qMax(20, QApplication::fontMetrics().lineSpacing() + BORDER_WIDTH);
+ return qMax(20, QApplication::fontMetrics().height() + BORDER_WIDTH);
}
/*!
diff --git a/src/gui/embedded/qdecorationwindows_qws.cpp b/src/gui/embedded/qdecorationwindows_qws.cpp
index 77393cf837..7764ca5eae 100644
--- a/src/gui/embedded/qdecorationwindows_qws.cpp
+++ b/src/gui/embedded/qdecorationwindows_qws.cpp
@@ -216,7 +216,7 @@ QRegion QDecorationWindows::region(const QWidget *widget, const QRect &rect, int
bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
const QFontMetrics fontMetrics = QApplication::fontMetrics();
- int titleHeight = hasTitle ? qMax(20, fontMetrics.lineSpacing()) : 0;
+ int titleHeight = hasTitle ? qMax(20, fontMetrics.height()) : 0;
int state = widget->windowState();
bool isMinimized = state & Qt::WindowMinimized;
bool isMaximized = state & Qt::WindowMaximized;
diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp
index 911a77e43b..ae5570febc 100644
--- a/src/gui/embedded/qscreen_qws.cpp
+++ b/src/gui/embedded/qscreen_qws.cpp
@@ -600,7 +600,7 @@ static void blit_template(QScreen *screen, const QImage &image,
const int screenStride = screen->linestep();
const int imageStride = image.bytesPerLine();
- if (region.numRects() == 1) {
+ if (region.rectCount() == 1) {
const QRect r = region.boundingRect();
const SRC *src = reinterpret_cast<const SRC*>(image.scanLine(r.y()))
+ r.x();
@@ -1385,7 +1385,7 @@ QImage::Format QScreenPrivate::preferredImageFormat() const
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 numCols()
+ 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.
@@ -1998,12 +1998,20 @@ QImage::Format QScreenPrivate::preferredImageFormat() const
i.e. in modes where only the palette indexes (and not the actual
color values) are stored in memory.
- \sa alloc(), depth(), numCols()
+ \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.
@@ -2103,7 +2111,7 @@ void QScreen::setPixelFormat(QImage::Format format)
i.e. in modes where only the palette indexes (and not the actual
color values) are stored in memory.
- \sa clut(), numCols()
+ \sa clut(), colorCount()
*/
int QScreen::alloc(unsigned int r,unsigned int g,unsigned int b)
@@ -2455,7 +2463,7 @@ void QScreen::exposeRegion(QRegion r, int windowIndex)
delete blendBuffer;
}
- if (r.numRects() == 1) {
+ if (r.rectCount() == 1) {
setDirty(r.boundingRect());
} else {
const QVector<QRect> rects = r.rects();
diff --git a/src/gui/embedded/qscreen_qws.h b/src/gui/embedded/qscreen_qws.h
index d20d7099e6..b3246f9edc 100644
--- a/src/gui/embedded/qscreen_qws.h
+++ b/src/gui/embedded/qscreen_qws.h
@@ -243,7 +243,8 @@ public:
int totalSize() const { return mapsize; }
QRgb * clut() { return screenclut; }
- int numCols() { return screencols; }
+ QT_DEPRECATED int numCols() { return screencols; }
+ int colorCount() { return screencols; }
virtual QSize mapToDevice(const QSize &) const;
virtual QSize mapFromDevice(const QSize &) const;
diff --git a/src/gui/embedded/qwscursor_qws.cpp b/src/gui/embedded/qwscursor_qws.cpp
index 07271e1d55..7d5a3d1cd7 100644
--- a/src/gui/embedded/qwscursor_qws.cpp
+++ b/src/gui/embedded/qwscursor_qws.cpp
@@ -534,7 +534,7 @@ void QWSCursor::set(const uchar *data, const uchar *mask,
if (!width || !height || !data || !mask || cursor.isNull())
return;
- cursor.setNumColors(3);
+ cursor.setColorCount(3);
cursor.setColor(0, 0xff000000);
cursor.setColor(1, 0xffffffff);
cursor.setColor(2, 0x00000000);
diff --git a/src/gui/graphicsview/qgraph_p.h b/src/gui/graphicsview/qgraph_p.h
index f1fa185fa7..0a2bf27fb0 100644
--- a/src/gui/graphicsview/qgraph_p.h
+++ b/src/gui/graphicsview/qgraph_p.h
@@ -201,11 +201,6 @@ public:
return l;
}
- void setRootVertex(Vertex *vertex)
- {
- userVertex = vertex;
- }
-
QSet<Vertex*> vertices() const {
QSet<Vertex *> setOfVertices;
for (const_iterator it = constBegin(); it != constEnd(); ++it) {
@@ -241,7 +236,7 @@ public:
EdgeData *data = edgeData(v, v1);
bool forward = data->from == v;
if (forward) {
- edges += QString::fromAscii("%1->%2 [label=\"[%3,%4,%5]\" dir=both color=\"#000000:#a0a0a0\"] \n")
+ edges += QString::fromAscii("\"%1\"->\"%2\" [label=\"[%3,%4,%5]\" dir=both color=\"#000000:#a0a0a0\"] \n")
.arg(v->toString())
.arg(v1->toString())
.arg(data->minSize)
@@ -250,17 +245,12 @@ public:
;
}
}
- strVertices += QString::fromAscii("%1 [label=\"%2\"]\n").arg(v->toString()).arg(v->toString());
+ strVertices += QString::fromAscii("\"%1\" [label=\"%2\"]\n").arg(v->toString()).arg(v->toString());
}
return QString::fromAscii("%1\n%2\n").arg(strVertices).arg(edges);
}
#endif
- Vertex *rootVertex() const
- {
- return userVertex;
- }
-
protected:
void createDirectedEdge(Vertex *from, Vertex *to, EdgeData *data)
{
@@ -286,8 +276,6 @@ protected:
}
private:
- Vertex *userVertex;
-
QHash<Vertex *, QHash<Vertex *, EdgeData *> *> m_graph;
};
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index ffbb67cf1f..7e5929e7b7 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -48,36 +48,73 @@
\ingroup geomanagement
\ingroup graphicsview-api
- The anchor layout is a layout where one can specify how widgets should be placed relative to
- each other. The specification is called an anchor, and it is set up by calling anchor().
+ The anchor layout allows developers to specify how widgets should be placed relative to
+ each other, and to the layout itself. The specification is made by adding anchors to the
+ layout by calling addAnchor(), addAnchors() or addCornerAnchors().
+
+ Existing anchors in the layout can be accessed with the anchor() function.
+ Items that are anchored are automatically added to the layout, and if items
+ are removed, all their anchors will be automatically removed.
+
+ \beginfloatleft
+ \inlineimage simpleanchorlayout-example.png Using an anchor layout to align simple colored widgets.
+ \endfloat
+
Anchors are always set up between edges of an item, where the "center" is also considered to
- be an edge. Considering this example:
- \code
- QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
- QGraphicsWidget *a = new QGraphicsWidget;
- QGraphicsWidget *b = new QGraphicsWidget;
- l->anchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
- \endcode
-
- Here is the right edge of item A anchored to the left edge of item B, with the result that
- item B will be placed to the right of item A, with a spacing between A and B. If the
- spacing is negative, the items will overlap to some extent. Items that are anchored are
- automatically added to the layout, and if items are removed, all their anchors will be
- automatically removed
-
- \section1 Size Hints and Size Policies in QGraphicsAnchorLayout
-
- QGraphicsAnchorLayout respects each item's size hints and size policies. However it does
- not respect stretch factors currently. This might change in the future, so please refrain
- from using stretch factors in anchor layout to avoid any future regressions.
-
- \section1 Spacing within QGraphicsAnchorLayout
-
- Between the items, the layout can distribute some space. If the spacing has not been
- explicitly specified, the actual amount of space will usually be 0, but if the first edge
- is the "opposite" of the second edge (i.e. Right is anchored to Left or vice-versa), the
- size of the anchor will be queried from the style through the pixelMetric
- PM_LayoutHorizontalSpacing (or PM_LayoutVerticalSpacing for vertical anchors).
+ be an edge. Consider the following example:
+
+ \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors
+
+ Here, the right edge of item \c a is anchored to the left edge of item \c b and the bottom
+ edge of item \c a is anchored to the top edge of item \c b, with the result that
+ item \c b will be placed diagonally to the right and below item \c b.
+
+ The addCornerAnchors() function provides a simpler way of anchoring the corners
+ of two widgets than the two individual calls to addAnchor() shown in the code
+ above. Here, we see how a widget can be anchored to the top-left corner of the enclosing
+ layout:
+
+ \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor
+
+ In cases where anchors are used to match the widths or heights of widgets, it is
+ convenient to use the addAnchors() function. As with the other functions for specifying
+ anchors, it can also be used to anchor a widget to a layout.
+
+ \clearfloat
+ \section1 Size Hints and Size Policies in an Anchor Layout
+
+ QGraphicsAnchorLayout respects each item's size hints and size policies.
+ Note that there are some properties of QSizePolicy that are \l{Known issues}{not respected}.
+
+ \section1 Spacing within an Anchor Layout
+
+ The layout may distribute some space between the items. If the spacing has not been
+ explicitly specified, the actual amount of space will usually be 0.
+
+ However, if the first edge is the \e opposite of the second edge (e.g., the right edge
+ of the first widget is anchored to the left edge of the second widget), the size of the
+ anchor will be queried from the style through a pixel metric:
+ \l{QStyle::}{PM_LayoutHorizontalSpacing} for horizontal anchors and
+ \l{QStyle::}{PM_LayoutVerticalSpacing} for vertical anchors.
+
+ If the spacing is negative, the items will overlap to some extent.
+
+
+ \section1 Known issues
+ There are some features that QGraphicsAnchorLayout currently does not support.
+ This might change in the future, so avoid using these features if you want to
+ avoid any future regressions in behaviour:
+ \list
+
+ \o Stretch factors are not respected.
+
+ \o QSizePolicy::ExpandFlag is not respected.
+
+ \o Height for width is not respected.
+
+ \endlist
+
+ \sa QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayout
*/
/*!
@@ -99,7 +136,7 @@
*/
#include "qgraphicsanchorlayout_p.h"
-
+#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
QGraphicsAnchor::QGraphicsAnchor(QGraphicsAnchorLayout *parentLayout)
@@ -118,13 +155,40 @@ QGraphicsAnchor::~QGraphicsAnchor()
}
/*!
+ \property QGraphicsAnchor::sizePolicy
+ \brief the size policy for the QGraphicsAnchor.
+
+ By setting the size policy on an anchor you can configure how the item can resize itself
+ from its preferred spacing. For instance, if the anchor has the size policy
+ QSizePolicy::Minimum, the spacing is the minimum size of the anchor. However, its size
+ can grow up to the anchors maximum size. If the default size policy is QSizePolicy::Fixed,
+ the anchor can neither grow or shrink, which means that the only size the anchor can have
+ is the spacing. QSizePolicy::Fixed is the default size policy.
+ QGraphicsAnchor always has a minimum spacing of 0 and a very large maximum spacing.
+
+ \sa QGraphicsAnchor::spacing
+*/
+
+void QGraphicsAnchor::setSizePolicy(QSizePolicy::Policy policy)
+{
+ Q_D(QGraphicsAnchor);
+ d->setSizePolicy(policy);
+}
+
+QSizePolicy::Policy QGraphicsAnchor::sizePolicy() const
+{
+ Q_D(const QGraphicsAnchor);
+ return d->sizePolicy;
+}
+
+/*!
\property QGraphicsAnchor::spacing
- \brief the space between items in the QGraphicsAnchorLayout.
+ \brief the preferred space between items in the QGraphicsAnchorLayout.
Depending on the anchor type, the default spacing is either
0 or a value returned from the style.
- \sa QGraphicsAnchorLayout::anchor()
+ \sa QGraphicsAnchorLayout::addAnchor()
*/
void QGraphicsAnchor::setSpacing(qreal spacing)
{
@@ -188,7 +252,7 @@ QGraphicsAnchorLayout::~QGraphicsAnchorLayout()
If there is already an anchor between the edges, the the new anchor will replace the old one.
\a firstItem and \a secondItem are automatically added to the layout if they are not part
- of the layout. This means that count() can increase with up to 2.
+ of the layout. This means that count() can increase by up to 2.
The spacing an anchor will get depends on the type of anchor. For instance, anchors from the
Right edge of one item to the Left edge of another (or vice versa) will use the default
@@ -198,7 +262,10 @@ QGraphicsAnchorLayout::~QGraphicsAnchorLayout()
The spacing can also be set manually by using QGraphicsAnchor::setSpacing() method.
- \sa addCornerAnchors(), addAnchors()
+ Calling this function where \a firstItem or \a secondItem are ancestors of the layout have
+ undefined behaviour.
+
+ \sa addAnchors(), addCornerAnchors()
*/
QGraphicsAnchor *
QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
@@ -223,29 +290,26 @@ QGraphicsAnchorLayout::anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint fi
}
/*!
- Creates two anchors between \a firstItem and \a secondItem, where one is for the horizontal
- edge and another one for the vertical edge that the corners \a firstCorner and \a
- secondCorner specifies.
- The magnitude of the anchors is picked up from the style.
+ Creates two anchors between \a firstItem and \a secondItem specified by the corners,
+ \a firstCorner and \a secondCorner, where one is for the horizontal edge and another
+ one for the vertical edge.
+
+ This is a convenience function, since anchoring corners can be expressed as anchoring
+ two edges. For instance:
- This is a convenience function, since anchoring corners can be expressed as anchoring two edges.
- For instance,
- \code
- layout->addAnchor(layout, Qt::AnchorTop, b, Qt::AnchorTop);
- layout->addAnchor(layout, Qt::AnchorLeft, b, Qt::AnchorLeft);
- \endcode
+ \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor in two steps
- has the same effect as
+ This can also be achieved with the following line of code:
- \code
- layout->addCornerAnchors(layout, Qt::TopLeft, b, Qt::TopLeft);
- \endcode
+ \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor
If there is already an anchor between the edge pairs, it will be replaced by the anchors that
this function specifies.
\a firstItem and \a secondItem are automatically added to the layout if they are not part of the
- layout. This means that count() can increase with up to 2.
+ layout. This means that count() can increase by up to 2.
+
+ \sa addAnchor(), addAnchors()
*/
void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
Qt::Corner firstCorner,
@@ -272,17 +336,16 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
edges of \a secondItem, so that \a firstItem has the same size as
\a secondItem in the dimensions specified by \a orientations.
- Calling this convenience function with the following arguments
- \code
- l->addAnchors(firstItem, secondItem, Qt::Horizontal)
- \endcode
+ For example, the following example anchors the left and right edges of two items
+ to match their widths:
+
+ \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors to match sizes in two steps
+
+ This can also be achieved using the following line of code:
- is the same as
+ \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors to match sizes
- \code
- l->addAnchor(firstItem, Qt::AnchorLeft, secondItem, Qt::AnchorLeft);
- l->addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight);
- \endcode
+ \sa addAnchor(), addCornerAnchors()
*/
void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem,
QGraphicsLayoutItem *secondItem,
@@ -306,6 +369,13 @@ void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem,
void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing)
{
Q_D(QGraphicsAnchorLayout);
+
+ // ### We don't support negative spacing yet
+ if (spacing < 0) {
+ spacing = 0;
+ qWarning() << "QGraphicsAnchorLayout does not support negative spacing.";
+ }
+
d->spacings[0] = spacing;
invalidate();
}
@@ -318,6 +388,13 @@ void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing)
void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing)
{
Q_D(QGraphicsAnchorLayout);
+
+ // ### We don't support negative spacing yet
+ if (spacing < 0) {
+ spacing = 0;
+ qWarning() << "QGraphicsAnchorLayout does not support negative spacing.";
+ }
+
d->spacings[1] = spacing;
invalidate();
}
@@ -327,11 +404,23 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing)
If an item is anchored with no spacing associated with the anchor, it will use the default
spacing.
+
+ Currently QGraphicsAnchorLayout does not support negative default spacings.
+
\sa setHorizontalSpacing(), setVerticalSpacing()
*/
void QGraphicsAnchorLayout::setSpacing(qreal spacing)
{
Q_D(QGraphicsAnchorLayout);
+
+ // ### Currently we do not support negative anchors inside the graph.
+ // To avoid those being created by a negative spacing, we must
+ // make this test.
+ if (spacing < 0) {
+ spacing = 0;
+ qWarning() << "QGraphicsAnchorLayout does not support negative spacing.";
+ }
+
d->spacings[0] = d->spacings[1] = spacing;
invalidate();
}
@@ -344,7 +433,7 @@ void QGraphicsAnchorLayout::setSpacing(qreal spacing)
qreal QGraphicsAnchorLayout::horizontalSpacing() const
{
Q_D(const QGraphicsAnchorLayout);
- return d->effectiveSpacing(QGraphicsAnchorLayoutPrivate::Horizontal);
+ return d->styleInfo().defaultSpacing(Qt::Horizontal);
}
/*!
@@ -355,7 +444,7 @@ qreal QGraphicsAnchorLayout::horizontalSpacing() const
qreal QGraphicsAnchorLayout::verticalSpacing() const
{
Q_D(const QGraphicsAnchorLayout);
- return d->effectiveSpacing(QGraphicsAnchorLayoutPrivate::Vertical);
+ return d->styleInfo().defaultSpacing(Qt::Vertical);
}
/*!
@@ -388,9 +477,6 @@ void QGraphicsAnchorLayout::removeAt(int index)
return;
// Removing an item affects both horizontal and vertical graphs
- d->restoreSimplifiedGraph(QGraphicsAnchorLayoutPrivate::Horizontal);
- d->restoreSimplifiedGraph(QGraphicsAnchorLayoutPrivate::Vertical);
-
d->removeCenterConstraints(item, QGraphicsAnchorLayoutPrivate::Horizontal);
d->removeCenterConstraints(item, QGraphicsAnchorLayoutPrivate::Vertical);
d->removeAnchors(item);
@@ -425,7 +511,8 @@ void QGraphicsAnchorLayout::invalidate()
{
Q_D(QGraphicsAnchorLayout);
QGraphicsLayout::invalidate();
- d->calculateGraphCacheDirty = 1;
+ d->calculateGraphCacheDirty = true;
+ d->styleInfoDirty = true;
}
/*!
@@ -459,3 +546,4 @@ QSizeF QGraphicsAnchorLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra
}
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h
index 99dbf9237b..063639e23d 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.h
@@ -62,10 +62,13 @@ 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);
@@ -73,6 +76,7 @@ private:
Q_DECLARE_PRIVATE(QGraphicsAnchor)
friend class QGraphicsAnchorLayoutPrivate;
+ friend struct AnchorData;
};
class Q_GUI_EXPORT QGraphicsAnchorLayout : public QGraphicsLayout
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
index f9b5c8cd2c..fb6727815e 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <QtGui/qwidget.h>
+#include <QtGui/qapplication.h>
#include <QtCore/qlinkedlist.h>
#include <QtCore/qstack.h>
@@ -48,12 +49,14 @@
#endif
#include "qgraphicsanchorlayout_p.h"
-
+#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
- : QObjectPrivate(version), layoutPrivate(0), data(0)
+ : QObjectPrivate(version), layoutPrivate(0), data(0),
+ sizePolicy(QSizePolicy::Fixed), preferredSize(0),
+ hasSize(true), reversed(false)
{
}
@@ -62,58 +65,78 @@ QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate()
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) {
- layoutPrivate->setAnchorSize(data, &value);
- } else {
+ if (!data) {
qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
+ return;
+ }
+
+ const qreal rawValue = reversed ? -preferredSize : preferredSize;
+ if (hasSize && (rawValue == value))
+ return;
+
+ // The anchor has an user-defined size
+ hasSize = true;
+
+ // The simplex solver cannot handle negative sizes. To workaround that,
+ // if value is less than zero, we reverse the anchor and set the absolute
+ // value;
+ if (value >= 0) {
+ preferredSize = value;
+ if (reversed)
+ qSwap(data->from, data->to);
+ reversed = false;
+ } else {
+ preferredSize = -value;
+ if (!reversed)
+ qSwap(data->from, data->to);
+ reversed = true;
}
+
+ layoutPrivate->q_func()->invalidate();
}
void QGraphicsAnchorPrivate::unsetSpacing()
{
- if (data) {
- layoutPrivate->setAnchorSize(data, 0);
- } else {
+ if (!data) {
qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
+ return;
}
+
+ // Return to standard direction
+ hasSize = false;
+ if (reversed)
+ qSwap(data->from, data->to);
+ reversed = false;
+
+ layoutPrivate->q_func()->invalidate();
}
qreal QGraphicsAnchorPrivate::spacing() const
{
- qreal size = 0;
- if (data) {
- layoutPrivate->anchorSize(data, 0, &size, 0);
- } else {
+ if (!data) {
qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
+ return 0;
}
- return size;
+
+ return reversed ? -preferredSize : preferredSize;
}
-static void sizeHintsFromItem(QGraphicsLayoutItem *item,
- const QGraphicsAnchorLayoutPrivate::Orientation orient,
- qreal *minSize, qreal *prefSize,
- qreal *expSize, qreal *maxSize)
+static void internalSizeHints(QSizePolicy::Policy policy,
+ qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint,
+ qreal *minSize, qreal *prefSize,
+ qreal *maxSize)
{
- QSizePolicy::Policy policy;
- qreal minSizeHint;
- qreal prefSizeHint;
- qreal maxSizeHint;
-
- if (orient == 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();
- }
-
// minSize, prefSize and maxSize are initialized
// with item's preferred Size: this is QSizePolicy::Fixed.
//
@@ -139,52 +162,77 @@ static void sizeHintsFromItem(QGraphicsLayoutItem *item,
// Note that these two initializations are affected by the previous flags
if (policy & QSizePolicy::IgnoreFlag)
- *prefSize = *maxSize;
+ *prefSize = *minSize;
else
*prefSize = prefSizeHint;
-
- if (policy & QSizePolicy::ExpandFlag)
- *expSize = *maxSize;
- else
- *expSize = *prefSize;
}
-void AnchorData::refreshSizeHints(qreal effectiveSpacing)
+void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
{
- const bool isInternalAnchor = from->m_item == to->m_item;
-
- if (isInternalAnchor) {
- const QGraphicsAnchorLayoutPrivate::Orientation orient =
- QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge);
+ 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;
- expSize = 0;
maxSize = QWIDGETSIZE_MAX;
+ if (isCenterAnchor)
+ maxSize /= 2;
+ return;
} else {
- QGraphicsLayoutItem *item = from->m_item;
- sizeHintsFromItem(item, orient, &minSize, &prefSize, &expSize, &maxSize);
- }
-
- const Qt::AnchorPoint centerEdge =
- QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient);
- bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge);
+ 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 (hasCenter) {
- minSize /= 2;
- prefSize /= 2;
- expSize /= 2;
- maxSize /= 2;
+ if (isCenterAnchor) {
+ minSizeHint /= 2;
+ prefSizeHint /= 2;
+ maxSizeHint /= 2;
+ }
}
-
- } else if (!hasSize) {
- // Anchor has no size defined, use given default information
- minSize = effectiveSpacing;
- prefSize = effectiveSpacing;
- expSize = effectiveSpacing;
- maxSize = effectiveSpacing;
+ } else {
+ // It is a user-created anchor, fetch size information from the associated QGraphicsAnchor
+ Q_ASSERT(graphicsAnchor);
+ QGraphicsAnchorPrivate *anchorPrivate = graphicsAnchor->d_func();
+ policy = anchorPrivate->sizePolicy;
+ minSizeHint = 0;
+ if (anchorPrivate->hasSize) {
+ // One can only configure the preferred size of a normal anchor. Their minimum and
+ // maximum "size hints" are always 0 and QWIDGETSIZE_MAX, correspondingly. However,
+ // their effective size hints might be narrowed down due to their size policies.
+ prefSizeHint = anchorPrivate->preferredSize;
+ } else {
+ 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;
+ }
+ maxSizeHint = QWIDGETSIZE_MAX;
}
+ internalSizeHints(policy, minSizeHint, prefSizeHint, maxSizeHint,
+ &minSize, &prefSize, &maxSize);
// Set the anchor effective sizes to preferred.
//
@@ -195,52 +243,85 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing)
// recalculate and override the values we set here.
sizeAtMinimum = prefSize;
sizeAtPreferred = prefSize;
- sizeAtExpanding = prefSize;
sizeAtMaximum = prefSize;
}
void ParallelAnchorData::updateChildrenSizes()
{
- firstEdge->sizeAtMinimum = secondEdge->sizeAtMinimum = sizeAtMinimum;
- firstEdge->sizeAtPreferred = secondEdge->sizeAtPreferred = sizeAtPreferred;
- firstEdge->sizeAtExpanding = secondEdge->sizeAtExpanding = sizeAtExpanding;
- firstEdge->sizeAtMaximum = secondEdge->sizeAtMaximum = sizeAtMaximum;
+ firstEdge->sizeAtMinimum = sizeAtMinimum;
+ firstEdge->sizeAtPreferred = sizeAtPreferred;
+ firstEdge->sizeAtMaximum = sizeAtMaximum;
+
+ // We have the convention that the first children will define the direction of the
+ // pararell group. So we can check whether the second edge is "forward" in relation
+ // to the group if it have the same direction as the first edge. Note that we don't
+ // use 'this->from' because it might be changed by vertex simplification.
+ const bool secondForward = (firstEdge->from == secondEdge->from);
+
+ if (secondForward) {
+ secondEdge->sizeAtMinimum = sizeAtMinimum;
+ secondEdge->sizeAtPreferred = sizeAtPreferred;
+ secondEdge->sizeAtMaximum = sizeAtMaximum;
+ } else {
+ secondEdge->sizeAtMinimum = -sizeAtMinimum;
+ secondEdge->sizeAtPreferred = -sizeAtPreferred;
+ secondEdge->sizeAtMaximum = -sizeAtMaximum;
+ }
firstEdge->updateChildrenSizes();
secondEdge->updateChildrenSizes();
}
-void ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing)
+bool ParallelAnchorData::calculateSizeHints()
{
- refreshSizeHints_helper(effectiveSpacing);
-}
+ // 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.
-void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing,
- bool refreshChildren)
-{
- if (refreshChildren) {
- firstEdge->refreshSizeHints(effectiveSpacing);
- secondEdge->refreshSizeHints(effectiveSpacing);
- }
+ // Account for parallel anchors where the second edge is backwards.
+ // We rely on the fact that a forward anchor of sizes min, pref, max is equivalent
+ // to a backwards anchor of size (-max, -pref, -min)
- // ### should we warn if the parallel connection is invalid?
- // e.g. 1-2-3 with 10-20-30, the minimum of the latter is
- // bigger than the maximum of the former.
+ // Also see comments in updateChildrenSizes().
+ const bool secondForward = (firstEdge->from == secondEdge->from);
+ const qreal secondMin = secondForward ? secondEdge->minSize : -secondEdge->maxSize;
+ const qreal secondPref = secondForward ? secondEdge->prefSize : -secondEdge->prefSize;
+ const qreal secondMax = secondForward ? secondEdge->maxSize : -secondEdge->minSize;
- minSize = qMax(firstEdge->minSize, secondEdge->minSize);
- maxSize = qMin(firstEdge->maxSize, secondEdge->maxSize);
+ minSize = qMax(firstEdge->minSize, secondMin);
+ maxSize = qMin(firstEdge->maxSize, secondMax);
- expSize = qMax(firstEdge->expSize, secondEdge->expSize);
- expSize = qMin(expSize, maxSize);
+ // 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;
+ }
+
+ // The equivalent preferred Size of a parallel anchor is calculated as to
+ // reduce the deviation from the original preferred sizes _and_ to avoid shrinking
+ // items below their preferred sizes, unless strictly needed.
- prefSize = qMax(firstEdge->prefSize, secondEdge->prefSize);
- prefSize = qMin(prefSize, expSize);
+ // ### This logic only holds if all anchors in the layout are "well-behaved" in the
+ // following terms:
+ //
+ // - There are no negative-sized anchors
+ // - All sequential anchors are composed of children in the same direction as the
+ // sequential anchor itself
+ //
+ // With these assumptions we can grow a child knowing that no hidden items will
+ // have to shrink as the result of that.
+ // If any of these does not hold, we have a situation where the ParallelAnchor
+ // does not have enough information to calculate its equivalent prefSize.
+ prefSize = qMax(firstEdge->prefSize, secondPref);
+ prefSize = qMin(prefSize, maxSize);
// See comment in AnchorData::refreshSizeHints() about sizeAt* values
sizeAtMinimum = prefSize;
sizeAtPreferred = prefSize;
- sizeAtExpanding = prefSize;
sizeAtMaximum = prefSize;
+
+ return true;
}
/*!
@@ -250,44 +331,52 @@ void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing,
0 is at Preferred
1 is at Maximum
*/
-static qreal getFactor(qreal value, qreal min, qreal pref, qreal max)
-{
- // ### Maybe remove some of the assertions? (since outside is asserting us)
- Q_ASSERT(value > min || qFuzzyCompare(value, min));
- Q_ASSERT(value < max || qFuzzyCompare(value, max));
-
- if (qFuzzyCompare(value, min)) {
- return -1.0;
- } else if (qFuzzyCompare(value, pref)) {
- return 0.0;
- } else if (qFuzzyCompare(value, max)) {
- return 1.0;
- } else if (value < pref) {
- // Since value < pref and value != pref and min <= value,
- // we can assert that min < pref.
- Q_ASSERT(min < pref);
- return (value - min) / (pref - min) - 1;
+static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal value, qreal min,
+ qreal pref, qreal max)
+{
+ QGraphicsAnchorLayoutPrivate::Interval interval;
+ qreal lower;
+ qreal upper;
+
+ if (value < pref) {
+ interval = QGraphicsAnchorLayoutPrivate::MinToPreferred;
+ lower = min;
+ upper = pref;
} else {
- // Since value > pref and value != pref and max >= value,
- // we can assert that max > pref.
- Q_ASSERT(max > pref);
- return (value - pref) / (max - pref);
+ interval = QGraphicsAnchorLayoutPrivate::PreferredToMax;
+ lower = pref;
+ upper = max;
}
+
+ qreal progress;
+ if (upper == lower) {
+ progress = 0;
+ } else {
+ progress = (value - lower) / (upper - lower);
+ }
+
+ return qMakePair(interval, progress);
}
-static qreal getExpandingFactor(const qreal &expSize, const qreal &sizeAtPreferred,
- const qreal &sizeAtExpanding, const qreal &sizeAtMaximum)
+static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor,
+ qreal min, qreal pref,
+ qreal max)
{
- const qreal lower = qMin(sizeAtPreferred, sizeAtMaximum);
- const qreal upper = qMax(sizeAtPreferred, sizeAtMaximum);
- const qreal boundedExpSize = qBound(lower, expSize, upper);
+ qreal lower;
+ qreal upper;
- const qreal bandSize = sizeAtMaximum - boundedExpSize;
- if (bandSize == 0) {
- return 0;
- } else {
- return (sizeAtExpanding - boundedExpSize) / bandSize;
+ switch (factor.first) {
+ case QGraphicsAnchorLayoutPrivate::MinToPreferred:
+ lower = min;
+ upper = pref;
+ break;
+ case QGraphicsAnchorLayoutPrivate::PreferredToMax:
+ lower = pref;
+ upper = max;
+ break;
}
+
+ return lower + factor.second * (upper - lower);
}
void SequentialAnchorData::updateChildrenSizes()
@@ -295,74 +384,52 @@ void SequentialAnchorData::updateChildrenSizes()
// ### REMOVE ME
// ### check whether we are guarantee to get those or we need to warn stuff at this
// point.
- Q_ASSERT(sizeAtMinimum > minSize || qFuzzyCompare(sizeAtMinimum, minSize));
- Q_ASSERT(sizeAtMinimum < maxSize || qFuzzyCompare(sizeAtMinimum, maxSize));
- Q_ASSERT(sizeAtPreferred > minSize || qFuzzyCompare(sizeAtPreferred, minSize));
- Q_ASSERT(sizeAtPreferred < maxSize || qFuzzyCompare(sizeAtPreferred, maxSize));
- Q_ASSERT(sizeAtExpanding > minSize || qFuzzyCompare(sizeAtExpanding, minSize));
- Q_ASSERT(sizeAtExpanding < maxSize || qFuzzyCompare(sizeAtExpanding, maxSize));
- Q_ASSERT(sizeAtMaximum > minSize || qFuzzyCompare(sizeAtMaximum, minSize));
- Q_ASSERT(sizeAtMaximum < maxSize || qFuzzyCompare(sizeAtMaximum, maxSize));
+ Q_ASSERT(sizeAtMinimum > minSize || qAbs(sizeAtMinimum - minSize) < 0.00000001);
+ Q_ASSERT(sizeAtPreferred > minSize || qAbs(sizeAtPreferred - minSize) < 0.00000001);
+ Q_ASSERT(sizeAtMaximum > minSize || qAbs(sizeAtMaximum - minSize) < 0.00000001);
+
+ // These may be false if this anchor was in parallel with the layout stucture
+ // Q_ASSERT(sizeAtMinimum < maxSize || qAbs(sizeAtMinimum - maxSize) < 0.00000001);
+ // Q_ASSERT(sizeAtPreferred < maxSize || qAbs(sizeAtPreferred - maxSize) < 0.00000001);
+ // Q_ASSERT(sizeAtMaximum < maxSize || qAbs(sizeAtMaximum - maxSize) < 0.00000001);
// Band here refers if the value is in the Minimum To Preferred
// band (the lower band) or the Preferred To Maximum (the upper band).
- const qreal minFactor = getFactor(sizeAtMinimum, minSize, prefSize, maxSize);
- const qreal prefFactor = getFactor(sizeAtPreferred, minSize, prefSize, maxSize);
- const qreal maxFactor = getFactor(sizeAtMaximum, minSize, prefSize, maxSize);
- const qreal expFactor = getExpandingFactor(expSize, sizeAtPreferred, sizeAtExpanding, sizeAtMaximum);
+ const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> minFactor =
+ getFactor(sizeAtMinimum, minSize, prefSize, maxSize);
+ const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> prefFactor =
+ getFactor(sizeAtPreferred, minSize, prefSize, maxSize);
+ const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> maxFactor =
+ getFactor(sizeAtMaximum, minSize, prefSize, maxSize);
for (int i = 0; i < m_edges.count(); ++i) {
AnchorData *e = m_edges.at(i);
- qreal bandSize = minFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize;
- e->sizeAtMinimum = e->prefSize + bandSize * minFactor;
-
- bandSize = prefFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize;
- e->sizeAtPreferred = e->prefSize + bandSize * prefFactor;
-
- bandSize = maxFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize;
- e->sizeAtMaximum = e->prefSize + bandSize * maxFactor;
-
- const qreal lower = qMin(e->sizeAtPreferred, e->sizeAtMaximum);
- const qreal upper = qMax(e->sizeAtPreferred, e->sizeAtMaximum);
- const qreal edgeBoundedExpSize = qBound(lower, e->expSize, upper);
- e->sizeAtExpanding = edgeBoundedExpSize + expFactor * (e->sizeAtMaximum - edgeBoundedExpSize);
+ e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->prefSize, e->maxSize);
+ e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->prefSize, e->maxSize);
+ e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->prefSize, e->maxSize);
e->updateChildrenSizes();
}
}
-void SequentialAnchorData::refreshSizeHints(qreal effectiveSpacing)
-{
- refreshSizeHints_helper(effectiveSpacing);
-}
-
-void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing,
- bool refreshChildren)
+void SequentialAnchorData::calculateSizeHints()
{
minSize = 0;
prefSize = 0;
- expSize = 0;
maxSize = 0;
for (int i = 0; i < m_edges.count(); ++i) {
AnchorData *edge = m_edges.at(i);
-
- // If it's the case refresh children information first
- if (refreshChildren)
- edge->refreshSizeHints(effectiveSpacing);
-
minSize += edge->minSize;
prefSize += edge->prefSize;
- expSize += edge->expSize;
maxSize += edge->maxSize;
}
// See comment in AnchorData::refreshSizeHints() about sizeAt* values
sizeAtMinimum = prefSize;
sizeAtPreferred = prefSize;
- sizeAtExpanding = prefSize;
sizeAtMaximum = prefSize;
}
@@ -429,18 +496,20 @@ QString GraphPath::toString() const
#endif
QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate()
- : calculateGraphCacheDirty(1)
+ : calculateGraphCacheDirty(true), styleInfoDirty(true)
{
for (int i = 0; i < NOrientations; ++i) {
for (int j = 0; j < 3; ++j) {
sizeHints[i][j] = -1;
}
- sizeAtExpanding[i] = -1;
interpolationProgress[i] = -1;
spacings[i] = -1;
- graphSimplified[i] = false;
graphHasConflicts[i] = false;
+
+ layoutFirstVertex[i] = 0;
+ layoutCentralVertex[i] = 0;
+ layoutLastVertex[i] = 0;
}
}
@@ -481,67 +550,125 @@ inline static qreal checkAdd(qreal a, qreal b)
}
/*!
- * \internal
- *
- * Takes the sequence of vertices described by (\a before, \a vertices, \a after) and replaces
- * all anchors connected to the vertices in \a vertices with one simplified anchor between
- * \a before and \a after. The simplified anchor will be a placeholder for all the previous
- * anchors between \a before and \a after, and can be restored back to the anchors it is a
- * placeholder for.
- */
-static bool simplifySequentialChunk(Graph<AnchorVertex, AnchorData> *graph,
- AnchorVertex *before,
- const QVector<AnchorVertex*> &vertices,
- AnchorVertex *after)
+ \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)
{
- int i;
+ 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];
+
+ if (!child->isCenterAnchor)
+ continue;
+
+ parallel->isCenterAnchor = true;
+
+ for (int i = 0; i < constraints.count(); ++i) {
+ QSimplexConstraint *c = constraints[i];
+ if (c->variables.contains(child)) {
+ childConstraints->append(c);
+ qreal v = c->variables.take(child);
+ 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)
+{
+ AnchorData *data = graph->edgeData(before, vertices.first());
+ Q_ASSERT(data);
+
+ const bool forward = (before == data->from);
+ QVector<AnchorVertex *> orderedVertices;
+
+ if (forward) {
+ orderedVertices = vertices;
+ } else {
+ qSwap(before, after);
+ for (int i = vertices.count() - 1; i >= 0; --i)
+ orderedVertices.append(vertices.at(i));
+ }
+
#if defined(QT_DEBUG) && 0
QString strVertices;
- for (i = 0; i < vertices.count(); ++i)
- strVertices += QString::fromAscii("%1 - ").arg(vertices.at(i)->toString());
+ for (int i = 0; i < orderedVertices.count(); ++i) {
+ strVertices += QString::fromAscii("%1 - ").arg(orderedVertices.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
- SequentialAnchorData *sequence = new SequentialAnchorData;
AnchorVertex *prev = before;
- AnchorData *data;
- for (i = 0; i <= vertices.count(); ++i) {
- AnchorVertex *next = (i < vertices.count()) ? vertices.at(i) : after;
- data = graph->takeEdge(prev, next);
- sequence->m_edges.append(data);
+ QVector<AnchorData *> edges;
+
+ for (int i = 0; i <= orderedVertices.count(); ++i) {
+ AnchorVertex *next = (i < orderedVertices.count()) ? orderedVertices.at(i) : after;
+ AnchorData *ad = graph->takeEdge(prev, next);
+ Q_ASSERT(ad);
+ edges.append(ad);
prev = next;
}
- sequence->setVertices(vertices);
+
+ SequentialAnchorData *sequence = new SequentialAnchorData(orderedVertices, edges);
sequence->from = before;
sequence->to = after;
- sequence->refreshSizeHints_helper(0, false);
-
- // data here is the last edge in the sequence
- // ### this seems to be here for supporting reverse order sequences,
- // but doesnt seem to be used right now
- if (data->from != vertices.last())
- qSwap(sequence->from, sequence->to);
-
- // Note that since layout 'edges' can't be simplified away from
- // the graph, it's safe to assume that if there's a layout
- // 'edge', it'll be in the boundaries of the sequence.
- sequence->isLayoutAnchor = (sequence->m_edges.first()->isLayoutAnchor
- || sequence->m_edges.last()->isLayoutAnchor);
-
- AnchorData *newAnchor = sequence;
- if (AnchorData *oldAnchor = graph->takeEdge(before, after)) {
- ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, sequence);
- parallel->isLayoutAnchor = (oldAnchor->isLayoutAnchor
- || sequence->isLayoutAnchor);
- parallel->refreshSizeHints_helper(0, false);
- newAnchor = parallel;
- }
- graph->createEdge(before, after, newAnchor);
+ sequence->calculateSizeHints();
- // True if we created a parallel anchor
- return newAnchor != sequence;
+ return sequence;
}
/*!
@@ -578,271 +705,546 @@ static bool simplifySequentialChunk(Graph<AnchorVertex, AnchorData> *graph,
2. Go to (1)
3. Done
-
- * Gathering sequential anchors *
- 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.
+ When creating the parallel anchors, the algorithm might identify unfeasible situations. In this
+ case the simplification process stops and returns false. Otherwise returns true.
*/
-void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation)
+bool QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation)
{
- static bool noSimplification = !qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty();
- if (noSimplification || items.isEmpty())
- return;
+ if (items.isEmpty())
+ return true;
- if (graphSimplified[orientation])
- return;
- graphSimplified[orientation] = true;
-
-#if 0
+#if defined(QT_DEBUG) && 0
qDebug("Simplifying Graph for %s",
orientation == Horizontal ? "Horizontal" : "Vertical");
-#endif
- AnchorVertex *rootVertex = graph[orientation].rootVertex();
+ static int count = 0;
+ if (orientation == Horizontal) {
+ count++;
+ dumpGraph(QString::fromAscii("%1-full").arg(count));
+ }
+#endif
- if (!rootVertex)
- return;
+ // Vertex simplification
+ if (!simplifyVertices(orientation)) {
+ restoreVertices(orientation);
+ return false;
+ }
+ // Anchor simplification
bool dirty;
+ bool feasible = true;
do {
- dirty = simplifyGraphIteration(orientation);
- } while (dirty);
+ 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::simplifyGraphIteration(QGraphicsAnchorLayoutPrivate::Orientation orientation)
+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];
- AnchorVertex *v = g.rootVertex();
- QSet<AnchorVertex *> visited;
+ // We'll walk through vertices
QStack<AnchorVertex *> stack;
- stack.push(v);
- QVector<AnchorVertex*> candidates;
+ stack.push(layoutFirstVertex[orientation]);
+ QSet<AnchorVertex *> visited;
- const Qt::AnchorPoint centerEdge = pickEdge(Qt::AnchorHorizontalCenter, orientation);
- const Qt::AnchorPoint layoutEdge = oppositeEdge(v->m_edge);
+ 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);
+ }
+ }
- bool dirty = false;
+ 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);
- // walk depth-first.
- while (!stack.isEmpty()) {
- v = stack.pop();
- QList<AnchorVertex *> vertices = g.adjacentVertices(v);
- const int count = vertices.count();
- bool endOfSequence = (v->m_item == q && v->m_edge == layoutEdge) || count != 2;
- if (count == 2 && v->m_item != q) {
- candidates.append(v);
- if (visited.contains(vertices.first()) && visited.contains(vertices.last())) {
- // in case of a cycle
- endOfSequence = true;
+ // 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);
}
}
- if (endOfSequence && candidates.count() >= 1) {
- int i;
- AnchorVertex *afterSequence= 0;
- AnchorVertex *beforeSequence = 0;
- // find the items before and after the valid sequence
- if (candidates.count() == 1) {
- QList<AnchorVertex *> beforeAndAfterVertices = g.adjacentVertices(candidates.at(0));
- Q_ASSERT(beforeAndAfterVertices.count() == 2);
- // Since we only have one vertex, we can pick
- // any of the two vertices to become before/after.
- afterSequence = beforeAndAfterVertices.last();
- beforeSequence = beforeAndAfterVertices.first();
- } else {
- QList<AnchorVertex *> adjacentOfSecondLastVertex = g.adjacentVertices(candidates.last());
- Q_ASSERT(adjacentOfSecondLastVertex.count() == 2);
- if (adjacentOfSecondLastVertex.first() == candidates.at(candidates.count() - 2))
- afterSequence = adjacentOfSecondLastVertex.last();
- else
- afterSequence = adjacentOfSecondLastVertex.first();
+ }
- QList<AnchorVertex *> adjacentOfSecondVertex = g.adjacentVertices(candidates.first());
- Q_ASSERT(adjacentOfSecondVertex.count() == 2);
- if (adjacentOfSecondVertex.first() == candidates.at(1))
- beforeSequence = adjacentOfSecondVertex.last();
- else
- beforeSequence = adjacentOfSecondVertex.first();
- }
- // The complete path of the sequence to simplify is: beforeSequence, <candidates>, afterSequence
- // where beforeSequence and afterSequence are the endpoints where the anchor is inserted
- // between.
-#if defined(QT_DEBUG) && 0
- // ### DEBUG
- QString strCandidates;
- for (i = 0; i < candidates.count(); ++i)
- strCandidates += QString::fromAscii("%1 - ").arg(candidates.at(i)->toString());
- QString strPath = QString::fromAscii("%1 - %2%3").arg(beforeSequence->toString(), strCandidates, afterSequence->toString());
- qDebug("candidate list for sequential simplification:\n[%s]", qPrintable(strPath));
-#endif
+ 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.
- bool forward = true;
- AnchorVertex *prev = beforeSequence;
- int intervalFrom = 0;
+ 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];
- // Check for directionality (from). We don't want to destroy that information,
- // thus we only combine anchors with the same direction.
+ QSet<AnchorVertex *> visited;
+ QStack<QPair<AnchorVertex *, AnchorVertex *> > stack;
+ stack.push(qMakePair(static_cast<AnchorVertex *>(0), layoutFirstVertex[orientation]));
+ QVector<AnchorVertex*> candidates;
+ bool candidatesForward = true;
- // "i" is the index *including* the beforeSequence and afterSequence vertices.
- for (i = 1; i <= candidates.count() + 1; ++i) {
- bool atVertexAfter = i > candidates.count();
- AnchorVertex *v1 = atVertexAfter ? afterSequence : candidates.at(i - 1);
- AnchorData *data = g.edgeData(prev, v1);
+ // 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) it will change the direction of the sequence;
+ // (d) its next adjacent is already visited (a cycle in the graph);
+ // (e) the next anchor is a center anchor.
+
+ 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) {
+ // If this is the first vertice, determine what is the direction to use for this
+ // sequence.
+ if (candidates.isEmpty()) {
+ const AnchorData *data = g.edgeData(beforeSequence, v);
Q_ASSERT(data);
- if (i == 1) {
- forward = (prev == data->from ? true : false);
- } else if (forward != (prev == data->from) || atVertexAfter) {
- int intervalTo = i;
- if (forward != (prev == data->from))
- --intervalTo;
-
- // intervalFrom and intervalTo should now be indices to the vertex before and
- // after the sequential anchor.
- if (intervalTo - intervalFrom >= 2) {
- // simplify in the range [intervalFrom, intervalTo]
-
- // Trim off internal center anchors (Left-Center/Center-Right) from the
- // start and the end of the sequence. We never want to simplify internal
- // center anchors where there is an external anchor connected to the center.
- AnchorVertex *intervalVertexFrom = intervalFrom == 0 ? beforeSequence : candidates.at(intervalFrom - 1);
- int effectiveIntervalFrom = intervalFrom;
- if (intervalVertexFrom->m_edge == centerEdge
- && intervalVertexFrom->m_item == candidates.at(effectiveIntervalFrom)->m_item) {
- ++effectiveIntervalFrom;
- intervalVertexFrom = candidates.at(effectiveIntervalFrom - 1);
- }
- AnchorVertex *intervalVertexTo = intervalTo <= candidates.count() ? candidates.at(intervalTo - 1) : afterSequence;
- int effectiveIntervalTo = intervalTo;
- if (intervalVertexTo->m_edge == centerEdge
- && intervalVertexTo->m_item == candidates.at(effectiveIntervalTo - 2)->m_item) {
- --effectiveIntervalTo;
- intervalVertexTo = candidates.at(effectiveIntervalTo - 1);
- }
- if (effectiveIntervalTo - effectiveIntervalFrom >= 2) {
- QVector<AnchorVertex*> subCandidates;
- if (forward) {
- subCandidates = candidates.mid(effectiveIntervalFrom, effectiveIntervalTo - effectiveIntervalFrom - 1);
- } else {
- // reverse the order of the candidates.
- qSwap(intervalVertexFrom, intervalVertexTo);
- do {
- ++effectiveIntervalFrom;
- subCandidates.prepend(candidates.at(effectiveIntervalFrom - 1));
- } while (effectiveIntervalFrom < effectiveIntervalTo - 1);
- }
- if (simplifySequentialChunk(&g, intervalVertexFrom, subCandidates, intervalVertexTo)) {
- dirty = true;
- break;
- }
- // finished simplification of chunk with same direction
- }
- }
- if (forward == (prev == data->from))
- --intervalTo;
- intervalFrom = intervalTo;
+ candidatesForward = (beforeSequence == data->from);
+ }
- forward = !forward;
+ // This is a tricky part. We peek at the next vertex to find out whether
+ //
+ // - the edge from this vertex to the next vertex has the same direction;
+ // - we already visited the next vertex;
+ // - the next anchor is a center.
+ //
+ // 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 willChangeDirection = (candidatesForward != (v == data->from));
+ const bool cycleFound = visited.contains(after);
+
+ // Now cases (c), (d) and (e)...
+ endOfSequence = willChangeDirection || cycleFound || data->isCenterAnchor;
+
+ if (endOfSequence) {
+ if (!willChangeDirection) {
+ // If the direction will not change, we can add the current vertex to the
+ // candidates list and we know that 'after' can be used as afterSequence.
+ candidates.append(v);
+ afterSequence = after;
}
- prev = v1;
+ } else {
+ // If it's not an end of sequence, then the vertex didn't trigger neither of the
+ // previously four cases, so it can be added to the candidates list.
+ 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 (dirty)
- break;
+ // 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));
}
- if (endOfSequence)
- candidates.clear();
+ 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);
- for (int i = 0; i < count; ++i) {
- AnchorVertex *next = vertices.at(i);
- if (next->m_item == q && next->m_edge == centerEdge)
+ // If there's not candidates to be simplified, leave.
+ if (candidates.isEmpty())
continue;
- if (visited.contains(next))
+ }
+
+ const AnchorData *lastAnchor = g.edgeData(candidates.last(), afterSequence);
+ if (lastAnchor->isCenterAnchor) {
+ afterSequence = candidates.last();
+ candidates.remove(candidates.count() - 1);
+
+ if (candidates.isEmpty())
continue;
- stack.push(next);
}
- visited.insert(v);
+ //
+ // 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 dirty;
+ return false;
}
-static void restoreSimplifiedAnchor(Graph<AnchorVertex, AnchorData> &g,
- AnchorData *edge,
- AnchorVertex *before,
- AnchorVertex *after)
+void QGraphicsAnchorLayoutPrivate::restoreSimplifiedAnchor(AnchorData *edge)
{
- Q_ASSERT(edge->type != AnchorData::Normal);
#if 0
static const char *anchortypes[] = {"Normal",
"Sequential",
"Parallel"};
qDebug("Restoring %s edge.", anchortypes[int(edge->type)]);
#endif
- if (edge->type == AnchorData::Sequential) {
- SequentialAnchorData* seqEdge = static_cast<SequentialAnchorData*>(edge);
- // restore the sequential anchor
- AnchorVertex *prev = before;
- AnchorVertex *last = after;
- if (edge->from != prev)
- qSwap(last, prev);
-
- for (int i = 0; i < seqEdge->m_edges.count(); ++i) {
- AnchorVertex *v1 = (i < seqEdge->m_children.count()) ? seqEdge->m_children.at(i) : last;
- AnchorData *data = seqEdge->m_edges.at(i);
- if (data->type != AnchorData::Normal) {
- restoreSimplifiedAnchor(g, data, prev, v1);
- } else {
- g.createEdge(prev, v1, data);
- }
- prev = v1;
+
+ 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) {
- ParallelAnchorData* parallelEdge = static_cast<ParallelAnchorData*>(edge);
- AnchorData *parallelEdges[2] = {parallelEdge->firstEdge,
- parallelEdge->secondEdge};
- for (int i = 0; i < 2; ++i) {
- AnchorData *data = parallelEdges[i];
- if (data->type == AnchorData::Normal) {
- g.createEdge(before, after, data);
- } else {
- restoreSimplifiedAnchor(g, data, before, after);
- }
- }
+
+ // 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::restoreSimplifiedGraph(Orientation orientation)
+void QGraphicsAnchorLayoutPrivate::restoreSimplifiedConstraints(ParallelAnchorData *parallel)
{
- if (!graphSimplified[orientation])
+ if (!parallel->isCenterAnchor)
return;
- graphSimplified[orientation] = false;
+ 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);
+ }
+
+ for (int i = 0; i < parallel->m_secondConstraints.count(); ++i) {
+ QSimplexConstraint *c = parallel->m_secondConstraints.at(i);
+ qreal v = c->variables[parallel];
+ 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);
- if (edge->type != AnchorData::Normal) {
- AnchorData *oldEdge = g.takeEdge(v1, v2);
- restoreSimplifiedAnchor(g, edge, v1, v2);
- delete oldEdge;
+
+ // 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];
+
+ // 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;
}
+ toRestore.clear();
+
+ // The restoration process for vertex simplification also restored the effect of the
+ // parallel anchors created during vertex simplification, so we just need to restore
+ // the constraints in case of parallels that contain center anchors. For the same
+ // reason as above, order matters here.
+ QList<AnchorData *> &parallelAnchors = anchorsFromSimplifiedVertices[orientation];
+
+ for (int i = parallelAnchors.count() - 1; i >= 0; --i) {
+ ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i));
+ restoreSimplifiedConstraints(parallel);
+ delete parallel;
+ }
+ parallelAnchors.clear();
}
QGraphicsAnchorLayoutPrivate::Orientation
@@ -872,9 +1274,10 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
data->maxSize = QWIDGETSIZE_MAX;
data->skipInPreferred = 1;
- // Set the Layout Left edge as the root of the horizontal graph.
- AnchorVertex *v = internalVertex(layout, Qt::AnchorLeft);
- graph[Horizontal].setRootVertex(v);
+ // 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;
@@ -883,17 +1286,18 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
data->maxSize = QWIDGETSIZE_MAX;
data->skipInPreferred = 1;
- // Set the Layout Top edge as the root of the vertical graph.
- v = internalVertex(layout, Qt::AnchorTop);
- graph[Vertical].setRootVertex(v);
+ // 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) == NULL);
- Q_ASSERT(internalVertex(q, Qt::AnchorVerticalCenter) == NULL);
+ Q_ASSERT(!internalVertex(q, Qt::AnchorHorizontalCenter));
+ Q_ASSERT(!internalVertex(q, Qt::AnchorVerticalCenter));
removeAnchor_helper(internalVertex(q, Qt::AnchorLeft),
internalVertex(q, Qt::AnchorRight));
@@ -903,19 +1307,17 @@ void QGraphicsAnchorLayoutPrivate::deleteLayoutEdges()
void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
{
- Q_ASSERT(!graphSimplified[Horizontal] && !graphSimplified[Vertical]);
-
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(0); // 0 = effectiveSpacing, will not be used
+ data->refreshSizeHints();
data = new AnchorData;
addAnchor_helper(item, Qt::AnchorTop, item, Qt::AnchorBottom, data);
- data->refreshSizeHints(0); // 0 = effectiveSpacing, will not be used
+ data->refreshSizeHints();
}
/*!
@@ -932,6 +1334,8 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge)
{
+ Q_Q(QGraphicsAnchorLayout);
+
Orientation orientation;
switch (centerEdge) {
case Qt::AnchorHorizontalCenter:
@@ -945,8 +1349,6 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
return;
}
- Q_ASSERT(!graphSimplified[orientation]);
-
// Check if vertex already exists
if (internalVertex(item, centerEdge))
return;
@@ -973,23 +1375,33 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
AnchorData *data = new AnchorData;
c->variables.insert(data, 1.0);
addAnchor_helper(item, firstEdge, item, centerEdge, data);
- data->refreshSizeHints(0);
+ 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->refreshSizeHints(0);
+ 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:
@@ -1003,8 +1415,6 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
return;
}
- Q_ASSERT(!graphSimplified[orientation]);
-
// Orientation code
Qt::AnchorPoint firstEdge;
Qt::AnchorPoint lastEdge;
@@ -1031,7 +1441,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
AnchorData *oldData = g.edgeData(first, center);
// Remove center constraint
for (int i = itemCenterConstraints[orientation].count() - 1; i >= 0; --i) {
- if (itemCenterConstraints[orientation][i]->variables.contains(oldData)) {
+ if (itemCenterConstraints[orientation].at(i)->variables.contains(oldData)) {
delete itemCenterConstraints[orientation].takeAt(i);
break;
}
@@ -1041,7 +1451,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
// 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(0);
+ data->refreshSizeHints();
// Remove old anchors
removeAnchor_helper(first, center);
@@ -1062,14 +1472,16 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
// 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)
{
- Q_ASSERT(!graphSimplified[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
@@ -1091,7 +1503,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem *
// Look for our anchor in all item center constraints, then remove it
for (int i = 0; i < itemCenterConstraints[orientation].size(); ++i) {
- if (itemCenterConstraints[orientation][i]->variables.contains(internalAnchor)) {
+ if (itemCenterConstraints[orientation].at(i)->variables.contains(internalAnchor)) {
delete itemCenterConstraints[orientation].takeAt(i);
break;
}
@@ -1100,15 +1512,21 @@ void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem *
/*!
* \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).
*
- * Helper function that is called from the anchor functions in the public API.
- * If \a spacing is 0, it will pick up the spacing defined by the style.
+ * 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)
+ Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem,
+ Qt::AnchorPoint secondEdge,
+ qreal *spacing)
{
Q_Q(QGraphicsAnchorLayout);
if ((firstItem == 0) || (secondItem == 0)) {
@@ -1129,10 +1547,6 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi
return 0;
}
- // Guarantee that the graph is no simplified when adding this anchor,
- // anchor manipulation always happen in the full graph
- restoreSimplifiedGraph(edgeOrientation(firstEdge));
-
// In QGraphicsAnchorLayout, items are represented in its internal
// graph as four anchors that connect:
// - Left -> HCenter
@@ -1142,12 +1556,10 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi
// Ensure that the internal anchors have been created for both items.
if (firstItem != q && !items.contains(firstItem)) {
- restoreSimplifiedGraph(edgeOrientation(firstEdge) == Horizontal ? Vertical : Horizontal);
createItemEdges(firstItem);
addChildLayoutItem(firstItem);
}
if (secondItem != q && !items.contains(secondItem)) {
- restoreSimplifiedGraph(edgeOrientation(firstEdge) == Horizontal ? Vertical : Horizontal);
createItemEdges(secondItem);
addChildLayoutItem(secondItem);
}
@@ -1160,7 +1572,13 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi
correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge);
AnchorData *data = new AnchorData;
- if (!spacing) {
+ 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):
@@ -1173,47 +1591,49 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi
|| secondItem == q
|| pickEdge(firstEdge, Horizontal) == Qt::AnchorHorizontalCenter
|| oppositeEdge(firstEdge) != secondEdge) {
- data->setFixedSize(0);
+ graphicsAnchor->setSpacing(0);
} else {
- data->unsetSize();
+ graphicsAnchor->unsetSpacing();
}
- addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
-
- } else if (*spacing >= 0) {
- data->setFixedSize(*spacing);
- addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
-
- } else {
- data->setFixedSize(-*spacing);
- addAnchor_helper(secondItem, secondEdge, firstItem, firstEdge, data);
}
- return acquireGraphicsAnchor(data);
+ 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)
+ Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem,
+ Qt::AnchorPoint secondEdge,
+ AnchorData *data)
{
Q_Q(QGraphicsAnchorLayout);
- // Guarantee that the graph is no simplified when adding this anchor,
- // anchor manipulation always happen in the full graph
- restoreSimplifiedGraph(edgeOrientation(firstEdge));
+ const Orientation orientation = edgeOrientation(firstEdge);
- // Is the Vertex (firstItem, firstEdge) already represented in our
- // internal structure?
+ // Create or increase the reference count for the related vertices.
AnchorVertex *v1 = addInternalVertex(firstItem, firstEdge);
AnchorVertex *v2 = addInternalVertex(secondItem, secondEdge);
// Remove previous anchor
- // ### Could we update the existing edgeData rather than creating a new one?
- if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2)) {
+ 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.
@@ -1222,10 +1642,11 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt
#ifdef QT_DEBUG
data->name = QString::fromAscii("%1 --to--> %2").arg(v1->toString()).arg(v2->toString());
#endif
- // Keep track of anchors that are connected to the layout 'edges'
- data->isLayoutAnchor = (v1->m_item == q || v2->m_item == q);
+ // ### bit to track internal anchors, since inside AnchorData methods
+ // we don't have access to the 'q' pointer.
+ data->isLayoutAnchor = (data->item == q);
- graph[edgeOrientation(firstEdge)].createEdge(v1, v2, data);
+ graph[orientation].createEdge(v1, v2, data);
}
QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *firstItem,
@@ -1233,15 +1654,13 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge)
{
- Orientation orient = edgeOrientation(firstEdge);
- restoreSimplifiedGraph(orient);
-
+ const Orientation orientation = edgeOrientation(firstEdge);
AnchorVertex *v1 = internalVertex(firstItem, firstEdge);
AnchorVertex *v2 = internalVertex(secondItem, secondEdge);
QGraphicsAnchor *graphicsAnchor = 0;
- AnchorData *data = graph[orient].edgeData(v1, v2);
+ AnchorData *data = graph[orientation].edgeData(v1, v2);
if (data)
graphicsAnchor = acquireGraphicsAnchor(data);
return graphicsAnchor;
@@ -1326,12 +1745,9 @@ void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex,
void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2)
{
Q_ASSERT(v1 && v2);
- // Guarantee that the graph is no simplified when removing this anchor,
- // anchor manipulation always happen in the full graph
- Orientation o = edgeOrientation(v1->m_edge);
- restoreSimplifiedGraph(o);
// Remove edge from graph
+ const Orientation o = edgeOrientation(v1->m_edge);
graph[o].removeEdge(v1, v2);
// Decrease vertices reference count (may trigger a deletion)
@@ -1339,67 +1755,6 @@ void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorV
removeInternalVertex(v2->m_item, v2->m_edge);
}
-/*!
- \internal
- Only called from outside. (calls invalidate())
-*/
-void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal *anchorSize)
-{
- Q_Q(QGraphicsAnchorLayout);
- // ### we can avoid restoration if we really want to, but we would have to
- // search recursively through all composite anchors
- Q_ASSERT(data);
- restoreSimplifiedGraph(edgeOrientation(data->from->m_edge));
-
- QGraphicsLayoutItem *firstItem = data->from->m_item;
- QGraphicsLayoutItem *secondItem = data->to->m_item;
- Qt::AnchorPoint firstEdge = data->from->m_edge;
- Qt::AnchorPoint secondEdge = data->to->m_edge;
-
- // Use heuristics to find out what the user meant with this anchor.
- correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge);
- if (data->from->m_item != firstItem)
- qSwap(data->from, data->to);
-
- if (anchorSize) {
- // ### The current implementation makes "setAnchorSize" behavior
- // dependent on the argument order for cases where we have
- // no heuristic. Ie. two widgets, same anchor point.
-
- // We cannot have negative sizes inside the graph. This would cause
- // the simplex solver to fail because all simplex variables are
- // positive by definition.
- // "negative spacing" is handled by inverting the standard item order.
- if (*anchorSize >= 0) {
- data->setFixedSize(*anchorSize);
- } else {
- data->setFixedSize(-*anchorSize);
- qSwap(data->from, data->to);
- }
- } else {
- data->unsetSize();
- }
- q->invalidate();
-}
-
-void QGraphicsAnchorLayoutPrivate::anchorSize(const AnchorData *data,
- qreal *minSize,
- qreal *prefSize,
- qreal *maxSize) const
-{
- Q_ASSERT(minSize || prefSize || maxSize);
- Q_ASSERT(data);
- QGraphicsAnchorLayoutPrivate *that = const_cast<QGraphicsAnchorLayoutPrivate *>(this);
- that->restoreSimplifiedGraph(edgeOrientation(data->from->m_edge));
-
- if (minSize)
- *minSize = data->minSize;
- if (prefSize)
- *prefSize = data->prefSize;
- if (maxSize)
- *maxSize = data->maxSize;
-}
-
AnchorVertex *QGraphicsAnchorLayoutPrivate::addInternalVertex(QGraphicsLayoutItem *item,
Qt::AnchorPoint edge)
{
@@ -1465,8 +1820,6 @@ void QGraphicsAnchorLayoutPrivate::removeVertex(QGraphicsLayoutItem *item, Qt::A
void QGraphicsAnchorLayoutPrivate::removeAnchors(QGraphicsLayoutItem *item)
{
- Q_ASSERT(!graphSimplified[Horizontal] && !graphSimplified[Vertical]);
-
// remove the center anchor first!!
removeCenterAnchors(item, Qt::AnchorHorizontalCenter, false);
removeVertex(item, Qt::AnchorLeft);
@@ -1530,27 +1883,32 @@ void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&fi
}
}
-qreal QGraphicsAnchorLayoutPrivate::effectiveSpacing(Orientation orientation) const
+QLayoutStyleInfo &QGraphicsAnchorLayoutPrivate::styleInfo() const
{
- Q_Q(const QGraphicsAnchorLayout);
- qreal s = spacings[orientation];
- if (s < 0) {
- // ### make sure behaviour is the same as in QGraphicsGridLayout
+ 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()) {
- QGraphicsWidget *w = static_cast<QGraphicsWidget*>(parentItem);
- s = w->style()->pixelMetric(orientation == Horizontal
- ? QStyle::PM_LayoutHorizontalSpacing
- : QStyle::PM_LayoutVerticalSpacing);
- }
+ 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 s;
+ return cachedStyleInfo;
}
/*!
@@ -1564,19 +1922,18 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs()
{
if (!calculateGraphCacheDirty)
return;
-
calculateGraphs(Horizontal);
calculateGraphs(Vertical);
-
- calculateGraphCacheDirty = 0;
+ calculateGraphCacheDirty = false;
}
-// ### remove me:
+// ### 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[i];
+ const QSimplexConstraint *c = constraints.at(i);
foreach (QSimplexVariable *var, c->variables.keys()) {
variableSet += static_cast<AnchorData *>(var);
}
@@ -1585,38 +1942,46 @@ QList<AnchorData *> getVariables(QList<QSimplexConstraint *> constraints)
}
/*!
- \internal
+ \internal
- Calculate graphs is the method that puts together all the helper routines
- so that the AnchorLayout can calculate the sizes of each item.
+ 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:
+ In a nutshell it should do:
- 1) Update 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.
+ 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.
+ 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.
+ 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.
+ 4) Once the root anchors had its sizes calculated, propagate that to the
+ anchors they represent.
*/
void QGraphicsAnchorLayoutPrivate::calculateGraphs(
QGraphicsAnchorLayoutPrivate::Orientation orientation)
{
- Q_Q(QGraphicsAnchorLayout);
+#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
+ lastCalculationUsedSimplex[orientation] = false;
+#endif
- // Simplify the graph
- simplifyGraph(orientation);
+ static bool simplificationEnabled = qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty();
// Reset the nominal sizes of each anchor based on the current item sizes
- setAnchorSizeHintsFromItems(orientation);
+ 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);
@@ -1635,163 +2000,161 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
// 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;
- parts = getGraphParts(orientation);
+ 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[0];
- QList<QSimplexConstraint *> sizeHintConstraints;
- sizeHintConstraints = constraintsFromSizeHints(getVariables(trunkConstraints));
- trunkConstraints += sizeHintConstraints;
+ 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.
-
- // Retrieve that path
- AnchorVertex *v = internalVertex(q, pickEdge(Qt::AnchorRight, orientation));
+ AnchorVertex *v = layoutLastVertex[orientation];
GraphPath trunkPath = graphPaths[orientation].value(v);
- bool feasible = true;
- if (!trunkConstraints.isEmpty()) {
-#if 0
- qDebug("Simplex used for trunk of %s",
- orientation == Horizontal ? "Horizontal" : "Vertical");
-#endif
+ bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables);
- // Solve min and max size hints for trunk
- qreal min, max;
- feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max);
+ // 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.
- if (feasible) {
- // Solve for preferred. The objective function is calculated from the constraints
- // and variables internally.
- solvePreferred(trunkConstraints);
+ // 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
+
+ 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();
- // remove sizeHintConstraints from trunkConstraints
- trunkConstraints = parts[0];
+#if 0
+ qDebug("Simplex %s for trunk of %s", needsSimplex ? "used" : "NOT used",
+ orientation == Horizontal ? "Horizontal" : "Vertical");
+#endif
- // Solve for expanding. The objective function and the constraints from items
- // are calculated internally.
- solveExpanding(trunkConstraints);
+ if (needsSimplex) {
- // Propagate the new sizes down the simplified graph, ie. tell the
- // group anchors to set their children anchors sizes.
+ QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
+ QList<QSimplexConstraint *> allConstraints = constraints + sizeHintConstraints;
- // ### we calculated variables already a few times, can't we reuse that?
- QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
+ // Solve min and max size hints
+ qreal min, max;
+ feasible = solveMinMax(allConstraints, path, &min, &max);
- for (int i = 0; i < trunkVariables.count(); ++i)
- trunkVariables.at(i)->updateChildrenSizes();
+ if (feasible) {
+ solvePreferred(allConstraints, variables);
- // Calculate and set the preferred and expanding sizes for the layout,
+ // Calculate and set the preferred size for the layout,
// from the edge sizes that were calculated above.
qreal pref(0.0);
- qreal expanding(0.0);
- foreach (const AnchorData *ad, trunkPath.positives) {
+ foreach (const AnchorData *ad, path.positives) {
pref += ad->sizeAtPreferred;
- expanding += ad->sizeAtExpanding;
}
- foreach (const AnchorData *ad, trunkPath.negatives) {
+ foreach (const AnchorData *ad, path.negatives) {
pref -= ad->sizeAtPreferred;
- expanding -= ad->sizeAtExpanding;
}
sizeHints[orientation][Qt::MinimumSize] = min;
sizeHints[orientation][Qt::PreferredSize] = pref;
sizeHints[orientation][Qt::MaximumSize] = max;
- sizeAtExpanding[orientation] = expanding;
}
- } else {
-#if 0
- qDebug("Simplex NOT used for trunk of %s",
- orientation == Horizontal ? "Horizontal" : "Vertical");
-#endif
+ qDeleteAll(sizeHintConstraints);
+
+ } else {
// No Simplex is necessary because the path was simplified all the way to a single
// anchor.
- Q_ASSERT(trunkPath.positives.count() == 1);
- Q_ASSERT(trunkPath.negatives.count() == 0);
+ Q_ASSERT(path.positives.count() == 1);
+ Q_ASSERT(path.negatives.count() == 0);
- AnchorData *ad = trunkPath.positives.toList()[0];
+ AnchorData *ad = path.positives.toList()[0];
ad->sizeAtMinimum = ad->minSize;
ad->sizeAtPreferred = ad->prefSize;
- ad->sizeAtExpanding = ad->expSize;
ad->sizeAtMaximum = ad->maxSize;
- // Propagate
- ad->updateChildrenSizes();
-
sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum;
sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred;
sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum;
- sizeAtExpanding[orientation] = ad->sizeAtExpanding;
}
- // Delete the constraints, we won't use them anymore.
- qDeleteAll(sizeHintConstraints);
- sizeHintConstraints.clear();
+#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
+ lastCalculationUsedSimplex[orientation] = needsSimplex;
+#endif
- // 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.
+ return feasible;
+}
- // Solve the other only for preferred, skip trunk
- if (feasible) {
- for (int i = 1; i < parts.count(); ++i) {
- QList<QSimplexConstraint *> partConstraints = parts[i];
- QList<AnchorData *> partVariables = getVariables(partConstraints);
- Q_ASSERT(!partVariables.isEmpty());
-
- sizeHintConstraints = constraintsFromSizeHints(partVariables);
- partConstraints += sizeHintConstraints;
- feasible &= solvePreferred(partConstraints);
- if (!feasible)
- break;
-
- // Propagate size at preferred to other sizes. Semi-floats
- // always will be in their sizeAtPreferred.
- for (int j = 0; j < partVariables.count(); ++j) {
- AnchorData *ad = partVariables[j];
- Q_ASSERT(ad);
- ad->sizeAtMinimum = ad->sizeAtPreferred;
- ad->sizeAtExpanding = ad->sizeAtPreferred;
- ad->sizeAtMaximum = ad->sizeAtPreferred;
- ad->updateChildrenSizes();
- }
+/*!
+ \internal
+*/
+bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables)
+{
+ QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
+ bool feasible = solvePreferred(constraints + sizeHintConstraints, variables);
- // Delete the constraints, we won't use them anymore.
- qDeleteAll(sizeHintConstraints);
- sizeHintConstraints.clear();
+ 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;
}
}
- 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(); // ###
+ qDeleteAll(sizeHintConstraints);
+ return feasible;
}
/*!
- \internal
+ \internal
- For graph edges ("anchors") that represent items, this method updates their
- intrinsic size restrictions, based on the item size hints.
+ Traverse the graph refreshing the size hints. Edges will query their associated
+ item or graphicsAnchor for their size hints.
*/
-void QGraphicsAnchorLayoutPrivate::setAnchorSizeHintsFromItems(Orientation orientation)
+void QGraphicsAnchorLayoutPrivate::refreshAllSizeHints(Orientation orientation)
{
Graph<AnchorVertex, AnchorData> &g = graph[orientation];
QList<QPair<AnchorVertex *, AnchorVertex *> > vertices = g.connections();
- qreal spacing = effectiveSpacing(orientation);
-
+ QLayoutStyleInfo styleInf = styleInfo();
for (int i = 0; i < vertices.count(); ++i) {
- AnchorData *data = g.edgeData(vertices.at(i).first, vertices.at(i).second);;
- Q_ASSERT(data->from && data->to);
- data->refreshSizeHints(spacing);
+ AnchorData *data = g.edgeData(vertices.at(i).first, vertices.at(i).second);
+ data->refreshSizeHints(&styleInf);
}
}
@@ -1811,7 +2174,7 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
QSet<AnchorData *> visited;
- AnchorVertex *root = graph[orientation].rootVertex();
+ AnchorVertex *root = layoutFirstVertex[orientation];
graphPaths[orientation].insert(root, GraphPath());
@@ -1869,13 +2232,27 @@ void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
QList<GraphPath> pathsToVertex = graphPaths[orientation].values(vertex);
for (int i = 1; i < valueCount; ++i) {
constraints[orientation] += \
- pathsToVertex[0].constraint(pathsToVertex[i]);
+ 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
@@ -1883,17 +2260,72 @@ void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
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.
+ if (layoutEdge->maxSize < QWIDGETSIZE_MAX)
+ 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) {
- QSimplexConstraint *c = new QSimplexConstraint;
- c->variables.insert(anchors[i], 1.0);
- c->constant = anchors[i]->minSize;
- c->ratio = QSimplexConstraint::MoreOrEqual;
- anchorConstraints += c;
+ 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;
+
+ if ((ad->minSize == ad->maxSize) || qFuzzyCompare(ad->minSize, ad->maxSize)) {
+ QSimplexConstraint *c = new QSimplexConstraint;
+ c->variables.insert(ad, 1.0);
+ c->constant = ad->minSize;
+ c->ratio = QSimplexConstraint::Equal;
+ anchorConstraints += c;
+ unboundedProblem = false;
+ } else {
+ QSimplexConstraint *c = new QSimplexConstraint;
+ c->variables.insert(ad, 1.0);
+ c->constant = ad->minSize;
+ 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(anchors[i], 1.0);
- c->constant = anchors[i]->maxSize;
+ c = new QSimplexConstraint;
+ c->variables.insert(ad, 1.0);
+ c->constant = ad->maxSize;
+ 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);
+ c->constant = QWIDGETSIZE_MAX;
c->ratio = QSimplexConstraint::LessOrEqual;
anchorConstraints += c;
}
@@ -1907,38 +2339,26 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
QList< QList<QSimplexConstraint *> >
QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
{
- Q_Q(QGraphicsAnchorLayout);
-
- // Find layout vertices and edges for the current orientation.
- AnchorVertex *layoutFirstVertex = \
- internalVertex(q, pickEdge(Qt::AnchorLeft, orientation));
-
- AnchorVertex *layoutCentralVertex = \
- internalVertex(q, pickEdge(Qt::AnchorHorizontalCenter, orientation));
-
- AnchorVertex *layoutLastVertex = \
- internalVertex(q, pickEdge(Qt::AnchorRight, orientation));
+ Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]);
- Q_ASSERT(layoutFirstVertex && layoutLastVertex);
-
- AnchorData *edgeL1 = NULL;
- AnchorData *edgeL2 = NULL;
+ 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) {
- edgeL1 = graph[orientation].edgeData(layoutFirstVertex, layoutCentralVertex);
- edgeL2 = graph[orientation].edgeData(layoutCentralVertex, layoutLastVertex);
+ 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, layoutLastVertex);
+ edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]);
}
QLinkedList<QSimplexConstraint *> remainingConstraints;
for (int i = 0; i < constraints[orientation].count(); ++i) {
- remainingConstraints += constraints[orientation][i];
+ remainingConstraints += constraints[orientation].at(i);
}
for (int i = 0; i < itemCenterConstraints[orientation].count(); ++i) {
- remainingConstraints += itemCenterConstraints[orientation][i];
+ remainingConstraints += itemCenterConstraints[orientation].at(i);
}
QList<QSimplexConstraint *> trunkConstraints;
@@ -2035,8 +2455,8 @@ void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems_helper(const AnchorData
switch(ad->type) {
case AnchorData::Normal:
- if (ad->from->m_item == ad->to->m_item && ad->to->m_item != q)
- nonFloatingItemsIdentifiedSoFar->insert(ad->to->m_item);
+ 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)
@@ -2120,7 +2540,7 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
QSet<AnchorVertex *> visited;
// Get root vertex
- AnchorVertex *root = graph[orientation].rootVertex();
+ AnchorVertex *root = layoutFirstVertex[orientation];
root->distance = 0;
visited.insert(root);
@@ -2133,20 +2553,16 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
// Do initial calculation required by "interpolateEdge()"
setupEdgesInterpolation(orientation);
- // Traverse the graph and calculate vertex positions, we need to
- // visit all pairs since each of them could have a sequential
- // anchor inside, which hides more vertices.
+ // 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);
- // Both vertices were interpolated, and the anchor itself can't have other
- // anchors inside (it's not a complex anchor).
- if (edge->type == AnchorData::Normal && visited.contains(pair.second))
+ if (visited.contains(pair.second))
continue;
visited.insert(pair.second);
- interpolateEdge(pair.first, edge, orientation);
+ interpolateEdge(pair.first, edge);
QList<AnchorVertex *> adjacents = graph[orientation].adjacentVertices(pair.second);
for (int i = 0; i < adjacents.count(); ++i) {
@@ -2160,150 +2576,62 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
\internal
Calculate interpolation parameters based on current Layout Size.
- Must once before calling "interpolateEdgeSize()" for each edge.
+ Must be called once before calling "interpolateEdgeSize()" for
+ the edges.
*/
void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
Orientation orientation)
{
Q_Q(QGraphicsAnchorLayout);
- qreal lower, upper, current;
- if (orientation == Horizontal) {
- current = q->contentsRect().width();
- } else {
- current = q->contentsRect().height();
- }
+ qreal current;
+ current = (orientation == Horizontal) ? q->contentsRect().width() : q->contentsRect().height();
- if (current < sizeHints[orientation][Qt::PreferredSize]) {
- interpolationInterval[orientation] = MinToPreferred;
- lower = sizeHints[orientation][Qt::MinimumSize];
- upper = sizeHints[orientation][Qt::PreferredSize];
- } else if (current < sizeAtExpanding[orientation]) {
- interpolationInterval[orientation] = PreferredToExpanding;
- lower = sizeHints[orientation][Qt::PreferredSize];
- upper = sizeAtExpanding[orientation];
- } else {
- interpolationInterval[orientation] = ExpandingToMax;
- lower = sizeAtExpanding[orientation];
- upper = sizeHints[orientation][Qt::MaximumSize];
- }
+ QPair<Interval, qreal> result;
+ result = getFactor(current,
+ sizeHints[orientation][Qt::MinimumSize],
+ sizeHints[orientation][Qt::PreferredSize],
+ sizeHints[orientation][Qt::MaximumSize]);
- if (upper == lower) {
- interpolationProgress[orientation] = 0;
- } else {
- interpolationProgress[orientation] = (current - lower) / (upper - lower);
- }
+ 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:
+ \internal
- - minimum size,
- - preferred size,
- - size when all expanding anchors are expanded,
- - maximum size.
+ 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:
- 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.
+ - minimum size,
+ - preferred size,
+ - maximum size.
- If the edge is sequential or parallel, it's possible to have more
- vertices to be initalized, so it calls specialized functions that
- will recurse back to interpolateEdge().
- */
-void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base,
- AnchorData *edge,
- Orientation orientation)
-{
- qreal lower, upper;
-
- if (interpolationInterval[orientation] == MinToPreferred) {
- lower = edge->sizeAtMinimum;
- upper = edge->sizeAtPreferred;
- } else if (interpolationInterval[orientation] == PreferredToExpanding) {
- lower = edge->sizeAtPreferred;
- upper = edge->sizeAtExpanding;
- } else {
- lower = edge->sizeAtExpanding;
- upper = edge->sizeAtMaximum;
- }
+ 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 = (interpolationProgress[orientation] * (upper - lower)) + lower;
+ qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred,
+ edge->sizeAtMaximum);
Q_ASSERT(edge->from == base || edge->to == base);
- if (edge->from == base)
+ // Calculate the distance for the vertex opposite to the base
+ if (edge->from == base) {
edge->to->distance = base->distance + edgeDistance;
- else
+ } else {
edge->from->distance = base->distance - edgeDistance;
+ }
+}
- // Process child anchors
- if (edge->type == AnchorData::Sequential)
- interpolateSequentialEdges(edge->from,
- static_cast<SequentialAnchorData *>(edge),
- orientation);
- else if (edge->type == AnchorData::Parallel)
- interpolateParallelEdges(edge->from,
- static_cast<ParallelAnchorData *>(edge),
- orientation);
-}
-
-void QGraphicsAnchorLayoutPrivate::interpolateParallelEdges(
- AnchorVertex *base, ParallelAnchorData *data, Orientation orientation)
-{
- // In parallels the boundary vertices are already calculate, we
- // just need to look for sequential groups inside, because only
- // them may have new vertices associated.
-
- // First edge
- if (data->firstEdge->type == AnchorData::Sequential)
- interpolateSequentialEdges(base,
- static_cast<SequentialAnchorData *>(data->firstEdge),
- orientation);
- else if (data->firstEdge->type == AnchorData::Parallel)
- interpolateParallelEdges(base,
- static_cast<ParallelAnchorData *>(data->firstEdge),
- orientation);
-
- // Second edge
- if (data->secondEdge->type == AnchorData::Sequential)
- interpolateSequentialEdges(base,
- static_cast<SequentialAnchorData *>(data->secondEdge),
- orientation);
- else if (data->secondEdge->type == AnchorData::Parallel)
- interpolateParallelEdges(base,
- static_cast<ParallelAnchorData *>(data->secondEdge),
- orientation);
-}
-
-void QGraphicsAnchorLayoutPrivate::interpolateSequentialEdges(
- AnchorVertex *base, SequentialAnchorData *data, Orientation orientation)
-{
- AnchorVertex *prev = base;
-
- // ### I'm not sure whether this assumption is safe. If not,
- // consider that m_edges.last() could be used instead (so
- // at(0) would be the one to be treated specially).
- Q_ASSERT(base == data->m_edges.at(0)->to || base == data->m_edges.at(0)->from);
-
- // Skip the last
- for (int i = 0; i < data->m_edges.count() - 1; ++i) {
- AnchorData *child = data->m_edges.at(i);
- interpolateEdge(prev, child, orientation);
- prev = child->to;
- }
-
- // Treat the last specially, since we already calculated it's end
- // vertex, so it's only interesting if it's a complex one
- if (data->m_edges.last()->type != AnchorData::Normal)
- interpolateEdge(prev, data->m_edges.last(), orientation);
-}
-
-bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList<QSimplexConstraint *> constraints,
+bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *> &constraints,
GraphPath path, qreal *min, qreal *max)
{
QSimplex simplex;
@@ -2324,11 +2652,12 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList<QSimplexConstraint *> const
*min = simplex.solveMin();
// Save sizeAtMinimum results
- QList<QSimplexVariable *> variables = simplex.constraintsVariables();
+ QList<AnchorData *> variables = getVariables(constraints);
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
- Q_ASSERT(ad->result >= ad->minSize || qFuzzyCompare(ad->result, ad->minSize));
+ AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
ad->sizeAtMinimum = ad->result;
+ Q_ASSERT(ad->sizeAtMinimum >= ad->minSize ||
+ qAbs(ad->sizeAtMinimum - ad->minSize) < 0.00000001);
}
// Calculate maximum values
@@ -2336,17 +2665,18 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList<QSimplexConstraint *> const
// Save sizeAtMaximum results
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
- Q_ASSERT(ad->result <= ad->maxSize || qFuzzyCompare(ad->result, ad->maxSize));
+ AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
ad->sizeAtMaximum = ad->result;
+ // Q_ASSERT(ad->sizeAtMaximum <= ad->maxSize ||
+ // qAbs(ad->sizeAtMaximum - ad->maxSize) < 0.00000001);
}
}
return feasible;
}
-bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> constraints)
+bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables)
{
- QList<AnchorData *> variables = getVariables(constraints);
QList<QSimplexConstraint *> preferredConstraints;
QList<QSimplexVariable *> preferredVariables;
QSimplexConstraint objective;
@@ -2369,7 +2699,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> co
// A + A_shrinker - A_grower = A_pref
//
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
+ AnchorData *ad = variables.at(i);
if (ad->skipInPreferred)
continue;
@@ -2400,7 +2730,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> co
// Save sizeAtPreferred results
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
+ AnchorData *ad = variables.at(i);
ad->sizeAtPreferred = ad->result;
}
@@ -2417,139 +2747,6 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> co
/*!
\internal
- Calculate the "expanding" keyframe
-
- This new keyframe sits between the already existing sizeAtPreferred and
- sizeAtMaximum keyframes. Its goal is to modify the interpolation between
- the latter as to respect the "expanding" size policy of some anchors.
-
- Previously all items would be subject to a linear interpolation between
- sizeAtPreferred and sizeAtMaximum values. This will change now, the
- expanding anchors will change their size before the others. To calculate
- this keyframe we use the following logic:
-
- 1) Ask each anchor for their desired expanding size (ad->expSize), this
- value depends on the anchor expanding property in the following way:
-
- - Expanding normal anchors want to grow towards their maximum size
- - Non-expanding normal anchors want to remain at their preferred size.
- - Sequential anchors wants to grow towards a size that is calculated by:
- summarizing it's child anchors, where it will use preferred size for non-expanding anchors
- and maximum size for expanding anchors.
- - Parallel anchors want to grow towards the smallest maximum size of all the expanding anchors.
-
- 2) Clamp their desired values to the value they assume in the neighbour
- keyframes (sizeAtPreferred and sizeAtExpanding)
-
- 3) Run simplex with a setup that ensures the following:
-
- a. Anchors will change their value from their sizeAtPreferred towards
- their sizeAtMaximum as much as required to ensure that ALL anchors
- reach their respective "desired" expanding sizes.
-
- b. No anchors will change their value beyond what is NEEDED to satisfy
- the requirement above.
-
- The final result is that, at the "expanding" keyframe expanding anchors
- will grow and take with them all anchors that are parallel to them.
- However, non-expanding anchors will remain at their preferred size unless
- they are forced to grow by a parallel expanding anchor.
-
- Note: For anchors where the sizeAtPreferred is bigger than sizeAtMaximum,
- the visual effect when the layout grows from its preferred size is
- the following: Expanding anchors will keep their size while non
- expanding ones will shrink. Only after non-expanding anchors have
- shrinked all the way, the expanding anchors will start to shrink too.
-*/
-void QGraphicsAnchorLayoutPrivate::solveExpanding(QList<QSimplexConstraint *> constraints)
-{
- QList<AnchorData *> variables = getVariables(constraints);
- QList<QSimplexConstraint *> itemConstraints;
- QSimplexConstraint *objective = new QSimplexConstraint;
- bool hasExpanding = false;
-
- // Construct the simplex constraints and objective
- for (int i = 0; i < variables.size(); ++i) {
- // For each anchor
- AnchorData *ad = variables[i];
-
- // Clamp the desired expanding size
- qreal upperBoundary = qMax(ad->sizeAtPreferred, ad->sizeAtMaximum);
- qreal lowerBoundary = qMin(ad->sizeAtPreferred, ad->sizeAtMaximum);
- qreal boundedExpSize = qBound(lowerBoundary, ad->expSize, upperBoundary);
-
- // Expanding anchors are those that want to move from their preferred size
- if (boundedExpSize != ad->sizeAtPreferred)
- hasExpanding = true;
-
- // Lock anchor between boundedExpSize and sizeAtMaximum (ensure 3.a)
- if (boundedExpSize == ad->sizeAtMaximum) {
- // The interval has only one possible value, we can use an "Equal"
- // constraint and don't need to add this variable to the objective.
- QSimplexConstraint *itemC = new QSimplexConstraint;
- itemC->ratio = QSimplexConstraint::Equal;
- itemC->variables.insert(ad, 1.0);
- itemC->constant = boundedExpSize;
- itemConstraints << itemC;
- } else {
- // Add MoreOrEqual and LessOrEqual constraints.
- QSimplexConstraint *itemC = new QSimplexConstraint;
- itemC->ratio = QSimplexConstraint::MoreOrEqual;
- itemC->variables.insert(ad, 1.0);
- itemC->constant = qMin(boundedExpSize, ad->sizeAtMaximum);
- itemConstraints << itemC;
-
- itemC = new QSimplexConstraint;
- itemC->ratio = QSimplexConstraint::LessOrEqual;
- itemC->variables.insert(ad, 1.0);
- itemC->constant = qMax(boundedExpSize, ad->sizeAtMaximum);
- itemConstraints << itemC;
-
- // Create objective to avoid the anchors from moving away from
- // the preferred size more than the needed amount. (ensure 3.b)
- // The objective function is the distance between sizeAtPreferred
- // and sizeAtExpanding, it will be minimized.
- if (ad->sizeAtExpanding < ad->sizeAtMaximum) {
- // Try to shrink this variable towards its sizeAtPreferred value
- objective->variables.insert(ad, 1.0);
- } else {
- // Try to grow this variable towards its sizeAtPreferred value
- objective->variables.insert(ad, -1.0);
- }
- }
- }
-
- // Solve
- if (hasExpanding == false) {
- // If no anchors are expanding, we don't need to run the simplex
- // Set all variables to their preferred size
- for (int i = 0; i < variables.size(); ++i) {
- variables[i]->sizeAtExpanding = variables[i]->sizeAtPreferred;
- }
- } else {
- // Run simplex
- QSimplex simplex;
-
- // Satisfy expanding (3.a)
- bool feasible = simplex.setConstraints(constraints + itemConstraints);
- Q_ASSERT(feasible);
-
- // Reduce damage (3.b)
- simplex.setObjective(objective);
- simplex.solveMin();
-
- // Collect results
- for (int i = 0; i < variables.size(); ++i) {
- variables[i]->sizeAtExpanding = variables[i]->result;
- }
- }
-
- delete objective;
- qDeleteAll(itemConstraints);
-}
-
-/*!
- \internal
Returns true if there are no arrangement that satisfies all constraints.
Otherwise returns false.
@@ -2566,9 +2763,9 @@ bool QGraphicsAnchorLayoutPrivate::hasConflicts() const
}
#ifdef QT_DEBUG
-void QGraphicsAnchorLayoutPrivate::dumpGraph()
+void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name)
{
- QFile file(QString::fromAscii("anchorlayout.dot"));
+ 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());
@@ -2582,3 +2779,4 @@ void QGraphicsAnchorLayoutPrivate::dumpGraph()
#endif
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
index 9ac0e19cd5..2b365fb14e 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
@@ -60,7 +60,7 @@
#include "qgraphicsanchorlayout.h"
#include "qgraph_p.h"
#include "qsimplex_p.h"
-
+#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
/*
@@ -78,66 +78,30 @@ QT_BEGIN_NAMESPACE
Represents a vertex (anchorage point) in the internal graph
*/
struct AnchorVertex {
+ enum Type {
+ Normal = 0,
+ Pair
+ };
+
AnchorVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
- : m_item(item), m_edge(edge) {}
+ : m_item(item), m_edge(edge), m_type(Normal) {}
AnchorVertex()
- : m_item(0), m_edge(Qt::AnchorPoint(0)) {}
+ : m_item(0), m_edge(Qt::AnchorPoint(0)), m_type(Normal) {}
#ifdef QT_DEBUG
inline QString toString() const;
#endif
+
QGraphicsLayoutItem *m_item;
Qt::AnchorPoint m_edge;
+ uint m_type : 1;
// Current distance from this vertex to the layout edge (Left or Top)
// Value is calculated from the current anchors sizes.
qreal distance;
};
-#ifdef QT_DEBUG
-inline QString AnchorVertex::toString() const
-{
- if (!this || !m_item) {
- return QLatin1String("NULL");
- }
- QString edge;
- switch (m_edge) {
- case Qt::AnchorLeft:
- edge = QLatin1String("Left");
- break;
- case Qt::AnchorHorizontalCenter:
- edge = QLatin1String("HorizontalCenter");
- break;
- case Qt::AnchorRight:
- edge = QLatin1String("Right");
- break;
- case Qt::AnchorTop:
- edge = QLatin1String("Top");
- break;
- case Qt::AnchorVerticalCenter:
- edge = QLatin1String("VerticalCenter");
- break;
- case Qt::AnchorBottom:
- edge = QLatin1String("Bottom");
- break;
- default:
- edge = QLatin1String("None");
- break;
- }
- QString itemName;
- if (m_item->isLayout()) {
- itemName = QLatin1String("layout");
- } else {
- if (QGraphicsItem *item = m_item->graphicsItem()) {
- itemName = item->data(0).toString();
- }
- }
- edge.insert(0, QLatin1String("%1_"));
- return edge.arg(itemName);
-}
-#endif
-
/*!
\internal
@@ -150,16 +114,24 @@ struct AnchorData : public QSimplexVariable {
Parallel
};
+ enum Dependency {
+ Independent = 0,
+ Master,
+ Slave
+ };
+
AnchorData()
: QSimplexVariable(), from(0), to(0),
- minSize(0), prefSize(0), expSize(0), maxSize(0),
+ minSize(0), prefSize(0), maxSize(0),
sizeAtMinimum(0), sizeAtPreferred(0),
- sizeAtExpanding(0), sizeAtMaximum(0),
+ sizeAtMaximum(0), item(0),
graphicsAnchor(0), skipInPreferred(0),
- type(Normal), hasSize(true), isLayoutAnchor(false) {}
+ type(Normal), isLayoutAnchor(false),
+ isCenterAnchor(false), orientation(0),
+ dependency(Independent) {}
virtual void updateChildrenSizes() {}
- virtual void refreshSizeHints(qreal effectiveSpacing);
+ void refreshSizeHints(const QLayoutStyleInfo *styleInfo = 0);
virtual ~AnchorData() {}
@@ -169,50 +141,40 @@ struct AnchorData : public QSimplexVariable {
QString name;
#endif
- inline void setFixedSize(qreal size)
- {
- minSize = size;
- prefSize = size;
- expSize = size;
- maxSize = size;
- sizeAtMinimum = size;
- sizeAtPreferred = size;
- sizeAtExpanding = size;
- sizeAtMaximum = size;
- hasSize = true;
- }
-
- inline void unsetSize()
- {
- hasSize = false;
- }
-
// Anchor is semantically directed
AnchorVertex *from;
AnchorVertex *to;
- // Size restrictions of this edge. For anchors internal to items, these
- // values are derived from the respective item size hints. For anchors
- // that were added by users, these values are equal to the specified anchor
- // size.
+ // Nominal sizes
+ // These are the intrinsic size restrictions for a given item. They are
+ // used as input for the calculation of the actual sizes.
+ // These values are filled by the refreshSizeHints method, based on the
+ // anchor size policy, the size hints of the item it (possibly) represents
+ // and the layout spacing information.
qreal minSize;
qreal prefSize;
- qreal expSize;
qreal maxSize;
+ // Calculated sizes
// These attributes define which sizes should that anchor be in when the
// layout is at its minimum, preferred or maximum sizes. Values are
// calculated by the Simplex solver based on the current layout setup.
qreal sizeAtMinimum;
qreal sizeAtPreferred;
- qreal sizeAtExpanding;
qreal sizeAtMaximum;
+
+ // References to the classes that represent this anchor in the public world
+ // An anchor may represent a LayoutItem, it may also be acessible externally
+ // through a GraphicsAnchor "handler".
+ QGraphicsLayoutItem *item;
QGraphicsAnchor *graphicsAnchor;
uint skipInPreferred : 1;
uint type : 2; // either Normal, Sequential or Parallel
- uint hasSize : 1; // if false, get size from style.
- uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge'
+ uint isLayoutAnchor : 1; // if this anchor is an internal layout anchor
+ uint isCenterAnchor : 1;
+ uint orientation : 1;
+ uint dependency : 2; // either Independent, Master or Slave
};
#ifdef QT_DEBUG
@@ -224,26 +186,18 @@ inline QString AnchorData::toString() const
struct SequentialAnchorData : public AnchorData
{
- SequentialAnchorData() : AnchorData()
+ SequentialAnchorData(const QVector<AnchorVertex *> &vertices, const QVector<AnchorData *> &edges)
+ : AnchorData(), m_children(vertices), m_edges(edges)
{
type = AnchorData::Sequential;
+ orientation = m_edges.at(0)->orientation;
#ifdef QT_DEBUG
- name = QLatin1String("SequentialAnchorData");
+ name = QString::fromAscii("%1 -- %2").arg(vertices.first()->toString(), vertices.last()->toString());
#endif
}
virtual void updateChildrenSizes();
- virtual void refreshSizeHints(qreal effectiveSpacing);
-
- void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true);
-
- void setVertices(const QVector<AnchorVertex*> &vertices)
- {
- m_children = vertices;
-#ifdef QT_DEBUG
- name = QString::fromAscii("%1 -- %2").arg(vertices.first()->toString(), vertices.last()->toString());
-#endif
- }
+ void calculateSizeHints();
QVector<AnchorVertex*> m_children; // list of vertices in the sequence
QVector<AnchorData*> m_edges; // keep the list of edges too.
@@ -255,11 +209,13 @@ struct ParallelAnchorData : public AnchorData
: AnchorData(), firstEdge(first), secondEdge(second)
{
type = AnchorData::Parallel;
+ orientation = first->orientation;
- // ### Those asserts force that both child anchors have the same direction,
- // but can't we simplify a pair of anchors in opposite directions?
- Q_ASSERT(first->from == second->from);
- Q_ASSERT(first->to == second->to);
+ // This assert whether the child anchors share their vertices
+ Q_ASSERT(((first->from == second->from) && (first->to == second->to)) ||
+ ((first->from == second->to) && (first->to == second->from)));
+
+ // We arbitrarily choose the direction of the first child as "our" direction
from = first->from;
to = first->to;
#ifdef QT_DEBUG
@@ -268,14 +224,77 @@ struct ParallelAnchorData : public AnchorData
}
virtual void updateChildrenSizes();
- virtual void refreshSizeHints(qreal effectiveSpacing);
-
- void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true);
+ bool calculateSizeHints();
AnchorData* firstEdge;
AnchorData* secondEdge;
+
+ QList<QSimplexConstraint *> m_firstConstraints;
+ QList<QSimplexConstraint *> m_secondConstraints;
};
+struct AnchorVertexPair : public AnchorVertex {
+ AnchorVertexPair(AnchorVertex *v1, AnchorVertex *v2, AnchorData *data)
+ : AnchorVertex(), m_first(v1), m_second(v2), m_removedAnchor(data) {
+ m_type = AnchorVertex::Pair;
+ }
+
+ AnchorVertex *m_first;
+ AnchorVertex *m_second;
+
+ AnchorData *m_removedAnchor;
+ QList<AnchorData *> m_firstAnchors;
+ QList<AnchorData *> m_secondAnchors;
+};
+
+#ifdef QT_DEBUG
+inline QString AnchorVertex::toString() const
+{
+ if (!this) {
+ return QLatin1String("NULL");
+ } else if (m_type == Pair) {
+ const AnchorVertexPair *vp = static_cast<const AnchorVertexPair *>(this);
+ return QString::fromAscii("(%1, %2)").arg(vp->m_first->toString()).arg(vp->m_second->toString());
+ } else if (!m_item) {
+ return QString::fromAscii("NULL_%1").arg(quintptr(this));
+ }
+ QString edge;
+ switch (m_edge) {
+ case Qt::AnchorLeft:
+ edge = QLatin1String("Left");
+ break;
+ case Qt::AnchorHorizontalCenter:
+ edge = QLatin1String("HorizontalCenter");
+ break;
+ case Qt::AnchorRight:
+ edge = QLatin1String("Right");
+ break;
+ case Qt::AnchorTop:
+ edge = QLatin1String("Top");
+ break;
+ case Qt::AnchorVerticalCenter:
+ edge = QLatin1String("VerticalCenter");
+ break;
+ case Qt::AnchorBottom:
+ edge = QLatin1String("Bottom");
+ break;
+ default:
+ edge = QLatin1String("None");
+ break;
+ }
+ QString itemName;
+ if (m_item->isLayout()) {
+ itemName = QLatin1String("layout");
+ } else {
+ if (QGraphicsItem *item = m_item->graphicsItem()) {
+ itemName = item->data(0).toString();
+ }
+ }
+ edge.insert(0, QLatin1String("%1_"));
+ return edge.arg(itemName);
+}
+#endif
+
/*!
\internal
@@ -316,8 +335,17 @@ public:
void unsetSpacing();
qreal spacing() const;
+ void setSizePolicy(QSizePolicy::Policy policy);
+
QGraphicsAnchorLayoutPrivate *layoutPrivate;
AnchorData *data;
+
+ // Size information for user controlled anchor
+ QSizePolicy::Policy sizePolicy;
+ qreal preferredSize;
+
+ uint hasSize : 1; // if false, get size from style.
+ uint reversed : 1; // if true, the anchor was inverted to keep its value positive
};
@@ -340,8 +368,7 @@ public:
// Interval represents which interpolation interval are we operating in.
enum Interval {
MinToPreferred = 0,
- PreferredToExpanding,
- ExpandingToMax
+ PreferredToMax
};
// Several structures internal to the layout are duplicated to handle
@@ -413,11 +440,6 @@ public:
void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex);
void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2);
- void setAnchorSize(AnchorData *data, const qreal *anchorSize);
- void anchorSize(const AnchorData *data,
- qreal *minSize = 0,
- qreal *prefSize = 0,
- qreal *maxSize = 0) const;
void removeAnchors(QGraphicsLayoutItem *item);
@@ -427,20 +449,40 @@ public:
Qt::AnchorPoint &firstEdge,
QGraphicsLayoutItem *&secondItem,
Qt::AnchorPoint &secondEdge);
- // for getting the actual spacing (will query the style if the
- // spacing is not explicitly set).
- qreal effectiveSpacing(Orientation orientation) const;
- // Activation methods
- void simplifyGraph(Orientation orientation);
- bool simplifyGraphIteration(Orientation orientation);
- void restoreSimplifiedGraph(Orientation orientation);
+ QLayoutStyleInfo &styleInfo() const;
+
+ AnchorData *addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible);
+ // Activation
void calculateGraphs();
void calculateGraphs(Orientation orientation);
- void setAnchorSizeHintsFromItems(Orientation orientation);
+
+ // Simplification
+ bool simplifyGraph(Orientation orientation);
+ bool simplifyVertices(Orientation orientation);
+ bool simplifyGraphIteration(Orientation orientation, bool *feasible);
+
+ bool replaceVertex(Orientation orientation, AnchorVertex *oldV,
+ AnchorVertex *newV, const QList<AnchorData *> &edges);
+
+
+ void restoreSimplifiedGraph(Orientation orientation);
+ void restoreSimplifiedAnchor(AnchorData *edge);
+ void restoreSimplifiedConstraints(ParallelAnchorData *parallel);
+ void restoreVertices(Orientation orientation);
+
+ bool calculateTrunk(Orientation orientation, const GraphPath &trunkPath,
+ const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables);
+ bool calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables);
+
+ // Support functions for calculateGraph()
+ void refreshAllSizeHints(Orientation orientation);
void findPaths(Orientation orientation);
void constraintsFromPaths(Orientation orientation);
+ void updateAnchorSizes(Orientation orientation);
QList<QSimplexConstraint *> constraintsFromSizeHints(const QList<AnchorData *> &anchors);
QList<QList<QSimplexConstraint *> > getGraphParts(Orientation orientation);
void identifyFloatItems(const QSet<AnchorData *> &visited, Orientation orientation);
@@ -456,6 +498,17 @@ public:
return internalVertex(qMakePair(const_cast<QGraphicsLayoutItem *>(item), edge));
}
+ inline void changeLayoutVertex(Orientation orientation, AnchorVertex *oldV, AnchorVertex *newV)
+ {
+ if (layoutFirstVertex[orientation] == oldV)
+ layoutFirstVertex[orientation] = newV;
+ else if (layoutCentralVertex[orientation] == oldV)
+ layoutCentralVertex[orientation] = newV;
+ else if (layoutLastVertex[orientation] == oldV)
+ layoutLastVertex[orientation] = newV;
+ }
+
+
AnchorVertex *addInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
void removeInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
@@ -464,28 +517,23 @@ public:
void calculateVertexPositions(Orientation orientation);
void setupEdgesInterpolation(Orientation orientation);
- void interpolateEdge(AnchorVertex *base, AnchorData *edge, Orientation orientation);
- void interpolateSequentialEdges(AnchorVertex *base, SequentialAnchorData *edge,
- Orientation orientation);
- void interpolateParallelEdges(AnchorVertex *base, ParallelAnchorData *edge,
- Orientation orientation);
+ void interpolateEdge(AnchorVertex *base, AnchorData *edge);
// Linear Programming solver methods
- bool solveMinMax(QList<QSimplexConstraint *> constraints,
+ bool solveMinMax(const QList<QSimplexConstraint *> &constraints,
GraphPath path, qreal *min, qreal *max);
- bool solvePreferred(QList<QSimplexConstraint *> constraints);
- void solveExpanding(QList<QSimplexConstraint *> constraints);
+ bool solvePreferred(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables);
bool hasConflicts() const;
#ifdef QT_DEBUG
- void dumpGraph();
+ void dumpGraph(const QString &name = QString());
#endif
qreal spacings[NOrientations];
// Size hints from simplex engine
qreal sizeHints[2][3];
- qreal sizeAtExpanding[2];
// Items
QVector<QGraphicsLayoutItem *> items;
@@ -498,6 +546,14 @@ public:
// Internal graph of anchorage points and anchors, for both orientations
Graph<AnchorVertex, AnchorData> graph[2];
+ AnchorVertex *layoutFirstVertex[2];
+ AnchorVertex *layoutCentralVertex[2];
+ AnchorVertex *layoutLastVertex[2];
+
+ // Combined anchors in order of creation
+ QList<AnchorVertexPair *> simplifiedVertices[2];
+ QList<AnchorData *> anchorsFromSimplifiedVertices[2];
+
// Graph paths and constraints, for both orientations
QMultiHash<AnchorVertex *, GraphPath> graphPaths[2];
QList<QSimplexConstraint *> constraints[2];
@@ -508,14 +564,21 @@ public:
Interval interpolationInterval[2];
qreal interpolationProgress[2];
- // ###
- bool graphSimplified[2];
bool graphHasConflicts[2];
QSet<QGraphicsLayoutItem *> m_floatItems[2];
+#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
+ bool lastCalculationUsedSimplex[2];
+#endif
+
uint calculateGraphCacheDirty : 1;
+ mutable uint styleInfoDirty : 1;
+ mutable QLayoutStyleInfo cachedStyleInfo;
+
+ friend class QGraphicsAnchorPrivate;
};
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSVIEW
#endif
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp
index d1d91dbad8..9a8dba0c93 100644
--- a/src/gui/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp
@@ -63,7 +63,7 @@
You can access each item in the layout by calling count() and itemAt(). Calling
removeAt() will remove an item from the layout, without
destroying it.
-
+
\sa QGraphicsLinearLayout, QGraphicsWidget
*/
@@ -89,7 +89,7 @@ public:
QLayoutStyleInfo styleInfo() const;
QGridLayoutEngine engine;
-#ifdef QT_DEBUG
+#ifdef QT_DEBUG
void dump(int indent) const;
#endif
};
@@ -121,7 +121,7 @@ QGraphicsGridLayout::~QGraphicsGridLayout()
for (int i = count() - 1; i >= 0; --i) {
QGraphicsLayoutItem *item = itemAt(i);
// The following lines can be removed, but this removes the item
- // from the layout more efficiently than the implementation of
+ // from the layout more efficiently than the implementation of
// ~QGraphicsLayoutItem.
removeAt(i);
if (item) {
@@ -141,18 +141,22 @@ void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *item, int row, int column
{
Q_D(QGraphicsGridLayout);
if (row < 0 || column < 0) {
- qWarning("QGraphicsGridLayout::addItem: invalid row/column: %d",
- row < 0 ? row : column);
- return;
+ qWarning("QGraphicsGridLayout::addItem: invalid row/column: %d",
+ row < 0 ? row : column);
+ return;
}
if (columnSpan < 1 || rowSpan < 1) {
- qWarning("QGraphicsGridLayout::addItem: invalid row span/column span: %d",
- rowSpan < 1 ? rowSpan : columnSpan);
- return;
+ qWarning("QGraphicsGridLayout::addItem: invalid row span/column span: %d",
+ rowSpan < 1 ? rowSpan : columnSpan);
+ return;
}
if (!item) {
- qWarning("QGraphicsGridLayout::addItem: cannot add null item");
- return;
+ qWarning("QGraphicsGridLayout::addItem: cannot add null item");
+ return;
+ }
+ if (item == this) {
+ qWarning("QGraphicsGridLayout::addItem: cannot insert itself");
+ return;
}
d->addChildLayoutItem(item);
@@ -647,5 +651,5 @@ QSizePolicy::ControlTypes QGraphicsGridLayout::controlTypes(LayoutSide side) con
#endif
QT_END_NAMESPACE
-
-#endif //QT_NO_GRAPHICSVIEW
+
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 45627f6e83..3f6dff2e4a 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -386,6 +386,12 @@
introduced in Qt 4.6.
\omitvalue ItemIsFocusScope Internal only (for now).
+
+ \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.
*/
/*!
@@ -562,6 +568,14 @@
\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).
*/
/*!
@@ -990,6 +1004,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
if (scene) {
// Deliver the change to the index
scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
+
+ // Disable scene pos notifications for old ancestors
+ if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
+ scene->d_func()->setScenePosItemEnabled(q, false);
}
if (subFocusItem && parent) {
@@ -1039,13 +1057,31 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
// Update focus scope item ptr in new scope.
- if (newParent) {
+ QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
+ if (newFocusScopeItem && newParent) {
+ if (subFocusItem) {
+ // Find the subFocusItem's topmost focus scope.
+ QGraphicsItem *ancestorScope = 0;
+ QGraphicsItem *p = subFocusItem->d_ptr->parent;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope)
+ ancestorScope = p;
+ if (p->isPanel())
+ break;
+ p = p->parentItem();
+ }
+ if (ancestorScope)
+ newFocusScopeItem = ancestorScope;
+ }
+
QGraphicsItem *p = newParent;
while (p) {
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
- p->d_ptr->focusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
- // ### The below line might not make sense...
- if (subFocusItem)
+ p->d_ptr->focusScopeItem = newFocusScopeItem;
+ // 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;
}
@@ -1066,10 +1102,15 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
parent->d_ptr->addChild(q);
parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
- if (!implicitUpdate && scene) {
- scene->d_func()->markDirty(q_ptr, QRect(),
- /*invalidateChildren=*/false,
- /*maybeDirtyClipPath=*/true);
+ if (scene) {
+ if (!implicitUpdate)
+ scene->d_func()->markDirty(q_ptr, QRect(),
+ /*invalidateChildren=*/false,
+ /*maybeDirtyClipPath=*/true);
+
+ // Re-enable scene pos notifications for new ancestors
+ if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
+ scene->d_func()->setScenePosItemEnabled(q, true);
}
// Inherit ancestor flags from the new parent.
@@ -1228,7 +1269,8 @@ void QGraphicsItemCache::purge()
}
/*!
- Constructs a QGraphicsItem with the given \a parent.
+ 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.
@@ -1286,6 +1328,8 @@ QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
*/
QGraphicsItem::~QGraphicsItem()
{
+ if (d_ptr->isObject)
+ QObjectPrivate::get(static_cast<QGraphicsObject *>(this))->wasDeleted = true;
d_ptr->inDestructor = 1;
d_ptr->removeExtraItemCache();
@@ -1315,7 +1359,9 @@ QGraphicsItem::~QGraphicsItem()
d_ptr->setParentItemHelper(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);
@@ -1511,6 +1557,8 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
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 parent have undefined behaviour.
+
\sa parentItem(), childItems()
*/
void QGraphicsItem::setParentItem(QGraphicsItem *parent)
@@ -1655,7 +1703,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags));
// Flags that alter the geometry of the item (or its children).
- const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations);
+ const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
if (fullUpdate)
d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
@@ -1723,6 +1771,12 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
}
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,
/*maybeDirtyClipPath*/true);
@@ -2482,12 +2536,16 @@ void QGraphicsItem::setOpacity(qreal opacity)
itemChange(ItemOpacityHasChanged, newOpacityVariant);
// Update.
- if (d_ptr->scene)
+ if (d_ptr->scene) {
+#ifndef QT_NO_GRAPHICSEFFECT
+ d_ptr->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
d_ptr->scene->d_func()->markDirty(this, QRectF(),
/*invalidateChildren=*/true,
/*maybeDirtyClipPath=*/false,
/*force=*/false,
/*ignoreOpacity=*/true);
+ }
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->opacityChanged();
@@ -2498,6 +2556,7 @@ void QGraphicsItem::setOpacity(qreal opacity)
\since 4.6
*/
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *QGraphicsItem::graphicsEffect() const
{
return d_ptr->graphicsEffect;
@@ -2544,6 +2603,7 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
prepareGeometryChange();
}
+#endif //QT_NO_GRAPHICSEFFECT
/*!
\internal
@@ -2557,6 +2617,7 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
*/
QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
{
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *effect = graphicsEffect;
QRectF brect = effect && effect->isEnabled() ? effect->boundingRect() : q_ptr->boundingRect();
if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
@@ -2573,6 +2634,10 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
}
return brect;
+#else //QT_NO_GRAPHICSEFFECT
+ return q_ptr->boundingRect();
+#endif //QT_NO_GRAPHICSEFFECT
+
}
/*!
@@ -2926,7 +2991,7 @@ bool QGraphicsItem::hasFocus() const
{
if (d_ptr->focusProxy)
return d_ptr->focusProxy->hasFocus();
- return (d_ptr->scene && d_ptr->scene->focusItem() == this);
+ return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this);
}
/*!
@@ -2977,8 +3042,11 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim
while (p) {
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
p->d_ptr->focusScopeItem = q_ptr;
- if (!q_ptr->isActive() || !p->focusItem())
+ if (!p->focusItem()) {
+ // 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;
@@ -3281,6 +3349,9 @@ QPointF QGraphicsItem::pos() const
*/
void QGraphicsItem::setX(qreal x)
{
+ if (d_ptr->inDestructor)
+ return;
+
d_ptr->setPosHelper(QPointF(x, d_ptr->pos.y()));
}
@@ -3302,6 +3373,9 @@ void QGraphicsItem::setX(qreal x)
*/
void QGraphicsItem::setY(qreal y)
{
+ if (d_ptr->inDestructor)
+ return;
+
d_ptr->setPosHelper(QPointF(d_ptr->pos.x(), y));
}
@@ -3367,6 +3441,9 @@ 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)) {
d_ptr->setPosHelper(pos);
@@ -3384,6 +3461,7 @@ void QGraphicsItem::setPos(const QPointF &pos)
// Send post-notification.
itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
+ d_ptr->sendScenePosChange();
}
/*!
@@ -3994,6 +4072,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
// Send post-notification.
itemChange(ItemTransformHasChanged, newTransformVariant);
+ d_ptr->sendScenePosChange();
}
/*!
@@ -4218,6 +4297,24 @@ void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
}
/*!
+ \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
@@ -4259,7 +4356,7 @@ void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
// 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 && d_ptr->z == sibling->d_ptr->z) {
+ if (myIndex >= siblingIndex) {
siblings->move(myIndex, siblingIndex);
// Fixup the insertion ordering.
for (int i = 0; i < siblings->size(); ++i) {
@@ -4268,6 +4365,12 @@ void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
++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();
}
}
@@ -4735,7 +4838,7 @@ bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
{
if (!item)
return false;
- return QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(item, this)
+ return qt_closestItemFirst(item, this)
&& qt_QGraphicsItem_isObscured(this, item, boundingRect());
}
@@ -4949,6 +5052,24 @@ int QGraphicsItemPrivate::depth() const
/*!
\internal
*/
+#ifndef QT_NO_GRAPHICSEFFECT
+void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
+{
+ 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));
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+/*!
+ \internal
+*/
void QGraphicsItemPrivate::invalidateDepthRecursively()
{
if (itemDepth == -1)
@@ -5249,6 +5370,16 @@ void QGraphicsItemPrivate::subFocusItemChange()
/*!
\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
@@ -5280,11 +5411,9 @@ void QGraphicsItem::update(const QRectF &rect)
return;
// Make sure we notify effects about invalidated source.
- QGraphicsItem *item = this;
- do {
- if (item->d_ptr->graphicsEffect)
- item->d_ptr->notifyInvalidated = 1;
- } while ((item = item->d_ptr->parent));
+#ifndef QT_NO_GRAPHICSEFFECT
+ d_ptr->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
if (CacheMode(d_ptr->cacheMode) != NoCache) {
// Invalidate cache.
@@ -7267,6 +7396,21 @@ static void qt_graphicsItem_highlightSelected(
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
*/
/*!
@@ -7288,22 +7432,38 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent
}
/*!
- Subscribes the graphics object to the given \a gesture for the specified \a context.
+ Subscribes the graphics object to the given \a gesture with specific \a flags.
- \sa QGestureEvent
+ \sa ungrabGesture(), QGestureEvent
*/
-
-void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureContext context)
+void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
{
QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
- d->gestureContext.insert(gesture, context);
+ d->gestureContext.insert(gesture, flags);
(void)QGestureManager::instance(); // create a gesture manager
}
/*!
+ Unsubscribes the graphics object from the given \a gesture.
+
+ \sa grabGesture(), QGestureEvent
+*/
+void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
+{
+ QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
+ if (d->gestureContext.remove(gesture)) {
+ QGestureManager *manager = QGestureManager::instance();
+ manager->cleanupCachedGestures(this, gesture);
+ }
+}
+
+/*!
\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()
*/
@@ -9122,10 +9282,14 @@ void QGraphicsPixmapItem::setOffset(const QPointF &offset)
QRectF QGraphicsPixmapItem::boundingRect() const
{
Q_D(const QGraphicsPixmapItem);
- qreal pw = 1.0;
if (d->pixmap.isNull())
return QRectF();
- return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
+ 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());
+ }
}
/*!
@@ -9442,6 +9606,7 @@ void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
QPalette pal = c->palette();
pal.setColor(QPalette::Text, col);
c->setPalette(pal);
+ update();
}
/*!
@@ -9635,12 +9800,14 @@ bool QGraphicsTextItem::sceneEvent(QEvent *event)
// 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;
default:
@@ -10011,9 +10178,10 @@ bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
{
if (flags == Qt::NoTextInteraction)
- setFlags(this->flags() & ~QGraphicsItem::ItemIsFocusable);
+ setFlags(this->flags() & ~(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod));
else
- setFlags(this->flags() | QGraphicsItem::ItemIsFocusable);
+ setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
+
dd->textControl()->setTextInteractionFlags(flags);
}
@@ -10601,6 +10769,7 @@ int QGraphicsItemGroup::type() const
return Type;
}
+#ifndef QT_NO_GRAPHICSEFFECT
QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
@@ -10644,7 +10813,8 @@ void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
}
}
-QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
+QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
+ QGraphicsEffect::PixmapPadMode mode) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
if (!info && deviceCoordinates) {
@@ -10658,7 +10828,17 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
const QRectF sourceRect = boundingRect(system);
- QRect effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
+ QRect effectRect;
+
+ if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
+ effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
+ } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
+ // adjust by 1.5 to account for cosmetic pens
+ effectRect = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5).toAlignedRect();
+ } else {
+ effectRect = sourceRect.toAlignedRect();
+ }
+
if (offset)
*offset = effectRect.topLeft();
@@ -10686,10 +10866,15 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
effectRect.setBottom(deviceHeight -1);
}
-
if (effectRect.isEmpty())
return QPixmap();
+ if (system == Qt::LogicalCoordinates
+ && effectRect.size() == sourceRect.size()
+ && isPixmap()) {
+ return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
+ }
+
QPixmap pixmap(effectRect.size());
pixmap.fill(Qt::transparent);
QPainter pixmapPainter(&pixmap);
@@ -10721,8 +10906,10 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
}
pixmapPainter.end();
+
return pixmap;
}
+#endif //QT_NO_GRAPHICSEFFECT
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, QGraphicsItem *item)
@@ -10732,14 +10919,35 @@ QDebug operator<<(QDebug debug, QGraphicsItem *item)
return debug;
}
- debug << "QGraphicsItem(this =" << ((void*)item)
- << ", parent =" << ((void*)item->parentItem())
+ 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";
@@ -10825,6 +11033,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
case QGraphicsItem::ItemOpacityHasChanged:
str = "ItemOpacityHasChanged";
break;
+ case QGraphicsItem::ItemScenePositionHasChanged:
+ str = "ItemScenePositionHasChanged";
+ break;
}
debug << str;
return debug;
@@ -10882,6 +11093,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemIsFocusScope:
str = "ItemIsFocusScope";
break;
+ case QGraphicsItem::ItemSendsScenePositionChanges:
+ str = "ItemSendsScenePositionChanges";
+ break;
}
debug << str;
return debug;
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index 2665235c48..8bbe9f1254 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -105,7 +105,8 @@ public:
ItemAcceptsInputMethod = 0x1000,
ItemNegativeZStacksBehindParent = 0x2000,
ItemIsPanel = 0x4000,
- ItemIsFocusScope = 0x8000 // internal
+ ItemIsFocusScope = 0x8000, // internal
+ ItemSendsScenePositionChanges = 0x10000
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
@@ -137,7 +138,8 @@ public:
ItemZValueChange,
ItemZValueHasChanged,
ItemOpacityChange,
- ItemOpacityHasChanged
+ ItemOpacityHasChanged,
+ ItemScenePositionHasChanged
};
enum CacheMode {
@@ -225,9 +227,11 @@ public:
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);
@@ -555,7 +559,8 @@ public:
using QObject::children;
#endif
- void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture);
+ void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
+ void ungrabGesture(Qt::GestureType type);
Q_SIGNALS:
void parentChanged();
@@ -1120,6 +1125,7 @@ template <class T> inline T qgraphicsitem_cast(const QGraphicsItem *item)
#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);
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 65503627b9..75c8246131 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -61,6 +61,7 @@
#include <private/qgraphicstransform_p.h>
#include <private/qgraphicseffect_p.h>
+#include <qgraphicseffect.h>
#include <QtCore/qpoint.h>
@@ -177,6 +178,8 @@ public:
wantsActive(0),
holesInSiblingIndex(0),
sequentialOrdering(1),
+ updateDueToGraphicsEffect(0),
+ scenePosDescendants(0),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -221,6 +224,9 @@ public:
bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false,
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
int depth() const;
+#ifndef QT_NO_GRAPHICSEFFECT
+ void invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
void invalidateDepthRecursively();
void resolveDepth();
void addChild(QGraphicsItem *child);
@@ -426,6 +432,8 @@ public:
inline void ensureSortedChildren();
static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
void ensureSequentialSiblingIndex();
+ inline void sendScenePosChange();
+ virtual void siblingOrderChange();
QPainterPath cachedClipPath;
QRectF childrenBoundingRect;
@@ -450,7 +458,7 @@ public:
QGraphicsItem *focusScopeItem;
Qt::InputMethodHints imHints;
QGraphicsItem::PanelModality panelModality;
- QMap<Qt::GestureType, Qt::GestureContext> gestureContext;
+ QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
// Packed 32 bits
quint32 acceptedMouseButtons : 5;
@@ -480,7 +488,7 @@ public:
// Packed 32 bits
quint32 fullUpdatePending : 1;
- quint32 flags : 16;
+ quint32 flags : 17;
quint32 dirtyChildrenBoundingRect : 1;
quint32 paintedViewBoundingRectsNeedRepaint : 1;
quint32 dirtySceneTransform : 1;
@@ -495,13 +503,15 @@ public:
quint32 sceneTransformTranslateOnly : 1;
quint32 notifyBoundingRectChanged : 1;
quint32 notifyInvalidated : 1;
- quint32 mouseSetsFocus : 1;
// New 32 bits
+ quint32 mouseSetsFocus : 1;
quint32 explicitActivate : 1;
quint32 wantsActive : 1;
quint32 holesInSiblingIndex : 1;
quint32 sequentialOrdering : 1;
+ quint32 updateDueToGraphicsEffect : 1;
+ quint32 scenePosDescendants : 1;
// Optional stacking order
int globalStackingOrder;
@@ -573,6 +583,7 @@ struct QGraphicsItemPaintInfo
quint32 drawItem : 1;
};
+#ifndef QT_NO_GRAPHICSEFFECT
class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
{
public:
@@ -589,16 +600,21 @@ public:
inline const QWidget *widget() const
{ return 0; }
- inline void update()
- { item->update(); }
+ 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->d_ptr->isObject && qobject_cast<QFxImage *>(q_func()));
+ return item->type() == QGraphicsPixmapItem::Type
+ && !(item->flags() & QGraphicsItem::ItemIsSelectable)
+ && item->d_ptr->children.size() == 0;
+ //|| (item->d_ptr->isObject && qobject_cast<QmlGraphicsImage *>(q_func()));
}
inline const QStyleOption *styleOption() const
@@ -615,12 +631,80 @@ public:
QRectF boundingRect(Qt::CoordinateSystem system) const;
void draw(QPainter *);
- QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset) const;
+ QPixmap pixmap(Qt::CoordinateSystem system,
+ QPoint *offset,
+ QGraphicsEffect::PixmapPadMode mode) const;
QGraphicsItem *item;
QGraphicsItemPaintInfo *info;
+ QTransform lastEffectTransform;
};
+#endif //QT_NO_GRAPHICSEFFECT
+/*!
+ Returns true if \a item1 is on top of \a item2.
+ The items dont 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 dont need to be siblings.
+
+ \internal
+*/
+inline bool qt_closestItemLast(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ return qt_closestItemFirst(item2, item1);
+}
/*!
\internal
@@ -642,7 +726,7 @@ inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item
/*!
\internal
*/
-static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
+inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
{ return qt_closestLeaf(item2, item1); }
/*
diff --git a/src/gui/graphicsview/qgraphicslayout_p.h b/src/gui/graphicsview/qgraphicslayout_p.h
index 59c6dba12e..4aeae39f72 100644
--- a/src/gui/graphicsview/qgraphicslayout_p.h
+++ b/src/gui/graphicsview/qgraphicslayout_p.h
@@ -60,6 +60,8 @@
#include "qgraphicslayout.h"
#include "qgraphicslayoutitem_p.h"
#include <QtGui/qstyle.h>
+#include <QtGui/qwidget.h>
+#include <QtGui/qstyleoption.h>
QT_BEGIN_NAMESPACE
@@ -76,6 +78,55 @@ inline bool qt_graphicsLayoutDebug()
}
#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)
+ { return m_style == other.m_style && m_widget == other.m_widget; }
+ inline bool operator!=(const QLayoutStyleInfo &other)
+ { 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)
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp
index 0aa68df5c6..cb68741ebd 100644
--- a/src/gui/graphicsview/qgraphicslinearlayout.cpp
+++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp
@@ -59,7 +59,7 @@
You can add widgets, layouts, stretches (addStretch(), insertStretch() or
setStretchFactor()), and spacings (setItemSpacing()) to a linear
- layout. The layout takes ownership of the items. In some cases when the layout
+ layout. The layout takes ownership of the items. In some cases when the layout
item also inherits from QGraphicsItem (such as QGraphicsWidget) there will be a
ambiguity in ownership because the layout item belongs to two ownership hierarchies.
See the documentation of QGraphicsLayoutItem::setOwnedByLayout() how to handle
@@ -208,7 +208,7 @@ QGraphicsLinearLayout::~QGraphicsLinearLayout()
for (int i = count() - 1; i >= 0; --i) {
QGraphicsLayoutItem *item = itemAt(i);
// The following lines can be removed, but this removes the item
- // from the layout more efficiently than the implementation of
+ // from the layout more efficiently than the implementation of
// ~QGraphicsLayoutItem.
removeAt(i);
if (item) {
@@ -272,6 +272,10 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item)
qWarning("QGraphicsLinearLayout::insertItem: cannot insert null item");
return;
}
+ if (item == this) {
+ qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself");
+ return;
+ }
d->addChildLayoutItem(item);
Q_ASSERT(item);
@@ -538,18 +542,21 @@ void QGraphicsLinearLayout::invalidate()
QGraphicsLayout::invalidate();
}
-#ifdef QT_DEBUG
+/*!
+ \internal
+*/
void QGraphicsLinearLayout::dump(int indent) const
{
+#ifdef QT_DEBUG
if (qt_graphicsLayoutDebug()) {
Q_D(const QGraphicsLinearLayout);
qDebug("%*s%s layout", indent, "",
d->orientation == Qt::Horizontal ? "Horizontal" : "Vertical");
d->engine.dump(indent + 1);
}
-}
#endif
+}
QT_END_NAMESPACE
-
+
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.h b/src/gui/graphicsview/qgraphicslinearlayout.h
index 742392e1a4..15fe81a541 100644
--- a/src/gui/graphicsview/qgraphicslinearlayout.h
+++ b/src/gui/graphicsview/qgraphicslinearlayout.h
@@ -97,9 +97,7 @@ public:
Q5SizePolicy::ControlTypes controlTypes(LayoutSide side) const;
#endif
-#ifdef QT_DEBUG
void dump(int indent = 0) const;
-#endif
protected:
#if 0
diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp
index b7a39628ab..e9173a910a 100644
--- a/src/gui/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp
@@ -57,6 +57,9 @@
#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
@@ -86,7 +89,9 @@ QT_BEGIN_NAMESPACE
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.
+ 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
@@ -184,6 +189,7 @@ QT_BEGIN_NAMESPACE
*/
extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
+extern bool qt_tab_all_widgets;
/*!
\internal
@@ -369,6 +375,7 @@ QVariant QGraphicsProxyWidgetPrivate::inputMethodQueryHelper(Qt::InputMethodQuer
/*!
\internal
+ Some of the logic is shared with QApplicationPrivate::focusNextPrevChild_helper
*/
QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) const
{
@@ -382,14 +389,16 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next)
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() & Qt::TabFocus)) {
+ && ((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;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 077355996d..5b0643d3eb 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -242,7 +242,6 @@
#include <QtGui/qstyleoption.h>
#include <QtGui/qtooltip.h>
#include <QtGui/qtransform.h>
-#include <QtGui/qgesture.h>
#include <QtGui/qinputcontext.h>
#include <QtGui/qgraphicseffect.h>
#include <private/qapplication_p.h>
@@ -251,6 +250,14 @@
#include <private/qt_x11_p.h>
#endif
#include <private/qgraphicseffect_p.h>
+#include <private/qgesturemanager_p.h>
+
+// #define GESTURE_DEBUG
+#ifndef GESTURE_DEBUG
+# define DEBUG if (0) qDebug
+#else
+# define DEBUG qDebug
+#endif
QT_BEGIN_NAMESPACE
@@ -287,6 +294,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
needSortTopLevelItems(true),
holesInTopLevelSiblingIndex(false),
topLevelSequentialOrdering(true),
+ scenePosDescendantsUpdatePending(false),
stickyFocus(false),
hasFocus(false),
focusItem(0),
@@ -481,6 +489,55 @@ void QGraphicsScenePrivate::_q_processDirtyItems()
/*!
\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
@@ -516,8 +573,19 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
widget->d_func()->fixFocusChainBeforeReparenting(0, 0);
}
+ if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
+ unregisterScenePosItem(item);
+
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));
+ }
+
// Unregister focus proxy.
item->d_ptr->resetFocusProxy();
@@ -564,12 +632,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
++iterator;
}
- 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->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
leaveModal(item);
@@ -684,6 +746,7 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
focusItem = 0;
sendEvent(lastFocusItem, &event);
+#ifndef QT_NO_IM
if (lastFocusItem
&& (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
// Reset any visible preedit text
@@ -699,6 +762,7 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
views.at(i)->inputContext()->reset();
}
}
+#endif //QT_NO_IM
}
if (item) {
@@ -1052,6 +1116,13 @@ bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event)
*/
bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
{
+ if (QGraphicsObject *object = item->toGraphicsObject()) {
+ if (qt_gestureManager) {
+ if (qt_gestureManager->filterEvent(object, event))
+ return true;
+ }
+ }
+
if (filterEvent(item, event))
return false;
if (filterDescendantEvent(item, event))
@@ -2275,8 +2346,9 @@ void QGraphicsScene::clear()
// NB! We have to clear the index before deleting items; otherwise the
// index might try to access dangling item pointers.
d->index->clear();
- const QList<QGraphicsItem *> items = d->topLevelItems;
- qDeleteAll(items);
+ // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items
+ while (!d->topLevelItems.isEmpty())
+ delete d->topLevelItems.first();
Q_ASSERT(d->topLevelItems.isEmpty());
d->lastItemCount = 0;
d->allItemsIgnoreHoverEvents = true;
@@ -2522,6 +2594,9 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
}
}
+ if (item->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)
@@ -2808,18 +2883,20 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
}
/*!
- Returns the scene's current focus item, or 0 if no item currently has
- focus.
+ 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()
+ \sa setFocusItem(), QGraphicsItem::hasFocus(), isActive()
*/
QGraphicsItem *QGraphicsScene::focusItem() const
{
Q_D(const QGraphicsScene);
- return d->focusItem;
+ return isActive() ? d->focusItem : d->lastFocusItem;
}
/*!
@@ -3365,6 +3442,10 @@ bool QGraphicsScene::event(QEvent *event)
case QEvent::TouchEnd:
d->touchEventHandler(static_cast<QTouchEvent *>(event));
break;
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
+ d->gestureEventHandler(static_cast<QGestureEvent *>(event));
+ break;
default:
return QObject::event(event);
}
@@ -4127,7 +4208,7 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &
QRect br = pixmapExposed.boundingRect();
// Don't use subpixmap if we get a full update.
- if (pixmapExposed.isEmpty() || (pixmapExposed.numRects() == 1 && br.contains(pix->rect()))) {
+ if (pixmapExposed.isEmpty() || (pixmapExposed.rectCount() == 1 && br.contains(pix->rect()))) {
pix->fill(Qt::transparent);
pixmapPainter.begin(pix);
} else {
@@ -4470,6 +4551,10 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
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();
+
QRectF exposedSceneRect;
if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
@@ -4555,6 +4640,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
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,
@@ -4569,10 +4655,17 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
else
painter->setWorldTransform(*transformPtr);
painter->setOpacity(opacity);
- item->d_ptr->graphicsEffect->draw(painter, source);
+
+ if (sourced->lastEffectTransform != painter->worldTransform()) {
+ sourced->lastEffectTransform = painter->worldTransform();
+ sourced->invalidateCache();
+ }
+ item->d_ptr->graphicsEffect->draw(painter);
painter->setWorldTransform(restoreTransform);
sourced->info = 0;
- } else {
+ } else
+#endif //QT_NO_GRAPHICSEFFECT
+ {
draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
effectTransform, wasDirtyParentSceneTransform, drawItem);
}
@@ -4741,10 +4834,12 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
QGraphicsItem *p = item->d_ptr->parent;
while (p) {
p->d_ptr->dirtyChildren = 1;
+#ifndef QT_NO_GRAPHICSEFFECT
if (p->d_ptr->graphicsEffect && p->d_ptr->graphicsEffect->isEnabled()) {
p->d_ptr->dirty = 1;
p->d_ptr->fullUpdatePending = 1;
}
+#endif //QT_NO_GRAPHICSEFFECT
p = p->d_ptr->parent;
}
}
@@ -4886,7 +4981,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
continue;
}
- if (item->d_ptr->paintedViewBoundingRectsNeedRepaint && !paintedViewBoundingRect.isEmpty()) {
+ if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset);
if (!viewPrivate->updateRect(paintedViewBoundingRect))
paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
@@ -4986,6 +5081,10 @@ void QGraphicsScene::drawItems(QPainter *painter,
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();
+
QTransform viewTransform = painter->worldTransform();
Q_UNUSED(options);
@@ -5297,7 +5396,7 @@ void QGraphicsScene::setActivePanel(QGraphicsItem *item)
/*!
\since 4.4
- Returns the current active window, or 0 if there is no window is currently
+ Returns the current active window, or 0 if no window is currently
active.
\sa QGraphicsScene::setActiveWindow()
@@ -5699,6 +5798,336 @@ void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel)
dispatchHoverEvent(&hoverEvent);
}
+void QGraphicsScenePrivate::getGestureTargets(const QSet<QGesture *> &gestures,
+ QWidget *viewport,
+ QMap<Qt::GestureType, QGesture *> *conflictedGestures,
+ QList<QList<QGraphicsObject *> > *conflictedItems,
+ QHash<QGesture *, QGraphicsObject *> *normalGestures)
+{
+ foreach (QGesture *gesture, gestures) {
+ Qt::GestureType gestureType = gesture->gestureType();
+ if (gesture->hasHotSpot()) {
+ QPoint screenPos = gesture->hotSpot().toPoint();
+ QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport);
+ QList<QGraphicsObject *> result;
+ 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(gestureType)) {
+ result.append(item);
+ }
+ }
+ DEBUG() << "QGraphicsScenePrivate::getGestureTargets:"
+ << gesture << result;
+ if (result.size() == 1) {
+ normalGestures->insert(gesture, result.first());
+ } else if (!result.isEmpty()) {
+ conflictedGestures->insert(gestureType, gesture);
+ conflictedItems->append(result);
+ }
+ }
+ }
+}
+
+void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
+{
+ QWidget *viewport = event->widget();
+ if (!viewport)
+ return;
+ QList<QGesture *> allGestures = event->gestures();
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "Delivering gestures:" << allGestures;
+
+ typedef QHash<QGraphicsObject *, QList<QGesture *> > GesturesPerItem;
+ GesturesPerItem gesturesPerItem;
+
+ QSet<QGesture *> startedGestures;
+ foreach (QGesture *gesture, allGestures) {
+ 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);
+ } else {
+ gesturesPerItem[target].append(gesture);
+ }
+ }
+
+ QMap<Qt::GestureType, QGesture *> conflictedGestures;
+ QList<QList<QGraphicsObject *> > conflictedItems;
+ QHash<QGesture *, QGraphicsObject *> normalGestures;
+ getGestureTargets(startedGestures, viewport, &conflictedGestures, &conflictedItems,
+ &normalGestures);
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "Conflicting gestures:" << conflictedGestures.values() << conflictedItems;
+ Q_ASSERT((conflictedGestures.isEmpty() && conflictedItems.isEmpty()) ||
+ (!conflictedGestures.isEmpty() && !conflictedItems.isEmpty()));
+
+ // gestures that were sent as override events, but no one accepted them
+ QHash<QGesture *, QGraphicsObject *> ignoredConflictedGestures;
+
+ // deliver conflicted gestures as override events first
+ while (!conflictedGestures.isEmpty() && !conflictedItems.isEmpty()) {
+ // get the topmost item to deliver the override event
+ Q_ASSERT(!conflictedItems.isEmpty());
+ Q_ASSERT(!conflictedItems.first().isEmpty());
+ QGraphicsObject *topmost = conflictedItems.first().first();
+ for (int i = 1; i < conflictedItems.size(); ++i) {
+ QGraphicsObject *item = conflictedItems.at(i).first();
+ if (qt_closestItemFirst(item, topmost)) {
+ topmost = item;
+ }
+ }
+ // get a list of gestures to send to the item
+ QList<Qt::GestureType> grabbedGestures =
+ topmost->QGraphicsItem::d_func()->gestureContext.keys();
+ QList<QGesture *> gestures;
+ for (int i = 0; i < grabbedGestures.size(); ++i) {
+ if (QGesture *g = conflictedGestures.value(grabbedGestures.at(i), 0)) {
+ gestures.append(g);
+ if (!ignoredConflictedGestures.contains(g))
+ ignoredConflictedGestures.insert(g, topmost);
+ }
+ }
+
+ // send gesture override to the topmost item
+ QGestureEvent ev(gestures);
+ 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);
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "delivering override to"
+ << topmost << gestures;
+ sendEvent(topmost, &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->gestureType());
+ gestureTargets.remove(g);
+ // add the gesture to the list of normal delivered gestures
+ normalGestures.insert(g, topmost);
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "override was accepted:"
+ << g << topmost;
+ ignoredConflictedGestures.remove(g);
+ }
+ }
+ // remove the item that we've already delivered from the list
+ for (int i = 0; i < conflictedItems.size(); ) {
+ QList<QGraphicsObject *> &items = conflictedItems[i];
+ if (items.first() == topmost) {
+ items.removeFirst();
+ if (items.isEmpty()) {
+ conflictedItems.removeAt(i);
+ continue;
+ }
+ }
+ ++i;
+ }
+ }
+
+ // put back those started gestures that are not in the conflicted state
+ // and remember their targets
+ QHash<QGesture *, QGraphicsObject *>::const_iterator it = normalGestures.begin(),
+ e = normalGestures.end();
+ for (; it != e; ++it) {
+ QGesture *g = it.key();
+ QGraphicsObject *receiver = it.value();
+ Q_ASSERT(!gestureTargets.contains(g));
+ gestureTargets.insert(g, receiver);
+ gesturesPerItem[receiver].append(g);
+ }
+ it = ignoredConflictedGestures.begin();
+ e = ignoredConflictedGestures.end();
+ for (; it != e; ++it) {
+ QGesture *g = it.key();
+ QGraphicsObject *receiver = it.value();
+ Q_ASSERT(!gestureTargets.contains(g));
+ gestureTargets.insert(g, receiver);
+ gesturesPerItem[receiver].append(g);
+ }
+
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "Started gestures:" << normalGestures.keys()
+ << "All gestures:" << gesturesPerItem.values();
+
+ // deliver all events
+ QList<QGesture *> alreadyIgnoredGestures;
+ QHash<QGraphicsObject *, QSet<QGesture *> > itemIgnoredGestures;
+ QList<QGraphicsObject *> targetItems = gesturesPerItem.keys();
+ qSort(targetItems.begin(), targetItems.end(), qt_closestItemFirst);
+ for (int i = 0; i < targetItems.size(); ++i) {
+ QGraphicsObject *item = targetItems.at(i);
+ QList<QGesture *> gestures = gesturesPerItem.value(item);
+ // remove gestures that were already delivered once and were ignored
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "already ignored gestures for item"
+ << item << ":" << itemIgnoredGestures.value(item);
+
+ if (itemIgnoredGestures.contains(item)) // don't deliver twice to the same item
+ continue;
+
+ QGraphicsItemPrivate *gid = item->QGraphicsItem::d_func();
+ foreach(QGesture *g, alreadyIgnoredGestures) {
+ QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
+ gid->gestureContext.find(g->gestureType());
+ bool deliver = contextit != gid->gestureContext.end() &&
+ (g->state() == Qt::GestureStarted ||
+ (contextit.value() & Qt::ReceivePartialGestures));
+ if (deliver)
+ gestures += g;
+ }
+ if (gestures.isEmpty())
+ continue;
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "delivering to"
+ << item << gestures;
+ QGestureEvent ev(gestures);
+ ev.setWidget(event->widget());
+ sendEvent(item, &ev);
+ QSet<QGesture *> ignoredGestures;
+ foreach (QGesture *g, gestures) {
+ if (!ev.isAccepted() && !ev.isAccepted(g)) {
+ ignoredGestures.insert(g);
+ } else {
+ if (g->state() == Qt::GestureStarted)
+ gestureTargets[g] = item;
+ }
+ }
+ if (!ignoredGestures.isEmpty()) {
+ // get a list of items under the (current) hotspot of each ignored
+ // gesture and start delivery again from the beginning
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "item has ignored the event, will propagate."
+ << item << ignoredGestures;
+ itemIgnoredGestures[item] += ignoredGestures;
+ QMap<Qt::GestureType, QGesture *> conflictedGestures;
+ QList<QList<QGraphicsObject *> > itemsForConflictedGestures;
+ QHash<QGesture *, QGraphicsObject *> normalGestures;
+ getGestureTargets(ignoredGestures, viewport,
+ &conflictedGestures, &itemsForConflictedGestures,
+ &normalGestures);
+ QSet<QGraphicsObject *> itemsSet = targetItems.toSet();
+ for (int k = 0; k < itemsForConflictedGestures.size(); ++k)
+ itemsSet += itemsForConflictedGestures.at(k).toSet();
+ targetItems = itemsSet.toList();
+ qSort(targetItems.begin(), targetItems.end(), qt_closestItemFirst);
+ alreadyIgnoredGestures = conflictedGestures.values();
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "new targets:" << targetItems;
+ 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, event->widget());
+ }
+ }
+
+ // 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;
+ }
+ }
+}
+
+void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original, QWidget *viewport)
+{
+ Q_ASSERT(original);
+ QGraphicsItem *originalItem = gestureTargets.value(original);
+ Q_ASSERT(originalItem);
+
+ // 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;
+
+ QPoint screenPos = g->hotSpot().toPoint();
+ QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport);
+ 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
+ }
+ }
+ }
+ }
+
+ Q_ASSERT(qt_gestureManager); // it would be very odd if we got called without a manager.
+ for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) {
+ qt_gestureManager->recycle(*setIter);
+ gestureTargets.remove(*setIter);
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qgraphicsscene.cpp"
diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h
index d6d48d77bd..a47574ea9d 100644
--- a/src/gui/graphicsview/qgraphicsscene.h
+++ b/src/gui/graphicsview/qgraphicsscene.h
@@ -299,6 +299,7 @@ private:
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 QGraphicsView;
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 807369584b..fdec466dc5 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -122,6 +122,13 @@ public:
void _q_processDirtyItems();
+ QSet<QGraphicsItem *> scenePosItems;
+ bool scenePosDescendantsUpdatePending;
+ void setScenePosItemEnabled(QGraphicsItem *item, bool enabled);
+ void registerScenePosItem(QGraphicsItem *item);
+ void unregisterScenePosItem(QGraphicsItem *item);
+ void _q_updateScenePosDescendants();
+
void removeItemHelper(QGraphicsItem *item);
QBrush backgroundBrush;
@@ -234,6 +241,7 @@ public:
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;
@@ -243,12 +251,15 @@ public:
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()
@@ -282,6 +293,14 @@ public:
bool allItemsIgnoreTouchEvents;
void enableTouchEventsOnViews();
+ QHash<QGesture *, QGraphicsObject *> gestureTargets;
+ void gestureEventHandler(QGestureEvent *event);
+ void getGestureTargets(const QSet<QGesture *> &gestures, QWidget *viewport,
+ QMap<Qt::GestureType, QGesture *> *conflictedGestures,
+ QList<QList<QGraphicsObject *> > *conflictedItems,
+ QHash<QGesture *, QGraphicsObject *> *normalGestures);
+ void cancelGesturesForChildren(QGesture *original, QWidget *viewport);
+
void updateInputMethodSensitivityInViews();
QList<QGraphicsItem *> modalPanels;
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
index e21183a0d5..47ae3f1752 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -405,70 +405,6 @@ QList<QGraphicsItem *> QGraphicsSceneBspTreeIndexPrivate::estimateItems(const QR
}
/*!
- Returns true if \a item1 is on top of \a item2.
-
- \internal
-*/
-bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(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 *a1 = t1;
- const QGraphicsItem *a2 = t2;
- while (a1) {
- const QGraphicsItem *p1 = a1;
- const QGraphicsItem *p2 = a2;
- a1 = a1->parentItem();
- a2 = a2->parentItem();
- if (a1 && a1 == a2)
- return qt_closestLeaf(p1, p2);
- }
-
- // No common ancestor? Then just compare the items' toplevels directly.
- return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem());
-}
-
-/*!
- Returns true if \a item2 is on top of \a item1.
-
- \internal
-*/
-bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- return closestItemFirst_withoutCache(item2, item1);
-}
-
-/*!
Sort a list of \a itemList in a specific \a order and use the cache if requested.
\internal
@@ -495,9 +431,9 @@ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList<QGraphicsItem *> *itemLi
}
} else {
if (order == Qt::DescendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache);
+ qSort(itemList->begin(), itemList->end(), qt_closestItemFirst);
} else if (order == Qt::AscendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache);
+ qSort(itemList->begin(), itemList->end(), qt_closestItemLast);
}
}
}
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
index 0a86bb79ae..c130190b7c 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
@@ -145,8 +145,6 @@ public:
QList<QGraphicsItem *> estimateItems(const QRectF &, Qt::SortOrder, bool b = false);
static void climbTree(QGraphicsItem *item, int *stackingOrder);
- static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2);
- static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2);
static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
{
diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp
index ec1a2f5ff4..83bc9e1c95 100644
--- a/src/gui/graphicsview/qgraphicstransform.cpp
+++ b/src/gui/graphicsview/qgraphicstransform.cpp
@@ -69,6 +69,9 @@
objects are applied to a QGraphicsItem, all of the transformations
are computed in true 3D space, with the projection back to 2D
only occurring after the last QGraphicsTransform is applied.
+ The exception to this is QGraphicsRotation, which projects back to
+ 2D after each rotation to preserve the perspective effect around
+ the X and Y axes.
If you want to create your own configurable transformation, you can create
a subclass of QGraphicsTransform (or any or the existing subclasses), and
@@ -90,8 +93,8 @@
#include <QDebug>
#include <QtCore/qmath.h>
+#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
-
void QGraphicsTransformPrivate::setItem(QGraphicsItem *i)
{
if (item == i)
@@ -547,7 +550,7 @@ void QGraphicsRotation::applyTo(QMatrix4x4 *matrix) const
return;
matrix->translate(d->origin);
- matrix->rotate(d->angle, d->axis.x(), d->axis.y(), d->axis.z());
+ matrix->projectedRotate(d->angle, d->axis.x(), d->axis.y(), d->axis.z());
matrix->translate(-d->origin);
}
@@ -562,3 +565,4 @@ void QGraphicsRotation::applyTo(QMatrix4x4 *matrix) const
#include "moc_qgraphicstransform.cpp"
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicstransform.h b/src/gui/graphicsview/qgraphicstransform.h
index 58075aa90b..58e3077767 100644
--- a/src/gui/graphicsview/qgraphicstransform.h
+++ b/src/gui/graphicsview/qgraphicstransform.h
@@ -47,6 +47,7 @@
#include <QtGui/QTransform>
#include <QtGui/QMatrix4x4>
+#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -150,5 +151,6 @@ private:
QT_END_NAMESPACE
QT_END_HEADER
+#endif //QT_NO_GRAPHICSVIEW
#endif // QFXTRANSFORM_H
diff --git a/src/gui/graphicsview/qgraphicstransform_p.h b/src/gui/graphicsview/qgraphicstransform_p.h
index 9e708b2a9f..ddf99bbc62 100644
--- a/src/gui/graphicsview/qgraphicstransform_p.h
+++ b/src/gui/graphicsview/qgraphicstransform_p.h
@@ -54,7 +54,7 @@
//
#include "private/qobject_p.h"
-
+#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
class QGraphicsItem;
@@ -73,5 +73,6 @@ public:
};
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHCISVIEW
#endif // QGRAPHICSTRANSFORM_P_H
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 32747cc393..3f9f4436fc 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -281,6 +281,7 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime <
#include <QtGui/qstyleoption.h>
#include <QtGui/qinputcontext.h>
#ifdef Q_WS_X11
+#include <QtGui/qpaintengine.h>
#include <private/qt_x11_p.h>
#endif
@@ -977,7 +978,7 @@ QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedReg
// 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.numRects() == 1 && matrix.type() <= QTransform::TxScale;
+ bool simpleRectLookup = exposedRegion.rectCount() == 1 && matrix.type() <= QTransform::TxScale;
if (simpleRectLookup) {
return scene->items(exposedRegionSceneBounds,
Qt::IntersectsItemBoundingRect,
@@ -1511,6 +1512,13 @@ void QGraphicsView::setScene(QGraphicsScene *scene)
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.)).
@@ -1532,6 +1540,11 @@ void QGraphicsView::setScene(QGraphicsScene *scene)
// 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();
}
@@ -2637,6 +2650,19 @@ bool QGraphicsView::viewportEvent(QEvent *event)
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
@@ -2701,6 +2727,19 @@ bool QGraphicsView::viewportEvent(QEvent *event)
return true;
}
+ 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;
+ }
default:
break;
}
@@ -3281,7 +3320,12 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
if (viewTransformed)
backgroundPainter.setTransform(viewTransform);
- backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
+#ifdef Q_WS_X11
+#undef X11
+ if (backgroundPainter.paintEngine()->type() != QPaintEngine::X11)
+#define X11 qt_x11Data
+#endif
+ backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
drawBackground(&backgroundPainter, exposedSceneRect);
d->backgroundPixmapExposed = QRegion();
}
@@ -3306,6 +3350,14 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
if (!(d->optimizationFlags & IndirectPainting)) {
d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
&d->exposedRegion, viewport());
+ // 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.setWorldTransform(viewTransform);
} else {
// Find all exposed items
bool allItems = false;
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 35a3c13eb1..d9c65bbd54 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -318,6 +318,12 @@ void QGraphicsWidget::resize(const QSizeF &size)
*/
/*!
+ \property QGraphicsWidget::sizePolicy
+ \brief the size policy for the widget
+ \sa sizePolicy(), setSizePolicy(), QWidget::sizePolicy()
+*/
+
+/*!
\property QGraphicsWidget::geometry
\brief the geometry of the widget
@@ -410,6 +416,27 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
*/
/*!
+ \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.
@@ -1352,6 +1379,8 @@ void QGraphicsWidget::changeEvent(QEvent *event)
case QEvent::StyleChange:
// ### Don't unset if the margins are explicitly set.
unsetWindowFrameMargins();
+ if (d->layout)
+ d->layout->invalidate();
case QEvent::FontChange:
update();
updateGeometry();
diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h
index 9c71140e74..05d3a49a40 100644
--- a/src/gui/graphicsview/qgraphicswidget.h
+++ b/src/gui/graphicsview/qgraphicswidget.h
@@ -74,6 +74,10 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay
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)
+ 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)
diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h
index a42a537b4c..ed335a828c 100644
--- a/src/gui/graphicsview/qgridlayoutengine_p.h
+++ b/src/gui/graphicsview/qgridlayoutengine_p.h
@@ -59,7 +59,7 @@
#include "qmap.h"
#include "qpair.h"
#include "qvector.h"
-
+#include "qgraphicslayout_p.h"
#include <float.h>
QT_BEGIN_NAMESPACE
@@ -128,29 +128,6 @@ public:
};
-class QLayoutStyleInfo
-{
-public:
- inline QLayoutStyleInfo() { invalidate(); }
- inline QLayoutStyleInfo(QStyle *style, QWidget *widget)
- : q_valid(true), q_style(style), q_widget(widget) {}
-
- inline void invalidate() { q_valid = false; q_style = 0; q_widget = 0; }
-
- inline QStyle *style() const { return q_style; }
- inline QWidget *widget() const { return q_widget; }
-
- inline bool operator==(const QLayoutStyleInfo &other)
- { return q_style == other.q_style && q_widget == other.q_widget; }
- inline bool operator!=(const QLayoutStyleInfo &other)
- { return !(*this == other); }
-
-private:
- bool q_valid;
- QStyle *q_style;
- QWidget *q_widget;
-};
-
class QGridLayoutBox
{
public:
diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp
index b8f8fb449c..cd40f9ed61 100644
--- a/src/gui/graphicsview/qsimplex_p.cpp
+++ b/src/gui/graphicsview/qsimplex_p.cpp
@@ -108,10 +108,8 @@ void QSimplex::clearDataStructures()
// Constraints
for (int i = 0; i < constraints.size(); ++i) {
delete constraints[i]->helper.first;
- constraints[i]->helper.first = 0;
- constraints[i]->helper.second = 0.0;
delete constraints[i]->artificial;
- constraints[i]->artificial = 0;
+ delete constraints[i];
}
constraints.clear();
@@ -137,7 +135,23 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
if (newConstraints.isEmpty())
return true; // we are ok with no constraints
- constraints = newConstraints;
+
+ // Make deep copy of constraints. We need this copy because we may change
+ // them in the simplification method.
+ for (int i = 0; i < newConstraints.size(); ++i) {
+ QSimplexConstraint *c = new QSimplexConstraint;
+ c->constant = newConstraints[i]->constant;
+ c->ratio = newConstraints[i]->ratio;
+ c->variables = newConstraints[i]->variables;
+ constraints << c;
+ }
+
+ // Remove constraints of type Var == K and replace them for their value.
+ if (!simplifyConstraints(&constraints)) {
+ qWarning() << "QSimplex: No feasible solution!";
+ clearDataStructures();
+ return false;
+ }
///////////////////////////////////////
// Prepare variables and constraints //
@@ -274,7 +288,7 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
// original problem.
// Otherwise, we clean up our structures and report there is
// no feasible solution.
- if (valueAt(0, columns - 1) != 0.0) {
+ if ((valueAt(0, columns - 1) != 0.0) && (qAbs(valueAt(0, columns - 1)) > 0.00001)) {
qWarning() << "QSimplex: No feasible solution!";
clearDataStructures();
return false;
@@ -508,11 +522,21 @@ qreal QSimplex::solver(solverFactor factor)
// Remove old objective
clearRow(0);
- // Set new objective
+ // Set new objective in the first row of the simplex matrix
+ qreal resultOffset = 0;
QHash<QSimplexVariable *, qreal>::const_iterator iter;
for (iter = objective->variables.constBegin();
iter != objective->variables.constEnd();
++iter) {
+
+ // Check if the variable was removed in the simplification process.
+ // If so, we save its offset to the objective function and skip adding
+ // it to the matrix.
+ if (iter.key()->index == -1) {
+ resultOffset += iter.value() * iter.key()->result;
+ continue;
+ }
+
setValueAt(0, iter.key()->index, -1 * factor * iter.value());
}
@@ -525,7 +549,9 @@ qreal QSimplex::solver(solverFactor factor)
}
#endif
- return factor * valueAt(0, columns - 1);
+ // Return the value calculated by the simplex plus the value of the
+ // fixed variables.
+ return (factor * valueAt(0, columns - 1)) + resultOffset;
}
/*!
@@ -571,4 +597,77 @@ void QSimplex::collectResults()
}
}
+/*!
+ \internal
+
+ Looks for single-valued variables and remove them from the constraints list.
+*/
+bool QSimplex::simplifyConstraints(QList<QSimplexConstraint *> *constraints)
+{
+ QHash<QSimplexVariable *, qreal> results; // List of single-valued variables
+ bool modified = true; // Any chance more optimization exists?
+
+ while (modified) {
+ modified = false;
+
+ // For all constraints
+ QList<QSimplexConstraint *>::iterator iter = constraints->begin();
+ while (iter != constraints->end()) {
+ QSimplexConstraint *c = *iter;
+ if ((c->ratio == QSimplexConstraint::Equal) && (c->variables.count() == 1)) {
+ // Check whether this is a constraint of type Var == K
+ // If so, save its value to "results".
+ QSimplexVariable *variable = c->variables.constBegin().key();
+ qreal result = c->constant / c->variables.value(variable);
+
+ results.insert(variable, result);
+ variable->result = result;
+ variable->index = -1;
+ modified = true;
+
+ }
+
+ // Replace known values among their variables
+ QHash<QSimplexVariable *, qreal>::const_iterator r;
+ for (r = results.constBegin(); r != results.constEnd(); ++r) {
+ if (c->variables.contains(r.key())) {
+ c->constant -= r.value() * c->variables.take(r.key());
+ modified = true;
+ }
+ }
+
+ // Keep it normalized
+ if (c->constant < 0)
+ c->invert();
+
+ if (c->variables.isEmpty()) {
+ // If constraint became empty due to substitution, delete it.
+ if (c->isSatisfied() == false)
+ // We must ensure that the constraint soon to be deleted would not
+ // make the problem unfeasible if left behind. If that's the case,
+ // we return false so the simplex solver can properly report that.
+ return false;
+
+ delete c;
+ iter = constraints->erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+ }
+
+ return true;
+}
+
+void QSimplexConstraint::invert()
+{
+ constant = -constant;
+ ratio = Ratio(2 - ratio);
+
+ QHash<QSimplexVariable *, qreal>::iterator iter;
+ for (iter = variables.begin(); iter != variables.end(); ++iter) {
+ iter.value() = -iter.value();
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h
index 51991a993b..a5816d1987 100644
--- a/src/gui/graphicsview/qsimplex_p.h
+++ b/src/gui/graphicsview/qsimplex_p.h
@@ -63,7 +63,7 @@ struct QSimplexVariable
QSimplexVariable() : result(0), index(0) {}
qreal result;
- uint index;
+ int index;
};
@@ -95,7 +95,8 @@ struct QSimplexConstraint
QPair<QSimplexVariable *, qreal> helper;
QSimplexVariable * artificial;
-#ifdef QT_DEBUG
+ void invert();
+
bool isSatisfied() {
qreal leftHandSide(0);
@@ -106,7 +107,7 @@ struct QSimplexConstraint
Q_ASSERT(constant > 0 || qFuzzyCompare(1, 1 + constant));
- if (qFuzzyCompare(1000 + leftHandSide, 1000 + constant))
+ if ((leftHandSide == constant) || qAbs(leftHandSide - constant) < 0.00000001)
return true;
switch (ratio) {
@@ -118,6 +119,30 @@ struct QSimplexConstraint
return false;
}
}
+
+#ifdef QT_DEBUG
+ QString toString() {
+ QString result;
+ result += QString::fromAscii("-- QSimplexConstraint %1 --").arg(quintptr(this), 0, 16);
+
+ QHash<QSimplexVariable *, qreal>::const_iterator iter;
+ for (iter = variables.constBegin(); iter != variables.constEnd(); ++iter) {
+ result += QString::fromAscii(" %1 x %2").arg(iter.value()).arg(quintptr(iter.key()), 0, 16);
+ }
+
+ switch (ratio) {
+ case LessOrEqual:
+ result += QString::fromAscii(" (less) <= %1").arg(constant);
+ break;
+ case MoreOrEqual:
+ result += QString::fromAscii(" (more) >= %1").arg(constant);
+ break;
+ default:
+ result += QString::fromAscii(" (eqal) == %1").arg(constant);
+ }
+
+ return result;
+ }
#endif
};
@@ -129,7 +154,6 @@ public:
qreal solveMin();
qreal solveMax();
- QList<QSimplexVariable *> constraintsVariables();
bool setConstraints(const QList<QSimplexConstraint *> constraints);
void setObjective(QSimplexConstraint *objective);
@@ -145,6 +169,7 @@ private:
void combineRows(int toIndex, int fromIndex, qreal factor);
// Simplex
+ bool simplifyConstraints(QList<QSimplexConstraint *> *constraints);
int findPivotColumn();
int pivotRowForColumn(int column);
void reducedRowEchelon();
@@ -168,11 +193,6 @@ private:
qreal *matrix;
};
-inline QList<QSimplexVariable *> QSimplex::constraintsVariables()
-{
- return variables;
-}
-
inline qreal QSimplex::valueAt(int rowIndex, int columnIndex)
{
return matrix[rowIndex * columns + columnIndex];
diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp
index e081735b69..4b8d4b889d 100644
--- a/src/gui/image/qbitmap.cpp
+++ b/src/gui/image/qbitmap.cpp
@@ -86,7 +86,7 @@ QT_BEGIN_NAMESPACE
object.
Just like the QPixmap class, QBitmap is optimized by the use of
- implicit data sharing. For more information, see the {Implicit
+ implicit data sharing. For more information, see the \l {Implicit
Data Sharing} documentation.
\sa QPixmap, QImage, QImageReader, QImageWriter
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 4b6fcba384..f3eb7c3fca 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -52,9 +52,9 @@ QT_BEGIN_NAMESPACE
static void swapPixel01(QImage *image) // 1-bpp: swap 0 and 1 pixels
{
int i;
- if (image->depth() == 1 && image->numColors() == 2) {
+ if (image->depth() == 1 && image->colorCount() == 2) {
register uint *p = (uint *)image->bits();
- int nbytes = image->numBytes();
+ int nbytes = image->byteCount();
for (i=0; i<nbytes/4; i++) {
*p = ~*p;
p++;
@@ -246,7 +246,7 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
if (depth != 32) {
ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
- image.setNumColors(ncols);
+ image.setColorCount(ncols);
}
image.setDotsPerMeterX(bi.biXPelsPerMeter);
@@ -526,7 +526,7 @@ bool qt_write_dib(QDataStream &s, QImage image)
if (!d->isWritable())
return false;
- if (image.depth() == 8 && image.numColors() <= 16) {
+ if (image.depth() == 8 && image.colorCount() <= 16) {
bpl_bmp = (((bpl+1)/2+3)/4)*4;
nbits = 4;
} else if (image.depth() == 32) {
@@ -554,23 +554,23 @@ bool qt_write_dib(QDataStream &s, QImage image)
bi.biXPelsPerMeter = image.dotsPerMeterX() ? image.dotsPerMeterX()
: 2834; // 72 dpi default
bi.biYPelsPerMeter = image.dotsPerMeterY() ? image.dotsPerMeterY() : 2834;
- bi.biClrUsed = image.numColors();
- bi.biClrImportant = image.numColors();
+ bi.biClrUsed = image.colorCount();
+ bi.biClrImportant = image.colorCount();
s << bi; // write info header
if (s.status() != QDataStream::Ok)
return false;
if (image.depth() != 32) { // write color table
- uchar *color_table = new uchar[4*image.numColors()];
+ uchar *color_table = new uchar[4*image.colorCount()];
uchar *rgb = color_table;
QVector<QRgb> c = image.colorTable();
- for (int i=0; i<image.numColors(); i++) {
+ for (int i=0; i<image.colorCount(); i++) {
*rgb++ = qBlue (c[i]);
*rgb++ = qGreen(c[i]);
*rgb++ = qRed (c[i]);
*rgb++ = 0;
}
- if (d->write((char *)color_table, 4*image.numColors()) == -1) {
+ if (d->write((char *)color_table, 4*image.colorCount()) == -1) {
delete [] color_table;
return false;
}
@@ -754,7 +754,7 @@ bool QBmpHandler::write(const QImage &img)
int bpl = image.bytesPerLine();
// Code partially repeated in qt_write_dib
- if (image.depth() == 8 && image.numColors() <= 16) {
+ if (image.depth() == 8 && image.colorCount() <= 16) {
bpl_bmp = (((bpl+1)/2+3)/4)*4;
} else if (image.depth() == 32) {
bpl_bmp = ((image.width()*24+31)/32)*4;
@@ -771,7 +771,7 @@ bool QBmpHandler::write(const QImage &img)
// write file header
bf.bfReserved1 = 0;
bf.bfReserved2 = 0;
- bf.bfOffBits = BMP_FILEHDR_SIZE + BMP_WIN + image.numColors() * 4;
+ bf.bfOffBits = BMP_FILEHDR_SIZE + BMP_WIN + image.colorCount() * 4;
bf.bfSize = bf.bfOffBits + bpl_bmp*image.height();
s << bf;
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index e0779a0f65..cff9cd207a 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -66,6 +66,7 @@
#include "private/qkde_p.h"
#endif
+#ifndef QT_NO_ICON
QT_BEGIN_NAMESPACE
/*!
@@ -1217,3 +1218,4 @@ QSize QIcon::pixmapSize(Size which)
*/
QT_END_NAMESPACE
+#endif //QT_NO_ICON
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
index fc96a65cde..43a59a6c5c 100644
--- a/src/gui/image/qicon_p.h
+++ b/src/gui/image/qicon_p.h
@@ -60,6 +60,7 @@
#include <QtGui/qicon.h>
#include <QtGui/qiconengine.h>
+#ifndef QT_NO_ICON
QT_BEGIN_NAMESPACE
class QIconPrivate
@@ -134,5 +135,5 @@ private:
};
QT_END_NAMESPACE
-
+#endif //QT_NO_ICON
#endif // QICON_P_H
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 5412e11ce1..15af7a2e4b 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -38,7 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
+#ifndef QT_NO_ICON
#include <private/qiconloader_p.h>
#include <private/qapplication_p.h>
@@ -61,7 +61,6 @@
#ifdef Q_WS_X11
#include <private/qt_x11_p.h>
-#include <private/gtksymbols_p.h>
#endif
QT_BEGIN_NAMESPACE
@@ -78,6 +77,8 @@ static QString fallbackTheme()
return X11->desktopVersion >= 4
? QString::fromLatin1("oxygen")
: QString::fromLatin1("crystalsvg");
+ } else {
+ return QLatin1String("hicolor");
}
#endif
return QString();
@@ -87,12 +88,16 @@ QIconLoader::QIconLoader() :
m_themeKey(1), m_supportsSvg(false)
{
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()
@@ -107,6 +112,8 @@ 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();
@@ -154,7 +161,7 @@ QIconTheme::QIconTheme(const QString &themeName)
break;
}
}
-
+#ifndef QT_NO_SETTINGS
if (themeIndex.exists()) {
const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
QStringListIterator keyIterator(indexReader.allKeys());
@@ -207,6 +214,7 @@ QIconTheme::QIconTheme(const QString &themeName)
if (!m_parents.contains(QLatin1String("hicolor")))
m_parents.append(QLatin1String("hicolor"));
}
+#endif //QT_NO_SETTINGS
}
QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
@@ -540,3 +548,5 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
}
QT_END_NAMESPACE
+
+#endif //QT_NO_ICON
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index b152d46071..2a330d33ce 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -42,6 +42,7 @@
#ifndef QDESKTOPICON_P_H
#define QDESKTOPICON_P_H
+#ifndef QT_NO_ICON
//
// W A R N I N G
// -------------
@@ -185,3 +186,5 @@ private:
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 9048387c32..ec8dd88c98 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -377,6 +377,9 @@ bool QImageData::checkForAlphaPixels() const
\note If you would like to load QImage objects in a static build of Qt,
refer to the \l{How To Create Qt Plugins#Static Plugins}{Plugin HowTo}.
+ \warning Painting on a QImage with the format
+ QImage::Format_Indexed8 is not supported.
+
\tableofcontents
\section1 Reading and Writing Image Files
@@ -446,7 +449,7 @@ bool QImageData::checkForAlphaPixels() const
to the pixel() function. The pixel() function returns the color
as a QRgb value indepedent of the image's format.
- In case of monochrome and 8-bit images, the numColors() and
+ In case of monochrome and 8-bit images, the colorCount() and
colorTable() functions provide information about the color
components used to store the image data: The colorTable() function
returns the image's entire color table. To obtain a single entry,
@@ -481,7 +484,7 @@ bool QImageData::checkForAlphaPixels() const
depths are 1 (monochrome), 8 and 32 (for more information see the
\l {QImage#Image Formats}{Image Formats} section).
- The format(), bytesPerLine(), and numBytes() functions provide
+ The format(), bytesPerLine(), and byteCount() functions provide
low-level information about the data stored in the image.
The cacheKey() function returns a number that uniquely
@@ -543,11 +546,7 @@ bool QImageData::checkForAlphaPixels() const
Each pixel stored in a QImage is represented by an integer. The
size of the integer varies depending on the format. QImage
supports several image formats described by the \l Format
- enum. The monochrome (1-bit), 8-bit and 32-bit images are
- available in all versions of Qt. In addition Qt for Embedded Linux
- also supports 2-bit, 4-bit, and 16-bit images. For more information
- about the Qt Extended specific formats, see the documentation of the \l
- Format enum.
+ enum.
Monochrome images are stored using 1-bit indexes into a color table
with at most two colors. There are two different types of
@@ -624,7 +623,7 @@ bool QImageData::checkForAlphaPixels() const
\o Sets the color table used to translate color indexes. Only
monochrome and 8-bit formats.
\row
- \o setNumColors()
+ \o setColorCount()
\o Resizes the color table. Only monochrome and 8-bit formats.
\endtable
@@ -704,9 +703,20 @@ bool QImageData::checkForAlphaPixels() const
packed with the most significant bit (MSB) first.
\value Format_MonoLSB The image is stored using 1-bit per pixel. Bytes are
packed with the less significant bit (LSB) first.
- \value Format_Indexed8 The image is stored using 8-bit indexes into a colormap.
+
+ \value Format_Indexed8 The image is stored using 8-bit indexes
+ into a colormap. \warning Drawing into a
+ QImage with Indexed8 format is not
+ supported.
+
\value Format_RGB32 The image is stored using a 32-bit RGB format (0xffRRGGBB).
- \value Format_ARGB32 The image is stored using a 32-bit ARGB format (0xAARRGGBB).
+
+ \value Format_ARGB32 The image is stored using a 32-bit ARGB
+ format (0xAARRGGBB). \warning Do not
+ render into ARGB32 images using
+ QPainter. Format_ARGB32_Premultiplied is
+ significantly faster.
+
\value Format_ARGB32_Premultiplied The image is stored using a premultiplied 32-bit
ARGB format (0xAARRGGBB), i.e. the red,
green, and blue channels are multiplied
@@ -715,7 +725,9 @@ bool QImageData::checkForAlphaPixels() const
undefined.) Certain operations (such as image composition
using alpha blending) are faster using premultiplied ARGB32
than with plain ARGB32.
+
\value Format_RGB16 The image is stored using a 16-bit RGB format (5-6-5).
+
\value Format_ARGB8565_Premultiplied The image is stored using a
premultiplied 24-bit ARGB format (8-5-6-5).
\value Format_RGB666 The image is stored using a 24-bit RGB format (6-6-6).
@@ -894,7 +906,7 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm
If \a format is an indexed color format, the image color table is
initially empty and must be sufficiently expanded with
- setNumColors() or setColorTable() before the image is used.
+ setColorCount() or setColorTable() before the image is used.
*/
QImage::QImage(uchar* data, int width, int height, Format format)
: QPaintDevice()
@@ -916,7 +928,7 @@ QImage::QImage(uchar* data, int width, int height, Format format)
If \a format is an indexed color format, the image color table is
initially empty and must be sufficiently expanded with
- setNumColors() or setColorTable() before the image is used.
+ setColorCount() or setColorTable() before the image is used.
Unlike the similar QImage constructor that takes a non-const data buffer,
this version will never alter the contents of the buffer. For example,
@@ -942,7 +954,7 @@ QImage::QImage(const uchar* data, int width, int height, Format format)
If \a format is an indexed color format, the image color table is
initially empty and must be sufficiently expanded with
- setNumColors() or setColorTable() before the image is used.
+ setColorCount() or setColorTable() before the image is used.
*/
QImage::QImage(uchar *data, int width, int height, int bytesPerLine, Format format)
:QPaintDevice()
@@ -962,7 +974,7 @@ QImage::QImage(uchar *data, int width, int height, int bytesPerLine, Format form
If \a format is an indexed color format, the image color table is
initially empty and must be sufficiently expanded with
- setNumColors() or setColorTable() before the image is used.
+ setColorCount() or setColorTable() before the image is used.
Unlike the similar QImage constructor that takes a non-const data buffer,
this version will never alter the contents of the buffer. For example,
@@ -1114,7 +1126,7 @@ QImage::QImage(const QImage &image)
Use the constructor that accepts a width, a height and a format
(i.e. specifying the depth and bit order), in combination with the
- setNumColors() function, instead.
+ setColorCount() function, instead.
\oldcode
QImage image(width, height, depth, numColors);
@@ -1123,15 +1135,15 @@ QImage::QImage(const QImage &image)
// For 8 bit images the default number of colors is 256. If
// another number of colors is required it can be specified
- // using the setNumColors() function.
- image.setNumColors(numColors);
+ // using the setColorCount() function.
+ image.setColorCount(numColors);
\endcode
*/
-QImage::QImage(int w, int h, int depth, int numColors, Endian bitOrder)
+QImage::QImage(int w, int h, int depth, int colorCount, Endian bitOrder)
: QPaintDevice()
{
- d = QImageData::create(QSize(w, h), formatFor(depth, bitOrder), numColors);
+ d = QImageData::create(QSize(w, h), formatFor(depth, bitOrder), colorCount);
}
/*!
@@ -1140,7 +1152,7 @@ QImage::QImage(int w, int h, int depth, int numColors, Endian bitOrder)
Use the constructor that accepts a size and a format
(i.e. specifying the depth and bit order), in combination with the
- setNumColors() function, instead.
+ setColorCount() function, instead.
\oldcode
QSize mySize(width, height);
@@ -1151,8 +1163,8 @@ QImage::QImage(int w, int h, int depth, int numColors, Endian bitOrder)
// For 8 bit images the default number of colors is 256. If
// another number of colors is required it can be specified
- // using the setNumColors() function.
- image.setNumColors(numColors);
+ // using the setColorCount() function.
+ image.setColorCount(numColors);
\endcode
*/
QImage::QImage(const QSize& size, int depth, int numColors, Endian bitOrder)
@@ -1220,7 +1232,7 @@ QImage::QImage(uchar* data, int w, int h, int depth, const QRgb* colortable, int
for (int i = 0; i < numColors; ++i)
d->colortable[i] = colortable[i];
} else if (numColors) {
- setNumColors(numColors);
+ setColorCount(numColors);
}
}
@@ -1271,7 +1283,7 @@ QImage::QImage(uchar* data, int w, int h, int depth, int bpl, const QRgb* colort
for (int i = 0; i < numColors; ++i)
d->colortable[i] = colortable[i];
} else if (numColors) {
- setNumColors(numColors);
+ setColorCount(numColors);
}
}
#endif // Q_WS_QWS
@@ -1580,17 +1592,31 @@ int QImage::depth() const
}
/*!
+ \obsolete
\fn int QImage::numColors() const
Returns the size of the color table for the image.
- Notice that numColors() returns 0 for 32-bpp images because these
+ \sa setColorCount()
+*/
+int QImage::numColors() const
+{
+ return d ? d->colortable.size() : 0;
+}
+
+/*!
+ \since 4.6
+ \fn int QImage::colorCount() const
+
+ Returns the size of the color table for the image.
+
+ Notice that colorCount() returns 0 for 32-bpp images because these
images do not use color tables, but instead encode pixel values as
ARGB quadruplets.
- \sa setNumColors(), {QImage#Image Information}{Image Information}
+ \sa setColorCount(), {QImage#Image Information}{Image Information}
*/
-int QImage::numColors() const
+int QImage::colorCount() const
{
return d ? d->colortable.size() : 0;
}
@@ -1699,7 +1725,7 @@ void QImage::setColorTable(const QVector<QRgb> colors)
Returns a list of the colors contained in the image's color table,
or an empty list if the image does not have a color table
- \sa setColorTable(), numColors(), color()
+ \sa setColorTable(), colorCount(), color()
*/
QVector<QRgb> QImage::colorTable() const
{
@@ -1708,12 +1734,24 @@ QVector<QRgb> QImage::colorTable() const
/*!
+ \obsolete
+ Returns the number of bytes occupied by the image data.
+
+ \sa byteCount()
+*/
+int QImage::numBytes() const
+{
+ return d ? d->nbytes : 0;
+}
+
+/*!
+ \since 4.6
Returns the number of bytes occupied by the image data.
\sa bytesPerLine(), bits(), {QImage#Image Information}{Image
Information}
*/
-int QImage::numBytes() const
+int QImage::byteCount() const
{
return d ? d->nbytes : 0;
}
@@ -1721,7 +1759,7 @@ int QImage::numBytes() const
/*!
Returns the number of bytes per image scanline.
- This is equivalent to numBytes()/ height().
+ This is equivalent to byteCount() / height().
\sa scanLine()
*/
@@ -1744,7 +1782,7 @@ int QImage::bytesPerLine() const
*/
QRgb QImage::color(int i) const
{
- Q_ASSERT(i < numColors());
+ Q_ASSERT(i < colorCount());
return d ? d->colortable.at(i) : QRgb(uint(-1));
}
@@ -1755,9 +1793,9 @@ QRgb QImage::color(int i) const
given to \a colorValue. The color value is an ARGB quadruplet.
If \a index is outside the current size of the color table, it is
- expanded with setNumColors().
+ expanded with setColorCount().
- \sa color(), numColors(), setColorTable(), {QImage#Pixel Manipulation}{Pixel
+ \sa color(), colorCount(), setColorTable(), {QImage#Pixel Manipulation}{Pixel
Manipulation}
*/
void QImage::setColor(int i, QRgb c)
@@ -1775,7 +1813,7 @@ void QImage::setColor(int i, QRgb c)
return;
if (i >= d->colortable.size())
- setNumColors(i+1);
+ setColorCount(i+1);
d->colortable[i] = c;
d->has_alpha_clut |= (qAlpha(c) != 255);
}
@@ -1832,7 +1870,7 @@ const uchar *QImage::scanLine(int i) const
data, thus ensuring that this QImage is the only one using the
current return value.
- \sa scanLine(), numBytes()
+ \sa scanLine(), byteCount()
*/
uchar *QImage::bits()
{
@@ -2013,8 +2051,21 @@ void QImage::invertPixels(InvertMode mode)
#endif
/*!
+ \obsolete
Resizes the color table to contain \a numColors entries.
+ \sa setColorCount()
+*/
+
+void QImage::setNumColors(int numColors)
+{
+ setColorCount(numColors);
+}
+
+/*!
+ \since 4.6
+ Resizes the color table to contain \a colorCount entries.
+
If the color table is expanded, all the extra colors will be set to
transparent (i.e qRgba(0, 0, 0, 0)).
@@ -2022,14 +2073,14 @@ void QImage::invertPixels(InvertMode mode)
have entries for all the pixel/index values present in the image,
otherwise the results are undefined.
- \sa numColors(), colorTable(), setColor(), {QImage#Image
+ \sa colorCount(), colorTable(), setColor(), {QImage#Image
Transformations}{Image Transformations}
*/
-void QImage::setNumColors(int numColors)
+void QImage::setColorCount(int colorCount)
{
if (!d) {
- qWarning("QImage::setNumColors: null image");
+ qWarning("QImage::setColorCount: null image");
return;
}
@@ -2039,17 +2090,16 @@ void QImage::setNumColors(int numColors)
if (!d)
return;
- if (numColors == d->colortable.size())
+ if (colorCount == d->colortable.size())
return;
- if (numColors <= 0) { // use no color table
+ if (colorCount <= 0) { // use no color table
d->colortable = QVector<QRgb>();
return;
}
int nc = d->colortable.size();
- d->colortable.resize(numColors);
- for (int i = nc; i < numColors; ++i)
+ d->colortable.resize(colorCount);
+ for (int i = nc; i < colorCount; ++i)
d->colortable[i] = 0;
-
}
/*!
@@ -3662,7 +3712,7 @@ QRgb QImage::pixel(int x, int y) const
otherwise the parameter must be a QRgb value.
If \a position is not a valid coordinate pair in the image, or if
- \a index_or_rgb >= numColors() in the case of monochrome and
+ \a index_or_rgb >= colorCount() in the case of monochrome and
8-bit images, the result is undefined.
\warning This function is expensive due to the call of the internal
@@ -3823,7 +3873,7 @@ bool QImage::allGray() const
} else {
if (d->colortable.isEmpty())
return true;
- for (int i = 0; i < numColors(); i++)
+ for (int i = 0; i < colorCount(); i++)
if (!qIsGray(d->colortable.at(i)))
return false;
}
@@ -3850,7 +3900,7 @@ bool QImage::isGrayscale() const
case 16:
return allGray();
case 8: {
- for (int i = 0; i < numColors(); i++)
+ for (int i = 0; i < colorCount(); i++)
if (d->colortable.at(i) != qRgb(i,i,i))
return false;
return true;
@@ -4071,7 +4121,8 @@ QImage QImage::createAlphaMask(Qt::ImageConversionFlags flags) const
}
QImage mask(d->width, d->height, Format_MonoLSB);
- dither_to_Mono(mask.d, d, flags, true);
+ if (!mask.isNull())
+ dither_to_Mono(mask.d, d, flags, true);
return mask;
}
@@ -4115,7 +4166,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
int w = width();
int h = height();
QImage m(w, h, Format_MonoLSB);
- m.setNumColors(2);
+ m.setColorCount(2);
m.setColor(0, QColor(Qt::color0).rgba());
m.setColor(1, QColor(Qt::color1).rgba());
m.fill(0xff);
@@ -5690,7 +5741,7 @@ QImage QImage::alphaChannel() const
int h = d->height;
QImage image(w, h, Format_Indexed8);
- image.setNumColors(256);
+ image.setColorCount(256);
// set up gray scale table.
for (int i=0; i<256; ++i)
@@ -5820,7 +5871,7 @@ static QImage smoothScaled(const QImage &source, int w, int h) {
static QImage rotated90(const QImage &image) {
QImage out(image.height(), image.width(), image.format());
- if (image.numColors() > 0)
+ if (image.colorCount() > 0)
out.setColorTable(image.colorTable());
int w = image.width();
int h = image.height();
@@ -5859,7 +5910,7 @@ static QImage rotated90(const QImage &image) {
break;
default:
for (int y=0; y<h; ++y) {
- if (image.numColors())
+ if (image.colorCount())
for (int x=0; x<w; ++x)
out.setPixel(h-y-1, x, image.pixelIndex(x, y));
else
@@ -5879,7 +5930,7 @@ static QImage rotated180(const QImage &image) {
static QImage rotated270(const QImage &image) {
QImage out(image.height(), image.width(), image.format());
- if (image.numColors() > 0)
+ if (image.colorCount() > 0)
out.setColorTable(image.colorTable());
int w = image.width();
int h = image.height();
@@ -5918,7 +5969,7 @@ static QImage rotated270(const QImage &image) {
break;
default:
for (int y=0; y<h; ++y) {
- if (image.numColors())
+ if (image.colorCount())
for (int x=0; x<w; ++x)
out.setPixel(y, w-x-1, image.pixelIndex(x, y));
else
@@ -6058,16 +6109,16 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
if (dImage.d->colortable.size() < 256) {
// colors are left in the color table, so pick that one as transparent
dImage.d->colortable.append(0x0);
- memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.numBytes());
+ memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.byteCount());
} else {
- memset(dImage.bits(), 0, dImage.numBytes());
+ memset(dImage.bits(), 0, dImage.byteCount());
}
break;
case 1:
case 16:
case 24:
case 32:
- memset(dImage.bits(), 0x00, dImage.numBytes());
+ memset(dImage.bits(), 0x00, dImage.byteCount());
break;
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 1ac56a7de0..d8809ef114 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -165,18 +165,21 @@ public:
QRect rect() const;
int depth() const;
- int numColors() const;
+ QT_DEPRECATED int numColors() const;
+ int colorCount() const;
QRgb color(int i) const;
void setColor(int i, QRgb c);
- void setNumColors(int);
+ QT_DEPRECATED void setNumColors(int);
+ void setColorCount(int);
bool allGray() const;
bool isGrayscale() const;
uchar *bits();
const uchar *bits() const;
- int numBytes() const;
+ QT_DEPRECATED int numBytes() const;
+ int byteCount() const;
uchar *scanLine(int);
const uchar *scanLine(int) const;
diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp
index d08d3ef738..35322e9811 100644
--- a/src/gui/image/qimagepixmapcleanuphooks.cpp
+++ b/src/gui/image/qimagepixmapcleanuphooks.cpp
@@ -40,7 +40,8 @@
****************************************************************************/
#include "qimagepixmapcleanuphooks_p.h"
-#include "qpixmapdata_p.h"
+#include "private/qpixmapdata_p.h"
+#include "private/qimage_p.h"
QT_BEGIN_NAMESPACE
@@ -70,19 +71,30 @@ QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance()
return qt_image_and_pixmap_cleanup_hooks;
}
-void QImagePixmapCleanupHooks::addPixmapHook(_qt_pixmap_cleanup_hook_pm hook)
+void QImagePixmapCleanupHooks::addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook)
{
- pixmapHooks.append(hook);
+ pixmapModificationHooks.append(hook);
}
+void QImagePixmapCleanupHooks::addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook)
+{
+ pixmapDestructionHooks.append(hook);
+}
+
+
void QImagePixmapCleanupHooks::addImageHook(_qt_image_cleanup_hook_64 hook)
{
imageHooks.append(hook);
}
-void QImagePixmapCleanupHooks::removePixmapHook(_qt_pixmap_cleanup_hook_pm hook)
+void QImagePixmapCleanupHooks::removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook)
{
- pixmapHooks.removeAll(hook);
+ pixmapModificationHooks.removeAll(hook);
+}
+
+void QImagePixmapCleanupHooks::removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook)
+{
+ pixmapDestructionHooks.removeAll(hook);
}
void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook)
@@ -91,18 +103,29 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook)
}
-void QImagePixmapCleanupHooks::executePixmapHooks(QPixmap* pm)
+void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm)
{
- for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapHooks.count(); ++i)
- qt_image_and_pixmap_cleanup_hooks->pixmapHooks[i](pm);
+ Q_ASSERT(qt_image_and_pixmap_cleanup_hooks);
+ for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks.count(); ++i)
+ qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks[i](pm);
if (qt_pixmap_cleanup_hook_64)
qt_pixmap_cleanup_hook_64(pm->cacheKey());
}
+void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm)
+{
+ Q_ASSERT(qt_image_and_pixmap_cleanup_hooks);
+ for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks.count(); ++i)
+ qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks[i](pm);
+
+ if (qt_pixmap_cleanup_hook_64)
+ qt_pixmap_cleanup_hook_64(pm->cacheKey());
+}
void QImagePixmapCleanupHooks::executeImageHooks(qint64 key)
{
+ Q_ASSERT(qt_image_and_pixmap_cleanup_hooks);
for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->imageHooks.count(); ++i)
qt_image_and_pixmap_cleanup_hooks->imageHooks[i](key);
@@ -110,4 +133,19 @@ void QImagePixmapCleanupHooks::executeImageHooks(qint64 key)
qt_image_cleanup_hook_64(key);
}
+void QImagePixmapCleanupHooks::enableCleanupHooks(const QPixmap &pixmap)
+{
+ enableCleanupHooks(const_cast<QPixmap &>(pixmap).data_ptr().data());
+}
+
+void QImagePixmapCleanupHooks::enableCleanupHooks(QPixmapData *pixmapData)
+{
+ pixmapData->is_cached = true;
+}
+
+void QImagePixmapCleanupHooks::enableCleanupHooks(const QImage &image)
+{
+ const_cast<QImage &>(image).data_ptr()->is_cached = true;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h
index dd2d0f7716..9e490d701c 100644
--- a/src/gui/image/qimagepixmapcleanuphooks_p.h
+++ b/src/gui/image/qimagepixmapcleanuphooks_p.h
@@ -70,18 +70,31 @@ public:
static QImagePixmapCleanupHooks *instance();
- void addPixmapHook(_qt_pixmap_cleanup_hook_pm);
+ static void enableCleanupHooks(const QImage &image);
+ static void enableCleanupHooks(const QPixmap &pixmap);
+ static void enableCleanupHooks(QPixmapData *pixmapData);
+
+ // Gets called when a pixmap is about to be modified:
+ void addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm);
+
+ // Gets called when a pixmap is about to be destroyed:
+ void addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm);
+
+ // Gets called when an image is about to be modified or destroyed:
void addImageHook(_qt_image_cleanup_hook_64);
- void removePixmapHook(_qt_pixmap_cleanup_hook_pm);
+ void removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm);
+ void removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm);
void removeImageHook(_qt_image_cleanup_hook_64);
- static void executePixmapHooks(QPixmap*);
+ static void executePixmapModificationHooks(QPixmap*);
+ static void executePixmapDestructionHooks(QPixmap*);
static void executeImageHooks(qint64 key);
private:
QList<_qt_image_cleanup_hook_64> imageHooks;
- QList<_qt_pixmap_cleanup_hook_pm> pixmapHooks;
+ QList<_qt_pixmap_cleanup_hook_pm> pixmapModificationHooks;
+ QList<_qt_pixmap_cleanup_hook_pm> pixmapDestructionHooks;
};
QT_END_NAMESPACE
diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp
index 88faea8ff6..e4ea2e9cad 100644
--- a/src/gui/image/qnativeimage.cpp
+++ b/src/gui/image/qnativeimage.cpp
@@ -199,10 +199,12 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /*
shmctl(xshminfo.shmid, IPC_RMID, 0);
return;
}
- xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data,
- &xshminfo, width, height, dd);
- if (!xshmpm) {
- qWarning() << "QNativeImage: Unable to create shared Pixmap.";
+ 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.";
+ }
}
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 21fb23e5f1..a5416684dd 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -113,13 +113,10 @@ void QPixmap::init(int w, int h, Type type)
void QPixmap::init(int w, int h, int type)
{
- QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
- if (gs)
- data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type));
+ if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
+ data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
else
- data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type));
-
- data->resize(w, h);
+ data = 0;
}
/*!
@@ -307,7 +304,7 @@ QPixmap::QPixmap(const char * const xpm[])
QImage image(xpm);
if (!image.isNull()) {
- if (data->pixelType() == QPixmapData::BitmapType)
+ if (data && data->pixelType() == QPixmapData::BitmapType)
*this = QBitmap::fromImage(image);
else
*this = fromImage(image);
@@ -322,8 +319,9 @@ QPixmap::QPixmap(const char * const xpm[])
QPixmap::~QPixmap()
{
- if (data->is_cached && data->ref == 1)
- QImagePixmapCleanupHooks::executePixmapHooks(this);
+ Q_ASSERT(!data || data->ref >= 1); // Catch if ref-counting changes again
+ if (data && data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns
+ QImagePixmapCleanupHooks::executePixmapDestructionHooks(this);
}
/*!
@@ -361,13 +359,7 @@ QPixmap QPixmap::copy(const QRect &rect) const
const QRect r = rect.isEmpty() ? QRect(0, 0, width(), height()) : rect;
- QPixmapData *d;
- QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
- if (gs)
- d = gs->createPixmapData(data->pixelType());
- else
- d = QGraphicsSystem::createDefaultPixmapData(data->pixelType());
-
+ QPixmapData *d = data->createCompatiblePixmapData();
d->copy(data.data(), r);
return QPixmap(d);
}
@@ -475,9 +467,11 @@ QPixmap::operator QVariant() const
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.
+ bit deep. Images with more bits will be returned in a format
+ closely represents the underlying system. Usually this will be
+ QImage::Format_ARGB32_Premultiplied for pixmaps with an alpha and
+ QImage::Format_RGB32 or QImage::Format_RGB16 for pixmaps without
+ alpha.
Note that for the moment, alpha masks on monochrome images are
ignored.
@@ -547,7 +541,7 @@ bool QPixmap::isQBitmap() const
*/
bool QPixmap::isNull() const
{
- return data->isNull();
+ return !data || data->isNull();
}
/*!
@@ -559,7 +553,7 @@ bool QPixmap::isNull() const
*/
int QPixmap::width() const
{
- return data->width();
+ return data ? data->width() : 0;
}
/*!
@@ -571,7 +565,7 @@ int QPixmap::width() const
*/
int QPixmap::height() const
{
- return data->height();
+ return data ? data->height() : 0;
}
/*!
@@ -584,7 +578,7 @@ int QPixmap::height() const
*/
QSize QPixmap::size() const
{
- return QSize(data->width(), data->height());
+ return data ? QSize(data->width(), data->height()) : QSize();
}
/*!
@@ -596,7 +590,7 @@ QSize QPixmap::size() const
*/
QRect QPixmap::rect() const
{
- return QRect(0, 0, data->width(), data->height());
+ return data ? QRect(0, 0, data->width(), data->height()) : QRect();
}
/*!
@@ -612,7 +606,7 @@ QRect QPixmap::rect() const
*/
int QPixmap::depth() const
{
- return data->depth();
+ return data ? data->depth() : 0;
}
/*!
@@ -642,16 +636,16 @@ void QPixmap::resize_helper(const QSize &s)
return;
// Create new pixmap
- QPixmap pm(QSize(w, h), data->type);
+ QPixmap pm(QSize(w, h), data ? data->type : QPixmapData::PixmapType);
bool uninit = false;
#if defined(Q_WS_X11)
- QX11PixmapData *x11Data = data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;
+ QX11PixmapData *x11Data = data && data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;
if (x11Data) {
pm.x11SetScreen(x11Data->xinfo.screen());
uninit = x11Data->flags & QX11PixmapData::Uninitialized;
}
#elif defined(Q_WS_MAC)
- QMacPixmapData *macData = data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
+ QMacPixmapData *macData = data && data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
if (macData)
uninit = macData->uninit;
#endif
@@ -731,6 +725,9 @@ void QPixmap::setMask(const QBitmap &mask)
return;
}
+ if (isNull())
+ return;
+
if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
return;
@@ -829,11 +826,14 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
QFileInfo info(fileName);
QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') +
- QString::number(info.size()) + QLatin1Char('_') + QString::number(data->pixelType());
+ QString::number(info.size()) + QLatin1Char('_') + QString::number(data ? data->pixelType() : QPixmapData::PixmapType);
if (QPixmapCache::find(key, *this))
return true;
+ if (!data)
+ data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
+
if (data->fromFile(fileName, format, flags)) {
QPixmapCache::insert(key, *this);
return true;
@@ -863,6 +863,12 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
{
+ if (len == 0 || buf == 0)
+ return false;
+
+ if (!data)
+ data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
+
return data->fromData(buf, len, format, flags);
}
@@ -947,6 +953,9 @@ bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
/*!
Fills the pixmap with the given \a color.
+ The effect of this function is undefined when the pixmap is
+ being painted on.
+
\sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
*/
@@ -955,7 +964,24 @@ void QPixmap::fill(const QColor &color)
if (isNull())
return;
- detach();
+ // Some people are probably already calling fill while a painter is active, so to not break
+ // their programs, only print a warning and return when the fill operation could cause a crash.
+ if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) {
+ qWarning("QPixmap::fill: Cannot fill while pixmap is being painted on");
+ return;
+ }
+
+ if (data->ref == 1) {
+ // detach() will also remove this pixmap from caches, so
+ // it has to be called even when ref == 1.
+ detach();
+ } 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();
+ d->resize(data->width(), data->height());
+ data = d;
+ }
data->fill(color);
}
@@ -988,6 +1014,9 @@ int QPixmap::serialNumber() const
*/
qint64 QPixmap::cacheKey() const
{
+ if (isNull())
+ return 0;
+
int classKey = data->classId();
if (classKey >= 1024)
classKey = -(classKey >> 10);
@@ -1204,7 +1233,7 @@ QPixmap::QPixmap(const QImage& image)
QPixmap &QPixmap::operator=(const QImage &image)
{
- if (data->pixelType() == QPixmapData::BitmapType)
+ if (data && data->pixelType() == QPixmapData::BitmapType)
*this = QBitmap::fromImage(image);
else
*this = fromImage(image);
@@ -1234,7 +1263,7 @@ bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Color
*/
bool QPixmap::convertFromImage(const QImage &image, ColorMode mode)
{
- if (data->pixelType() == QPixmapData::BitmapType)
+ if (data && data->pixelType() == QPixmapData::BitmapType)
*this = QBitmap::fromImage(image, colorModeToFlags(mode));
else
*this = fromImage(image, colorModeToFlags(mode));
@@ -1321,7 +1350,7 @@ Q_GUI_EXPORT void copyBlt(QPixmap *dst, int dx, int dy,
bool QPixmap::isDetached() const
{
- return data->ref == 1;
+ return data && data->ref == 1;
}
/*! \internal
@@ -1663,10 +1692,10 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
identifies the contents of the QPixmap object.
The x11Info() function returns information about the configuration
- of the X display used to display the widget. The
- x11PictureHandle() function returns the X11 Picture handle of the
- pixmap for XRender support. Note that the two latter functions are
- only available on x11.
+ of the X display used by the screen to which the pixmap currently
+ belongs. The x11PictureHandle() function returns the X11 Picture
+ handle of the pixmap for XRender support. Note that the two latter
+ functions are only available on x11.
\endtable
@@ -1733,7 +1762,7 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
*/
bool QPixmap::hasAlpha() const
{
- return (data->hasAlphaChannel() || !data->mask().isNull());
+ return data && (data->hasAlphaChannel() || !data->mask().isNull());
}
/*!
@@ -1744,7 +1773,7 @@ bool QPixmap::hasAlpha() const
*/
bool QPixmap::hasAlphaChannel() const
{
- return data->hasAlphaChannel();
+ return data && data->hasAlphaChannel();
}
/*!
@@ -1752,7 +1781,7 @@ bool QPixmap::hasAlphaChannel() const
*/
int QPixmap::metric(PaintDeviceMetric metric) const
{
- return data->metric(metric);
+ return data ? data->metric(metric) : 0;
}
/*!
@@ -1824,7 +1853,7 @@ void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
*/
QPixmap QPixmap::alphaChannel() const
{
- return data->alphaChannel();
+ return data ? data->alphaChannel() : QPixmap();
}
/*!
@@ -1832,7 +1861,7 @@ QPixmap QPixmap::alphaChannel() const
*/
QPaintEngine *QPixmap::paintEngine() const
{
- return data->paintEngine();
+ return data ? data->paintEngine() : 0;
}
/*!
@@ -1847,7 +1876,7 @@ QPaintEngine *QPixmap::paintEngine() const
*/
QBitmap QPixmap::mask() const
{
- return data->mask();
+ return data ? data->mask() : QBitmap();
}
/*!
@@ -1898,6 +1927,9 @@ int QPixmap::defaultDepth()
*/
void QPixmap::detach()
{
+ if (!data)
+ return;
+
QPixmapData::ClassId id = data->classId();
if (id == QPixmapData::RasterClass) {
QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(data.data());
@@ -1905,7 +1937,7 @@ void QPixmap::detach()
}
if (data->is_cached && data->ref == 1)
- QImagePixmapCleanupHooks::executePixmapHooks(this);
+ QImagePixmapCleanupHooks::executePixmapModificationHooks(this);
#if defined(Q_WS_MAC)
QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
@@ -2086,7 +2118,7 @@ QPixmapData* QPixmap::pixmapData() const
/*! \fn const QX11Info &QPixmap::x11Info() const
\bold{X11 only:} Returns information about the configuration of
- the X display used to display the widget.
+ the X display used by the screen to which the pixmap currently belongs.
\warning This function is only available on X11.
@@ -2120,6 +2152,13 @@ QPixmapData* QPixmap::pixmapData() const
*/
/*! \fn int QPixmap::numCols() const
+ \obsolete
+ \internal
+ \sa colorCount()
+*/
+
+/*! \fn int QPixmap::colorCount() const
+ \since 4.6
\internal
*/
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index d11bd03565..d95b4eead8 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -185,7 +185,8 @@ public:
const uchar *qwsBits() const;
int qwsBytesPerLine() const;
QRgb *clut() const;
- int numCols() const;
+ QT_DEPRECATED int numCols() const;
+ int colorCount() const;
#elif defined(Q_WS_MAC)
Qt::HANDLE macQDHandle() const;
Qt::HANDLE macQDAlphaHandle() const;
diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp
index de532fd5a8..6175931f80 100644
--- a/src/gui/image/qpixmap_mac.cpp
+++ b/src/gui/image/qpixmap_mac.cpp
@@ -166,6 +166,11 @@ QMacPixmapData::QMacPixmapData(PixelType type)
{
}
+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))
@@ -243,7 +248,7 @@ void QMacPixmapData::fromImage(const QImage &img,
} else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
conv8 = d == 1; // native depth wanted
} else if (d == 1) {
- if (image.numColors() == 2) {
+ 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);
@@ -300,11 +305,15 @@ void QMacPixmapData::fromImage(const QImage &img,
}
break;
}
- case QImage::Format_Indexed8:
- for (int x = 0; x < w; ++x) {
- *(drow+x) = PREMUL(image.color(*(srow + x)));
+ 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;
+ } break;
case QImage::Format_RGB32:
for (int x = 0; x < w; ++x)
*(drow+x) = *(((quint32*)srow) + x) | 0xFF000000;
@@ -330,7 +339,7 @@ void QMacPixmapData::fromImage(const QImage &img,
bool alphamap = image.depth() == 32;
if (sfmt == QImage::Format_Indexed8) {
const QVector<QRgb> rgb = image.colorTable();
- for (int i = 0, count = image.numColors(); i < count; ++i) {
+ for (int i = 0, count = image.colorCount(); i < count; ++i) {
const int alpha = qAlpha(rgb[i]);
if (alpha != 0xff) {
alphamap = true;
@@ -346,13 +355,13 @@ void QMacPixmapData::fromImage(const QImage &img,
int get_index(QImage * qi,QRgb mycol)
{
int loopc;
- for(loopc=0;loopc<qi->numColors();loopc++) {
+ for(loopc=0;loopc<qi->colorCount();loopc++) {
if(qi->color(loopc)==mycol)
return loopc;
}
- qi->setNumColors(qi->numColors()+1);
- qi->setColor(qi->numColors(),mycol);
- return qi->numColors();
+ qi->setColorCount(qi->colorCount()+1);
+ qi->setColor(qi->colorCount(),mycol);
+ return qi->colorCount();
}
QImage QMacPixmapData::toImage() const
@@ -367,7 +376,7 @@ QImage QMacPixmapData::toImage() const
const uint sbpr = bytesPerRow;
if (format == QImage::Format_MonoLSB) {
image.fill(0);
- image.setNumColors(2);
+ image.setColorCount(2);
image.setColor(0, QColor(Qt::color0).rgba());
image.setColor(1, QColor(Qt::color1).rgba());
for (int y = 0; y < h; ++y) {
@@ -960,6 +969,9 @@ Qt::HANDLE QPixmap::macQDAlphaHandle() const
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)
diff --git a/src/gui/image/qpixmap_mac_p.h b/src/gui/image/qpixmap_mac_p.h
index 528dd1f346..a3fb95f847 100644
--- a/src/gui/image/qpixmap_mac_p.h
+++ b/src/gui/image/qpixmap_mac_p.h
@@ -65,6 +65,8 @@ 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);
diff --git a/src/gui/image/qpixmap_qws.cpp b/src/gui/image/qpixmap_qws.cpp
index 6b4283ecc8..69626edb83 100644
--- a/src/gui/image/qpixmap_qws.cpp
+++ b/src/gui/image/qpixmap_qws.cpp
@@ -114,7 +114,7 @@ QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
QRgb* QPixmap::clut() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
return d->image.colorTable().data();
}
@@ -124,9 +124,14 @@ QRgb* QPixmap::clut() const
int QPixmap::numCols() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ return colorCount();
+}
+
+int QPixmap::colorCount() const
+{
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
- return d->image.numColors();
+ return d->image.colorCount();
}
return 0;
@@ -134,7 +139,7 @@ int QPixmap::numCols() const
const uchar* QPixmap::qwsBits() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
return d->image.bits();
}
@@ -144,7 +149,7 @@ const uchar* QPixmap::qwsBits() const
int QPixmap::qwsBytesPerLine() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
return d->image.bytesPerLine();
}
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index ad68b07e96..1b01e6f3bb 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -55,6 +55,29 @@ 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);
+
+ data->fromImage(image, Qt::AutoColor);
+
+ return QPixmap(data);
+}
+
+QPixmap qt_toRasterPixmap(const QPixmap &pixmap)
+{
+ if (pixmap.isNull())
+ return QPixmap();
+
+ if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::RasterClass)
+ return pixmap;
+
+ return qt_toRasterPixmap(pixmap.toImage());
+}
+
QRasterPixmapData::QRasterPixmapData(PixelType type)
: QPixmapData(type, RasterClass)
{
@@ -64,6 +87,11 @@ QRasterPixmapData::~QRasterPixmapData()
{
}
+QPixmapData *QRasterPixmapData::createCompatiblePixmapData() const
+{
+ return new QRasterPixmapData(pixelType());
+}
+
void QRasterPixmapData::resize(int width, int height)
{
QImage::Format format;
@@ -91,7 +119,7 @@ void QRasterPixmapData::resize(int width, int height)
is_null = (w <= 0 || h <= 0);
if (pixelType() == BitmapType && !image.isNull()) {
- image.setNumColors(2);
+ image.setColorCount(2);
image.setColor(0, QColor(Qt::color0).rgba());
image.setColor(1, QColor(Qt::color1).rgba());
}
diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h
index da0405e9f7..1553940cd8 100644
--- a/src/gui/image/qpixmap_raster_p.h
+++ b/src/gui/image/qpixmap_raster_p.h
@@ -68,6 +68,8 @@ public:
QRasterPixmapData(PixelType type);
~QRasterPixmapData();
+ QPixmapData *createCompatiblePixmapData() const;
+
void resize(int width, int height);
void fromFile(const QString &filename, Qt::ImageConversionFlags flags);
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index 9ae8d7291d..17baa50dcf 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -73,27 +73,27 @@ const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
used to lock the global bitmap heap. Only used in
S60 v3.1 and S60 v3.2.
*/
+_LIT(KFBSERVLargeBitmapAccessName,"FbsLargeBitmapAccess");
class QSymbianFbsClient
{
public:
- QSymbianFbsClient() : heapLock(0), heapLocked(false)
+ QSymbianFbsClient() : heapLocked(false)
{
- QT_TRAP_THROWING(heapLock = new(ELeave) CFbsBitmap);
- heapLock->Create(TSize(0,0), S60->screenDevice()->DisplayMode());
+ heapLock.OpenGlobal(KFBSERVLargeBitmapAccessName);
}
~QSymbianFbsClient()
{
- delete heapLock;
+ heapLock.Close();
}
bool lockHeap()
{
bool wasLocked = heapLocked;
- if (heapLock && !heapLocked) {
- heapLock->LockHeap(ETrue);
+ if (heapLock.Handle() && !heapLocked) {
+ heapLock.Wait();
heapLocked = true;
}
@@ -104,8 +104,8 @@ public:
{
bool wasLocked = heapLocked;
- if (heapLock && heapLocked) {
- heapLock->UnlockHeap(ETrue);
+ if (heapLock.Handle() && heapLocked) {
+ heapLock.Signal();
heapLocked = false;
}
@@ -115,7 +115,7 @@ public:
private:
- CFbsBitmap *heapLock;
+ RMutex heapLock;
bool heapLocked;
};
@@ -169,7 +169,7 @@ public:
inline void beginDataAccess(CFbsBitmap *bitmap)
{
- if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3)
+ if (symbianVersion == QSysInfo::SV_9_2)
heapWasLocked = qt_symbianFbsClient()->lockHeap();
else
bitmap->LockHeap(ETrue);
@@ -177,7 +177,7 @@ public:
inline void endDataAccess(CFbsBitmap *bitmap)
{
- if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) {
+ if (symbianVersion == QSysInfo::SV_9_2) {
if (!heapWasLocked)
qt_symbianFbsClient()->unlockHeap();
} else {
@@ -311,7 +311,7 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h)
CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
{
QPixmapData *data = pixmapData();
- if (data->isNull())
+ if (!data || data->isNull())
return 0;
return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPixmapData::FbsBitmap));
@@ -337,8 +337,9 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
if (!bitmap)
return QPixmap();
- QPixmap pixmap;
- pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
+ QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
+ data->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
+ QPixmap pixmap(data.take());
return pixmap;
}
@@ -348,7 +349,8 @@ QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
bitmapDevice(0),
bitmapGc(0),
pengine(0),
- bytes(0)
+ bytes(0),
+ formatLocked(false)
{
}
@@ -424,11 +426,12 @@ void QS60PixmapData::release()
}
/*!
- * Takes ownership of bitmap
+ * Takes ownership of bitmap. Used by window surface
*/
void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap)
{
cfbsBitmap = bitmap;
+ formatLocked = true;
if(!initSymbianBitmapContext()) {
qWarning("Could not create CBitmapContext");
@@ -442,7 +445,7 @@ void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap)
// Create default palette if needed
if (cfbsBitmap->DisplayMode() == EGray2) {
- image.setNumColors(2);
+ image.setColorCount(2);
image.setColor(0, QColor(Qt::color0).rgba());
image.setColor(1, QColor(Qt::color1).rgba());
@@ -496,11 +499,12 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags
mode = EColor16MU;
break;
case QImage::Format_ARGB32_Premultiplied:
-#if !defined(__SERIES60_31__) && !defined(__S60_32__)
- mode = EColor16MAP;
- break;
-#endif
- destFormat = QImage::Format_ARGB32;
+ if (S60->supportsPremultipliedAlpha) {
+ mode = Q_SYMBIAN_ECOLOR16MAP;
+ break;
+ } else {
+ destFormat = QImage::Format_ARGB32;
+ }
// Fall through intended
case QImage::Format_ARGB32:
mode = EColor16MA;
@@ -524,13 +528,13 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags
const uchar *sptr = const_cast<const QImage &>(sourceImage).bits();
symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
uchar *dptr = (uchar*)cfbsBitmap->DataAddress();
- Mem::Copy(dptr, sptr, sourceImage.numBytes());
+ Mem::Copy(dptr, sptr, sourceImage.byteCount());
symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
UPDATE_BUFFER();
if (destFormat == QImage::Format_MonoLSB) {
- image.setNumColors(2);
+ image.setColorCount(2);
image.setColor(0, QColor(Qt::color0).rgba());
image.setColor(1, QColor(Qt::color1).rgba());
} else {
@@ -683,14 +687,19 @@ void QS60PixmapData::beginDataAccess()
uchar* newBytes = (uchar*)cfbsBitmap->DataAddress();
- if (newBytes == bytes)
- return;
+ 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);
- TSize size = cfbsBitmap->SizeInPixels();
+ // 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())
@@ -747,9 +756,9 @@ QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage)
if (!sgImage)
return QPixmap();
- QPixmap pixmap;
- pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
-
+ QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
+ data->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
+ QPixmap pixmap(data.take());
return pixmap;
}
@@ -794,8 +803,8 @@ void* QS60PixmapData::toNativeType(NativeType type)
bool needsCopy = false;
QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
- if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) {
- // Convert argb32_premultiplied to argb32 since Symbian 9.2 and Symbian 9.3 do
+ if (!(S60->supportsPremultipliedAlpha)) {
+ // Convert argb32_premultiplied to argb32 since Symbian 9.2 does
// not support premultipied format.
if (image.format() == QImage::Format_ARGB32_Premultiplied) {
@@ -830,7 +839,7 @@ void* QS60PixmapData::toNativeType(NativeType type)
symbianBitmapDataAccess->beginDataAccess(newBitmap);
uchar *dptr = (uchar*)newBitmap->DataAddress();
- Mem::Copy(dptr, sptr, source.numBytes());
+ Mem::Copy(dptr, sptr, source.byteCount());
symbianBitmapDataAccess->endDataAccess(newBitmap);
@@ -930,18 +939,21 @@ void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType)
da.beginDataAccess(sourceBitmap);
uchar *bytes = (uchar*)sourceBitmap->DataAddress();
QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
+ img = img.copy();
da.endDataAccess(sourceBitmap);
- fromImage(img, Qt::AutoColor);
-
- if(deleteSourceBitmap)
- delete 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.
- image.invertPixels();
+ 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);
diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h
index b23961a148..b1b58248d6 100644
--- a/src/gui/image/qpixmap_s60_p.h
+++ b/src/gui/image/qpixmap_s60_p.h
@@ -118,6 +118,8 @@ private:
QPaintEngine *pengine;
uchar* bytes;
+ bool formatLocked;
+
friend class QPixmap;
friend class QS60WindowSurface;
friend class QS60PaintEngine;
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 1b6148479d..04027c156a 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -121,6 +121,9 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h )
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());
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index 74543a034a..7008fbd4a1 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -319,6 +319,11 @@ QX11PixmapData::QX11PixmapData(PixelType type)
{
}
+QPixmapData *QX11PixmapData::createCompatiblePixmapData() const
+{
+ return new QX11PixmapData(pixelType());
+}
+
void QX11PixmapData::resize(int width, int height)
{
setSerialNumber(++qt_pixmap_serial);
@@ -411,6 +416,11 @@ void QX11PixmapData::fromImage(const QImage &img,
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;
@@ -459,7 +469,7 @@ void QX11PixmapData::fromImage(const QImage &img,
} else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
conv8 = (d == 1); // native depth wanted
} else if (d == 1) {
- if (image.numColors() == 2) {
+ 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);
@@ -484,7 +494,7 @@ void QX11PixmapData::fromImage(const QImage &img,
Visual *visual = (Visual *)xinfo.visual();
XImage *xi = 0;
bool trucol = (visual->c_class >= TrueColor);
- int nbytes = image.numBytes();
+ int nbytes = image.byteCount();
uchar *newbits= 0;
#ifndef QT_NO_XRENDER
@@ -626,7 +636,7 @@ void QX11PixmapData::fromImage(const QImage &img,
if (d8) { // setup pixel translation
QVector<QRgb> ctable = cimage.colorTable();
- for (int i=0; i < cimage.numColors(); i++) {
+ for (int i=0; i < cimage.colorCount(); i++) {
int r = qRed (ctable[i]);
int g = qGreen(ctable[i]);
int b = qBlue (ctable[i]);
@@ -952,8 +962,8 @@ void QX11PixmapData::fromImage(const QImage &img,
if (d == 8 && !trucol) { // 8 bit pixmap
int pop[256]; // pixel popularity
- if (image.numColors() == 0)
- image.setNumColors(1);
+ if (image.colorCount() == 0)
+ image.setColorCount(1);
const QImage &cimage = image;
memset(pop, 0, sizeof(int)*256); // reset popularity array
@@ -983,11 +993,11 @@ void QX11PixmapData::fromImage(const QImage &img,
int mindist;
};
int ncols = 0;
- for (int i=0; i< cimage.numColors(); i++) { // compute number of colors
+ for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors
if (pop[i] > 0)
ncols++;
}
- for (int i = cimage.numColors(); i < 256; i++) // ignore out-of-range pixels
+ 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
@@ -1646,7 +1656,7 @@ QImage QX11PixmapData::toImage() const
}
if (d == 1) { // bitmap
- image.setNumColors(2);
+ image.setColorCount(2);
image.setColor(0, qRgb(255,255,255));
image.setColor(1, qRgb(0,0,0));
} else if (!trucol) { // pixmap with colormap
@@ -1702,10 +1712,10 @@ QImage QX11PixmapData::toImage() const
int trans;
if (ncols < 256) {
trans = ncols++;
- image.setNumColors(ncols); // create color table
+ image.setColorCount(ncols); // create color table
image.setColor(trans, 0x00000000);
} else {
- image.setNumColors(ncols); // create color table
+ 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];
@@ -1728,7 +1738,7 @@ QImage QX11PixmapData::toImage() const
}
}
} else {
- image.setNumColors(ncols); // create color table
+ image.setColorCount(ncols); // create color table
}
QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap();
int j = 0;
@@ -1911,8 +1921,8 @@ QPixmap QX11PixmapData::transformed(const QTransform &transform,
free(dptr);
return bm;
} else { // color pixmap
- QPixmap pm;
- QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pm.data.data());
+ QX11PixmapData *x11Data = new QX11PixmapData(QPixmapData::PixmapType);
+ QPixmap pm(x11Data);
x11Data->flags &= ~QX11PixmapData::Uninitialized;
x11Data->xinfo = xinfo;
x11Data->d = d;
@@ -1971,6 +1981,9 @@ void QPixmap::x11SetScreen(int screen)
return;
}
+ if (isNull())
+ return;
+
if (data->classId() != QPixmapData::X11Class)
return;
@@ -2073,7 +2086,7 @@ bool QX11PixmapData::hasAlphaChannel() const
const QX11Info &QPixmap::x11Info() const
{
- if (data->classId() == QPixmapData::X11Class)
+ if (data && data->classId() == QPixmapData::X11Class)
return static_cast<QX11PixmapData*>(data.data())->xinfo;
else {
static QX11Info nullX11Info;
@@ -2130,7 +2143,7 @@ QPaintEngine* QX11PixmapData::paintEngine() const
Qt::HANDLE QPixmap::x11PictureHandle() const
{
#ifndef QT_NO_XRENDER
- if (data->classId() == QPixmapData::X11Class)
+ if (data && data->classId() == QPixmapData::X11Class)
return static_cast<const QX11PixmapData*>(data.data())->picture;
else
return 0;
diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h
index e34e690c67..8ce7c0d053 100644
--- a/src/gui/image/qpixmap_x11_p.h
+++ b/src/gui/image/qpixmap_x11_p.h
@@ -71,6 +71,8 @@ public:
// 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);
@@ -101,6 +103,7 @@ private:
friend class QRasterWindowSurface;
friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags
friend class QEglContext; // Needs gl_surface
+ friend class QX11GLPixmapData; // Needs gl_surface
friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface
void release();
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index f12d3976b6..b0b7d728fe 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -221,6 +221,7 @@ QPMCache::QPMCache()
}
QPMCache::~QPMCache()
{
+ clear();
free(keyArray);
}
diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp
index 93fc2ebe21..38f6b5d550 100644
--- a/src/gui/image/qpixmapdata.cpp
+++ b/src/gui/image/qpixmapdata.cpp
@@ -43,12 +43,27 @@
#include <QtCore/qbuffer.h>
#include <QtGui/qbitmap.h>
#include <QtGui/qimagereader.h>
+#include <private/qgraphicssystem_p.h>
+#include <private/qapplication_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),
@@ -67,6 +82,17 @@ QPixmapData::~QPixmapData()
{
}
+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) {
@@ -175,7 +201,7 @@ QBitmap QPixmapData::mask() const
if (mask.isNull()) // allocation failed
return QBitmap();
- mask.setNumColors(2);
+ mask.setColorCount(2);
mask.setColor(0, QColor(Qt::color0).rgba());
mask.setColor(1, QColor(Qt::color1).rgba());
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index c26fba35d5..41e29230f1 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -75,9 +75,11 @@ public:
enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass,
OpenGLClass, OpenVGClass, CustomClass = 1024 };
- QPixmapData(PixelType pixelpType, int classId);
+ 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;
@@ -111,7 +113,8 @@ public:
inline int width() const { return w; }
inline int height() const { return h; }
- inline int numColors() const { return metric(QPaintDevice::PdmNumColors); }
+ 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; }
@@ -120,6 +123,8 @@ public:
virtual void fromNativeType(void* pixmap, NativeType type);
#endif
+ static QPixmapData *create(int w, int h, PixelType type);
+
protected:
void setSerialNumber(int serNo);
int w;
@@ -129,12 +134,11 @@ protected:
private:
friend class QPixmap;
- friend class QGLContextPrivate;
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>;
- friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs to set is_cached
QAtomicInt ref;
int detach_no;
diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp
index df445db53a..3723500cd9 100644
--- a/src/gui/image/qpixmapfilter.cpp
+++ b/src/gui/image/qpixmapfilter.cpp
@@ -53,6 +53,7 @@
#include "private/qpaintengineex_p.h"
#include "private/qpaintengine_raster_p.h"
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
class QPixmapFilterPrivate : public QObjectPrivate
@@ -489,7 +490,7 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q
which is applied when \l{QPixmapFilter::}{draw()} is called.
The filter lets you specialize the radius of the blur as well
- as hint as to whether to prefer performance or quality.
+ 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
@@ -504,10 +505,10 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q
class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate
{
public:
- QPixmapBlurFilterPrivate() : radius(5), hint(Qt::PerformanceHint) {}
+ QPixmapBlurFilterPrivate() : radius(5), hints(QGraphicsBlurEffect::PerformanceHint) {}
- int radius;
- Qt::RenderHint hint;
+ qreal radius;
+ QGraphicsBlurEffect::BlurHints hints;
};
@@ -535,7 +536,7 @@ QPixmapBlurFilter::~QPixmapBlurFilter()
\internal
*/
-void QPixmapBlurFilter::setRadius(int radius)
+void QPixmapBlurFilter::setRadius(qreal radius)
{
Q_D(QPixmapBlurFilter);
d->radius = radius;
@@ -546,36 +547,42 @@ void QPixmapBlurFilter::setRadius(int radius)
\internal
*/
-int QPixmapBlurFilter::radius() const
+qreal QPixmapBlurFilter::radius() const
{
Q_D(const QPixmapBlurFilter);
return d->radius;
}
/*!
- Setting the blur hint to PerformanceHint causes the implementation
+ Setting the blur hints to PerformanceHint causes the implementation
to trade off visual quality to blur the image faster. Setting the
- blur hint to QualityHint causes the implementation to improve
- visual quality at the expense of speed. The implementation is free
- to ignore this value if it only has a single blur algorithm.
+ 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::setBlurHint(Qt::RenderHint hint)
+void QPixmapBlurFilter::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
{
Q_D(QPixmapBlurFilter);
- d->hint = hint;
+ d->hints = hints;
}
/*!
- Gets the blur hint of the blur filter.
+ Gets the blur hints of the blur filter.
\internal
*/
-Qt::RenderHint QPixmapBlurFilter::blurHint() const
+QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const
{
Q_D(const QPixmapBlurFilter);
- return d->hint;
+ return d->hints;
}
/*!
@@ -584,14 +591,14 @@ Qt::RenderHint QPixmapBlurFilter::blurHint() const
QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const
{
Q_D(const QPixmapBlurFilter);
- const qreal delta = d->radius * 2;
+ const qreal delta = d->radius + 1;
return rect.adjusted(-delta, -delta, delta, delta);
}
// Blur the image according to the blur radius
// Based on exponential blur algorithm by Jani Huhtanen
// (maximum radius is set to 16)
-static QImage blurred(const QImage& image, const QRect& rect, int radius)
+static QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
{
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
@@ -606,47 +613,53 @@ static QImage blurred(const QImage& image, const QRect& rect, int radius)
int rgba[4];
unsigned char* p;
+ int i1 = 0;
+ int i2 = 3;
+
+ if (alphaOnly)
+ i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
+
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r1) + col * 4;
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += bpl;
for (int j = r1; j < r2; j++, p += bpl)
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c1 * 4;
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += 4;
for (int j = c1; j < c2; j++, p += 4)
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r2) + col * 4;
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= bpl;
for (int j = r1; j < r2; j++, p -= bpl)
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c2 * 4;
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= 4;
for (int j = c1; j < c2; j++, p -= 4)
- for (int i = 0; i < 4; i++)
+ for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
@@ -662,7 +675,7 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap
if (!painter->isActive())
return;
- if (d->radius == 0) {
+ if (d->radius <= 0) {
painter->drawPixmap(srcRect.translated(p), src, srcRect);
return;
}
@@ -672,7 +685,7 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap
QPixmapBlurFilter *blurFilter = static_cast<QPixmapBlurFilter*>(filter);
if (blurFilter) {
blurFilter->setRadius(d->radius);
- blurFilter->setBlurHint(d->hint);
+ blurFilter->setBlurHints(d->hints);
blurFilter->draw(painter, p, src, srcRect);
return;
}
@@ -682,12 +695,12 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap
if (srcRect.isNull()) {
srcImage = src.toImage();
- destImage = blurred(srcImage, srcImage.rect(), d->radius);
+ destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius));
} else {
QRect rect = srcRect.toAlignedRect().intersected(src.rect());
srcImage = src.copy(rect).toImage();
- destImage = blurred(srcImage, srcImage.rect(), d->radius);
+ destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius));
}
painter->drawImage(p, destImage);
@@ -892,11 +905,11 @@ class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate
{
public:
QPixmapDropShadowFilterPrivate()
- : offset(8, 8), color(63, 63, 63, 180), blurFilter(new QPixmapBlurFilter) {}
+ : offset(8, 8), color(63, 63, 63, 180), radius(1) {}
QPointF offset;
QColor color;
- QPixmapBlurFilter *blurFilter;
+ qreal radius;
};
/*!
@@ -940,8 +953,6 @@ public:
QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent)
: QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent)
{
- Q_D(QPixmapDropShadowFilter);
- d->blurFilter->setRadius(1);
}
/*!
@@ -951,8 +962,6 @@ QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent)
*/
QPixmapDropShadowFilter::~QPixmapDropShadowFilter()
{
- Q_D(QPixmapDropShadowFilter);
- delete d->blurFilter;
}
/*!
@@ -964,10 +973,10 @@ QPixmapDropShadowFilter::~QPixmapDropShadowFilter()
\internal
*/
-int QPixmapDropShadowFilter::blurRadius() const
+qreal QPixmapDropShadowFilter::blurRadius() const
{
Q_D(const QPixmapDropShadowFilter);
- return d->blurFilter->radius();
+ return d->radius;
}
/*!
@@ -979,10 +988,10 @@ int QPixmapDropShadowFilter::blurRadius() const
\internal
*/
-void QPixmapDropShadowFilter::setBlurRadius(int radius)
+void QPixmapDropShadowFilter::setBlurRadius(qreal radius)
{
Q_D(QPixmapDropShadowFilter);
- d->blurFilter->setRadius(radius);
+ d->radius = radius;
}
/*!
@@ -1055,14 +1064,7 @@ void QPixmapDropShadowFilter::setOffset(const QPointF &offset)
QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const
{
Q_D(const QPixmapDropShadowFilter);
-
- const qreal delta = qreal(d->blurFilter->radius() * 2);
- qreal x1 = qMin(rect.left(), rect.left() + d->offset.x() - delta);
- qreal y1 = qMin(rect.top(), rect.top() + d->offset.y() - delta);
- qreal x2 = qMax(rect.right(), rect.right() + d->offset.x() + delta);
- qreal y2 = qMax(rect.bottom(), rect.bottom() + d->offset.y() + delta);
-
- return QRectF(x1, y1, x2 - x1, y2 - y1);
+ return rect.united(rect.translated(d->offset).adjusted(-d->radius, -d->radius, d->radius, d->radius));
}
/*!
@@ -1079,27 +1081,35 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter);
if (dropShadowFilter) {
dropShadowFilter->setColor(d->color);
- dropShadowFilter->setBlurRadius(d->blurFilter->radius());
+ dropShadowFilter->setBlurRadius(d->radius);
dropShadowFilter->setOffset(d->offset);
dropShadowFilter->draw(p, pos, px, src);
return;
}
- QImage tmp = src.isNull() ? px.toImage() : px.copy(src.toRect()).toImage();
+ 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
+ tmp = blurred(tmp, tmp.rect(), qRound(d->radius), true);
// blacken the image...
+ tmpPainter.begin(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
- tmpPainter.fillRect(0, 0, tmp.width(), tmp.height(), d->color);
+ tmpPainter.fillRect(tmp.rect(), d->color);
tmpPainter.end();
- const QPixmap pixTmp = QPixmap::fromImage(tmp);
-
// draw the blurred drop shadow...
- d->blurFilter->draw(p, pos + d->offset, pixTmp);
+ 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
index 8a2207aa53..46e744e729 100644
--- a/src/gui/image/qpixmapfilter_p.h
+++ b/src/gui/image/qpixmapfilter_p.h
@@ -55,7 +55,9 @@
#include <QtCore/qnamespace.h>
#include <QtGui/qpixmap.h>
+#include <QtGui/qgraphicseffect.h>
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -129,11 +131,11 @@ public:
QPixmapBlurFilter(QObject *parent = 0);
~QPixmapBlurFilter();
- void setRadius(int radius);
- void setBlurHint(Qt::RenderHint hint);
+ void setRadius(qreal radius);
+ void setBlurHints(QGraphicsBlurEffect::BlurHints hints);
- int radius() const;
- Qt::RenderHint blurHint() const;
+ 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;
@@ -175,8 +177,8 @@ public:
QRectF boundingRectFor(const QRectF &rect) const;
void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src = QRectF()) const;
- int blurRadius() const;
- void setBlurRadius(int radius);
+ qreal blurRadius() const;
+ void setBlurRadius(qreal radius);
QColor color() const;
void setColor(const QColor &color);
@@ -190,4 +192,5 @@ QT_END_NAMESPACE
QT_END_HEADER
+#endif //QT_NO_GRAPHICSEFFECT
#endif // QPIXMAPFILTER_H
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 44d689d80f..14c863b2e3 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -171,7 +171,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float scre
if (image.isNull())
return;
}
- image.setNumColors(2);
+ image.setColorCount(2);
image.setColor(1, qRgb(0,0,0));
image.setColor(0, qRgb(255,255,255));
} else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
@@ -199,7 +199,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float scre
if (image.isNull())
return;
}
- image.setNumColors(ncols);
+ image.setColorCount(ncols);
for (int i=0; i<ncols; i++) {
int c = i*255/(ncols-1);
image.setColor(i, qRgba(c,c,c,0xff));
@@ -230,7 +230,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float scre
if (image.isNull())
return;
}
- image.setNumColors(info_ptr->num_palette);
+ image.setColorCount(info_ptr->num_palette);
int i = 0;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
while (i < info_ptr->num_trans) {
@@ -508,7 +508,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage)
// sanity check palette entries
if (color_type == PNG_COLOR_TYPE_PALETTE
&& outImage->format() == QImage::Format_Indexed8) {
- int color_table_size = outImage->numColors();
+ int color_table_size = outImage->colorCount();
for (int y=0; y<(int)height; ++y) {
uchar *p = outImage->scanLine(y);
uchar *end = p + width;
@@ -762,9 +762,9 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in,
png_colorp palette = 0;
png_bytep copy_trans = 0;
- if (image.numColors()) {
+ if (image.colorCount()) {
// Paletted
- int num_palette = image.numColors();
+ int num_palette = image.colorCount();
palette = new png_color[num_palette];
png_set_PLTE(png_ptr, info_ptr, palette, num_palette);
int* trans = new int[num_palette];
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 28e4a2ac25..8ec9efbe08 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -242,11 +242,11 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
}
if (nbits == 1) { // bitmap
- outImage->setNumColors(2);
+ outImage->setColorCount(2);
outImage->setColor(0, qRgb(255,255,255)); // white
outImage->setColor(1, qRgb(0,0,0)); // black
} else if (nbits == 8) { // graymap
- outImage->setNumColors(maxc+1);
+ outImage->setColorCount(maxc+1);
for (int i=0; i<=maxc; i++)
outImage->setColor(i, qRgb(i*255/maxc,i*255/maxc,i*255/maxc));
}
@@ -287,7 +287,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
}
}
- if (image.depth() == 1 && image.numColors() == 2) {
+ if (image.depth() == 1 && image.colorCount() == 2) {
if (qGray(image.color(0)) < qGray(image.color(1))) {
// 0=dark/black, 1=light/white - invert
image.detach();
diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp
index 1c74351ee0..0d76ea0910 100644
--- a/src/gui/image/qxbmhandler.cpp
+++ b/src/gui/image/qxbmhandler.cpp
@@ -135,7 +135,7 @@ static bool read_xbm_body(QIODevice *device, int w, int h, QImage *outImage)
return false;
}
- outImage->setNumColors(2);
+ outImage->setColorCount(2);
outImage->setColor(0, qRgb(255,255,255)); // white
outImage->setColor(1, qRgb(0,0,0)); // black
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index 4bdd16eeee..ac4711a66e 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -895,7 +895,7 @@ static bool read_xpm_body(
if (image.isNull())
return false;
}
- image.setNumColors(ncols);
+ image.setColorCount(ncols);
}
QMap<quint64, int> colorMap;
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 15310366bd..e24ee04d80 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -65,10 +65,10 @@
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QCoeFepInputContext : public QInputContext,
- public MCoeFepAwareTextEditor,
- public MCoeFepAwareTextEditor_Extension1,
- public MObjectProvider
+class QCoeFepInputContext : public QInputContext,
+ public MCoeFepAwareTextEditor,
+ public MCoeFepAwareTextEditor_Extension1,
+ public MObjectProvider
{
Q_OBJECT
@@ -84,7 +84,7 @@ public:
bool filterEvent(const QEvent *event);
void mouseHandler( int x, QMouseEvent *event);
- bool isComposing() const { return m_isEditing; }
+ bool isComposing() const { return !m_preeditString.isEmpty(); }
void setFocusWidget(QWidget * w);
void widgetDestroyed(QWidget *w);
@@ -97,6 +97,7 @@ private:
void applyHints(Qt::InputMethodHints hints);
void applyFormat(QList<QInputMethodEvent::Attribute> *attributes);
void queueInputCapabilitiesChanged();
+ bool needsInputPanel();
private Q_SLOTS:
void ensureInputCapabilitiesChanged();
@@ -131,6 +132,7 @@ public:
// From MObjectProvider
public:
TTypeUid::Ptr MopSupplyObject(TTypeUid id);
+ MObjectProvider *MopNext();
private:
QSymbianControl *m_parent;
@@ -138,13 +140,14 @@ private:
QString m_preeditString;
Qt::InputMethodHints m_lastImHints;
TUint m_textCapabilities;
- bool m_isEditing;
bool m_inDestruction;
bool m_pendingInputCapabilitiesChanged;
int m_cursorVisibility;
int m_inlinePosition;
MFepInlineTextFormatRetriever *m_formatRetriever;
MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
+ int m_longPress;
+ int m_cursorPos;
};
QT_END_NAMESPACE
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index c4d17ff9be..bdff5e751e 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -47,6 +47,7 @@
#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
@@ -64,13 +65,14 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new
m_lastImHints(Qt::ImhNone),
m_textCapabilities(TCoeInputCapabilities::EAllText),
- m_isEditing(false),
m_inDestruction(false),
m_pendingInputCapabilitiesChanged(false),
m_cursorVisibility(1),
m_inlinePosition(0),
m_formatRetriever(0),
- m_pointerHandler(0)
+ m_pointerHandler(0),
+ m_longPress(0),
+ m_cursorPos(0)
{
m_fepState->SetObjectProvider(this);
m_fepState->SetFlags(EAknEditorFlagDefault);
@@ -78,7 +80,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
m_fepState->SetDefaultCase( EAknEditorLowerCase );
m_fepState->SetPermittedCases( EAknEditorLowerCase|EAknEditorUpperCase );
- m_fepState->SetSpecialCharacterTableResourceId( 0 );
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
}
@@ -153,6 +155,44 @@ QString QCoeFepInputContext::language()
}
}
+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
@@ -163,21 +203,31 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
- Q_ASSERT(m_lastImHints == focusWidget()->inputMethodHints());
- if (keyEvent->key() == Qt::Key_F20 && 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;
+ switch (keyEvent->key()) {
+ case Qt::Key_F20:
+ Q_ASSERT(m_lastImHints == focusWidget()->inputMethodHints());
+ 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(false);
+ return true;
+ }
+ break;
+ default:
+ break;
}
}
- // For pre-5.0 SDKs, we don't launch the keyboard.
- if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) {
+ if (!needsInputPanel())
return false;
- }
if (event->type() == QEvent::RequestSoftwareInputPanel) {
// Notify S60 that we want the virtual keyboard to show up.
@@ -206,7 +256,6 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
{
- Q_ASSERT(m_isEditing);
Q_ASSERT(focusWidget());
if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) {
@@ -370,6 +419,14 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
}
m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags));
+ if (hints & ImhEmailCharactersOnly) {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else if (hints & ImhUrlCharactersOnly) {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
+ }
+
if (hints & ImhHiddenText) {
m_textCapabilities = TCoeInputCapabilities::EAllText | TCoeInputCapabilities::ESecretText;
} else {
@@ -441,8 +498,8 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
if (!w)
return;
- m_isEditing = true;
-
+ m_cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
+
QList<QInputMethodEvent::Attribute> attributes;
m_cursorVisibility = aCursorVisibility ? 1 : 0;
@@ -506,8 +563,6 @@ void QCoeFepInputContext::CancelFepInlineEdit()
event.setCommitString(QLatin1String(""), 0, 0);
m_preeditString.clear();
sendEvent(event);
-
- m_isEditing = false;
}
TInt QCoeFepInputContext::DocumentLengthForFep() const
@@ -561,8 +616,28 @@ void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSele
int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt() + m_preeditString.size();
int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt() + m_preeditString.size();
- aCursorSelection.iAnchorPos = anchor;
- aCursorSelection.iCursorPos = cursor;
+ 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,
@@ -626,16 +701,22 @@ void QCoeFepInputContext::DoCommitFepInlineEditL()
void QCoeFepInputContext::commitCurrentString(bool triggeredBySymbian)
{
if (m_preeditString.size() == 0) {
+ QWidget *w = focusWidget();
+ if (triggeredBySymbian && w) {
+ // We must replace the last character only if the input box has already accepted one
+ if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos)
+ m_longPress = 1;
+ }
return;
}
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_preeditString, 0, 0);//m_preeditString.size());
+ event.setCommitString(m_preeditString, 0-m_longPress, m_longPress);
m_preeditString.clear();
sendEvent(event);
- m_isEditing = false;
+ m_longPress = 0;
if (!triggeredBySymbian) {
CCoeFep* fep = CCoeEnv::Static()->Fep();
@@ -676,6 +757,14 @@ 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
index 8ee417f206..ea6ed35b57 100644
--- a/src/gui/inputmethod/qinputcontext.cpp
+++ b/src/gui/inputmethod/qinputcontext.cpp
@@ -467,32 +467,32 @@ bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/)
}
#endif // Q_WS_X11
-#ifdef Q_WS_S60
+#ifdef Q_OS_SYMBIAN
/*!
\since 4.6
This function may be overridden only if input method is depending
- on Symbian and you need raw TWsEvent. Otherwise, this function must not.
+ on Symbian and you need raw Symbian events. Otherwise, this function must not.
- This function is designed to filter raw key events on S60, but
+ 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 s60FilterEvent() and
+ 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 TWsEvent.
+ event is inputted QSymbianEvent.
\sa filterEvent()
*/
-bool QInputContext::s60FilterEvent(QWidget * /*keywidget*/, TWsEvent * /*event*/)
+bool QInputContext::symbianFilterEvent(QWidget * /*keywidget*/, const QSymbianEvent * /*event*/)
{
return false;
}
-#endif // Q_WS_S60
+#endif // Q_OS_SYMBIAN
QT_END_NAMESPACE
diff --git a/src/gui/inputmethod/qinputcontext.h b/src/gui/inputmethod/qinputcontext.h
index 73b05d8dde..14096e319a 100644
--- a/src/gui/inputmethod/qinputcontext.h
+++ b/src/gui/inputmethod/qinputcontext.h
@@ -67,10 +67,6 @@
QT_BEGIN_HEADER
-#ifdef Q_WS_S60
-class TWsEvent;
-#endif
-
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
@@ -79,6 +75,9 @@ class QWidget;
class QFont;
class QPopupMenu;
class QInputContextPrivate;
+#ifdef Q_OS_SYMBIAN
+class QSymbianEvent;
+#endif
class Q_GUI_EXPORT QInputContext : public QObject
{
@@ -108,9 +107,9 @@ public:
#if defined(Q_WS_X11)
virtual bool x11FilterEvent( QWidget *keywidget, XEvent *event );
#endif // Q_WS_X11
-#if defined(Q_WS_S60)
- virtual bool s60FilterEvent( QWidget *keywidget, TWsEvent *event );
-#endif // Q_WS_S60
+#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);
diff --git a/src/gui/inputmethod/qmacinputcontext_mac.cpp b/src/gui/inputmethod/qmacinputcontext_mac.cpp
index 116d2339ff..994edb9a76 100644
--- a/src/gui/inputmethod/qmacinputcontext_mac.cpp
+++ b/src/gui/inputmethod/qmacinputcontext_mac.cpp
@@ -217,7 +217,11 @@ QMacInputContext::globalEventProcessor(EventHandlerCallRef, EventRef event, void
case kEventClassTextInput: {
handled_event = false;
QWidget *widget = QApplicationPrivate::focus_widget;
- if(!widget || (context && widget->inputContext() != context)) {
+ bool canCompose = widget && (!context || widget->inputContext() == context)
+ && !(widget->inputMethodHints() & Qt::ImhDigitsOnly
+ || widget->inputMethodHints() & Qt::ImhFormattedNumbersOnly
+ || widget->inputMethodHints() & Qt::ImhHiddenText);
+ if(!canCompose) {
handled_event = false;
} else if(ekind == kEventTextInputOffsetToPos) {
if(!widget->testAttribute(Qt::WA_InputMethodEnabled)) {
diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp
index e9ab870906..ef2f5c03e1 100644
--- a/src/gui/inputmethod/qwininputcontext_win.cpp
+++ b/src/gui/inputmethod/qwininputcontext_win.cpp
@@ -327,28 +327,13 @@ static int getCursorPosition(HIMC himc)
static QString getString(HIMC himc, DWORD dwindex, int *selStart = 0, int *selLength = 0)
{
- static wchar_t *buffer = 0;
- static int buflen = 0;
-
- int len = getCompositionString(himc, dwindex, 0, 0) + 1;
- if (!buffer || len > buflen) {
- delete [] buffer;
- buflen = qMin(len, 256);
- buffer = new wchar_t[buflen];
- }
-
- len = getCompositionString(himc, dwindex, buffer, buflen * sizeof(wchar_t));
+ const int bufferSize = 256;
+ wchar_t buffer[bufferSize];
+ int len = getCompositionString(himc, dwindex, buffer, bufferSize * sizeof(wchar_t));
if (selStart) {
- static wchar_t *attrbuffer = 0;
- static int attrbuflen = 0;
- int attrlen = getCompositionString(himc, dwindex, 0, 0) + 1;
- if (!attrbuffer || attrlen> attrbuflen) {
- delete [] attrbuffer;
- attrbuflen = qMin(attrlen, 256);
- attrbuffer = new wchar_t[attrbuflen];
- }
- attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, attrbuflen * sizeof(wchar_t));
+ char attrbuffer[bufferSize];
+ int attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, bufferSize);
*selStart = attrlen+1;
*selLength = -1;
for (int i = 0; i < attrlen; i++) {
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 268e78ea38..23bef12004 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -605,6 +605,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
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)),
@@ -637,6 +639,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
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(rowsAboutToBeRemoved(QModelIndex,int,int)),
@@ -1697,7 +1701,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
if ((event->buttons() & Qt::LeftButton) && d->selectionAllowed(index) && d->selectionModel) {
setState(DragSelectingState);
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
- if (command.testFlag(QItemSelectionModel::Toggle)) {
+ if (d->ctrlDragSelectionFlag != QItemSelectionModel::NoUpdate && command.testFlag(QItemSelectionModel::Toggle)) {
command &= ~QItemSelectionModel::Toggle;
command |= d->ctrlDragSelectionFlag;
}
@@ -3029,7 +3033,7 @@ void QAbstractItemView::update(const QModelIndex &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->geometry().intersects(rect))
+ if (d->viewport->rect().intersects(rect))
d->viewport->update(rect);
}
}
@@ -3637,7 +3641,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC
const bool controlKeyPressed = modifiers & Qt::ControlModifier;
if (((index == pressedIndex && selectionModel->isSelected(index))
|| !index.isValid()) && state != QAbstractItemView::DragSelectingState
- && !shiftKeyPressed && !controlKeyPressed && !rightButtonPressed)
+ && !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid()))
return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
return QItemSelectionModel::NoUpdate;
}
diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h
index b4f0957c87..ea5d259f06 100644
--- a/src/gui/itemviews/qabstractitemview.h
+++ b/src/gui/itemviews/qabstractitemview.h
@@ -358,9 +358,12 @@ private:
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())
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)
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index fcf381a2a2..c691f61f9c 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -117,6 +117,7 @@ public:
virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
virtual void _q_modelDestroyed();
virtual void _q_layoutChanged();
+ void _q_headerDataChanged() { doDelayedItemsLayout(); }
void fetchMore();
@@ -164,7 +165,8 @@ public:
}
#ifndef QT_NO_DRAGANDDROP
- QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
+ 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();
diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/gui/itemviews/qdirmodel.cpp
index 29737419f1..942cfd709d 100644
--- a/src/gui/itemviews/qdirmodel.cpp
+++ b/src/gui/itemviews/qdirmodel.cpp
@@ -1351,7 +1351,7 @@ QString QDirModelPrivate::size(const QModelIndex &index) const
return QFileSystemModel::tr("%1 MB").arg(QLocale().toString(qreal(bytes) / mb, 'f', 1));
if (bytes >= kb)
return QFileSystemModel::tr("%1 KB").arg(QLocale().toString(bytes / kb));
- return QFileSystemModel::tr("%1 bytes").arg(QLocale().toString(bytes));
+ return QFileSystemModel::tr("%1 byte(s)").arg(QLocale().toString(bytes));
}
QString QDirModelPrivate::type(const QModelIndex &index) const
diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp
index e3d17ade04..631679713e 100644
--- a/src/gui/itemviews/qfileiconprovider.cpp
+++ b/src/gui/itemviews/qfileiconprovider.cpp
@@ -47,24 +47,24 @@
#include <qdir.h>
#include <qpixmapcache.h>
#if defined(Q_WS_WIN)
-#define _WIN32_IE 0x0500
-#include <qt_windows.h>
-#include <commctrl.h>
-#include <objbase.h>
+# define _WIN32_IE 0x0500
+# include <qt_windows.h>
+# include <commctrl.h>
+# include <objbase.h>
#elif defined(Q_WS_MAC)
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
-#if defined(Q_WS_X11) && !defined(Q_NO_STYLE_GTK)
-#include <private/qt_x11_p.h>
-#include <private/gtksymbols_p.h>
+# include <private/qt_cocoa_helpers_mac_p.h>
#endif
#include <private/qfunctions_p.h>
#include <private/qguiplatformplugin_p.h>
+#if defined(Q_WS_X11) && !defined(Q_NO_STYLE_GTK)
+# include <private/qgtkstyle_p.h>
+# include <private/qt_x11_p.h>
+#endif
+
#ifndef SHGFI_ADDOVERLAYS
-#define SHGFI_ADDOVERLAYS 0x000000020
+# define SHGFI_ADDOVERLAYS 0x000000020
#endif
QT_BEGIN_NAMESPACE
@@ -392,7 +392,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const
#if defined(Q_WS_X11) && !defined(QT_NO_STYLE_GTK)
if (X11->desktopEnvironment == DE_GNOME) {
- QIcon gtkIcon = QGtk::getFilesystemIcon(info);
+ QIcon gtkIcon = QGtkStylePrivate::getFilesystemIcon(info);
if (!gtkIcon.isNull())
return gtkIcon;
}
diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp
index fc9820f7df..6f2cff976c 100644
--- a/src/gui/itemviews/qheaderview.cpp
+++ b/src/gui/itemviews/qheaderview.cpp
@@ -1419,7 +1419,7 @@ int QHeaderView::minimumSectionSize() const
int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
if (d->orientation == Qt::Horizontal)
return qMax(strut.width(), (fontMetrics().maxWidth() + margin));
- return qMax(strut.height(), (fontMetrics().lineSpacing() + margin));
+ return qMax(strut.height(), (fontMetrics().height() + margin));
}
return d->minimumSectionSize;
}
@@ -2516,6 +2516,8 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const
Q_D(const QHeaderView);
Q_ASSERT(logicalIndex >= 0);
+ ensurePolished();
+
// use SizeHintRole
QVariant variant = d->model->headerData(logicalIndex, d->orientation, Qt::SizeHintRole);
if (variant.isValid())
diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp
index 871a4b137f..3e00dba9f1 100644
--- a/src/gui/itemviews/qitemdelegate.cpp
+++ b/src/gui/itemviews/qitemdelegate.cpp
@@ -255,7 +255,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
\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 and QColor
+ \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
@@ -1059,7 +1059,7 @@ QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette,
painter.end();
QPixmap selected = QPixmap(QPixmap::fromImage(img));
- int n = (img.numBytes() >> 10) + 1;
+ int n = (img.byteCount() >> 10) + 1;
if (QPixmapCache::cacheLimit() < n)
QPixmapCache::setCacheLimit(n);
diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp
index dfebe0328f..2e4a6021d1 100644
--- a/src/gui/itemviews/qitemselectionmodel.cpp
+++ b/src/gui/itemviews/qitemselectionmodel.cpp
@@ -599,7 +599,7 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
while (itParent.isValid() && itParent.parent() != parent)
itParent = itParent.parent();
- if (parent.isValid() && start <= itParent.row() && itParent.row() <= end) {
+ if (itParent.isValid() && start <= itParent.row() && itParent.row() <= end) {
deselected.append(*it);
it = ranges.erase(it);
} else {
@@ -730,13 +730,14 @@ void QItemSelectionModelPrivate::_q_layoutAboutToBeChanged()
savedPersistentIndexes.clear();
savedPersistentCurrentIndexes.clear();
- // special case for when all indexes are selected
+ // optimisation for when all indexes are selected
+ // (only if there is lots of items (1000) because this is not entirely correct)
if (ranges.isEmpty() && currentSelection.count() == 1) {
QItemSelectionRange range = currentSelection.first();
QModelIndex parent = range.parent();
tableRowCount = model->rowCount(parent);
tableColCount = model->columnCount(parent);
- if (tableRowCount * tableColCount > 100
+ if (tableRowCount * tableColCount > 1000
&& range.top() == 0
&& range.left() == 0
&& range.bottom() == tableRowCount - 1
@@ -1587,7 +1588,8 @@ void QItemSelectionModel::emitSelectionChanged(const QItemSelection &newSelectio
}
}
- emit selectionChanged(selected, deselected);
+ if (!selected.isEmpty() || !deselected.isEmpty())
+ emit selectionChanged(selected, deselected);
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 9b0b00f3ed..c6622cbf6e 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -357,7 +357,7 @@ QListView::LayoutMode QListView::layoutMode() const
/*!
\property QListView::spacing
- \brief the space between items in the layout
+ \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.
@@ -853,8 +853,13 @@ void QListView::resizeEvent(QResizeEvent *e)
*/
void QListView::dragMoveEvent(QDragMoveEvent *e)
{
- if (!d_func()->commonListView->filterDragMoveEvent(e))
- QAbstractItemView::dragMoveEvent(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);
+ }
}
@@ -967,9 +972,9 @@ void QListView::paintEvent(QPaintEvent *e)
option.rect = visualRect(*it);
if (flow() == TopToBottom)
- option.rect.setWidth(qMin(viewport()->size().width(), option.rect.width()));
+ option.rect.setWidth(qMin(d->contentsSize().width() - 2 * d->spacing(), option.rect.width()));
else
- option.rect.setHeight(qMin(viewport()->size().height(), option.rect.height()));
+ option.rect.setHeight(qMin(d->contentsSize().height() - 2 * d->spacing(), option.rect.height()));
option.state = state;
if (selections && selections->isSelected(*it))
@@ -1105,13 +1110,13 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
++row;
if (row >= rowCount)
return QModelIndex();
- return d->model->index(row, 0, d->root);
+ 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, 0, d->root);
+ return d->model->index(0, d->column, d->root);
}
if (d->gridSize().isValid()) rect.setSize(d->gridSize());
@@ -1804,6 +1809,16 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const
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);
+}
+#endif
+
/*
* Common ListView Implementation
*/
@@ -1822,14 +1837,14 @@ void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
{
horizontalScrollBar()->setSingleStep(step.width() + spacing());
horizontalScrollBar()->setPageStep(viewport()->width());
- horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width());
+ horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width() - 2 * spacing());
}
void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
{
verticalScrollBar()->setSingleStep(step.height() + spacing());
verticalScrollBar()->setPageStep(viewport()->height());
- verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height());
+ verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height() - 2 * spacing());
}
void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
@@ -1893,6 +1908,96 @@ void QListModeViewBase::paintDragDrop(QPainter *painter)
// 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();
+
+ QModelIndex index = qq->indexAt(event->pos());
+ 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);
+ switch (dd->dropIndicatorPosition) {
+ case QAbstractItemView::AboveItem:
+ if (dd->isIndexDropEnabled(index.parent())) {
+ dd->dropIndicatorRect = QRect(rect.left(), 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(), 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();
+}
+
#endif //QT_NO_DRAGANDDROP
void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
@@ -1900,7 +2005,7 @@ void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
&& ((flow() == QListView::TopToBottom && !isWrapping())
|| (flow() == QListView::LeftToRight && isWrapping()))) {
- const int steps = (flow() == QListView::TopToBottom ? flowPositions : segmentPositions).count() - 1;
+ 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);
@@ -1921,7 +2026,7 @@ void QListModeViewBase::updateHorizontalScrollBar(const QSize &step)
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem
&& ((flow() == QListView::TopToBottom && isWrapping())
|| (flow() == QListView::LeftToRight && !isWrapping()))) {
- int steps = (flow() == QListView::TopToBottom ? segmentPositions : flowPositions).count() - 1;
+ int steps = (flow() == QListView::TopToBottom ? segmentPositions : scrollValueMap).count() - 1;
if (steps > 0) {
const int pageSteps = perItemScrollingPageSteps(viewport()->width(), contentsSize.width(), isWrapping());
horizontalScrollBar()->setSingleStep(1);
@@ -1939,7 +2044,11 @@ int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hi
bool above, bool below, const QRect &area, const QRect &rect) const
{
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int value = qBound(0, verticalScrollBar()->value(), flowPositions.count() - 1);
+ 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)
@@ -1966,8 +2075,8 @@ int QListModeViewBase::horizontalOffset() const
return (isRightToLeft() ? maximum - position : position);
}
} else if (flow() == QListView::LeftToRight && !flowPositions.isEmpty()) {
- int position = flowPositions.at(horizontalScrollBar()->value());
- int maximum = flowPositions.at(horizontalScrollBar()->maximum());
+ int position = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->value()));
+ int maximum = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->maximum()));
return (isRightToLeft() ? maximum - position : position);
}
}
@@ -1986,9 +2095,9 @@ int QListModeViewBase::verticalOffset() const
}
} else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
int value = verticalScrollBar()->value();
- if (value > flowPositions.count())
+ if (value > scrollValueMap.count())
return 0;
- return flowPositions.at(value) - spacing();
+ return flowPositions.at(scrollValueMap.at(value)) - spacing();
}
}
return QCommonListViewBase::verticalOffset();
@@ -2000,7 +2109,11 @@ int QListModeViewBase::horizontalScrollToValue(int index, QListView::ScrollHint
if (horizontalScrollMode() != QAbstractItemView::ScrollPerItem)
return QCommonListViewBase::horizontalScrollToValue(index, hint, leftOf, rightOf, area, rect);
- int value = qBound(0, horizontalScrollBar()->value(), flowPositions.count() - 1);
+ 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)
@@ -2043,14 +2156,14 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
if (vertical && flow() == QListView::TopToBottom && dy != 0) {
int currentValue = qBound(0, verticalValue, max);
int previousValue = qBound(0, currentValue + dy, max);
- int currentCoordinate = flowPositions.at(currentValue);
- int previousCoordinate = flowPositions.at(previousValue);
+ 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(currentValue);
- int previousCoordinate = flowPositions.at(previousValue);
+ int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
+ int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
dx = previousCoordinate - currentCoordinate;
}
}
@@ -2113,6 +2226,7 @@ QPoint QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info)
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);
@@ -2204,6 +2318,7 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
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);
@@ -2229,6 +2344,7 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
// 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);
}
@@ -2287,6 +2403,12 @@ QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
return ret;
}
+void QListModeViewBase::dataChanged(const QModelIndex &, const QModelIndex &)
+{
+ dd->doDelayedItemsLayout();
+}
+
+
QRect QListModeViewBase::mapToViewport(const QRect &rect) const
{
if (isWrapping())
@@ -2306,7 +2428,14 @@ QRect QListModeViewBase::mapToViewport(const QRect &rect) const
int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
{
- const QVector<int> positions = (wrap ? segmentPositions : flowPositions);
+ 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()) {
@@ -2490,7 +2619,7 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
for (int i = 0; i < indexes.count(); ++i) {
QModelIndex index = indexes.at(i);
QRect rect = dd->rectForIndex(index);
- viewport()->update(mapToViewport(rect));
+ viewport()->update(dd->mapToViewport(rect, false));
QPoint dest = rect.topLeft() + delta;
if (qq->isRightToLeft())
dest.setX(dd->flipX(dest.x()) - rect.width());
diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h
index b6785da4eb..31459b07e4 100644
--- a/src/gui/itemviews/qlistview_p.h
+++ b/src/gui/itemviews/qlistview_p.h
@@ -130,6 +130,7 @@ public:
virtual void clear() = 0;
virtual void setRowCount(int) = 0;
virtual QVector<QModelIndex> intersectingSet(const QRect &area) const = 0;
+ virtual void dataChanged(const QModelIndex &, const QModelIndex &) = 0;
virtual int horizontalScrollToValue(int index, QListView::ScrollHint hint,
bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const;
@@ -141,7 +142,6 @@ public:
virtual int verticalOffset() const { return verticalScrollBar()->value(); }
virtual void updateHorizontalScrollBar(const QSize &step);
virtual void updateVerticalScrollBar(const QSize &step);
- virtual void dataChanged(const QModelIndex &, const QModelIndex &) { }
virtual void appendHiddenRow(int row);
virtual void removeHiddenRow(int row);
virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { }
@@ -205,6 +205,7 @@ public:
QVector<int> segmentPositions;
QVector<int> segmentStartRows;
QVector<int> segmentExtents;
+ QVector<int> scrollValueMap;
// used when laying out in batches
int batchSavedPosition;
@@ -216,6 +217,7 @@ public:
void clear();
void setRowCount(int rowCount) { flowPositions.resize(rowCount); }
QVector<QModelIndex> intersectingSet(const QRect &area) const;
+ void dataChanged(const QModelIndex &, const QModelIndex &);
int horizontalScrollToValue(int index, QListView::ScrollHint hint,
bool leftOf, bool rightOf,const QRect &area, const QRect &rect) const;
@@ -230,6 +232,11 @@ public:
#ifndef QT_NO_DRAGANDDROP
void paintDragDrop(QPainter *painter);
+
+ // The next two methods are to be used on LefToRight flow only.
+ // WARNING: Plenty of duplicated code from QAbstractItemView{,Private}.
+ QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
+ void dragMoveEvent(QDragMoveEvent *e);
#endif
private:
@@ -355,6 +362,10 @@ public:
QItemSelection selection(const QRect &rect) const;
void selectAll(QItemSelectionModel::SelectionFlags command);
+#ifndef QT_NO_DRAGANDDROP
+ virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
+#endif
+
inline void setGridSize(const QSize &size) { grid = size; }
inline QSize gridSize() const { return grid; }
inline void setWrapping(bool b) { wrap = b; }
diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp
index a978d0f048..5dd1d76bb3 100644
--- a/src/gui/itemviews/qlistwidget.cpp
+++ b/src/gui/itemviews/qlistwidget.cpp
@@ -169,6 +169,20 @@ QListWidgetItem *QListModel::take(int row)
return item;
}
+void QListModel::move(int srcRow, int dstRow)
+{
+ if (srcRow == dstRow
+ || srcRow < 0 || srcRow >= items.count()
+ || dstRow < 0 || dstRow >= items.count())
+ return;
+
+ beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow);
+ if (srcRow < dstRow)
+ --dstRow;
+ items.move(srcRow, dstRow);
+ endMoveRows();
+}
+
int QListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : items.count();
@@ -1804,22 +1818,15 @@ void QListWidget::dropEvent(QDropEvent *event) {
if (persIndexes.contains(topIndex))
return;
+ qSort(persIndexes); // The dropped items will remain in the same visual order.
QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
- QList<QListWidgetItem *> taken;
- for (int i = 0; i < persIndexes.count(); ++i)
- taken.append(takeItem(persIndexes.at(i).row()));
-
- // insert them back in at their new positions
+ int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row);
for (int i = 0; i < persIndexes.count(); ++i) {
- // Either at a specific point or appended
- if (row == -1) {
- insertItem(count(), taken.takeFirst());
- } else {
- int r = dropRow.row() >= 0 ? dropRow.row() : row;
- insertItem(qMin(r, count()), taken.takeFirst());
- }
+ const QPersistentModelIndex &pIndex = persIndexes.at(i);
+ d->listModel()->move(pIndex.row(), r);
+ r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order.
}
event->accept();
diff --git a/src/gui/itemviews/qlistwidget_p.h b/src/gui/itemviews/qlistwidget_p.h
index 69cfa26864..b5f28e33df 100644
--- a/src/gui/itemviews/qlistwidget_p.h
+++ b/src/gui/itemviews/qlistwidget_p.h
@@ -77,7 +77,7 @@ public:
{ return *i2 < *i1; }
};
-class QListModel : public QAbstractListModel
+class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel
{
Q_OBJECT
public:
@@ -90,6 +90,7 @@ public:
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;
diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp
index 1c3678799d..1ca03915f3 100644
--- a/src/gui/itemviews/qstyleditemdelegate.cpp
+++ b/src/gui/itemviews/qstyleditemdelegate.cpp
@@ -148,7 +148,7 @@ public:
\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 and QColor
+ \row \o \l Qt::DecorationRole \o QIcon, QPixmap, QImage 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
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 2d98258894..02e5fffc6d 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -117,7 +117,7 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height)
Index::iterator it_y = index.lowerBound(-span->bottom());
Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
while (-it_y.key() <= span->top() + old_height -1) {
- if(-it_y.key() != span->bottom()) {
+ if (-it_y.key() > span->bottom()) {
(*it_y).remove(-span->left());
if (it_y->isEmpty()) {
it_y = index.erase(it_y) - 1;
@@ -544,6 +544,47 @@ void QSpanCollection::updateRemovedColumns(int start, int end)
qDeleteAll(toBeDeleted);
}
+#ifdef QT_BUILD_INTERNAL
+/*!
+ \internal
+ Checks whether the span index structure is self-consistent, and consistent with the spans list.
+*/
+bool QSpanCollection::checkConsistency() const
+{
+ for (Index::const_iterator it_y = index.begin(); it_y != index.end(); ++it_y) {
+ int y = -it_y.key();
+ const SubIndex &subIndex = it_y.value();
+ for (SubIndex::const_iterator it = subIndex.begin(); it != subIndex.end(); ++it) {
+ int x = -it.key();
+ Span *span = it.value();
+ if (!spans.contains(span) || span->left() != x
+ || y < span->top() || y > span->bottom())
+ return false;
+ }
+ }
+
+ foreach (const Span *span, spans) {
+ if (span->width() < 1 || span->height() < 1
+ || (span->width() == 1 && span->height() == 1))
+ return false;
+ for (int y = span->top(); y <= span->bottom(); ++y) {
+ Index::const_iterator it_y = index.find(-y);
+ if (it_y == index.end()) {
+ if (y == span->top())
+ return false;
+ else
+ continue;
+ }
+ const SubIndex &subIndex = it_y.value();
+ SubIndex::const_iterator it = subIndex.find(-span->left());
+ if (it == subIndex.end() || it.value() != span)
+ return false;
+ }
+ }
+ return true;
+}
+#endif
+
class QTableCornerButton : public QAbstractButton
{
Q_OBJECT
@@ -1117,6 +1158,9 @@ void QTableView::setHorizontalHeader(QHeaderView *header)
connect(d->horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)),
this, SLOT(resizeColumnToContents(int)));
connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
+
+ //update the sorting enabled states on the new header
+ setSortingEnabled(d->sortingEnabled);
}
/*!
@@ -1596,7 +1640,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
break;
visualColumn = right + 1;
if (visualRow == 0) {
- wrapped == true;
+ wrapped = true;
visualRow = bottom;
} else {
--visualRow;
@@ -2062,6 +2106,8 @@ int QTableView::sizeHintForRow(int row) const
if (!model())
return -1;
+ ensurePolished();
+
int left = qMax(0, columnAt(0));
int right = columnAt(d->viewport->width());
if (right == -1) // the table don't have enough columns to fill the viewport
@@ -2119,6 +2165,8 @@ int QTableView::sizeHintForColumn(int column) const
if (!model())
return -1;
+ ensurePolished();
+
int top = qMax(0, rowAt(0));
int bottom = rowAt(d->viewport->height());
if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport
diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h
index 9fa14c2612..6b19ded585 100644
--- a/src/gui/itemviews/qtableview_p.h
+++ b/src/gui/itemviews/qtableview_p.h
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
* The key of the first map is the row where the subspan starts, the value of the first map is
* a list (map) of all subspans that starts at the same row. It is indexed with its row
*/
-class QSpanCollection
+class Q_AUTOTEST_EXPORT QSpanCollection
{
public:
struct Span
@@ -112,6 +112,10 @@ public:
void updateRemovedRows(int start, int end);
void updateRemovedColumns(int start, int end);
+#ifdef QT_BUILD_INTERNAL
+ bool checkConsistency() const;
+#endif
+
typedef QLinkedList<Span *> SpanList;
SpanList spans; //lists of all spans
private:
diff --git a/src/gui/itemviews/qtablewidget.cpp b/src/gui/itemviews/qtablewidget.cpp
index a0864984f0..d9b834647c 100644
--- a/src/gui/itemviews/qtablewidget.cpp
+++ b/src/gui/itemviews/qtablewidget.cpp
@@ -571,6 +571,8 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
colItems.remove(oldRow);
vit = sortedInsertionIterator(vit, colItems.end(), order, item);
int newRow = qMax((int)(vit - colItems.begin()), 0);
+ if ((newRow < oldRow) && !(*item < *colItems.at(oldRow - 1)) && !(*colItems.at(oldRow - 1) < *item))
+ newRow = oldRow;
vit = colItems.insert(vit, item);
if (newRow != oldRow) {
changed = true;
@@ -2456,7 +2458,7 @@ const QTableWidgetItem *QTableWidget::itemPrototype() const
The table widget will use the item prototype clone function when it needs
to create a new table item. For example when the user is editing
- editing in an empty cell. This is useful when you have a QTableWidgetItem
+ in an empty cell. This is useful when you have a QTableWidgetItem
subclass and want to make sure that QTableWidget creates instances of
your subclass.
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 210534e916..a3cbc0d337 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -1226,8 +1226,12 @@ bool QTreeView::viewportEvent(QEvent *event)
if (oldIndex != newIndex) {
QRect oldRect = visualRect(oldIndex);
QRect newRect = visualRect(newIndex);
- viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height());
- viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height());
+ oldRect.setLeft(oldRect.left() - d->indent);
+ newRect.setLeft(newRect.left() - d->indent);
+ //we need to paint the whole items (including the decoration) so that when the user
+ //moves the mouse over those elements they are updated
+ viewport()->update(oldRect);
+ viewport()->update(newRect);
}
}
if (selectionBehavior() == QAbstractItemView::SelectRows) {
@@ -1422,8 +1426,9 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
for (; i < viewItems.count() && y <= area.bottom(); ++i) {
const int itemHeight = d->itemHeight(i);
option.rect.setRect(0, y, viewportWidth, itemHeight);
- option.state = state | (viewItems.at(i).expanded
- ? QStyle::State_Open : QStyle::State_None);
+ option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)
+ | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None)
+ | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);
d->current = i;
d->spanning = viewItems.at(i).spanning;
if (!multipleRects || !drawn.contains(i)) {
@@ -1748,14 +1753,8 @@ void QTreeView::drawBranches(QPainter *painter, const QRect &rect,
opt.rect = primitive;
const bool expanded = viewItem.expanded;
- const bool children = (((expanded && viewItem.total > 0)) // already laid out and has children
- || d->hasVisibleChildren(index)); // not laid out yet, so we don't know
- bool moreSiblings = false;
- if (d->hiddenIndexes.isEmpty())
- moreSiblings = (d->model->rowCount(parent) - 1 > index.row());
- else
- moreSiblings = ((d->viewItems.size() > item +1)
- && (d->viewItems.at(item + 1).index.parent() == parent));
+ const bool children = viewItem.hasChildren;
+ bool moreSiblings = viewItem.hasMoreSiblings;
opt.state = QStyle::State_Item | extraFlags
| (moreSiblings ? QStyle::State_Sibling : QStyle::State_None)
@@ -1845,9 +1844,7 @@ void QTreeView::mouseDoubleClickEvent(QMouseEvent *event)
return; // user clicked outside the items
const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index;
-
- int column = d->header->logicalIndexAt(event->x());
- QPersistentModelIndex persistent = firstColumnIndex.sibling(firstColumnIndex.row(), column);
+ const QPersistentModelIndex persistent = indexAt(event->pos());
if (d->pressedIndex != persistent) {
mousePressEvent(event);
@@ -2116,6 +2113,12 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
if (vi < 0)
vi = qMax(0, d->viewIndex(current));
+ if (isRightToLeft()) {
+ if (cursorAction == MoveRight)
+ cursorAction = MoveLeft;
+ else if (cursorAction == MoveLeft)
+ cursorAction = MoveRight;
+ }
switch (cursorAction) {
case MoveNext:
case MoveDown:
@@ -2437,7 +2440,9 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
return;
}
- if (parent != d->root && !d->isIndexExpanded(parent) && d->model->rowCount(parent) > (end - start) + 1) {
+ const int parentRowCount = d->model->rowCount(parent);
+ const int delta = end - start + 1;
+ if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) {
QAbstractItemView::rowsInserted(parent, start, end);
return;
}
@@ -2452,11 +2457,29 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
? d->viewItems.count()
: d->viewItems.at(parentItem).total) - 1;
- const int delta = end - start + 1;
+ if (parentRowCount == end + 1 && start > 0) {
+ //need to Update hasMoreSiblings
+ int previousRow = start - 1;
+ QModelIndex previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
+ bool isHidden = d->isRowHidden(previousSibilingModelIndex);
+ while (isHidden && previousRow > 0) {
+ previousRow--;
+ previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
+ isHidden = d->isRowHidden(previousSibilingModelIndex);
+ }
+ if (!isHidden) {
+ const int previousSibilling = d->viewIndex(previousSibilingModelIndex);
+ if(previousSibilling != -1)
+ d->viewItems[previousSibilling].hasMoreSiblings = true;
+ }
+ }
+
QVector<QTreeViewItem> insertedItems(delta);
for (int i = 0; i < delta; ++i) {
insertedItems[i].index = d->model->index(i + start, 0, parent);
insertedItems[i].level = childLevel;
+ insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index);
+ insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1));
}
if (d->viewItems.isEmpty())
d->defaultItemHeight = indexRowSizeHint(insertedItems[0].index);
@@ -2498,13 +2521,17 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
d->viewItems.begin() + insertPos + 1);
}
+ if (parentItem != -1)
+ d->viewItems[parentItem].hasChildren = true;
d->updateChildCount(parentItem, delta);
+
updateGeometries();
viewport()->update();
} else if ((parentItem != -1) && d->viewItems.at(parentItem).expanded) {
d->doDelayedItemsLayout();
} else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) {
- // the parent just went from 0 children to having some update to re-paint the decoration
+ // the parent just went from 0 children to more. update to re-paint the decoration
+ d->viewItems[parentItem].hasChildren = true;
viewport()->update();
}
QAbstractItemView::rowsInserted(parent, start, end);
@@ -2908,6 +2935,8 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
layout(item);
q->setState(oldState);
+ if (model->canFetchMore(index))
+ model->fetchMore(index);
if (emitSignal) {
emit q->expanded(index);
#ifndef QT_NO_ANIMATION
@@ -2915,8 +2944,6 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
beginAnimatedOperation();
#endif //QT_NO_ANIMATION
}
- if (model->canFetchMore(index))
- model->fetchMore(index);
}
void QTreeViewPrivate::collapse(int item, bool emitSignal)
@@ -3005,10 +3032,12 @@ void QTreeViewPrivate::beginAnimatedOperation()
animatedOperation.setEndValue(animatedOperation.top() + h);
}
- animatedOperation.after = renderTreeToPixmapForAnimation(rect);
+ if (!rect.isEmpty()) {
+ animatedOperation.after = renderTreeToPixmapForAnimation(rect);
- q->setState(QAbstractItemView::AnimatingState);
- animatedOperation.start(); //let's start the animation
+ q->setState(QAbstractItemView::AnimatingState);
+ animatedOperation.start(); //let's start the animation
+ }
}
void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const
@@ -3125,7 +3154,7 @@ void QTreeViewPrivate::layout(int i)
int hidden = 0;
int last = 0;
int children = 0;
-
+ QTreeViewItem *item = 0;
for (int j = first; j < first + count; ++j) {
current = model->index(j - first, 0, parent);
if (isRowHidden(current)) {
@@ -3133,17 +3162,25 @@ void QTreeViewPrivate::layout(int i)
last = j - hidden + children;
} else {
last = j - hidden + children;
- viewItems[last].index = current;
- viewItems[last].level = level;
- viewItems[last].height = 0;
- viewItems[last].spanning = q->isFirstColumnSpanned(current.row(), parent);
- viewItems[last].expanded = false;
- viewItems[last].total = 0;
+ if (item)
+ item->hasMoreSiblings = true;
+ item = &viewItems[last];
+ item->index = current;
+ item->level = level;
+ item->height = 0;
+ item->spanning = q->isFirstColumnSpanned(current.row(), parent);
+ item->expanded = false;
+ item->total = 0;
+ item->hasMoreSiblings = false;
if (isIndexExpanded(current)) {
- viewItems[last].expanded = true;
+ item->expanded = true;
layout(last);
- children += viewItems[last].total;
+ item = &viewItems[last];
+ children += item->total;
+ item->hasChildren = item->total > 0;
last = j - hidden + children;
+ } else {
+ item->hasChildren = hasVisibleChildren(current);
}
}
}
@@ -3699,6 +3736,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent,
const int delta = end - start + 1;
+ int previousSibiling = -1;
int removedCount = 0;
for (int item = firstChildItem; item <= lastChildItem; ) {
Q_ASSERT(viewItems.at(item).level == childLevel);
@@ -3706,6 +3744,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent,
//Q_ASSERT(modelIndex.parent() == parent);
const int count = viewItems.at(item).total + 1;
if (modelIndex.row() < start) {
+ previousSibiling = item;
// not affected by the removal
item += count;
} else if (modelIndex.row() <= end) {
@@ -3723,7 +3762,13 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent,
}
}
+ if (previousSibiling != -1 && after && model->rowCount(parent) == start)
+ viewItems[previousSibiling].hasMoreSiblings = false;
+
+
updateChildCount(parentItem, -removedCount);
+ if (parentItem != -1 && viewItems.at(parentItem).total == 0)
+ viewItems[parentItem].hasChildren = false; //every children have been removed;
if (after) {
q->updateGeometries();
viewport->update();
diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h
index def82538ec..d58dea34c2 100644
--- a/src/gui/itemviews/qtreeview_p.h
+++ b/src/gui/itemviews/qtreeview_p.h
@@ -62,11 +62,14 @@ QT_BEGIN_NAMESPACE
struct QTreeViewItem
{
- QTreeViewItem() : expanded(false), spanning(false), total(0), level(0), height(0) {}
+ QTreeViewItem() : expanded(false), spanning(false), hasChildren(false),
+ hasMoreSiblings(false), total(0), level(0), height(0) {}
QModelIndex index; // we remove items whenever the indexes are invalidated
uint expanded : 1;
uint spanning : 1;
- uint total : 30; // total number of children visible
+ 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
};
@@ -102,7 +105,7 @@ public:
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(); }
+ void updateState(State state, State) { if (state == Stopped) before = after = QPixmap(); }
} animatedOperation;
void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
void beginAnimatedOperation();
diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp
index 06342d8e4b..c133ae4865 100644
--- a/src/gui/itemviews/qtreewidget.cpp
+++ b/src/gui/itemviews/qtreewidget.cpp
@@ -623,7 +623,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
lit = sortedInsertionIterator(lit, lst.end(), order, item);
int newRow = qMax(lit - lst.begin(), 0);
- if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1)))
+ if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1)) && !(*lst.at(oldRow - 1) < *item ))
newRow = oldRow;
lit = lst.insert(lit, item);
@@ -2851,7 +2851,14 @@ QTreeWidgetItem *QTreeWidget::itemAt(const QPoint &p) const
QRect QTreeWidget::visualItemRect(const QTreeWidgetItem *item) const
{
Q_D(const QTreeWidget);
- return visualRect(d->index(item));
+ //the visual rect for an item is across all columns. So we need to determine
+ //what is the first and last column and get their visual index rects
+ QModelIndex base = d->index(item);
+ const int firstVisiblesection = header()->logicalIndexAt(- header()->offset());
+ const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1);
+ QModelIndex first = base.sibling(base.row(), header()->logicalIndex(firstVisiblesection));
+ QModelIndex last = base.sibling(base.row(), header()->logicalIndex(lastVisibleSection));
+ return visualRect(first) | visualRect(last);
}
/*!
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index af7c55f418..73dfd52d2f 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -84,6 +84,7 @@ SOURCES += \
kernel/qgesturerecognizer.cpp \
kernel/qgesturemanager.cpp \
kernel/qsoftkeymanager.cpp \
+ kernel/qdesktopwidget.cpp \
kernel/qguiplatformplugin.cpp
win32 {
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index 6a6e549cb2..3eaf2e1ce1 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -100,6 +100,21 @@ QActionPrivate::~QActionPrivate()
{
}
+bool QActionPrivate::showStatusText(QWidget *widget, const QString &str)
+{
+#ifdef QT_NO_STATUSTIP
+ Q_UNUSED(widget);
+ Q_UNUSED(str);
+#else
+ if(QObject *object = widget ? widget : parent) {
+ QStatusTipEvent tip(str);
+ QApplication::sendEvent(object, &tip);
+ return true;
+ }
+#endif
+ return false;
+}
+
void QActionPrivate::sendDataChanged()
{
Q_Q(QAction);
@@ -276,7 +291,7 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map)
This enum describes how an action should be placed in the softkey bar. Currently this enum only
has an effect on the Symbian platform.
- \value NoSoftKey This action should be used as a softkey
+ \value NoSoftKey This action should not be used as a softkey
\value PositiveSoftKey This action is used to describe a softkey with a positive or non-destructive
role such as Ok, Select, or Options.
\value NegativeSoftKey This action is used to describe a soft ey with a negative or destructive role
@@ -286,7 +301,7 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map)
Actions with a softkey role defined are only visible in the softkey bar when the widget containing
the action has focus. If no widget currently has focus, the softkey framework will traverse up the
- widget parent heirarchy looking for a widget containing softkey actions.
+ widget parent hierarchy looking for a widget containing softkey actions.
*/
/*!
@@ -1206,16 +1221,7 @@ QAction::setData(const QVariant &data)
bool
QAction::showStatusText(QWidget *widget)
{
-#ifdef QT_NO_STATUSTIP
- Q_UNUSED(widget);
-#else
- if(QObject *object = widget ? widget : parent()) {
- QStatusTipEvent tip(statusTip());
- QApplication::sendEvent(object, &tip);
- return true;
- }
-#endif
- return false;
+ return d_func()->showStatusText(widget, statusTip());
}
/*!
diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h
index 2527a02a13..f7b035b1f8 100644
--- a/src/gui/kernel/qaction_p.h
+++ b/src/gui/kernel/qaction_p.h
@@ -75,6 +75,8 @@ public:
QActionPrivate();
~QActionPrivate();
+ bool showStatusText(QWidget *w, const QString &str);
+
QPointer<QActionGroup> group;
QString text;
QString iconText;
diff --git a/src/gui/kernel/qactiongroup.cpp b/src/gui/kernel/qactiongroup.cpp
index 40d18a2c92..8db76e4585 100644
--- a/src/gui/kernel/qactiongroup.cpp
+++ b/src/gui/kernel/qactiongroup.cpp
@@ -72,10 +72,16 @@ void QActionGroupPrivate::_q_actionChanged()
Q_Q(QActionGroup);
QAction *action = qobject_cast<QAction*>(q->sender());
Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionChanged", "internal error");
- if(exclusive && action->isChecked() && action != current) {
- if(current)
- current->setChecked(false);
- current = action;
+ if(exclusive) {
+ if (action->isChecked()) {
+ if (action != current) {
+ if(current)
+ current->setChecked(false);
+ current = action;
+ }
+ } else if (action == current) {
+ current = 0;
+ }
}
}
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index c36dc444f2..bbf7b4095e 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -68,9 +68,6 @@
#include "private/qstylesheetstyle_p.h"
#include "private/qstyle_p.h"
#include "qmessagebox.h"
-#include "qlineedit.h"
-#include "qlistview.h"
-#include "qtextedit.h"
#include <QtGui/qgraphicsproxywidget.h>
#include "qinputcontext.h"
@@ -157,14 +154,6 @@ bool QApplicationPrivate::autoSipEnabled = false;
bool QApplicationPrivate::autoSipEnabled = true;
#endif
-QGestureManager* QGestureManager::instance()
-{
- QApplicationPrivate *d = qApp->d_func();
- if (!d->gestureManager)
- d->gestureManager = new QGestureManager(qApp);
- return d->gestureManager;
-}
-
QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type)
: QCoreApplicationPrivate(argc, argv)
{
@@ -188,7 +177,7 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T
directPainters = 0;
#endif
- gestureManager = 0;
+ gestureWidget = 0;
if (!self)
self = this;
@@ -477,9 +466,6 @@ bool QApplicationPrivate::fade_tooltip = false;
bool QApplicationPrivate::animate_toolbox = false;
bool QApplicationPrivate::widgetCount = false;
bool QApplicationPrivate::load_testability = false;
-#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
-bool QApplicationPrivate::inSizeMove = false;
-#endif
#ifdef QT_KEYPAD_NAVIGATION
# ifdef Q_OS_SYMBIAN
Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
@@ -807,7 +793,8 @@ void QApplicationPrivate::construct(
}
//make sure the plugin is loaded
- qt_guiPlatformPlugin();
+ if (qt_is_gui_used)
+ qt_guiPlatformPlugin();
#endif
}
@@ -945,12 +932,8 @@ void QApplicationPrivate::initialize()
graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
#endif
#ifndef QT_NO_WHEELEVENT
-#ifdef Q_OS_MAC
- QApplicationPrivate::wheel_scroll_lines = 1;
-#else
QApplicationPrivate::wheel_scroll_lines = 3;
#endif
-#endif
initializeMultitouch();
}
@@ -2090,7 +2073,7 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
}
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
@@ -2103,6 +2086,7 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
qic->setFocusWidget(0);
}
}
+#endif //QT_NO_IM
if(focus_widget)
focus_widget->d_func()->setFocus_sys();
@@ -2134,12 +2118,14 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
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);
@@ -2500,9 +2486,12 @@ void QApplication::setActiveWindow(QWidget* act)
/*!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;
@@ -2510,22 +2499,11 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
QWidget *w = f;
QWidget *test = f->d_func()->focus_next;
while (test && test != f) {
- if ((test->focusPolicy() & Qt::TabFocus)
+ 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))
- && (qt_tab_all_widgets
-#ifndef QT_NO_LINEEDIT
- || qobject_cast<QLineEdit*>(test)
-#endif
-#ifndef QT_NO_TEXTEDIT
- || qobject_cast<QTextEdit*>(test)
-#endif
-#ifndef QT_NO_ITEMVIEWS
- || qobject_cast<QListView*>(test)
-#endif
- )) {
+ && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
w = test;
if (next)
break;
@@ -2664,7 +2642,10 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
if (!isAlien(w))
break;
if (w->testAttribute(Qt::WA_SetCursor)) {
- parentOfLeavingCursor = w->parentWidget();
+ 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)
}
@@ -3654,9 +3635,14 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
}
// walk through parents and check for gestures
- if (d->gestureManager) {
- if (d->gestureManager->filterEvent(receiver, e))
- return true;
+ if (qt_gestureManager) {
+ if (receiver->isWidgetType()) {
+ if (qt_gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+ return true;
+ } else if (QGesture *gesture = qobject_cast<QGesture *>(receiver)) {
+ if (qt_gestureManager->filterEvent(gesture, e))
+ return true;
+ }
}
@@ -4167,7 +4153,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
if (receiver->isWidgetType()) {
QWidget *w = static_cast<QWidget *>(receiver);
QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
- QList<QGesture *> allGestures = gestureEvent->allGestures();
+ QList<QGesture *> allGestures = gestureEvent->gestures();
bool eventAccepted = gestureEvent->isAccepted();
bool wasAccepted = eventAccepted;
@@ -4178,43 +4164,49 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
for (int i = 0; i < allGestures.size();) {
QGesture *g = allGestures.at(i);
Qt::GestureType type = g->gestureType();
- if (wd->gestureContext.contains(type)) {
+ 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);
- gestureEvent->setAccepted(g, false);
} else {
++i;
}
}
- if (!gestures.isEmpty()) {
+ 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();
- if (res && eventAccepted)
- break;
- if (!eventAccepted) {
- // ### two ways to ignore the event/gesture
-
- // if the whole event wasn't accepted, put back those
- // gestures that were not accepted.
- for (int i = 0; i < gestures.size(); ++i) {
- QGesture *g = gestures.at(i);
- if (!ge.isAccepted(g))
- allGestures.append(g);
+ for (int i = 0; i < gestures.size(); ++i) {
+ QGesture *g = gestures.at(i);
+ if ((res && eventAccepted) || (!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 (!eventAccepted && !ge.isAccepted(g)) {
+ // if the gesture was explicitly ignored by the application,
+ // put it back so a parent can get it
+ allGestures.append(g);
}
}
}
- if (allGestures.isEmpty())
+ if (allGestures.isEmpty()) // everything delivered
break;
if (w->isWindow())
break;
w = w->parentWidget();
}
- gestureEvent->m_accept = eventAccepted;
+ 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);
}
@@ -5627,37 +5619,6 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
}
-/*!
- \since 4.6
-
- Registers the given \a recognizer in the gesture framework and returns a gesture ID
- for it.
-
- The application takes ownership of the \a recognizer and returns the gesture type
- ID associated with it. For gesture recognizers which handle custom QGesture
- objects (i.e., those which return Qt::CustomGesture in a QGesture::gestureType()
- function) the return value is a gesture ID between Qt::CustomGesture and
- Qt::LastGestureType, inclusive.
-
- \sa unregisterGestureRecognizer(), QGestureRecognizer::createGesture(), QGesture
-*/
-Qt::GestureType QApplication::registerGestureRecognizer(QGestureRecognizer *recognizer)
-{
- return QGestureManager::instance()->registerGestureRecognizer(recognizer);
-}
-
-/*!
- \since 4.6
-
- Unregisters all gesture recognizers of the specified \a type.
-
- \sa registerGestureRecognizer
-*/
-void QApplication::unregisterGestureRecognizer(Qt::GestureType type)
-{
- QGestureManager::instance()->unregisterGestureRecognizer(type);
-}
-
QT_END_NAMESPACE
#include "moc_qapplication.cpp"
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 12b398d7fb..e8c1281591 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -61,9 +61,6 @@
QT_BEGIN_HEADER
-#if defined(Q_OS_SYMBIAN)
-class TWsEvent;
-#endif
#if defined(Q_WS_S60)
class CApaApplication;
#endif
@@ -83,10 +80,12 @@ class QLocale;
#if defined(Q_WS_QWS)
class QDecoration;
#endif
+#if defined(Q_OS_SYMBIAN)
+class QSymbianEvent;
+#endif
class QApplication;
class QApplicationPrivate;
-class QGestureRecognizer;
#if defined(qApp)
#undef qApp
#endif
@@ -241,10 +240,8 @@ public:
int x11ProcessEvent(XEvent*);
#endif
#if defined(Q_OS_SYMBIAN)
- int s60ProcessEvent(TWsEvent *event);
- virtual bool s60EventFilter(TWsEvent *aEvent);
- void symbianHandleCommand(int command);
- void symbianResourceChange(int type);
+ int symbianProcessEvent(const QSymbianEvent *event);
+ virtual bool symbianEventFilter(const QSymbianEvent *event);
#endif
#if defined(Q_WS_QWS)
virtual bool qwsEventFilter(QWSEvent *);
@@ -290,9 +287,6 @@ public:
static Qt::NavigationMode navigationMode();
#endif
- Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer);
- void unregisterGestureRecognizer(Qt::GestureType type);
-
Q_SIGNALS:
void lastWindowClosed();
void focusChanged(QWidget *old, QWidget *now);
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index f9c8aa3e24..84da56e5b9 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -104,6 +104,7 @@
#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"
@@ -203,6 +204,8 @@ 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
*****************************************************************************/
@@ -222,6 +225,12 @@ extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplicatio
void onApplicationWindowChangedActivation( QWidget*widget, bool activated );
void onApplicationChangedActivation( bool activated );
+static void qt_mac_read_fontsmoothing_settings()
+{
+ NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"];
+ qt_applefontsmoothing_enabled = (appleFontSmoothing > 0);
+}
+
Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
OSStatus err;
AEDesc scriptTextDesc;
@@ -958,7 +967,8 @@ struct QMacAppleEventTypeSpec {
AEEventID mac_id;
} app_apple_events[] = {
{ kCoreEventClass, kAEQuitApplication },
- { kCoreEventClass, kAEOpenDocuments }
+ { kCoreEventClass, kAEOpenDocuments },
+ { kInternetEventClass, kAEGetURL },
};
#ifndef QT_MAC_USE_COCOA
@@ -1193,7 +1203,7 @@ void qt_init(QApplicationPrivate *priv, int)
app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
- app_proc_ae_handlerUPP, SRefCon(qApp), true);
+ app_proc_ae_handlerUPP, SRefCon(qApp), false);
}
if (QApplicationPrivate::app_style) {
@@ -1203,6 +1213,9 @@ void qt_init(QApplicationPrivate *priv, int)
}
if (QApplication::desktopSettingsAware())
QApplicationPrivate::qt_mac_apply_settings();
+
+ qt_mac_read_fontsmoothing_settings();
+
// Cocoa application delegate
#ifdef QT_MAC_USE_COCOA
NSApplication *cocoaApp = [NSApplication sharedApplication];
@@ -1226,6 +1239,10 @@ void qt_init(QApplicationPrivate *priv, int)
[cocoaApp setMenu:[qtMenuLoader menu]];
[newDelegate setMenuLoader:qtMenuLoader];
[qtMenuLoader release];
+
+ NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
+ forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
#endif
// Register for Carbon tablet proximity events on the event monitor target.
@@ -1686,15 +1703,14 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef 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'.
- const int scrollFactor = 4 * 8;
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaX = mdelt * scrollFactor;
+ wheel_deltaX = mdelt;
mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaY = mdelt * scrollFactor;
+ wheel_deltaY = mdelt;
GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
sizeof(compatibilityEvent), 0, &compatibilityEvent);
} else if (ekind == kEventMouseWheelMoved) {
@@ -1707,31 +1723,11 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
sizeof(axis), 0, &axis);
- // The 'new' event has acceleration applied by the OS, while the old (on
- // Carbon only), has not. So we introduce acceleration here to be consistent.
- // The acceleration is trying to respect both pixel based and line scrolling,
- // which turns out to be rather difficult.
- int linesToScroll = mdelt > 0 ? 1 : -1;
- static QTime t;
- int elapsed = t.elapsed();
- t.restart();
- if (elapsed < 20)
- linesToScroll *= 120;
- else if (elapsed < 30)
- linesToScroll *= 60;
- else if (elapsed < 50)
- linesToScroll *= 30;
- else if (elapsed < 100)
- linesToScroll *= 6;
- else if (elapsed < 200)
- linesToScroll *= 3;
- else if (elapsed < 300)
- linesToScroll *= 2;
-
+ // Remove acceleration, and use either -120 or 120 as delta:
if (axis == kEventMouseWheelAxisX)
- wheel_deltaX = linesToScroll * 120;
+ wheel_deltaX = qBound(-120, int(mdelt * 10000), 120);
else
- wheel_deltaY = linesToScroll * 120;
+ wheel_deltaY = qBound(-120, int(mdelt * 10000), 120);
}
}
@@ -2487,6 +2483,22 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap
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 ? "(*)" : "",
@@ -2684,11 +2696,7 @@ int QApplication::keyboardInputInterval()
void QApplication::setWheelScrollLines(int n)
{
- Q_UNUSED(n);
- // On Mac, acceleration is handled by the OS. Multiplying wheel scroll
- // deltas with n will not be as cross platform as one might think! So
- // we choose to go native in this case (and let wheel_scroll_lines == 1).
- // QApplicationPrivate::wheel_scroll_lines = n;
+ QApplicationPrivate::wheel_scroll_lines = n;
}
int QApplication::wheelScrollLines()
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index baec8ca4f3..48d8535d4b 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -84,7 +84,6 @@ class QInputContext;
class QObject;
class QWidget;
class QSocketNotifier;
-class QGestureManager;
extern bool qt_is_gui_used;
#ifndef QT_NO_CLIPBOARD
@@ -441,9 +440,6 @@ public:
#ifdef Q_WS_MAC
static bool native_modal_dialog_active;
#endif
-#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
- static bool inSizeMove;
-#endif
static void setSystemPalette(const QPalette &pal);
static void setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash);
@@ -503,12 +499,17 @@ public:
static void setNavigationMode(Qt::NavigationMode mode);
static TUint resolveS60ScanCode(TInt scanCode, TUint keysym);
QSet<WId> nativeWindows;
+
+ int symbianProcessWsEvent(const TWsEvent *event);
+ int symbianHandleCommand(int command);
+ int symbianResourceChange(int type);
+
#endif
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_LITE)
void sendSyntheticEnterLeave(QWidget *widget);
#endif
- QGestureManager *gestureManager;
+ QWidget *gestureWidget;
QMap<int, QWidget *> widgetForTouchPointId;
QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 6d50e55bfd..c7f0c00a6b 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -42,6 +42,7 @@
#include "qapplication_p.h"
#include "qsessionmanager.h"
#include "qevent.h"
+#include "qsymbianevent.h"
#include "qeventdispatcher_s60_p.h"
#include "qwidget.h"
#include "qdesktopwidget.h"
@@ -318,7 +319,11 @@ void QLongTapTimer::RunL()
}
QSymbianControl::QSymbianControl(QWidget *w)
- : CCoeControl(), qwidget(w), m_ignoreFocusChanged(false)
+ : CCoeControl()
+ , qwidget(w)
+ , m_longTapDetector(0)
+ , m_ignoreFocusChanged(0)
+ , m_symbianPopupIsOpen(0)
{
}
@@ -370,19 +375,11 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons
alienWidget = qwidget->childAt(widgetPos);
if (!alienWidget)
alienWidget = qwidget;
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons &(~Qt::LeftButton);
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons | Qt::RightButton;
- QMouseEvent mEvent(QEvent::MouseButtonPress, alienWidget->mapFrom(qwidget, widgetPos), globalPos,
- Qt::RightButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier);
-
- bool res = sendMouseEvent(alienWidget, &mEvent);
#if !defined(QT_NO_CONTEXTMENU)
- QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, widgetPos, globalPos, mEvent.modifiers());
+ QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, widgetPos, globalPos, Qt::NoModifier);
qt_sendSpontaneousEvent(alienWidget, &contextMenuEvent);
#endif
-
- m_previousEventLongTap = true;
}
#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
@@ -464,96 +461,122 @@ void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
}
+typedef QPair<QWidget*,QMouseEvent> Event;
+
+/*
+ * Helper function called by HandlePointerEvent - separated to keep that function readable
+ */
+static void generateEnterLeaveEvents(QList<Event> &events, QWidget *widgetUnderPointer,
+ QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
+{
+ //moved to another widget, create enter and leave events
+ if (S60->lastPointerEventTarget) {
+ QMouseEvent mEventLeave(QEvent::Leave, S60->lastPointerEventTarget->mapFromGlobal(
+ S60->lastCursorPos), S60->lastCursorPos, button, QApplicationPrivate::mouse_buttons,
+ modifiers);
+ events.append(Event(S60->lastPointerEventTarget, mEventLeave));
+ }
+ if (widgetUnderPointer) {
+ QMouseEvent mEventEnter(QEvent::Enter, widgetUnderPointer->mapFromGlobal(globalPos),
+ globalPos, button, QApplicationPrivate::mouse_buttons, modifiers);
+
+ events.append(Event(widgetUnderPointer, mEventEnter));
+#ifndef QT_NO_CURSOR
+ S60->curWin = widgetUnderPointer->effectiveWinId();
+ if (!QApplication::overrideCursor()) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_set_pointer_sprite(widgetUnderPointer->cursor());
+ else
+#endif
+ qt_symbian_setWindowCursor(widgetUnderPointer->cursor(), S60->curWin);
+ }
+#endif
+ }
+}
+
+
void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
{
- //### refactor me, getting too complex
QMouseEvent::Type type;
Qt::MouseButton button;
mapS60MouseEventTypeToQt(&type, &button, &pEvent);
+ Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
- if (m_previousEventLongTap)
- if (type == QEvent::MouseButtonRelease){
- button = Qt::RightButton;
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons & ~Qt::RightButton;
- m_previousEventLongTap = false;
- }
if (type == QMouseEvent::None)
return;
// store events for later sending/saving
- QWidget *alienWidget;
- typedef QPair<QWidget*,QMouseEvent> Event;
QList<Event > events;
QPoint widgetPos = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY);
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
- if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove)
- {
- // get the widget where the event happened
- alienWidget = qwidget->childAt(widgetPos);
- if (!alienWidget)
- alienWidget = qwidget;
- S60->mousePressTarget = alienWidget;
+ // widgets interested in the event
+ QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
+ if (!widgetUnderPointer)
+ widgetUnderPointer = qwidget; //i.e. this container widget
+
+ QWidget *widgetWithMouseGrab = QWidget::mouseGrabber();
+
+ // handle auto grab of pointer when pressing / releasing
+ if (!widgetWithMouseGrab && type == QEvent::MouseButtonPress) {
+ //if previously auto-grabbed, generate a fake mouse release (platform bug: mouse release event was lost)
+ if (S60->mousePressTarget) {
+ QMouseEvent mEvent(QEvent::MouseButtonRelease, S60->mousePressTarget->mapFromGlobal(globalPos), globalPos,
+ button, QApplicationPrivate::mouse_buttons, modifiers);
+ events.append(Event(S60->mousePressTarget,mEvent));
+ }
+ //auto grab the mouse
+ widgetWithMouseGrab = S60->mousePressTarget = widgetUnderPointer;
+ widgetWithMouseGrab->grabMouse();
+ }
+ if (widgetWithMouseGrab && widgetWithMouseGrab == S60->mousePressTarget && type == QEvent::MouseButtonRelease) {
+ //release the auto grab - note this release event still goes to the autograb widget
+ S60->mousePressTarget = 0;
+ widgetWithMouseGrab->releaseMouse();
}
- alienWidget = S60->mousePressTarget;
+ QWidget *widgetToReceiveMouseEvent;
+ if (widgetWithMouseGrab)
+ widgetToReceiveMouseEvent = widgetWithMouseGrab;
+ else
+ widgetToReceiveMouseEvent = widgetUnderPointer;
- if (alienWidget != S60->lastPointerEventTarget)
- if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove)
- {
- //moved to another widget, create enter and leave events
- if (S60->lastPointerEventTarget)
- {
- QMouseEvent mEventLeave(QEvent::Leave, S60->lastPointerEventTarget->mapFromGlobal(S60->lastCursorPos), S60->lastCursorPos,
- button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers));
- events.append(Event(S60->lastPointerEventTarget,mEventLeave));
- }
- if (alienWidget) {
- QMouseEvent mEventEnter(QEvent::Enter, alienWidget->mapFromGlobal(globalPos),
- globalPos, button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(
- pEvent.iModifiers));
+ //queue QEvent::Enter and QEvent::Leave, if the pointer has moved
+ if (widgetUnderPointer != S60->lastPointerEventTarget && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove))
+ generateEnterLeaveEvents(events, widgetUnderPointer, globalPos, button, modifiers);
- events.append(Event(alienWidget, mEventEnter));
-#ifndef QT_NO_CURSOR
- S60->curWin = alienWidget->effectiveWinId();
- if (!QApplication::overrideCursor()) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors)
- qt_symbian_set_pointer_sprite(alienWidget->cursor());
- else
-#endif
- qt_symbian_setWindowCursor(alienWidget->cursor(), S60->curWin);
- }
-#endif
- }
- }
+ //save global state
S60->lastCursorPos = globalPos;
+ S60->lastPointerEventPos = widgetPos;
+ S60->lastPointerEventTarget = widgetUnderPointer;
+
#if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS)
if (S60->brokenPointerCursors)
qt_symbian_move_cursor_sprite();
#endif
- S60->lastPointerEventPos = widgetPos;
- S60->lastPointerEventTarget = alienWidget;
- if (alienWidget)
- {
- QMouseEvent mEvent(type, alienWidget->mapFromGlobal(globalPos), globalPos,
- button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers));
- events.append(Event(alienWidget,mEvent));
- QEventDispatcherS60 *dispatcher;
- // It is theoretically possible for someone to install a different event dispatcher.
- if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(alienWidget->d_func()->threadData->eventDispatcher)) != 0) {
- if (dispatcher->excludeUserInputEvents()) {
- for (int i=0;i < events.count();++i)
- {
- Event next = events[i];
- dispatcher->saveInputEvent(this, next.first, new QMouseEvent(next.second));
- }
- return;
+
+ //queue this event.
+ Q_ASSERT(widgetToReceiveMouseEvent);
+ QMouseEvent mEvent(type, widgetToReceiveMouseEvent->mapFromGlobal(globalPos), globalPos,
+ button, QApplicationPrivate::mouse_buttons, modifiers);
+ events.append(Event(widgetToReceiveMouseEvent,mEvent));
+ QEventDispatcherS60 *dispatcher;
+ // It is theoretically possible for someone to install a different event dispatcher.
+ if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widgetToReceiveMouseEvent->d_func()->threadData->eventDispatcher)) != 0) {
+ if (dispatcher->excludeUserInputEvents()) {
+ for (int i=0;i < events.count();++i)
+ {
+ Event next = events[i];
+ dispatcher->saveInputEvent(this, next.first, new QMouseEvent(next.second));
}
+ return;
}
}
+
+ //send events in the queue
for (int i=0;i < events.count();++i)
{
Event next = events[i];
@@ -803,7 +826,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
if (qwidget->d_func()->isOpaque)
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
- }
+ }
} else {
surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint());
}
@@ -833,6 +856,11 @@ void QSymbianControl::SizeChanged()
tlwExtra->inTopLevelResize = 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()
@@ -870,6 +898,15 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
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());
#ifdef Q_WS_S60
// If widget is fullscreen, hide status pane and button container
@@ -877,12 +914,22 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
CEikStatusPane* statusPane = S60->statusPane();
CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
- if (statusPane && (statusPane->IsVisible() == isFullscreen))
+ if (statusPane && (bool)statusPane->IsVisible() == isFullscreen)
statusPane->MakeVisible(!isFullscreen);
- if (buttonGroup && (buttonGroup->IsVisible() == isFullscreen))
+ if (buttonGroup && (bool)buttonGroup->IsVisible() == isFullscreen)
buttonGroup->MakeVisible(!isFullscreen);
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
+ if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
+ 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 }
@@ -892,6 +939,12 @@ void QSymbianControl::HandleResourceChange(int resourceType)
{
switch (resourceType) {
case KInternalStatusPaneChange:
+ if (qwidget->isFullScreen()) {
+ SetExtentToWholeScreen();
+ } else if (qwidget->isMaximized()) {
+ TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+ SetExtent(r.iTl, r.Size());
+ }
qwidget->d_func()->setWindowIcon_sys(true);
break;
case KUidValueCoeFontChangeEvent:
@@ -997,6 +1050,14 @@ QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int
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 initalized. We need to do it.
TApaApplicationFactory factory(S60->s60ApplicationFactory ?
S60->s60ApplicationFactory : newS60Application);
@@ -1005,8 +1066,19 @@ void qt_init(QApplicationPrivate * /* priv */, int)
// After this construction, CEikonEnv will be available from CEikonEnv::Static().
// (much like our qApp).
CEikonEnv* coe = new CEikonEnv;
- QT_TRAP_THROWING(coe->ConstructAppFromCommandLineL(factory,*commandLine));
+ //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
+ if(err == KErrNone)
+ TRAP(err, coe->ConstructAppFromCommandLineL(factory,*commandLine));
delete 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 {
@@ -1024,15 +1096,22 @@ void qt_init(QApplicationPrivate * /* priv */, int)
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();
+ 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)
+ //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.
@@ -1052,6 +1131,13 @@ void qt_init(QApplicationPrivate * /* priv */, int)
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;
@@ -1123,6 +1209,11 @@ void qt_init(QApplicationPrivate * /* priv */, int)
;
}
*/
+
+ // Register WId with the metatype system. This is to enable
+ // QWidgetPrivate::create_sys to used delayed slot invokation in order
+ // to destroy WId objects during reparenting.
+ qRegisterMetaType<WId>("WId");
}
/*****************************************************************************
@@ -1143,6 +1234,9 @@ void qt_cleanup()
S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
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.
@@ -1175,7 +1269,7 @@ bool QApplicationPrivate::modalState()
void QApplicationPrivate::enterModal_sys(QWidget *widget)
{
if (widget) {
- widget->effectiveWinId()->DrawableWindow()->FadeBehind(ETrue);
+ 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);
@@ -1190,7 +1284,7 @@ void QApplicationPrivate::enterModal_sys(QWidget *widget)
void QApplicationPrivate::leaveModal_sys(QWidget *widget)
{
if (widget) {
- widget->effectiveWinId()->DrawableWindow()->FadeBehind(EFalse);
+ static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse);
// ### FixMe: Add specialized behaviour for fullscreen modal dialogs
widget->effectiveWinId()->SetGloballyCapturing(EFalse);
widget->effectiveWinId()->SetPointerCapture(EFalse);
@@ -1382,43 +1476,47 @@ void QApplication::beep()
\warning This function is only available on Symbian.
\since 4.6
- This function processes an individual Symbian window server
+ 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 handle (\c{TWsEvent::Handle()})
- is not known to Qt.
+ not handled because the event is not known to Qt.
*/
-int QApplication::s60ProcessEvent(TWsEvent *event)
+
+int QApplication::symbianProcessEvent(const QSymbianEvent *event)
{
- bool handled = s60EventFilter(event);
- if (handled)
+ Q_D(QApplication);
+
+ QScopedLoopLevelCounter counter(d->threadData);
+
+ 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->windowServerEvent());
+ case QSymbianEvent::CommandEvent:
+ return d->symbianHandleCommand(event->command());
+ case QSymbianEvent::ResourceChangeEvent:
+ return d->symbianResourceChange(event->resourceChangeType());
+ default:
+ return -1;
+ }
+}
+
+int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
+{
// Qt event handling. Handle some events regardless of if the handle is in our
// widget map or not.
CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
switch (event->Type()) {
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
- case EEventKey:
- case EEventKeyUp:
- case EEventKeyDown:
- {
- // The control doesn't seem to be any of our widgets, so rely on the focused
- // widget instead. If the user needs the control, it can be found inside the
- // event structure.
- QWidget *w = qApp ? qApp->focusWidget() : 0;
- if (w) {
- QInputContext *ic = w->inputContext();
- if (ic && ic->s60FilterEvent(w, event)) {
- return 1;
- } else {
- return 0;
- }
- }
- break;
- }
-#endif
case EEventPointerEnter:
if (controlInMap)
return 1; // Qt::Enter will be generated in HandlePointerL
@@ -1491,7 +1589,7 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
}
#endif
break;
- default:
+ default:
break;
}
@@ -1507,15 +1605,15 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
If you create an application that inherits QApplication and reimplement
this function, you get direct access to events that the are received
- from the Symbian window server. The events are passed in the TWsEvent
- \a aEvent parameter.
+ 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
- false, and does nothing with \a aEvent.
+ false for normal event dispatching. The default implementation returns
+ false, and does nothing with \a event.
*/
-bool QApplication::s60EventFilter(TWsEvent * /* aEvent */)
+bool QApplication::symbianEventFilter(const QSymbianEvent *event)
{
+ Q_UNUSED(event);
return false;
}
@@ -1530,32 +1628,39 @@ bool QApplication::s60EventFilter(TWsEvent * /* aEvent */)
\sa s60EventFilter(), s60ProcessEvent()
*/
-void QApplication::symbianHandleCommand(int command)
+int QApplicationPrivate::symbianHandleCommand(int command)
{
- QScopedLoopLevelCounter counter(d_func()->threadData);
+ Q_Q(QApplication);
+ int ret = 0;
+
switch (command) {
#ifdef Q_WS_S60
case EAknSoftkeyExit: {
QCloseEvent ev;
- QApplication::sendSpontaneousEvent(this, &ev);
- if (ev.isAccepted())
- quit();
+ QApplication::sendSpontaneousEvent(q, &ev);
+ if (ev.isAccepted()) {
+ q->quit();
+ ret = 1;
+ }
break;
}
#endif
case EEikCmdExit:
- quit();
+ q->quit();
+ ret = 1;
break;
default:
bool handled = QSoftKeyManager::handleCommand(command);
+ if (handled)
+ ret = 1;
#ifdef Q_WS_S60
- if (!handled)
- QMenuBarPrivate::symbianCommands(command);
-#else
- Q_UNUSED(handled);
+ else
+ ret = QMenuBarPrivate::symbianCommands(command);
#endif
break;
}
+
+ return ret;
}
/*!
@@ -1567,8 +1672,10 @@ void QApplication::symbianHandleCommand(int command)
Currently, KEikDynamicLayoutVariantSwitch and
KAknsMessageSkinChange are handled.
*/
-void QApplication::symbianResourceChange(int type)
+int QApplicationPrivate::symbianResourceChange(int type)
{
+ int ret = 0;
+
switch (type) {
#ifdef Q_WS_S60
case KEikDynamicLayoutVariantSwitch:
@@ -1587,22 +1694,28 @@ void QApplication::symbianResourceChange(int type)
#endif
s60Style = qobject_cast<QS60Style*>(QApplication::style());
- if (s60Style)
+ if (s60Style) {
s60Style->d_func()->handleDynamicLayoutVariantSwitch();
+ ret = 1;
+ }
#endif
}
break;
#ifndef QT_NO_STYLE_S60
case KAknsMessageSkinChange:
- if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style()))
+ 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
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 5bb25fa3a7..05e75a2cac 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -615,6 +615,8 @@ static void qt_set_windows_font_resources()
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
}
@@ -830,6 +832,7 @@ void qt_init(QApplicationPrivate *priv, int)
priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo;
priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments;
#elif !defined(Q_WS_WINCE)
+ #if !defined(QT_NO_NATIVE_GESTURES)
priv->GetGestureInfo =
(PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"),
"GetGestureInfo");
@@ -845,6 +848,7 @@ void qt_init(QApplicationPrivate *priv, int)
priv->GetGestureConfig =
(PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"),
"GetGestureConfig");
+ #endif // QT_NO_NATIVE_GESTURES
priv->BeginPanningFeedback =
(PtrBeginPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"),
"BeginPanningFeedback");
@@ -1916,11 +1920,9 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
#ifndef Q_WS_WINCE
case WM_ENTERSIZEMOVE:
autoCaptureWnd = hwnd;
- QApplicationPrivate::inSizeMove = true;
break;
case WM_EXITSIZEMOVE:
autoCaptureWnd = 0;
- QApplicationPrivate::inSizeMove = false;
break;
#endif
case WM_MOVE: // move window
@@ -2499,24 +2501,24 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
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;
+ 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;
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index bf956841ff..b71ae73a46 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -79,7 +79,7 @@
#include <private/qcolor_p.h>
#include <private/qcursor_p.h>
#include <private/qiconloader_p.h>
-#include <private/gtksymbols_p.h>
+#include <qgtkstyle.h>
#include "qstyle.h"
#include "qmetaobject.h"
#include "qtimer.h"
@@ -1625,6 +1625,7 @@ void qt_init(QApplicationPrivate *priv, int,
// MIT-SHM
X11->use_mitshm = false;
+ X11->use_mitshm_pixmaps = false;
X11->mitshm_major = 0;
X11->sip_serial = 0;
@@ -1918,12 +1919,13 @@ void qt_init(QApplicationPrivate *priv, int,
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 = mitshm_pixmaps && ((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 = ((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
@@ -2297,7 +2299,7 @@ void qt_init(QApplicationPrivate *priv, int,
#if !defined(QT_NO_STYLE_GTK)
if (X11->desktopEnvironment == DE_GNOME) {
- static bool menusHaveIcons = QGtk::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true);
+ static bool menusHaveIcons = QGtkStyle::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true);
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons);
}
#endif
@@ -3750,6 +3752,12 @@ int QApplication::x11ProcessEvent(XEvent* event)
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);
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index 5ed4dc9953..e43f8b5f16 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -296,12 +296,16 @@ QString QClipboard::text(QString &subtype, Mode mode) const
const QByteArray rawData = data->data(QLatin1String("text/") + subtype);
+#ifndef QT_NO_TEXTCODEC
QTextCodec* codec = QTextCodec::codecForMib(106); // utf-8 is default
if (subtype == QLatin1String("html"))
codec = QTextCodec::codecForHtml(rawData, codec);
else
codec = QTextCodec::codecForUtfText(rawData, codec);
return codec->toUnicode(rawData);
+#else //QT_NO_TEXTCODEC
+ return rawData;
+#endif //QT_NO_TEXTCODEC
}
/*!
diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp
index 3db647b123..8892269311 100644
--- a/src/gui/kernel/qclipboard_mac.cpp
+++ b/src/gui/kernel/qclipboard_mac.cpp
@@ -532,7 +532,7 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const
// Try to get the NSStringPboardType from NSPasteboard, newlines are mapped
// correctly (as '\n') in this data. The 'public.utf16-plain-text' type
// usually maps newlines to '\r' instead.
- QString str = qt_mac_get_pasteboardString();
+ QString str = qt_mac_get_pasteboardString(paste);
if (!str.isEmpty())
return str;
}
diff --git a/src/gui/kernel/qclipboard_s60.cpp b/src/gui/kernel/qclipboard_s60.cpp
index de13a5185f..48aa331c9a 100644
--- a/src/gui/kernel/qclipboard_s60.cpp
+++ b/src/gui/kernel/qclipboard_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/gui/kernel/qclipboard_win.cpp
index 7f7ef0c314..01570525d7 100644
--- a/src/gui/kernel/qclipboard_win.cpp
+++ b/src/gui/kernel/qclipboard_win.cpp
@@ -51,6 +51,7 @@
#include "qmime.h"
#include "qt_windows.h"
#include "qdnd_p.h"
+#include <private/qwidget_p.h>
QT_BEGIN_NAMESPACE
@@ -140,6 +141,9 @@ public:
clipBoardViewer = new QWidget();
clipBoardViewer->createWinId();
clipBoardViewer->setObjectName(QLatin1String("internal clipboard owner"));
+ // We dont need this internal widget to appear in QApplication::topLevelWidgets()
+ if (QWidgetPrivate::allWidgets)
+ QWidgetPrivate::allWidgets->remove(clipBoardViewer);
}
~QClipboardData()
diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp
index 9621944722..22d7c9e235 100644
--- a/src/gui/kernel/qclipboard_x11.cpp
+++ b/src/gui/kernel/qclipboard_x11.cpp
@@ -78,6 +78,7 @@
#include "qimagewriter.h"
#include "qvariant.h"
#include "qdnd_p.h"
+#include <private/qwidget_p.h>
#ifndef QT_NO_XFIXES
#include <X11/extensions/Xfixes.h>
@@ -131,6 +132,11 @@ void setupOwner()
requestor = new QWidget(0);
requestor->createWinId();
requestor->setObjectName(QLatin1String("internal clipboard requestor"));
+ // We dont need this internal widgets to appear in QApplication::topLevelWidgets()
+ if (QWidgetPrivate::allWidgets) {
+ QWidgetPrivate::allWidgets->remove(owner);
+ QWidgetPrivate::allWidgets->remove(requestor);
+ }
qAddPostRoutine(cleanup);
}
@@ -769,6 +775,9 @@ QByteArray QX11Data::clipboardReadIncrementalProperty(Window win, Atom property,
delete requestor;
requestor = new QWidget(0);
requestor->setObjectName(QLatin1String("internal clipboard requestor"));
+ // We dont need this internal widget to appear in QApplication::topLevelWidgets()
+ if (QWidgetPrivate::allWidgets)
+ QWidgetPrivate::allWidgets->remove(requestor);
return QByteArray();
}
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
index d103cbdc62..37dcc67fe1 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
@@ -83,6 +83,7 @@
#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
@@ -303,5 +304,15 @@ static void cleanupCocoaApplicationDelegate()
[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);
+}
+
@end
#endif
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
index 80df6452c7..a137744118 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
@@ -123,5 +123,6 @@ QT_FORWARD_DECLARE_CLASS(QApplicationPrivate);
- (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/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index b1c5fc5485..a16d1f803d 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -51,6 +51,7 @@
#include <private/qmacinputcontext_p.h>
#include <private/qmultitouch_mac_p.h>
#include <private/qevent_p.h>
+#include <private/qbackingstore_p.h>
#include <qscrollarea.h>
#include <qhash.h>
@@ -503,6 +504,12 @@ extern "C" {
- (void)drawRect:(NSRect)aRect
{
+ if (QApplicationPrivate::graphicsSystem() != 0) {
+ if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore())
+ bs->markDirty(qwidget->rect(), qwidget);
+ qwidgetprivate->syncBackingStore(qwidget->rect());
+ return;
+ }
CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
qwidgetprivate->hd = cg;
CGContextSaveGState(cg);
@@ -738,7 +745,7 @@ extern "C" {
{
qMacDnDParams()->view = self;
qMacDnDParams()->theEvent = theEvent;
- bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::LeftButton);
+ bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
if (!mouseOK)
[super mouseDragged:theEvent];
@@ -748,7 +755,7 @@ extern "C" {
{
qMacDnDParams()->view = self;
qMacDnDParams()->theEvent = theEvent;
- bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::RightButton);
+ bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
if (!mouseOK)
[super rightMouseDragged:theEvent];
@@ -758,8 +765,7 @@ extern "C" {
{
qMacDnDParams()->view = self;
qMacDnDParams()->theEvent = theEvent;
- Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
- bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, mouseButton);
+ bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
if (!mouseOK)
[super otherMouseDragged:theEvent];
@@ -788,23 +794,23 @@ extern "C" {
const EventRef carbonEvent = (EventRef)[theEvent eventRef];
const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
- if (carbonEventKind == kEventMouseScroll) {
+ 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 four degrees per pixel behaves most native.
// Qt expects the unit for delta to be 1/8 of a degree:
- const int scrollFactor = 4 * 8;
- deltaX = (int)[theEvent deviceDeltaX] * scrollFactor;
- deltaY = (int)[theEvent deviceDeltaY] * scrollFactor;
- deltaZ = (int)[theEvent deviceDeltaZ] * scrollFactor;
- } else { // carbonEventKind == kEventMouseWheelMoved
- // Mouse wheel deltas seem to tick in at increments of 0.1.
- // Qt widgets expect the delta to be a multiple of 120.
- const int scrollFactor = 10 * 120;
- deltaX = [theEvent deltaX] * scrollFactor;
- deltaY = [theEvent deltaY] * scrollFactor;
- deltaZ = [theEvent deltaZ] * scrollFactor;
+ deltaX = [theEvent deviceDeltaX];
+ deltaY = [theEvent deviceDeltaY];
+ deltaZ = [theEvent deviceDeltaZ];
+ } 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);
}
if (deltaX != 0) {
@@ -1066,7 +1072,10 @@ extern "C" {
sendToPopup = true;
}
- if (widgetToGetKey->testAttribute(Qt::WA_InputMethodEnabled)) {
+ if (widgetToGetKey->testAttribute(Qt::WA_InputMethodEnabled)
+ && !(widgetToGetKey->inputMethodHints() & Qt::ImhDigitsOnly
+ || widgetToGetKey->inputMethodHints() & Qt::ImhFormattedNumbersOnly
+ || widgetToGetKey->inputMethodHints() & Qt::ImhHiddenText)) {
[qt_mac_nativeview_for(widgetToGetKey) interpretKeyEvents:[NSArray arrayWithObject: theEvent]];
}
if (sendKeyEvents && !composing) {
@@ -1420,29 +1429,29 @@ Qt::DropAction QDragManager::drag(QDrag *o)
// convert the image to NSImage.
NSImage *image = (NSImage *)qt_mac_create_nsimage(pix);
[image retain];
- DnDParams *dndParams = [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent];
+ DnDParams dndParams = *[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent];
// save supported actions
- [dndParams->view setSupportedActions: qt_mac_mapDropActions(dragPrivate()->possible_actions)];
- NSPoint imageLoc = {dndParams->localPoint.x - hotspot.x(),
- dndParams->localPoint.y + pix.height() - hotspot.y()};
+ [dndParams.view setSupportedActions: qt_mac_mapDropActions(dragPrivate()->possible_actions)];
+ NSPoint imageLoc = {dndParams.localPoint.x - hotspot.x(),
+ dndParams.localPoint.y + pix.height() - hotspot.y()};
NSSize mouseOffset = {0.0, 0.0};
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- NSPoint windowPoint = [dndParams->theEvent locationInWindow];
+ NSPoint windowPoint = [dndParams.theEvent locationInWindow];
dragPrivate()->executed_action = Qt::ActionMask;
// do the drag
- [dndParams->view retain];
- [dndParams->view dragImage:image
+ [dndParams.view retain];
+ [dndParams.view dragImage:image
at:imageLoc
offset:mouseOffset
- event:dndParams->theEvent
+ event:dndParams.theEvent
pasteboard:pboard
- source:dndParams->view
+ source:dndParams.view
slideBack:YES];
- [dndParams->view release];
+ [dndParams.view release];
[image release];
dragPrivate()->executed_action = Qt::IgnoreAction;
object = 0;
- Qt::DropAction performedAction(qt_mac_mapNSDragOperation(dndParams->performedAction));
+ Qt::DropAction performedAction(qt_mac_mapNSDragOperation(dndParams.performedAction));
// do post drag processing, if required.
if(performedAction != Qt::IgnoreAction) {
// check if the receiver points us to a file location.
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm
index 95c89e5b5e..9fb674e0cf 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac.mm
+++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm
@@ -307,6 +307,18 @@ static void cleanupCocoaWindowDelegate()
return m_windowHash->value(window);
}
+- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
+{
+ Q_UNUSED(newFrame);
+ // saving the current window geometry before the window is maximized
+ QWidget *qwidget = m_windowHash->value(window);
+ if (qwidget->isWindow() && !(qwidget->windowState() & Qt::WindowMaximized)) {
+ QWidgetPrivate *widgetPrivate = qt_widget_private(qwidget);
+ widgetPrivate->topData()->normalGeometry = qwidget->geometry();
+ }
+ return YES;
+}
+
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame
{
NSRect frameToReturn = defaultFrame;
@@ -346,5 +358,28 @@ static void cleanupCocoaWindowDelegate()
m_drawerHash->remove(drawer);
}
+- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
+{
+ Q_UNUSED(menu);
+ QWidget *qwidget = m_windowHash->value(window);
+ if (qwidget && !qwidget->windowFilePath().isEmpty()) {
+ return YES;
+ }
+ return NO;
+}
+
+- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event
+ from:(NSPoint)dragImageLocation
+ withPasteboard:(NSPasteboard *)pasteboard
+{
+ Q_UNUSED(event);
+ Q_UNUSED(dragImageLocation);
+ Q_UNUSED(pasteboard);
+ QWidget *qwidget = m_windowHash->value(window);
+ if (qwidget && !qwidget->windowFilePath().isEmpty()) {
+ return YES;
+ }
+ return NO;
+}
@end
#endif// QT_MAC_USE_COCOA
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac_p.h b/src/gui/kernel/qcocoawindowdelegate_mac_p.h
index a06c516720..243ba03a1e 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac_p.h
+++ b/src/gui/kernel/qcocoawindowdelegate_mac_p.h
@@ -76,6 +76,9 @@ QT_FORWARD_DECLARE_CLASS(QWidgetData)
- (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
@protocol NSDrawerDelegate <NSObject>
diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp
index 7f5c32a9ab..07b6de4ca8 100644
--- a/src/gui/kernel/qcursor_s60.cpp
+++ b/src/gui/kernel/qcursor_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp
index 26cde1afcd..a4e7b1fb83 100644
--- a/src/gui/kernel/qcursor_win.cpp
+++ b/src/gui/kernel/qcursor_win.cpp
@@ -153,8 +153,8 @@ static HCURSOR create32BitCursor(const QPixmap &pixmap, int hx, int hy)
bool invb, invm;
bbits = pixmap.toImage().convertToFormat(QImage::Format_Mono);
mbits = pixmap.toImage().convertToFormat(QImage::Format_Mono);
- invb = bbits.numColors() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
- invm = mbits.numColors() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
+ invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
+ invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
int sysW = GetSystemMetrics(SM_CXCURSOR);
int sysH = GetSystemMetrics(SM_CYCURSOR);
@@ -396,8 +396,8 @@ void QCursorData::update()
} else {
bbits = bm->toImage().convertToFormat(QImage::Format_Mono);
mbits = bmm->toImage().convertToFormat(QImage::Format_Mono);
- invb = bbits.numColors() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
- invm = mbits.numColors() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
+ invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
+ invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
}
int n = qMax(1, bbits.width() / 8);
int h = bbits.height();
diff --git a/src/gui/kernel/qdesktopwidget.cpp b/src/gui/kernel/qdesktopwidget.cpp
new file mode 100644
index 0000000000..c6d500050a
--- /dev/null
+++ b/src/gui/kernel/qdesktopwidget.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** 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 "qglobal.h"
+#include "qdesktopwidget.h"
+#include "qwidget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const
+{
+ QRect rect = QWidgetPrivate::screenGeometry(widget);
+ if (rect.isNull())
+ return screenGeometry(screenNumber(widget));
+ else return rect;
+}
+
+const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const
+{
+ QRect rect = QWidgetPrivate::screenGeometry(widget);
+ if (rect.isNull())
+ return availableGeometry(screenNumber(widget));
+ else
+ return rect;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/kernel/qdesktopwidget.h b/src/gui/kernel/qdesktopwidget.h
index 85f479e346..6e3447ce2a 100644
--- a/src/gui/kernel/qdesktopwidget.h
+++ b/src/gui/kernel/qdesktopwidget.h
@@ -75,14 +75,12 @@ public:
QWidget *screen(int screen = -1);
const QRect screenGeometry(int screen = -1) const;
- const QRect screenGeometry(const QWidget *widget) const
- { return screenGeometry(screenNumber(widget)); }
+ 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
- { return availableGeometry(screenNumber(widget)); }
+ const QRect availableGeometry(const QWidget *widget) const;
const QRect availableGeometry(const QPoint &point) const
{ return availableGeometry(screenNumber(point)); }
diff --git a/src/gui/kernel/qdesktopwidget_mac.mm b/src/gui/kernel/qdesktopwidget_mac.mm
index 88dc17377b..c2d05d71bf 100644
--- a/src/gui/kernel/qdesktopwidget_mac.mm
+++ b/src/gui/kernel/qdesktopwidget_mac.mm
@@ -136,16 +136,19 @@ void QDesktopWidgetImplementation::onResize()
screenRects.clear();
availableRects.clear();
NSRect primaryRect = [[displays objectAtIndex:0] frame];
- for (int i = 0; i<screenCount; i++) {
- NSRect r = [[displays objectAtIndex:i] frame];
- const int flippedY = - r.origin.y + // account for position offset and
+ for (int i = 0; i<screenCount; i++) {
+ NSRect r = [[displays objectAtIndex:i] frame];
+ int flippedY = - r.origin.y + // account for position offset and
primaryRect.size.height - r.size.height; // height difference.
screenRects.append(QRectF(r.origin.x, flippedY,
r.size.width, r.size.height));
- r = [[displays objectAtIndex:i] visibleFrame];
+
+ r = [[displays objectAtIndex:i] visibleFrame];
+ flippedY = - r.origin.y + // account for position offset and
+ primaryRect.size.height - r.size.height; // height difference.
availableRects.append(QRectF(r.origin.x, flippedY,
r.size.width, r.size.height));
- }
+ }
}
diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp
index 43e0b8519f..79b8f91520 100644
--- a/src/gui/kernel/qdesktopwidget_s60.cpp
+++ b/src/gui/kernel/qdesktopwidget_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/kernel/qdesktopwidget_x11.cpp b/src/gui/kernel/qdesktopwidget_x11.cpp
index 02a2c82c29..14eb976447 100644
--- a/src/gui/kernel/qdesktopwidget_x11.cpp
+++ b/src/gui/kernel/qdesktopwidget_x11.cpp
@@ -384,10 +384,8 @@ void QDesktopWidget::resizeEvent(QResizeEvent *event)
Q_D(QDesktopWidget);
int oldScreenCount = d->screenCount;
QVector<QRect> oldRects(oldScreenCount);
- QVector<QRect> oldWorks(oldScreenCount);
for (int i = 0; i < oldScreenCount; ++i) {
oldRects[i] = d->rects[i];
- oldWorks[i] = d->workareas[i];
}
d->init();
@@ -397,13 +395,6 @@ void QDesktopWidget::resizeEvent(QResizeEvent *event)
emit resized(i);
}
- // ### workareas are just reset by init, not filled with new values
- // ### so this will not work correctly
- for (int j = 0; j < qMin(oldScreenCount, d->screenCount); ++j) {
- if (oldWorks.at(j) != d->workareas[j])
- emit workAreaResized(j);
- }
-
if (oldScreenCount != d->screenCount) {
emit screenCountChanged(d->screenCount);
}
diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/gui/kernel/qdnd_s60.cpp
index a8d3ac550e..65deb5d3fe 100644
--- a/src/gui/kernel/qdnd_s60.cpp
+++ b/src/gui/kernel/qdnd_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 4826704486..c4a25e18c2 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -45,6 +45,7 @@
#include "private/qapplication_p.h"
#include "private/qkeysequence_p.h"
#include "qwidget.h"
+#include "qgraphicsview.h"
#include "qdebug.h"
#include "qmime.h"
#include "qdnd_p.h"
@@ -398,6 +399,40 @@ QMouseEventEx::~QMouseEventEx()
The function pos() gives the current cursor position, while oldPos() gives
the old mouse position.
+
+ There are a few similarities between the events QEvent::HoverEnter
+ and QEvent::HoverLeave, and the events QEvent::Enter and QEvent::Leave.
+ However, they are slightly different because we do an update() in the event
+ handler of HoverEnter and HoverLeave.
+
+ QEvent::HoverMove is also slightly different from QEvent::MouseMove. Let us
+ consider a top-level window A containing a child B which in turn contains a
+ child C (all with mouse tracking enabled):
+
+ \image hoverEvents.png
+
+ Now, if you move the cursor from the top to the bottom in the middle of A,
+ you will get the following QEvent::MouseMove events:
+
+ \list 1
+ \o A::MouseMove
+ \o B::MouseMove
+ \o C::MouseMove
+ \endlist
+
+ You will get the same events for QEvent::HoverMove, except that the event
+ always propagates to the top-level regardless whether the event is accepted
+ or not. It will only stop propagating with the Qt::WA_NoMousePropagation
+ attribute.
+
+ In this case the events will occur in the following way:
+
+ \list 1
+ \o A::HoverMove
+ \o A::HoverMove, B::HoverMove
+ \o A::HoverMove, B::HoverMove, C::HoverMove
+ \endlist
+
*/
/*!
@@ -2975,13 +3010,13 @@ QShowEvent::~QShowEvent()
/*!
\class QFileOpenEvent
\brief The QFileOpenEvent class provides an event that will be
- sent when there is a request to open a file.
+ sent when there is a request to open a file or a URL.
\ingroup events
File open events will be sent to the QApplication::instance()
- when the operating system requests that a file be opened. This is
- a high-level event that can be caused by different user actions
+ when the operating system requests that a file or URL should be opened.
+ This is a high-level event that can be caused by different user actions
depending on the user's desktop environment; for example, double
clicking on an file icon in the Finder on Mac OS X.
@@ -2998,12 +3033,27 @@ QShowEvent::~QShowEvent()
*/
QFileOpenEvent::QFileOpenEvent(const QString &file)
: QEvent(FileOpen), f(file)
-{}
+{
+ d = reinterpret_cast<QEventPrivate *>(new QFileOpenEventPrivate(QUrl::fromLocalFile(file)));
+}
+
+/*!
+ \internal
+
+ Constructs a file open event for the given \a url.
+*/
+QFileOpenEvent::QFileOpenEvent(const QUrl &url)
+ : QEvent(FileOpen)
+{
+ d = reinterpret_cast<QEventPrivate *>(new QFileOpenEventPrivate(url));
+ f = url.toLocalFile();
+}
/*! \internal
*/
QFileOpenEvent::~QFileOpenEvent()
{
+ delete reinterpret_cast<QFileOpenEventPrivate *>(d);
}
/*!
@@ -3012,6 +3062,16 @@ QFileOpenEvent::~QFileOpenEvent()
Returns the file that is being opened.
*/
+/*!
+ \fn QUrl QFileOpenEvent::url() const
+
+ Returns the url that is being opened.
+*/
+QUrl QFileOpenEvent::url() const
+{
+ return reinterpret_cast<const QFileOpenEventPrivate *>(d)->url;
+}
+
#ifndef QT_NO_TOOLBAR
/*!
\internal
@@ -3563,6 +3623,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar)
\brief The QTouchEvent class contains parameters that describe a touch event.
\since 4.6
\ingroup events
+ \ingroup multitouch
\section1 Enabling Touch Events
@@ -4195,11 +4256,12 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
\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
- allGestures() function.
+ 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
@@ -4208,10 +4270,11 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
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
- 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.
+ 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.
\sa QGesture, QGestureRecognizer,
QWidget::grabGesture(), QGraphicsObject::grabGesture()
@@ -4221,16 +4284,25 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
Creates new QGestureEvent containing a list of \a gestures.
*/
QGestureEvent::QGestureEvent(const QList<QGesture *> &gestures)
- : QEvent(QEvent::Gesture), gestures_(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::allGestures() const
+QList<QGesture *> QGestureEvent::gestures() const
{
- return gestures_;
+ return d_func()->gestures;
}
/*!
@@ -4238,9 +4310,10 @@ QList<QGesture *> QGestureEvent::allGestures() const
*/
QGesture *QGestureEvent::gesture(Qt::GestureType type) const
{
- for(int i = 0; i < gestures_.size(); ++i)
- if (gestures_.at(i)->gestureType() == type)
- return gestures_.at(i);
+ 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;
}
@@ -4249,7 +4322,12 @@ QGesture *QGestureEvent::gesture(Qt::GestureType type) const
*/
QList<QGesture *> QGestureEvent::activeGestures() const
{
- return gestures_;
+ QList<QGesture *> gestures;
+ foreach (QGesture *gesture, d_func()->gestures) {
+ if (gesture->state() != Qt::GestureCanceled)
+ gestures.append(gesture);
+ }
+ return gestures;
}
/*!
@@ -4257,7 +4335,12 @@ QList<QGesture *> QGestureEvent::activeGestures() const
*/
QList<QGesture *> QGestureEvent::canceledGestures() const
{
- return gestures_;
+ QList<QGesture *> gestures;
+ foreach (QGesture *gesture, d_func()->gestures) {
+ if (gesture->state() == Qt::GestureCanceled)
+ gestures.append(gesture);
+ }
+ return gestures;
}
/*!
@@ -4275,9 +4358,8 @@ QList<QGesture *> QGestureEvent::canceledGestures() const
*/
void QGestureEvent::setAccepted(QGesture *gesture, bool value)
{
- setAccepted(false);
if (gesture)
- gesture->d_func()->accept = value;
+ setAccepted(gesture->gestureType(), value);
}
/*!
@@ -4291,7 +4373,8 @@ void QGestureEvent::setAccepted(QGesture *gesture, bool value)
*/
void QGestureEvent::accept(QGesture *gesture)
{
- setAccepted(gesture, true);
+ if (gesture)
+ setAccepted(gesture->gestureType(), true);
}
/*!
@@ -4305,7 +4388,8 @@ void QGestureEvent::accept(QGesture *gesture)
*/
void QGestureEvent::ignore(QGesture *gesture)
{
- setAccepted(gesture, false);
+ if (gesture)
+ setAccepted(gesture->gestureType(), false);
}
/*!
@@ -4313,7 +4397,163 @@ void QGestureEvent::ignore(QGesture *gesture)
*/
bool QGestureEvent::isAccepted(QGesture *gesture) const
{
- return gesture ? gesture->d_func()->accept : false;
+ 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
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 3516222b13..98392696df 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -638,9 +638,11 @@ class Q_GUI_EXPORT QFileOpenEvent : public QEvent
{
public:
QFileOpenEvent(const QString &file);
+ QFileOpenEvent(const QUrl &url);
~QFileOpenEvent();
inline QString file() const { return f; }
+ QUrl url() const;
private:
QString f;
};
@@ -820,12 +822,14 @@ protected:
};
class QGesture;
+class QGestureEventPrivate;
class Q_GUI_EXPORT QGestureEvent : public QEvent
{
public:
QGestureEvent(const QList<QGesture *> &gestures);
+ ~QGestureEvent();
- QList<QGesture *> allGestures() const;
+ QList<QGesture *> gestures() const;
QGesture *gesture(Qt::GestureType type) const;
QList<QGesture *> activeGestures() const;
@@ -849,8 +853,24 @@ public:
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:
- QList<QGesture *> gestures_;
+ QGestureEventPrivate *d_func();
+ const QGestureEventPrivate *d_func() const;
+
+ friend class QApplication;
+ friend class QGestureManager;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index c7a4975ea5..4aaaa8bfc1 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -43,6 +43,7 @@
#define QEVENT_P_H
#include <QtCore/qglobal.h>
+#include <QtCore/qurl.h>
#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
@@ -150,6 +151,32 @@ public:
#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;
+};
+
+
+class QFileOpenEventPrivate
+{
+public:
+ inline QFileOpenEventPrivate(const QUrl &url)
+ : url(url)
+ {
+ }
+
+ QUrl url;
+};
+
QT_END_NAMESPACE
#endif // QEVENT_P_H
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm
index 49c851bf4f..427f0b0a15 100644
--- a/src/gui/kernel/qeventdispatcher_mac.mm
+++ b/src/gui/kernel/qeventdispatcher_mac.mm
@@ -136,14 +136,19 @@ void QEventDispatcherMacPrivate::activateTimer(CFRunLoopTimerRef, void *info)
if (tmr == 0 || tmr->pending == true)
return; // Can't send another timer event if it's pending.
- tmr->pending = true;
- QTimerEvent e(tmr->id);
- qt_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;
+ if (blockSendPostedEvents) {
+ QCoreApplication::postEvent(tmr->obj, new QTimerEvent(tmr->id));
+ } else {
+ tmr->pending = true;
+ QTimerEvent e(tmr->id);
+ qt_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 QEventDispatcherMac::registerTimer(int timerId, int interval, QObject *obj)
@@ -566,6 +571,12 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags)
QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
while (!d->interrupt && [NSApp runModalSession:session] == NSRunContinuesResponse)
qt_mac_waitForMoreModalSessionEvents();
+ if (!d->interrupt && session == d->currentModalSessionCached) {
+ // Someone called e.g. [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);
@@ -767,7 +778,7 @@ NSModalSession QEventDispatcherMacPrivate::currentModalSession()
// Sadly, we need to introduce this little event flush
// to stop dialogs from blinking/poping in front if a
// modal session restart was needed:
- while (NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ while (NSEvent *event = [NSApp nextEventMatchingMask:0
untilDate:nil
inMode:NSDefaultRunLoopMode
dequeue: YES]) {
diff --git a/src/gui/kernel/qeventdispatcher_s60.cpp b/src/gui/kernel/qeventdispatcher_s60.cpp
index dcf83bcd0e..9d18c9b0cd 100644
--- a/src/gui/kernel/qeventdispatcher_s60.cpp
+++ b/src/gui/kernel/qeventdispatcher_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/kernel/qeventdispatcher_s60_p.h b/src/gui/kernel/qeventdispatcher_s60_p.h
index 94282b7590..fbce60a592 100644
--- a/src/gui/kernel/qeventdispatcher_s60_p.h
+++ b/src/gui/kernel/qeventdispatcher_s60_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 3639a45621..e8c2f8af50 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -47,15 +47,19 @@ 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.
- QGesture objects are delivered to widgets and \l{QGraphicsObject}s with
- \l{QGestureEvent}s.
+ Gesture objects are not constructed directly by developers. They are created by
+ the QGestureRecognizer object that is registered with the application; see
+ QGestureRecognizer::registerRecognizer().
+
+ \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 QPinchGesture gesture has a scale
+ 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
@@ -63,6 +67,22 @@ QT_BEGIN_NAMESPACE
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
*/
@@ -70,7 +90,7 @@ QT_BEGIN_NAMESPACE
Constructs a new gesture object with the given \a parent.
QGesture objects are created by gesture recognizers in the
- QGestureRecognizer::createGesture() function.
+ QGestureRecognizer::create() function.
*/
QGesture::QGesture(QObject *parent)
: QObject(*new QGesturePrivate, parent)
@@ -108,8 +128,12 @@ QGesture::~QGesture()
\brief The point that is used to find the receiver for the gesture event.
- If the hot-spot is not set, the targetObject is used as the receiver of 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.
*/
/*!
@@ -117,12 +141,6 @@ QGesture::~QGesture()
\brief whether the gesture has a hot-spot
*/
-/*!
- \property QGesture::targetObject
- \brief the target object which will receive the gesture event if the hotSpot is
- not set
-*/
-
Qt::GestureType QGesture::gestureType() const
{
return d_func()->gestureType;
@@ -133,16 +151,6 @@ Qt::GestureState QGesture::state() const
return d_func()->state;
}
-QObject *QGesture::targetObject() const
-{
- return d_func()->targetObject;
-}
-
-void QGesture::setTargetObject(QObject *value)
-{
- d_func()->targetObject = value;
-}
-
QPointF QGesture::hotSpot() const
{
return d_func()->hotSpot;
@@ -165,46 +173,123 @@ void QGesture::unsetHotSpot()
d_func()->isHotSpotSet = false;
}
-// QPanGesture
+/*!
+ \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
+
+ \sa {Gestures Programming}, 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
+*/
+
+/*!
+ \internal
+*/
QPanGesture::QPanGesture(QObject *parent)
: QGesture(*new QPanGesturePrivate, parent)
{
d_func()->gestureType = Qt::PanGesture;
}
-QSizeF QPanGesture::totalOffset() const
-{
- return d_func()->totalOffset;
-}
-QSizeF QPanGesture::lastOffset() const
+QPointF QPanGesture::lastOffset() const
{
return d_func()->lastOffset;
}
-QSizeF QPanGesture::offset() const
+QPointF QPanGesture::offset() const
{
return d_func()->offset;
}
-qreal QPanGesture::acceleration() const
+QPointF QPanGesture::delta() const
{
- return d_func()->acceleration;
+ Q_D(const QPanGesture);
+ return d->offset - d->lastOffset;
}
-
-void QPanGesture::setTotalOffset(const QSizeF &value)
+qreal QPanGesture::acceleration() const
{
- d_func()->totalOffset = value;
+ return d_func()->acceleration;
}
-void QPanGesture::setLastOffset(const QSizeF &value)
+void QPanGesture::setLastOffset(const QPointF &value)
{
d_func()->lastOffset = value;
}
-void QPanGesture::setOffset(const QSizeF &value)
+void QPanGesture::setOffset(const QPointF &value)
{
d_func()->offset = value;
}
@@ -214,24 +299,175 @@ void QPanGesture::setAcceleration(qreal value)
d_func()->acceleration = value;
}
-// QPinchGesture
+/*!
+ \class QPinchGesture
+ \since 4.6
+ \brief The QPinchGesture class describes a pinch gesture made my the user.
+ \ingroup multitouch
+ \ingroup gestures
+
+ A pinch gesture is a form of multitouch 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.
+
+ \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 {Gestures Programming}, 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 multitouch 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::WhatChanged QPinchGesture::whatChanged() const
+QPinchGesture::ChangeFlags QPinchGesture::totalChangeFlags() const
+{
+ return d_func()->totalChangeFlags;
+}
+
+void QPinchGesture::setTotalChangeFlags(QPinchGesture::ChangeFlags value)
{
- return d_func()->whatChanged;
+ d_func()->totalChangeFlags = value;
}
-void QPinchGesture::setWhatChanged(QPinchGesture::WhatChanged value)
+QPinchGesture::ChangeFlags QPinchGesture::changeFlags() const
{
- d_func()->whatChanged = value;
+ return d_func()->changeFlags;
}
+void QPinchGesture::setChangeFlags(QPinchGesture::ChangeFlags value)
+{
+ d_func()->changeFlags = value;
+}
QPointF QPinchGesture::startCenterPoint() const
{
@@ -325,8 +561,65 @@ void QPinchGesture::setRotationAngle(qreal value)
d_func()->rotationAngle = value;
}
-// QSwipeGesture
+/*!
+ \class QSwipeGesture
+ \since 4.6
+ \brief The QSwipeGesture class describes a swipe gesture made by the user.
+ \ingroup gestures
+
+ \image swipegesture.png
+
+ \sa {Gestures Programming}, 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{The Coordinate System}{coordinate system}.
+
+ \sa horizontalDirection, verticalDirection
+*/
+
+/*!
+ \internal
+*/
QSwipeGesture::QSwipeGesture(QObject *parent)
: QGesture(*new QSwipeGesturePrivate, parent)
{
@@ -365,4 +658,70 @@ 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
+
+ \sa {Gestures Programming}, 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
+
+ \sa {Gestures Programming}, 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;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index 00348190c4..f995d7b616 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -51,12 +51,12 @@
QT_BEGIN_HEADER
+Q_DECLARE_METATYPE(Qt::GestureState)
+
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-Q_DECLARE_METATYPE(Qt::GestureState)
-
class QGesturePrivate;
class Q_GUI_EXPORT QGesture : public QObject
{
@@ -65,9 +65,9 @@ class Q_GUI_EXPORT QGesture : public QObject
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)
- Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject)
public:
explicit QGesture(QObject *parent = 0);
@@ -77,14 +77,19 @@ public:
Qt::GestureState state() const;
- QObject *targetObject() const;
- void setTargetObject(QObject *value);
-
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);
@@ -92,6 +97,7 @@ private:
friend class QGestureEvent;
friend class QGestureRecognizer;
friend class QGestureManager;
+ friend class QGraphicsScenePrivate;
};
class QPanGesturePrivate;
@@ -100,22 +106,21 @@ class Q_GUI_EXPORT QPanGesture : public QGesture
Q_OBJECT
Q_DECLARE_PRIVATE(QPanGesture)
- Q_PROPERTY(QSizeF totalOffset READ totalOffset WRITE setTotalOffset)
- Q_PROPERTY(QSizeF lastOffset READ lastOffset WRITE setLastOffset)
- Q_PROPERTY(QSizeF offset READ offset WRITE setOffset)
+ 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)
public:
QPanGesture(QObject *parent = 0);
- QSizeF totalOffset() const;
- QSizeF lastOffset() const;
- QSizeF offset() const;
+ QPointF lastOffset() const;
+ QPointF offset() const;
+ QPointF delta() const;
qreal acceleration() const;
- void setTotalOffset(const QSizeF &value);
- void setLastOffset(const QSizeF &value);
- void setOffset(const QSizeF &value);
+ void setLastOffset(const QPointF &value);
+ void setOffset(const QPointF &value);
void setAcceleration(qreal value);
friend class QPanGestureRecognizer;
@@ -129,14 +134,15 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture
Q_DECLARE_PRIVATE(QPinchGesture)
public:
- enum WhatChange {
+ enum ChangeFlag {
ScaleFactorChanged = 0x1,
RotationAngleChanged = 0x2,
CenterPointChanged = 0x4
};
- Q_DECLARE_FLAGS(WhatChanged, WhatChange)
+ Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
- Q_PROPERTY(WhatChanged whatChanged READ whatChanged WRITE setWhatChanged)
+ 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)
@@ -153,8 +159,11 @@ public:
public:
QPinchGesture(QObject *parent = 0);
- WhatChanged whatChanged() const;
- void setWhatChanged(WhatChanged value);
+ ChangeFlags totalChangeFlags() const;
+ void setTotalChangeFlags(ChangeFlags value);
+
+ ChangeFlags changeFlags() const;
+ void setChangeFlags(ChangeFlags value);
QPointF startCenterPoint() const;
QPointF lastCenterPoint() const;
@@ -180,7 +189,11 @@ public:
friend class QPinchGestureRecognizer;
};
-Q_DECLARE_METATYPE(QPinchGesture::WhatChanged)
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPinchGesture::ChangeFlags)
+
+QT_BEGIN_NAMESPACE
class QSwipeGesturePrivate;
class Q_GUI_EXPORT QSwipeGesture : public QGesture
@@ -206,8 +219,43 @@ public:
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);
+
+ friend class QTapAndHoldGestureRecognizer;
+};
+
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy)
QT_END_HEADER
#endif // QGESTURE_H
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 7f69a4e906..2537f47029 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -67,17 +67,17 @@ class QGesturePrivate : public QObjectPrivate
public:
QGesturePrivate()
- : gestureType(Qt::CustomGesture), state(Qt::NoGesture), isHotSpotSet(false),
- targetObject(0), accept(true)
+ : gestureType(Qt::CustomGesture), state(Qt::NoGesture),
+ isHotSpotSet(false), gestureCancelPolicy(0)
+
{
}
Qt::GestureType gestureType;
Qt::GestureState state;
QPointF hotSpot;
- bool isHotSpotSet;
- QObject *targetObject;
- bool accept;
+ uint isHotSpotSet : 1;
+ uint gestureCancelPolicy : 2;
};
class QPanGesturePrivate : public QGesturePrivate
@@ -90,10 +90,9 @@ public:
{
}
- QSizeF totalOffset;
- QSizeF lastOffset;
- QSizeF offset;
- QPoint lastPosition;
+ QPointF lastOffset;
+ QPointF offset;
+ QPoint startPosition;
qreal acceleration;
};
@@ -103,12 +102,15 @@ class QPinchGesturePrivate : public QGesturePrivate
public:
QPinchGesturePrivate()
- : whatChanged(0), totalScaleFactor(0), lastScaleFactor(0), scaleFactor(0),
- totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0)
+ : totalChangeFlags(0), changeFlags(0),
+ totalScaleFactor(0), lastScaleFactor(0), scaleFactor(0),
+ totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0),
+ isNewSequence(true)
{
}
- QPinchGesture::WhatChanged whatChanged;
+ QPinchGesture::ChangeFlags totalChangeFlags;
+ QPinchGesture::ChangeFlags changeFlags;
QPointF startCenterPoint;
QPointF lastCenterPoint;
@@ -121,6 +123,9 @@ public:
qreal totalRotationAngle;
qreal lastRotationAngle;
qreal rotationAngle;
+
+ bool isNewSequence;
+ QPointF startPosition[2];
};
class QSwipeGesturePrivate : public QGesturePrivate
@@ -131,13 +136,45 @@ public:
QSwipeGesturePrivate()
: horizontalDirection(QSwipeGesture::NoDirection),
verticalDirection(QSwipeGesture::NoDirection),
- swipeAngle(0)
+ swipeAngle(0),
+ started(false), speed(0)
{
}
QSwipeGesture::SwipeDirection horizontalDirection;
QSwipeGesture::SwipeDirection verticalDirection;
qreal swipeAngle;
+
+ QPoint lastPositions[3];
+ bool started;
+ qreal speed;
+ QTime 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;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 0f0aef2b75..192f9acf62 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -44,6 +44,7 @@
#include "private/qwidget_p.h"
#include "private/qgesture_p.h"
#include "private/qgraphicsitem_p.h"
+#include "private/qevent_p.h"
#include "qgesture.h"
#include "qevent.h"
#include "qgraphicsitem.h"
@@ -51,6 +52,9 @@
#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"
@@ -63,8 +67,17 @@
QT_BEGIN_NAMESPACE
+QGestureManager *qt_gestureManager = 0;
+
+QGestureManager* QGestureManager::instance()
+{
+ if (!qt_gestureManager)
+ qt_gestureManager = new QGestureManager(qApp);
+ return qt_gestureManager;
+}
+
QGestureManager::QGestureManager(QObject *parent)
- : QObject(parent), state(NotGesture), lastCustomGestureId(0)
+ : QObject(parent), state(NotGesture), m_lastCustomGestureId(0)
{
qRegisterMetaType<Qt::GestureState>();
@@ -76,38 +89,89 @@ QGestureManager::QGestureManager(QObject *parent)
#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)
+ 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->createGesture(0);
+ QGesture *dummy = recognizer->create(0);
if (!dummy) {
- qWarning("QGestureManager::registerGestureRecognizer: the recognizer doesn't provide gesture object");
+ 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
- ++lastCustomGestureId;
- type = Qt::GestureType(Qt::CustomGesture + lastCustomGestureId);
+ ++m_lastCustomGestureId;
+ type = Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId);
}
- recognizers.insertMulti(type, recognizer);
+ m_recognizers.insertMulti(type, recognizer);
delete dummy;
return type;
}
-void QGestureManager::unregisterGestureRecognizer(Qt::GestureType)
+void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
{
+ QList<QGestureRecognizer *> list = m_recognizers.values(type);
+ m_recognizers.remove(type);
+ foreach (QGesture *g, m_gestureToRecognizer.keys()) {
+ QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
+ if (list.contains(recognizer)) {
+ m_deletedRecognizers.insert(g, recognizer);
+ m_gestureToRecognizer.remove(g);
+ }
+ }
+
+ foreach (QGestureRecognizer *recognizer, list) {
+ QList<QGesture *> obsoleteGestures;
+ QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin();
+ while (iter != m_objectGestures.end()) {
+ ObjectGesture objectGesture = iter.key();
+ if (objectGesture.gesture == type)
+ obsoleteGestures << iter.value();
+ ++iter;
+ }
+ m_obsoleteGestures.insert(recognizer, obsoleteGestures);
+ }
+}
+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.data()) {
+ qDeleteAll(iter.value());
+ iter = m_objectGestures.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
}
-QGesture* QGestureManager::getState(QObject *object, Qt::GestureType type)
+// 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 carefull and not to
// create a new state, as it will create QWeakPointer which doesnt work
@@ -115,28 +179,45 @@ QGesture* QGestureManager::getState(QObject *object, Qt::GestureType type)
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));
+#endif
}
- QWeakPointer<QGesture> state = objectGestures.value(QGestureManager::ObjectGesture(object, type));
- if (!state) {
- QGestureRecognizer *recognizer = recognizers.value(type);
- if (recognizer) {
- state = recognizer->createGesture(object);
- if (!state)
- return 0;
- if (state.data()->gestureType() == Qt::CustomGesture) {
- // if the recognizer didn't fill in the gesture type, then this
- // is a custom gesture with autogenerated it and we fill it.
- state.data()->d_func()->gestureType = type;
- }
- objectGestures.insert(QGestureManager::ObjectGesture(object, type), state);
- gestureToRecognizer[state.data()] = recognizer;
- }
+ QList<QGesture *> states =
+ m_objectGestures.value(QGestureManager::ObjectGesture(object, type));
+ // check if the QGesture for this recognizer has already been created
+ foreach (QGesture *state, states) {
+ 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
}
- return state.data();
+ m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state);
+ m_gestureToRecognizer[state] = recognizer;
+ m_gestureOwners[state] = object;
+
+ return state;
}
-bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
+bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
+ Qt::GestureType> &contexts,
+ QEvent *event)
{
QSet<QGesture *> triggeredGestures;
QSet<QGesture *> finishedGestures;
@@ -144,140 +225,80 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
QSet<QGesture *> canceledGestures;
QSet<QGesture *> notGestures;
- QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(receiver);
- if (receiver->isWidgetType() || graphicsObject) {
- QMap<QObject *, Qt::GestureType> contexts;
- if (receiver->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(receiver);
- if (!w->d_func()->gestureContext.isEmpty()) {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
- for(ContextIterator it = w->d_func()->gestureContext.begin(),
- e = w->d_func()->gestureContext.end(); it != e; ++it) {
- contexts.insertMulti(w, it.key());
- }
- }
- // find all gesture contexts for the widget tree
- w = w->parentWidget();
- while (w)
- {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
- for (ContextIterator it = w->d_func()->gestureContext.begin(),
- e = w->d_func()->gestureContext.end(); it != e; ++it) {
- if (it.value() == Qt::WidgetWithChildrenGesture)
- contexts.insertMulti(w, it.key());
- }
- w = w->parentWidget();
- }
- } else {
- QGraphicsObject *item = graphicsObject;
- if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
- for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
- e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- contexts.insertMulti(item, it.key());
- }
- }
- // find all gesture contexts for the widget tree
- item = item->parentObject();
- while (item)
- {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::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::WidgetWithChildrenGesture)
- contexts.insertMulti(item, it.key());
- }
- item = item->parentObject();
- }
- }
- // filter the event through recognizers
- typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
- for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
- Qt::GestureType gestureType = cit.value();
- QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
- rit = recognizers.lowerBound(gestureType),
- re = recognizers.upperBound(gestureType);
- for (; rit != re; ++rit) {
- QGestureRecognizer *recognizer = rit.value();
- QObject *target = cit.key();
- QGesture *state = getState(target, gestureType);
- if (!state)
- continue;
- QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event);
- QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
- if (type == QGestureRecognizer::GestureTriggered) {
- DEBUG() << "QGestureManager: gesture triggered: " << state;
- triggeredGestures << state;
- } else if (type == QGestureRecognizer::GestureFinished) {
- DEBUG() << "QGestureManager: gesture finished: " << state;
- finishedGestures << state;
- } else if (type == QGestureRecognizer::MaybeGesture) {
- DEBUG() << "QGestureManager: maybe gesture: " << state;
- newMaybeGestures << state;
- } else if (type == QGestureRecognizer::NotGesture) {
- DEBUG() << "QGestureManager: not gesture: " << state;
- notGestures << state;
- } else if (type == QGestureRecognizer::Ignore) {
- DEBUG() << "QGestureManager: gesture ignored the event: " << state;
- } else {
- DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state;
- }
- if (result & QGestureRecognizer::ConsumeEventHint) {
- DEBUG() << "QGestureManager: we were asked to consume the event: " << state;
- //TODO: consume events if asked
- }
- }
- }
- } else if (QGesture *state = qobject_cast<QGesture*>(receiver)) {
- if (QGestureRecognizer *recognizer = gestureToRecognizer.value(state)) {
- QGestureRecognizer::Result result = recognizer->filterEvent(state, state, event);
+ // TODO: sort contexts by the gesture type and check if one of the contexts
+ // is already active.
+
+ bool ret = false;
+
+ // filter the event through recognizers
+ typedef QHash<QObject *, Qt::GestureType>::const_iterator ContextIterator;
+ for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
+ Qt::GestureType gestureType = cit.value();
+ QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
+ rit = m_recognizers.lowerBound(gestureType),
+ re = m_recognizers.upperBound(gestureType);
+ for (; rit != re; ++rit) {
+ QGestureRecognizer *recognizer = rit.value();
+ QObject *target = cit.key();
+ QGesture *state = getState(target, recognizer, gestureType);
+ if (!state)
+ continue;
+ QGestureRecognizer::Result result = recognizer->recognize(state, target, event);
QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
- if (type == QGestureRecognizer::GestureTriggered) {
- DEBUG() << "QGestureManager: gesture triggered: " << state;
+ result &= QGestureRecognizer::ResultHint_Mask;
+ if (type == QGestureRecognizer::TriggerGesture) {
+ DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state;
triggeredGestures << state;
- } else if (type == QGestureRecognizer::GestureFinished) {
- DEBUG() << "QGestureManager: gesture finished: " << state;
+ } else if (type == QGestureRecognizer::FinishGesture) {
+ DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state;
finishedGestures << state;
- } else if (type == QGestureRecognizer::MaybeGesture) {
- DEBUG() << "QGestureManager: maybe gesture: " << state;
+ } else if (type == QGestureRecognizer::MayBeGesture) {
+ DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state;
newMaybeGestures << state;
- } else if (type == QGestureRecognizer::NotGesture) {
- DEBUG() << "QGestureManager: not gesture: " << state;
+ } else if (type == QGestureRecognizer::CancelGesture) {
+ DEBUG() << "QGestureManager:Recognizer: not gesture: " << state;
notGestures << state;
} else if (type == QGestureRecognizer::Ignore) {
- DEBUG() << "QGestureManager: gesture ignored the event: " << state;
+ DEBUG() << "QGestureManager:Recognizer: ignored the event: " << state;
} else {
- DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state;
+ DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer"
+ << "ignored the event: " << state;
+ }
+ if (result & QGestureRecognizer::ConsumeEventHint) {
+ DEBUG() << "QGestureManager: we were asked to consume the event: "
+ << state;
+ ret = true;
}
}
- } else {
- return false;
}
- QSet<QGesture *> startedGestures = triggeredGestures - activeGestures;
- triggeredGestures &= activeGestures;
+ QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
+ triggeredGestures &= m_activeGestures;
// check if a running gesture switched back to maybe state
- QSet<QGesture *> activeToMaybeGestures = activeGestures & newMaybeGestures;
+ QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures;
- // check if a running gesture switched back to not gesture state, i.e. were canceled
- QSet<QGesture *> activeToCancelGestures = activeGestures & notGestures;
+ // check if a running gesture switched back to not gesture state,
+ // i.e. were canceled
+ QSet<QGesture *> activeToCancelGestures = m_activeGestures & notGestures;
canceledGestures += activeToCancelGestures;
// start timers for new gestures in maybe state
foreach (QGesture *state, newMaybeGestures) {
- QBasicTimer &timer = maybeGestures[state];
+ QBasicTimer &timer = m_maybeGestures[state];
if (!timer.isActive())
timer.start(3000, this);
}
// kill timers for gestures that were in maybe state
- QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures | finishedGestures | canceledGestures | notGestures);
+ QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
+ | finishedGestures | canceledGestures
+ | notGestures);
foreach(QGesture *gesture, notMaybeGestures) {
- QMap<QGesture *, QBasicTimer>::iterator it =
- maybeGestures.find(gesture);
- if (it != maybeGestures.end()) {
+ QHash<QGesture *, QBasicTimer>::iterator it =
+ m_maybeGestures.find(gesture);
+ if (it != m_maybeGestures.end()) {
it.value().stop();
- maybeGestures.erase(it);
+ m_maybeGestures.erase(it);
}
}
@@ -288,21 +309,23 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
- QSet<QGesture *> notStarted = finishedGestures - activeGestures;
+ 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;
- deliverEvents(notStarted, receiver);
+ QSet<QGesture *> undeliveredGestures;
+ deliverEvents(notStarted, &undeliveredGestures);
+ finishedGestures -= undeliveredGestures;
}
- activeGestures += startedGestures;
+ m_activeGestures += startedGestures;
// sanity check: all triggered gestures should already be in active gestures list
- Q_ASSERT((activeGestures & triggeredGestures).size() == triggeredGestures.size());
- activeGestures -= finishedGestures;
- activeGestures -= activeToMaybeGestures;
- activeGestures -= canceledGestures;
+ 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)
@@ -316,152 +339,378 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
foreach (QGesture *gesture, activeToMaybeGestures)
gesture->d_func()->state = Qt::GestureFinished;
- if (!activeGestures.isEmpty() || !maybeGestures.isEmpty() ||
+ if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() ||
!startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
!finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
- DEBUG() << "QGestureManager::filterEvent:"
- << "\n\tactiveGestures:" << activeGestures
- << "\n\tmaybeGestures:" << maybeGestures.keys()
+ DEBUG() << "QGestureManager::filterEventThroughContexts:"
+ << "\n\tactiveGestures:" << m_activeGestures
+ << "\n\tmaybeGestures:" << m_maybeGestures.keys()
<< "\n\tstarted:" << startedGestures
<< "\n\ttriggered:" << triggeredGestures
<< "\n\tfinished:" << finishedGestures
<< "\n\tcanceled:" << canceledGestures;
}
- deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, receiver);
+ 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;
+ QSet<QGesture *> endedGestures =
+ finishedGestures + canceledGestures + undeliveredGestures;
foreach (QGesture *gesture, endedGestures) {
- if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) {
- recognizer->reset(gesture);
+ recycle(gesture);
+ m_gestureTargets.remove(gesture);
+ }
+ return ret;
+}
+
+// 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);
+ Q_ASSERT(recognizer);
+ 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)
+{
+ QSet<Qt::GestureType> types;
+ QMultiHash<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());
+ 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());
+ contexts.insertMulti(w, it.key());
+ }
+ }
+ }
+ if (w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ return filterEventThroughContexts(contexts, event);
+}
+
+#ifndef QT_NO_GRAPHICSVIEW
+bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
+{
+ QSet<Qt::GestureType> types;
+ QMultiHash<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());
+ 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());
+ contexts.insertMulti(item, it.key());
+ }
+ }
+ }
+ item = item->parentObject();
+ }
+ return filterEventThroughContexts(contexts, event);
+}
+#endif
+
+bool QGestureManager::filterEvent(QGesture *state, QEvent *event)
+{
+ QMultiHash<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'
+ Qt::GestureFlags flags = it.value();
+ 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]);
}
- gestureTargets.remove(gesture);
}
- return false;
}
-void QGestureManager::deliverEvents(const QSet<QGesture*> &gestures, QObject *lastReceiver)
+void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
+ QSet<QGesture *> *undeliveredGestures)
{
if (gestures.isEmpty())
return;
- // group gestures by widgets
- typedef QMap<QObject *, QList<QGesture *> > GesturesPerReceiver;
- GesturesPerReceiver groupedGestures;
- // for conflicted gestures the key is always the innermost widget (i.e. the child)
- GesturesPerReceiver conflictedGestures;
- QMultiHash<QObject *, QGesture *> objectGestures;
+ typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
+ GesturesPerWidget conflictedGestures;
+ GesturesPerWidget normalStartedGestures;
- foreach (QGesture *gesture, gestures) {
- QObject *target = gestureTargets.value(gesture, 0);
+ 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 using the hotspot of the gesture
+ // guess the target widget using the hotspot of the gesture
QPoint pt = gesture->hotSpot().toPoint();
- if (!pt.isNull()) {
- if (QWidget *w = qApp->topLevelAt(pt))
- target = w->childAt(w->mapFromGlobal(pt));
+ if (QWidget *w = qApp->topLevelAt(pt)) {
+ target = w->childAt(w->mapFromGlobal(pt));
}
+ } 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) {
- target = gesture->targetObject();
- if (!target)
- target = lastReceiver;
- }
+ if (target)
+ m_gestureTargets.insert(gesture, target);
}
+
+ Qt::GestureType gestureType = gesture->gestureType();
+ Q_ASSERT(gestureType != Qt::CustomGesture);
+ Q_UNUSED(gestureType);
+
if (target) {
- gestureTargets.insert(gesture, target);
- if (target->isWidgetType())
- objectGestures.insert(target, gesture);
- groupedGestures[target].append(gesture);
+ if (gesture->state() == Qt::GestureStarted) {
+ startedGestures.insert(gesture);
+ } else {
+ normalStartedGestures[target].append(gesture);
+ }
} else {
- qWarning() << "QGestureManager::deliverEvent: could not find the target for gesture"
+ 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);
}
}
- typedef QMultiHash<QObject *, QGesture *>::const_iterator ObjectGesturesIterator;
- for (ObjectGesturesIterator it = objectGestures.begin(), e = objectGestures.end(); it != e; ++it) {
- QObject *object1 = it.key();
- QWidget *widget1 = qobject_cast<QWidget *>(object1);
- QGraphicsObject *item1 = qobject_cast<QGraphicsObject *>(object1);
- QGesture *gesture1 = it.value();
- ObjectGesturesIterator cit = it;
- for (++cit; cit != e; ++cit) {
- QObject *object2 = cit.key();
- QWidget *widget2 = qobject_cast<QWidget *>(object2);
- QGraphicsObject *item2 = qobject_cast<QGraphicsObject *>(object2);
- QGesture *gesture2 = cit.value();
- // TODO: ugly, rewrite this.
- if ((widget1 && widget2 && widget2->isAncestorOf(widget1)) ||
- (item1 && item2 && item2->isAncestorOf(item1))) {
- groupedGestures[object2].removeOne(gesture2);
- groupedGestures[object1].removeOne(gesture1);
- conflictedGestures[object1].append(gesture1);
- } else if ((widget1 && widget2 && widget1->isAncestorOf(widget2)) ||
- (item1 && item2 && item1->isAncestorOf(item2))) {
- groupedGestures[object2].removeOne(gesture2);
- groupedGestures[object1].removeOne(gesture1);
- conflictedGestures[object2].append(gesture2);
- }
- }
- }
-
- DEBUG() << "deliverEvents: conflicted =" << conflictedGestures.values()
- << " grouped =" << groupedGestures.values();
+ getGestureTargets(startedGestures, &conflictedGestures, &normalStartedGestures);
+ DEBUG() << "QGestureManager::deliverEvents:"
+ << "\nstarted: " << startedGestures
+ << "\nconflicted: " << conflictedGestures
+ << "\nnormal: " << normalStartedGestures
+ << "\n";
// if there are conflicting gestures, send the GestureOverride event
- for (GesturesPerReceiver::const_iterator it = conflictedGestures.begin(),
+ 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"
- << it.key()
- << " gestures:" << it.value();
- QGestureEvent event(it.value());
+ << receiver
+ << "gestures:" << gestures;
+ QGestureEvent event(gestures);
event.t = QEvent::GestureOverride;
+ // mark event and individual gestures as ignored
event.ignore();
- QApplication::sendEvent(it.key(), &event);
- if (!event.isAccepted()) {
- // nobody accepted the GestureOverride, put it back to deliver to
- // the closest context (i.e. to the inner-most widget).
- DEBUG() <<" override was not accepted";
- groupedGestures[it.key()].append(it.value());
+ 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);
+ }
}
}
- for (GesturesPerReceiver::const_iterator it = groupedGestures.begin(),
- e = groupedGestures.end(); it != e; ++it) {
+ // 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();
+ << "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::timerEvent(QTimerEvent *event)
{
- QMap<QGesture*, QBasicTimer>::iterator it = maybeGestures.begin(),
- e = maybeGestures.end();
+ QHash<QGesture *, QBasicTimer>::iterator it = m_maybeGestures.begin(),
+ e = m_maybeGestures.end();
for (; it != e; ) {
QBasicTimer &timer = it.value();
Q_ASSERT(timer.isActive());
if (timer.timerId() == event->timerId()) {
timer.stop();
QGesture *gesture = it.key();
- it = maybeGestures.erase(it);
- DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:" << gesture;
- QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0);
- if (recognizer)
- recognizer->reset(gesture);
+ it = m_maybeGestures.erase(it);
+ DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:"
+ << gesture;
+ recycle(gesture);
} else {
++it;
}
}
}
+void QGestureManager::recycle(QGesture *gesture)
+{
+ QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
+ if (recognizer) {
+ gesture->setGestureCancelPolicy(QGesture::CancelNone);
+ recognizer->reset(gesture);
+ } else {
+ cleanupGesturesForRemovedRecognizer(gesture);
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qgesturemanager_p.cpp"
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
index c61819f5c2..4efa10b0c0 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -61,6 +61,7 @@
QT_BEGIN_NAMESPACE
class QBasicTimer;
+class QGraphicsObject;
class QGestureManager : public QObject
{
Q_OBJECT
@@ -71,19 +72,28 @@ public:
Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer);
void unregisterGestureRecognizer(Qt::GestureType type);
- bool filterEvent(QObject *receiver, QEvent *event);
+ bool filterEvent(QWidget *receiver, QEvent *event);
+ bool filterEvent(QGesture *receiver, QEvent *event);
+#ifndef QT_NO_GRAPHICSVIEW
+ bool filterEvent(QGraphicsObject *receiver, QEvent *event);
+#endif //QT_NO_GRAPHICSVIEW
- // declared in qapplication.cpp
static QGestureManager* instance();
+ void cleanupCachedGestures(QObject *target, Qt::GestureType type);
+
+ void recycle(QGesture *gesture);
+
protected:
void timerEvent(QTimerEvent *event);
+ bool filterEventThroughContexts(const QMultiHash<QObject *, Qt::GestureType> &contexts,
+ QEvent *event);
private:
- QMultiMap<Qt::GestureType, QGestureRecognizer *> recognizers;
+ QMultiMap<Qt::GestureType, QGestureRecognizer *> m_recognizers;
- QSet<QGesture *> activeGestures;
- QMap<QGesture *, QBasicTimer> maybeGestures;
+ QSet<QGesture *> m_activeGestures;
+ QHash<QGesture *, QBasicTimer> m_maybeGestures;
enum State {
Gesture,
@@ -99,7 +109,7 @@ private:
Qt::GestureType gesture;
ObjectGesture(QObject *o, const Qt::GestureType &g) : object(o), gesture(g) { }
- inline bool operator<(const ObjectGesture& rhs) const
+ inline bool operator<(const ObjectGesture &rhs) const
{
if (object.data() < rhs.object.data())
return true;
@@ -109,17 +119,31 @@ private:
}
};
- QMap<ObjectGesture, QWeakPointer<QGesture> > objectGestures;
- QMap<QGesture *, QGestureRecognizer *> gestureToRecognizer;
+ QMap<ObjectGesture, QList<QGesture *> > m_objectGestures;
+ QHash<QGesture *, QGestureRecognizer *> m_gestureToRecognizer;
+ QHash<QGesture *, QObject *> m_gestureOwners;
+
+ QHash<QGesture *, QWidget *> m_gestureTargets;
- QHash<QGesture *, QObject *> gestureTargets;
+ int m_lastCustomGestureId;
- int lastCustomGestureId;
+ QHash<QGestureRecognizer *, QList<QGesture *> > m_obsoleteGestures;
+ QHash<QGesture *, QGestureRecognizer *> m_deletedRecognizers;
+ void cleanupGesturesForRemovedRecognizer(QGesture *gesture);
- QGesture *getState(QObject *widget, Qt::GestureType gesture);
- void deliverEvents(const QSet<QGesture *> &gestures, QObject *lastReceiver);
+ QGesture *getState(QObject *widget, QGestureRecognizer *recognizer,
+ Qt::GestureType gesture);
+ void deliverEvents(const QSet<QGesture *> &gestures,
+ QSet<QGesture *> *undeliveredGestures);
+ void getGestureTargets(const QSet<QGesture*> &gestures,
+ QMap<QWidget *, QList<QGesture *> > *conflicts,
+ QMap<QWidget *, QList<QGesture *> > *normal);
+
+ void cancelGesturesForChildren(QGesture *originatingGesture);
};
+extern QGestureManager *qt_gestureManager;
+
QT_END_NAMESPACE
#endif // QGESTUREMANAGER_P_H
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
index 2af087fc42..ed0bdcca9f 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -42,6 +42,7 @@
#include "qgesturerecognizer.h"
#include "private/qgesture_p.h"
+#include "private/qgesturemanager_p.h"
QT_BEGIN_NAMESPACE
@@ -49,6 +50,7 @@ QT_BEGIN_NAMESPACE
\class QGestureRecognizer
\since 4.6
\brief The QGestureRecognizer class provides the infrastructure for gesture recognition.
+ \ingroup gestures
Gesture recognizers are responsible for creating and managing QGesture objects and
monitoring input events sent to QWidget and QGraphicsObject subclasses.
@@ -64,10 +66,12 @@ QT_BEGIN_NAMESPACE
objects, and modifying the associated QGesture objects to include relevant information
about the user's input.
- Gestures are created when the framework calls createGesture() to handle user input
- for a particular target QWidget or QGraphicsObject instance. Once a QGesture has been
- created for one of these objects, the gesture recognizer will receive events for it
- in its filterEvent() handler function.
+ Gestures are created when the framework calls create() to handle user input
+ for a particular instance of a QWidget or QGraphicsObject subclass. A QGesture object
+ is created for each widget or item that is configured to use gestures.
+
+ Once a QGesture has been created for a target object, the gesture recognizer will
+ receive events for it in its recognize() handler function.
When a gesture is canceled, the reset() function is called, giving the recognizer the
chance to update the appropriate properties in the corresponding QGesture object.
@@ -75,18 +79,23 @@ QT_BEGIN_NAMESPACE
\section1 Supporting New Gestures
To add support for new gestures, you need to derive from QGestureRecognizer to create
- a custom recognizer class and register it with the application by calling
- QApplication::registerGestureRecognizer(). You can also derive from QGesture to create
- a custom gesture class, or rely on dynamic properties to express specific details
- of the gesture you want to handle.
-
- Your custom QGestureRecognizer subclass needs to reimplement the filterEvent() function
- to handle and filter the incoming input events for QWidget and QGraphicsObject subclasses.
- Although the logic for gesture recognition is implemented in this function, the state of
- recognition for each target object can be recorded in the QGesture object supplied.
+ a custom recognizer class, construct an instance of this class, and register it with
+ the application by calling QGestureRecognizer::registerRecognizer(). You can also
+ subclass QGesture to create a custom gesture class, or rely on dynamic properties
+ to express specific details of the gesture you want to handle.
+
+ Your custom QGestureRecognizer subclass needs to reimplement the recognize()
+ function to handle and filter the incoming input events for QWidget and
+ QGraphicsObject subclasses. Although the logic for gesture recognition is
+ implemented in this function, you can store persistent information about the
+ state of the recognition process in the QGesture object supplied. The
+ recognize() function must return a value of QGestureRecognizer::Result that
+ indicates the state of recognition for a given gesture and target object.
+ This determines whether or not a gesture event will be delivered to a target
+ object.
If you choose to represent a gesture by a custom QGesture subclass, you will need to
- reimplement the createGesture() function to construct instances of your gesture class.
+ reimplement the create() function to construct instances of your gesture class.
Similarly, you may need to reimplement the reset() function if your custom gesture
objects need to be specially handled when a gesture is canceled.
@@ -94,42 +103,42 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \enum QGestureRecognizer::ResultFlags
+ \enum QGestureRecognizer::ResultFlag
This enum describes the result of the current event filtering step in
a gesture recognizer state machine.
- The result consists of a state value (one of Ignore, NotGesture,
- MaybeGesture, GestureTriggered, GestureFinished) and an optional hint
+ The result consists of a state value (one of Ignore, MayBeGesture,
+ TriggerGesture, FinishGesture, CancelGesture) and an optional hint
(ConsumeEventHint).
\value Ignore The event does not change the state of the recognizer.
- \value NotGesture The event made it clear that it is not a gesture. If the
- gesture recognizer was in GestureTriggered state before, then the gesture
- is canceled and the appropriate QGesture object will be delivered to the
- target as a part of a QGestureEvent.
-
- \value MaybeGesture The event changed the internal state of the recognizer,
+ \value MayBeGesture The event changed the internal state of the recognizer,
but it isn't clear yet if it is a gesture or not. The recognizer needs to
- filter more events to decide. Gesture recognizers in the MaybeGesture state
+ filter more events to decide. Gesture recognizers in the MayBeGesture state
may be reset automatically if they take too long to recognize gestures.
- \value GestureTriggered The gesture has been triggered and the appropriate
+ \value TriggerGesture The gesture has been triggered and the appropriate
QGesture object will be delivered to the target as a part of a
QGestureEvent.
- \value GestureFinished The gesture has been finished successfully and the
+ \value FinishGesture The gesture has been finished successfully and the
appropriate QGesture object will be delivered to the target as a part of a
QGestureEvent.
- \value ConsumeEventHint This hint specifies that the gesture framework should
- consume the filtered event and not deliver it to the receiver.
+ \value CancelGesture The event made it clear that it is not a gesture. If
+ the gesture recognizer was in GestureTriggered state before, then the
+ gesture is canceled and the appropriate QGesture object will be delivered
+ to the target as a part of a QGestureEvent.
+
+ \value ConsumeEventHint This hint specifies that the gesture framework
+ should consume the filtered event and not deliver it to the receiver.
\omitvalue ResultState_Mask
\omitvalue ResultHint_Mask
- \sa QGestureRecognizer::filterEvent()
+ \sa QGestureRecognizer::recognize()
*/
/*!
@@ -153,7 +162,7 @@ QGestureRecognizer::~QGestureRecognizer()
Reimplement this function to create a custom QGesture-derived gesture
object if necessary.
*/
-QGesture *QGestureRecognizer::createGesture(QObject *target)
+QGesture *QGestureRecognizer::create(QObject *target)
{
Q_UNUSED(target);
return new QGesture;
@@ -172,15 +181,15 @@ void QGestureRecognizer::reset(QGesture *gesture)
QGesturePrivate *d = gesture->d_func();
d->state = Qt::NoGesture;
d->hotSpot = QPointF();
- d->targetObject = 0;
+ d->isHotSpotSet = false;
}
}
/*!
- \fn QGestureRecognizer::filterEvent(QGesture *gesture, QObject *watched, QEvent *event)
+ \fn QGestureRecognizer::recognize(QGesture *gesture, QObject *watched, QEvent *event)
Handles the given \a event for the \a watched object, updating the state of the \a gesture
- object as required, and returns a suitable Result for the current recognition step.
+ object as required, and returns a suitable result for the current recognition step.
This function is called by the framework to allow the recognizer to filter input events
dispatched to QWidget or QGraphicsObject instances that it is monitoring.
@@ -188,7 +197,34 @@ void QGestureRecognizer::reset(QGesture *gesture)
The result reflects how much of the gesture has been recognized. The state of the
\a gesture object is set depending on the result.
- \sa Qt::GestureState
+ \sa QGestureRecognizer::Result
+*/
+
+/*!
+ Registers the given \a recognizer in the gesture framework and returns a gesture ID
+ for it.
+
+ The application takes ownership of the \a recognizer and returns the gesture type
+ ID associated with it. For gesture recognizers which handle custom QGesture
+ objects (i.e., those which return Qt::CustomGesture in a QGesture::gestureType()
+ function) the return value is a generated gesture ID with the Qt::CustomGesture
+ flag set.
+
+ \sa unregisterRecognizer(), QGestureRecognizer::create(), QGesture
*/
+Qt::GestureType QGestureRecognizer::registerRecognizer(QGestureRecognizer *recognizer)
+{
+ return QGestureManager::instance()->registerGestureRecognizer(recognizer);
+}
+
+/*!
+ Unregisters all gesture recognizers of the specified \a type.
+
+ \sa registerRecognizer()
+*/
+void QGestureRecognizer::unregisterRecognizer(Qt::GestureType type)
+{
+ QGestureManager::instance()->unregisterGestureRecognizer(type);
+}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h
index efd85654a7..4eebf7cf3f 100644
--- a/src/gui/kernel/qgesturerecognizer.h
+++ b/src/gui/kernel/qgesturerecognizer.h
@@ -43,6 +43,7 @@
#define QGESTURERECOGNIZER_H
#include <QtCore/qglobal.h>
+#include <QtCore/qnamespace.h>
QT_BEGIN_HEADER
@@ -56,32 +57,36 @@ class QGesture;
class Q_GUI_EXPORT QGestureRecognizer
{
public:
- enum ResultFlags
+ enum ResultFlag
{
- Ignore = 0x0001,
- NotGesture = 0x0002,
- MaybeGesture = 0x0004,
- GestureTriggered = 0x0008, // Gesture started or updated
- GestureFinished = 0x0010,
+ Ignore = 0x0001,
- ResultState_Mask = 0x00ff,
+ MayBeGesture = 0x0002,
+ TriggerGesture = 0x0004,
+ FinishGesture = 0x0008,
+ CancelGesture = 0x0010,
+
+ ResultState_Mask = 0x00ff,
ConsumeEventHint = 0x0100,
// StoreEventHint = 0x0200,
// ReplayStoredEventsHint = 0x0400,
// DiscardStoredEventsHint = 0x0800,
- ResultHint_Mask = 0xff00
+ ResultHint_Mask = 0xff00
};
- Q_DECLARE_FLAGS(Result, ResultFlags)
+ Q_DECLARE_FLAGS(Result, ResultFlag)
QGestureRecognizer();
virtual ~QGestureRecognizer();
- virtual QGesture *createGesture(QObject *target);
- virtual QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event) = 0;
-
+ 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)
diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
index 69e6290bd7..1b4265662a 100644
--- a/src/gui/kernel/qguiplatformplugin.cpp
+++ b/src/gui/kernel/qguiplatformplugin.cpp
@@ -59,9 +59,9 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
#if defined(Q_WS_X11)
-#include "qkde_p.h"
-#include "qt_x11_p.h"
-#include <private/gtksymbols_p.h>
+#include <private/qkde_p.h>
+#include <private/qgtkstyle_p.h>
+#include <private/qt_x11_p.h>
#endif
@@ -206,7 +206,7 @@ QString QGuiPlatformPlugin::systemIconThemeName()
if (X11->desktopEnvironment == DE_GNOME) {
result = QString::fromLatin1("gnome");
#ifndef QT_NO_STYLE_GTK
- result = QGtk::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"), result);
+ result = QGtkStylePrivate::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"), result);
#endif
} else if (X11->desktopEnvironment == DE_KDE) {
result = X11->desktopVersion >= 4 ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg");
@@ -288,6 +288,8 @@ int QGuiPlatformPlugin::platformHint(PlatformHint hint)
#endif
//by default keep ret = 0 so QCommonStyle will use the style default
break;
+ default:
+ break;
}
return ret;
}
diff --git a/src/gui/kernel/qkeymapper_s60.cpp b/src/gui/kernel/qkeymapper_s60.cpp
index d272d6e483..ecfb7fb436 100644
--- a/src/gui/kernel/qkeymapper_s60.cpp
+++ b/src/gui/kernel/qkeymapper_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp
index be207df67d..f95efa2656 100644
--- a/src/gui/kernel/qkeymapper_win.cpp
+++ b/src/gui/kernel/qkeymapper_win.cpp
@@ -438,10 +438,10 @@ static const Qt::KeyboardModifiers ModsTbl[] = {
*/
inline int winceKeyBend(int keyCode)
{
-#ifdef Q_OS_WINCE_WM
+#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 == 13)
+ if (keyCode == VK_RETURN && QApplication::keypadNavigationEnabled())
return Qt::Key_Select;
else
return KeyTbl[keyCode];
diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp
index 0ce77feae0..8164589070 100644
--- a/src/gui/kernel/qkeymapper_x11.cpp
+++ b/src/gui/kernel/qkeymapper_x11.cpp
@@ -714,47 +714,144 @@ extern bool qt_sm_blockUserInput;
#define XK_KP_Delete 0xFF9F
#endif
-// the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special
+// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
// multimedia keys. They are included here as not every system has them.
-#define XF86XK_Standby 0x1008FF10
-#define XF86XK_AudioLowerVolume 0x1008FF11
-#define XF86XK_AudioMute 0x1008FF12
-#define XF86XK_AudioRaiseVolume 0x1008FF13
-#define XF86XK_AudioPlay 0x1008FF14
-#define XF86XK_AudioStop 0x1008FF15
-#define XF86XK_AudioPrev 0x1008FF16
-#define XF86XK_AudioNext 0x1008FF17
-#define XF86XK_HomePage 0x1008FF18
-#define XF86XK_Calculator 0x1008FF1D
-#define XF86XK_Mail 0x1008FF19
-#define XF86XK_Start 0x1008FF1A
-#define XF86XK_Search 0x1008FF1B
-#define XF86XK_AudioRecord 0x1008FF1C
-#define XF86XK_Back 0x1008FF26
-#define XF86XK_Forward 0x1008FF27
-#define XF86XK_Stop 0x1008FF28
-#define XF86XK_Refresh 0x1008FF29
-#define XF86XK_Favorites 0x1008FF30
-#define XF86XK_AudioPause 0x1008FF31
-#define XF86XK_AudioMedia 0x1008FF32
-#define XF86XK_MyComputer 0x1008FF33
-#define XF86XK_OpenURL 0x1008FF38
-#define XF86XK_Launch0 0x1008FF40
-#define XF86XK_Launch1 0x1008FF41
-#define XF86XK_Launch2 0x1008FF42
-#define XF86XK_Launch3 0x1008FF43
-#define XF86XK_Launch4 0x1008FF44
-#define XF86XK_Launch5 0x1008FF45
-#define XF86XK_Launch6 0x1008FF46
-#define XF86XK_Launch7 0x1008FF47
-#define XF86XK_Launch8 0x1008FF48
-#define XF86XK_Launch9 0x1008FF49
-#define XF86XK_LaunchA 0x1008FF4A
-#define XF86XK_LaunchB 0x1008FF4B
-#define XF86XK_LaunchC 0x1008FF4C
-#define XF86XK_LaunchD 0x1008FF4D
-#define XF86XK_LaunchE 0x1008FF4E
-#define XF86XK_LaunchF 0x1008FF4F
+#define XF86XK_MonBrightnessUp 0x1008FF02
+#define XF86XK_MonBrightnessDown 0x1008FF03
+#define XF86XK_KbdLightOnOff 0x1008FF04
+#define XF86XK_KbdBrightnessUp 0x1008FF05
+#define XF86XK_KbdBrightnessDown 0x1008FF06
+#define XF86XK_Standby 0x1008FF10
+#define XF86XK_AudioLowerVolume 0x1008FF11
+#define XF86XK_AudioMute 0x1008FF12
+#define XF86XK_AudioRaiseVolume 0x1008FF13
+#define XF86XK_AudioPlay 0x1008FF14
+#define XF86XK_AudioStop 0x1008FF15
+#define XF86XK_AudioPrev 0x1008FF16
+#define XF86XK_AudioNext 0x1008FF17
+#define XF86XK_HomePage 0x1008FF18
+#define XF86XK_Mail 0x1008FF19
+#define XF86XK_Start 0x1008FF1A
+#define XF86XK_Search 0x1008FF1B
+#define XF86XK_AudioRecord 0x1008FF1C
+#define XF86XK_Calculator 0x1008FF1D
+#define XF86XK_Memo 0x1008FF1E
+#define XF86XK_ToDoList 0x1008FF1F
+#define XF86XK_Calendar 0x1008FF20
+#define XF86XK_PowerDown 0x1008FF21
+#define XF86XK_ContrastAdjust 0x1008FF22
+#define XF86XK_Back 0x1008FF26
+#define XF86XK_Forward 0x1008FF27
+#define XF86XK_Stop 0x1008FF28
+#define XF86XK_Refresh 0x1008FF29
+#define XF86XK_PowerOff 0x1008FF2A
+#define XF86XK_WakeUp 0x1008FF2B
+#define XF86XK_Eject 0x1008FF2C
+#define XF86XK_ScreenSaver 0x1008FF2D
+#define XF86XK_WWW 0x1008FF2E
+#define XF86XK_Sleep 0x1008FF2F
+#define XF86XK_Favorites 0x1008FF30
+#define XF86XK_AudioPause 0x1008FF31
+#define XF86XK_AudioMedia 0x1008FF32
+#define XF86XK_MyComputer 0x1008FF33
+#define XF86XK_LightBulb 0x1008FF35
+#define XF86XK_Shop 0x1008FF36
+#define XF86XK_History 0x1008FF37
+#define XF86XK_OpenURL 0x1008FF38
+#define XF86XK_AddFavorite 0x1008FF39
+#define XF86XK_HotLinks 0x1008FF3A
+#define XF86XK_BrightnessAdjust 0x1008FF3B
+#define XF86XK_Finance 0x1008FF3C
+#define XF86XK_Community 0x1008FF3D
+#define XF86XK_AudioRewind 0x1008FF3E
+#define XF86XK_BackForward 0x1008FF3F
+#define XF86XK_Launch0 0x1008FF40
+#define XF86XK_Launch1 0x1008FF41
+#define XF86XK_Launch2 0x1008FF42
+#define XF86XK_Launch3 0x1008FF43
+#define XF86XK_Launch4 0x1008FF44
+#define XF86XK_Launch5 0x1008FF45
+#define XF86XK_Launch6 0x1008FF46
+#define XF86XK_Launch7 0x1008FF47
+#define XF86XK_Launch8 0x1008FF48
+#define XF86XK_Launch9 0x1008FF49
+#define XF86XK_LaunchA 0x1008FF4A
+#define XF86XK_LaunchB 0x1008FF4B
+#define XF86XK_LaunchC 0x1008FF4C
+#define XF86XK_LaunchD 0x1008FF4D
+#define XF86XK_LaunchE 0x1008FF4E
+#define XF86XK_LaunchF 0x1008FF4F
+#define XF86XK_ApplicationLeft 0x1008FF50
+#define XF86XK_ApplicationRight 0x1008FF51
+#define XF86XK_Book 0x1008FF52
+#define XF86XK_CD 0x1008FF53
+#define XF86XK_Calculater 0x1008FF54
+#define XF86XK_Clear 0x1008FF55
+#define XF86XK_ClearGrab 0x1008FE21
+#define XF86XK_Close 0x1008FF56
+#define XF86XK_Copy 0x1008FF57
+#define XF86XK_Cut 0x1008FF58
+#define XF86XK_Display 0x1008FF59
+#define XF86XK_DOS 0x1008FF5A
+#define XF86XK_Documents 0x1008FF5B
+#define XF86XK_Excel 0x1008FF5C
+#define XF86XK_Explorer 0x1008FF5D
+#define XF86XK_Game 0x1008FF5E
+#define XF86XK_Go 0x1008FF5F
+#define XF86XK_iTouch 0x1008FF60
+#define XF86XK_LogOff 0x1008FF61
+#define XF86XK_Market 0x1008FF62
+#define XF86XK_Meeting 0x1008FF63
+#define XF86XK_MenuKB 0x1008FF65
+#define XF86XK_MenuPB 0x1008FF66
+#define XF86XK_MySites 0x1008FF67
+#define XF86XK_News 0x1008FF69
+#define XF86XK_OfficeHome 0x1008FF6A
+#define XF86XK_Option 0x1008FF6C
+#define XF86XK_Paste 0x1008FF6D
+#define XF86XK_Phone 0x1008FF6E
+#define XF86XK_Reply 0x1008FF72
+#define XF86XK_Reload 0x1008FF73
+#define XF86XK_RotateWindows 0x1008FF74
+#define XF86XK_RotationPB 0x1008FF75
+#define XF86XK_RotationKB 0x1008FF76
+#define XF86XK_Save 0x1008FF77
+#define XF86XK_Send 0x1008FF7B
+#define XF86XK_Spell 0x1008FF7C
+#define XF86XK_SplitScreen 0x1008FF7D
+#define XF86XK_Support 0x1008FF7E
+#define XF86XK_TaskPane 0x1008FF7F
+#define XF86XK_Terminal 0x1008FF80
+#define XF86XK_Tools 0x1008FF81
+#define XF86XK_Travel 0x1008FF82
+#define XF86XK_Video 0x1008FF87
+#define XF86XK_Word 0x1008FF89
+#define XF86XK_Xfer 0x1008FF8A
+#define XF86XK_ZoomIn 0x1008FF8B
+#define XF86XK_ZoomOut 0x1008FF8C
+#define XF86XK_Away 0x1008FF8D
+#define XF86XK_Messenger 0x1008FF8E
+#define XF86XK_WebCam 0x1008FF8F
+#define XF86XK_MailForward 0x1008FF90
+#define XF86XK_Pictures 0x1008FF91
+#define XF86XK_Music 0x1008FF92
+#define XF86XK_Battery 0x1008FF93
+#define XF86XK_Bluetooth 0x1008FF94
+#define XF86XK_WLAN 0x1008FF95
+#define XF86XK_UWB 0x1008FF96
+#define XF86XK_AudioForward 0x1008FF97
+#define XF86XK_AudioRepeat 0x1008FF98
+#define XF86XK_AudioRandomPlay 0x1008FF99
+#define XF86XK_Subtitle 0x1008FF9A
+#define XF86XK_AudioCycleTrack 0x1008FF9B
+#define XF86XK_Time 0x1008FF9F
+#define XF86XK_Select 0x1008FFA0
+#define XF86XK_View 0x1008FFA1
+#define XF86XK_TopMenu 0x1008FFA2
+#define XF86XK_Suspend 0x1008FFA7
+#define XF86XK_Hibernate 0x1008FFA8
+
+
// end of XF86keysyms.h
// Special keys used by Qtopia, mapped into the X11 private keypad range.
@@ -942,10 +1039,8 @@ static const unsigned int KeyTbl[] = {
XK_dead_hook, Qt::Key_Dead_Hook,
XK_dead_horn, Qt::Key_Dead_Horn,
- // Special multimedia keys
- // currently only tested with MS internet keyboard
-
- // browsing keys
+ // Special keys from X.org - This include multimedia keys,
+ // wireless/bluetooth/uwb keys, special launcher keys, etc.
XF86XK_Back, Qt::Key_Back,
XF86XK_Forward, Qt::Key_Forward,
XF86XK_Stop, Qt::Key_Stop,
@@ -955,8 +1050,6 @@ static const unsigned int KeyTbl[] = {
XF86XK_OpenURL, Qt::Key_OpenUrl,
XF86XK_HomePage, Qt::Key_HomePage,
XF86XK_Search, Qt::Key_Search,
-
- // media keys
XF86XK_AudioLowerVolume, Qt::Key_VolumeDown,
XF86XK_AudioMute, Qt::Key_VolumeMute,
XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp,
@@ -965,13 +1058,106 @@ static const unsigned int KeyTbl[] = {
XF86XK_AudioPrev, Qt::Key_MediaPrevious,
XF86XK_AudioNext, Qt::Key_MediaNext,
XF86XK_AudioRecord, Qt::Key_MediaRecord,
-
- // launch keys
XF86XK_Mail, Qt::Key_LaunchMail,
XF86XK_MyComputer, Qt::Key_Launch0,
- XF86XK_Calculator, Qt::Key_Launch1,
+ XF86XK_Calculator, Qt::Key_Calculator,
+ XF86XK_Memo, Qt::Key_Memo,
+ XF86XK_ToDoList, Qt::Key_ToDoList,
+ XF86XK_Calendar, Qt::Key_Calendar,
+ XF86XK_PowerDown, Qt::Key_PowerDown,
+ XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust,
XF86XK_Standby, Qt::Key_Standby,
-
+ XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp,
+ XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown,
+ XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff,
+ XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp,
+ XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown,
+ XF86XK_PowerOff, Qt::Key_PowerOff,
+ XF86XK_WakeUp, Qt::Key_WakeUp,
+ XF86XK_Eject, Qt::Key_Eject,
+ XF86XK_ScreenSaver, Qt::Key_ScreenSaver,
+ XF86XK_WWW, Qt::Key_WWW,
+ XF86XK_Sleep, Qt::Key_Sleep,
+ XF86XK_LightBulb, Qt::Key_LightBulb,
+ XF86XK_Shop, Qt::Key_Shop,
+ XF86XK_History, Qt::Key_History,
+ XF86XK_AddFavorite, Qt::Key_AddFavorite,
+ XF86XK_HotLinks, Qt::Key_HotLinks,
+ XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust,
+ XF86XK_Finance, Qt::Key_Finance,
+ XF86XK_Community, Qt::Key_Community,
+ XF86XK_AudioRewind, Qt::Key_AudioRewind,
+ XF86XK_BackForward, Qt::Key_BackForward,
+ XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft,
+ XF86XK_ApplicationRight, Qt::Key_ApplicationRight,
+ XF86XK_Book, Qt::Key_Book,
+ XF86XK_CD, Qt::Key_CD,
+ XF86XK_Calculater, Qt::Key_Calculator,
+ XF86XK_Clear, Qt::Key_Clear,
+ XF86XK_ClearGrab, Qt::Key_ClearGrab,
+ XF86XK_Close, Qt::Key_Close,
+ XF86XK_Copy, Qt::Key_Copy,
+ XF86XK_Cut, Qt::Key_Cut,
+ XF86XK_Display, Qt::Key_Display,
+ XF86XK_DOS, Qt::Key_DOS,
+ XF86XK_Documents, Qt::Key_Documents,
+ XF86XK_Excel, Qt::Key_Excel,
+ XF86XK_Explorer, Qt::Key_Explorer,
+ XF86XK_Game, Qt::Key_Game,
+ XF86XK_Go, Qt::Key_Go,
+ XF86XK_iTouch, Qt::Key_iTouch,
+ XF86XK_LogOff, Qt::Key_LogOff,
+ XF86XK_Market, Qt::Key_Market,
+ XF86XK_Meeting, Qt::Key_Meeting,
+ XF86XK_MenuKB, Qt::Key_MenuKB,
+ XF86XK_MenuPB, Qt::Key_MenuPB,
+ XF86XK_MySites, Qt::Key_MySites,
+ XF86XK_News, Qt::Key_News,
+ XF86XK_OfficeHome, Qt::Key_OfficeHome,
+ XF86XK_Option, Qt::Key_Option,
+ XF86XK_Paste, Qt::Key_Paste,
+ XF86XK_Phone, Qt::Key_Phone,
+ XF86XK_Reply, Qt::Key_Reply,
+ XF86XK_Reload, Qt::Key_Reload,
+ XF86XK_RotateWindows, Qt::Key_RotateWindows,
+ XF86XK_RotationPB, Qt::Key_RotationPB,
+ XF86XK_RotationKB, Qt::Key_RotationKB,
+ XF86XK_Save, Qt::Key_Save,
+ XF86XK_Send, Qt::Key_Send,
+ XF86XK_Spell, Qt::Key_Spell,
+ XF86XK_SplitScreen, Qt::Key_SplitScreen,
+ XF86XK_Support, Qt::Key_Support,
+ XF86XK_TaskPane, Qt::Key_TaskPane,
+ XF86XK_Terminal, Qt::Key_Terminal,
+ XF86XK_Tools, Qt::Key_Tools,
+ XF86XK_Travel, Qt::Key_Travel,
+ XF86XK_Video, Qt::Key_Video,
+ XF86XK_Word, Qt::Key_Word,
+ XF86XK_Xfer, Qt::Key_Xfer,
+ XF86XK_ZoomIn, Qt::Key_ZoomIn,
+ XF86XK_ZoomOut, Qt::Key_ZoomOut,
+ XF86XK_Away, Qt::Key_Away,
+ XF86XK_Messenger, Qt::Key_Messenger,
+ XF86XK_WebCam, Qt::Key_WebCam,
+ XF86XK_MailForward, Qt::Key_MailForward,
+ XF86XK_Pictures, Qt::Key_Pictures,
+ XF86XK_Music, Qt::Key_Music,
+ XF86XK_Battery, Qt::Key_Battery,
+ XF86XK_Bluetooth, Qt::Key_Bluetooth,
+ XF86XK_WLAN, Qt::Key_WLAN,
+ XF86XK_UWB, Qt::Key_UWB,
+ XF86XK_AudioForward, Qt::Key_AudioForward,
+ XF86XK_AudioRepeat, Qt::Key_AudioRepeat,
+ XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay,
+ XF86XK_Subtitle, Qt::Key_Subtitle,
+ XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack,
+ XF86XK_Time, Qt::Key_Time,
+ XF86XK_Select, Qt::Key_Select,
+ XF86XK_View, Qt::Key_View,
+ XF86XK_TopMenu, Qt::Key_TopMenu,
+ XF86XK_Bluetooth, Qt::Key_Bluetooth,
+ XF86XK_Suspend, Qt::Key_Suspend,
+ XF86XK_Hibernate, Qt::Key_Hibernate,
XF86XK_Launch0, Qt::Key_Launch2,
XF86XK_Launch1, Qt::Key_Launch3,
XF86XK_Launch2, Qt::Key_Launch4,
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index b44ef7fa79..e3af6838e9 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -416,47 +416,139 @@ static const struct {
{ Qt::Key_Menu, QT_TRANSLATE_NOOP("QShortcut", "Menu") },
{ Qt::Key_Help, QT_TRANSLATE_NOOP("QShortcut", "Help") },
- // Multimedia keys
- { Qt::Key_Back, QT_TRANSLATE_NOOP("QShortcut", "Back") },
- { Qt::Key_Forward, QT_TRANSLATE_NOOP("QShortcut", "Forward") },
- { Qt::Key_Stop, QT_TRANSLATE_NOOP("QShortcut", "Stop") },
- { Qt::Key_Refresh, QT_TRANSLATE_NOOP("QShortcut", "Refresh") },
- { Qt::Key_VolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Volume Down") },
- { Qt::Key_VolumeMute, QT_TRANSLATE_NOOP("QShortcut", "Volume Mute") },
- { Qt::Key_VolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Volume Up") },
- { Qt::Key_BassBoost, QT_TRANSLATE_NOOP("QShortcut", "Bass Boost") },
- { Qt::Key_BassUp, QT_TRANSLATE_NOOP("QShortcut", "Bass Up") },
- { Qt::Key_BassDown, QT_TRANSLATE_NOOP("QShortcut", "Bass Down") },
- { Qt::Key_TrebleUp, QT_TRANSLATE_NOOP("QShortcut", "Treble Up") },
- { Qt::Key_TrebleDown, QT_TRANSLATE_NOOP("QShortcut", "Treble Down") },
- { Qt::Key_MediaPlay, QT_TRANSLATE_NOOP("QShortcut", "Media Play") },
- { Qt::Key_MediaStop, QT_TRANSLATE_NOOP("QShortcut", "Media Stop") },
- { Qt::Key_MediaPrevious,QT_TRANSLATE_NOOP("QShortcut", "Media Previous") },
- { Qt::Key_MediaNext, QT_TRANSLATE_NOOP("QShortcut", "Media Next") },
- { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP("QShortcut", "Media Record") },
- { Qt::Key_HomePage, QT_TRANSLATE_NOOP("QShortcut", "Home Page") },
- { Qt::Key_Favorites, QT_TRANSLATE_NOOP("QShortcut", "Favorites") },
- { Qt::Key_Search, QT_TRANSLATE_NOOP("QShortcut", "Search") },
- { Qt::Key_Standby, QT_TRANSLATE_NOOP("QShortcut", "Standby") },
- { Qt::Key_OpenUrl, QT_TRANSLATE_NOOP("QShortcut", "Open URL") },
- { Qt::Key_LaunchMail, QT_TRANSLATE_NOOP("QShortcut", "Launch Mail") },
- { Qt::Key_LaunchMedia, QT_TRANSLATE_NOOP("QShortcut", "Launch Media") },
- { Qt::Key_Launch0, QT_TRANSLATE_NOOP("QShortcut", "Launch (0)") },
- { Qt::Key_Launch1, QT_TRANSLATE_NOOP("QShortcut", "Launch (1)") },
- { Qt::Key_Launch2, QT_TRANSLATE_NOOP("QShortcut", "Launch (2)") },
- { Qt::Key_Launch3, QT_TRANSLATE_NOOP("QShortcut", "Launch (3)") },
- { Qt::Key_Launch4, QT_TRANSLATE_NOOP("QShortcut", "Launch (4)") },
- { Qt::Key_Launch5, QT_TRANSLATE_NOOP("QShortcut", "Launch (5)") },
- { Qt::Key_Launch6, QT_TRANSLATE_NOOP("QShortcut", "Launch (6)") },
- { Qt::Key_Launch7, QT_TRANSLATE_NOOP("QShortcut", "Launch (7)") },
- { Qt::Key_Launch8, QT_TRANSLATE_NOOP("QShortcut", "Launch (8)") },
- { Qt::Key_Launch9, QT_TRANSLATE_NOOP("QShortcut", "Launch (9)") },
- { Qt::Key_LaunchA, QT_TRANSLATE_NOOP("QShortcut", "Launch (A)") },
- { Qt::Key_LaunchB, QT_TRANSLATE_NOOP("QShortcut", "Launch (B)") },
- { Qt::Key_LaunchC, QT_TRANSLATE_NOOP("QShortcut", "Launch (C)") },
- { Qt::Key_LaunchD, QT_TRANSLATE_NOOP("QShortcut", "Launch (D)") },
- { Qt::Key_LaunchE, QT_TRANSLATE_NOOP("QShortcut", "Launch (E)") },
- { Qt::Key_LaunchF, QT_TRANSLATE_NOOP("QShortcut", "Launch (F)") },
+ // Special keys
+ // Includes multimedia, launcher, lan keys ( bluetooth, wireless )
+ // window navigation
+ { Qt::Key_Back, QT_TRANSLATE_NOOP("QShortcut", "Back") },
+ { Qt::Key_Forward, QT_TRANSLATE_NOOP("QShortcut", "Forward") },
+ { Qt::Key_Stop, QT_TRANSLATE_NOOP("QShortcut", "Stop") },
+ { Qt::Key_Refresh, QT_TRANSLATE_NOOP("QShortcut", "Refresh") },
+ { Qt::Key_VolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Volume Down") },
+ { Qt::Key_VolumeMute, QT_TRANSLATE_NOOP("QShortcut", "Volume Mute") },
+ { Qt::Key_VolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Volume Up") },
+ { Qt::Key_BassBoost, QT_TRANSLATE_NOOP("QShortcut", "Bass Boost") },
+ { Qt::Key_BassUp, QT_TRANSLATE_NOOP("QShortcut", "Bass Up") },
+ { Qt::Key_BassDown, QT_TRANSLATE_NOOP("QShortcut", "Bass Down") },
+ { Qt::Key_TrebleUp, QT_TRANSLATE_NOOP("QShortcut", "Treble Up") },
+ { Qt::Key_TrebleDown, QT_TRANSLATE_NOOP("QShortcut", "Treble Down") },
+ { Qt::Key_MediaPlay, QT_TRANSLATE_NOOP("QShortcut", "Media Play") },
+ { Qt::Key_MediaStop, QT_TRANSLATE_NOOP("QShortcut", "Media Stop") },
+ { Qt::Key_MediaPrevious, QT_TRANSLATE_NOOP("QShortcut", "Media Previous") },
+ { Qt::Key_MediaNext, QT_TRANSLATE_NOOP("QShortcut", "Media Next") },
+ { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP("QShortcut", "Media Record") },
+ { Qt::Key_HomePage, QT_TRANSLATE_NOOP("QShortcut", "Home Page") },
+ { Qt::Key_Favorites, QT_TRANSLATE_NOOP("QShortcut", "Favorites") },
+ { Qt::Key_Search, QT_TRANSLATE_NOOP("QShortcut", "Search") },
+ { Qt::Key_Standby, QT_TRANSLATE_NOOP("QShortcut", "Standby") },
+ { Qt::Key_OpenUrl, QT_TRANSLATE_NOOP("QShortcut", "Open URL") },
+ { Qt::Key_LaunchMail, QT_TRANSLATE_NOOP("QShortcut", "Launch Mail") },
+ { Qt::Key_LaunchMedia, QT_TRANSLATE_NOOP("QShortcut", "Launch Media") },
+ { Qt::Key_Launch0, QT_TRANSLATE_NOOP("QShortcut", "Launch (0)") },
+ { Qt::Key_Launch1, QT_TRANSLATE_NOOP("QShortcut", "Launch (1)") },
+ { Qt::Key_Launch2, QT_TRANSLATE_NOOP("QShortcut", "Launch (2)") },
+ { Qt::Key_Launch3, QT_TRANSLATE_NOOP("QShortcut", "Launch (3)") },
+ { Qt::Key_Launch4, QT_TRANSLATE_NOOP("QShortcut", "Launch (4)") },
+ { Qt::Key_Launch5, QT_TRANSLATE_NOOP("QShortcut", "Launch (5)") },
+ { Qt::Key_Launch6, QT_TRANSLATE_NOOP("QShortcut", "Launch (6)") },
+ { Qt::Key_Launch7, QT_TRANSLATE_NOOP("QShortcut", "Launch (7)") },
+ { Qt::Key_Launch8, QT_TRANSLATE_NOOP("QShortcut", "Launch (8)") },
+ { Qt::Key_Launch9, QT_TRANSLATE_NOOP("QShortcut", "Launch (9)") },
+ { Qt::Key_LaunchA, QT_TRANSLATE_NOOP("QShortcut", "Launch (A)") },
+ { Qt::Key_LaunchB, QT_TRANSLATE_NOOP("QShortcut", "Launch (B)") },
+ { Qt::Key_LaunchC, QT_TRANSLATE_NOOP("QShortcut", "Launch (C)") },
+ { Qt::Key_LaunchD, QT_TRANSLATE_NOOP("QShortcut", "Launch (D)") },
+ { Qt::Key_LaunchE, QT_TRANSLATE_NOOP("QShortcut", "Launch (E)") },
+ { Qt::Key_LaunchF, QT_TRANSLATE_NOOP("QShortcut", "Launch (F)") },
+ { Qt::Key_MonBrightnessUp, QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Up") },
+ { Qt::Key_MonBrightnessDown, QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Down") },
+ { Qt::Key_KeyboardLightOnOff, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Light On/Off") },
+ { Qt::Key_KeyboardBrightnessUp, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Up") },
+ { Qt::Key_KeyboardBrightnessDown, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Down") },
+ { Qt::Key_PowerOff, QT_TRANSLATE_NOOP("QShortcut", "Power Off") },
+ { Qt::Key_WakeUp, QT_TRANSLATE_NOOP("QShortcut", "Wake Up") },
+ { Qt::Key_Eject, QT_TRANSLATE_NOOP("QShortcut", "Eject") },
+ { Qt::Key_ScreenSaver, QT_TRANSLATE_NOOP("QShortcut", "Screensaver") },
+ { Qt::Key_WWW, QT_TRANSLATE_NOOP("QShortcut", "WWW") },
+ { Qt::Key_Sleep, QT_TRANSLATE_NOOP("QShortcut", "Sleep") },
+ { Qt::Key_LightBulb, QT_TRANSLATE_NOOP("QShortcut", "LightBulb") },
+ { Qt::Key_Shop, QT_TRANSLATE_NOOP("QShortcut", "Shop") },
+ { Qt::Key_History, QT_TRANSLATE_NOOP("QShortcut", "History") },
+ { Qt::Key_AddFavorite, QT_TRANSLATE_NOOP("QShortcut", "Add Favorite") },
+ { Qt::Key_HotLinks, QT_TRANSLATE_NOOP("QShortcut", "Hot Links") },
+ { Qt::Key_BrightnessAdjust, QT_TRANSLATE_NOOP("QShortcut", "Adjust Brightness") },
+ { Qt::Key_Finance, QT_TRANSLATE_NOOP("QShortcut", "Finance") },
+ { Qt::Key_Community, QT_TRANSLATE_NOOP("QShortcut", "Community") },
+ { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Audio Rewind") },
+ { Qt::Key_BackForward, QT_TRANSLATE_NOOP("QShortcut", "Back Forward") },
+ { Qt::Key_ApplicationLeft, QT_TRANSLATE_NOOP("QShortcut", "Application Left") },
+ { Qt::Key_ApplicationRight, QT_TRANSLATE_NOOP("QShortcut", "Application Right") },
+ { Qt::Key_Book, QT_TRANSLATE_NOOP("QShortcut", "Book") },
+ { Qt::Key_CD, QT_TRANSLATE_NOOP("QShortcut", "CD") },
+ { Qt::Key_Calculator, QT_TRANSLATE_NOOP("QShortcut", "Calculator") },
+ { Qt::Key_Clear, QT_TRANSLATE_NOOP("QShortcut", "Clear") },
+ { Qt::Key_ClearGrab, QT_TRANSLATE_NOOP("QShortcut", "Clear Grab") },
+ { Qt::Key_Close, QT_TRANSLATE_NOOP("QShortcut", "Close") },
+ { Qt::Key_Copy, QT_TRANSLATE_NOOP("QShortcut", "Copy") },
+ { Qt::Key_Cut, QT_TRANSLATE_NOOP("QShortcut", "Cut") },
+ { Qt::Key_Display, QT_TRANSLATE_NOOP("QShortcut", "Display") },
+ { Qt::Key_DOS, QT_TRANSLATE_NOOP("QShortcut", "DOS") },
+ { Qt::Key_Documents, QT_TRANSLATE_NOOP("QShortcut", "Documents") },
+ { Qt::Key_Excel, QT_TRANSLATE_NOOP("QShortcut", "Spreadsheet") },
+ { Qt::Key_Explorer, QT_TRANSLATE_NOOP("QShortcut", "Browser") },
+ { Qt::Key_Game, QT_TRANSLATE_NOOP("QShortcut", "Game") },
+ { Qt::Key_Go, QT_TRANSLATE_NOOP("QShortcut", "Go") },
+ { Qt::Key_iTouch, QT_TRANSLATE_NOOP("QShortcut", "iTouch") },
+ { Qt::Key_LogOff, QT_TRANSLATE_NOOP("QShortcut", "Logoff") },
+ { Qt::Key_Market, QT_TRANSLATE_NOOP("QShortcut", "Market") },
+ { Qt::Key_Meeting, QT_TRANSLATE_NOOP("QShortcut", "Meeting") },
+ { Qt::Key_MenuKB, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Menu") },
+ { Qt::Key_MenuPB, QT_TRANSLATE_NOOP("QShortcut", "Menu PB") },
+ { Qt::Key_MySites, QT_TRANSLATE_NOOP("QShortcut", "My Sites") },
+ { Qt::Key_News, QT_TRANSLATE_NOOP("QShortcut", "News") },
+ { Qt::Key_OfficeHome, QT_TRANSLATE_NOOP("QShortcut", "Home Office") },
+ { Qt::Key_Option, QT_TRANSLATE_NOOP("QShortcut", "Option") },
+ { Qt::Key_Paste, QT_TRANSLATE_NOOP("QShortcut", "Paste") },
+ { Qt::Key_Phone, QT_TRANSLATE_NOOP("QShortcut", "Phone") },
+ { Qt::Key_Reply, QT_TRANSLATE_NOOP("QShortcut", "Reply") },
+ { Qt::Key_Reload, QT_TRANSLATE_NOOP("QShortcut", "Reload") },
+ { Qt::Key_RotateWindows, QT_TRANSLATE_NOOP("QShortcut", "Rotate Windows") },
+ { Qt::Key_RotationPB, QT_TRANSLATE_NOOP("QShortcut", "Rotation PB") },
+ { Qt::Key_RotationKB, QT_TRANSLATE_NOOP("QShortcut", "Rotation KB") },
+ { Qt::Key_Save, QT_TRANSLATE_NOOP("QShortcut", "Save") },
+ { Qt::Key_Send, QT_TRANSLATE_NOOP("QShortcut", "Send") },
+ { Qt::Key_Spell, QT_TRANSLATE_NOOP("QShortcut", "Spellchecker") },
+ { Qt::Key_SplitScreen, QT_TRANSLATE_NOOP("QShortcut", "Split Screen") },
+ { Qt::Key_Support, QT_TRANSLATE_NOOP("QShortcut", "Support") },
+ { Qt::Key_TaskPane, QT_TRANSLATE_NOOP("QShortcut", "Task Panel") },
+ { Qt::Key_Terminal, QT_TRANSLATE_NOOP("QShortcut", "Terminal") },
+ { Qt::Key_Tools, QT_TRANSLATE_NOOP("QShortcut", "Tools") },
+ { Qt::Key_Travel, QT_TRANSLATE_NOOP("QShortcut", "Travel") },
+ { Qt::Key_Video, QT_TRANSLATE_NOOP("QShortcut", "Video") },
+ { Qt::Key_Word, QT_TRANSLATE_NOOP("QShortcut", "Word Processor") },
+ { Qt::Key_Xfer, QT_TRANSLATE_NOOP("QShortcut", "XFer") },
+ { Qt::Key_ZoomIn, QT_TRANSLATE_NOOP("QShortcut", "Zoom In") },
+ { Qt::Key_ZoomOut, QT_TRANSLATE_NOOP("QShortcut", "Zoom Out") },
+ { Qt::Key_Away, QT_TRANSLATE_NOOP("QShortcut", "Away") },
+ { Qt::Key_Messenger, QT_TRANSLATE_NOOP("QShortcut", "Messenger") },
+ { Qt::Key_WebCam, QT_TRANSLATE_NOOP("QShortcut", "WebCam") },
+ { Qt::Key_MailForward, QT_TRANSLATE_NOOP("QShortcut", "Mail Forward") },
+ { Qt::Key_Pictures, QT_TRANSLATE_NOOP("QShortcut", "Pictures") },
+ { Qt::Key_Music, QT_TRANSLATE_NOOP("QShortcut", "Music") },
+ { Qt::Key_Battery, QT_TRANSLATE_NOOP("QShortcut", "Battery") },
+ { Qt::Key_Bluetooth, QT_TRANSLATE_NOOP("QShortcut", "Bluetooth") },
+ { Qt::Key_WLAN, QT_TRANSLATE_NOOP("QShortcut", "Wireless") },
+ { Qt::Key_UWB, QT_TRANSLATE_NOOP("QShortcut", "Ultra Wide Band") },
+ { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Audio Forward") },
+ { Qt::Key_AudioRepeat, QT_TRANSLATE_NOOP("QShortcut", "Audio Repeat") },
+ { Qt::Key_AudioRandomPlay, QT_TRANSLATE_NOOP("QShortcut", "Audio Random Play") },
+ { Qt::Key_Subtitle, QT_TRANSLATE_NOOP("QShortcut", "Subtitle") },
+ { Qt::Key_AudioCycleTrack, QT_TRANSLATE_NOOP("QShortcut", "Audio Cycle Track") },
+ { Qt::Key_Time, QT_TRANSLATE_NOOP("QShortcut", "Time") },
+ { Qt::Key_Select, QT_TRANSLATE_NOOP("QShortcut", "Select") },
+ { Qt::Key_View, QT_TRANSLATE_NOOP("QShortcut", "View") },
+ { Qt::Key_TopMenu, QT_TRANSLATE_NOOP("QShortcut", "Top Menu") },
+ { Qt::Key_Suspend, QT_TRANSLATE_NOOP("QShortcut", "Suspend") },
+ { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") },
// --------------------------------------------------------------
// More consistent namings
@@ -922,9 +1014,12 @@ bool QKeySequence::isEmpty() const
*/
QKeySequence QKeySequence::mnemonic(const QString &text)
{
+ QKeySequence ret;
+
if(qt_sequence_no_mnemonics)
- return QKeySequence();
+ return ret;
+ bool found = false;
int p = 0;
while (p >= 0) {
p = text.indexOf(QLatin1Char('&'), p) + 1;
@@ -933,13 +1028,22 @@ QKeySequence QKeySequence::mnemonic(const QString &text)
if (text.at(p) != QLatin1Char('&')) {
QChar c = text.at(p);
if (c.isPrint()) {
- c = c.toUpper();
- return QKeySequence(c.unicode() + Qt::ALT);
+ if (!found) {
+ c = c.toUpper();
+ ret = QKeySequence(c.unicode() + Qt::ALT);
+#ifdef QT_NO_DEBUG
+ return ret;
+#else
+ found = true;
+ } else {
+ qWarning("QKeySequence::mnemonic: \"%s\" contains multiple occurences of '&'", qPrintable(text));
+#endif
+ }
}
}
p++;
}
- return QKeySequence();
+ return ret;
}
/*!
diff --git a/src/gui/kernel/qlayout.cpp b/src/gui/kernel/qlayout.cpp
index 70cd5a53cb..5d44b3d2a9 100644
--- a/src/gui/kernel/qlayout.cpp
+++ b/src/gui/kernel/qlayout.cpp
@@ -496,6 +496,21 @@ void QLayout::setContentsMargins(int left, int top, int right, int bottom)
}
/*!
+ \since 4.6
+
+ Sets the \a margins to use around the layout.
+
+ By default, QLayout uses the values provided by the style. On
+ most platforms, the margin is 11 pixels in all directions.
+
+ \sa contentsMargins()
+*/
+void QLayout::setContentsMargins(const QMargins &margins)
+{
+ setContentsMargins(margins.left(), margins.top(), margins.right(), margins.bottom());
+}
+
+/*!
\since 4.3
Extracts the left, top, right, and bottom margins used around the
@@ -521,6 +536,23 @@ void QLayout::getContentsMargins(int *left, int *top, int *right, int *bottom) c
}
/*!
+ \since 4.6
+
+ Returns the margins used around the layout.
+
+ By default, QLayout uses the values provided by the style. On
+ most platforms, the margin is 11 pixels in all directions.
+
+ \sa setContentsMargins()
+*/
+QMargins QLayout::contentsMargins() const
+{
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ return QMargins(left, top, right, bottom);
+}
+
+/*!
\since 4.3
Returns the layout's geometry() rectangle, but taking into account the
diff --git a/src/gui/kernel/qlayout.h b/src/gui/kernel/qlayout.h
index 83cbab6cdb..2f302944e1 100644
--- a/src/gui/kernel/qlayout.h
+++ b/src/gui/kernel/qlayout.h
@@ -46,6 +46,7 @@
#include <QtGui/qlayoutitem.h>
#include <QtGui/qsizepolicy.h>
#include <QtCore/qrect.h>
+#include <QtCore/qmargins.h>
#include <limits.h>
@@ -122,7 +123,9 @@ public:
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);
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm
index 7b19a547c3..3e0ba2360d 100644
--- a/src/gui/kernel/qmacgesturerecognizer_mac.mm
+++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm
@@ -53,13 +53,13 @@ QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
{
}
-QGesture *QMacSwipeGestureRecognizer::createGesture(QObject * /*target*/)
+QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/)
{
return new QSwipeGesture;
}
QGestureRecognizer::Result
-QMacSwipeGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
{
if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
@@ -67,7 +67,7 @@ QMacSwipeGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent
case QNativeGestureEvent::Swipe: {
QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
g->setSwipeAngle(ev->angle);
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
break; }
default:
break;
@@ -90,13 +90,13 @@ QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
{
}
-QGesture *QMacPinchGestureRecognizer::createGesture(QObject * /*target*/)
+QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/)
{
return new QPinchGesture;
}
QGestureRecognizer::Result
-QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
{
if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
@@ -106,26 +106,26 @@ QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent
reset(gesture);
g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->position));
g->setCenterPoint(g->startCenterPoint());
- g->setWhatChanged(QPinchGesture::CenterPointChanged);
- return QGestureRecognizer::MaybeGesture | QGestureRecognizer::ConsumeEventHint;
+ g->setChangeFlags(QPinchGesture::CenterPointChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint;
case QNativeGestureEvent::Rotate: {
g->setLastScaleFactor(g->scaleFactor());
g->setLastRotationAngle(g->rotationAngle());
g->setRotationAngle(g->rotationAngle() + ev->percentage);
- g->setWhatChanged(QPinchGesture::RotationAngleChanged);
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
- break;
+ g->setChangeFlags(QPinchGesture::RotationAngleChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
}
case QNativeGestureEvent::Zoom:
g->setLastScaleFactor(g->scaleFactor());
g->setLastRotationAngle(g->rotationAngle());
- g->setScaleFactor(g->scaleFactor() + ev->percentage);
- g->setWhatChanged(QPinchGesture::ScaleFactorChanged);
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
- break;
+ g->setScaleFactor(g->scaleFactor() * (1 + ev->percentage));
+ g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
case QNativeGestureEvent::GestureEnd:
- return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint;
- break;
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
default:
break;
}
@@ -137,7 +137,8 @@ QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent
void QMacPinchGestureRecognizer::reset(QGesture *gesture)
{
QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
- g->setWhatChanged(0);
+ g->setChangeFlags(0);
+ g->setTotalChangeFlags(0);
g->setScaleFactor(1.0f);
g->setTotalScaleFactor(1.0f);
g->setLastScaleFactor(1.0f);
@@ -158,7 +159,7 @@ QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
{
}
-QGesture *QMacPanGestureRecognizer::createGesture(QObject *target)
+QGesture *QMacPanGestureRecognizer::create(QObject *target)
{
if (!target)
return new QPanGesture;
@@ -172,7 +173,7 @@ QGesture *QMacPanGestureRecognizer::createGesture(QObject *target)
}
QGestureRecognizer::Result
-QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent *event)
+QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
{
const int panBeginDelay = 300;
const int panBeginRadius = 3;
@@ -185,10 +186,9 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
if (ev->touchPoints().size() == 1) {
reset(gesture);
_startPos = QCursor::pos();
- _lastPos = _startPos;
_panTimer.start(panBeginDelay, target);
_panCanceled = false;
- return QGestureRecognizer::MaybeGesture;
+ return QGestureRecognizer::MayBeGesture;
}
break;}
case QEvent::TouchEnd: {
@@ -197,7 +197,7 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
if (ev->touchPoints().size() == 1)
- return QGestureRecognizer::GestureFinished;
+ return QGestureRecognizer::FinishGesture;
break;}
case QEvent::TouchUpdate: {
if (_panCanceled)
@@ -212,23 +212,21 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
if ((p - _startPos).manhattanLength() > panBeginRadius) {
_panCanceled = true;
_panTimer.stop();
- return QGestureRecognizer::NotGesture;
+ return QGestureRecognizer::CancelGesture;
}
} else {
const QPointF p = QCursor::pos();
- const QPointF posOffset = p - _lastPos;
+ const QPointF posOffset = p - _startPos;
g->setLastOffset(g->offset());
- g->setOffset(QSizeF(posOffset.x(), posOffset.y()));
- g->setTotalOffset(g->lastOffset() + g->offset());
- _lastPos = p;
- return QGestureRecognizer::GestureTriggered;
+ g->setOffset(QPointF(posOffset.x(), posOffset.y()));
+ return QGestureRecognizer::TriggerGesture;
}
} else if (_panTimer.isActive()) {
// I only want to cancel the pan if the user is pressing
// more than one finger, and the pan hasn't started yet:
_panCanceled = true;
_panTimer.stop();
- return QGestureRecognizer::NotGesture;
+ return QGestureRecognizer::CancelGesture;
}
break;}
case QEvent::Timer: {
@@ -239,8 +237,7 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
break;
// Begin new pan session!
_startPos = QCursor::pos();
- _lastPos = _startPos;
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
}
break; }
default:
@@ -254,11 +251,9 @@ void QMacPanGestureRecognizer::reset(QGesture *gesture)
{
QPanGesture *g = static_cast<QPanGesture *>(gesture);
_startPos = QPointF();
- _lastPos = QPointF();
_panCanceled = true;
- g->setOffset(QSizeF(0, 0));
- g->setLastOffset(QSizeF(0, 0));
- g->setTotalOffset(QSizeF(0, 0));
+ g->setOffset(QPointF(0, 0));
+ g->setLastOffset(QPointF(0, 0));
g->setAcceleration(qreal(1));
QGestureRecognizer::reset(gesture);
}
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac_p.h b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
index bdc2e081a9..2dac56a833 100644
--- a/src/gui/kernel/qmacgesturerecognizer_mac_p.h
+++ b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
@@ -64,8 +64,8 @@ class QMacSwipeGestureRecognizer : public QGestureRecognizer
public:
QMacSwipeGestureRecognizer();
- QGesture *createGesture(QObject *target);
- QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
};
@@ -74,8 +74,8 @@ class QMacPinchGestureRecognizer : public QGestureRecognizer
public:
QMacPinchGestureRecognizer();
- QGesture *createGesture(QObject *target);
- QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
};
@@ -86,12 +86,11 @@ class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
public:
QMacPanGestureRecognizer();
- QGesture *createGesture(QObject *target);
- QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
private:
QPointF _startPos;
- QPointF _lastPos;
QBasicTimer _panTimer;
bool _panCanceled;
};
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 1214f08180..775d773df5 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -48,6 +48,7 @@
#include "private/qsoftkeymanager_p.h"
#include "private/qobject_p.h"
+#ifndef QT_NO_SOFTKEYMANAGER
QT_BEGIN_NAMESPACE
#ifdef Q_WS_S60
@@ -125,7 +126,6 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act
break;
}
action->setSoftKeyRole(softKeyRole);
- action->setEnabled(actionWidget->isEnabled());
return action;
}
@@ -137,12 +137,21 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act
*/
QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget)
{
+#ifndef QT_NO_ACTION
QScopedPointer<QAction> action(createAction(standardKey, actionWidget));
connect(action.data(), SIGNAL(triggered()), QSoftKeyManager::instance(), SLOT(sendKeyEvent()));
-
+ connect(action.data(), SIGNAL(destroyed(QObject*)), QSoftKeyManager::instance(), SLOT(cleanupHash(QObject*)));
QSoftKeyManager::instance()->d_func()->keyedActions.insert(action.data(), key);
return action.take();
+#endif //QT_NO_ACTION
+}
+
+void QSoftKeyManager::cleanupHash(QObject* obj)
+{
+ Q_D(QSoftKeyManager);
+ QAction *action = qobject_cast<QAction*>(obj);
+ d->keyedActions.remove(action);
}
void QSoftKeyManager::sendKeyEvent()
@@ -168,6 +177,7 @@ void QSoftKeyManager::updateSoftKeys()
bool QSoftKeyManager::event(QEvent *e)
{
+#ifndef QT_NO_ACTION
if (e->type() == QEvent::UpdateSoftKeys) {
QList<QAction*> softKeys;
QWidget *source = QApplication::focusWidget();
@@ -193,24 +203,34 @@ bool QSoftKeyManager::event(QEvent *e)
QSoftKeyManagerPrivate::updateSoftKeys_sys(softKeys);
return true;
}
+#endif //QT_NO_ACTION
return false;
}
#ifdef Q_WS_S60
void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
{
+ // lets not update softkeys if s60 native dialog or menu is shown
+ if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog())
+ return;
+
CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer();
+ nativeContainer->DrawableWindow()->SetOrdinalPosition(0);
nativeContainer->DrawableWindow()->SetPointerCapturePriority(1); //keep softkeys available in modal dialog
- QT_TRAP_THROWING(nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS));
+ nativeContainer->DrawableWindow()->SetFaded(EFalse, RWindowTreeNode::EFadeIncludeChildren);
int position = -1;
- int command;
bool needsExitButton = true;
+ QT_TRAP_THROWING(
+ //Using -1 instead of EAknSoftkeyEmpty to avoid flickering.
+ nativeContainer->SetCommandL(0, -1, KNullDesC);
+ nativeContainer->SetCommandL(2, -1, KNullDesC);
+ );
for (int index = 0; index < softkeys.count(); index++) {
const QAction* softKeyAction = softkeys.at(index);
switch (softKeyAction->softKeyRole()) {
- // Positive Actions go on LSK
+ // Positive Actions on the LSK
case QAction::PositiveSoftKey:
position = 0;
break;
@@ -226,7 +246,7 @@ void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
break;
}
- command = (softKeyAction->objectName().contains("_q_menuSoftKeyAction"))
+ int command = (softKeyAction->objectName().contains("_q_menuSoftKeyAction"))
? EAknSoftkeyOptions
: s60CommandStart + index;
@@ -238,8 +258,13 @@ void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
}
}
- if (needsExitButton)
- QT_TRAP_THROWING(nativeContainer->SetCommandL(2, EAknSoftkeyExit, qt_QString2TPtrC(QSoftKeyManager::tr("Exit"))));
+ const Qt::WindowType sourceWindowType = QSoftKeyManagerPrivate::softKeySource
+ ? QSoftKeyManagerPrivate::softKeySource->window()->windowType()
+ : Qt::Widget;
+
+ if (needsExitButton && sourceWindowType != Qt::Dialog && sourceWindowType != Qt::Popup)
+ QT_TRAP_THROWING(
+ nativeContainer->SetCommandL(2, EAknSoftkeyExit, qt_QString2TPtrC(QSoftKeyManager::tr("Exit"))));
nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation
}
@@ -253,7 +278,8 @@ bool QSoftKeyManager::handleCommand(int command)
QAction *action = softKeys.at(i);
if (action->softKeyRole() != QAction::NoSoftKey) {
if (j == index) {
- if (action->isEnabled()) {
+ QWidget *parent = action->parentWidget();
+ if (parent && parent->isEnabled()) {
action->activate(QAction::Trigger);
return true;
}
@@ -275,4 +301,4 @@ void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &)
#endif
QT_END_NAMESPACE
-
+#endif //QT_NO_SOFTKEYMANAGER
diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h
index b455445ced..796e080d7d 100644
--- a/src/gui/kernel/qsoftkeymanager_p.h
+++ b/src/gui/kernel/qsoftkeymanager_p.h
@@ -58,6 +58,7 @@
QT_BEGIN_HEADER
+#ifndef QT_NO_SOFTKEYMANAGER
QT_BEGIN_NAMESPACE
class QSoftKeyManagerPrivate;
@@ -96,10 +97,12 @@ protected:
Q_DISABLE_COPY(QSoftKeyManager)
private Q_SLOTS:
+ void cleanupHash(QObject* obj);
void sendKeyEvent();
};
QT_END_NAMESPACE
+#endif //QT_NO_SOFTKEYMANAGER
QT_END_HEADER
diff --git a/src/gui/kernel/qsound_s60.cpp b/src/gui/kernel/qsound_s60.cpp
index 352580e57c..af0fae60ed 100644
--- a/src/gui/kernel/qsound_s60.cpp
+++ b/src/gui/kernel/qsound_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -60,13 +60,13 @@ class QAuServerS60;
class QAuBucketS60 : public QAuBucket, public MMdaAudioPlayerCallback
{
public:
- QAuBucketS60( QAuServerS60 *server, QSound *sound);
+ QAuBucketS60(QAuServerS60 *server, QSound *sound);
~QAuBucketS60();
void play();
void stop();
- inline QSound* sound() const { return m_sound; }
+ inline QSound *sound() const { return m_sound; }
public: // from MMdaAudioPlayerCallback
void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration);
@@ -77,88 +77,106 @@ private:
QAuServerS60 *m_server;
bool m_prepared;
bool m_playCalled;
- CMdaAudioPlayerUtility* m_playUtility;
+ CMdaAudioPlayerUtility *m_playUtility;
};
class QAuServerS60 : public QAuServer
{
public:
- QAuServerS60( QObject* parent );
+ QAuServerS60(QObject *parent);
- void init( QSound* s )
+ void init(QSound *s)
{
- QAuBucketS60 *bucket = new QAuBucketS60( this, s );
- setBucket( s, bucket );
+ QAuBucketS60 *bucket = new QAuBucketS60(this, s);
+ setBucket(s, bucket);
}
- void play( QSound* s )
+ void play(QSound *s)
{
- bucket( s )->play();
+ bucket(s)->play();
}
- void stop( QSound* s )
+ void stop(QSound *s)
{
- bucket( s )->stop();
+ bucket(s)->stop();
}
bool okay() { return true; }
+ void play(const QString& filename);
+
protected:
- void playCompleted(QAuBucketS60* bucket, int error)
- {
- QSound *sound = bucket->sound();
- if(!error) {
- // We need to handle repeats by ourselves, since with Symbian API we don't
- // know how many loops have been played when user asks it
- if( decLoop( sound ) ) {
- play( sound );
- }
- } else {
- // We don't have a way to inform about errors -> just decrement loops
- // in order that QSound::isFinished will return true;
- while(decLoop(sound)) {}
- }
- }
+ void playCompleted(QAuBucketS60 *bucket, int error);
protected:
- QAuBucketS60* bucket( QSound *s )
+ QAuBucketS60 *bucket(QSound *s)
{
- return (QAuBucketS60*)QAuServer::bucket( s );
+ return (QAuBucketS60 *)QAuServer::bucket( s );
}
friend class QAuBucketS60;
+ // static QSound::play(filename) cannot be stopped, meaning that playCompleted
+ // will get always called and QSound gets removed form this list.
+ QList<QSound *> staticPlayingSounds;
};
-QAuServerS60::QAuServerS60(QObject* parent) :
+QAuServerS60::QAuServerS60(QObject *parent) :
QAuServer(parent)
{
setObjectName(QLatin1String("QAuServerS60"));
}
+void QAuServerS60::play(const QString& filename)
+{
+ QSound *s = new QSound(filename);
+ staticPlayingSounds.append(s);
+ play(s);
+}
+
+void QAuServerS60::playCompleted(QAuBucketS60 *bucket, int error)
+{
+ QSound *sound = bucket->sound();
+ if (!error) {
+ // We need to handle repeats by ourselves, since with Symbian API we don't
+ // know how many loops have been played when user asks it
+ if (decLoop(sound)) {
+ play(sound);
+ } else {
+ if (staticPlayingSounds.removeAll(sound))
+ delete sound;
+ }
+ } else {
+ // We don't have a way to inform about errors -> just decrement loops
+ // in order that QSound::isFinished will return true;
+ while (decLoop(sound)) {}
+ if (staticPlayingSounds.removeAll(sound))
+ delete sound;
+ }
+}
-QAuServer* qt_new_audio_server()
+QAuServer *qt_new_audio_server()
{
return new QAuServerS60(qApp);
}
-QAuBucketS60::QAuBucketS60( QAuServerS60 *server, QSound *sound )
- : m_sound( sound ), m_server( server ), m_prepared(false), m_playCalled(false)
+QAuBucketS60::QAuBucketS60(QAuServerS60 *server, QSound *sound)
+ : m_sound(sound), m_server(server), m_prepared(false), m_playCalled(false)
{
- QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath();
+ QString filepath = QFileInfo(m_sound->fileName()).absoluteFilePath();
filepath = QDir::toNativeSeparators(filepath);
TPtrC filepathPtr(qt_QString2TPtrC(filepath));
TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this);
m_playUtility->OpenFileL(filepathPtr));
- if(err){
+ if (err) {
m_server->playCompleted(this, err);
}
}
void QAuBucketS60::play()
{
- if(m_prepared) {
+ if (m_prepared) {
// OpenFileL call is completed we can start playing immediately
m_playUtility->Play();
} else {
@@ -180,11 +198,11 @@ void QAuBucketS60::MapcPlayComplete(TInt aError)
void QAuBucketS60::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/)
{
- if(aError) {
+ if (aError) {
m_server->playCompleted(this, aError);
} else {
m_prepared = true;
- if(m_playCalled){
+ if (m_playCalled){
play();
}
}
@@ -192,7 +210,7 @@ void QAuBucketS60::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds
QAuBucketS60::~QAuBucketS60()
{
- if(m_playUtility){
+ if (m_playUtility){
m_playUtility->Stop();
m_playUtility->Close();
}
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index dfc349965b..6b0441bd8d 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -44,6 +44,8 @@
#include "qgesture_p.h"
#include "qevent.h"
#include "qwidget.h"
+#include "qabstractscrollarea.h"
+#include "qdebug.h"
QT_BEGIN_NAMESPACE
@@ -51,29 +53,35 @@ QPanGestureRecognizer::QPanGestureRecognizer()
{
}
-QGesture *QPanGestureRecognizer::createGesture(QObject *target)
+QGesture *QPanGestureRecognizer::create(QObject *target)
{
if (target && target->isWidgetType()) {
+#if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
+ // for scroll areas on Windows we want to use native gestures instead
+ if (!qobject_cast<QAbstractScrollArea *>(target->parent()))
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+#else
static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+#endif
}
return new QPanGesture;
}
-QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event)
+QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
{
- QPanGesture *q = static_cast<QPanGesture*>(state);
+ QPanGesture *q = static_cast<QPanGesture *>(state);
QPanGesturePrivate *d = q->d_func();
- const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
QGestureRecognizer::Result result;
-
switch (event->type()) {
case QEvent::TouchBegin: {
- result = QGestureRecognizer::MaybeGesture;
+ result = QGestureRecognizer::MayBeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
- d->lastPosition = p.pos().toPoint();
- d->lastOffset = d->totalOffset = d->offset = QSize();
+ d->lastOffset = d->offset = QPointF();
break;
}
case QEvent::TouchEnd: {
@@ -83,13 +91,12 @@ QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, Q
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
d->lastOffset = d->offset;
d->offset =
- QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
- p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
- d->totalOffset += d->offset;
+ QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
+ p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
}
- result = QGestureRecognizer::GestureFinished;
+ result = QGestureRecognizer::FinishGesture;
} else {
- result = QGestureRecognizer::NotGesture;
+ result = QGestureRecognizer::CancelGesture;
}
break;
}
@@ -99,14 +106,13 @@ QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, Q
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
d->lastOffset = d->offset;
d->offset =
- QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
- p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
- d->totalOffset += d->offset;
- if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 ||
- d->totalOffset.width() < -10 || d->totalOffset.height() < -10) {
- result = QGestureRecognizer::GestureTriggered;
+ QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
+ p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
+ if (d->offset.x() > 10 || d->offset.y() > 10 ||
+ d->offset.x() < -10 || d->offset.y() < -10) {
+ result = QGestureRecognizer::TriggerGesture;
} else {
- result = QGestureRecognizer::MaybeGesture;
+ result = QGestureRecognizer::MayBeGesture;
}
}
break;
@@ -128,109 +134,433 @@ void QPanGestureRecognizer::reset(QGesture *state)
QPanGesture *pan = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = pan->d_func();
- d->totalOffset = d->lastOffset = d->offset = QSizeF();
- d->lastPosition = QPoint();
+ d->lastOffset = d->offset = QPointF();
d->acceleration = 0;
-//#if defined(QT_MAC_USE_COCOA)
-// d->singleTouchPanTimer.stop();
-// d->prevMousePos = QPointF(0, 0);
-//#endif
-
QGestureRecognizer::reset(state);
}
-/*! \internal */
-/*
-bool QPanGestureRecognizer::event(QEvent *event)
+
+//
+// QPinchGestureRecognizer
+//
+
+QPinchGestureRecognizer::QPinchGestureRecognizer()
+{
+}
+
+QGesture *QPinchGestureRecognizer::create(QObject *target)
{
-#if defined(QT_MAC_USE_COCOA)
- Q_D(QPanGesture);
- if (event->type() == QEvent::Timer) {
- const QTimerEvent *te = static_cast<QTimerEvent *>(event);
- if (te->timerId() == d->singleTouchPanTimer.timerId()) {
- d->singleTouchPanTimer.stop();
- updateState(Qt::GestureStarted);
- }
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
}
-#endif
+ return new QPinchGesture;
+}
+
+QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QPinchGesture *q = static_cast<QPinchGesture *>(state);
+ QPinchGesturePrivate *d = q->d_func();
- bool consume = false;
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
-#if defined(Q_WS_WIN)
-#elif defined(QT_MAC_USE_COCOA)
- // The following implements single touch
- // panning on Mac:
- const int panBeginDelay = 300;
- const int panBeginRadius = 3;
- const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ QGestureRecognizer::Result result;
switch (event->type()) {
case QEvent::TouchBegin: {
- if (ev->touchPoints().size() == 1) {
- d->delayManager->setEnabled(true);
- consume = d->delayManager->append(d->gestureTarget, *event);
- d->lastPosition = QCursor::pos();
- d->singleTouchPanTimer.start(panBeginDelay, this);
+ result = QGestureRecognizer::MayBeGesture;
+ break;
+ }
+ case QEvent::TouchEnd: {
+ if (q->state() != Qt::NoGesture) {
+ result = QGestureRecognizer::FinishGesture;
+ } else {
+ result = QGestureRecognizer::CancelGesture;
}
- break;}
+ break;
+ }
+ case QEvent::TouchUpdate: {
+ d->changeFlags = 0;
+ if (ev->touchPoints().size() == 2) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+
+ d->hotSpot = p1.screenPos();
+ d->isHotSpotSet = true;
+
+ if (d->isNewSequence) {
+ d->startPosition[0] = p1.screenPos();
+ d->startPosition[1] = p2.screenPos();
+ }
+ QLineF line(p1.screenPos(), p2.screenPos());
+ QLineF tmp(line);
+ tmp.setLength(line.length() / 2.);
+ QPointF centerPoint = tmp.p2();
+
+ d->lastCenterPoint = d->centerPoint;
+ d->centerPoint = centerPoint;
+ d->changeFlags |= QPinchGesture::CenterPointChanged;
+
+ const qreal scaleFactor =
+ QLineF(p1.screenPos(), p2.screenPos()).length()
+ / QLineF(d->startPosition[0], d->startPosition[1]).length();
+ if (d->isNewSequence) {
+ d->lastScaleFactor = scaleFactor;
+ } else {
+ d->lastScaleFactor = d->scaleFactor;
+ }
+ d->scaleFactor = scaleFactor;
+ d->totalScaleFactor += d->scaleFactor - d->lastScaleFactor;
+ d->changeFlags |= QPinchGesture::ScaleFactorChanged;
+
+ qreal angle = QLineF(p1.screenPos(), p2.screenPos()).angle();
+ if (angle > 180)
+ angle -= 360;
+ qreal startAngle = QLineF(p1.startScreenPos(), p2.startScreenPos()).angle();
+ if (startAngle > 180)
+ startAngle -= 360;
+ const qreal rotationAngle = startAngle - angle;
+ if (d->isNewSequence)
+ d->lastRotationAngle = rotationAngle;
+ else
+ d->lastRotationAngle = d->rotationAngle;
+ d->rotationAngle = rotationAngle;
+ d->totalRotationAngle += d->rotationAngle - d->lastRotationAngle;
+ d->changeFlags |= QPinchGesture::RotationAngleChanged;
+
+ d->totalChangeFlags |= d->changeFlags;
+ d->isNewSequence = false;
+ result = QGestureRecognizer::TriggerGesture;
+ } else {
+ d->isNewSequence = true;
+ if (q->state() == Qt::NoGesture)
+ result = QGestureRecognizer::Ignore;
+ else
+ result = QGestureRecognizer::FinishGesture;
+ }
+ break;
+ }
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ result = QGestureRecognizer::Ignore;
+ break;
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QPinchGestureRecognizer::reset(QGesture *state)
+{
+ QPinchGesture *pinch = static_cast<QPinchGesture *>(state);
+ QPinchGesturePrivate *d = pinch->d_func();
+
+ d->totalChangeFlags = d->changeFlags = 0;
+
+ d->startCenterPoint = d->lastCenterPoint = d->centerPoint = QPointF();
+ d->totalScaleFactor = d->lastScaleFactor = d->scaleFactor = 0;
+ d->totalRotationAngle = d->lastRotationAngle = d->rotationAngle = 0;
+
+ d->isNewSequence = true;
+ d->startPosition[0] = d->startPosition[1] = QPointF();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QSwipeGestureRecognizer
+//
+
+QSwipeGestureRecognizer::QSwipeGestureRecognizer()
+{
+}
+
+QGesture *QSwipeGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ return new QSwipeGesture;
+}
+
+QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
+ QSwipeGesturePrivate *d = q->d_func();
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+
+ QGestureRecognizer::Result result;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ d->speed = 1;
+ d->time = QTime::currentTime();
+ d->started = true;
+ result = QGestureRecognizer::MayBeGesture;
+ break;
+ }
case QEvent::TouchEnd: {
- d->delayManager->setEnabled(false);
- if (state() != Qt::NoGesture) {
- updateState(Qt::GestureFinished);
- consume = true;
- d->delayManager->clear();
+ if (q->state() != Qt::NoGesture) {
+ result = QGestureRecognizer::FinishGesture;
} else {
- d->delayManager->replay();
+ result = QGestureRecognizer::CancelGesture;
}
- reset();
- break;}
+ break;
+ }
case QEvent::TouchUpdate: {
- consume = d->delayManager->append(d->gestureTarget, *event);
- if (ev->touchPoints().size() == 1) {
- if (state() == Qt::NoGesture) {
- // INVARIANT: The singleTouchTimer has still not fired.
- // Lets check if the user moved his finger so much from
- // the starting point that it makes sense to cancel:
- const QPointF startPos = ev->touchPoints().at(0).startPos().toPoint();
- const QPointF p = ev->touchPoints().at(0).pos().toPoint();
- if ((startPos - p).manhattanLength() > panBeginRadius) {
- d->delayManager->replay();
- consume = false;
- reset();
- } else {
- d->lastPosition = QCursor::pos();
+ if (!d->started)
+ result = QGestureRecognizer::CancelGesture;
+ else if (ev->touchPoints().size() == 3) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ QTouchEvent::TouchPoint p3 = ev->touchPoints().at(2);
+
+ if (d->lastPositions[0].isNull()) {
+ d->lastPositions[0] = p1.startScreenPos().toPoint();
+ d->lastPositions[1] = p2.startScreenPos().toPoint();
+ d->lastPositions[2] = p3.startScreenPos().toPoint();
+ }
+ d->hotSpot = p1.screenPos();
+ d->isHotSpotSet = true;
+
+ int xDistance = (p1.screenPos().x() - d->lastPositions[0].x() +
+ p2.screenPos().x() - d->lastPositions[1].x() +
+ p3.screenPos().x() - d->lastPositions[2].x()) / 3;
+ int yDistance = (p1.screenPos().y() - d->lastPositions[0].y() +
+ p2.screenPos().y() - d->lastPositions[1].y() +
+ p3.screenPos().y() - d->lastPositions[2].y()) / 3;
+
+ const int distance = xDistance >= yDistance ? xDistance : yDistance;
+ int elapsedTime = d->time.msecsTo(QTime::currentTime());
+ if (!elapsedTime)
+ elapsedTime = 1;
+ d->speed = 0.9 * d->speed + distance / elapsedTime;
+ d->time = QTime::currentTime();
+ d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle();
+
+ static const int MoveThreshold = 50;
+ if (xDistance > MoveThreshold || yDistance > MoveThreshold) {
+ // measure the distance to check if the direction changed
+ d->lastPositions[0] = p1.screenPos().toPoint();
+ d->lastPositions[1] = p2.screenPos().toPoint();
+ d->lastPositions[2] = p3.screenPos().toPoint();
+ QSwipeGesture::SwipeDirection horizontal =
+ xDistance > 0 ? QSwipeGesture::Right : QSwipeGesture::Left;
+ QSwipeGesture::SwipeDirection vertical =
+ yDistance > 0 ? QSwipeGesture::Down : QSwipeGesture::Up;
+ if (d->verticalDirection == QSwipeGesture::NoDirection)
+ d->verticalDirection = vertical;
+ if (d->horizontalDirection == QSwipeGesture::NoDirection)
+ d->horizontalDirection = horizontal;
+ if (d->verticalDirection != vertical || d->horizontalDirection != horizontal) {
+ // the user has changed the direction!
+ result = QGestureRecognizer::CancelGesture;
}
+ result = QGestureRecognizer::TriggerGesture;
} else {
- d->delayManager->clear();
- QPointF mousePos = QCursor::pos();
- QPointF dist = mousePos - d->lastPosition;
- d->lastPosition = mousePos;
- d->lastOffset = d->offset;
- d->offset = QSizeF(dist.x(), dist.y());
- d->totalOffset += d->offset;
- updateState(Qt::GestureUpdated);
+ if (q->state() != Qt::NoGesture)
+ result = QGestureRecognizer::TriggerGesture;
+ else
+ result = QGestureRecognizer::MayBeGesture;
+ }
+ } else if (ev->touchPoints().size() > 3) {
+ result = QGestureRecognizer::CancelGesture;
+ } else { // less than 3 touch points
+ if (d->started && (ev->touchPointStates() & Qt::TouchPointPressed))
+ result = QGestureRecognizer::CancelGesture;
+ else if (d->started)
+ result = QGestureRecognizer::Ignore;
+ else
+ result = QGestureRecognizer::MayBeGesture;
+ }
+ break;
+ }
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ result = QGestureRecognizer::Ignore;
+ break;
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QSwipeGestureRecognizer::reset(QGesture *state)
+{
+ QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
+ QSwipeGesturePrivate *d = q->d_func();
+
+ d->verticalDirection = d->horizontalDirection = QSwipeGesture::NoDirection;
+ d->swipeAngle = 0;
+
+ d->lastPositions[0] = d->lastPositions[1] = d->lastPositions[2] = QPoint();
+ d->started = false;
+ d->speed = 0;
+ d->time = QTime();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QTapGestureRecognizer
+//
+
+QTapGestureRecognizer::QTapGestureRecognizer()
+{
+}
+
+QGesture *QTapGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ return new QTapGesture;
+}
+
+QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QTapGesture *q = static_cast<QTapGesture *>(state);
+ QTapGesturePrivate *d = q->d_func();
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+
+ QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ d->position = ev->touchPoints().at(0).pos();
+ result = QGestureRecognizer::TriggerGesture;
+ break;
+ }
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd: {
+ if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) {
+ QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
+ QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
+ enum { TapRadius = 40 };
+ if (delta.manhattanLength() <= TapRadius) {
+ if (event->type() == QEvent::TouchEnd)
+ result = QGestureRecognizer::FinishGesture;
+ else
+ result = QGestureRecognizer::TriggerGesture;
}
- } else if (state() == Qt::NoGesture) {
- d->delayManager->replay();
- consume = false;
- reset();
}
- break;}
+ break;
+ }
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
- if (d->delayManager->isEnabled())
- consume = d->delayManager->append(d->gestureTarget, *event);
+ result = QGestureRecognizer::Ignore;
break;
default:
- return false;
+ result = QGestureRecognizer::Ignore;
+ break;
}
-#else
- Q_UNUSED(event);
-#endif
- return QGestureRecognizer::Ignore;
+ return result;
+}
+
+void QTapGestureRecognizer::reset(QGesture *state)
+{
+ QTapGesture *q = static_cast<QTapGesture *>(state);
+ QTapGesturePrivate *d = q->d_func();
+
+ d->position = QPointF();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QTapAndHoldGestureRecognizer
+//
+
+QTapAndHoldGestureRecognizer::QTapAndHoldGestureRecognizer()
+{
+}
+
+QGesture *QTapAndHoldGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ return new QTapAndHoldGesture;
+}
+
+QGestureRecognizer::Result
+QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object,
+ QEvent *event)
+{
+ QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
+ QTapAndHoldGesturePrivate *d = q->d_func();
+
+ if (object == state && event->type() == QEvent::Timer) {
+ q->killTimer(d->timerId);
+ d->timerId = 0;
+ return QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint;
+ }
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+
+ QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;
+
+ enum { TimerInterval = 2000 };
+ enum { TapRadius = 40 };
+
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ d->position = ev->touchPoints().at(0).pos();
+ if (d->timerId)
+ q->killTimer(d->timerId);
+ d->timerId = q->startTimer(TimerInterval);
+ result = QGestureRecognizer::TriggerGesture;
+ break;
+ case QEvent::TouchEnd:
+ if (d->timerId)
+ result = QGestureRecognizer::CancelGesture;
+ else
+ result = QGestureRecognizer::FinishGesture;
+ break;
+ case QEvent::TouchUpdate:
+ if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) {
+ QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
+ QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
+ if (delta.manhattanLength() <= TapRadius)
+ result = QGestureRecognizer::TriggerGesture;
+ }
+ break;
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ result = QGestureRecognizer::Ignore;
+ break;
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QTapAndHoldGestureRecognizer::reset(QGesture *state)
+{
+ QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
+ QTapAndHoldGesturePrivate *d = q->d_func();
+
+ d->position = QPointF();
+ if (d->timerId)
+ q->killTimer(d->timerId);
+ d->timerId = 0;
+
+ QGestureRecognizer::reset(state);
}
- */
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h
index fec5c2fbd9..8fea2bc30d 100644
--- a/src/gui/kernel/qstandardgestures_p.h
+++ b/src/gui/kernel/qstandardgestures_p.h
@@ -63,9 +63,48 @@ class QPanGestureRecognizer : public QGestureRecognizer
public:
QPanGestureRecognizer();
- QGesture *createGesture(QObject *target);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QPinchGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QPinchGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QSwipeGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QSwipeGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QTapGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QTapGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QTapAndHoldGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QTapAndHoldGestureRecognizer();
- QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
void reset(QGesture *state);
};
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 2b2259c41a..c0fb8aac00 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1152,16 +1152,23 @@ CGFloat qt_mac_get_scalefactor()
#endif
}
-QString qt_mac_get_pasteboardString()
+QString qt_mac_get_pasteboardString(OSPasteboardRef paste)
{
QMacCocoaAutoReleasePool pool;
- NSPasteboard *pb = [NSPasteboard generalPasteboard];
- NSString *text = [pb stringForType:NSStringPboardType];
- if (text) {
- return qt_mac_NSStringToQString(text);
+ NSPasteboard *pb = nil;
+ CFStringRef pbname;
+ if (PasteboardCopyName (paste, &pbname)) {
+ pb = [NSPasteboard generalPasteboard];
} else {
- return QString();
+ pb = [NSPasteboard pasteboardWithName:reinterpret_cast<const NSString *>(pbname)];
+ CFRelease (pbname);
}
+ 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)
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index 62db0640d6..f11ccc56d4 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -116,7 +116,7 @@ typedef struct CGPoint NSPoint;
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);
+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 );
@@ -170,7 +170,7 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list);
void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow);
CGFloat qt_mac_get_scalefactor();
-QString qt_mac_get_pasteboardString();
+QString qt_mac_get_pasteboardString(OSPasteboardRef paste);
#ifdef __OBJC__
inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist)
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index d33791bdd6..08f8bb5163 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -73,6 +73,7 @@
#include <akntitle.h> // CAknTitlePane
#include <akncontext.h> // CAknContextPane
#include <eikspane.h> // CEikStatusPane
+#include <aknpopupfader.h> // MAknFadedComponent and TAknPopupFader
#endif
QT_BEGIN_NAMESPACE
@@ -81,6 +82,9 @@ QT_BEGIN_NAMESPACE
// system events seems to start with 0x10
const TInt KInternalStatusPaneChange = 0x50000000;
+//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2
+#define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13)
+
class QS60Data
{
public:
@@ -108,9 +112,10 @@ public:
int mouseInteractionEnabled : 1;
int virtualMouseRequired : 1;
int qtOwnsS60Environment : 1;
+ int supportsPremultipliedAlpha : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
static inline void updateScreenSize();
- static inline RWsSession& wsSession();
+ static inline RWsSession& wsSession();
static inline RWindowGroup& windowGroup();
static inline CWsScreenDevice* screenDevice();
static inline CCoeAppUi* appUi();
@@ -120,6 +125,8 @@ public:
static inline CAknTitlePane* titlePane();
static inline CAknContextPane* contextPane();
static inline CEikButtonGroupContainer* buttonGroupContainer();
+
+ TTrapHandler *s60InstalledTrapHandler;
#endif
};
@@ -134,7 +141,11 @@ public:
};
class QLongTapTimer;
+
class QSymbianControl : public CCoeControl, public QAbstractLongTapObserver
+#ifdef Q_WS_S60
+, public MAknFadedComponent
+#endif
{
public:
DECLARE_TYPE_ID(0x51740000) // Fun fact: the two first values are "Qt" in ASCII.
@@ -159,6 +170,17 @@ public:
void setFocusSafely(bool focus);
+#ifdef Q_WS_S60
+ void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); }
+
+protected: // from MAknFadedComponent
+ TInt CountFadedComponents() {return 1;}
+ CCoeControl* FadedComponent(TInt /*aIndex*/) {return this;}
+#else
+ #warning No fallback implementation for QSymbianControl::FadeBehindPopup
+ void FadeBehindPopup(bool /*fade*/){ }
+#endif
+
protected:
void Draw(const TRect& aRect) const;
void SizeChanged();
@@ -180,9 +202,14 @@ private:
private:
QWidget *qwidget;
- bool m_ignoreFocusChanged;
QLongTapTimer* m_longTapDetector;
- bool m_previousEventLongTap;
+ bool m_ignoreFocusChanged : 1;
+ bool m_symbianPopupIsOpen : 1;
+
+#ifdef Q_WS_S60
+ // Fader object used to fade everything except this menu and the CBA.
+ TAknPopupFader popupFader;
+#endif
};
inline QS60Data::QS60Data()
@@ -199,7 +226,7 @@ inline void QS60Data::updateScreenSize()
S60->screenHeightInPixels = params.iPixelSize.iHeight;
S60->screenWidthInTwips = params.iTwipsSize.iWidth;
S60->screenHeightInTwips = params.iTwipsSize.iHeight;
-
+
S60->virtualMouseMaxAccel = qMax(S60->screenHeightInPixels, S60->screenWidthInPixels) / 20;
TReal inches = S60->screenHeightInTwips / (TReal)KTwipsPerInch;
@@ -302,11 +329,9 @@ static inline QImage::Format qt_TDisplayMode2Format(TDisplayMode mode)
case EColor16MA:
format = QImage::Format_ARGB32;
break;
-#if !defined(__SERIES60_31__) && !defined(__S60_32__)
- case EColor16MAP:
+ case Q_SYMBIAN_ECOLOR16MAP:
format = QImage::Format_ARGB32_Premultiplied;
break;
-#endif
default:
format = QImage::Format_Invalid;
break;
diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h
index 61acbac681..9e4cf60b40 100644
--- a/src/gui/kernel/qt_x11_p.h
+++ b/src/gui/kernel/qt_x11_p.h
@@ -163,7 +163,9 @@ extern "C" {
#endif // QT_NO_XRENDER
#ifndef QT_NO_XSYNC
+extern "C" {
# include "X11/extensions/sync.h"
+}
#endif
// #define QT_NO_XKB
@@ -428,6 +430,7 @@ struct QX11Data
// 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.
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 4d8386b3ff..babc68b025 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -93,6 +93,7 @@
# include "qx11info_x11.h"
#endif
+#include <private/qgraphicseffect_p.h>
#include <private/qwindowsurface_p.h>
#include <private/qbackingstore_p.h>
#ifdef Q_WS_MAC
@@ -149,24 +150,6 @@ static inline bool hasBackingStoreSupport()
#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(QWidget *p)
-{
- while (p) {
- if (p->windowFlags() & Qt::BypassGraphicsProxyWidget)
- return true;
- p = p->parentWidget();
- }
- return false;
-}
-
#ifdef Q_WS_MAC
# define QT_NO_PAINT_DEBUG
#endif
@@ -214,6 +197,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, picture(0)
#elif defined(Q_WS_WIN)
, noPaintOnScreen(0)
+ , nativeGesturePanEnabled(0)
#elif defined(Q_WS_MAC)
, needWindowChange(0)
, isGLWidget(0)
@@ -246,7 +230,9 @@ QWidgetPrivate::~QWidgetPrivate()
if (extra)
deleteExtra();
+#ifndef QT_NO_GRAPHICSEFFECT
delete graphicsEffect;
+#endif //QT_NO_GRAPHICSEFFECT
}
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
@@ -914,7 +900,7 @@ void QWidget::setAutoFillBackground(bool enabled)
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
- heirarchy so it is possible to define a single set of softkeys that are
+ 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
@@ -1355,6 +1341,8 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
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();
@@ -1502,6 +1490,8 @@ void QWidgetPrivate::setWinId(WId id) // set widget identifier
mapper->remove(data.winid);
}
+ const WId oldWinId = data.winid;
+
data.winid = id;
#if defined(Q_WS_X11)
hd = id; // X11: hd == ident
@@ -1509,6 +1499,16 @@ void QWidgetPrivate::setWinId(WId id) // set widget identifier
if (mapper && id && !userDesktopWidget) {
mapper->insert(data.winid, q);
}
+
+ if(oldWinId != id) {
+ // Do not emit an event when the old winId is destroyed. This only
+ // happens (a) during widget destruction, and (b) immediately prior
+ // to creation of a new winId, for example as a result of re-parenting.
+ if(id != 0) {
+ QEvent e(QEvent::WinIdChange);
+ QCoreApplication::sendEvent(q, &e);
+ }
+ }
}
void QWidgetPrivate::createTLExtra()
@@ -1552,7 +1552,9 @@ void QWidgetPrivate::createExtra()
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
@@ -1702,12 +1704,13 @@ void QWidgetPrivate::propagatePaletteChange()
{
Q_Q(QWidget);
// Propagate a new inherited mask to all children.
- if (!q->parentWidget() && extra && extra->proxyWidget) {
#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
- } else if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
+ if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
inheritedPaletteResolveMask = 0;
}
int mask = data.pal.resolve() | inheritedPaletteResolveMask;
@@ -1792,12 +1795,33 @@ QRegion QWidgetPrivate::clipRegion() const
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;
@@ -1811,18 +1835,6 @@ void QWidgetPrivate::setDirtyOpaqueRegion()
pd->setDirtyOpaqueRegion();
}
-QRegion QWidgetPrivate::getOpaqueRegion() const
-{
- Q_Q(const QWidget);
-
- QRegion r = isOpaque ? q->rect() : getOpaqueChildren();
- if (extra && extra->hasMask)
- r &= extra->mask;
- if (r.isEmpty())
- return r;
- return r & clipRect();
-}
-
const QRegion &QWidgetPrivate::getOpaqueChildren() const
{
if (!dirtyOpaqueChildren)
@@ -1837,9 +1849,17 @@ const QRegion &QWidgetPrivate::getOpaqueChildren() const
continue;
const QPoint offset = child->geometry().topLeft();
- that->opaqueChildren += child->d_func()->getOpaqueRegion().translated(offset);
+ 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;
@@ -1949,10 +1969,12 @@ void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
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();
@@ -1987,11 +2009,13 @@ 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
@@ -2227,8 +2251,8 @@ QWidget *QWidget::find(WId id)
against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt
is using Cocoa, {WId} is a pointer to an NSView.
- \note We recommend that you do not store this value as it is likely to
- change at run-time.
+ 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()
*/
@@ -3061,15 +3085,18 @@ void QWidgetPrivate::setEnabled_helper(bool enable)
#if defined(Q_WS_MAC)
setEnabled_helper_sys(enable);
#endif
+#ifndef QT_NO_IM
if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) {
- QInputContext *qic = inputContext();
+ QWidget *focusWidget = effectiveFocusWidget();
+ QInputContext *qic = focusWidget->d_func()->inputContext();
if (enable) {
- qic->setFocusWidget(q);
+ qic->setFocusWidget(focusWidget);
} else {
qic->reset();
qic->setFocusWidget(0);
}
}
+#endif //QT_NO_IM
QEvent e(QEvent::EnabledChange);
QApplication::sendEvent(q, &e);
#ifdef QT3_SUPPORT
@@ -4371,7 +4398,11 @@ 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) || (extra && extra->proxyWidget))) {
+ && (!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())) {
@@ -4382,13 +4413,14 @@ QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
naturalPalette = p->palette();
}
}
- } else if (extra && extra->proxyWidget) {
+ }
#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
}
+#endif //QT_NO_GRAPHICSVIEW
}
naturalPalette.resolve(0);
return naturalPalette;
@@ -4506,7 +4538,11 @@ 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) || (extra && extra->proxyWidget))) {
+ && (!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())) {
@@ -4517,13 +4553,14 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
naturalFont = p->font();
}
}
- } else if (extra && extra->proxyWidget) {
+ }
#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
}
+#endif //QT_NO_GRAPHICSVIEW
}
naturalFont.resolve(0);
return naturalFont;
@@ -4570,12 +4607,13 @@ void QWidgetPrivate::updateFont(const QFont &font)
data.fnt.x11SetScreen(xinfo.screen());
#endif
// Combine new mask with natural mask and propagate to children.
- if (!q->parentWidget() && extra && extra->proxyWidget) {
#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
- } else if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
+ if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
inheritedFontResolveMask = 0;
}
uint newMask = data.fnt.resolve() | inheritedFontResolveMask;
@@ -4645,8 +4683,10 @@ void QWidgetPrivate::resolveLayoutDirection()
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. Children added after the call to \c
- setLayoutDirection() will not inherit the parent's layout
+ 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.
\sa QApplication::layoutDirection
@@ -4992,11 +5032,13 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
\sa setGraphicsEffect()
*/
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *QWidget::graphicsEffect() const
{
Q_D(const QWidget);
return d->graphicsEffect;
}
+#endif //QT_NO_GRAPHICSEFFECT
/*!
@@ -5015,6 +5057,7 @@ QGraphicsEffect *QWidget::graphicsEffect() const
\sa graphicsEffect()
*/
+#ifndef QT_NO_GRAPHICSEFFECT
void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
{
Q_D(QWidget);
@@ -5044,6 +5087,7 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
d->updateIsOpaque();
update();
}
+#endif //QT_NO_GRAPHICSEFFECT
bool QWidgetPrivate::isAboutToShow() const
{
@@ -5136,8 +5180,7 @@ void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset
return;
QPixmap pixmap(size);
- if (!(renderFlags & QWidget::DrawWindowBackground)
- || !q->palette().brush(q->backgroundRole()).isOpaque())
+ if (!(renderFlags & QWidget::DrawWindowBackground) || !isOpaque)
pixmap.fill(Qt::transparent);
q->render(&pixmap, QPoint(), toBePainted, renderFlags);
@@ -5190,6 +5233,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
return;
Q_Q(QWidget);
+#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect && graphicsEffect->isEnabled()) {
QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
@@ -5203,19 +5247,24 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
QPainter p(pdev);
p.translate(offset);
context.painter = &p;
- graphicsEffect->draw(&p, source);
+ 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, source);
+ graphicsEffect->draw(sharedPainter);
sharedPainter->restore();
}
sourced->context = 0;
return;
}
}
+#endif //QT_NO_GRAFFICSEFFECT
const bool asRoot = flags & DrawAsRoot;
const bool alsoOnScreen = flags & DrawPaintOnScreen;
@@ -5370,7 +5419,6 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
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)
@@ -5382,7 +5430,11 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
, sharedPainter, backingStore);
}
- if (w->updatesEnabled() && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget)) {
+ 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);
@@ -5392,6 +5444,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
}
}
+#ifndef QT_NO_GRAPHICSEFFECT
QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
{
if (system != Qt::DeviceCoordinates)
@@ -5425,7 +5478,8 @@ void QWidgetEffectSourcePrivate::draw(QPainter *painter)
context->sharedPainter, context->backingStore);
}
-QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
+QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
+ QGraphicsEffect::PixmapPadMode mode) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
if (!context && deviceCoordinates) {
@@ -5443,7 +5497,20 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
pixmapOffset = painterTransform.map(pixmapOffset);
}
- QRect effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
+
+ 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();
@@ -5478,7 +5545,9 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
m_widget->render(&pixmap, pixmapOffset);
return pixmap;
}
+#endif //QT_NO_GRAPHICSEFFECT
+#ifndef QT_NO_GRAPHICSVIEW
/*!
\internal
@@ -5487,7 +5556,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
If successful, the function returns the proxy that embeds the widget, or 0 if no embedded
widget was found.
*/
-QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(QWidget *origin)
+QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
{
if (origin) {
QWExtra *extra = origin->d_func()->extra;
@@ -5497,6 +5566,7 @@ QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(QWidget *origi
}
return 0;
}
+#endif
/*!
\property QWidget::locale
@@ -5671,9 +5741,8 @@ QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widg
void QWidgetPrivate::setWindowTitle_helper(const QString &title)
{
Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created))
- createWinId();
- setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q));
+ if (q->testAttribute(Qt::WA_WState_Created))
+ setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q));
}
void QWidgetPrivate::setWindowIconText_helper(const QString &title)
@@ -7307,7 +7376,7 @@ void QWidget::setVisible(bool visible)
break;
parent = parent->parentWidget();
}
- if (parent && !d->getOpaqueRegion().isEmpty())
+ if (parent)
parent->d_func()->setDirtyOpaqueRegion();
}
@@ -7732,6 +7801,10 @@ void QWidget::adjustSize()
Q_D(QWidget);
ensurePolished();
QSize s = d->adjustedSize();
+
+ if (d->layout)
+ d->layout->activate();
+
if (s.isValid())
resize(s);
}
@@ -8933,11 +9006,16 @@ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const
Qt::InputMethodHints QWidget::inputMethodHints() const
{
Q_D(const QWidget);
+#ifndef QT_NO_IM
return d->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;
// Optimisation to update input context only it has already been created.
@@ -8946,6 +9024,7 @@ void QWidget::setInputMethodHints(Qt::InputMethodHints hints)
if (ic)
ic->update();
}
+#endif //QT_NO_IM
}
@@ -10282,9 +10361,11 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
QApplication::sendEvent(this, &e);
break; }
case Qt::WA_NativeWindow: {
+#ifndef QT_NO_IM
+ QWidget *focusWidget = d->effectiveFocusWidget();
QInputContext *ic = 0;
if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) {
- ic = d->inputContext();
+ ic = focusWidget->d_func()->inputContext();
ic->reset();
ic->setFocusWidget(0);
}
@@ -10293,7 +10374,8 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
d->createWinId();
if (ic && isEnabled())
- ic->setFocusWidget(this);
+ ic->setFocusWidget(focusWidget);
+#endif //QT_NO_IM
break;
}
case Qt::WA_PaintOnScreen:
@@ -10323,17 +10405,20 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
#endif
break;
case Qt::WA_InputMethodEnabled: {
- QInputContext *ic = d->ic;
+#ifndef QT_NO_IM
+ QWidget *focusWidget = d->effectiveFocusWidget();
+ QInputContext *ic = focusWidget->d_func()->ic;
if (!ic && (!on || hasFocus()))
- ic = d->inputContext();
+ ic = focusWidget->d_func()->inputContext();
if (ic) {
- if (on && hasFocus() && ic->focusWidget() != this && isEnabled()) {
- ic->setFocusWidget(this);
- } else if (!on && ic->focusWidget() == this) {
+ if (on && hasFocus() && ic->focusWidget() != focusWidget && isEnabled()) {
+ ic->setFocusWidget(focusWidget);
+ } else if (!on && ic->focusWidget() == focusWidget) {
ic->reset();
ic->setFocusWidget(0);
}
}
+#endif //QT_NO_IM
break;
}
case Qt::WA_WindowPropagation:
@@ -11393,6 +11478,17 @@ void QWidget::languageChange() { } // compat
\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);
@@ -11684,21 +11780,33 @@ QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const
*/
/*!
- Subscribes the widget to a given \a gesture with a \a context.
+ Subscribes the widget to a given \a gesture with specific \a flags.
- \sa QGestureEvent
+ \sa ungrabGesture(), QGestureEvent
\since 4.6
*/
-void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureContext context)
+void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
{
Q_D(QWidget);
- d->gestureContext.insert(gesture, context);
+ d->gestureContext.insert(gesture, flags);
(void)QGestureManager::instance(); // create a gesture manager
}
-QT_END_NAMESPACE
+/*!
+ 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)) {
+ QGestureManager *manager = QGestureManager::instance();
+ manager->cleanupCachedGestures(this, gesture);
+ }
+}
-#include "moc_qwidget.cpp"
/*!
\typedef WId
@@ -11774,8 +11882,7 @@ QT_END_NAMESPACE
isVisible() returns false for a widget, that widget cannot call
grabMouse().
- \sa releaseMouse() grabKeyboard() releaseKeyboard() grabKeyboard()
- focusWidget()
+ \sa releaseMouse() grabKeyboard() releaseKeyboard()
*/
/*!
@@ -12009,3 +12116,15 @@ void QWidget::clearMask()
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
+
+QT_END_NAMESPACE
+
+#include "moc_qwidget.cpp"
+
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 3501c6eec8..5ba1d231a6 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -288,6 +288,10 @@ public:
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);
@@ -351,10 +355,13 @@ public:
const QRegion &sourceRegion = QRegion(),
RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *graphicsEffect() const;
void setGraphicsEffect(QGraphicsEffect *effect);
+#endif //QT_NO_GRAPHICSEFFECT
- void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture);
+ void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
+ void ungrabGesture(Qt::GestureType type);
public Q_SLOTS:
void setWindowTitle(const QString &);
@@ -726,14 +733,11 @@ private:
friend class QGLContext;
friend class QGLWidget;
friend class QGLWindowSurface;
- friend class QGLWindowSurfaceGLPaintDevice;
- friend class QVGWindowSurface;
friend class QX11PaintEngine;
friend class QWin32PaintEngine;
friend class QShortcutPrivate;
friend class QShortcutMap;
friend class QWindowSurface;
- friend class QD3DWindowSurface;
friend class QGraphicsProxyWidget;
friend class QGraphicsProxyWidgetPrivate;
friend class QStyleSheetStyle;
@@ -776,6 +780,9 @@ private:
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;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index c966aa3ba8..71f0077521 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -305,6 +305,8 @@ bool qt_mac_insideKeyWindow(const QWidget *w)
{
#ifdef QT_MAC_USE_COCOA
return [[reinterpret_cast<NSView *>(w->winId()) window] isKeyWindow];
+#else
+ Q_UNUSED(w);
#endif
return false;
}
@@ -728,6 +730,7 @@ static EventTypeSpec window_events[] = {
{ kEventClassWindow, kEventWindowClose },
{ kEventClassWindow, kEventWindowExpanded },
{ kEventClassWindow, kEventWindowHidden },
+ { kEventClassWindow, kEventWindowZoom },
{ kEventClassWindow, kEventWindowZoomed },
{ kEventClassWindow, kEventWindowCollapsed },
{ kEventClassWindow, kEventWindowToolbarSwitchMode },
@@ -810,6 +813,9 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event,
QShowEvent qse;
QApplication::sendSpontaneousEvent(widget, &qse);
+ } else if(ekind == kEventWindowZoom) {
+ widget->d_func()->topData()->normalGeometry = widget->geometry();
+ handled_event = false;
} else if(ekind == kEventWindowZoomed) {
WindowPartCode windowPart;
GetEventParameter(event, kEventParamWindowPartCode,
@@ -2667,7 +2673,10 @@ void QWidgetPrivate::transferChildren()
// site disabled until it is part of the new hierarchy.
bool oldRegistered = w->testAttribute(Qt::WA_DropSiteRegistered);
w->setAttribute(Qt::WA_DropSiteRegistered, false);
+ [qt_mac_nativeview_for(w) retain];
+ [qt_mac_nativeview_for(w) removeFromSuperview];
[qt_mac_nativeview_for(q) addSubview:qt_mac_nativeview_for(w)];
+ [qt_mac_nativeview_for(w) release];
w->setAttribute(Qt::WA_DropSiteRegistered, oldRegistered);
#endif
}
@@ -2894,6 +2903,7 @@ void QWidgetPrivate::setCursor_sys(const QCursor &)
#else
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_WState_Created)) {
+ QMacCocoaAutoReleasePool pool;
[qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
}
#endif
@@ -2906,6 +2916,7 @@ void QWidgetPrivate::unsetCursor_sys()
#else
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_WState_Created)) {
+ QMacCocoaAutoReleasePool pool;
[qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
}
#endif
@@ -3013,10 +3024,17 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
#else
QMacCocoaAutoReleasePool pool;
NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
+ if (iconButton == nil) {
+ QCFString string(q->windowTitle());
+ const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
+ [qt_mac_window_for(q) setRepresentedURL:[NSURL fileURLWithPath:tmpString]];
+ iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
+ }
if (icon.isNull()) {
[iconButton setImage:nil];
} else {
- NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(*pm));
+ QPixmap scaled = pm->scaled(QSize(16,16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(scaled));
[iconButton setImage:image];
[image release];
}
@@ -3046,6 +3064,7 @@ void QWidget::grabMouse()
}
}
+#ifndef QT_NO_CURSOR
void QWidget::grabMouse(const QCursor &)
{
if(isVisible() && !qt_nograb()) {
@@ -3054,6 +3073,7 @@ void QWidget::grabMouse(const QCursor &)
mac_mouse_grabber=this;
}
}
+#endif
void QWidget::releaseMouse()
{
@@ -3301,7 +3321,11 @@ void QWidgetPrivate::show_sys()
[window miniaturize:window];
#endif
} else if (!q->testAttribute(Qt::WA_ShowWithoutActivating)) {
+#ifndef QT_MAC_USE_COCOA
qt_event_request_activate(q);
+#else
+ [qt_mac_window_for(q) makeKeyWindow];
+#endif
}
} else if(topData()->embedded || !q->parentWidget() || q->parentWidget()->isVisible()) {
#ifndef QT_MAC_USE_COCOA
@@ -3382,12 +3406,19 @@ void QWidgetPrivate::hide_sys()
w = q->parentWidget()->window();
if(!w || (!w->isVisible() && !w->isMinimized())) {
#ifndef QT_MAC_USE_COCOA
- for(WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
- wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
+ for (WindowPtr wp = GetFrontWindowOfClass(kMovableModalWindowClass, true);
+ wp; wp = GetNextWindowOfClass(wp, kMovableModalWindowClass, true)) {
if((w = qt_mac_find_window(wp)))
break;
}
if (!w){
+ for (WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
+ wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
+ if((w = qt_mac_find_window(wp)))
+ break;
+ }
+ }
+ if (!w){
for(WindowPtr wp = GetFrontWindowOfClass(kSimpleWindowClass, true);
wp; wp = GetNextWindowOfClass(wp, kSimpleWindowClass, true)) {
if((w = qt_mac_find_window(wp)))
@@ -3404,8 +3435,13 @@ void QWidgetPrivate::hide_sys()
}
#endif
}
- if(w && w->isVisible() && !w->isMinimized())
- qt_event_request_activate(w);
+ if(w && w->isVisible() && !w->isMinimized()) {
+#ifndef QT_MAC_USE_COCOA
+ qt_event_request_activate(w);
+#else
+ [qt_mac_window_for(w) makeKeyWindow];
+#endif
+ }
}
} else {
invalidateBuffer(q->rect());
@@ -3458,10 +3494,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
qt_mac_set_fullscreen_mode(true);
} else {
needShow = isVisible();
- setParent(parentWidget(), d->topData()->savedFlags);
- setGeometry(d->topData()->normalGeometry);
if(!qApp->desktop()->screenNumber(this))
qt_mac_set_fullscreen_mode(false);
+ setParent(parentWidget(), d->topData()->savedFlags);
+ setGeometry(d->topData()->normalGeometry);
d->topData()->normalGeometry.setRect(0, 0, -1, -1);
}
}
@@ -3563,7 +3599,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
[window zoom:window];
#endif
needSendStateChange = oldstate == windowState(); // Zoom didn't change flags.
- } else if(oldstate & Qt::WindowMaximized) {
+ } else if(oldstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen)) {
#ifndef QT_MAC_USE_COCOA
Point idealSize;
ZoomWindowIdeal(window, inZoomIn, &idealSize);
@@ -3758,7 +3794,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget *w)
/*
Modifies the bounds for a widgets backing HIView during moves and resizes. Also updates the
widget, either by scrolling its contents or repainting, depending on the WA_StaticContents
- and QWidgetPrivate::isOpaque flags.
+ flag
*/
static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newRect)
{
@@ -3775,8 +3811,8 @@ static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newR
// Perform a normal (complete repaint) update in some cases:
if (
- // move-by-scroll requires QWidgetPrivate::isOpaque set
- (isMove && q->testAttribute(Qt::WA_OpaquePaintEvent) == false) ||
+ // always repaint on move.
+ (isMove) ||
// limited update on resize requires WA_StaticContents.
(isResize && q->testAttribute(Qt::WA_StaticContents) == false) ||
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 640351860f..3494a1d6cd 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -63,7 +63,9 @@
#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
@@ -180,7 +182,9 @@ struct QWExtra {
// 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
@@ -235,6 +239,24 @@ struct QWExtra {
#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)
@@ -296,7 +318,8 @@ public:
void setMask_sys(const QRegion &);
#ifdef Q_OS_SYMBIAN
void setSoftKeys_sys(const QList<QAction*> &softkeys);
- void activateSymbianWindow();
+ void activateSymbianWindow(WId wid = 0);
+ void _q_delayedDestroy(WId winId);
#endif
void raise_sys();
@@ -344,7 +367,9 @@ public:
QPainter *beginSharedPainter();
bool endSharedPainter();
- static QGraphicsProxyWidget * nearestGraphicsProxyWidget(QWidget *origin);
+#ifndef QT_NO_GRAPHICSVIEW
+ static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin);
+#endif
QWindowSurface *createDefaultWindowSurface();
QWindowSurface *createDefaultWindowSurface_sys();
void repaint_sys(const QRegion &rgn);
@@ -359,8 +384,10 @@ public:
void setOpaque(bool opaque);
void updateIsTranslucent();
bool paintOnScreen() const;
+#ifndef QT_NO_GRAPHICSEFFECT
+ void invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
- QRegion getOpaqueRegion() const;
const QRegion &getOpaqueChildren() const;
void setDirtyOpaqueRegion();
@@ -438,9 +465,40 @@ public:
void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0);
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));
@@ -480,8 +538,10 @@ public:
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;
}
@@ -580,7 +640,7 @@ public:
#ifndef QT_NO_ACTION
QList<QAction*> actions;
#endif
- QMap<Qt::GestureType, Qt::GestureContext> gestureContext;
+ QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
// Bit fields.
uint high_attributes[3]; // the low ones are in QWidget::widget_attributes
@@ -730,11 +790,12 @@ struct QWidgetPaintContext
QPainter *painter;
};
+#ifndef QT_NO_GRAPHICSEFFECT
class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
{
public:
QWidgetEffectSourcePrivate(QWidget *widget)
- : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0)
+ : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0), updateDueToGraphicsEffect(false)
{}
inline void detach()
@@ -747,7 +808,11 @@ public:
{ return m_widget; }
inline void update()
- { m_widget->update(); }
+ {
+ updateDueToGraphicsEffect = true;
+ m_widget->update();
+ updateDueToGraphicsEffect = false;
+ }
inline bool isPixmap() const
{ return false; }
@@ -759,7 +824,7 @@ public:
if (QWidget *parent = m_widget->parentWidget())
parent->update();
else
- m_widget->update();
+ update();
}
inline const QStyleOption *styleOption() const
@@ -770,11 +835,15 @@ public:
QRectF boundingRect(Qt::CoordinateSystem system) const;
void draw(QPainter *p);
- QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset) const;
+ 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
{
diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp
index 0f46016aa6..e299c6e2ee 100644
--- a/src/gui/kernel/qwidget_qws.cpp
+++ b/src/gui/kernel/qwidget_qws.cpp
@@ -280,7 +280,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
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;
@@ -291,6 +291,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
if (qic)
qic->widgetDestroyed(this);
}
+#endif //QT_NO_IM
if ((windowType() == Qt::Desktop)) {
} else {
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index b0d405afb3..b1c37d3bc9 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -56,6 +56,12 @@
#include <aknappui.h>
#endif
+// This is necessary in order to be able to perform delayed invokation on slots
+// which take arguments of type WId. One example is
+// QWidgetPrivate::_q_delayedDestroy, which is used to delay destruction of
+// CCoeControl objects until after the CONE event handler has finished running.
+Q_DECLARE_METATYPE(WId)
+
QT_BEGIN_NAMESPACE
extern bool qt_nograb();
@@ -207,6 +213,15 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if ((q->windowType() == Qt::Desktop))
return;
+
+ QPoint oldPos(q->pos());
+ QSize oldSize(q->size());
+ QRect oldGeom(data.crect);
+
+ // Lose maximized status if deliberate resize
+ if (w != oldSize.width() || h != oldSize.height())
+ data.window_state &= ~Qt::WindowMaximized;
+
if (extra) { // any size restrictions?
w = qMin(w,extra->maxw);
h = qMin(h,extra->maxh);
@@ -222,17 +237,10 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
data.window_state = s;
}
- QPoint oldPos(q->pos());
- QSize oldSize(q->size());
- QRect oldGeom(data.crect);
-
bool isResize = w != oldSize.width() || h != oldSize.height();
if (!isMove && !isResize)
return;
- if (isResize)
- data.window_state &= ~Qt::WindowMaximized;
-
if (q->isWindow()) {
if (w == 0 || h == 0) {
q->setAttribute(Qt::WA_OutsideWSRange, true);
@@ -318,8 +326,6 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
bool desktop = (type == Qt::Desktop);
//bool tool = (type == Qt::Tool || type == Qt::Drawer);
- WId id = 0;
-
if (popup)
flags |= Qt::WindowStaysOnTopHint; // a popup stays on top
@@ -341,13 +347,10 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
data.crect.setSize(QSize(width, height));
}
- CCoeControl *destroyw = 0;
+ CCoeControl *const destroyw = destroyOldWindow ? data.winid : 0;
createExtra();
if (window) {
- if (destroyOldWindow)
- destroyw = data.winid;
- id = window;
setWinId(window);
TRect tr = window->Rect();
data.crect.setRect(tr.iTl.iX, tr.iTl.iY, tr.Width(), tr.Height());
@@ -355,10 +358,16 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
} else if (topLevel) {
if (!q->testAttribute(Qt::WA_Moved) && !q->testAttribute(Qt::WA_DontShowOnScreen))
data.crect.moveTopLeft(QPoint(clientRect.iTl.iX, clientRect.iTl.iY));
- QSymbianControl *control= q_check_ptr(new QSymbianControl(q));
- id = (WId)control;
- setWinId(id);
- QT_TRAP_THROWING(control->ConstructL(true,desktop));
+
+ QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) );
+ QT_TRAP_THROWING(control->ConstructL(true, desktop));
+ control->SetMopParent(static_cast<CEikAppUi*>(S60->appUi()));
+
+ // Symbian windows are always created in an inactive state
+ // We perform this assignment for the case where the window is being re-created
+ // as aa result of a call to setParent_sys, on either this widget or one of its
+ // ancestors.
+ extra->activated = 0;
if (!desktop) {
TInt stackingFlags;
@@ -368,7 +377,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
stackingFlags = ECoeStackFlagStandard;
}
control->MakeVisible(false);
- QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control, ECoeStackPriorityDefault, stackingFlags));
+ QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags));
// Avoid keyboard focus to a hidden window.
control->setFocusSafely(false);
@@ -391,11 +400,22 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
int x, y, w, h;
data.crect.getRect(&x, &y, &w, &h);
control->SetRect(TRect(TPoint(x, y), TSize(w, h)));
+
+ // We wait until the control is fully constructed before calling setWinId, because
+ // this generates a WinIdChanged event.
+ setWinId(control.take());
+
} else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create native child widget
- QSymbianControl *control = new QSymbianControl(q);
- setWinId(control);
+
+ QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) );
QT_TRAP_THROWING(control->ConstructL(!parentWidget));
+ // Symbian windows are always created in an inactive state
+ // We perform this assignment for the case where the window is being re-created
+ // as aa result of a call to setParent_sys, on either this widget or one of its
+ // ancestors.
+ extra->activated = 0;
+
TInt stackingFlags;
if ((q->windowType() & Qt::Popup) == Qt::Popup) {
stackingFlags = ECoeStackFlagRefusesAllKeys | ECoeStackFlagRefusesFocus;
@@ -403,7 +423,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
stackingFlags = ECoeStackFlagStandard;
}
control->MakeVisible(false);
- QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control, ECoeStackPriorityDefault, stackingFlags));
+ QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags));
// Avoid keyboard focus to a hidden window.
control->setFocusSafely(false);
@@ -417,13 +437,24 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
drawableWindow->PointerFilter(EPointerFilterEnterExit
| EPointerFilterMove | EPointerFilterDrag, 0);
- if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
- activateSymbianWindow();
+ if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) {
+ activateSymbianWindow(control.data());
+ control->MakeVisible(true);
+ }
+
+ // We wait until the control is fully constructed before calling setWinId, because
+ // this generates a WinIdChanged event.
+ setWinId(control.take());
}
if (destroyw) {
destroyw->ControlEnv()->AppUi()->RemoveFromStack(destroyw);
- CBase::Delete(destroyw);
+
+ // Delay deletion of the control in case this function is called in the
+ // context of a CONE event handler such as
+ // CCoeControl::ProcessPointerEventL
+ QMetaObject::invokeMethod(q, "_q_delayedDestroy",
+ Qt::QueuedConnection, Q_ARG(WId, destroyw));
}
if (q->testAttribute(Qt::WA_AcceptTouchEvents))
@@ -468,7 +499,7 @@ void QWidgetPrivate::show_sys()
invalidateBuffer(q->rect());
}
-void QWidgetPrivate::activateSymbianWindow()
+void QWidgetPrivate::activateSymbianWindow(WId wid)
{
Q_Q(QWidget);
@@ -476,8 +507,12 @@ void QWidgetPrivate::activateSymbianWindow()
Q_ASSERT(q->testAttribute(Qt::WA_Mapped));
Q_ASSERT(!extra->activated);
- WId id = q->internalWinId();
- QT_TRAP_THROWING(id->ActivateL());
+ if(!wid)
+ wid = q->internalWinId();
+
+ Q_ASSERT(wid);
+
+ QT_TRAP_THROWING(wid->ActivateL());
extra->activated = 1;
}
@@ -520,8 +555,13 @@ void QWidgetPrivate::raise_sys()
Q_Q(QWidget);
Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (q->internalWinId())
+ if (q->internalWinId()) {
q->internalWinId()->DrawableWindow()->SetOrdinalPosition(0);
+
+ // If toplevel widget, raise app to foreground
+ if (q->isWindow())
+ S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), 0);
+ }
}
void QWidgetPrivate::lower_sys()
@@ -529,8 +569,13 @@ void QWidgetPrivate::lower_sys()
Q_Q(QWidget);
Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (q->internalWinId())
- q->internalWinId()->DrawableWindow()->SetOrdinalPosition(-1);
+ if (q->internalWinId()) {
+ // If toplevel widget, lower app to background
+ if (q->isWindow())
+ S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), -1);
+ else
+ q->internalWinId()->DrawableWindow()->SetOrdinalPosition(-1);
+ }
if (!q->isWindow())
invalidateBuffer(q->rect());
@@ -571,8 +616,14 @@ void QWidgetPrivate::reparentChildren()
w->d_func()->invalidateBuffer(w->rect());
WId parent = q->effectiveWinId();
WId child = w->effectiveWinId();
- if (parent != child)
- child->SetParent(parent);
+ if (parent != child) {
+ // Child widget is native. Because Symbian windows cannot be
+ // re-parented, we must re-create the window.
+ const WId window = 0;
+ const bool initializeWindow = false;
+ const bool destroyOldWindow = true;
+ w->d_func()->create_sys(window, initializeWindow, destroyOldWindow);
+ }
// ### TODO: We probably also need to update the component array here
w->d_func()->reparentChildren();
} else {
@@ -670,62 +721,6 @@ void QWidgetPrivate::s60UpdateIsOpaque()
window->SetTransparentRegion(TRegionFix<1>());
}
-CFbsBitmap* qt_pixmapToNativeBitmap(QPixmap pixmap, bool invert)
-{
- CFbsBitmap* fbsBitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
- TSize size(pixmap.size().width(), pixmap.size().height());
- TDisplayMode mode(EColor16MU);
-
- bool isNull = pixmap.isNull();
- int depth = pixmap.depth();
-
- // TODO: dummy assumptions from bit amounts for each color
- // Will fix later on when native pixmap is implemented
- switch(pixmap.depth()) {
- case 1:
- mode = EGray2;
- break;
- case 4:
- mode = EColor16;
- break;
- case 8:
- mode = EColor256;
- break;
- case 12:
- mode = EColor4K;
- break;
- case 16:
- mode = EColor64K;
- break;
- case 24:
- mode = EColor16M;
- break;
- case 32:
- case EColor16MU:
- break;
- default:
- qFatal("Unsupported pixmap depth");
- break;
- }
-
- qt_symbian_throwIfError(fbsBitmap->Create(size, mode));
- fbsBitmap->LockHeap();
- QImage image = pixmap.toImage();
-
- if (invert)
- image.invertPixels();
-
- int height = pixmap.size().height();
- for(int i=0;i<height;i++ )
- {
- TPtr8 scanline(image.scanLine(i), image.bytesPerLine(), image.bytesPerLine());
- fbsBitmap->SetScanLine( scanline, i );
- }
-
- fbsBitmap->UnlockHeap();
- return fbsBitmap;
-}
-
void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
{
#ifdef Q_WS_S60
@@ -754,12 +749,8 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
mask.fill(Qt::color1);
}
- // Convert to CFbsBitmp
- // TODO: When QPixmap is adapted to use native CFbsBitmap,
- // it could be set directly to context pane
- CFbsBitmap* nBitmap = qt_pixmapToNativeBitmap(pm, false);
- CFbsBitmap* nMask = qt_pixmapToNativeBitmap(mask, true);
-
+ CFbsBitmap* nBitmap = pm.toSymbianCFbsBitmap();
+ CFbsBitmap* nMask = mask.toSymbianCFbsBitmap();
contextPane->SetPicture(nBitmap,nMask);
} else {
// Icon set to null -> set context pane picture to default
@@ -790,12 +781,8 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
mask.fill(Qt::color1);
}
- // Convert to CFbsBitmp
- // TODO: When QPixmap is adapted to use native CFbsBitmap,
- // it could be set directly to context pane
- CFbsBitmap* nBitmap = qt_pixmapToNativeBitmap(pm, false);
- CFbsBitmap* nMask = qt_pixmapToNativeBitmap(mask, true);
-
+ CFbsBitmap* nBitmap = pm.toSymbianCFbsBitmap();
+ CFbsBitmap* nMask = mask.toSymbianCFbsBitmap();
titlePane->SetSmallPicture( nBitmap, nMask, ETrue );
} else {
// Icon set to null -> set context pane picture to default
@@ -1251,7 +1238,7 @@ void QWidget::releaseKeyboard()
void QWidget::grabMouse()
{
- if (!qt_nograb()) {
+ if (isVisible() && !qt_nograb()) {
if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
QWidgetPrivate::mouseGrabber->releaseMouse();
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
@@ -1268,7 +1255,7 @@ void QWidget::grabMouse()
#ifndef QT_NO_CURSOR
void QWidget::grabMouse(const QCursor &cursor)
{
- if (!qt_nograb()) {
+ if (isVisible() && !qt_nograb()) {
if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
QWidgetPrivate::mouseGrabber->releaseMouse();
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 2b11becd56..fde0d45122 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -161,6 +161,9 @@ static void qt_tablet_init()
qt_tablet_widget = new QWidget(0);
qt_tablet_widget->createWinId();
qt_tablet_widget->setObjectName(QLatin1String("Qt internal tablet widget"));
+ // We dont need this internal widget to appear in QApplication::topLevelWidgets()
+ if (QWidgetPrivate::allWidgets)
+ QWidgetPrivate::allWidgets->remove(qt_tablet_widget);
LOGCONTEXT lcMine;
qAddPostRoutine(qt_tablet_cleanup);
struct tagAXIS tpOri[3];
@@ -674,7 +677,11 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const
QWidget *parentWindow = window();
QWExtra *extra = parentWindow->d_func()->extra;
if (!isVisible() || parentWindow->isMinimized() || !testAttribute(Qt::WA_WState_Created) || !internalWinId()
- || (extra && extra->proxyWidget)) {
+ || (extra
+#ifndef QT_NO_GRAPHICSVIEW
+ && extra->proxyWidget
+#endif //QT_NO_GRAPHICSVIEW
+ )) {
if (extra && extra->topextra && extra->topextra->embedded) {
QPoint pt = mapTo(parentWindow, pos);
POINT p = {pt.x(), pt.y()};
@@ -701,7 +708,11 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const
QWidget *parentWindow = window();
QWExtra *extra = parentWindow->d_func()->extra;
if (!isVisible() || parentWindow->isMinimized() || !testAttribute(Qt::WA_WState_Created) || !internalWinId()
- || (extra && extra->proxyWidget)) {
+ || (extra
+#ifndef QT_NO_GRAPHICSVIEW
+ && extra->proxyWidget
+#endif //QT_NO_GRAPHICSVIEW
+ )) {
if (extra && extra->topextra && extra->topextra->embedded) {
POINT p = {pos.x(), pos.y()};
ScreenToClient(parentWindow->effectiveWinId(), &p);
@@ -851,10 +862,13 @@ void QWidget::grabMouse()
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
SetCapture(effectiveWinId());
mouseGrb = this;
+#ifndef QT_NO_CURSOR
mouseGrbCur = new QCursor(mouseGrb->cursor());
+#endif
}
}
+#ifndef QT_NO_CURSOR
void QWidget::grabMouse(const QCursor &cursor)
{
if (!qt_nograb()) {
@@ -868,6 +882,7 @@ void QWidget::grabMouse(const QCursor &cursor)
mouseGrb = this;
}
}
+#endif
void QWidget::releaseMouse()
{
@@ -1324,8 +1339,15 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if (isResize && !q->testAttribute(Qt::WA_StaticContents) && q->internalWinId())
ValidateRgn(q->internalWinId(), 0);
+#ifdef Q_WS_WINCE
+ // On Windows CE we can't just fiddle around with the window state.
+ // Too much magic in setWindowState.
+ if (isResize && q->isMaximized())
+ q->setWindowState(q->windowState() & ~Qt::WindowMaximized);
+#else
if (isResize)
data.window_state &= ~Qt::WindowMaximized;
+#endif
if (data.window_state & Qt::WindowFullScreen) {
QTLWExtra *top = topData();
@@ -2025,16 +2047,21 @@ void QWidgetPrivate::registerTouchWindow()
void QWidgetPrivate::winSetupGestures()
{
+#if !defined(QT_NO_NATIVE_GESTURES)
Q_Q(QWidget);
- if (!q || !q->isVisible())
+ if (!q || !q->isVisible() || !nativeGesturePanEnabled)
return;
+
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- WId winid = q->effectiveWinId();
+ if (!qAppPriv->SetGestureConfig)
+ return;
+ WId winid = q->internalWinId();
bool needh = false;
bool needv = false;
bool singleFingerPanEnabled = false;
+#ifndef QT_NO_SCROLLAREA
if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q->parent())) {
QScrollBar *hbar = asa->horizontalScrollBar();
QScrollBar *vbar = asa->verticalScrollBar();
@@ -2045,8 +2072,12 @@ void QWidgetPrivate::winSetupGestures()
needv = (vbarpolicy == Qt::ScrollBarAlwaysOn ||
(vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled;
+ if (!winid) {
+ winid = q->winId(); // enforces the native winid on the viewport
+ }
}
- if (winid && qAppPriv->SetGestureConfig) {
+#endif //QT_NO_SCROLLAREA
+ if (winid) {
GESTURECONFIG gc[1];
memset(gc, 0, sizeof(gc));
gc[0].dwID = GID_PAN;
@@ -2064,19 +2095,9 @@ void QWidgetPrivate::winSetupGestures()
gc[0].dwBlock = GC_PAN;
}
-// gc[1].dwID = GID_ZOOM;
-// if (gestures.pinch)
-// gc[1].dwWant = GC_ZOOM;
-// else
-// gc[1].dwBlock = GC_ZOOM;
-// gc[2].dwID = GID_ROTATE;
-// if (gestures.pinch)
-// gc[2].dwWant = GC_ROTATE;
-// else
-// gc[2].dwBlock = GC_ROTATE;
-
qAppPriv->SetGestureConfig(winid, 0, sizeof(gc)/sizeof(gc[0]), gc, sizeof(gc[0]));
}
+#endif
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp
index 4a0d30c422..2fe69e4aa7 100644
--- a/src/gui/kernel/qwidget_wince.cpp
+++ b/src/gui/kernel/qwidget_wince.cpp
@@ -474,7 +474,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
int normal = SW_SHOWNOACTIVATE;
if ((oldstate & Qt::WindowMinimized) && !(newstate & Qt::WindowMinimized))
- newstate |= Qt::WindowActive;
+ newstate |= Qt::WindowActive;
if (newstate & Qt::WindowActive)
normal = SW_SHOWNORMAL;
if (isWindow()) {
@@ -490,13 +490,13 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
d->topData()->normalGeometry = geometry();
}
if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
- if (!(newstate & Qt::WindowMaximized)) {
+ if (!(newstate & Qt::WindowMaximized)) {
int style = GetWindowLong(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION;
SetWindowLong(internalWinId(), GWL_STYLE, style);
SetWindowLong(internalWinId(), GWL_EXSTYLE, GetWindowLong (internalWinId(), GWL_EXSTYLE) & ~ WS_EX_NODRAG);
}
- if (isVisible() && newstate & Qt::WindowMaximized)
- qt_wince_maximize(this);
+ if (isVisible() && newstate & Qt::WindowMaximized)
+ qt_wince_maximize(this);
if (isVisible() && !(newstate & Qt::WindowMinimized)) {
ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal);
if (!(newstate & Qt::WindowFullScreen)) {
@@ -558,18 +558,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
else if (newstate & Qt::WindowMaximized) {
ShowWindow(internalWinId(), max);
qt_wince_maximize(this);
+ } else {
+ ShowWindow(internalWinId(), normal);
}
}
- if ((newstate & Qt::WindowMaximized) && !(newstate & Qt::WindowFullScreen)) {
- QRect r = d->topData()->normalGeometry;
-#ifdef Q_WS_WINCE_WM
- if (!inherits("QDialog") && !inherits("QMdiArea") && !isVisible()) {
- d->data.crect.setRect(0, 0, -1, -1);
- }
-#else
- qt_wince_maximize(this);
-#endif
- }
}
data->window_state = newstate;
QWindowStateChangeEvent e(oldstate);
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 283dfb25c7..7461637ba0 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -518,14 +518,18 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
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 (parentWidget && parentWidget->d_func()->xinfo.screen() != xinfo.screen()) {
- xinfo = parentWidget->d_func()->xinfo;
+ } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
+ || parentXinfo->visual() != xinfo.visual()))
+ {
+ xinfo = *parentXinfo;
}
//get display, screen number, root window and desktop geometry for
@@ -920,6 +924,43 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
#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.
+ QEvent e(QEvent::ParentChange);
+ QApplication::sendEvent(widget, &e);
+ } 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
@@ -930,29 +971,9 @@ void QWidgetPrivate::x11UpdateIsOpaque()
bool topLevel = (data.window_flags & Qt::Window);
int screen = xinfo.screen();
if (topLevel && X11->use_xrender
- && X11->argbVisuals[screen] && xinfo.depth() != 32) {
-
- if (q->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.
- QEvent e(QEvent::ParentChange);
- QApplication::sendEvent(q, &e);
- }
- else {
- // For regular widgets, reparent them with their parent which
- // also triggers a recreation of the native window
- QPoint pos = q->pos();
- bool visible = q->isVisible();
- if (visible)
- q->hide();
-
- q->setParent(q->parentWidget(), q->windowFlags());
- q->move(pos);
- if (visible)
- q->show();
- }
+ && X11->argbVisuals[screen] && xinfo.depth() != 32)
+ {
+ qt_x11_recreateNativeWidgetsRecursive(q);
}
#endif
}
@@ -1424,7 +1445,7 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
icon_data[pos++] = image.width();
icon_data[pos++] = image.height();
if (sizeof(long) == sizeof(quint32)) {
- memcpy(icon_data.data() + pos, image.scanLine(0), image.numBytes());
+ 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));
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
index 461959410e..7dff54317e 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
@@ -52,20 +52,22 @@
QT_BEGIN_NAMESPACE
+#if !defined(QT_NO_NATIVE_GESTURES)
+
QWinNativePanGestureRecognizer::QWinNativePanGestureRecognizer()
{
}
-QGesture* QWinNativePanGestureRecognizer::createGesture(QObject *target) const
+QGesture *QWinNativePanGestureRecognizer::create(QObject *target)
{
if (!target)
return new QPanGesture; // a special case
- if (qobject_cast<QGraphicsObject*>(target))
- return 0;
if (!target->isWidgetType())
return 0;
+ if (qobject_cast<QGraphicsObject *>(target))
+ return 0;
- QWidget *q = static_cast<QWidget*>(target);
+ QWidget *q = static_cast<QWidget *>(target);
QWidgetPrivate *d = q->d_func();
d->nativeGesturePanEnabled = true;
d->winSetupGestures();
@@ -73,7 +75,9 @@ QGesture* QWinNativePanGestureRecognizer::createGesture(QObject *target) const
return new QPanGesture;
}
-QGestureRecognizer::Result QWinNativePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event)
+QGestureRecognizer::Result QWinNativePanGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
{
QPanGesture *q = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = q->d_func();
@@ -85,26 +89,25 @@ QGestureRecognizer::Result QWinNativePanGestureRecognizer::filterEvent(QGesture
case QNativeGestureEvent::GestureBegin:
break;
case QNativeGestureEvent::Pan:
- result = QGestureRecognizer::GestureTriggered;
+ result = QGestureRecognizer::TriggerGesture;
event->accept();
break;
case QNativeGestureEvent::GestureEnd:
if (q->state() == Qt::NoGesture)
return QGestureRecognizer::Ignore; // some other gesture has ended
- result = QGestureRecognizer::GestureFinished;
+ result = QGestureRecognizer::FinishGesture;
break;
default:
return QGestureRecognizer::Ignore;
}
if (q->state() == Qt::NoGesture) {
- d->lastOffset = d->totalOffset = d->offset = QSize();
+ d->lastOffset = d->offset = QPointF();
+ d->startPosition = ev->position;
} else {
d->lastOffset = d->offset;
- d->offset = QSize(ev->position.x() - d->lastPosition.x(),
- ev->position.y() - d->lastPosition.y());
- d->totalOffset += d->offset;
+ d->offset = QPointF(ev->position.x() - d->startPosition.x(),
+ ev->position.y() - d->startPosition.y());
}
- d->lastPosition = ev->position;
}
return result;
}
@@ -114,11 +117,13 @@ void QWinNativePanGestureRecognizer::reset(QGesture *state)
QPanGesture *pan = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = pan->d_func();
- d->totalOffset = d->lastOffset = d->offset = QSizeF();
- d->lastPosition = QPoint();
+ d->lastOffset = d->offset = QPointF();
+ d->startPosition = QPoint();
d->acceleration = 0;
QGestureRecognizer::reset(state);
}
+#endif // QT_NO_NATIVE_GESTURES
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
index a1e8511f66..7d53ed2b57 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
@@ -57,17 +57,20 @@
QT_BEGIN_NAMESPACE
+#if !defined(QT_NO_NATIVE_GESTURES)
+
class QWinNativePanGestureRecognizer : public QGestureRecognizer
{
public:
QWinNativePanGestureRecognizer();
- QGesture* createGesture(QObject *target) const;
-
- QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
void reset(QGesture *state);
};
+#endif // QT_NO_NATIVE_GESTURES
+
QT_END_NAMESPACE
#endif // QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H
diff --git a/src/gui/kernel/symbian.pri b/src/gui/kernel/symbian.pri
index 5497ccb2da..69422dd02e 100644
--- a/src/gui/kernel/symbian.pri
+++ b/src/gui/kernel/symbian.pri
@@ -1,4 +1,7 @@
symbian {
contains(QT_CONFIG, s60): LIBS+= $$QMAKE_LIBS_S60
RESOURCES += symbian/symbianresources.qrc
+
+ HEADERS += symbian/qsymbianevent.h
+ SOURCES += symbian/qsymbianevent.cpp
}
diff --git a/src/gui/math3d/qgenericmatrix.cpp b/src/gui/math3d/qgenericmatrix.cpp
index d211229eed..aa985362d3 100644
--- a/src/gui/math3d/qgenericmatrix.cpp
+++ b/src/gui/math3d/qgenericmatrix.cpp
@@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE
The contents of the array \a values is assumed to be in
row-major order.
- \sa toValueArray()
+ \sa copyDataTo()
*/
/*!
@@ -102,11 +102,11 @@ QT_BEGIN_NAMESPACE
Returns true if this matrix is the identity; false otherwise.
- \sa setIdentity()
+ \sa setToIdentity()
*/
/*!
- \fn void QGenericMatrix::setIdentity()
+ \fn void QGenericMatrix::setToIdentity()
Sets this matrix to the identity.
@@ -213,9 +213,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QGenericMatrix::toValueArray(T *values)
+ \fn void QGenericMatrix::copyDataTo(T *values) const
- Retrieves the N * M items in this matrix and writes them to \a values
+ Retrieves the N * M items in this matrix and copies them to \a values
in row-major order.
*/
@@ -243,4 +243,100 @@ QT_BEGIN_NAMESPACE
\sa data()
*/
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
+ \relates QGenericMatrix
+
+ Writes the given \a matrix to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
+ \relates QGenericMatrix
+
+ Reads a NxM matrix from the given \a stream into the given \a matrix
+ and returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+#endif
+
+/*!
+ \typedef QMatrix2x2
+ \relates QGenericMatrix
+
+ The QMatrix2x2 type defines a convenient instantiation of the
+ QGenericMatrix template for 2 columns, 2 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix2x3
+ \relates QGenericMatrix
+
+ The QMatrix2x3 type defines a convenient instantiation of the
+ QGenericMatrix template for 2 columns, 3 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix2x4
+ \relates QGenericMatrix
+
+ The QMatrix2x4 type defines a convenient instantiation of the
+ QGenericMatrix template for 2 columns, 4 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix3x2
+ \relates QGenericMatrix
+
+ The QMatrix3x2 type defines a convenient instantiation of the
+ QGenericMatrix template for 3 columns, 2 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix3x3
+ \relates QGenericMatrix
+
+ The QMatrix3x3 type defines a convenient instantiation of the
+ QGenericMatrix template for 3 columns, 3 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix3x4
+ \relates QGenericMatrix
+
+ The QMatrix3x4 type defines a convenient instantiation of the
+ QGenericMatrix template for 3 columns, 4 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix4x2
+ \relates QGenericMatrix
+
+ The QMatrix4x2 type defines a convenient instantiation of the
+ QGenericMatrix template for 4 columns, 2 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix4x3
+ \relates QGenericMatrix
+
+ The QMatrix4x3 type defines a convenient instantiation of the
+ QGenericMatrix template for 4 columns, 3 rows, and qreal as
+ the element type.
+*/
+
QT_END_NAMESPACE
diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h
index f178d027bf..3871754324 100644
--- a/src/gui/math3d/qgenericmatrix.h
+++ b/src/gui/math3d/qgenericmatrix.h
@@ -44,6 +44,7 @@
#include <QtCore/qmetatype.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qdatastream.h>
QT_BEGIN_HEADER
@@ -63,7 +64,7 @@ public:
T& operator()(int row, int column);
bool isIdentity() const;
- void setIdentity();
+ void setToIdentity();
void fill(T value);
@@ -76,7 +77,7 @@ public:
bool operator==(const QGenericMatrix<N, M, T>& other) const;
bool operator!=(const QGenericMatrix<N, M, T>& other) const;
- void toValueArray(T *values);
+ void copyDataTo(T *values) const;
T *data() { return m[0]; }
const T *data() const { return m[0]; }
@@ -113,7 +114,7 @@ private:
template <int N, int M, typename T>
Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix()
{
- setIdentity();
+ setToIdentity();
}
template <int N, int M, typename T>
@@ -164,7 +165,7 @@ Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
}
template <int N, int M, typename T>
-Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setIdentity()
+Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
{
for (int col = 0; col < N; ++col) {
for (int row = 0; row < M; ++row) {
@@ -316,7 +317,7 @@ Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M
}
template <int N, int M, typename T>
-Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::toValueArray(T *values)
+Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
{
for (int col = 0; col < N; ++col)
for (int row = 0; row < M; ++row)
@@ -352,6 +353,32 @@ QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
#endif
+#ifndef QT_NO_DATASTREAM
+
+template <int N, int M, typename T>
+QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
+{
+ for (int row = 0; row < M; ++row)
+ for (int col = 0; col < N; ++col)
+ stream << double(matrix(row, col));
+ return stream;
+}
+
+template <int N, int M, typename T>
+QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
+{
+ double x;
+ for (int row = 0; row < M; ++row) {
+ for (int col = 0; col < N; ++col) {
+ stream >> x;
+ matrix(row, col) = T(x);
+ }
+ }
+ return stream;
+}
+
+#endif
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QMatrix2x2)
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index ed1b13d4dd..2c3d616473 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -58,6 +58,8 @@ QT_BEGIN_NAMESPACE
\sa QVector3D, QGenericMatrix
*/
+static const qreal inv_dist_to_plane = 1. / 1024.;
+
/*!
\fn QMatrix4x4::QMatrix4x4()
@@ -71,10 +73,10 @@ QT_BEGIN_NAMESPACE
If the matrix has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa toValueArray(), inferSpecialType()
+ \sa copyDataTo(), optimize()
*/
QMatrix4x4::QMatrix4x4(const qreal *values)
{
@@ -94,10 +96,10 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
If the matrix has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa inferSpecialType()
+ \sa optimize()
*/
#if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
@@ -174,10 +176,10 @@ QMatrix4x4::QMatrix4x4(const qreal *values, int cols, int rows)
If \a matrix has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa toAffine(), inferSpecialType()
+ \sa toAffine(), optimize()
*/
QMatrix4x4::QMatrix4x4(const QMatrix& matrix)
{
@@ -206,10 +208,10 @@ QMatrix4x4::QMatrix4x4(const QMatrix& matrix)
If \a transform has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa toTransform(), inferSpecialType()
+ \sa toTransform(), optimize()
*/
QMatrix4x4::QMatrix4x4(const QTransform& transform)
{
@@ -247,7 +249,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
Returns a reference to the element at position (\a row, \a column)
in this matrix so that the element can be assigned to.
- \sa inferSpecialType(), setColumn(), setRow()
+ \sa optimize(), setColumn(), setRow()
*/
/*!
@@ -287,11 +289,11 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
Returns true if this matrix is the identity; false otherwise.
- \sa setIdentity()
+ \sa setToIdentity()
*/
/*!
- \fn void QMatrix4x4::setIdentity()
+ \fn void QMatrix4x4::setToIdentity()
Sets this matrix to the identity.
@@ -692,11 +694,11 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor)
/*!
Multiplies this matrix by another that scales coordinates by
- the components of \a vector. Returns this matrix.
+ the components of \a vector.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector)
+void QMatrix4x4::scale(const QVector3D& vector)
{
qreal vx = vector.x();
qreal vy = vector.y();
@@ -730,7 +732,6 @@ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector)
m[2][3] *= vz;
flagBits = General;
}
- return *this;
}
#endif
@@ -738,11 +739,11 @@ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector)
\overload
Multiplies this matrix by another that scales coordinates by the
- components \a x, and \a y. Returns this matrix.
+ components \a x, and \a y.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y)
+void QMatrix4x4::scale(qreal x, qreal y)
{
if (flagBits == Identity) {
m[0][0] = x;
@@ -766,18 +767,17 @@ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y)
m[1][3] *= y;
flagBits = General;
}
- return *this;
}
/*!
\overload
Multiplies this matrix by another that scales coordinates by the
- components \a x, \a y, and \a z. Returns this matrix.
+ components \a x, \a y, and \a z.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y, qreal z)
+void QMatrix4x4::scale(qreal x, qreal y, qreal z)
{
if (flagBits == Identity) {
m[0][0] = x;
@@ -808,18 +808,17 @@ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y, qreal z)
m[2][3] *= z;
flagBits = General;
}
- return *this;
}
/*!
\overload
Multiplies this matrix by another that scales coordinates by the
- given \a factor. Returns this matrix.
+ given \a factor.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(qreal factor)
+void QMatrix4x4::scale(qreal factor)
{
if (flagBits == Identity) {
m[0][0] = factor;
@@ -850,17 +849,16 @@ QMatrix4x4& QMatrix4x4::scale(qreal factor)
m[2][3] *= factor;
flagBits = General;
}
- return *this;
}
#ifndef QT_NO_VECTOR3D
/*!
Multiplies this matrix by another that translates coordinates by
- the components of \a vector. Returns this matrix.
+ the components of \a vector.
\sa scale(), rotate()
*/
-QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector)
+void QMatrix4x4::translate(const QVector3D& vector)
{
qreal vx = vector.x();
qreal vy = vector.y();
@@ -893,7 +891,6 @@ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector)
else if (flagBits != (Rotation | Translation))
flagBits = General;
}
- return *this;
}
#endif
@@ -902,11 +899,11 @@ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector)
\overload
Multiplies this matrix by another that translates coordinates
- by the components \a x, and \a y. Returns this matrix.
+ by the components \a x, and \a y.
\sa scale(), rotate()
*/
-QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y)
+void QMatrix4x4::translate(qreal x, qreal y)
{
if (flagBits == Identity) {
m[3][0] = x;
@@ -933,18 +930,17 @@ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y)
else if (flagBits != (Rotation | Translation))
flagBits = General;
}
- return *this;
}
/*!
\overload
Multiplies this matrix by another that translates coordinates
- by the components \a x, \a y, and \a z. Returns this matrix.
+ by the components \a x, \a y, and \a z.
\sa scale(), rotate()
*/
-QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y, qreal z)
+void QMatrix4x4::translate(qreal x, qreal y, qreal z)
{
if (flagBits == Identity) {
m[3][0] = x;
@@ -974,20 +970,19 @@ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y, qreal z)
else if (flagBits != (Rotation | Translation))
flagBits = General;
}
- return *this;
}
#ifndef QT_NO_VECTOR3D
/*!
Multiples this matrix by another that rotates coordinates through
- \a angle degrees about \a vector. Returns this matrix.
+ \a angle degrees about \a vector.
\sa scale(), translate()
*/
-QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
+void QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
{
- return rotate(angle, vector.x(), vector.y(), vector.z());
+ rotate(angle, vector.x(), vector.y(), vector.z());
}
#endif
@@ -996,14 +991,14 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
\overload
Multiplies this matrix by another that rotates coordinates through
- \a angle degrees about the vector (\a x, \a y, \a z). Returns this matrix.
+ \a angle degrees about the vector (\a x, \a y, \a z).
\sa scale(), translate()
*/
-QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
+void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
{
if (angle == 0.0f)
- return *this;
+ return;
QMatrix4x4 m(1); // The "1" says to not load the identity.
qreal c, s, ic;
if (angle == 90.0f || angle == -270.0f) {
@@ -1025,7 +1020,7 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
if (y == 0.0f) {
if (z != 0.0f) {
// Rotate around the Z axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[0][0] = c;
m.m[1][1] = c;
if (z < 0.0f) {
@@ -1040,7 +1035,7 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
}
} else if (z == 0.0f) {
// Rotate around the Y axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[0][0] = c;
m.m[2][2] = c;
if (y < 0.0f) {
@@ -1055,7 +1050,7 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
}
} else if (y == 0.0f && z == 0.0f) {
// Rotate around the X axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[1][1] = c;
m.m[2][2] = c;
if (x < 0.0f) {
@@ -1100,19 +1095,121 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
flagBits = flags | Rotation;
else
flagBits = Rotation;
- return *this;
}
-#ifndef QT_NO_VECTOR4D
+/*!
+ \internal
+*/
+void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
+{
+ // Used by QGraphicsRotation::applyTo() to perform a rotation
+ // and projection back to 2D in a single step.
+ if (angle == 0.0f)
+ return;
+ QMatrix4x4 m(1); // The "1" says to not load the identity.
+ qreal c, s, ic;
+ if (angle == 90.0f || angle == -270.0f) {
+ s = 1.0f;
+ c = 0.0f;
+ } else if (angle == -90.0f || angle == 270.0f) {
+ s = -1.0f;
+ c = 0.0f;
+ } else if (angle == 180.0f || angle == -180.0f) {
+ s = 0.0f;
+ c = -1.0f;
+ } else {
+ qreal a = angle * M_PI / 180.0f;
+ c = qCos(a);
+ s = qSin(a);
+ }
+ bool quick = false;
+ if (x == 0.0f) {
+ if (y == 0.0f) {
+ if (z != 0.0f) {
+ // Rotate around the Z axis.
+ m.setToIdentity();
+ m.m[0][0] = c;
+ m.m[1][1] = c;
+ if (z < 0.0f) {
+ m.m[1][0] = s;
+ m.m[0][1] = -s;
+ } else {
+ m.m[1][0] = -s;
+ m.m[0][1] = s;
+ }
+ m.flagBits = General;
+ quick = true;
+ }
+ } else if (z == 0.0f) {
+ // Rotate around the Y axis.
+ m.setToIdentity();
+ m.m[0][0] = c;
+ m.m[2][2] = 1.0f;
+ if (y < 0.0f) {
+ m.m[0][3] = -s * inv_dist_to_plane;
+ } else {
+ m.m[0][3] = s * inv_dist_to_plane;
+ }
+ m.flagBits = General;
+ quick = true;
+ }
+ } else if (y == 0.0f && z == 0.0f) {
+ // Rotate around the X axis.
+ m.setToIdentity();
+ m.m[1][1] = c;
+ m.m[2][2] = 1.0f;
+ if (x < 0.0f) {
+ m.m[1][3] = s * inv_dist_to_plane;
+ } else {
+ m.m[1][3] = -s * inv_dist_to_plane;
+ }
+ m.flagBits = General;
+ quick = true;
+ }
+ if (!quick) {
+ qreal len = x * x + y * y + z * z;
+ if (!qFuzzyIsNull(len - 1.0f) && !qFuzzyIsNull(len)) {
+ len = qSqrt(len);
+ x /= len;
+ y /= len;
+ z /= len;
+ }
+ ic = 1.0f - c;
+ m.m[0][0] = x * x * ic + c;
+ m.m[1][0] = x * y * ic - z * s;
+ m.m[2][0] = 0.0f;
+ m.m[3][0] = 0.0f;
+ m.m[0][1] = y * x * ic + z * s;
+ m.m[1][1] = y * y * ic + c;
+ m.m[2][1] = 0.0f;
+ m.m[3][1] = 0.0f;
+ m.m[0][2] = 0.0f;
+ m.m[1][2] = 0.0f;
+ m.m[2][2] = 1.0f;
+ m.m[3][2] = 0.0f;
+ m.m[0][3] = (x * z * ic - y * s) * -inv_dist_to_plane;
+ m.m[1][3] = (y * z * ic + x * s) * -inv_dist_to_plane;
+ m.m[2][3] = 0.0f;
+ m.m[3][3] = 1.0f;
+ }
+ int flags = flagBits;
+ *this *= m;
+ if (flags != Identity)
+ flagBits = flags | Rotation;
+ else
+ flagBits = Rotation;
+}
+
+#ifndef QT_NO_QUATERNION
/*!
Multiples this matrix by another that rotates coordinates according
to a specified \a quaternion. The \a quaternion is assumed to have
- been normalized. Returns this matrix.
+ been normalized.
\sa scale(), translate(), QQuaternion
*/
-QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion)
+void QMatrix4x4::rotate(const QQuaternion& quaternion)
{
// Algorithm from:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54
@@ -1148,7 +1245,6 @@ QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion)
flagBits = flags | Rotation;
else
flagBits = Rotation;
- return *this;
}
#endif
@@ -1159,17 +1255,16 @@ QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion)
Multiplies this matrix by another that applies an orthographic
projection for a window with boundaries specified by \a rect.
The near and far clipping planes will be -1 and 1 respectively.
- Returns this matrix.
\sa frustum(), perspective()
*/
-QMatrix4x4& QMatrix4x4::ortho(const QRect& rect)
+void QMatrix4x4::ortho(const QRect& rect)
{
// Note: rect.right() and rect.bottom() subtract 1 in QRect,
// which gives the location of a pixel within the rectangle,
// instead of the extent of the rectangle. We want the extent.
// QRectF expresses the extent properly.
- return ortho(rect.x(), rect.x() + rect.width(), rect.y() + rect.height(), rect.y(), -1.0f, 1.0f);
+ ortho(rect.x(), rect.x() + rect.width(), rect.y() + rect.height(), rect.y(), -1.0f, 1.0f);
}
/*!
@@ -1178,28 +1273,27 @@ QMatrix4x4& QMatrix4x4::ortho(const QRect& rect)
Multiplies this matrix by another that applies an orthographic
projection for a window with boundaries specified by \a rect.
The near and far clipping planes will be -1 and 1 respectively.
- Returns this matrix.
\sa frustum(), perspective()
*/
-QMatrix4x4& QMatrix4x4::ortho(const QRectF& rect)
+void QMatrix4x4::ortho(const QRectF& rect)
{
- return ortho(rect.left(), rect.right(), rect.bottom(), rect.top(), -1.0f, 1.0f);
+ ortho(rect.left(), rect.right(), rect.bottom(), rect.top(), -1.0f, 1.0f);
}
/*!
Multiplies this matrix by another that applies an orthographic
projection for a window with lower-left corner (\a left, \a bottom),
upper-right corner (\a right, \a top), and the specified \a nearPlane
- and \a farPlane clipping planes. Returns this matrix.
+ and \a farPlane clipping planes.
\sa frustum(), perspective()
*/
-QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
{
// Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane)
- return *this;
+ return;
// Construct the projection.
qreal width = right - left;
@@ -1218,7 +1312,7 @@ QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top,
(2.0f / width,
2.0f / invheight,
-1.0f));
- return *this;
+ return;
}
#endif
QMatrix4x4 m(1);
@@ -1241,22 +1335,22 @@ QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top,
// Apply the projection.
*this *= m;
- return *this;
+ return;
}
/*!
Multiplies this matrix by another that applies a perspective
frustum projection for a window with lower-left corner (\a left, \a bottom),
upper-right corner (\a right, \a top), and the specified \a nearPlane
- and \a farPlane clipping planes. Returns this matrix.
+ and \a farPlane clipping planes.
\sa ortho(), perspective()
*/
-QMatrix4x4& QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
{
// Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane)
- return *this;
+ return;
// Construct the projection.
QMatrix4x4 m(1);
@@ -1282,7 +1376,6 @@ QMatrix4x4& QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top
// Apply the projection.
*this *= m;
- return *this;
}
/*!
@@ -1290,22 +1383,21 @@ QMatrix4x4& QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top
projection. The field of view will be \a angle degrees within
a window with a given \a aspect ratio. The projection will
have the specified \a nearPlane and \a farPlane clipping planes.
- Returns this matrix.
\sa ortho(), frustum()
*/
-QMatrix4x4& QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane)
{
// Bail out if the projection volume is zero-sized.
if (nearPlane == farPlane || aspect == 0.0f)
- return *this;
+ return;
// Construct the projection.
QMatrix4x4 m(1);
qreal radians = (angle / 2.0f) * M_PI / 180.0f;
qreal sine = qSin(radians);
if (sine == 0.0f)
- return *this;
+ return;
qreal cotan = qCos(radians) / sine;
qreal clip = farPlane - nearPlane;
m.m[0][0] = cotan / aspect;
@@ -1327,7 +1419,6 @@ QMatrix4x4& QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane,
// Apply the projection.
*this *= m;
- return *this;
}
#ifndef QT_NO_VECTOR3D
@@ -1337,9 +1428,8 @@ QMatrix4x4& QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane,
transformation. The \a center value indicates the center of the
view that the \a eye is looking at. The \a up value indicates
which direction should be considered up with respect to the \a eye.
- Returns this matrix.
*/
-QMatrix4x4& QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up)
+void QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up)
{
QVector3D forward = (center - eye).normalized();
QVector3D side = QVector3D::crossProduct(forward, up).normalized();
@@ -1365,7 +1455,7 @@ QMatrix4x4& QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, co
m.m[3][3] = 1.0f;
*this *= m;
- return translate(-eye);
+ translate(-eye);
}
#endif
@@ -1374,11 +1464,11 @@ QMatrix4x4& QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, co
Flips between right-handed and left-handed coordinate systems
by multiplying the y and z co-ordinates by -1. This is normally
used to create a left-handed orthographic view without scaling
- the viewport as ortho() does. Returns this matrix.
+ the viewport as ortho() does.
\sa ortho()
*/
-QMatrix4x4& QMatrix4x4::flipCoordinates()
+void QMatrix4x4::flipCoordinates()
{
if (flagBits == Scale || flagBits == (Scale | Translation)) {
m[1][1] = -m[1][1];
@@ -1402,14 +1492,13 @@ QMatrix4x4& QMatrix4x4::flipCoordinates()
m[2][3] = -m[2][3];
flagBits = General;
}
- return *this;
}
/*!
- Retrieves the 16 items in this matrix and writes them to \a values
+ Retrieves the 16 items in this matrix and copies them to \a values
in row-major order.
*/
-void QMatrix4x4::toValueArray(qreal *values) const
+void QMatrix4x4::copyDataTo(qreal *values) const
{
for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col)
@@ -1430,15 +1519,31 @@ QMatrix QMatrix4x4::toAffine() const
m[3][0], m[3][1]);
}
-static const qreal inv_dist_to_plane = 1. / 1024.;
+/*!
+ Returns the conventional Qt 2D transformation matrix that
+ corresponds to this matrix.
+
+ The returned QTransform is formed by simply dropping the
+ third row and third column of the QMatrix4x4. This is suitable
+ for implementing orthographic projections where the z co-ordinate
+ should be dropped rather than projected.
+
+ \sa toAffine()
+*/
+QTransform QMatrix4x4::toTransform() const
+{
+ return QTransform(m[0][0], m[0][1], m[0][3],
+ m[1][0], m[1][1], m[1][3],
+ m[3][0], m[3][1], m[3][3]);
+}
/*!
Returns the conventional Qt 2D transformation matrix that
corresponds to this matrix.
If \a distanceToPlane is non-zero, it indicates a projection
- factor to use to adjust for the z co-ordinate. The default
- value of 1024 corresponds to the projection factor used
+ factor to use to adjust for the z co-ordinate. The value of
+ 1024 corresponds to the projection factor used
by QTransform::rotate() for the x and y axes.
If \a distanceToPlane is zero, then the returned QTransform
@@ -1617,7 +1722,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
Returns a pointer to the raw data of this matrix.
- \sa constData(), inferSpecialType()
+ \sa constData(), optimize()
*/
/*!
@@ -1666,94 +1771,8 @@ QMatrix4x4 QMatrix4x4::orthonormalInverse() const
return result;
}
-#ifndef QT_NO_VECTOR3D
-/*!
- Decomposes the current rotation matrix into an \a axis of rotation plus
- an \a angle. The result can be used to construct an equivalent rotation
- matrix using glRotate(). It is assumed that the homogenous coordinate
- is 1.0. The returned vector is guaranteed to be normalized.
-
- \code
- qreal angle;
- QVector3D axis;
-
- matrix.extractAxisAngle(angle, axis);
- glRotate(angle, axis[0], axis[1], axis[2]);
- \endcode
-
- \sa rotate()
-*/
-void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const
-{
- // Orientation is dependent on the upper 3x3 matrix; subtract the
- // homogeneous scaling element from the trace of the 4x4 matrix
- qreal tr = m[0][0] + m[1][1] + m[2][2];
- qreal cosa = qreal(0.5f * (tr - 1.0f));
- angle = acos(cosa) * 180.0f / M_PI;
-
- // Any axis will work if r is zero (means no rotation)
- if (qFuzzyIsNull(angle)) {
- axis.setX(1.0f);
- axis.setY(0.0f);
- axis.setZ(0.0f);
- return;
- }
-
- if (angle < 180.0f) {
- axis.setX(m[1][2] - m[2][1]);
- axis.setY(m[2][0] - m[0][2]);
- axis.setZ(m[0][1] - m[1][0]);
- axis.normalize();
- return;
- }
-
- // rads == PI
- qreal tmp;
-
- // r00 is maximum
- if ((m[0][0] >= m[2][2]) && (m[0][0] >= m[1][1])) {
- axis.setX(0.5f * qSqrt(m[0][0] - m[1][1] - m[2][2] + 1.0f));
- tmp = 0.5f / axis.x();
- axis.setY(m[1][0] * tmp);
- axis.setZ(m[2][0] * tmp);
- }
-
- // r11 is maximum
- if ((m[1][1] >= m[2][2]) && (m[1][1] >= m[0][0])) {
- axis.setY(0.5f * qSqrt(m[1][1] - m[0][0] - m[2][2] + 1.0f));
- tmp = 0.5f / axis.y();
- axis.setX(tmp * m[1][0]);
- axis.setZ(tmp * m[2][1]);
- }
-
- // r22 is maximum
- if ((m[2][2] >= m[1][1]) && (m[2][2] >= m[0][0])) {
- axis.setZ(0.5f * qSqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f));
- tmp = 0.5f / axis.z();
- axis.setX(m[2][0]*tmp);
- axis.setY(m[2][1]*tmp);
- }
-}
-
-/*!
- If this is an orthonormal transformation matrix (e.g. only rotations and
- translations have been applied to the matrix, no scaling, or shearing)
- then the world translational component can be obtained by calling this function.
-
- This is most useful for camera matrices, where the negation of this vector
- is effectively the camera world coordinates.
-*/
-QVector3D QMatrix4x4::extractTranslation() const
-{
- return QVector3D
- (m[0][0] * m[3][0] + m[0][1] * m[3][1] + m[0][2] * m[3][2],
- m[1][0] * m[3][0] + m[1][1] * m[3][1] + m[1][2] * m[3][2],
- m[2][0] * m[3][0] + m[2][1] * m[3][1] + m[2][2] * m[3][2]);
-}
-#endif
-
/*!
- Infers the special type of this matrix from its current elements.
+ Optimize the usage of this matrix from its current elements.
Some operations such as translate(), scale(), and rotate() can be
performed more efficiently if the matrix being modified is already
@@ -1766,13 +1785,13 @@ QVector3D QMatrix4x4::extractTranslation() const
the special type and will revert to the safest but least efficient
operations thereafter.
- By calling inferSpecialType() after directly modifying the matrix,
+ By calling optimize() after directly modifying the matrix,
the programmer can force QMatrix4x4 to recover the special type if
the elements appear to conform to one of the known optimized types.
\sa operator()(), data(), translate()
*/
-void QMatrix4x4::inferSpecialType()
+void QMatrix4x4::optimize()
{
// If the last element is not 1, then it can never be special.
if (m[3][3] != 1.0f) {
@@ -1889,7 +1908,7 @@ QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix)
matrix(row, col) = qreal(x);
}
}
- matrix.inferSpecialType();
+ matrix.optimize();
return stream;
}
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index b32e00a16a..4193bdc79e 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -63,7 +63,7 @@ class QVariant;
class Q_GUI_EXPORT QMatrix4x4
{
public:
- inline QMatrix4x4() { setIdentity(); }
+ inline QMatrix4x4() { setToIdentity(); }
explicit QMatrix4x4(const qreal *values);
inline QMatrix4x4(qreal m11, qreal m12, qreal m13, qreal m14,
qreal m21, qreal m22, qreal m23, qreal m24,
@@ -87,7 +87,7 @@ public:
inline void setRow(int index, const QVector4D& value);
inline bool isIdentity() const;
- inline void setIdentity();
+ inline void setToIdentity();
inline void fill(qreal value);
@@ -127,39 +127,35 @@ public:
friend inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2);
#ifndef QT_NO_VECTOR3D
- QMatrix4x4& scale(const QVector3D& vector);
- QMatrix4x4& translate(const QVector3D& vector);
- QMatrix4x4& rotate(qreal angle, const QVector3D& vector);
+ void scale(const QVector3D& vector);
+ void translate(const QVector3D& vector);
+ void rotate(qreal angle, const QVector3D& vector);
#endif
- QMatrix4x4& scale(qreal x, qreal y);
- QMatrix4x4& scale(qreal x, qreal y, qreal z);
- QMatrix4x4& scale(qreal factor);
- QMatrix4x4& translate(qreal x, qreal y);
- QMatrix4x4& translate(qreal x, qreal y, qreal z);
- QMatrix4x4& rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f);
+ void scale(qreal x, qreal y);
+ void scale(qreal x, qreal y, qreal z);
+ void scale(qreal factor);
+ void translate(qreal x, qreal y);
+ void translate(qreal x, qreal y, qreal z);
+ void rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f);
#ifndef QT_NO_QUATERNION
- QMatrix4x4& rotate(const QQuaternion& quaternion);
+ void rotate(const QQuaternion& quaternion);
#endif
+ void ortho(const QRect& rect);
+ void ortho(const QRectF& rect);
+ void ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
+ void frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
+ void perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane);
#ifndef QT_NO_VECTOR3D
- void extractAxisRotation(qreal &angle, QVector3D &axis) const;
- QVector3D extractTranslation() const;
+ void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
#endif
+ void flipCoordinates();
- QMatrix4x4& ortho(const QRect& rect);
- QMatrix4x4& ortho(const QRectF& rect);
- QMatrix4x4& ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
- QMatrix4x4& frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
- QMatrix4x4& perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane);
-#ifndef QT_NO_VECTOR3D
- QMatrix4x4& lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
-#endif
- QMatrix4x4& flipCoordinates();
-
- void toValueArray(qreal *values) const;
+ void copyDataTo(qreal *values) const;
QMatrix toAffine() const;
- QTransform toTransform(qreal distanceToPlane = 1024.0f) const;
+ QTransform toTransform() const;
+ QTransform toTransform(qreal distanceToPlane) const;
QPoint map(const QPoint& point) const;
QPointF map(const QPointF& point) const;
@@ -182,7 +178,7 @@ public:
inline const qreal *data() const { return m[0]; }
inline const qreal *constData() const { return m[0]; }
- void inferSpecialType();
+ void optimize();
operator QVariant() const;
@@ -206,6 +202,10 @@ private:
QMatrix4x4(int) { flagBits = General; }
QMatrix4x4 orthonormalInverse() const;
+
+ void projectedRotate(qreal angle, qreal x, qreal y, qreal z);
+
+ friend class QGraphicsRotation;
};
inline QMatrix4x4::QMatrix4x4
@@ -325,7 +325,7 @@ inline bool QMatrix4x4::isIdentity() const
return (m[3][3] == 1.0f);
}
-inline void QMatrix4x4::setIdentity()
+inline void QMatrix4x4::setToIdentity()
{
m[0][0] = 1.0f;
m[0][1] = 0.0f;
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index d5ec054a6d..626cb3ccf1 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -288,7 +288,7 @@ void QQuaternion::normalize()
in 3D space. The following code:
\code
- QVector3D result = q.rotateVector(vector);
+ QVector3D result = q.rotatedVector(vector);
\endcode
is equivalent to the following:
@@ -297,7 +297,7 @@ void QQuaternion::normalize()
QVector3D result = (q * QQuaternion(0, vector) * q.conjugate()).vector();
\endcode
*/
-QVector3D QQuaternion::rotateVector(const QVector3D& vector) const
+QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const
{
return (*this * QQuaternion(0, vector) * conjugate()).vector();
}
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index 7480a5cdae..5b2454f3c3 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -95,7 +95,7 @@ public:
QQuaternion conjugate() const;
- QVector3D rotateVector(const QVector3D& vector) const;
+ QVector3D rotatedVector(const QVector3D& vector) const;
QQuaternion &operator+=(const QQuaternion &quaternion);
QQuaternion &operator-=(const QQuaternion &quaternion);
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 2c6dedadad..97007d81cf 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -381,7 +381,6 @@ symbian {
SOURCES += painting/qwindowsurface_s60.cpp
armccIfdefBlock = \
"$${LITERAL_HASH}if defined(ARMV6)" \
- "MACRO QT_HAVE_ARMV6" \
"SOURCEPATH painting" \
"SOURCE qblendfunctions_armv6_rvct.s" \
"SOURCE qdrawhelper_armv6_rvct.s" \
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 2272d45095..882ae6c882 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -56,6 +56,7 @@
#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"
@@ -497,18 +498,6 @@ static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately)
if (!widget)
return;
-#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
- if (QApplicationPrivate::inSizeMove && widget->internalWinId() && !updateImmediately
- && !widget->testAttribute(Qt::WA_DontShowOnScreen)) {
- // Tell Windows to send us a paint event if we're in WM_SIZE/WM_MOVE; posted events
- // are blocked until the mouse button is released. See task 146849.
- const QRegion rgn(qt_dirtyRegion(widget));
- InvalidateRgn(widget->internalWinId(), rgn.handle(), false);
- qt_widget_private(widget)->dirty = QRegion();
- return;
- }
-#endif
-
if (updateImmediately) {
QEvent event(QEvent::UpdateRequest);
QApplication::sendEvent(widget, &event);
@@ -540,6 +529,10 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
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;
@@ -568,9 +561,11 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
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);
@@ -585,9 +580,11 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
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 {
@@ -615,6 +612,10 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool upd
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);
@@ -889,7 +890,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
const QRect parentRect(rect & clipR);
bool accelerateMove = accelEnv && isOpaque
-#ifndef QT_NO_GRAPHICSCVIEW
+#ifndef QT_NO_GRAPHICSVIEW
// No accelerate move for proxy widgets.
&& !tlw->d_func()->extra->proxyWidget
#endif
@@ -1187,7 +1188,7 @@ void QWidgetBackingStore::sync()
: wd->dirty);
toClean += widgetDirty;
-#ifndef QT_NO_GRAPHICSCVIEW
+#ifndef QT_NO_GRAPHICSVIEW
if (tlw->d_func()->extra->proxyWidget) {
resetWidget(w);
continue;
diff --git a/src/gui/painting/qbackingstore_p.h b/src/gui/painting/qbackingstore_p.h
index 94d756ea96..fbef9801a5 100644
--- a/src/gui/painting/qbackingstore_p.h
+++ b/src/gui/painting/qbackingstore_p.h
@@ -97,6 +97,12 @@ public:
);
}
+ // ### 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
@@ -126,11 +132,6 @@ private:
QRegion dirtyRegion(QWidget *widget = 0) const;
QRegion staticContents(QWidget *widget = 0, const QRect &withinClipRect = QRect()) const;
- // ### 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);
void markDirtyOnScreen(const QRegion &dirtyOnScreen, QWidget *widget, const QPoint &topLevelOffset);
void removeDirtyWidget(QWidget *w);
@@ -145,9 +146,11 @@ private:
{
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;
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 89adaf51aa..b92c5c20ee 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -223,11 +223,24 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
- const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1;
- const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1;
- quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
- quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
+ quint32 basex;
+ quint32 srcy;
+
+ if (sx < 0) {
+ int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;
+ basex = quint32(srcRect.right() * 65536) + dstx;
+ } else {
+ int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;
+ basex = quint32(srcRect.left() * 65536) + dstx;
+ }
+ if (sy < 0) {
+ int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;
+ srcy = quint32(srcRect.bottom() * 65536) + dsty;
+ } else {
+ int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;
+ srcy = quint32(srcRect.top() * 65536) + dsty;
+ }
quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;
@@ -374,9 +387,9 @@ template <typename T> void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl,
const uchar *src = srcPixels + y * sbpl;
const uchar *srcEnd = src + srcOffset;
while (src < srcEnd) {
-#if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || defined(QT_ARCH_SH) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_))
+#if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || defined(QT_ARCH_SH) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_)) || (defined(QT_ARCH_SPARC) && defined(Q_CC_GNU))
// non-16-bit aligned memory access is not possible on PowerPC,
- // ARM <v6 (QT_ARCH_ARMV6) & SH & AVR32
+ // ARM <v6 (QT_ARCH_ARMV6) & SH & AVR32 & SPARC w/GCC
quint16 spix = (quint16(src[2])<<8) + src[1];
#else
quint16 spix = *(quint16 *) (src + 1);
@@ -723,11 +736,27 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
+ quint32 basex;
+ quint32 srcy;
+
const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1;
const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1;
- quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
- quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
+
+ if (sx < 0) {
+ int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;
+ basex = quint32(srcRect.right() * 65536) + dstx;
+ } else {
+ int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;
+ basex = quint32(srcRect.left() * 65536) + dstx;
+ }
+ if (sy < 0) {
+ int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;
+ srcy = quint32(srcRect.bottom() * 65536) + dsty;
+ } else {
+ int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;
+ srcy = quint32(srcRect.top() * 65536) + dsty;
+ }
quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index cbfbba63da..7273c35cee 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -970,7 +970,29 @@ bool QBrush::operator==(const QBrush &b) const
QDebug operator<<(QDebug dbg, const QBrush &b)
{
#ifndef Q_BROKEN_DEBUG_STREAM
- dbg.nospace() << "QBrush(" << b.color() << ',' << b.style() << ')';
+ static const char *BRUSH_STYLES[] = {
+ "NoBrush",
+ "SolidPattern",
+ "Dense1Pattern",
+ "Dense2Pattern",
+ "Dense3Pattern",
+ "Dense4Pattern",
+ "Dense5Pattern",
+ "Dense6Pattern",
+ "Dense7Pattern",
+ "HorPattern",
+ "VerPattern",
+ "CrossPattern",
+ "BDiagPattern",
+ "FDiagPattern",
+ "DiagCrossPattern",
+ "LinearGradientPattern",
+ "RadialGradientPattern",
+ "ConicalGradientPattern",
+ "TexturePattern"
+ };
+
+ dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
return dbg.space();
#else
qWarning("This compiler doesn't support streaming QBrush to QDebug");
diff --git a/src/gui/painting/qcolormap_qws.cpp b/src/gui/painting/qcolormap_qws.cpp
index ce4cd0995d..bc97b086e7 100644
--- a/src/gui/painting/qcolormap_qws.cpp
+++ b/src/gui/painting/qcolormap_qws.cpp
@@ -170,7 +170,7 @@ const QColor QColormap::colorAt(uint pixel) const
(pixel & green_mask) >> green_shift,
(pixel & blue_mask));
}
- Q_ASSERT_X(int(pixel) < qt_screen->numCols(), "QColormap::colorAt", "pixel out of bounds of palette");
+ Q_ASSERT_X(int(pixel) < qt_screen->colorCount(), "QColormap::colorAt", "pixel out of bounds of palette");
return QColor(qt_screen->clut()[pixel]);
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 53edbb0b96..4df7f8ab20 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -2386,12 +2386,12 @@ static void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int len
}
/*
- if 2.Sca < Sa
- Dca' = Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise if 8.Dca <= Da
- Dca' = Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa).(3 - 8.Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise
- Dca' = (Dca.Sa + ((Dca/Da)^(0.5).Da - Dca).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ 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)
*/
static inline int soft_light_op(int dst, int src, int da, int sa)
{
@@ -2400,13 +2400,11 @@ static inline int soft_light_op(int dst, int src, int da, int sa)
const int temp = (src * (255 - da) + dst * (255 - sa)) * 255;
if (src2 < sa)
- return (dst * ((sa * 255) - (255 - dst_np) * (src2 - sa)) + temp) / 65025;
- else if (8 * dst <= da)
- return (dst * ((sa * 255) - ((255 - dst_np) * (src2 - sa) * ((3 * 255) - 8 * dst_np)) / 255) + temp) / 65025;
+ return (dst * (sa * 255 + (src2 - sa) * (255 - dst_np)) + temp) / 65025;
+ else if (4 * dst <= da)
+ return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
else {
- // sqrt is too expensive to do three times per pixel, so skipping it for now
- // a future possibility is to use a LUT
- return ((dst * sa * 255) + (int(dst_np) * da - (dst * 255)) * (src2 - sa) + temp) / 65025;
+ return (dst * sa * 255 + da * (src2 - sa) * (int(sqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
}
}
@@ -7424,6 +7422,14 @@ QT_RECTFILL(qrgb444)
QT_RECTFILL(qargb4444)
#undef QT_RECTFILL
+inline static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
+{
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
// Map table for destination image format. Contains function pointers
// for blends of various types unto the destination
@@ -7466,7 +7472,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_quint32
+ qt_rectfill_nonpremul_quint32
},
// Format_ARGB32_Premultiplied
{
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index 88b2b7aafa..17b7241926 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -85,7 +85,7 @@ QT_BEGIN_NAMESPACE
which returns true if the matrix is non-singular (i.e. AB = BA =
I). The inverted() function returns an inverted copy of \e this
matrix if it is invertible (otherwise it returns the identity
- matrix). In addition, QMatrix provides the det() function
+ matrix). In addition, QMatrix provides the determinant() function
returning the matrix's determinant.
Finally, the QMatrix class supports matrix multiplication, and
@@ -959,9 +959,19 @@ QMatrix &QMatrix::rotate(qreal a)
*/
/*!
+ \obsolete
\fn qreal QMatrix::det() const
Returns the matrix's determinant.
+
+ \sa determinant()
+*/
+
+/*!
+ \since 4.6
+ \fn qreal QMatrix::determinant() const
+
+ Returns the matrix's determinant.
*/
/*!
@@ -985,8 +995,8 @@ QMatrix &QMatrix::rotate(qreal a)
QMatrix QMatrix::inverted(bool *invertible) const
{
- qreal determinant = det();
- if (determinant == 0.0) {
+ qreal dtr = determinant();
+ if (dtr == 0.0) {
if (invertible)
*invertible = false; // singular matrix
return QMatrix(true);
@@ -994,7 +1004,7 @@ QMatrix QMatrix::inverted(bool *invertible) const
else { // invertible matrix
if (invertible)
*invertible = true;
- qreal dinv = 1.0/determinant;
+ qreal dinv = 1.0/dtr;
return QMatrix((_m22*dinv), (-_m12*dinv),
(-_m21*dinv), (_m11*dinv),
((_m21*_dy - _m22*_dx)*dinv),
diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h
index 8887f0ef7c..152b3c9b40 100644
--- a/src/gui/painting/qmatrix.h
+++ b/src/gui/painting/qmatrix.h
@@ -101,7 +101,8 @@ public:
QMatrix &rotate(qreal a);
bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); }
- qreal det() const { return _m11*_m22 - _m12*_m21; }
+ qreal determinant() const { return _m11*_m22 - _m12*_m21; }
+ QT_DEPRECATED qreal det() const { return _m11*_m22 - _m12*_m21; }
QMatrix inverted(bool *invertible = 0) const;
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index 6b9d77c77a..b8700c33e9 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -48,7 +48,7 @@
#include <QDebug>
-//#define QPAINTBUFFER_DEBUG_DRAW
+// #define QPAINTBUFFER_DEBUG_DRAW
QT_BEGIN_NAMESPACE
@@ -247,23 +247,24 @@ void QPaintBuffer::draw(QPainter *painter, int frame) const
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << "QPaintBuffer::draw() --------------------------------";
-// printf("Float buffer:");
-// for (int i=0; i<d->floats.size(); i++) {
-// if ((i % 10) == 0) {
-// printf("\n%4d-%4d: ", i, i+9);
-// }
-// printf("%4.2f ", d->floats[i]);
-// }
-// printf("\n");
-
-// printf("Int Buffer:");
-// for (int i=0; i<d->ints.size(); i++) {
-// if ((i % 10) == 0) {
-// printf("\n%4d-%4d: ", i, i+10);
-// }
-// printf("%5d", d->ints[i]);
-// }
-// printf("\n");
+ Q_D(const QPaintBuffer);
+ printf("Float buffer:");
+ for (int i=0; i<d->floats.size(); i++) {
+ if ((i % 10) == 0) {
+ printf("\n%4d-%4d: ", i, i+9);
+ }
+ printf("%4.2f ", d->floats[i]);
+ }
+ printf("\n");
+
+ printf("Int Buffer:");
+ for (int i=0; i<d->ints.size(); i++) {
+ if ((i % 10) == 0) {
+ printf("\n%4d-%4d: ", i, i+10);
+ }
+ printf("%5d", d->ints[i]);
+ }
+ printf("\n");
#endif
if (painter && !painter->isActive())
@@ -406,16 +407,17 @@ void QPaintBufferEngine::clipEnabledChanged()
void QPaintBufferEngine::penChanged()
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine:" << state()->pen;
-#endif
const QPen &pen = state()->pen;
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetPen) {
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: penChanged (compressed)" << state()->pen;
+#endif
buffer->variants[buffer->commands.last().offset] = pen;
return;
}
+
if (buffer->calculateBoundingRect) {
if (pen.style() == Qt::NoPen) {
buffer->penWidthAdjustment = 0;
@@ -427,22 +429,28 @@ void QPaintBufferEngine::penChanged()
buffer->penWidthAdjustment = transformedWidth.x() / 2.0;
}
}
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: penChanged" << state()->pen;
+#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetPen, pen);
}
void QPaintBufferEngine::brushChanged()
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine:" << state()->brush;
-#endif
const QBrush &brush = state()->brush;
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetBrush) {
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: brushChanged (compressed)" << state()->brush;
+#endif
buffer->variants[buffer->commands.last().offset] = brush;
return;
}
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: brushChanged" << state()->brush;
+#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetBrush, brush);
}
@@ -488,14 +496,14 @@ void QPaintBufferEngine::transformChanged()
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetTransform) {
#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: compressing " << state()->matrix;
+ qDebug() << "QPaintBufferEngine: transformChanged (compressing) " << state()->matrix;
#endif
buffer->variants[buffer->commands.last().offset] = state()->matrix;
return;
}
#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: " << state()->matrix;
+ qDebug() << "QPaintBufferEngine: transformChanged:" << state()->matrix;
#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetTransform, state()->matrix);
}
@@ -514,7 +522,18 @@ void QPaintBufferEngine::draw(const QVectorPath &path)
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << "QPaintBufferEngine: draw vpath:" << path.elementCount();
#endif
- buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path);
+
+ bool hasBrush = qbrush_style(state()->brush) != Qt::NoBrush;
+ bool hasPen = qpen_style(state()->pen) != Qt::NoPen
+ && qbrush_style(qpen_brush(state()->pen)) != Qt::NoBrush;
+
+ if (hasPen || hasBrush)
+ buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path);
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ else
+ qDebug() << " - no pen or brush active, discarded...\n";
+#endif
+
// if (buffer->calculateBoundingRect) {
// QRealRect r = path.controlPointRect();
// buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1));
@@ -745,15 +764,15 @@ void QPaintBufferEngine::drawEllipse(const QRect &r)
void QPaintBufferEngine::drawPath(const QPainterPath &path)
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: drawPath: element count:" << path.elementCount();
-#endif
- // ### Path -> QVariant
- // buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPath, QVariant(path));
+// #ifdef QPAINTBUFFER_DEBUG_DRAW
+// qDebug() << "QPaintBufferEngine: drawPath: element count:" << path.elementCount();
+// #endif
+// // ### Path -> QVariant
+// // buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPath, QVariant(path));
QPaintEngineEx::drawPath(path);
- if (buffer->calculateBoundingRect)
- buffer->updateBoundingRect(path.boundingRect());
+// if (buffer->calculateBoundingRect)
+// buffer->updateBoundingRect(path.boundingRect());
}
void QPaintBufferEngine::drawPoints(const QPoint *points, int pointCount)
@@ -1424,10 +1443,6 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
QTextItemInt &ti = (*tiCopy)();
QString text(ti.text());
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << " -> Cmd_DrawTextItem:" << pos << " " << text << " " << scaleFactor;
-#endif
-
QFont font(ti.font());
font.setUnderline(false);
font.setStrikeOut(false);
@@ -1439,6 +1454,10 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
justificationWidth = si.width.toReal();
qreal scaleFactor = font.d->dpi/qreal(qt_defaultDpiY());
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << " -> Cmd_DrawTextItem:" << pos << " " << text << " " << scaleFactor;
+#endif
+
if (scaleFactor != 1.0) {
QFont fnt(font);
QFakeDevice fake;
diff --git a/src/gui/painting/qpaintbuffer_p.h b/src/gui/painting/qpaintbuffer_p.h
index 6a7ac7342c..e100512f18 100644
--- a/src/gui/painting/qpaintbuffer_p.h
+++ b/src/gui/painting/qpaintbuffer_p.h
@@ -66,6 +66,7 @@ class QPaintBufferPlayback;
class Q_GUI_EXPORT QPaintBuffer : public QPaintDevice
{
+ Q_DECLARE_PRIVATE(QPaintBuffer)
public:
QPaintBuffer();
QPaintBuffer(const QPaintBuffer &other);
@@ -311,7 +312,7 @@ public:
virtual ~QPainterReplayer() { }
void setupTransform(QPainter *painter);
- void process(const QPaintBufferCommand &cmd);
+ virtual void process(const QPaintBufferCommand &cmd);
void draw(const QPaintBuffer &buffer, QPainter *painter, int frame);
protected:
@@ -326,7 +327,7 @@ class Q_GUI_EXPORT QPaintEngineExReplayer : public QPainterReplayer
public:
QPaintEngineExReplayer() { }
- void process(const QPaintBufferCommand &cmd);
+ virtual void process(const QPaintBufferCommand &cmd);
};
class QPaintBufferEnginePrivate;
diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp
index 5138d3d2e4..75d19afd33 100644
--- a/src/gui/painting/qpaintdevice.cpp
+++ b/src/gui/painting/qpaintdevice.cpp
@@ -67,4 +67,9 @@ int QPaintDevice::metric(PaintDeviceMetric) const
}
#endif
+Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice::PaintDeviceMetric metric)
+{
+ return device->metric(metric);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h
index 92aa3cb224..9148e4b7ec 100644
--- a/src/gui/painting/qpaintdevice.h
+++ b/src/gui/painting/qpaintdevice.h
@@ -96,7 +96,8 @@ public:
int logicalDpiY() const { return metric(PdmDpiY); }
int physicalDpiX() const { return metric(PdmPhysicalDpiX); }
int physicalDpiY() const { return metric(PdmPhysicalDpiY); }
- int numColors() const { return metric(PdmNumColors); }
+ QT_DEPRECATED int numColors() const { return metric(PdmNumColors); }
+ int colorCount() const { return metric(PdmNumColors); }
int depth() const { return metric(PdmDepth); }
protected:
@@ -137,6 +138,7 @@ public:
friend class QPainter;
friend class QFontEngineMac;
friend class QX11PaintEngine;
+ friend Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, PaintDeviceMetric metric);
};
#ifdef QT3_SUPPORT
diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc
index dca7e0ea16..ac1c3def31 100644
--- a/src/gui/painting/qpaintdevice.qdoc
+++ b/src/gui/painting/qpaintdevice.qdoc
@@ -83,7 +83,7 @@
inch. The physicalDpiX() and physicalDpiY() functions also return
the resolution of the device in dots per inch, but note that if
the logical and vertical resolution differ, the corresponding
- QPaintEngine must handle the mapping. Finally, the numColors()
+ QPaintEngine must handle the mapping. Finally, the colorCount()
function returns the number of different colors available for the
paint device.
@@ -111,7 +111,7 @@
also heightMM().
\value PdmNumColors The number of different colors available for
- the paint device. See also numColors().
+ the paint device. See also colorCount().
\value PdmDepth The bit depth (number of bit planes) of the paint
device. See also depth().
@@ -221,11 +221,23 @@
/*!
\fn int QPaintDevice::numColors() const
+ \deprecated
+
+ Use colorCount() instead.
+
+ Returns the number of different colors available for the paint
+ device. Since this value is an int, it will not be sufficient to
+ represent the number of colors on 32 bit displays, in this case
+ INT_MAX is returned instead.
+ */
+
+/*!
+ \fn int QPaintDevice::colorCount() const
Returns the number of different colors available for the paint
- device. Since this value is an int, it will not be sufficient to represent
- the number of colors on 32 bit displays, in this case INT_MAX is
- returned instead.
+ device. Since this value is an int, it will not be sufficient to
+ represent the number of colors on 32 bit displays, in this case
+ INT_MAX is returned instead.
*/
/*!
diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
index 321bbf5e9f..c042cb0968 100644
--- a/src/gui/painting/qpaintengine.h
+++ b/src/gui/painting/qpaintengine.h
@@ -282,6 +282,7 @@ private:
friend class QWin32PaintEnginePrivate;
friend class QMacCGContext;
friend class QPreviewPaintEngine;
+ friend class QX11GLPixmapData;
};
diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp
index e6863736de..c1b887cc81 100644
--- a/src/gui/painting/qpaintengine_mac.cpp
+++ b/src/gui/painting/qpaintengine_mac.cpp
@@ -1023,7 +1023,7 @@ CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imag
#endif
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image,
static_cast<const QImage *>(image)->bits(),
- image->numBytes(),
+ image->byteCount(),
drawImageReleaseData);
if (imagePtr)
*imagePtr = image;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 6037bd5199..3f33319f1c 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -132,6 +132,10 @@ static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
extern bool qt_cleartype_enabled;
#endif
+#ifdef Q_WS_MAC
+extern bool qt_applefontsmoothing_enabled;
+#endif
+
/********************************************************************************
* Span functions
@@ -508,7 +512,7 @@ bool QRasterPaintEngine::begin(QPaintDevice *device)
#if defined(Q_WS_WIN)
else if (qt_cleartype_enabled)
#elif defined (Q_WS_MAC)
- else if (true)
+ else if (qt_applefontsmoothing_enabled)
#else
else if (false)
#endif
@@ -1358,7 +1362,7 @@ void QRasterPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
Q_D(QRasterPaintEngine);
- if (region.numRects() == 1) {
+ if (region.rectCount() == 1) {
clip(region.boundingRect(), op);
return;
}
@@ -1682,7 +1686,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
if (!s->penData.blend)
return;
- if (s->flags.fast_pen && path.shape() <= QVectorPath::NonCurvedShapeHint
+ if (s->flags.fast_pen && !path.isCurved()
&& s->lastPen.brush().isOpaque()) {
int count = path.elementCount();
QPointF *points = (QPointF *) path.points();
@@ -1735,8 +1739,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
const QLineF *lines = reinterpret_cast<const QLineF *>(path.points());
for (int i = 0; i < lineCount; ++i) {
- if (path.shape() == QVectorPath::LinesHint)
- dashOffset = s->lastPen.dashOffset();
+ dashOffset = s->lastPen.dashOffset();
if (lines[i].p1() == lines[i].p2()) {
if (s->lastPen.capStyle() != Qt::FlatCap) {
QPointF p = lines[i].p1();
@@ -2376,6 +2379,7 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
if (s->matrix.type() <= QTransform::TxTranslate) {
+ ensurePen();
drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
} else {
drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
@@ -2389,6 +2393,7 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
if (s->matrix.type() <= QTransform::TxTranslate) {
+ ensurePen();
drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
} else {
drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
@@ -4213,13 +4218,6 @@ void QRasterBuffer::prepare(QCustomRasterPaintDevice *device)
drawHelper = qDrawHelper + format;
}
-class MetricAccessor : public QWidget {
-public:
- int metric(PaintDeviceMetric m) {
- return QWidget::metric(m);
- }
-};
-
int QCustomRasterPaintDevice::metric(PaintDeviceMetric m) const
{
switch (m) {
@@ -4231,7 +4229,7 @@ int QCustomRasterPaintDevice::metric(PaintDeviceMetric m) const
break;
}
- return (static_cast<MetricAccessor*>(widget)->metric(m));
+ return qt_paint_device_metric(widget, m);
}
int QCustomRasterPaintDevice::bytesPerLine() const
@@ -4538,7 +4536,7 @@ void QClipData::setClipRect(const QRect &rect)
*/
void QClipData::setClipRegion(const QRegion &region)
{
- if (region.numRects() == 1) {
+ if (region.rectCount() == 1) {
setClipRect(region.rects().at(0));
return;
}
@@ -5121,6 +5119,9 @@ void QSpanData::adjustSpanMethods()
#else
unclipped_blend = qBlendTexture;
#endif
+ if (!texture.imageData)
+ unclipped_blend = 0;
+
break;
}
// setup clipping
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index 59482c6dca..35b77f7e59 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -146,7 +146,7 @@ static inline int qpainterOpToXrender(QPainter::CompositionMode mode)
// hack, so we don't have to make QRegion::clipRectangles() public or include
// X11 headers in qregion.h
-Q_AUTOTEST_EXPORT void *qt_getClipRects(const QRegion &r, int &num)
+Q_GUI_EXPORT void *qt_getClipRects(const QRegion &r, int &num)
{
return r.clipRectangles(num);
}
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 195be0a33f..7d1c109de7 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -92,6 +92,24 @@ QRectF QVectorPath::controlPointRect() const
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
}
+
+QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data,
+ qvectorpath_cache_cleanup cleanup) {
+ Q_ASSERT(!lookupCacheData(engine));
+ if ((m_hints & IsCachedHint) == 0) {
+ m_cache = 0;
+ m_hints |= IsCachedHint;
+ }
+ CacheEntry *e = new CacheEntry;
+ e->engine = engine;
+ e->data = data;
+ e->cleanup = cleanup;
+ e->next = m_cache;
+ m_cache = e;
+ return m_cache;
+}
+
+
const QVectorPath &qtVectorPathForPath(const QPainterPath &path)
{
Q_ASSERT(path.d_func());
@@ -413,8 +431,12 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
// Some engines might decide to optimize for the non-shape hint later on...
uint flags = QVectorPath::WindingFill;
+
+ if (path.elementCount() > 2)
+ flags |= QVectorPath::NonConvexShapeMask;
+
if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
- flags |= QVectorPath::CurvedShapeHint;
+ flags |= QVectorPath::CurvedShapeMask;
// ### Perspective Xforms are currently not supported...
if (!pen.isCosmetic()) {
@@ -442,7 +464,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
points[4], points[5]);
points += 6;
types += 3;
- flags |= QVectorPath::CurvedShapeHint;
+ flags |= QVectorPath::CurvedShapeMask;
break;
default:
break;
@@ -504,7 +526,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
points += 6;
types += 3;
- flags |= QVectorPath::CurvedShapeHint;
+ flags |= QVectorPath::CurvedShapeMask;
break;
}
default:
@@ -580,7 +602,7 @@ void QPaintEngineEx::clip(const QRect &r, Qt::ClipOperation op)
void QPaintEngineEx::clip(const QRegion &region, Qt::ClipOperation op)
{
- if (region.numRects() == 1)
+ if (region.rectCount() == 1)
clip(region.boundingRect(), op);
QVector<QRect> rects = region.rects();
@@ -736,7 +758,7 @@ void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yR
x1 + xRadius, y1
};
- QVectorPath path(pts, 17, qpaintengineex_roundedrect_types);
+ QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint);
draw(path);
}
@@ -827,7 +849,7 @@ void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount)
pts[++oset] = points[i].x() + 0.001;
pts[++oset] = points[i].y();
}
- QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint);
+ QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
stroke(path, pen);
pointCount -= 16;
points += 16;
@@ -858,7 +880,7 @@ void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount)
pts[++oset] = points[i].x() + 0.001;
pts[++oset] = points[i].y();
}
- QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint);
+ QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
stroke(path, pen);
pointCount -= 16;
points += 16;
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index 3ec9bd60b1..02d77f46d0 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -250,9 +250,9 @@ public:
inline uint QVectorPath::polygonFlags(QPaintEngine::PolygonDrawMode mode) {
switch (mode) {
case QPaintEngine::ConvexMode: return ConvexPolygonHint | ImplicitClose;
- case QPaintEngine::OddEvenMode: return NonCurvedShapeHint | OddEvenFill | ImplicitClose;
- case QPaintEngine::WindingMode: return NonCurvedShapeHint | WindingFill | ImplicitClose;
- case QPaintEngine::PolylineMode: return NonCurvedShapeHint;
+ case QPaintEngine::OddEvenMode: return PolygonHint | OddEvenFill | ImplicitClose;
+ case QPaintEngine::WindingMode: return PolygonHint | WindingFill | ImplicitClose;
+ case QPaintEngine::PolylineMode: return PolygonHint;
default: return 0;
}
}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index f271af9856..48629d196c 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1608,9 +1608,21 @@ void QPainter::restore()
\warning A paint device can only be painted by one painter at a
time.
+ \warning Painting on a QImage with the format
+ QImage::Format_Indexed8 is not supported.
+
\sa end(), QPainter()
*/
+static inline void qt_cleanup_painter_state(QPainterPrivate *d)
+{
+ d->states.clear();
+ delete d->state;
+ d->state = 0;
+ d->engine = 0;
+ d->device = 0;
+}
+
bool QPainter::begin(QPaintDevice *pd)
{
Q_ASSERT(pd);
@@ -1656,15 +1668,21 @@ bool QPainter::begin(QPaintDevice *pd)
printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType());
#endif
-
- d->device = pd;
if (pd->devType() == QInternal::Pixmap)
static_cast<QPixmap *>(pd)->detach();
else if (pd->devType() == QInternal::Image)
static_cast<QImage *>(pd)->detach();
d->engine = pd->paintEngine();
- d->extended = d->engine && d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0;
+
+ if (!d->engine) {
+ qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType());
+ return false;
+ }
+
+ d->device = pd;
+
+ d->extended = d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0;
if (d->emulationEngine)
d->emulationEngine->real_engine = d->extended;
@@ -1677,11 +1695,6 @@ bool QPainter::begin(QPaintDevice *pd)
d->state->redirectionMatrix.translate(-redirectionOffset.x(), -redirectionOffset.y());
d->state->brushOrigin = QPointF();
- if (!d->engine) {
- qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType());
- return false;
- }
-
// Slip a painter state into the engine before we do any other operations
if (d->extended)
d->extended->setState(d->state);
@@ -1700,8 +1713,7 @@ bool QPainter::begin(QPaintDevice *pd)
&& !paintOutsidePaintEvent && !inPaintEvent) {
qWarning("QPainter::begin: Widget painting can only begin as a "
"result of a paintEvent");
- d->engine = 0;
- d->device = 0;
+ qt_cleanup_painter_state(d);
return false;
}
@@ -1719,8 +1731,7 @@ bool QPainter::begin(QPaintDevice *pd)
Q_ASSERT(pm);
if (pm->isNull()) {
qWarning("QPainter::begin: Cannot paint on a null pixmap");
- d->engine = 0;
- d->device = 0;
+ qt_cleanup_painter_state(d);
return false;
}
@@ -1736,8 +1747,12 @@ bool QPainter::begin(QPaintDevice *pd)
Q_ASSERT(img);
if (img->isNull()) {
qWarning("QPainter::begin: Cannot paint on a null image");
- d->engine = 0;
- d->device = 0;
+ qt_cleanup_painter_state(d);
+ return false;
+ } else if (img->format() == QImage::Format_Indexed8) {
+ // Painting on indexed8 images is not supported.
+ qWarning("QPainter::begin: Cannot paint on an image with the QImage::Format_Indexed8 format");
+ qt_cleanup_painter_state(d);
return false;
}
if (img->depth() == 1) {
@@ -1760,12 +1775,8 @@ bool QPainter::begin(QPaintDevice *pd)
if (d->engine->isActive()) {
end();
} else {
- d->states.clear();
- delete d->state;
- d->state = 0;
+ qt_cleanup_painter_state(d);
}
- d->engine = 0;
- d->device = 0;
return false;
} else {
d->engine->setActive(begun);
@@ -1828,10 +1839,7 @@ bool QPainter::end()
if (!d->engine) {
qWarning("QPainter::end: Painter not active, aborted");
- d->states.clear();
- delete d->state;
- d->state = 0;
- d->device = 0;
+ qt_cleanup_painter_state(d);
return false;
}
@@ -1862,8 +1870,6 @@ bool QPainter::end()
delete d->engine;
}
- d->engine = 0;
-
if (d->emulationEngine) {
delete d->emulationEngine;
d->emulationEngine = 0;
@@ -1873,11 +1879,8 @@ bool QPainter::end()
d->extended = 0;
}
- d->states.clear();
- delete d->state;
- d->state = 0;
+ qt_cleanup_painter_state(d);
- d->device = 0;
return ended;
}
@@ -2051,8 +2054,7 @@ QPoint QPainter::brushOrigin() const
Sets the brush origin to \a position.
The brush origin specifies the (0, 0) coordinate of the painter's
- brush. This setting only applies to pattern brushes and pixmap
- brushes.
+ brush.
Note that while the brushOrigin() was necessary to adopt the
parent's background for a widget in Qt 3, this is no longer the
@@ -2273,8 +2275,9 @@ void QPainter::setBrushOrigin(const QPointF &p)
/*!
Sets the composition mode to the given \a mode.
- \warning You can only set the composition mode for QPainter
- objects that operates on a QImage.
+ \warning Only a QPainter operating on a QImage fully supports all
+ composition modes. The RasterOp modes are supported for X11 as
+ described in compositionMode().
\sa compositionMode()
*/
@@ -3784,27 +3787,14 @@ void QPainter::setPen(const QPen &pen)
if (d->state->pen == pen)
return;
+ d->state->pen = pen;
+
if (d->extended) {
- d->state->pen = pen;
d->checkEmulation();
d->extended->penChanged();
return;
}
- // Do some checks to see if we are the same pen.
- Qt::PenStyle currentStyle = d->state->pen.style();
- if (currentStyle == pen.style() && currentStyle != Qt::CustomDashLine) {
- if (currentStyle == Qt::NoPen ||
- (d->state->pen.isSolid() && pen.isSolid()
- && d->state->pen.color() == pen.color()
- && d->state->pen.widthF() == pen.widthF()
- && d->state->pen.capStyle() == pen.capStyle()
- && d->state->pen.joinStyle() == pen.joinStyle()
- && d->state->pen.isCosmetic() == pen.isCosmetic()))
- return;
- }
-
- d->state->pen = pen;
d->state->dirtyFlags |= QPaintEngine::DirtyPen;
}
@@ -3887,14 +3877,6 @@ void QPainter::setBrush(const QBrush &brush)
return;
}
- Qt::BrushStyle currentStyle = d->state->brush.style();
- if (currentStyle == brush.style()) {
- if (currentStyle == Qt::NoBrush
- || (currentStyle == Qt::SolidPattern
- && d->state->brush.color() == brush.color()))
- return;
- }
-
d->state->brush = brush;
d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
}
@@ -5161,7 +5143,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
Q_D(QPainter);
- if (!d->engine)
+ if (!d->engine || pm.isNull())
return;
#ifndef QT_NO_DEBUG
@@ -7601,7 +7583,7 @@ start_lengthVariant:
l.setPosition(QPointF(0., height));
height += l.height();
width = qMax(width, l.naturalTextWidth());
- if (!brect && height >= r.height())
+ if (!dontclip && !brect && height >= r.height())
break;
}
textLayout.endLayout();
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 69e189c846..8133793edc 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -688,6 +688,8 @@ void QPainterPath::lineTo(const QPointF &p)
return;
Element elm = { p.x(), p.y(), LineToElement };
d->elements.append(elm);
+
+ d->convex = d->elements.size() == 3 || (d->elements.size() == 4 && d->isClosed());
}
/*!
@@ -960,6 +962,8 @@ void QPainterPath::addRect(const QRectF &r)
ensureData();
detach();
+ bool first = d_func()->elements.size() < 2;
+
d_func()->elements.reserve(d_func()->elements.size() + 5);
moveTo(r.x(), r.y());
@@ -970,6 +974,7 @@ void QPainterPath::addRect(const QRectF &r)
d_func()->elements << l1 << l2 << l3 << l4;
d_func()->require_moveTo = true;
+ d_func()->convex = first;
}
/*!
@@ -1039,6 +1044,7 @@ void QPainterPath::addEllipse(const QRectF &boundingRect)
detach();
Q_D(QPainterPath);
+ bool first = d_func()->elements.size() < 2;
d->elements.reserve(d->elements.size() + 13);
QPointF pts[12];
@@ -1051,6 +1057,8 @@ void QPainterPath::addEllipse(const QRectF &boundingRect)
cubicTo(pts[6], pts[7], pts[8]); // 180 -> 90
cubicTo(pts[9], pts[10], pts[11]); // 90 - >0
d_func()->require_moveTo = true;
+
+ d_func()->convex = first;
}
/*!
@@ -3027,14 +3035,17 @@ void QPainterPath::addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadi
ensureData();
detach();
- arcMoveTo(x, y, rxx2, ryy2, 90);
- arcTo(x, y, rxx2, ryy2, 90, 90);
- arcTo(x, y+h-ryy2, rxx2, ryy2, 2*90, 90);
- arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*90, 90);
- arcTo(x+w-rxx2, y, rxx2, ryy2, 0, 90);
+ bool first = d_func()->elements.size() < 2;
+
+ arcMoveTo(x, y, rxx2, ryy2, 180);
+ arcTo(x, y, rxx2, ryy2, 180, -90);
+ arcTo(x+w-rxx2, y, rxx2, ryy2, 90, -90);
+ arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 0, -90);
+ arcTo(x, y+h-ryy2, rxx2, ryy2, 270, -90);
closeSubpath();
d_func()->require_moveTo = true;
+ d_func()->convex = first;
}
/*!
@@ -3081,14 +3092,17 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)
ensureData();
detach();
- arcMoveTo(x, y, rxx2, ryy2, 90);
- arcTo(x, y, rxx2, ryy2, 90, 90);
- arcTo(x, y+h-ryy2, rxx2, ryy2, 2*90, 90);
- arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*90, 90);
- arcTo(x+w-rxx2, y, rxx2, ryy2, 0, 90);
+ bool first = d_func()->elements.size() < 2;
+
+ arcMoveTo(x, y, rxx2, ryy2, 180);
+ arcTo(x, y, rxx2, ryy2, 180, -90);
+ arcTo(x+w-rxx2, y, rxx2, ryy2, 90, -90);
+ arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 0, -90);
+ arcTo(x, y+h-ryy2, rxx2, ryy2, 270, -90);
closeSubpath();
d_func()->require_moveTo = true;
+ d_func()->convex = first;
}
/*!
@@ -3269,6 +3283,7 @@ void QPainterPath::setDirty(bool dirty)
d_func()->dirtyControlBounds = dirty;
delete d_func()->pathConverter;
d_func()->pathConverter = 0;
+ d_func()->convex = false;
}
void QPainterPath::computeBoundingRect() const
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index 54c182dcc7..54b9392dc7 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -81,8 +81,8 @@ class QVectorPathConverter;
class QVectorPathConverter
{
public:
- QVectorPathConverter(const QVector<QPainterPath::Element> &path, uint fillRule)
- : pathData(path, fillRule),
+ QVectorPathConverter(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex)
+ : pathData(path, fillRule, convex),
path(pathData.points.data(), path.size(),
pathData.elements.data(), pathData.flags) {}
@@ -91,7 +91,7 @@ public:
}
struct QVectorPathData {
- QVectorPathData(const QVector<QPainterPath::Element> &path, uint fillRule)
+ QVectorPathData(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex)
: elements(path.size()),
points(path.size() * 2),
flags(0)
@@ -103,7 +103,7 @@ public:
points[ptsPos++] = e.x;
points[ptsPos++] = e.y;
if (e.type == QPainterPath::CurveToElement)
- flags |= QVectorPath::CurvedShapeHint;
+ flags |= QVectorPath::CurvedShapeMask;
}
if (fillRule == Qt::WindingFill)
@@ -111,6 +111,8 @@ public:
else
flags |= QVectorPath::OddEvenFill;
+ if (!convex)
+ flags |= QVectorPath::NonConvexShapeMask;
}
QVarLengthArray<QPainterPath::ElementType> elements;
QVarLengthArray<qreal> points;
@@ -128,19 +130,24 @@ class QPainterPathData : public QPainterPathPrivate
{
public:
QPainterPathData() :
- cStart(0), fillRule(Qt::OddEvenFill),
- dirtyBounds(false), dirtyControlBounds(false),
+ cStart(0),
+ fillRule(Qt::OddEvenFill),
+ dirtyBounds(false),
+ dirtyControlBounds(false),
pathConverter(0)
{
ref = 1;
require_moveTo = false;
+ convex = false;
}
QPainterPathData(const QPainterPathData &other) :
QPainterPathPrivate(), cStart(other.cStart), fillRule(other.fillRule),
- dirtyBounds(other.dirtyBounds), bounds(other.bounds),
- dirtyControlBounds(other.dirtyControlBounds),
+ bounds(other.bounds),
controlBounds(other.controlBounds),
+ dirtyBounds(other.dirtyBounds),
+ dirtyControlBounds(other.dirtyControlBounds),
+ convex(other.convex),
pathConverter(0)
{
ref = 1;
@@ -158,20 +165,21 @@ public:
const QVectorPath &vectorPath() {
if (!pathConverter)
- pathConverter = new QVectorPathConverter(elements, fillRule);
+ pathConverter = new QVectorPathConverter(elements, fillRule, convex);
return pathConverter->path;
}
int cStart;
Qt::FillRule fillRule;
- bool require_moveTo;
-
- bool dirtyBounds;
QRectF bounds;
- bool dirtyControlBounds;
QRectF controlBounds;
+ uint require_moveTo : 1;
+ uint dirtyBounds : 1;
+ uint dirtyControlBounds : 1;
+ uint convex : 1;
+
QVectorPathConverter *pathConverter;
};
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index ab2dc33023..51d6195ed8 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -1650,7 +1650,7 @@ static void clear(QWingedEdge& list, int edge, QPathEdge::Traversal traversal)
template <typename InputIterator>
InputIterator qFuzzyFind(InputIterator first, InputIterator last, qreal val)
{
- while (first != last && !qFuzzyCompare(qreal(*first), qreal(val)))
+ while (first != last && !QT_PREPEND_NAMESPACE(qFuzzyCompare)(qreal(*first), qreal(val)))
++first;
return first;
}
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 41a7fbb5ba..d45bd10f11 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -78,8 +78,8 @@ const char *qt_real_to_string(qreal val, char *buf) {
unsigned int ival = (unsigned int) val;
qreal frac = val - (qreal)ival;
- int ifrac = (int)(frac * 1000000);
- if (ifrac == 1000000) {
+ int ifrac = (int)(frac * 1000000000);
+ if (ifrac == 1000000000) {
++ival;
ifrac = 0;
}
@@ -90,7 +90,7 @@ const char *qt_real_to_string(qreal val, char *buf) {
++i;
ival /= 10;
}
- int fact = 100000;
+ int fact = 100000000;
if (i == 0) {
*(buf++) = '0';
} else {
@@ -145,7 +145,7 @@ namespace QPdf {
fileBackingActive(false),
handleDirty(false)
{
- dev->open(QIODevice::ReadWrite);
+ dev->open(QIODevice::ReadWrite | QIODevice::Append);
}
ByteStream::ByteStream(bool fileBacking)
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 41efc80fb3..77aa74817f 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -835,16 +835,17 @@ bool QPen::operator==(const QPen &p) const
{
QPenData *dd = static_cast<QPenData *>(d);
QPenData *pdd = static_cast<QPenData *>(p.d);
- return (p.d == d) || (p.d->style == d->style
- && p.d->capStyle == d->capStyle
- && p.d->joinStyle == d->joinStyle
- && p.d->width == d->width
- && pdd->miterLimit == dd->miterLimit
- && (d->style != Qt::CustomDashLine
- || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
- pdd->dashPattern == dd->dashPattern))
- && p.d->brush == d->brush
- && pdd->cosmetic == dd->cosmetic);
+ return (p.d == d)
+ || (p.d->style == d->style
+ && p.d->capStyle == d->capStyle
+ && p.d->joinStyle == d->joinStyle
+ && p.d->width == d->width
+ && pdd->miterLimit == dd->miterLimit
+ && (d->style != Qt::CustomDashLine
+ || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
+ pdd->dashPattern == dd->dashPattern))
+ && p.d->brush == d->brush
+ && pdd->cosmetic == dd->cosmetic);
}
@@ -983,8 +984,18 @@ QDataStream &operator>>(QDataStream &s, QPen &p)
QDebug operator<<(QDebug dbg, const QPen &p)
{
#ifndef Q_BROKEN_DEBUG_STREAM
+ const char *PEN_STYLES[] = {
+ "NoPen",
+ "SolidLine",
+ "DashLine",
+ "DotLine",
+ "DashDotLine",
+ "DashDotDotLine",
+ "CustomDashLine"
+ };
+
dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
- << ',' << int(p.style()) << ',' << int(p.capStyle())
+ << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
<< ',' << int(p.joinStyle()) << ',' << p.dashPattern()
<< ',' << p.dashOffset()
<< ',' << p.miterLimit() << ')';
diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp
index 7e2946a25d..6684ff75f1 100644
--- a/src/gui/painting/qprinterinfo_unix.cpp
+++ b/src/gui/painting/qprinterinfo_unix.cpp
@@ -421,6 +421,7 @@ int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
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;
@@ -444,6 +445,7 @@ int qt_retrieveNisPrinters(QList<QPrinterDescription> *printers)
if (!err)
return Success;
}
+#endif //QT_NO_LIBRARY
return Unavail;
}
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index 66d0c9d927..b602690f3a 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -310,7 +310,7 @@ struct QBoolToType
template <typename T>
void qScanConvert(QScanConverter &d, T allVertical)
{
- qSort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), topOrder);
+ qSort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), QT_PREPEND_NAMESPACE(topOrder));
int line = 0;
for (int y = d.m_lines.first().top; y <= d.m_bottom; ++y) {
for (; line < d.m_lines.size() && d.m_lines.at(line).top == y; ++line) {
@@ -319,7 +319,7 @@ void qScanConvert(QScanConverter &d, T allVertical)
QScanConverter::Line *l = &d.m_lines.at(line);
d.m_active.resize(d.m_active.size() + 1);
int j;
- for (j = d.m_active.size() - 2; j >= 0 && xOrder(l, d.m_active.at(j)); --j)
+ for (j = d.m_active.size() - 2; j >= 0 && QT_PREPEND_NAMESPACE(xOrder)(l, d.m_active.at(j)); --j)
d.m_active.at(j+1) = d.m_active.at(j);
d.m_active.at(j+1) = l;
} else {
@@ -334,7 +334,7 @@ void qScanConvert(QScanConverter &d, T allVertical)
for (int i = 1; i < numActive; ++i) {
QScanConverter::Line *l = d.m_active.at(i);
int j;
- for (j = i-1; j >= 0 && xOrder(l, d.m_active.at(j)); --j)
+ for (j = i-1; j >= 0 && QT_PREPEND_NAMESPACE(xOrder)(l, d.m_active.at(j)); --j)
d.m_active.at(j+1) = d.m_active.at(j);
d.m_active.at(j+1) = l;
}
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index d2ab80cd73..64a64118b8 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -690,7 +690,7 @@ bool QRegion::intersects(const QRegion &region) const
if (!rect_intersects(boundingRect(), region.boundingRect()))
return false;
- if (numRects() == 1 && region.numRects() == 1)
+ if (rectCount() == 1 && region.rectCount() == 1)
return true;
const QVector<QRect> myRects = rects();
@@ -717,7 +717,7 @@ bool QRegion::intersects(const QRect &rect) const
const QRect r = rect.normalized();
if (!rect_intersects(boundingRect(), r))
return false;
- if (numRects() == 1)
+ if (rectCount() == 1)
return true;
const QVector<QRect> myRects = rects();
@@ -739,6 +739,7 @@ QRegion QRegion::intersect(const QRect &r) const
#endif
/*!
+ \obsolete
\fn int QRegion::numRects() const
\since 4.4
@@ -746,6 +747,13 @@ QRegion QRegion::intersect(const QRect &r) const
*/
/*!
+ \fn int QRegion::rectCount() const
+ \since 4.6
+
+ Returns the number of rectangles that will be returned in rects().
+*/
+
+/*!
\fn bool QRegion::isEmpty() const
Returns true if the region is empty; otherwise returns false. An
@@ -1027,7 +1035,7 @@ void addSegmentsToPath(Segment *segment, QPainterPath &path)
Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region)
{
QPainterPath result;
- if (region.numRects() == 1) {
+ if (region.rectCount() == 1) {
result.addRect(region.boundingRect());
return result;
}
@@ -3859,23 +3867,28 @@ QRegion::QRegion(const QRect &r, RegionType t)
QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)
{
if (a.count() > 2) {
- d = new QRegionData;
- d->ref = 1;
+ QRegionPrivate *qt_rgn = PolygonRegion(a.constData(), a.size(),
+ fillRule == Qt::WindingFill ? WindingRule : EvenOddRule);
+ if (qt_rgn) {
+ d = new QRegionData;
+ d->ref = 1;
#if defined(Q_WS_X11)
- d->rgn = 0;
- d->xrectangles = 0;
+ d->rgn = 0;
+ d->xrectangles = 0;
#elif defined(Q_WS_WIN)
- d->rgn = 0;
+ d->rgn = 0;
#endif
- d->qt_rgn = PolygonRegion(a.constData(), a.size(),
- fillRule == Qt::WindingFill ? WindingRule : EvenOddRule);
+ d->qt_rgn = qt_rgn;
+ } else {
+ d = &shared_empty;
+ d->ref.ref();
+ }
} else {
d = &shared_empty;
d->ref.ref();
}
}
-
QRegion::QRegion(const QRegion &r)
{
d = r.d;
@@ -4317,6 +4330,12 @@ int QRegion::numRects() const
return (d->qt_rgn ? d->qt_rgn->numRects : 0);
}
+int QRegion::rectCount() const
+{
+ return (d->qt_rgn ? d->qt_rgn->numRects : 0);
+}
+
+
bool QRegion::operator==(const QRegion &r) const
{
if (!d->qt_rgn)
diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h
index de510ee3ff..eb75733a07 100644
--- a/src/gui/painting/qregion.h
+++ b/src/gui/painting/qregion.h
@@ -116,7 +116,8 @@ public:
QRect boundingRect() const;
QVector<QRect> rects() const;
void setRects(const QRect *rect, int num);
- int numRects() const;
+ QT_DEPRECATED int numRects() const;
+ int rectCount() const;
const QRegion operator|(const QRegion &r) const;
const QRegion operator+(const QRegion &r) const;
diff --git a/src/gui/painting/qregion_s60.cpp b/src/gui/painting/qregion_s60.cpp
index 76b0948ea0..3dc2e8dca3 100644
--- a/src/gui/painting/qregion_s60.cpp
+++ b/src/gui/painting/qregion_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 90639458be..228a6b12f3 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -452,6 +452,17 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
#endif
if (join == FlatJoin) {
+ QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y),
+ qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y));
+ QPointF isect;
+ QLineF::IntersectType type = prevLine.intersect(nextLine, &isect);
+ QLineF shortCut(prevLine.p2(), nextLine.p1());
+ qreal angle = shortCut.angleTo(prevLine);
+ if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
+ emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
+ return;
+ }
emitLineTo(qt_real_to_fixed(nextLine.x1()),
qt_real_to_fixed(nextLine.y1()));
@@ -468,8 +479,8 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
// If we are on the inside, do the short cut...
QLineF shortCut(prevLine.p2(), nextLine.p1());
qreal angle = shortCut.angleTo(prevLine);
-
if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
return;
}
@@ -509,8 +520,9 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
qfixed offset = m_strokeWidth / 2;
QLineF shortCut(prevLine.p2(), nextLine.p1());
- qreal angle = prevLine.angle(shortCut);
+ qreal angle = shortCut.angleTo(prevLine);
if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
return;
}
@@ -581,6 +593,13 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
qt_real_to_fixed(l1.x1()),
qt_real_to_fixed(l1.y1()));
} else if (join == SvgMiterJoin) {
+ QLineF shortCut(prevLine.p2(), nextLine.p1());
+ qreal angle = shortCut.angleTo(prevLine);
+ if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
+ emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
+ return;
+ }
QLineF miterLine(QPointF(qt_fixed_to_real(focal_x),
qt_fixed_to_real(focal_y)), isect);
if (miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) {
@@ -969,13 +988,31 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt
}
+static inline void qdashstroker_moveTo(qfixed x, qfixed y, void *data) {
+ ((QStroker *) data)->moveTo(x, y);
+}
+
+static inline void qdashstroker_lineTo(qfixed x, qfixed y, void *data) {
+ ((QStroker *) data)->lineTo(x, y);
+}
+
+static inline void qdashstroker_cubicTo(qfixed, qfixed, qfixed, qfixed, qfixed, qfixed, void *) {
+ Q_ASSERT(0);
+// ((QStroker *) data)->cubicTo(c1x, c1y, c2x, c2y, ex, ey);
+}
+
+
/*******************************************************************************
* QDashStroker members
*/
QDashStroker::QDashStroker(QStroker *stroker)
- : m_stroker(stroker), m_dashOffset(0)
+ : m_stroker(stroker), m_dashOffset(0), m_stroke_width(1), m_miter_limit(1)
{
-
+ if (m_stroker) {
+ setMoveToHook(qdashstroker_moveTo);
+ setLineToHook(qdashstroker_lineTo);
+ setCubicToHook(qdashstroker_cubicTo);
+ }
}
QVector<qfixed> QDashStroker::patternForStyle(Qt::PenStyle style)
@@ -1012,10 +1049,16 @@ void QDashStroker::processCurrentSubpath()
int dashCount = qMin(m_dashPattern.size(), 32);
qfixed dashes[32];
+ if (m_stroker) {
+ m_customData = m_stroker;
+ m_stroke_width = m_stroker->strokeWidth();
+ m_miter_limit = m_stroker->miterLimit();
+ }
+
qreal longestLength = 0;
qreal sumLength = 0;
for (int i=0; i<dashCount; ++i) {
- dashes[i] = qMax(m_dashPattern.at(i), qreal(0)) * m_stroker->strokeWidth();
+ dashes[i] = qMax(m_dashPattern.at(i), qreal(0)) * m_stroke_width;
sumLength += dashes[i];
if (dashes[i] > longestLength)
longestLength = dashes[i];
@@ -1031,7 +1074,7 @@ void QDashStroker::processCurrentSubpath()
int idash = 0; // Index to current dash
qreal pos = 0; // The position on the curve, 0 <= pos <= path.length
qreal elen = 0; // element length
- qreal doffset = m_dashOffset * m_stroker->strokeWidth();
+ qreal doffset = m_dashOffset * m_stroke_width;
// make sure doffset is in range [0..sumLength)
doffset -= qFloor(doffset / sumLength) * sumLength;
@@ -1056,7 +1099,7 @@ void QDashStroker::processCurrentSubpath()
qfixed2d line_to_pos;
// Pad to avoid clipping the borders of thick pens.
- qfixed padding = qt_real_to_fixed(qMax(m_stroker->strokeWidth(), m_stroker->miterLimit()) * longestLength);
+ qfixed padding = qt_real_to_fixed(qMax(m_stroke_width, m_miter_limit) * longestLength);
qfixed2d clip_tl = { qt_real_to_fixed(m_clip_rect.left()) - padding,
qt_real_to_fixed(m_clip_rect.top()) - padding };
qfixed2d clip_br = { qt_real_to_fixed(m_clip_rect.right()) + padding ,
@@ -1108,7 +1151,7 @@ void QDashStroker::processCurrentSubpath()
// continue the current dash, without starting a
// new subpath.
if (!has_offset || !hasMoveTo) {
- m_stroker->moveTo(move_to_pos.x, move_to_pos.y);
+ emitMoveTo(move_to_pos.x, move_to_pos.y);
hasMoveTo = true;
}
@@ -1120,7 +1163,7 @@ void QDashStroker::processCurrentSubpath()
|| (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x
&& line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y))
{
- m_stroker->lineTo(line_to_pos.x, line_to_pos.y);
+ emitLineTo(line_to_pos.x, line_to_pos.y);
}
} else {
move_to_pos.x = qt_real_to_fixed(p2.x());
@@ -1134,6 +1177,7 @@ void QDashStroker::processCurrentSubpath()
estart = estop;
prev = e;
}
+
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h
index d33eeb4592..a10ebd937c 100644
--- a/src/gui/painting/qstroker_p.h
+++ b/src/gui/painting/qstroker_p.h
@@ -171,7 +171,6 @@ protected:
QRectF m_clip_rect;
-private:
void *m_customData;
qStrokerMoveToHook m_moveTo;
qStrokerLineToHook m_lineTo;
@@ -258,12 +257,18 @@ public:
virtual void begin(void *data);
virtual void end();
+ inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
+ inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
+
protected:
virtual void processCurrentSubpath();
QStroker *m_stroker;
QVector<qfixed> m_dashPattern;
qreal m_dashOffset;
+
+ qreal m_stroke_width;
+ qreal m_miter_limit;
};
@@ -361,16 +366,16 @@ inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y,
*/
inline void QDashStroker::begin(void *data)
{
- Q_ASSERT(m_stroker);
- m_stroker->begin(data);
+ if (m_stroker)
+ m_stroker->begin(data);
QStrokerOps::begin(data);
}
inline void QDashStroker::end()
{
- Q_ASSERT(m_stroker);
QStrokerOps::end();
- m_stroker->end();
+ if (m_stroker)
+ m_stroker->end();
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 25b6abad90..a192e8776c 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -229,8 +229,8 @@ void QImageTextureGlyphCache::createTextureData(int width, int height)
int QImageTextureGlyphCache::glyphMargin() const
{
-#ifdef Q_WS_MAC
- return 2;
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ return 0;
#else
return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
#endif
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 81184501f4..45db80ac64 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -1421,7 +1421,7 @@ QRegion QTransform::map(const QRegion &r) const
return copy;
}
- if (t == TxScale && r.numRects() == 1)
+ if (t == TxScale && r.rectCount() == 1)
return QRegion(mapRect(r.boundingRect()));
QPainterPath p = map(qt_regionToPath(r));
@@ -2214,12 +2214,14 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
{
const QTransform::TransformationType type = transform.type();
if (type <= QTransform::TxTranslate) {
- *scale = 1;
+ if (scale)
+ *scale = 1;
return true;
} else if (type == QTransform::TxScale) {
const qreal xScale = qAbs(transform.m11());
const qreal yScale = qAbs(transform.m22());
- *scale = qMax(xScale, yScale);
+ if (scale)
+ *scale = qMax(xScale, yScale);
return qFuzzyCompare(xScale, yScale);
}
@@ -2227,7 +2229,8 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
+ transform.m21() * transform.m21();
const qreal yScale = transform.m12() * transform.m12()
+ transform.m22() * transform.m22();
- *scale = qSqrt(qMax(xScale, yScale));
+ if (scale)
+ *scale = qSqrt(qMax(xScale, yScale));
return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
}
diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h
index d02313112f..ec27970696 100644
--- a/src/gui/painting/qvectorpath_p.h
+++ b/src/gui/painting/qvectorpath_p.h
@@ -66,8 +66,9 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
+class QPaintEngineEx;
-#define QVECTORPATH_NO_CACHE
+typedef void (*qvectorpath_cache_cleanup)(void *data);
struct QRealRect {
qreal x1, y1, x2, y2;
@@ -77,19 +78,27 @@ class Q_GUI_EXPORT QVectorPath
{
public:
enum Hint {
- // Basic shapes...
- LinesHint = 0x0001, // Just plain lines...
- RectangleHint = 0x0002,
- ConvexPolygonHint = 0x0003, // Convex polygon...
- NonISectPolygonHint = 0x0004, // concave polygon, but not intersecting..
- NonCurvedShapeHint = 0x0005, // Generic polygon, possibly self-intersecting...
- CurvedShapeHint = 0x0006, // Generic vector path..
- EllipseHint = 0x0007,
- ShapeHintMask = 0x000f,
+ // Shape hints, in 0x000000ff, access using shape()
+ AreaShapeMask = 0x0001, // shape covers an area
+ NonConvexShapeMask = 0x0002, // shape is not convex
+ CurvedShapeMask = 0x0004, // shape contains curves...
+ LinesShapeMask = 0x0008,
+ RectangleShapeMask = 0x0010,
+ ShapeMask = 0x001f,
+
+ // Shape hints merged into basic shapes..
+ LinesHint = LinesShapeMask,
+ RectangleHint = AreaShapeMask | RectangleShapeMask,
+ EllipseHint = AreaShapeMask | CurvedShapeMask,
+ ConvexPolygonHint = AreaShapeMask,
+ PolygonHint = AreaShapeMask | NonConvexShapeMask,
+ RoundedRectHint = AreaShapeMask | CurvedShapeMask,
+ ArbitraryShapeHint = AreaShapeMask | NonConvexShapeMask | CurvedShapeMask,
// Other hints
- CacheHint = 0x0100,
- ControlPointRect = 0x0200, // Set if the control point rect has been calculated...
+ IsCachedHint = 0x0100, // Set if the cache hint is set
+ ShouldUseCacheHint = 0x0200, // Set if the path should be cached when possible..
+ ControlPointRect = 0x0400, // Set if the control point rect has been calculated...
// Shape rendering specifiers...
OddEvenFill = 0x1000,
@@ -101,22 +110,21 @@ public:
QVectorPath(const qreal *points,
int count,
const QPainterPath::ElementType *elements = 0,
- uint hints = CurvedShapeHint)
+ uint hints = ArbitraryShapeHint)
: m_elements(elements),
m_points(points),
m_count(count),
m_hints(hints)
-#ifndef QVECTORPATH_NO_CACHE
- , m_cache(0)
-#endif
{
}
QRectF controlPointRect() const;
- inline Hint shape() const { return (Hint) (m_hints & ShapeHintMask); }
+ inline Hint shape() const { return (Hint) (m_hints & ShapeMask); }
+ inline bool isConvex() const { return (m_hints & NonConvexShapeMask) == 0; }
+ inline bool isCurved() const { return m_hints & CurvedShapeMask; }
- inline bool hasCacheHint() const { return m_hints & CacheHint; }
+ inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; }
inline bool hasImplicitClose() const { return m_hints & ImplicitClose; }
inline bool hasWindingFill() const { return m_hints & WindingFill; }
@@ -131,24 +139,30 @@ public:
static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode);
-private:
- Q_DISABLE_COPY(QVectorPath)
-
-#ifndef QVECTORPATH_NO_CACHE
struct CacheEntry {
- void *engine;
- int id;
- void *extra;
+ QPaintEngineEx *engine;
+ void *data;
+ qvectorpath_cache_cleanup cleanup;
CacheEntry *next;
};
- void addCacheData(CacheEntry *d) {
- d->next = m_cache;
- m_cache = d;
+ CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup);
+ inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const {
+ Q_ASSERT(m_hints & IsCachedHint);
+ CacheEntry *e = m_cache;
+ while (e) {
+ if (e->engine == engine)
+ return e;
+ e = e->next;
+ }
+ return 0;
}
+
+private:
+ Q_DISABLE_COPY(QVectorPath)
+
CacheEntry *m_cache;
-#endif
const QPainterPath::ElementType *m_elements;
const qreal *m_points;
diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp
index 4f489c4efd..fa0c80eb7f 100644
--- a/src/gui/painting/qwindowsurface_qws.cpp
+++ b/src/gui/painting/qwindowsurface_qws.cpp
@@ -668,9 +668,11 @@ void QWSWindowSurface::flush(QWidget *widget, const QRegion &region,
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);
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index 3a118bd679..5060f95f0b 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -140,7 +140,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
// Not ready for painting yet, bail out. This can happen in
// QWidget::create_sys()
- if (!d->image || rgn.numRects() == 0)
+ if (!d->image || rgn.rectCount() == 0)
return;
#ifdef Q_WS_WIN
@@ -203,7 +203,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
wrgn.translate(-wOffset);
QRect wbr = wrgn.boundingRect();
- if (wrgn.numRects() != 1) {
+ if (wrgn.rectCount() != 1) {
int num;
XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num);
XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded);
@@ -215,6 +215,12 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc,
br.x(), br.y(), br.width(), br.height(), wbr.x(), wbr.y());
XSync(X11->display, False);
+ } 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);
+ XSync(X11->display, False);
} else
#endif
{
@@ -236,7 +242,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
}
}
- if (wrgn.numRects() != 1)
+ if (wrgn.rectCount() != 1)
XSetClipMask(X11->display, d_ptr->gc, XNone);
#endif // FALCON
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index dc4e43b408..c66da7114d 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/painting/qwindowsurface_s60_p.h b/src/gui/painting/qwindowsurface_s60_p.h
index 3c4059f2e9..0305454d85 100644
--- a/src/gui/painting/qwindowsurface_s60_p.h
+++ b/src/gui/painting/qwindowsurface_s60_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp
index 46c4c42066..77e019cb09 100644
--- a/src/gui/painting/qwindowsurface_x11.cpp
+++ b/src/gui/painting/qwindowsurface_x11.cpp
@@ -94,6 +94,8 @@ QPaintDevice *QX11WindowSurface::paintDevice()
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();
@@ -157,8 +159,8 @@ void QX11WindowSurface::setGeometry(const QRect &rect)
QPixmap::x11SetDefaultScreen(d_ptr->widget->x11Info().screen());
QX11PixmapData *oldData = static_cast<QX11PixmapData *>(d_ptr->device.pixmapData());
- Q_ASSERT(oldData);
- if (!(oldData->flags & QX11PixmapData::Uninitialized) && hasStaticContents()) {
+
+ 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());
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index 611ca593b7..4c4c9940c1 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -50,6 +50,7 @@
#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>
@@ -60,7 +61,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QS60MainAppUi
\since 4.6
- \brief Helper class for S60 migration
+ \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
@@ -134,8 +135,10 @@ QS60MainAppUi::~QS60MainAppUi()
*/
void QS60MainAppUi::HandleCommandL(TInt command)
{
- if (qApp)
- QT_TRYCATCH_LEAVING(qApp->symbianHandleCommand(command));
+ if (qApp) {
+ QSymbianEvent event(QSymbianEvent::CommandEvent, command);
+ QT_TRYCATCH_LEAVING(qApp->symbianProcessEvent(&event));
+ }
}
/*!
@@ -151,29 +154,33 @@ void QS60MainAppUi::HandleResourceChangeL(TInt type)
{
CAknAppUi::HandleResourceChangeL(type);
- if (qApp)
- QT_TRYCATCH_LEAVING(qApp->symbianResourceChange(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 event, while the receiving control is passed in
+ * 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& event, CCoeControl *destination)
+void QS60MainAppUi::HandleWsEventL(const TWsEvent& wsEvent, CCoeControl *destination)
{
int result = 0;
- if (qApp)
+ if (qApp) {
+ QSymbianEvent event(&wsEvent);
QT_TRYCATCH_LEAVING(
- result = qApp->s60ProcessEvent(const_cast<TWsEvent*>(&event))
+ result = qApp->symbianProcessEvent(&event)
);
+ }
if (result <= 0)
- CAknAppUi::HandleWsEventL(event, destination);
+ CAknAppUi::HandleWsEventL(wsEvent, destination);
}
diff --git a/src/gui/s60framework/qs60maindocument.cpp b/src/gui/s60framework/qs60maindocument.cpp
index 54df17e437..7405784931 100644
--- a/src/gui/s60framework/qs60maindocument.cpp
+++ b/src/gui/s60framework/qs60maindocument.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QS60MainDocument
\since 4.6
- \brief Helper class for S60 migration
+ \brief The QS60MainDocument 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
diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri
index fea74fe58c..5884b68754 100644
--- a/src/gui/s60framework/s60framework.pri
+++ b/src/gui/s60framework/s60framework.pri
@@ -1,3 +1,14 @@
+# This block serves the minimalistic resource file for S60 3.1 platforms.
+# Note there is no way to ifdef S60 version in mmp file, that is why the resource
+# file is always compiled for WINSCW
+minimalAppResource31 = \
+ "SOURCEPATH s60framework" \
+ "START RESOURCE s60main.rss" \
+ "HEADER" \
+ "TARGETPATH resource\apps" \
+ "END"
+MMP_RULES += minimalAppResource31
+
SOURCES += s60framework/qs60mainapplication.cpp \
s60framework/qs60mainappui.cpp \
s60framework/qs60maindocument.cpp
diff --git a/src/gui/s60framework/s60main.rss b/src/gui/s60framework/s60main.rss
new file mode 100644
index 0000000000..07dc6a136c
--- /dev/null
+++ b/src/gui/s60framework/s60main.rss
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 Symbian application wrapper of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Even S60 application have ENoAppResourceFile and ENonStandardResourceFile
+// flags set, the S60 3rd Edition FP1 emulator requires applications to have
+// very minimalistic application resource file, otherwise apps refures to start
+// This file serves the minimalistic resource file for S60 3.1 platforms.
+
+// RESOURCE IDENTIFIER
+NAME QTMA // 4 letter ID
+
+// INCLUDES
+//#include <eikon.rh>
+#include <appinfo.rh>
+#include <eikon.rh>
+#include <avkon.rsg>
+#include <avkon.rh>
+#include <avkon.mbg>
+
+// RESOURCE DEFINITIONS
+RESOURCE RSS_SIGNATURE
+ {
+ }
+
+RESOURCE TBUF r_default_document_name
+ {
+ buf="QTMA";
+ }
+
+RESOURCE EIK_APP_INFO
+ {
+ menubar = r_qt_wrapperapp_menubar;
+ cba = R_AVKON_SOFTKEYS_EXIT;
+ }
+
+RESOURCE MENU_BAR r_qt_wrapperapp_menubar
+ {
+ titles =
+ {
+ MENU_TITLE { menu_pane = r_qt_wrapperapp_menu; }
+ };
+ }
+
+RESOURCE MENU_PANE r_qt_wrapperapp_menu
+ {
+ }
+// End of File
diff --git a/src/gui/statemachine/qbasickeyeventtransition.cpp b/src/gui/statemachine/qbasickeyeventtransition.cpp
index 445a253273..bf10e3da1c 100644
--- a/src/gui/statemachine/qbasickeyeventtransition.cpp
+++ b/src/gui/statemachine/qbasickeyeventtransition.cpp
@@ -68,14 +68,14 @@ public:
QEvent::Type eventType;
int key;
- Qt::KeyboardModifiers modifiersMask;
+ Qt::KeyboardModifiers modifierMask;
};
QBasicKeyEventTransitionPrivate::QBasicKeyEventTransitionPrivate()
{
eventType = QEvent::None;
key = 0;
- modifiersMask = Qt::NoModifier;
+ modifierMask = Qt::NoModifier;
}
QBasicKeyEventTransitionPrivate *QBasicKeyEventTransitionPrivate::get(QBasicKeyEventTransition *q)
@@ -106,17 +106,17 @@ QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key,
/*!
Constructs a new event transition for events of the given \a type for the
- given \a key, with the given \a modifiersMask and \a sourceState.
+ given \a key, with the given \a modifierMask and \a sourceState.
*/
QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key,
- Qt::KeyboardModifiers modifiersMask,
+ Qt::KeyboardModifiers modifierMask,
QState *sourceState)
: QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState)
{
Q_D(QBasicKeyEventTransition);
d->eventType = type;
d->key = key;
- d->modifiersMask = modifiersMask;
+ d->modifierMask = modifierMask;
}
/*!
@@ -163,23 +163,23 @@ void QBasicKeyEventTransition::setKey(int key)
}
/*!
- Returns the keyboard modifiers mask that this key event transition checks
+ Returns the keyboard modifier mask that this key event transition checks
for.
*/
-Qt::KeyboardModifiers QBasicKeyEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QBasicKeyEventTransition::modifierMask() const
{
Q_D(const QBasicKeyEventTransition);
- return d->modifiersMask;
+ return d->modifierMask;
}
/*!
- Sets the keyboard modifiers mask that this key event transition will check
+ Sets the keyboard modifier mask that this key event transition will check
for.
*/
-void QBasicKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QBasicKeyEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QBasicKeyEventTransition);
- d->modifiersMask = modifiersMask;
+ d->modifierMask = modifierMask;
}
/*!
@@ -191,7 +191,7 @@ bool QBasicKeyEventTransition::eventTest(QEvent *event)
if (event->type() == d->eventType) {
QKeyEvent *ke = static_cast<QKeyEvent*>(event);
return (ke->key() == d->key)
- && ((ke->modifiers() & d->modifiersMask) == d->modifiersMask);
+ && ((ke->modifiers() & d->modifierMask) == d->modifierMask);
}
return false;
}
diff --git a/src/gui/statemachine/qbasickeyeventtransition_p.h b/src/gui/statemachine/qbasickeyeventtransition_p.h
index 3c2ec7d818..87d3dc7195 100644
--- a/src/gui/statemachine/qbasickeyeventtransition_p.h
+++ b/src/gui/statemachine/qbasickeyeventtransition_p.h
@@ -69,7 +69,7 @@ public:
QBasicKeyEventTransition(QState *sourceState = 0);
QBasicKeyEventTransition(QEvent::Type type, int key, QState *sourceState = 0);
QBasicKeyEventTransition(QEvent::Type type, int key,
- Qt::KeyboardModifiers modifiersMask,
+ Qt::KeyboardModifiers modifierMask,
QState *sourceState = 0);
~QBasicKeyEventTransition();
@@ -79,8 +79,8 @@ public:
int key() const;
void setKey(int key);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
protected:
bool eventTest(QEvent *event);
diff --git a/src/gui/statemachine/qbasicmouseeventtransition.cpp b/src/gui/statemachine/qbasicmouseeventtransition.cpp
index 694c3195cc..fe0dea9439 100644
--- a/src/gui/statemachine/qbasicmouseeventtransition.cpp
+++ b/src/gui/statemachine/qbasicmouseeventtransition.cpp
@@ -69,7 +69,7 @@ public:
QEvent::Type eventType;
Qt::MouseButton button;
- Qt::KeyboardModifiers modifiersMask;
+ Qt::KeyboardModifiers modifierMask;
QPainterPath path;
};
@@ -149,38 +149,38 @@ void QBasicMouseEventTransition::setButton(Qt::MouseButton button)
}
/*!
- Returns the keyboard modifiers mask that this mouse event transition checks
+ Returns the keyboard modifier mask that this mouse event transition checks
for.
*/
-Qt::KeyboardModifiers QBasicMouseEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QBasicMouseEventTransition::modifierMask() const
{
Q_D(const QBasicMouseEventTransition);
- return d->modifiersMask;
+ return d->modifierMask;
}
/*!
- Sets the keyboard modifiers mask that this mouse event transition will check
+ Sets the keyboard modifier mask that this mouse event transition will check
for.
*/
-void QBasicMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QBasicMouseEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QBasicMouseEventTransition);
- d->modifiersMask = modifiersMask;
+ d->modifierMask = modifierMask;
}
/*!
- Returns the path for this mouse event transition.
+ Returns the hit test path for this mouse event transition.
*/
-QPainterPath QBasicMouseEventTransition::path() const
+QPainterPath QBasicMouseEventTransition::hitTestPath() const
{
Q_D(const QBasicMouseEventTransition);
return d->path;
}
/*!
- Sets the path for this mouse event transition.
+ Sets the hit test path for this mouse event transition.
*/
-void QBasicMouseEventTransition::setPath(const QPainterPath &path)
+void QBasicMouseEventTransition::setHitTestPath(const QPainterPath &path)
{
Q_D(QBasicMouseEventTransition);
d->path = path;
@@ -195,7 +195,7 @@ bool QBasicMouseEventTransition::eventTest(QEvent *event)
if (event->type() == d->eventType) {
QMouseEvent *me = static_cast<QMouseEvent*>(event);
return (me->button() == d->button)
- && ((me->modifiers() & d->modifiersMask) == d->modifiersMask)
+ && ((me->modifiers() & d->modifierMask) == d->modifierMask)
&& (d->path.isEmpty() || d->path.contains(me->pos()));
}
return false;
diff --git a/src/gui/statemachine/qbasicmouseeventtransition_p.h b/src/gui/statemachine/qbasicmouseeventtransition_p.h
index 512e0f8dc7..6754c55114 100644
--- a/src/gui/statemachine/qbasicmouseeventtransition_p.h
+++ b/src/gui/statemachine/qbasicmouseeventtransition_p.h
@@ -79,11 +79,11 @@ public:
Qt::MouseButton button() const;
void setButton(Qt::MouseButton button);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
- QPainterPath path() const;
- void setPath(const QPainterPath &path);
+ QPainterPath hitTestPath() const;
+ void setHitTestPath(const QPainterPath &path);
protected:
bool eventTest(QEvent *event);
diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp
index 1de5ffa7d7..4f7806fe7e 100644
--- a/src/gui/statemachine/qguistatemachine.cpp
+++ b/src/gui/statemachine/qguistatemachine.cpp
@@ -106,8 +106,10 @@ static QEvent *cloneEvent(QEvent *e)
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:
@@ -190,8 +192,10 @@ static QEvent *cloneEvent(QEvent *e)
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:
@@ -200,10 +204,12 @@ static QEvent *cloneEvent(QEvent *e)
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:
@@ -238,8 +244,10 @@ static QEvent *cloneEvent(QEvent *e)
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:
@@ -249,8 +257,10 @@ static QEvent *cloneEvent(QEvent *e)
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));
@@ -263,11 +273,15 @@ static QEvent *cloneEvent(QEvent *e)
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);
@@ -397,9 +411,11 @@ static QEvent *cloneEvent(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:
diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/gui/statemachine/qkeyeventtransition.cpp
index dee31682b8..a15e671fc9 100644
--- a/src/gui/statemachine/qkeyeventtransition.cpp
+++ b/src/gui/statemachine/qkeyeventtransition.cpp
@@ -69,9 +69,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \property QKeyEventTransition::modifiersMask
+ \property QKeyEventTransition::modifierMask
- \brief the keyboard modifiers mask that this key event transition checks for
+ \brief the keyboard modifier mask that this key event transition checks for
*/
class QKeyEventTransitionPrivate : public QEventTransitionPrivate
@@ -133,23 +133,23 @@ void QKeyEventTransition::setKey(int key)
}
/*!
- Returns the keyboard modifiers mask that this key event transition checks
+ Returns the keyboard modifier mask that this key event transition checks
for.
*/
-Qt::KeyboardModifiers QKeyEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QKeyEventTransition::modifierMask() const
{
Q_D(const QKeyEventTransition);
- return d->transition->modifiersMask();
+ return d->transition->modifierMask();
}
/*!
- Sets the keyboard \a modifiers mask that this key event transition will
- check for.
+ Sets the keyboard modifier mask that this key event transition will
+ check for to \a modifierMask.
*/
-void QKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QKeyEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QKeyEventTransition);
- d->transition->setModifiersMask(modifiersMask);
+ d->transition->setModifierMask(modifierMask);
}
/*!
diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h
index 8df8138a3a..ab1c155bfd 100644
--- a/src/gui/statemachine/qkeyeventtransition.h
+++ b/src/gui/statemachine/qkeyeventtransition.h
@@ -57,7 +57,7 @@ class Q_GUI_EXPORT QKeyEventTransition : public QEventTransition
{
Q_OBJECT
Q_PROPERTY(int key READ key WRITE setKey)
- Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask)
+ Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
public:
QKeyEventTransition(QState *sourceState = 0);
QKeyEventTransition(QObject *object, QEvent::Type type, int key,
@@ -67,8 +67,8 @@ public:
int key() const;
void setKey(int key);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
protected:
void onTransition(QEvent *event);
diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/gui/statemachine/qmouseeventtransition.cpp
index 86cacf78b5..f5c0cb198b 100644
--- a/src/gui/statemachine/qmouseeventtransition.cpp
+++ b/src/gui/statemachine/qmouseeventtransition.cpp
@@ -70,9 +70,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \property QMouseEventTransition::modifiersMask
+ \property QMouseEventTransition::modifierMask
- \brief the keyboard modifiers mask that this mouse event transition checks for
+ \brief the keyboard modifier mask that this mouse event transition checks for
*/
class QMouseEventTransitionPrivate : public QEventTransitionPrivate
@@ -139,45 +139,45 @@ void QMouseEventTransition::setButton(Qt::MouseButton button)
}
/*!
- Returns the keyboard modifiers mask that this mouse event transition checks
+ Returns the keyboard modifier mask that this mouse event transition checks
for.
*/
-Qt::KeyboardModifiers QMouseEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QMouseEventTransition::modifierMask() const
{
Q_D(const QMouseEventTransition);
- return d->transition->modifiersMask();
+ return d->transition->modifierMask();
}
/*!
- Sets the keyboard \a modifiers mask that this mouse event transition will
- check for.
+ Sets the keyboard modifier mask that this mouse event transition will
+ check for to \a modifierMask.
*/
-void QMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QMouseEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QMouseEventTransition);
- d->transition->setModifiersMask(modifiersMask);
+ d->transition->setModifierMask(modifierMask);
}
/*!
- Returns the path for this mouse event transition.
+ Returns the hit test path for this mouse event transition.
*/
-QPainterPath QMouseEventTransition::path() const
+QPainterPath QMouseEventTransition::hitTestPath() const
{
Q_D(const QMouseEventTransition);
- return d->transition->path();
+ return d->transition->hitTestPath();
}
/*!
- Sets the \a path for this mouse event transition.
+ Sets the hit test path for this mouse event transition to \a path.
If a valid path has been set, the transition will only trigger if the mouse
event position (QMouseEvent::pos()) is inside the path.
\sa QPainterPath::contains()
*/
-void QMouseEventTransition::setPath(const QPainterPath &path)
+void QMouseEventTransition::setHitTestPath(const QPainterPath &path)
{
Q_D(QMouseEventTransition);
- d->transition->setPath(path);
+ d->transition->setHitTestPath(path);
}
/*!
diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h
index 4e324ec119..e7f6a45cc1 100644
--- a/src/gui/statemachine/qmouseeventtransition.h
+++ b/src/gui/statemachine/qmouseeventtransition.h
@@ -58,7 +58,7 @@ class Q_GUI_EXPORT QMouseEventTransition : public QEventTransition
{
Q_OBJECT
Q_PROPERTY(Qt::MouseButton button READ button WRITE setButton)
- Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask)
+ Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
public:
QMouseEventTransition(QState *sourceState = 0);
QMouseEventTransition(QObject *object, QEvent::Type type,
@@ -68,11 +68,11 @@ public:
Qt::MouseButton button() const;
void setButton(Qt::MouseButton button);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
- QPainterPath path() const;
- void setPath(const QPainterPath &path);
+ QPainterPath hitTestPath() const;
+ void setHitTestPath(const QPainterPath &path);
protected:
void onTransition(QEvent *event);
diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp
deleted file mode 100644
index 6ec5796ca0..0000000000
--- a/src/gui/styles/gtksymbols.cpp
+++ /dev/null
@@ -1,1005 +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$
-** 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 "gtksymbols_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 <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 <X11/Xlib.h>
-
-QT_BEGIN_NAMESPACE
-
-static bool displayDepth = -1;
-Q_GLOBAL_STATIC(QGtkStyleUpdateScheduler, styleScheduler)
-
-typedef QHash<QString, GtkWidget*> WidgetMap;
-Q_GLOBAL_STATIC(WidgetMap, gtkWidgetMap)
-
-Ptr_gtk_container_forall QGtk::gtk_container_forall = 0;
-Ptr_gtk_init QGtk::gtk_init = 0;
-Ptr_gtk_style_attach QGtk::gtk_style_attach = 0;
-Ptr_gtk_window_new QGtk::gtk_window_new = 0;
-Ptr_gtk_widget_destroy QGtk::gtk_widget_destroy = 0;
-Ptr_gtk_widget_realize QGtk::gtk_widget_realize = 0;
-Ptr_gtk_widget_set_default_direction QGtk::gtk_widget_set_default_direction = 0;
-Ptr_gtk_widget_modify_color QGtk::gtk_widget_modify_fg = 0;
-Ptr_gtk_widget_modify_color QGtk::gtk_widget_modify_bg = 0;
-Ptr_gtk_arrow_new QGtk::gtk_arrow_new = 0;
-Ptr_gtk_menu_item_new QGtk::gtk_menu_item_new = 0;
-Ptr_gtk_check_menu_item_new QGtk::gtk_check_menu_item_new = 0;
-Ptr_gtk_menu_bar_new QGtk::gtk_menu_bar_new = 0;
-Ptr_gtk_menu_new QGtk::gtk_menu_new = 0;
-Ptr_gtk_button_new QGtk::gtk_button_new = 0;
-Ptr_gtk_hbutton_box_new QGtk::gtk_hbutton_box_new = 0;
-Ptr_gtk_check_button_new QGtk::gtk_check_button_new = 0;
-Ptr_gtk_radio_button_new QGtk::gtk_radio_button_new = 0;
-Ptr_gtk_spin_button_new QGtk::gtk_spin_button_new = 0;
-Ptr_gtk_frame_new QGtk::gtk_frame_new = 0;
-Ptr_gtk_expander_new QGtk::gtk_expander_new = 0;
-Ptr_gtk_statusbar_new QGtk::gtk_statusbar_new = 0;
-Ptr_gtk_entry_new QGtk::gtk_entry_new = 0;
-Ptr_gtk_hscale_new QGtk::gtk_hscale_new = 0;
-Ptr_gtk_vscale_new QGtk::gtk_vscale_new = 0;
-Ptr_gtk_hscrollbar_new QGtk::gtk_hscrollbar_new = 0;
-Ptr_gtk_vscrollbar_new QGtk::gtk_vscrollbar_new = 0;
-Ptr_gtk_scrolled_window_new QGtk::gtk_scrolled_window_new = 0;
-Ptr_gtk_notebook_new QGtk::gtk_notebook_new = 0;
-Ptr_gtk_toolbar_new QGtk::gtk_toolbar_new = 0;
-Ptr_gtk_toolbar_insert QGtk::gtk_toolbar_insert = 0;
-Ptr_gtk_separator_tool_item_new QGtk::gtk_separator_tool_item_new = 0;
-Ptr_gtk_tree_view_new QGtk::gtk_tree_view_new = 0;
-Ptr_gtk_combo_box_new QGtk::gtk_combo_box_new = 0;
-Ptr_gtk_combo_box_entry_new QGtk::gtk_combo_box_entry_new = 0;
-Ptr_gtk_progress_bar_new QGtk::gtk_progress_bar_new = 0;
-Ptr_gtk_container_add QGtk::gtk_container_add = 0;
-Ptr_gtk_menu_shell_append QGtk::gtk_menu_shell_append = 0;
-Ptr_gtk_progress_set_adjustment QGtk::gtk_progress_set_adjustment = 0;
-Ptr_gtk_range_set_adjustment QGtk::gtk_range_set_adjustment = 0;
-Ptr_gtk_range_set_inverted QGtk::gtk_range_set_inverted = 0;
-Ptr_gtk_icon_factory_lookup_default QGtk::gtk_icon_factory_lookup_default = 0;
-Ptr_gtk_icon_theme_get_default QGtk::gtk_icon_theme_get_default = 0;
-Ptr_gtk_widget_style_get QGtk::gtk_widget_style_get = 0;
-Ptr_gtk_icon_set_render_icon QGtk::gtk_icon_set_render_icon = 0;
-Ptr_gtk_fixed_new QGtk::gtk_fixed_new = 0;
-Ptr_gtk_tree_view_column_new QGtk::gtk_tree_view_column_new = 0;
-Ptr_gtk_tree_view_get_column QGtk::gtk_tree_view_get_column = 0;
-Ptr_gtk_tree_view_append_column QGtk::gtk_tree_view_append_column = 0;
-Ptr_gtk_paint_check QGtk::gtk_paint_check = 0;
-Ptr_gtk_paint_box QGtk::gtk_paint_box = 0;
-Ptr_gtk_paint_box_gap QGtk::gtk_paint_box_gap = 0;
-Ptr_gtk_paint_flat_box QGtk::gtk_paint_flat_box = 0;
-Ptr_gtk_paint_option QGtk::gtk_paint_option = 0;
-Ptr_gtk_paint_extension QGtk::gtk_paint_extension = 0;
-Ptr_gtk_paint_slider QGtk::gtk_paint_slider = 0;
-Ptr_gtk_paint_shadow QGtk::gtk_paint_shadow = 0;
-Ptr_gtk_paint_resize_grip QGtk::gtk_paint_resize_grip = 0;
-Ptr_gtk_paint_focus QGtk::gtk_paint_focus = 0;
-Ptr_gtk_paint_arrow QGtk::gtk_paint_arrow = 0;
-Ptr_gtk_paint_handle QGtk::gtk_paint_handle = 0;
-Ptr_gtk_paint_expander QGtk::gtk_paint_expander = 0;
-Ptr_gtk_adjustment_new QGtk::gtk_adjustment_new = 0;
-Ptr_gtk_paint_hline QGtk::gtk_paint_hline = 0;
-Ptr_gtk_paint_vline QGtk::gtk_paint_vline = 0;
-Ptr_gtk_menu_item_set_submenu QGtk::gtk_menu_item_set_submenu = 0;
-Ptr_gtk_settings_get_default QGtk::gtk_settings_get_default = 0;
-Ptr_gtk_separator_menu_item_new QGtk::gtk_separator_menu_item_new = 0;
-Ptr_gtk_widget_size_allocate QGtk::gtk_widget_size_allocate = 0;
-Ptr_gtk_widget_set_direction QGtk::gtk_widget_set_direction = 0;
-Ptr_gtk_widget_path QGtk::gtk_widget_path = 0;
-Ptr_gtk_container_get_type QGtk::gtk_container_get_type = 0;
-Ptr_gtk_window_get_type QGtk::gtk_window_get_type = 0;
-Ptr_gtk_widget_get_type QGtk::gtk_widget_get_type = 0;
-Ptr_gtk_rc_get_style_by_paths QGtk::gtk_rc_get_style_by_paths = 0;
-Ptr_gtk_check_version QGtk::gtk_check_version = 0;
-
-Ptr_pango_font_description_get_size QGtk::pango_font_description_get_size = 0;
-Ptr_pango_font_description_get_weight QGtk::pango_font_description_get_weight = 0;
-Ptr_pango_font_description_get_family QGtk::pango_font_description_get_family = 0;
-Ptr_pango_font_description_get_style QGtk::pango_font_description_get_style = 0;
-
-Ptr_gtk_file_filter_new QGtk::gtk_file_filter_new = 0;
-Ptr_gtk_file_filter_set_name QGtk::gtk_file_filter_set_name = 0;
-Ptr_gtk_file_filter_add_pattern QGtk::gtk_file_filter_add_pattern = 0;
-Ptr_gtk_file_chooser_add_filter QGtk::gtk_file_chooser_add_filter = 0;
-Ptr_gtk_file_chooser_set_filter QGtk::gtk_file_chooser_set_filter = 0;
-Ptr_gtk_file_chooser_get_filter QGtk::gtk_file_chooser_get_filter = 0;
-Ptr_gtk_file_chooser_dialog_new QGtk::gtk_file_chooser_dialog_new = 0;
-Ptr_gtk_file_chooser_set_current_folder QGtk::gtk_file_chooser_set_current_folder = 0;
-Ptr_gtk_file_chooser_get_filename QGtk::gtk_file_chooser_get_filename = 0;
-Ptr_gtk_file_chooser_get_filenames QGtk::gtk_file_chooser_get_filenames = 0;
-Ptr_gtk_file_chooser_set_current_name QGtk::gtk_file_chooser_set_current_name = 0;
-Ptr_gtk_dialog_run QGtk::gtk_dialog_run = 0;
-Ptr_gtk_file_chooser_set_filename QGtk::gtk_file_chooser_set_filename = 0;
-
-Ptr_gdk_pixbuf_get_pixels QGtk::gdk_pixbuf_get_pixels = 0;
-Ptr_gdk_pixbuf_get_width QGtk::gdk_pixbuf_get_width = 0;
-Ptr_gdk_pixbuf_get_height QGtk::gdk_pixbuf_get_height = 0;
-Ptr_gdk_pixmap_new QGtk::gdk_pixmap_new = 0;
-Ptr_gdk_pixbuf_new QGtk::gdk_pixbuf_new = 0;
-Ptr_gdk_pixbuf_get_from_drawable QGtk::gdk_pixbuf_get_from_drawable = 0;
-Ptr_gdk_draw_rectangle QGtk::gdk_draw_rectangle = 0;
-Ptr_gdk_pixbuf_unref QGtk::gdk_pixbuf_unref = 0;
-Ptr_gdk_drawable_unref QGtk::gdk_drawable_unref = 0;
-Ptr_gdk_drawable_get_depth QGtk::gdk_drawable_get_depth = 0;
-Ptr_gdk_color_free QGtk::gdk_color_free = 0;
-Ptr_gdk_x11_window_set_user_time QGtk::gdk_x11_window_set_user_time = 0;
-Ptr_gdk_x11_drawable_get_xid QGtk::gdk_x11_drawable_get_xid = 0;
-Ptr_gdk_x11_drawable_get_xdisplay QGtk::gdk_x11_drawable_get_xdisplay = 0;
-
-Ptr_gconf_client_get_default QGtk::gconf_client_get_default = 0;
-Ptr_gconf_client_get_string QGtk::gconf_client_get_string = 0;
-Ptr_gconf_client_get_bool QGtk::gconf_client_get_bool = 0;
-
-Ptr_gnome_icon_lookup_sync QGtk::gnome_icon_lookup_sync = 0;
-Ptr_gnome_vfs_init QGtk::gnome_vfs_init = 0;
-
-static QString classPath(GtkWidget *widget)
-{
- char* class_path;
- QGtk::gtk_widget_path (widget, NULL, &class_path, NULL);
- QString path = QLS(class_path);
- g_free(class_path);
-
- // Remove the prefixes
- path.remove(QLS("GtkWindow."));
- path.remove(QLS("GtkFixed."));
- return path;
-}
-
-static void resolveGtk()
-{
- // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0
- QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0);
- QGtk::gtk_init = (Ptr_gtk_init)libgtk.resolve("gtk_init");
- QGtk::gtk_window_new = (Ptr_gtk_window_new)libgtk.resolve("gtk_window_new");
- QGtk::gtk_style_attach = (Ptr_gtk_style_attach)libgtk.resolve("gtk_style_attach");
- QGtk::gtk_widget_destroy = (Ptr_gtk_widget_destroy)libgtk.resolve("gtk_widget_destroy");
- QGtk::gtk_widget_realize = (Ptr_gtk_widget_realize)libgtk.resolve("gtk_widget_realize");
-
- QGtk::gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
- QGtk::gtk_file_filter_new = (Ptr_gtk_file_filter_new)libgtk.resolve("gtk_file_filter_new");
- QGtk::gtk_file_filter_set_name = (Ptr_gtk_file_filter_set_name)libgtk.resolve("gtk_file_filter_set_name");
- QGtk::gtk_file_filter_add_pattern = (Ptr_gtk_file_filter_add_pattern)libgtk.resolve("gtk_file_filter_add_pattern");
- QGtk::gtk_file_chooser_add_filter = (Ptr_gtk_file_chooser_add_filter)libgtk.resolve("gtk_file_chooser_add_filter");
- QGtk::gtk_file_chooser_set_filter = (Ptr_gtk_file_chooser_set_filter)libgtk.resolve("gtk_file_chooser_set_filter");
- QGtk::gtk_file_chooser_get_filter = (Ptr_gtk_file_chooser_get_filter)libgtk.resolve("gtk_file_chooser_get_filter");
- QGtk::gtk_file_chooser_dialog_new = (Ptr_gtk_file_chooser_dialog_new)libgtk.resolve("gtk_file_chooser_dialog_new");
- QGtk::gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
- QGtk::gtk_file_chooser_get_filename = (Ptr_gtk_file_chooser_get_filename)libgtk.resolve("gtk_file_chooser_get_filename");
- QGtk::gtk_file_chooser_get_filenames = (Ptr_gtk_file_chooser_get_filenames)libgtk.resolve("gtk_file_chooser_get_filenames");
- QGtk::gtk_file_chooser_set_current_name = (Ptr_gtk_file_chooser_set_current_name)libgtk.resolve("gtk_file_chooser_set_current_name");
- QGtk::gtk_dialog_run = (Ptr_gtk_dialog_run)libgtk.resolve("gtk_dialog_run");
- QGtk::gtk_file_chooser_set_filename = (Ptr_gtk_file_chooser_set_filename)libgtk.resolve("gtk_file_chooser_set_filename");
-
- QGtk::gdk_pixbuf_get_pixels = (Ptr_gdk_pixbuf_get_pixels)libgtk.resolve("gdk_pixbuf_get_pixels");
- QGtk::gdk_pixbuf_get_width = (Ptr_gdk_pixbuf_get_width)libgtk.resolve("gdk_pixbuf_get_width");
- QGtk::gdk_pixbuf_get_height = (Ptr_gdk_pixbuf_get_height)libgtk.resolve("gdk_pixbuf_get_height");
- QGtk::gdk_pixmap_new = (Ptr_gdk_pixmap_new)libgtk.resolve("gdk_pixmap_new");
- QGtk::gdk_pixbuf_new = (Ptr_gdk_pixbuf_new)libgtk.resolve("gdk_pixbuf_new");
- QGtk::gdk_pixbuf_get_from_drawable = (Ptr_gdk_pixbuf_get_from_drawable)libgtk.resolve("gdk_pixbuf_get_from_drawable");
- QGtk::gdk_draw_rectangle = (Ptr_gdk_draw_rectangle)libgtk.resolve("gdk_draw_rectangle");
- QGtk::gdk_pixbuf_unref = (Ptr_gdk_pixbuf_unref)libgtk.resolve("gdk_pixbuf_unref");
- QGtk::gdk_drawable_unref = (Ptr_gdk_drawable_unref)libgtk.resolve("gdk_drawable_unref");
- QGtk::gdk_drawable_get_depth = (Ptr_gdk_drawable_get_depth)libgtk.resolve("gdk_drawable_get_depth");
- QGtk::gdk_color_free = (Ptr_gdk_color_free)libgtk.resolve("gdk_color_free");
- QGtk::gdk_x11_window_set_user_time = (Ptr_gdk_x11_window_set_user_time)libgtk.resolve("gdk_x11_window_set_user_time");
- QGtk::gdk_x11_drawable_get_xid = (Ptr_gdk_x11_drawable_get_xid)libgtk.resolve("gdk_x11_drawable_get_xid");
- QGtk::gdk_x11_drawable_get_xdisplay = (Ptr_gdk_x11_drawable_get_xdisplay)libgtk.resolve("gdk_x11_drawable_get_xdisplay");
-
- QGtk::gtk_widget_set_default_direction = (Ptr_gtk_widget_set_default_direction)libgtk.resolve("gtk_widget_set_default_direction");
- QGtk::gtk_widget_modify_fg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_fg");
- QGtk::gtk_widget_modify_bg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_bg");
- QGtk::gtk_arrow_new = (Ptr_gtk_arrow_new)libgtk.resolve("gtk_arrow_new");
- QGtk::gtk_menu_item_new = (Ptr_gtk_menu_item_new)libgtk.resolve("gtk_menu_item_new");
- QGtk::gtk_check_menu_item_new = (Ptr_gtk_check_menu_item_new)libgtk.resolve("gtk_check_menu_item_new");
- QGtk::gtk_menu_bar_new = (Ptr_gtk_menu_bar_new)libgtk.resolve("gtk_menu_bar_new");
- QGtk::gtk_menu_new = (Ptr_gtk_menu_new)libgtk.resolve("gtk_menu_new");
- QGtk::gtk_toolbar_new = (Ptr_gtk_toolbar_new)libgtk.resolve("gtk_toolbar_new");
- QGtk::gtk_separator_tool_item_new = (Ptr_gtk_separator_tool_item_new)libgtk.resolve("gtk_separator_tool_item_new");
- QGtk::gtk_toolbar_insert = (Ptr_gtk_toolbar_insert)libgtk.resolve("gtk_toolbar_insert");
- QGtk::gtk_button_new = (Ptr_gtk_button_new)libgtk.resolve("gtk_button_new");
- QGtk::gtk_hbutton_box_new = (Ptr_gtk_hbutton_box_new)libgtk.resolve("gtk_hbutton_box_new");
- QGtk::gtk_check_button_new = (Ptr_gtk_check_button_new)libgtk.resolve("gtk_check_button_new");
- QGtk::gtk_radio_button_new = (Ptr_gtk_radio_button_new)libgtk.resolve("gtk_radio_button_new");
- QGtk::gtk_notebook_new = (Ptr_gtk_notebook_new)libgtk.resolve("gtk_notebook_new");
- QGtk::gtk_progress_bar_new = (Ptr_gtk_progress_bar_new)libgtk.resolve("gtk_progress_bar_new");
- QGtk::gtk_spin_button_new = (Ptr_gtk_spin_button_new)libgtk.resolve("gtk_spin_button_new");
- QGtk::gtk_hscale_new = (Ptr_gtk_hscale_new)libgtk.resolve("gtk_hscale_new");
- QGtk::gtk_vscale_new = (Ptr_gtk_vscale_new)libgtk.resolve("gtk_vscale_new");
- QGtk::gtk_hscrollbar_new = (Ptr_gtk_hscrollbar_new)libgtk.resolve("gtk_hscrollbar_new");
- QGtk::gtk_vscrollbar_new = (Ptr_gtk_vscrollbar_new)libgtk.resolve("gtk_vscrollbar_new");
- QGtk::gtk_scrolled_window_new = (Ptr_gtk_scrolled_window_new)libgtk.resolve("gtk_scrolled_window_new");
- QGtk::gtk_menu_shell_append = (Ptr_gtk_menu_shell_append)libgtk.resolve("gtk_menu_shell_append");
- QGtk::gtk_entry_new = (Ptr_gtk_entry_new)libgtk.resolve("gtk_entry_new");
- QGtk::gtk_tree_view_new = (Ptr_gtk_tree_view_new)libgtk.resolve("gtk_tree_view_new");
- QGtk::gtk_combo_box_new = (Ptr_gtk_combo_box_new)libgtk.resolve("gtk_combo_box_new");
- QGtk::gtk_progress_set_adjustment = (Ptr_gtk_progress_set_adjustment)libgtk.resolve("gtk_progress_set_adjustment");
- QGtk::gtk_range_set_adjustment = (Ptr_gtk_range_set_adjustment)libgtk.resolve("gtk_range_set_adjustment");
- QGtk::gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted");
- QGtk::gtk_container_add = (Ptr_gtk_container_add)libgtk.resolve("gtk_container_add");
- QGtk::gtk_icon_factory_lookup_default = (Ptr_gtk_icon_factory_lookup_default)libgtk.resolve("gtk_icon_factory_lookup_default");
- QGtk::gtk_icon_theme_get_default = (Ptr_gtk_icon_theme_get_default)libgtk.resolve("gtk_icon_theme_get_default");
- QGtk::gtk_widget_style_get = (Ptr_gtk_widget_style_get)libgtk.resolve("gtk_widget_style_get");
- QGtk::gtk_icon_set_render_icon = (Ptr_gtk_icon_set_render_icon)libgtk.resolve("gtk_icon_set_render_icon");
- QGtk::gtk_fixed_new = (Ptr_gtk_fixed_new)libgtk.resolve("gtk_fixed_new");
- QGtk::gtk_tree_view_column_new = (Ptr_gtk_tree_view_column_new)libgtk.resolve("gtk_tree_view_column_new");
- QGtk::gtk_tree_view_append_column= (Ptr_gtk_tree_view_append_column )libgtk.resolve("gtk_tree_view_append_column");
- QGtk::gtk_tree_view_get_column = (Ptr_gtk_tree_view_get_column )libgtk.resolve("gtk_tree_view_get_column");
- QGtk::gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
- QGtk::gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
- QGtk::gtk_paint_flat_box = (Ptr_gtk_paint_flat_box)libgtk.resolve("gtk_paint_flat_box");
- QGtk::gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
- QGtk::gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
- QGtk::gtk_paint_resize_grip = (Ptr_gtk_paint_resize_grip)libgtk.resolve("gtk_paint_resize_grip");
- QGtk::gtk_paint_focus = (Ptr_gtk_paint_focus)libgtk.resolve("gtk_paint_focus");
- QGtk::gtk_paint_shadow = (Ptr_gtk_paint_shadow)libgtk.resolve("gtk_paint_shadow");
- QGtk::gtk_paint_slider = (Ptr_gtk_paint_slider)libgtk.resolve("gtk_paint_slider");
- QGtk::gtk_paint_expander = (Ptr_gtk_paint_expander)libgtk.resolve("gtk_paint_expander");
- QGtk::gtk_paint_handle = (Ptr_gtk_paint_handle)libgtk.resolve("gtk_paint_handle");
- QGtk::gtk_paint_option = (Ptr_gtk_paint_option)libgtk.resolve("gtk_paint_option");
- QGtk::gtk_paint_arrow = (Ptr_gtk_paint_arrow)libgtk.resolve("gtk_paint_arrow");
- QGtk::gtk_paint_box_gap = (Ptr_gtk_paint_box_gap)libgtk.resolve("gtk_paint_box_gap");
- QGtk::gtk_paint_extension = (Ptr_gtk_paint_extension)libgtk.resolve("gtk_paint_extension");
- QGtk::gtk_paint_hline = (Ptr_gtk_paint_hline)libgtk.resolve("gtk_paint_hline");
- QGtk::gtk_paint_vline = (Ptr_gtk_paint_vline)libgtk.resolve("gtk_paint_vline");
- QGtk::gtk_adjustment_new = (Ptr_gtk_adjustment_new)libgtk.resolve("gtk_adjustment_new");
- QGtk::gtk_menu_item_set_submenu = (Ptr_gtk_menu_item_set_submenu)libgtk.resolve("gtk_menu_item_set_submenu");
- QGtk::gtk_settings_get_default = (Ptr_gtk_settings_get_default)libgtk.resolve("gtk_settings_get_default");
- QGtk::gtk_separator_menu_item_new = (Ptr_gtk_separator_menu_item_new)libgtk.resolve("gtk_separator_menu_item_new");
- QGtk::gtk_frame_new = (Ptr_gtk_frame_new)libgtk.resolve("gtk_frame_new");
- QGtk::gtk_expander_new = (Ptr_gtk_expander_new)libgtk.resolve("gtk_expander_new");
- QGtk::gtk_statusbar_new = (Ptr_gtk_statusbar_new)libgtk.resolve("gtk_statusbar_new");
- QGtk::gtk_combo_box_entry_new = (Ptr_gtk_combo_box_entry_new)libgtk.resolve("gtk_combo_box_entry_new");
- QGtk::gtk_container_forall = (Ptr_gtk_container_forall)libgtk.resolve("gtk_container_forall");
- QGtk::gtk_widget_size_allocate =(Ptr_gtk_widget_size_allocate)libgtk.resolve("gtk_widget_size_allocate");
- QGtk::gtk_widget_set_direction =(Ptr_gtk_widget_set_direction)libgtk.resolve("gtk_widget_set_direction");
- QGtk::gtk_widget_path =(Ptr_gtk_widget_path)libgtk.resolve("gtk_widget_path");
- QGtk::gtk_container_get_type =(Ptr_gtk_container_get_type)libgtk.resolve("gtk_container_get_type");
- QGtk::gtk_window_get_type =(Ptr_gtk_window_get_type)libgtk.resolve("gtk_window_get_type");
- QGtk::gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type");
- QGtk::gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths");
- QGtk::gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version");
- QGtk::pango_font_description_get_size = (Ptr_pango_font_description_get_size)libgtk.resolve("pango_font_description_get_size");
- QGtk::pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight");
- QGtk::pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family");
- QGtk::pango_font_description_get_style = (Ptr_pango_font_description_get_style)libgtk.resolve("pango_font_description_get_style");
-
- QGtk::gnome_icon_lookup_sync = (Ptr_gnome_icon_lookup_sync)QLibrary::resolve( QLS("gnomeui-2"), 0, "gnome_icon_lookup_sync");
- QGtk::gnome_vfs_init= (Ptr_gnome_vfs_init)QLibrary::resolve( QLS("gnomevfs-2"), 0, "gnome_vfs_init");
-}
-
-void QGtk::cleanup_gtk_widgets()
-{
- if (gtkWidgetMap()->contains(QLS("GtkWindow"))) // Gtk will destroy all children
- QGtk::gtk_widget_destroy(gtkWidgetMap()->value(QLS("GtkWindow")));
-}
-
-static bool resolveGConf()
-{
- if (!QGtk::gconf_client_get_default) {
- QGtk::gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_default");
- QGtk::gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_string");
- QGtk::gconf_client_get_bool = (Ptr_gconf_client_get_bool)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_bool");
- }
- return (QGtk::gconf_client_get_default !=0);
-}
-
-typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
-
-QString QGtk::getGConfString(const QString &value, const QString &fallback)
-{
- QString retVal = fallback;
- if (resolveGConf()) {
- g_type_init();
- GConfClient* client = QGtk::gconf_client_get_default();
- GError *err = 0;
- char *str = QGtk::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 QGtk::getGConfBool(const QString &key, bool fallback)
-{
- bool retVal = fallback;
- if (resolveGConf()) {
- g_type_init();
- GConfClient* client = QGtk::gconf_client_get_default();
- GError *err = 0;
- bool result = QGtk::gconf_client_get_bool(client, qPrintable(key), &err);
- g_object_unref(client);
- if (!err)
- retVal = result;
- else
- g_error_free (err);
- }
- return retVal;
-}
-
-static QString 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 = QGtk::getGConfString(QLS("/desktop/gnome/interface/gtk_theme"));
-
- return themeName;
-}
-
-static void init_gtk_window()
-{
- static QString themeName;
- if (!gtkWidgetMap()->contains(QLS("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;
- }
-
- resolveGtk();
-
- if (QGtk::gtk_init) {
- // Gtk will set the Qt error handler so we have to reset it afterwards
- x11ErrorHandler qt_x_errhandler = XSetErrorHandler(0);
- QGtk::gtk_init (NULL, NULL);
- XSetErrorHandler(qt_x_errhandler);
-
- GtkWidget* gtkWindow = QGtk::gtk_window_new(GTK_WINDOW_POPUP);
- QGtk::gtk_widget_realize(gtkWindow);
- if (displayDepth == -1)
- displayDepth = QGtk::gdk_drawable_get_depth(gtkWindow->window);
- gtkWidgetMap()->insert(QLS("GtkWindow"), gtkWindow);
- } else {
- qWarning("QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries.");
- }
- }
-}
-
-static void setup_gtk_widget(GtkWidget* widget)
-{
- if (Q_GTK_IS_WIDGET(widget)) {
- static GtkWidget* protoLayout = 0;
- if (!protoLayout) {
- protoLayout = QGtk::gtk_fixed_new();
- QGtk::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value(QLS("GtkWindow"))), protoLayout);
- }
- Q_ASSERT(protoLayout);
-
- QGtk::gtk_container_add((GtkContainer*)(protoLayout), widget);
- QGtk::gtk_widget_realize(widget);
- }
-}
-
-static void add_widget_to_map(GtkWidget *widget)
-{
- if (Q_GTK_IS_WIDGET(widget)) {
- QGtk::gtk_widget_realize(widget);
- gtkWidgetMap()->insert(classPath(widget), widget);
- }
- }
-
-static void add_all_sub_widgets(GtkWidget *widget, gpointer v = 0)
-{
- Q_UNUSED(v);
- add_widget_to_map(widget);
- if (GTK_CHECK_TYPE ((widget), Q_GTK_TYPE_CONTAINER))
- QGtk::gtk_container_forall((GtkContainer*)widget, add_all_sub_widgets, NULL);
-}
-
-static void init_gtk_menu()
-{
- // Create menubar
- GtkWidget *gtkMenuBar = QGtk::gtk_menu_bar_new();
- setup_gtk_widget(gtkMenuBar);
-
- GtkWidget *gtkMenuBarItem = QGtk::gtk_menu_item_new();
- QGtk::gtk_menu_shell_append((GtkMenuShell*)(gtkMenuBar), gtkMenuBarItem);
- QGtk::gtk_widget_realize(gtkMenuBarItem);
-
- // Create menu
- GtkWidget *gtkMenu = QGtk::gtk_menu_new();
- QGtk::gtk_menu_item_set_submenu((GtkMenuItem*)(gtkMenuBarItem), gtkMenu);
- QGtk::gtk_widget_realize(gtkMenu);
-
- GtkWidget *gtkMenuItem = QGtk::gtk_menu_item_new();
- QGtk::gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem);
- QGtk::gtk_widget_realize(gtkMenuItem);
-
- GtkWidget *gtkCheckMenuItem = QGtk::gtk_check_menu_item_new();
- QGtk::gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem);
- QGtk::gtk_widget_realize(gtkCheckMenuItem);
-
- GtkWidget *gtkMenuSeparator = QGtk::gtk_separator_menu_item_new();
- QGtk::gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuSeparator);
-
- add_all_sub_widgets(gtkMenuBar);
- add_all_sub_widgets(gtkMenu);
-}
-
-// Updates window/windowtext palette based on the indicated gtk widget
-static QPalette gtkWidgetPalette(const QString &gtkWidgetName)
-{
- GtkWidget *gtkWidget = QGtk::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;
-}
-
-bool QGtk::isKDE4Session()
-{
- static int version = -1;
- if (version == -1)
- version = qgetenv("KDE_SESSION_VERSION").toInt();
- return (version == 4);
-}
-
-void QGtk::applyCustomPaletteHash()
-{
- QPalette menuPal = gtkWidgetPalette(QLS("GtkMenu"));
- GdkColor gdkBg = QGtk::gtkWidget(QLS("GtkMenu"))->style->bg[GTK_STATE_NORMAL];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- menuPal.setBrush(QPalette::Base, bgColor);
- menuPal.setBrush(QPalette::Window, bgColor);
- qApp->setPalette(menuPal, "QMenu");
-
- QPalette toolbarPal = gtkWidgetPalette(QLS("GtkToolbar"));
- qApp->setPalette(toolbarPal, "QToolBar");
-
- QPalette menuBarPal = gtkWidgetPalette(QLS("GtkMenuBar"));
- qApp->setPalette(menuBarPal, "QMenuBar");
-}
-
-static void gtkStyleSetCallback(GtkWidget*, GtkStyle*, void*)
-{
- // We have to let this function return and complete the event
- // loop to ensure that all gtk widgets have been styled before
- // updating
- QMetaObject::invokeMethod(styleScheduler(), "updateTheme", Qt::QueuedConnection);
-}
-
-void QGtkStyleUpdateScheduler::updateTheme()
-{
- static QString oldTheme(QLS("qt_not_set"));
- QPixmapCache::clear();
-
- QFont font = QGtk::getThemeFont();
- if (QApplication::font() != font)
- qApp->setFont(font);
-
- if (oldTheme != getThemeName()) {
- oldTheme = getThemeName();
- QPalette newPalette = qApp->style()->standardPalette();
- QApplicationPrivate::setSystemPalette(newPalette);
- QApplication::setPalette(newPalette);
- QGtk::initGtkWidgets();
- QGtk::applyCustomPaletteHash();
- QList<QWidget*> widgets = QApplication::allWidgets();
- // Notify all widgets that size metrics might have changed
- foreach (QWidget *widget, widgets) {
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(widget, &e);
- }
- }
- QIconLoader::instance()->updateSystemTheme();
-}
-
-static void add_widget(GtkWidget *widget)
-{
- if (widget) {
- setup_gtk_widget(widget);
- add_all_sub_widgets(widget);
- }
-}
-
-static void init_gtk_treeview()
-{
- GtkWidget *gtkTreeView = QGtk::gtk_tree_view_new();
- QGtk::gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, QGtk::gtk_tree_view_column_new());
- QGtk::gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, QGtk::gtk_tree_view_column_new());
- QGtk::gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, QGtk::gtk_tree_view_column_new());
- add_widget(gtkTreeView);
-}
-
-
-// Fetch the application font from the pango font description
-// contained in the theme.
-QFont QGtk::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;
-}
-
-GtkWidget* QGtk::gtkWidget(const QString &path)
-{
- GtkWidget *widget = gtkWidgetMap()->value(path);
- if (!widget) {
- // Theme might have rearranged widget internals
- widget = gtkWidgetMap()->value(path);
- }
- return widget;
-}
-
-GtkStyle* QGtk::gtkStyle(const QString &path)
-{
- if (gtkWidgetMap()->contains(path))
- return gtkWidgetMap()->value(path)->style;
- return 0;
-}
-
-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);
- }
- }
-}
-
-void QGtk::initGtkWidgets()
-{
- // 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;
- }
-
- init_gtk_window();
-
- if (QGtk::gtk_init) {
-
- // Make all widgets respect the text direction
- if (qApp->layoutDirection() == Qt::RightToLeft)
- QGtk::gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL);
-
- if (!gtkWidgetMap()->contains(QLS("GtkButton"))) {
- GtkWidget *gtkButton = QGtk::gtk_button_new();
- add_widget(gtkButton);
- g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), NULL);
- add_widget(QGtk::gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE));
- add_widget(QGtk::gtk_hbutton_box_new());
- add_widget(QGtk::gtk_check_button_new());
- add_widget(QGtk::gtk_radio_button_new(NULL));
- add_widget(QGtk::gtk_combo_box_new());
- add_widget(QGtk::gtk_combo_box_entry_new());
- add_widget(QGtk::gtk_entry_new());
- add_widget(QGtk::gtk_frame_new(NULL));
- add_widget(QGtk::gtk_expander_new(""));
- add_widget(QGtk::gtk_statusbar_new());
- add_widget(QGtk::gtk_hscale_new((GtkAdjustment*)(QGtk::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
- add_widget(QGtk::gtk_hscrollbar_new(NULL));
- add_widget(QGtk::gtk_scrolled_window_new(NULL, NULL));
- init_gtk_menu();
- add_widget(QGtk::gtk_notebook_new());
- add_widget(QGtk::gtk_progress_bar_new());
- add_widget(QGtk::gtk_spin_button_new((GtkAdjustment*)
- (QGtk::gtk_adjustment_new(1, 0, 1, 0, 0, 0)), 0.1, 3));
- GtkWidget *toolbar = QGtk::gtk_toolbar_new();
- g_signal_connect (toolbar, "notify::toolbar-style", G_CALLBACK (update_toolbar_style), toolbar);
- QGtk::gtk_toolbar_insert((GtkToolbar*)toolbar, QGtk::gtk_separator_tool_item_new(), -1);
- add_widget(toolbar);
- init_gtk_treeview();
- add_widget(QGtk::gtk_vscale_new((GtkAdjustment*)(QGtk::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
- add_widget(QGtk::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<QString, GtkWidget*> oldMap = *gtkWidgetMap();
- gtkWidgetMap()->clear();
- QHashIterator<QString, GtkWidget*> it(oldMap);
- while (it.hasNext()) {
- it.next();
- if (!it.key().contains(QLatin1Char('.'))) {
- add_all_sub_widgets(it.value());
- }
- }
- }
- }
-}
-
-// ----------- Native file dialogs -----------
-
-// Extract filter list from expressions of type: foo (*.a *.b *.c)"
-static QStringList 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);
-
-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)
-{
- 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 = QGtk::gtk_file_filter_new ();
- QString name = rawfilter.left(rawfilter.indexOf(QLatin1Char('(')));
- QStringList extensions = extract_filter(rawfilter);
- QGtk::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);
- }
- }
- QGtk::gtk_file_filter_add_pattern (gtkFilter, qPrintable(caseInsensitive));
-
- }
- if (filterMap)
- filterMap->insert(gtkFilter, rawfilter);
- QGtk::gtk_file_chooser_add_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
- if (selectedFilter && (rawfilter == *selectedFilter))
- QGtk::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) {
- QGtk::gtk_widget_realize(gtkFileChooser); // Creates X window
- XSetTransientForHint(QGtk::gdk_x11_drawable_get_xdisplay(gtkFileChooser->window),
- QGtk::gdk_x11_drawable_get_xid(gtkFileChooser->window),
- modalFor->winId());
- QGtk::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()) {
- QGtk::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
- } else if (isSaveDialog) {
- QGtk::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.absolutePath()));
- QGtk::gtk_file_chooser_set_current_name((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.fileName()));
- } else {
- QGtk::gtk_file_chooser_set_filename((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
- }
-}
-
-QString QGtk::openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QMap<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtk::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 (QGtk::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtk::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtk::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::leaveModal(&modal_widget);
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-
-
-QString QGtk::openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
-{
- QMap<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtk::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 (QGtk::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtk::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 QGtk::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 = QGtk::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 = QGtk::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 = QGtk::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::leaveModal(&modal_widget);
- gtk_widget_destroy (gtkFileChooser);
- return filenames;
-}
-
-QString QGtk::saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QMap<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtk::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 (QGtk::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtk::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtk::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::leaveModal(&modal_widget);
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-
-QIcon QGtk::getFilesystemIcon(const QFileInfo &info)
-{
- QIcon icon;
- if (QGtk::gnome_vfs_init && QGtk::gnome_icon_lookup_sync) {
- QGtk::gnome_vfs_init();
- GtkIconTheme *theme = QGtk::gtk_icon_theme_get_default();
- QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
- char * icon_name = QGtk::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;
-}
-
-QT_END_NAMESPACE
-
-#endif // !defined(QT_NO_STYLE_GTK)
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index fabd7cafdc..b08847d718 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -3817,6 +3817,7 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption *
newSize.setWidth(80);
if (!btn->icon.isNull() && btn->iconSize.height() > 16)
newSize -= QSize(0, 2);
+ newSize += QSize(0, 1);
}
if (const QPushButton *button = qobject_cast<const QPushButton *>(widget)) {
if (qobject_cast<const QDialogButtonBox *>(button->parentWidget())) {
@@ -3825,6 +3826,7 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption *
}
}
break;
+#ifndef QT_NO_GROUPBOX
case CT_GroupBox:
// Since we use a bold font we have to recalculate base width
if (const QGroupBox *gb = qobject_cast<const QGroupBox*>(widget)) {
@@ -3840,6 +3842,7 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption *
}
newSize += QSize(0, 1);
break;
+#endif //QT_NO_GROUPBOX
case CT_RadioButton:
case CT_CheckBox:
newSize += QSize(0, 1);
@@ -3866,7 +3869,7 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption *
if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
if (!menuItem->text.isEmpty()) {
- newSize.setHeight(menuItem->fontMetrics.lineSpacing());
+ newSize.setHeight(menuItem->fontMetrics.height());
}
}
#ifndef QT_NO_COMBOBOX
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index 58865127f7..4c9541b353 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -4396,13 +4396,13 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
case PM_TitleBarHeight: {
if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) {
- ret = qMax(widget ? widget->fontMetrics().lineSpacing() : opt->fontMetrics.lineSpacing(), 16);
+ ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 16);
#ifndef QT_NO_DOCKWIDGET
} else if (qobject_cast<const QDockWidget*>(widget)) {
- ret = qMax(widget->fontMetrics().lineSpacing(), int(QStyleHelper::dpiScaled(13)));
+ ret = qMax(widget->fontMetrics().height(), int(QStyleHelper::dpiScaled(13)));
#endif
} else {
- ret = qMax(widget ? widget->fontMetrics().lineSpacing() : opt->fontMetrics.lineSpacing(), 18);
+ ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 18);
}
} else {
ret = int(QStyleHelper::dpiScaled(18.));
@@ -4661,7 +4661,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
case PM_ToolBarIconSize:
ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolBarIconSize);
if (!ret)
- ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
+ ret = int(QStyleHelper::dpiScaled(24.));
break;
case PM_TabBarIconSize:
@@ -5169,13 +5169,12 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
const QWidget *widget) const
{
+ const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft());
#ifdef QT_NO_IMAGEFORMAT_PNG
- Q_UNUSED(option);
Q_UNUSED(widget);
Q_UNUSED(sp);
#else
QPixmap pixmap;
- const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft());
if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
switch (sp) {
@@ -5657,102 +5656,103 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons
default:
break;
}
-
+ } // if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty())
if (!icon.isNull())
return icon;
#if defined(Q_WS_MAC)
- OSType iconType = 0;
- switch (standardIcon) {
- case QStyle::SP_MessageBoxQuestion:
- case QStyle::SP_MessageBoxInformation:
- case QStyle::SP_MessageBoxWarning:
- case QStyle::SP_MessageBoxCritical:
- iconType = kGenericApplicationIcon;
- break;
- case SP_DesktopIcon:
- iconType = kDesktopIcon;
- break;
- case SP_TrashIcon:
- iconType = kTrashIcon;
- break;
- case SP_ComputerIcon:
- iconType = kComputerIcon;
- break;
- case SP_DriveFDIcon:
- iconType = kGenericFloppyIcon;
- break;
- case SP_DriveHDIcon:
- iconType = kGenericHardDiskIcon;
- break;
- case SP_DriveCDIcon:
- case SP_DriveDVDIcon:
- iconType = kGenericCDROMIcon;
- break;
- case SP_DriveNetIcon:
- iconType = kGenericNetworkIcon;
- break;
- case SP_DirOpenIcon:
- iconType = kOpenFolderIcon;
- break;
- case SP_DirClosedIcon:
- case SP_DirLinkIcon:
- iconType = kGenericFolderIcon;
- break;
- case SP_FileLinkIcon:
- case SP_FileIcon:
- iconType = kGenericDocumentIcon;
- break;
- case SP_DirIcon: {
- // A rather special case
- QIcon closeIcon = QStyle::standardIcon(SP_DirClosedIcon, option, widget);
- QIcon openIcon = QStyle::standardIcon(SP_DirOpenIcon, option, widget);
- closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
- closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
- closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
- closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
- return closeIcon;
- }
- case SP_TitleBarNormalButton:
- case SP_TitleBarCloseButton: {
- QIcon titleBarIcon;
- if (standardIcon == SP_TitleBarCloseButton) {
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-16.png"));
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
- } else {
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-16.png"));
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ if (QApplication::desktopSettingsAware()) {
+ OSType iconType = 0;
+ switch (standardIcon) {
+ case QStyle::SP_MessageBoxQuestion:
+ case QStyle::SP_MessageBoxInformation:
+ case QStyle::SP_MessageBoxWarning:
+ case QStyle::SP_MessageBoxCritical:
+ iconType = kGenericApplicationIcon;
+ break;
+ case SP_DesktopIcon:
+ iconType = kDesktopIcon;
+ break;
+ case SP_TrashIcon:
+ iconType = kTrashIcon;
+ break;
+ case SP_ComputerIcon:
+ iconType = kComputerIcon;
+ break;
+ case SP_DriveFDIcon:
+ iconType = kGenericFloppyIcon;
+ break;
+ case SP_DriveHDIcon:
+ iconType = kGenericHardDiskIcon;
+ break;
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ iconType = kGenericCDROMIcon;
+ break;
+ case SP_DriveNetIcon:
+ iconType = kGenericNetworkIcon;
+ break;
+ case SP_DirOpenIcon:
+ iconType = kOpenFolderIcon;
+ break;
+ case SP_DirClosedIcon:
+ case SP_DirLinkIcon:
+ iconType = kGenericFolderIcon;
+ break;
+ case SP_FileLinkIcon:
+ case SP_FileIcon:
+ iconType = kGenericDocumentIcon;
+ break;
+ case SP_DirIcon: {
+ // A rather special case
+ QIcon closeIcon = QStyle::standardIcon(SP_DirClosedIcon, option, widget);
+ QIcon openIcon = QStyle::standardIcon(SP_DirOpenIcon, option, widget);
+ closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
+ return closeIcon;
+ }
+ case SP_TitleBarNormalButton:
+ case SP_TitleBarCloseButton: {
+ QIcon titleBarIcon;
+ if (standardIcon == SP_TitleBarCloseButton) {
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-16.png"));
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ } else {
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-16.png"));
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ }
+ return titleBarIcon;
}
- return titleBarIcon;
- }
- default:
- break;
- }
- if (iconType != 0) {
- QIcon retIcon;
- IconRef icon;
- IconRef overlayIcon = 0;
- if (iconType != kGenericApplicationIcon) {
- GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon);
- } else {
- FSRef fsRef;
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- GetProcessBundleLocation(&psn, &fsRef);
- GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0);
- if (standardIcon == SP_MessageBoxCritical) {
- overlayIcon = icon;
- GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon);
- }
- }
- if (icon) {
- qt_mac_constructQIconFromIconRef(icon, overlayIcon, &retIcon, standardIcon);
- ReleaseIconRef(icon);
- }
- if (overlayIcon)
- ReleaseIconRef(overlayIcon);
- return retIcon;
- }
+ default:
+ break;
+ }
+ if (iconType != 0) {
+ QIcon retIcon;
+ IconRef icon;
+ IconRef overlayIcon = 0;
+ if (iconType != kGenericApplicationIcon) {
+ GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon);
+ } else {
+ FSRef fsRef;
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ GetProcessBundleLocation(&psn, &fsRef);
+ GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0);
+ if (standardIcon == SP_MessageBoxCritical) {
+ overlayIcon = icon;
+ GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon);
+ }
+ }
+ if (icon) {
+ qt_mac_constructQIconFromIconRef(icon, overlayIcon, &retIcon, standardIcon);
+ ReleaseIconRef(icon);
+ }
+ if (overlayIcon)
+ ReleaseIconRef(overlayIcon);
+ return retIcon;
+ }
+ } // if (QApplication::desktopSettingsAware())
#endif // Q_WS_MAC
- }
switch (standardIcon) {
#ifndef QT_NO_IMAGEFORMAT_PNG
diff --git a/src/gui/styles/qcommonstyle_p.h b/src/gui/styles/qcommonstyle_p.h
index a90560164f..6122f814d2 100644
--- a/src/gui/styles/qcommonstyle_p.h
+++ b/src/gui/styles/qcommonstyle_p.h
@@ -62,25 +62,6 @@ QT_BEGIN_NAMESPACE
class QStringList;
-#ifdef Q_WS_X11
-class QIconTheme
-{
-public:
- QIconTheme(QHash <int, QString> dirList, QStringList parents) :
- _dirList(dirList), _parents(parents), _valid(true){ }
- QIconTheme() : _valid(false){ }
-
- QHash <int, QString> dirList() {return _dirList;}
- QStringList parents() {return _parents;}
- bool isValid() {return _valid;}
-
-private:
- QHash <int, QString> _dirList;
- QStringList _parents;
- bool _valid;
-};
-#endif
-
// Private class
class QCommonStylePrivate : public QStylePrivate
{
diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp
index 05c5804274..aaa029ab78 100644
--- a/src/gui/styles/qgtkpainter.cpp
+++ b/src/gui/styles/qgtkpainter.cpp
@@ -108,41 +108,41 @@ QPixmap QGtkPainter::renderTheme(uchar *bdata, uchar *wdata, const QRect &rect)
return; \
QRect pixmapRect(0, 0, rect.width(), rect.height()); \
{ \
- GdkPixmap *pixmap = QGtk::gdk_pixmap_new((GdkDrawable*)(m_window->window), \
+ GdkPixmap *pixmap = QGtkStylePrivate::gdk_pixmap_new((GdkDrawable*)(m_window->window), \
rect.width(), rect.height(), -1); \
if (!pixmap) \
return; \
- style = QGtk::gtk_style_attach (style, m_window->window); \
- QGtk::gdk_draw_rectangle(pixmap, m_alpha ? style->black_gc : *style->bg_gc, true, \
+ 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 = QGtk::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect.width(), rect.height());\
+ GdkPixbuf *imgb = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect.width(), rect.height());\
if (!imgb) \
return; \
- imgb = QGtk::gdk_pixbuf_get_from_drawable(imgb, pixmap, NULL, 0, 0, 0, 0, \
+ imgb = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgb, pixmap, NULL, 0, 0, 0, 0, \
rect.width(), rect.height()); \
- uchar* bdata = (uchar*)QGtk::gdk_pixbuf_get_pixels(imgb); \
+ uchar* bdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgb); \
if (m_alpha) { \
- QGtk::gdk_draw_rectangle(pixmap, style->white_gc, true, 0, 0, rect.width(), rect.height()); \
+ QGtkStylePrivate::gdk_draw_rectangle(pixmap, style->white_gc, true, 0, 0, rect.width(), rect.height()); \
draw_func; \
- GdkPixbuf *imgw = QGtk::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect. \
+ GdkPixbuf *imgw = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect. \
width(), rect.height()); \
if (!imgw) \
return; \
- imgw = QGtk::gdk_pixbuf_get_from_drawable(imgw, pixmap, NULL, 0, 0, 0, 0, \
+ imgw = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgw, pixmap, NULL, 0, 0, 0, 0, \
rect.width(), rect.height()); \
- uchar* wdata = (uchar*)QGtk::gdk_pixbuf_get_pixels(imgw); \
+ uchar* wdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgw); \
cache = renderTheme(bdata, wdata, rect); \
- QGtk::gdk_pixbuf_unref(imgw); \
+ QGtkStylePrivate::gdk_pixbuf_unref(imgw); \
} else { \
cache = renderTheme(bdata, 0, rect); \
} \
- QGtk::gdk_drawable_unref(pixmap); \
- QGtk::gdk_pixbuf_unref(imgb); \
+ QGtkStylePrivate::gdk_drawable_unref(pixmap); \
+ QGtkStylePrivate::gdk_pixbuf_unref(imgb); \
}
QGtkPainter::QGtkPainter(QPainter *_painter)
- : m_window(QGtk::gtkWidget(QLatin1String("GtkWindow")))
+ : m_window(QGtkStylePrivate::gtkWidget(QLatin1String("GtkWindow")))
, m_painter(_painter)
, m_alpha(true)
, m_hflipped(false)
@@ -185,18 +185,18 @@ GtkStyle* QGtkPainter::getStyle(GtkWidget *gtkWidget)
QPixmap QGtkPainter::getIcon(const char* iconName, GtkIconSize size)
{
- GtkStyle *style = QGtk::gtkStyle();
- GtkIconSet* iconSet = QGtk::gtk_icon_factory_lookup_default (iconName);
- GdkPixbuf* icon = QGtk::gtk_icon_set_render_icon(iconSet,
+ 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*)QGtk::gdk_pixbuf_get_pixels(icon);
- int width = QGtk::gdk_pixbuf_get_width(icon);
- int height = QGtk::gdk_pixbuf_get_height(icon);
+ 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();
@@ -208,7 +208,7 @@ QPixmap QGtkPainter::getIcon(const char* iconName, GtkIconSize size)
tdata[index + QT_ALPHA] = data[index + GTK_ALPHA];
}
- QGtk::gdk_pixbuf_unref(icon);
+ QGtkStylePrivate::gdk_pixbuf_unref(icon);
// should we free iconset?
return QPixmap::fromImage(converted);
@@ -240,7 +240,7 @@ void QGtkPainter::paintBoxGap(GtkWidget *gtkWidget, const gchar* part,
QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + gapExtras;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_box_gap (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box_gap (style,
pixmap,
state,
shadow,
@@ -305,7 +305,7 @@ void QGtkPainter::paintBox(GtkWidget *gtkWidget, const gchar* part,
rect.size(), gtkWidget) + pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_box (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box (style,
pixmap,
state,
shadow,
@@ -356,7 +356,7 @@ void QGtkPainter::paintHline(GtkWidget *gtkWidget, const gchar* part,
QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
+ hLineExtras + pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_hline (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_hline (style,
pixmap,
state,
NULL,
@@ -383,7 +383,7 @@ void QGtkPainter::paintVline(GtkWidget *gtkWidget, const gchar* part,
QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(),
gtkWidget) + vLineExtras +pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_vline (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_vline (style,
pixmap,
state,
NULL,
@@ -410,7 +410,7 @@ void QGtkPainter::paintExpander(GtkWidget *gtkWidget,
QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(),
gtkWidget) + QString::number(expander_state) + pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_expander (style, pixmap,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_expander (style, pixmap,
state, NULL,
gtkWidget, part,
rect.width()/2,
@@ -433,7 +433,7 @@ void QGtkPainter::paintFocus(GtkWidget *gtkWidget, const gchar* part,
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(QGtk::gtk_paint_focus (style, pixmap, state, NULL,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_focus (style, pixmap, state, NULL,
gtkWidget,
part,
0, 0,
@@ -458,7 +458,7 @@ void QGtkPainter::paintResizeGrip(GtkWidget *gtkWidget, const gchar* part,
QPixmap cache;
QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_resize_grip (style, pixmap, state,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_resize_grip (style, pixmap, state,
NULL, gtkWidget,
part, edge, 0, 0,
rect.width(),
@@ -488,7 +488,7 @@ void QGtkPainter::paintArrow(GtkWidget *gtkWidget, const gchar* part,
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(QGtk::gtk_paint_arrow (style, pixmap, state, shadow,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_arrow (style, pixmap, state, shadow,
&gtkCliprect,
gtkWidget,
part,
@@ -515,7 +515,7 @@ void QGtkPainter::paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRe
QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
+ QString::number(orientation);
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_handle (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_handle (style,
pixmap,
state,
shadow,
@@ -543,7 +543,7 @@ void QGtkPainter::paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRe
QPixmap cache;
QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_slider (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_slider (style,
pixmap,
state,
shadow,
@@ -574,7 +574,7 @@ void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part,
QPixmap cache;
QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_shadow(style, pixmap, state, shadow, NULL,
+ 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);
@@ -593,7 +593,7 @@ void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part,
QPixmap cache;
QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + pmKey;
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_flat_box (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_flat_box (style,
pixmap,
state,
shadow,
@@ -622,7 +622,7 @@ void QGtkPainter::paintExtention(GtkWidget *gtkWidget,
pixmapName += QString::number(gap_pos);
if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk::gtk_paint_extension (style, pixmap, state, shadow,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_extension (style, pixmap, state, shadow,
NULL, gtkWidget,
(gchar*)part, 0, 0,
rect.width(),
@@ -651,7 +651,7 @@ void QGtkPainter::paintOption(GtkWidget *gtkWidget, const QRect &radiorect,
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(QGtk::gtk_paint_option(style, pixmap,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_option(style, pixmap,
state, shadow,
&gtkCliprect,
gtkWidget,
@@ -683,7 +683,7 @@ void QGtkPainter::paintCheckbox(GtkWidget *gtkWidget, const QRect &checkrect,
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(QGtk::gtk_paint_check (style,
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_check (style,
pixmap,
state,
shadow,
diff --git a/src/gui/styles/qgtkpainter_p.h b/src/gui/styles/qgtkpainter_p.h
index 0e8ffe2341..cbc96c0623 100644
--- a/src/gui/styles/qgtkpainter_p.h
+++ b/src/gui/styles/qgtkpainter_p.h
@@ -56,11 +56,11 @@
#include <QtCore/qglobal.h>
#if !defined(QT_NO_STYLE_GTK)
-#include "gtksymbols_p.h"
#include <QtGui/QCleanlooksStyle>
#include <QtGui/QPainter>
#include <QtGui/QPalette>
#include <QtGui/QFont>
+#include <private/qgtkstyle_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index 414580e874..5566cc6a1e 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -69,28 +69,14 @@
#include <QtGui/QTreeView>
#include <qpixmapcache.h>
#undef signals // Collides with GTK stymbols
-#include "qgtkpainter_p.h"
-#include "qstylehelper_p.h"
-
+#include <private/qgtkpainter_p.h>
+#include <private/qstylehelper_p.h>
+#include <private/qgtkstyle_p.h>
#include <private/qcleanlooksstyle_p.h>
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;
-
static const char * const dock_widget_close_xpm[] =
{
"11 13 5 1",
@@ -137,57 +123,26 @@ static const char * const dock_widget_restore_xpm[] =
" "
};
-
-class QGtkStyleFilter : public QObject
-{
-public:
- QGtkStyleFilter() {}
-private:
- bool eventFilter(QObject *obj, QEvent *e);
-};
-
-bool QGtkStyleFilter::eventFilter(QObject *obj, QEvent *e)
-{
- if (e->type() == QEvent::ApplicationPaletteChange) {
- // Only do this the first time since this will also
- // generate applicationPaletteChange events
- if (!qt_app_palettes_hash() || qt_app_palettes_hash()->isEmpty()) {
- QGtk::applyCustomPaletteHash();
- }
- }
- return QObject::eventFilter(obj, e);
-}
-
-class QGtkStylePrivate : public QCleanlooksStylePrivate
-{
- Q_DECLARE_PUBLIC(QGtkStyle)
-public:
- QGtkStylePrivate()
- : QCleanlooksStylePrivate()
- {
- QGtk::initGtkWidgets();
- if (QGtk::isThemeAvailable())
- qApp->installEventFilter(&filter);
-
- }
- QGtkStyleFilter filter;
-};
-
static const int groupBoxBottomMargin = 2; // space below the groupbox
static const int groupBoxTitleMargin = 6; // space between contents and title
static const int groupBoxTopMargin = 2;
-// Get size of the arrow controls in a GtkSpinButton
-static int spinboxArrowSize()
+/*!
+ 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)
{
- const int MIN_ARROW_WIDTH = 6;
- GtkWidget *spinButton = QGtk::gtkWidget(QLS("GtkSpinButton"));
- GtkStyle *style = spinButton->style;
- gint size = QGtk::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;
+ 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)
@@ -233,9 +188,24 @@ static GdkColor fromQColor(const QColor &color)
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()
@@ -247,11 +217,13 @@ QGtkStyle::~QGtkStyle()
*/
QPalette QGtkStyle::standardPalette() const
{
+ Q_D(const QGtkStyle);
+
QPalette palette = QCleanlooksStyle::standardPalette();
- if (QGtk::isThemeAvailable()) {
- GtkStyle *style = QGtk::gtkStyle();
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
- GtkWidget *gtkEntry = QGtk::gtkWidget(QLS("GtkEntry"));
+ if (d->isThemeAvailable()) {
+ GtkStyle *style = d->gtkStyle();
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkEntry = d->getTextColorWidget();
GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg;
QColor bg, base, text, fg, highlight, highlightText;
@@ -281,12 +253,12 @@ QPalette QGtkStyle::standardPalette() const
palette.setColor(QPalette::Base, base);
QColor alternateRowColor = palette.base().color().lighter(93); // ref gtkstyle.c draw_flat_box
- GtkWidget *gtkTreeView = QGtk::gtkWidget(QLS("GtkTreeView"));
+ GtkWidget *gtkTreeView = d->gtkWidget(QLS("GtkTreeView"));
GdkColor *gtkAltBase = NULL;
- QGtk::gtk_widget_style_get(gtkTreeView, "odd-row-color", &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);
- QGtk::gdk_color_free(gtkAltBase);
+ d->gdk_color_free(gtkAltBase);
}
palette.setColor(QPalette::AlternateBase, alternateRowColor);
@@ -306,7 +278,8 @@ QPalette QGtkStyle::standardPalette() const
highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
palette.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
palette.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
- style = QGtk::gtk_rc_get_style_by_paths(QGtk::gtk_settings_get_default(), "gtk-tooltips", "GtkWindow", Q_GTK_TYPE_WINDOW);
+ 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);
@@ -321,10 +294,12 @@ QPalette QGtkStyle::standardPalette() const
*/
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 (!QGtk::isThemeAvailable())
+ if (!d->isThemeAvailable())
QCleanlooksStyle::polish(palette);
else
palette = palette.resolve(standardPalette());
@@ -335,19 +310,21 @@ void QGtkStyle::polish(QPalette &palette)
*/
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() && QGtk::isThemeAvailable()) {
+ if (app->desktopSettingsAware() && d->isThemeAvailable()) {
QApplicationPrivate::setSystemPalette(standardPalette());
- QApplicationPrivate::setSystemFont(QGtk::getThemeFont());
- QGtk::applyCustomPaletteHash();
- if (!QGtk::isKDE4Session()) {
- qt_filedialog_open_filename_hook = &QGtk::openFilename;
- qt_filedialog_save_filename_hook = &QGtk::saveFilename;
- qt_filedialog_open_filenames_hook = &QGtk::openFilenames;
- qt_filedialog_existing_directory_hook = &QGtk::openDirectory;
+ 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;
}
}
}
@@ -357,11 +334,13 @@ void QGtkStyle::polish(QApplication *app)
*/
void QGtkStyle::unpolish(QApplication *app)
{
+ Q_D(QGtkStyle);
+
QCleanlooksStyle::unpolish(app);
QPixmapCache::clear();
- if (app->desktopSettingsAware() && QGtk::isThemeAvailable()
- && !QGtk::isKDE4Session()) {
+ 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;
@@ -375,8 +354,10 @@ void QGtkStyle::unpolish(QApplication *app)
void QGtkStyle::polish(QWidget *widget)
{
+ Q_D(QGtkStyle);
+
QCleanlooksStyle::polish(widget);
- if (!QGtk::isThemeAvailable())
+ if (!d->isThemeAvailable())
return;
if (qobject_cast<QAbstractButton*>(widget)
|| qobject_cast<QToolButton*>(widget)
@@ -404,21 +385,22 @@ void QGtkStyle::unpolish(QWidget *widget)
\reimp
*/
int QGtkStyle::pixelMetric(PixelMetric metric,
-
const QStyleOption *option,
const QWidget *widget) const
{
- if (!QGtk::isThemeAvailable())
+ 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 =
- QGtk::gtk_rc_get_style_by_paths(QGtk::gtk_settings_get_default(),
+ d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
"*.GtkScrolledWindow",
"*.GtkScrolledWindow",
- Q_GTK_TYPE_WINDOW))
+ d->gtk_window_get_type()))
return qMax(style->xthickness, style->ythickness);
}
return 2;
@@ -439,16 +421,16 @@ int QGtkStyle::pixelMetric(PixelMetric metric,
return 0;
case PM_ButtonShiftHorizontal: {
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton"));
guint horizontal_shift;
- QGtk::gtk_widget_style_get(gtkButton, "child-displacement-x", &horizontal_shift, NULL);
+ d->gtk_widget_style_get(gtkButton, "child-displacement-x", &horizontal_shift, NULL);
return horizontal_shift;
}
case PM_ButtonShiftVertical: {
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton"));
guint vertical_shift;
- QGtk::gtk_widget_style_get(gtkButton, "child-displacement-y", &vertical_shift, NULL);
+ d->gtk_widget_style_get(gtkButton, "child-displacement-y", &vertical_shift, NULL);
return vertical_shift;
}
@@ -456,18 +438,18 @@ int QGtkStyle::pixelMetric(PixelMetric metric,
return 0;
case PM_MenuPanelWidth: {
- GtkWidget *gtkMenu = QGtk::gtkWidget(QLS("GtkMenu"));
+ GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu"));
guint horizontal_padding = 0;
// horizontal-padding is used by Maemo to get thicker borders
- if (!QGtk::gtk_check_version(2, 10, 0))
- QGtk::gtk_widget_style_get(gtkMenu, "horizontal-padding", &horizontal_padding, NULL);
+ 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 = QGtk::gtk_settings_get_default();
+ 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(':'));
@@ -513,9 +495,9 @@ int QGtkStyle::pixelMetric(PixelMetric metric,
case PM_SliderThickness:
case PM_SliderControlThickness: {
- GtkWidget *gtkScale = QGtk::gtkWidget(QLS("GtkHScale"));
+ GtkWidget *gtkScale = d->gtkWidget(QLS("GtkHScale"));
gint val;
- QGtk::gtk_widget_style_get(gtkScale, "slider-width", &val, NULL);
+ d->gtk_widget_style_get(gtkScale, "slider-width", &val, NULL);
if (metric == PM_SliderControlThickness)
return val + 2*gtkScale->style->ythickness;
return val;
@@ -524,8 +506,8 @@ int QGtkStyle::pixelMetric(PixelMetric metric,
case PM_ScrollBarExtent: {
gint sliderLength;
gint trough_border;
- GtkWidget *hScrollbar = QGtk::gtkWidget(QLS("GtkHScrollbar"));
- QGtk::gtk_widget_style_get(hScrollbar,
+ GtkWidget *hScrollbar = d->gtkWidget(QLS("GtkHScrollbar"));
+ d->gtk_widget_style_get(hScrollbar,
"trough-border", &trough_border,
"slider-width", &sliderLength,
NULL);
@@ -537,35 +519,35 @@ int QGtkStyle::pixelMetric(PixelMetric metric,
case PM_SliderLength:
gint val;
- QGtk::gtk_widget_style_get(QGtk::gtkWidget(QLS("GtkHScale")), "slider-length", &val, NULL);
+ d->gtk_widget_style_get(d->gtkWidget(QLS("GtkHScale")), "slider-length", &val, NULL);
return val;
case PM_ExclusiveIndicatorWidth:
case PM_ExclusiveIndicatorHeight:
case PM_IndicatorWidth:
case PM_IndicatorHeight: {
- GtkWidget *gtkCheckButton = QGtk::gtkWidget(QLS("GtkCheckButton"));
+ GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
gint size, spacing;
- QGtk::gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, "indicator-size", &size, NULL);
+ d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, "indicator-size", &size, NULL);
return size + 2 * spacing;
}
case PM_MenuBarVMargin: {
- GtkWidget *gtkMenubar = QGtk::gtkWidget(QLS("GtkMenuBar"));
+ GtkWidget *gtkMenubar = d->gtkWidget(QLS("GtkMenuBar"));
return qMax(0, gtkMenubar->style->ythickness);
}
case PM_ScrollView_ScrollBarSpacing:
{
gint spacing = 3;
- GtkWidget *gtkScrollWindow = QGtk::gtkWidget(QLS("GtkScrolledWindow"));
+ GtkWidget *gtkScrollWindow = d->gtkWidget(QLS("GtkScrolledWindow"));
Q_ASSERT(gtkScrollWindow);
- QGtk::gtk_widget_style_get(gtkScrollWindow, "scrollbar-spacing", &spacing, NULL);
+ d->gtk_widget_style_get(gtkScrollWindow, "scrollbar-spacing", &spacing, NULL);
return spacing;
}
case PM_SubMenuOverlap: {
gint offset = 0;
- GtkWidget *gtkMenu = QGtk::gtkWidget(QLS("GtkMenu"));
- QGtk::gtk_widget_style_get(gtkMenu, "horizontal-offset", &offset, NULL);
+ GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu"));
+ d->gtk_widget_style_get(gtkMenu, "horizontal-offset", &offset, NULL);
return offset;
}
default:
@@ -580,7 +562,9 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
QStyleHintReturn *returnData = 0) const
{
- if (!QGtk::isThemeAvailable())
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
switch (hint) {
@@ -588,7 +572,7 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
case SH_DialogButtonLayout: {
int ret = QDialogButtonBox::GnomeLayout;
gboolean alternateOrder = 0;
- GtkSettings *settings = QGtk::gtk_settings_get_default();
+ GtkSettings *settings = d->gtk_settings_get_default();
g_object_get(settings, "gtk-alternative-button-order", &alternateOrder, NULL);
if (alternateOrder)
@@ -601,9 +585,9 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
case SH_ToolButtonStyle:
{
- if (QGtk::isKDE4Session())
+ if (d->isKDE4Session())
return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
- GtkWidget *gtkToolbar = QGtk::gtkWidget(QLS("GtkToolbar"));
+ GtkWidget *gtkToolbar = d->gtkWidget(QLS("GtkToolbar"));
GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
g_object_get(gtkToolbar, "toolbar-style", &toolbar_style, NULL);
switch (toolbar_style) {
@@ -626,9 +610,9 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
return int(false);
case SH_ComboBox_Popup: {
- GtkWidget *gtkComboBox = QGtk::gtkWidget(QLS("GtkComboBox"));
+ GtkWidget *gtkComboBox = d->gtkWidget(QLS("GtkComboBox"));
gboolean appears_as_list;
- QGtk::gtk_widget_style_get((GtkWidget*)gtkComboBox, "appears-as-list", &appears_as_list, NULL);
+ d->gtk_widget_style_get((GtkWidget*)gtkComboBox, "appears-as-list", &appears_as_list, NULL);
return appears_as_list ? 0 : 1;
}
@@ -640,7 +624,7 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
case SH_Menu_SubMenuPopupDelay: {
gint delay = 225;
- GtkSettings *settings = QGtk::gtk_settings_get_default();
+ GtkSettings *settings = d->gtk_settings_get_default();
g_object_get(settings, "gtk-menu-popup-delay", &delay, NULL);
return delay;
}
@@ -649,15 +633,15 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
gboolean scrollbars_within_bevel = false;
if (widget && widget->isWindow())
scrollbars_within_bevel = true;
- else if (!QGtk::gtk_check_version(2, 12, 0)) {
- GtkWidget *gtkScrollWindow = QGtk::gtkWidget(QLS("GtkScrolledWindow"));
- QGtk::gtk_widget_style_get(gtkScrollWindow, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
+ else if (!d->gtk_check_version(2, 12, 0)) {
+ GtkWidget *gtkScrollWindow = d->gtkWidget(QLS("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 = QGtk::getGConfBool(QLS("/desktop/gnome/interface/buttons_have_icons"));
+ static bool buttonsHaveIcons = d->getGConfBool(QLS("/desktop/gnome/interface/buttons_have_icons"));
return buttonsHaveIcons;
}
@@ -670,17 +654,18 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
\reimp
*/
void QGtkStyle::drawPrimitive(PrimitiveElement element,
-
const QStyleOption *option,
QPainter *painter,
const QWidget *widget) const
{
- if (!QGtk::isThemeAvailable()) {
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
return;
}
- GtkStyle* style = QGtk::gtkStyle();
+ GtkStyle* style = d->gtkStyle();
QGtkPainter gtkPainter(painter);
switch (element) {
@@ -715,10 +700,10 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
else if (option->state & State_Raised)
shadow_type = GTK_SHADOW_OUT;
- GtkStyle *style = QGtk::gtk_rc_get_style_by_paths(QGtk::gtk_settings_get_default(),
- "*.GtkScrolledWindow", "*.GtkScrolledWindow", Q_GTK_TYPE_WINDOW);
+ 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(QGtk::gtkWidget(QLS("GtkFrame")), "viewport", pmRect,
+ gtkFramePainter.paintShadow(d->gtkWidget(QLS("GtkFrame")), "viewport", pmRect,
option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
shadow_type, style);
QPixmapCache::insert(pmKey, pixmap);
@@ -745,8 +730,9 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
break;
case PE_PanelTipLabel: {
- GtkWidget *gtkWindow = QGtk::gtkWidget(QLS("GtkWindow")); // The Murrine Engine currently assumes a widget is passed
- style = QGtk::gtk_rc_get_style_by_paths(QGtk::gtk_settings_get_default(), "gtk-tooltips", "GtkWindow", Q_GTK_TYPE_WINDOW);
+ GtkWidget *gtkWindow = d->gtkWidget(QLS("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;
@@ -759,8 +745,8 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
break;
}
GtkShadowType shadow_type;
- GtkWidget *gtkStatusbarFrame = QGtk::gtkWidget(QLS("GtkStatusbar.GtkFrame"));
- QGtk::gtk_widget_style_get(gtkStatusbarFrame->parent, "shadow-type", &shadow_type, NULL);
+ GtkWidget *gtkStatusbarFrame = d->gtkWidget(QLS("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);
}
@@ -768,7 +754,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
case PE_IndicatorHeaderArrow:
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- GtkWidget *gtkTreeHeader = QGtk::gtkWidget(QLS("GtkTreeView.GtkButton"));
+ GtkWidget *gtkTreeHeader = d->gtkWidget(QLS("GtkTreeView.GtkButton"));
GtkStateType state = gtkPainter.gtkState(option);
style = gtkTreeHeader->style;
GtkArrowType type = GTK_ARROW_UP;
@@ -806,7 +792,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
rect.translate(2, 0);
GtkExpanderStyle openState = GTK_EXPANDER_EXPANDED;
GtkExpanderStyle closedState = GTK_EXPANDER_COLLAPSED;
- GtkWidget *gtkTreeView = QGtk::gtkWidget(QLS("GtkTreeView"));
+ GtkWidget *gtkTreeView = d->gtkWidget(QLS("GtkTreeView"));
GtkStateType state = GTK_STATE_NORMAL;
if (!(option->state & State_Enabled))
@@ -842,7 +828,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
case PE_IndicatorToolBarSeparator:
{
const int margin = 6;
- GtkWidget *gtkSeparator = QGtk::gtkWidget(QLS("GtkToolbar.GtkSeparatorToolItem"));
+ GtkWidget *gtkSeparator = d->gtkWidget(QLS("GtkToolbar.GtkSeparatorToolItem"));
if (option->state & State_Horizontal) {
const int offset = option->rect.width()/2;
QRect rect = option->rect.adjusted(offset, margin, 0, -margin);
@@ -862,9 +848,9 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
break;
case PE_IndicatorToolBarHandle: {
- GtkWidget *gtkToolbar = QGtk::gtkWidget(QLS("GtkToolbar"));
+ GtkWidget *gtkToolbar = d->gtkWidget(QLS("GtkToolbar"));
GtkShadowType shadow_type;
- QGtk::gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
+ 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),
@@ -910,14 +896,14 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
GtkStateType state = gtkPainter.gtkState(option);
QColor arrowColor = option->palette.buttonText().color();
- GtkWidget *gtkArrow = QGtk::gtkWidget(QLS("GtkArrow"));
+ GtkWidget *gtkArrow = d->gtkWidget(QLS("GtkArrow"));
GdkColor color = fromQColor(arrowColor);
- QGtk::gtk_widget_modify_fg (gtkArrow, state, &color);
+ 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
- QGtk::gtk_widget_modify_fg (gtkArrow, state, NULL);
+ d->gtk_widget_modify_fg (gtkArrow, state, NULL);
}
break;
@@ -926,7 +912,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
break;
case PE_PanelMenu: {
- GtkWidget *gtkMenu = QGtk::gtkWidget(QLS("GtkMenu"));
+ GtkWidget *gtkMenu = d->gtkWidget(QLS("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());
}
@@ -938,7 +924,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
// This is only used by floating tool bars
if (qobject_cast<const QToolBar *>(widget)) {
- GtkWidget *gtkMenubar = QGtk::gtkWidget(QLS("GtkMenuBar"));
+ GtkWidget *gtkMenubar = d->gtkWidget(QLS("GtkMenuBar"));
gtkPainter.paintBox( gtkMenubar, "toolbar", option->rect,
GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
gtkPainter.paintBox( gtkMenubar, "menu", option->rect,
@@ -947,13 +933,13 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
break;
case PE_FrameLineEdit: {
- GtkWidget *gtkEntry = QGtk::gtkWidget(QLS("GtkEntry"));
+ GtkWidget *gtkEntry = d->gtkWidget(QLS("GtkEntry"));
gboolean interior_focus;
gint focus_line_width;
QRect rect = option->rect;
- QGtk::gtk_widget_style_get(gtkEntry,
+ d->gtk_widget_style_get(gtkEntry,
"interior-focus", &interior_focus,
"focus-line-width", &focus_line_width, NULL);
@@ -981,7 +967,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
case PE_PanelLineEdit:
if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- GtkWidget *gtkEntry = QGtk::gtkWidget(QLS("GtkEntry"));
+ GtkWidget *gtkEntry = d->gtkWidget(QLS("GtkEntry"));
if (panel->lineWidth > 0)
proxy()->drawPrimitive(PE_FrameLineEdit, option, painter, widget);
uint resolve_mask = option->palette.resolve();
@@ -999,54 +985,58 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
case PE_FrameTabWidget:
if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option)) {
- GtkWidget *gtkNotebook = QGtk::gtkWidget(QLS("GtkNotebook"));
+ GtkWidget *gtkNotebook = d->gtkWidget(QLS("GtkNotebook"));
style = gtkPainter.getStyle(gtkNotebook);
gtkPainter.setAlphaSupport(false);
GtkShadowType shadow = GTK_SHADOW_OUT;
GtkStateType state = GTK_STATE_NORMAL; // Only state supported by gtknotebook
- if (const QTabWidget *tabwidget = qobject_cast<const QTabWidget*>(widget)) {
- // We should introduce QStyleOptionTabWidgetFrameV2 to obtain this information
- // No gap if we do not show the actual tabs
- QTabBar *tabBar = tabwidget->findChild<QTabBar*>();
- if (tabwidget->count() > 0 && tabBar->isVisible()) {
- QRect tabRect = tabBar->tabRect(tabBar->currentIndex());
- int begin = 0, size = 0;
- GtkPositionType frameType = GTK_POS_TOP;
- QTabBar::Shape shape = frame->shape;
- if (shape == QTabBar::RoundedNorth || shape == QTabBar::RoundedSouth) {
- begin = option->direction == Qt::LeftToRight ?
- frame->leftCornerWidgetSize.width() + tabRect.left() :
- frame->rect.width() - frame->tabBarSize.width() + tabRect.left()
- - frame->rightCornerWidgetSize.width();
- size = tabRect.width();
- frameType = (shape == QTabBar::RoundedNorth) ? GTK_POS_TOP : GTK_POS_BOTTOM;
- } else {
- begin = frame->leftCornerWidgetSize.height() + tabRect.top();
- size = tabRect.height();
- frameType = (shape == QTabBar::RoundedWest) ? GTK_POS_LEFT : GTK_POS_RIGHT;
- }
- gtkPainter.paintBoxGap(gtkNotebook, "notebook", option->rect, state, shadow, frameType,
- begin, size, style);
- break; // done
+ 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_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 = QGtk::gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkButton = d->gtkWidget(isTool ? QLS("GtkToolButton.GtkButton") : QLS("GtkButton"));
gint focusWidth, focusPad;
gboolean interiorFocus = false;
- QGtk::gtk_widget_style_get (gtkButton,
+ d->gtk_widget_style_get (gtkButton,
"focus-line-width", &focusWidth,
"focus-padding", &focusPad,
"interior-focus", &interiorFocus, NULL);
@@ -1099,14 +1089,14 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
else
shadow = GTK_SHADOW_OUT;
- GtkWidget *gtkRadioButton = QGtk::gtkWidget(QLS("GtkRadioButton"));
+ GtkWidget *gtkRadioButton = d->gtkWidget(QLS("GtkRadioButton"));
gint spacing;
- QGtk::gtk_widget_style_get(gtkRadioButton, "indicator-spacing", &spacing, NULL);
+ 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 = QGtk::gtkWidget(QLS("GtkCheckButton"));
+ GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, QLS("radiobutton"));
}
@@ -1128,12 +1118,12 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
int spacing;
- GtkWidget *gtkCheckButton = QGtk::gtkWidget(QLS("GtkCheckButton"));
+ GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
// Some styles such as aero-clone assume they can paint in the spacing area
gtkPainter.setClipRect(option->rect);
- QGtk::gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, NULL);
+ d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, NULL);
QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
@@ -1200,12 +1190,14 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
QPainter *painter, const QWidget *widget) const
{
- if (!QGtk::isThemeAvailable()) {
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
QCleanlooksStyle::drawComplexControl(control, option, painter, widget);
return;
}
- GtkStyle* style = QGtk::gtkStyle();
+ GtkStyle* style = d->gtkStyle();
QGtkPainter gtkPainter(painter);
QColor button = option->palette.button().color();
QColor dark;
@@ -1260,7 +1252,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
// Draw prelight background
- GtkWidget *gtkCheckButton = QGtk::gtkWidget(QLS("GtkCheckButton"));
+ GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton"));
if (option->state & State_MouseOver) {
QRect bgRect = textRect | checkBoxRect;
@@ -1336,14 +1328,14 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
QString comboBoxPath = QLS(comboBox->editable ? "GtkComboBoxEntry" : "GtkComboBox");
// We use the gtk widget to position arrows and separators for us
- GtkWidget *gtkCombo = QGtk::gtkWidget(comboBoxPath);
+ GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath);
GtkAllocation geometry = {0, 0, option->rect.width(), option->rect.height()};
- QGtk::gtk_widget_set_direction(gtkCombo, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- QGtk::gtk_widget_size_allocate(gtkCombo, &geometry);
+ d->gtk_widget_set_direction(gtkCombo, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ d->gtk_widget_size_allocate(gtkCombo, &geometry);
QString buttonPath = comboBoxPath + QLS(".GtkToggleButton");
- GtkWidget *gtkToggleButton = QGtk::gtkWidget(buttonPath);
- QGtk::gtk_widget_set_direction(gtkToggleButton, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ 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);
@@ -1351,8 +1343,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
if (comboBox->editable || appears_as_list) {
GtkStateType frameState = (state == GTK_STATE_PRELIGHT) ? GTK_STATE_NORMAL : state;
QString entryPath = QLS(comboBox->editable ? "GtkComboBoxEntry.GtkEntry" : "GtkComboBox.GtkFrame");
- GtkWidget *gtkEntry = QGtk::gtkWidget(entryPath);
- QGtk::gtk_widget_set_direction(gtkEntry, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ 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)
@@ -1421,7 +1413,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
// Draw the separator between label and arrows
QString vSeparatorPath = buttonPath + QLS(".GtkHBox.GtkVSeparator");
- if (GtkWidget *gtkVSeparator = QGtk::gtkWidget(vSeparatorPath)) {
+ if (GtkWidget *gtkVSeparator = d->gtkWidget(vSeparatorPath)) {
QRect vLineRect(gtkVSeparator->allocation.x,
gtkVSeparator->allocation.y,
gtkVSeparator->allocation.width,
@@ -1433,7 +1425,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
gint interiorFocus = true;
- QGtk::gtk_widget_style_get(gtkToggleButton, "interior-focus", &interiorFocus, NULL);
+ 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)))
@@ -1457,14 +1449,14 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
QString arrowPath = comboBoxPath + QLS(appears_as_list ? ".GtkToggleButton.GtkArrow"
: ".GtkToggleButton.GtkHBox.GtkArrow");
- GtkWidget *gtkArrow = QGtk::gtkWidget(arrowPath);
+ GtkWidget *gtkArrow = d->gtkWidget(arrowPath);
gfloat scale = 0.7;
gint minSize = 15;
QRect arrowWidgetRect;
- if (gtkArrow && !QGtk::gtk_check_version(2, 12, 0)) {
- QGtk::gtk_widget_style_get(gtkArrow, "arrow-scaling", &scale, NULL);
- QGtk::gtk_widget_style_get(gtkCombo, "arrow-size", &minSize, NULL);
+ 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,
@@ -1482,9 +1474,9 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
if (sunken) {
int xoff, yoff;
- GtkWidget *gtkButton = QGtk::gtkWidget(comboBoxPath + QLS(".GtkToggleButton"));
- QGtk::gtk_widget_style_get(gtkButton, "child-displacement-x", &xoff, NULL);
- QGtk::gtk_widget_style_get(gtkButton, "child-displacement-y", &yoff, NULL);
+ GtkWidget *gtkButton = d->gtkWidget(comboBoxPath + QLS(".GtkToggleButton"));
+ 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);
}
@@ -1555,7 +1547,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
QStyleOptionToolButton label = *toolbutton;
label.state = bflags;
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkToolButton.GtkButton"));
QPalette pal = toolbutton->palette;
if (option->state & State_Enabled &&
option->state & State_MouseOver && !(widget && widget->testAttribute(Qt::WA_SetPalette))) {
@@ -1590,8 +1582,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
case CC_ScrollBar:
if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- GtkWidget *gtkHScrollBar = QGtk::gtkWidget(QLS("GtkHScrollbar"));
- GtkWidget *gtkVScrollBar = QGtk::gtkWidget(QLS("GtkVScrollbar"));
+ GtkWidget *gtkHScrollBar = d->gtkWidget(QLS("GtkHScrollbar"));
+ GtkWidget *gtkVScrollBar = d->gtkWidget(QLS("GtkVScrollbar"));
// Fill background in case the scrollbar is partially transparent
painter->fillRect(option->rect, option->palette.background());
@@ -1608,8 +1600,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
gboolean trough_side_details = false;
gboolean stepper_size = 14;
gint trough_border = 1;
- if (!QGtk::gtk_check_version(2, 10, 0)) {
- QGtk::gtk_widget_style_get((GtkWidget*)(scrollbarWidget),
+ 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,
@@ -1633,12 +1625,12 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
fakePos = maximum;
else if (scrollBar->sliderPosition > scrollBar->minimum)
fakePos = maximum - 1;
- GtkObject *adjustment = QGtk::gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
+ GtkObject *adjustment = d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
if (horizontal)
- QGtk::gtk_range_set_adjustment((GtkRange*)(gtkHScrollBar), (GtkAdjustment*)(adjustment));
+ d->gtk_range_set_adjustment((GtkRange*)(gtkHScrollBar), (GtkAdjustment*)(adjustment));
else
- QGtk::gtk_range_set_adjustment((GtkRange*)(gtkVScrollBar), (GtkAdjustment*)(adjustment));
+ d->gtk_range_set_adjustment((GtkRange*)(gtkVScrollBar), (GtkAdjustment*)(adjustment));
if (scrollBar->subControls & SC_ScrollBarGroove) {
GtkStateType state = GTK_STATE_ACTIVE;
@@ -1735,7 +1727,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
case CC_SpinBox:
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- GtkWidget *gtkSpinButton = QGtk::gtkWidget(QLS("GtkSpinButton"));
+ GtkWidget *gtkSpinButton = d->gtkWidget(QLS("GtkSpinButton"));
bool isEnabled = (spinBox->state & State_Enabled);
bool hover = isEnabled && (spinBox->state & State_MouseOver);
bool sunken = (spinBox->state & State_Sunken);
@@ -1850,7 +1842,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
}
} else {
- int size = spinboxArrowSize();
+ int size = d->getSpinboxArrowSize();
int w = size / 2 - 1;
w -= w % 2 - 1; // force odd
int h = (w + 1)/2;
@@ -1882,8 +1874,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
case CC_Slider:
if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- GtkWidget *hScaleWidget = QGtk::gtkWidget(QLS("GtkHScale"));
- GtkWidget *vScaleWidget = QGtk::gtkWidget(QLS("GtkVScale"));
+ GtkWidget *hScaleWidget = d->gtkWidget(QLS("GtkHScale"));
+ GtkWidget *vScaleWidget = d->gtkWidget(QLS("GtkVScale"));
QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
@@ -1907,16 +1899,16 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
style = scaleWidget->style;
if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
- GtkObject *adjustment = QGtk::gtk_adjustment_new(slider->sliderPosition,
+ GtkObject *adjustment = d->gtk_adjustment_new(slider->sliderPosition,
slider->minimum,
slider->maximum,
slider->singleStep,
slider->singleStep,
slider->pageStep);
int outerSize;
- QGtk::gtk_range_set_adjustment ((GtkRange*)(scaleWidget), (GtkAdjustment*)(adjustment));
- QGtk::gtk_range_set_inverted((GtkRange*)(scaleWidget), !horizontal);
- QGtk::gtk_widget_style_get(scaleWidget, "trough-border", &outerSize, NULL);
+ d->gtk_range_set_adjustment ((GtkRange*)(scaleWidget), (GtkAdjustment*)(adjustment));
+ d->gtk_range_set_inverted((GtkRange*)(scaleWidget), !horizontal);
+ d->gtk_widget_style_get(scaleWidget, "trough-border", &outerSize, NULL);
outerSize++;
GtkStateType state = gtkPainter.gtkState(option);
@@ -1924,20 +1916,30 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom
QRect grooveRect = option->rect.adjusted(focusFrameMargin, outerSize + focusFrameMargin,
-focusFrameMargin, -outerSize - focusFrameMargin);
- gtkPainter.paintBox( scaleWidget, "trough", grooveRect, state,
- GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
-
gboolean trough_side_details = false; // Indicates if the upper or lower scale background differs
- if (!QGtk::gtk_check_version(2, 10, 0))
- QGtk::gtk_widget_style_get((GtkWidget*)(scaleWidget), "trough-side-details", &trough_side_details, NULL);
+ 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 && horizontal) { //### Vertical sliders look broken with this for some reason
+ 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;
- lowerGroove.setRight(handle.center().x());
+
+ if (horizontal) {
+ upperGroove.setLeft(handle.center().x());
+ lowerGroove.setRight(handle.center().x());
+ } 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) {
@@ -2050,18 +2052,20 @@ void QGtkStyle::drawControl(ControlElement element,
QPainter *painter,
const QWidget *widget) const
{
- if (!QGtk::isThemeAvailable()) {
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
QCleanlooksStyle::drawControl(element, option, painter, widget);
return;
}
- GtkStyle* style = QGtk::gtkStyle();
+ GtkStyle* style = d->gtkStyle();
QGtkPainter gtkPainter(painter);
switch (element) {
case CE_ProgressBarLabel:
if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- GtkWidget *gtkProgressBar = QGtk::gtkWidget(QLS("GtkProgressBar"));
+ GtkWidget *gtkProgressBar = d->gtkWidget(QLS("GtkProgressBar"));
if (!gtkProgressBar)
return;
@@ -2164,7 +2168,7 @@ void QGtkStyle::drawControl(ControlElement element,
if (button->features & QStyleOptionButton::HasMenu)
ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton"));
QPalette pal = button->palette;
int labelState = GTK_STATE_INSENSITIVE;
if (option->state & State_Enabled)
@@ -2185,7 +2189,7 @@ void QGtkStyle::drawControl(ControlElement element,
bool isRadio = (element == CE_RadioButton);
// Draw prelight background
- GtkWidget *gtkRadioButton = QGtk::gtkWidget(QLS("GtkRadioButton"));
+ GtkWidget *gtkRadioButton = d->gtkWidget(QLS("GtkRadioButton"));
if (option->state & State_MouseOver) {
gtkPainter.paintFlatBox(gtkRadioButton, "checkbutton", option->rect,
@@ -2253,7 +2257,7 @@ void QGtkStyle::drawControl(ControlElement element,
}
if (!cb->currentText.isEmpty() && !cb->editable) {
- GtkWidget *gtkCombo = QGtk::gtkWidget(QLS("GtkComboBox"));
+ GtkWidget *gtkCombo = d->gtkWidget(QLS("GtkComboBox"));
QPalette pal = cb->palette;
int labelState = GTK_STATE_INSENSITIVE;
@@ -2330,9 +2334,9 @@ void QGtkStyle::drawControl(ControlElement element,
// Draws the header in tables.
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
Q_UNUSED(header);
- GtkWidget *gtkTreeView = QGtk::gtkWidget(QLS("GtkTreeView"));
+ GtkWidget *gtkTreeView = d->gtkWidget(QLS("GtkTreeView"));
// Get the middle column
- GtkTreeViewColumn *column = QGtk::gtk_tree_view_get_column((GtkTreeView*)gtkTreeView, 1);
+ GtkTreeViewColumn *column = d->gtk_tree_view_get_column((GtkTreeView*)gtkTreeView, 1);
Q_ASSERT(column);
GtkWidget *gtkTreeHeader = column->button;
@@ -2351,7 +2355,7 @@ void QGtkStyle::drawControl(ControlElement element,
#ifndef QT_NO_SIZEGRIP
case CE_SizeGrip: {
- GtkWidget *gtkStatusbar = QGtk::gtkWidget(QLS("GtkStatusbar.GtkFrame"));
+ GtkWidget *gtkStatusbar = d->gtkWidget(QLS("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() ?
@@ -2363,7 +2367,7 @@ void QGtkStyle::drawControl(ControlElement element,
#endif // QT_NO_SIZEGRIP
case CE_MenuBarEmptyArea: {
- GtkWidget *gtkMenubar = QGtk::gtkWidget(QLS("GtkMenuBar"));
+ GtkWidget *gtkMenubar = d->gtkWidget(QLS("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
@@ -2373,7 +2377,7 @@ void QGtkStyle::drawControl(ControlElement element,
QPainter pmPainter(&pixmap);
QGtkPainter gtkMenuBarPainter(&pmPainter);
GtkShadowType shadow_type;
- QGtk::gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
+ 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();
@@ -2386,8 +2390,8 @@ void QGtkStyle::drawControl(ControlElement element,
painter->save();
if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- GtkWidget *gtkMenubarItem = QGtk::gtkWidget(QLS("GtkMenuBar.GtkMenuItem"));
- GtkWidget *gtkMenubar = QGtk::gtkWidget(QLS("GtkMenuBar"));
+ GtkWidget *gtkMenubarItem = d->gtkWidget(QLS("GtkMenuBar.GtkMenuItem"));
+ GtkWidget *gtkMenubar = d->gtkWidget(QLS("GtkMenuBar"));
style = gtkMenubarItem->style;
@@ -2402,7 +2406,7 @@ void QGtkStyle::drawControl(ControlElement element,
QPainter pmPainter(&pixmap);
QGtkPainter menubarPainter(&pmPainter);
GtkShadowType shadow_type;
- QGtk::gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
+ 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,
@@ -2426,7 +2430,7 @@ void QGtkStyle::drawControl(ControlElement element,
if (act) {
GtkShadowType shadowType = GTK_SHADOW_NONE;
- QGtk::gtk_widget_style_get (gtkMenubarItem, "selected-shadow-type", &shadowType, NULL);
+ 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
@@ -2443,7 +2447,7 @@ void QGtkStyle::drawControl(ControlElement element,
break;
case CE_Splitter: {
- GtkWidget *gtkWindow = QGtk::gtkWidget(QLS("GtkWindow")); // The Murrine Engine currently assumes a widget is passed
+ GtkWidget *gtkWindow = d->gtkWidget(QLS("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);
@@ -2463,9 +2467,9 @@ void QGtkStyle::drawControl(ControlElement element,
if (toolbar->positionWithinLine != QStyleOptionToolBar::End)
rect.adjust(0, 0, 1, 0);
- GtkWidget *gtkToolbar = QGtk::gtkWidget(QLS("GtkToolbar"));
+ GtkWidget *gtkToolbar = d->gtkWidget(QLS("GtkToolbar"));
GtkShadowType shadow_type = GTK_SHADOW_NONE;
- QGtk::gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
+ d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
gtkPainter.paintBox( gtkToolbar, "toolbar", rect,
GTK_STATE_NORMAL, shadow_type, gtkToolbar->style);
}
@@ -2482,22 +2486,22 @@ void QGtkStyle::drawControl(ControlElement element,
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 *gtkMenu = QGtk::gtkWidget(QLS("GtkMenu"));
- GtkWidget *gtkMenuItem = menuItem->checked ? QGtk::gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")) :
- QGtk::gtkWidget(QLS("GtkMenu.GtkMenuItem"));
+ GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu"));
+ GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")) :
+ d->gtkWidget(QLS("GtkMenu.GtkMenuItem"));
style = gtkPainter.getStyle(gtkMenuItem);
QColor borderColor = option->palette.background().color().darker(160);
QColor shadow = option->palette.dark().color();
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
- GtkWidget *gtkMenuSeparator = QGtk::gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem"));
+ GtkWidget *gtkMenuSeparator = d->gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem"));
painter->setPen(shadow.lighter(106));
gboolean wide_separators = 0;
gint separator_height = 0;
guint horizontal_padding = 3;
- if (!QGtk::gtk_check_version(2, 10, 0)) {
- QGtk::gtk_widget_style_get(gtkMenuSeparator,
+ 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,
@@ -2517,7 +2521,7 @@ void QGtkStyle::drawControl(ControlElement element,
bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
if (selected) {
- QRect rect = option->rect.adjusted(0, 0, -1, -1);
+ QRect rect = option->rect.adjusted(0, 0, 0, -1);
#ifndef QT_NO_COMBOBOX
if (qobject_cast<const QComboBox*>(widget))
rect = option->rect;
@@ -2531,7 +2535,7 @@ void QGtkStyle::drawControl(ControlElement element,
bool ignoreCheckMark = false;
gint checkSize;
- QGtk::gtk_widget_style_get(QGtk::gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")), "indicator-size", &checkSize, NULL);
+ d->gtk_widget_style_get(d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")), "indicator-size", &checkSize, NULL);
int checkcol = qMax(menuItem->maxIconWidth, qMax(20, checkSize));
@@ -2624,7 +2628,7 @@ void QGtkStyle::drawControl(ControlElement element,
int pixw = pixmap.width();
int pixh = pixmap.height();
QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(vCheckRect.center());
+ pmr.moveCenter(vCheckRect.center() - QPoint(0, 1));
painter->setPen(menuItem->palette.text().color());
if (!ignoreCheckMark && checkable && checked) {
QStyleOption opt = *option;
@@ -2666,8 +2670,8 @@ void QGtkStyle::drawControl(ControlElement element,
menuitem->rect.getRect(&x, &y, &w, &h);
int tab = menuitem->tabWidth;
int xm = windowsItemFrame + checkcol + windowsItemHMargin;
- int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ int xpos = menuitem->rect.x() + xm + 1;
+ QRect textRect(xpos, y + windowsItemVMargin - 1, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
QString s = menuitem->text;
@@ -2714,13 +2718,19 @@ void QGtkStyle::drawControl(ControlElement element,
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;
+ }
- // "arrow-scaling" is actually hardcoded and fails on hardy (see gtk+-2.12/gtkmenuitem.c)
- // though the current documentation states otherwise
int horizontal_padding;
- QGtk::gtk_widget_style_get(gtkMenuItem, "horizontal-padding", &horizontal_padding, NULL);
+ d->gtk_widget_style_get(gtkMenuItem, "horizontal-padding", &horizontal_padding, NULL);
- const int dim = static_cast<int>(arrow_size * arrow_scaling);
+ 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() +
@@ -2736,12 +2746,12 @@ void QGtkStyle::drawControl(ControlElement element,
case CE_PushButton:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton"));
proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
QStyleOptionButton subopt = *btn;
subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
gint interiorFocus = true;
- QGtk::gtk_widget_style_get(gtkButton, "interior-focus", &interiorFocus, NULL);
+ d->gtk_widget_style_get(gtkButton, "interior-focus", &interiorFocus, NULL);
int xt = interiorFocus ? gtkButton->style->xthickness : 0;
int yt = interiorFocus ? gtkButton->style->ythickness : 0;
@@ -2762,7 +2772,7 @@ void QGtkStyle::drawControl(ControlElement element,
case CE_TabBarTabShape:
if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
- GtkWidget *gtkNotebook = QGtk::gtkWidget(QLS("GtkNotebook"));
+ GtkWidget *gtkNotebook = d->gtkWidget(QLS("GtkNotebook"));
style = gtkPainter.getStyle(gtkNotebook);
QRect rect = option->rect;
@@ -2829,7 +2839,7 @@ void QGtkStyle::drawControl(ControlElement element,
case CE_ProgressBarGroove:
if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
Q_UNUSED(bar);
- GtkWidget *gtkProgressBar = QGtk::gtkWidget(QLS("GtkProgressBar"));
+ GtkWidget *gtkProgressBar = d->gtkWidget(QLS("GtkProgressBar"));
GtkStateType state = gtkPainter.gtkState(option);
gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, gtkProgressBar->style);
}
@@ -2839,7 +2849,7 @@ void QGtkStyle::drawControl(ControlElement element,
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 = QGtk::gtkWidget(QLS("GtkProgressBar"));
+ GtkWidget *gtkProgressBar = d->gtkWidget(QLS("GtkProgressBar"));
style = gtkProgressBar->style;
gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, style);
int xt = style->xthickness;
@@ -2887,8 +2897,8 @@ void QGtkStyle::drawControl(ControlElement element,
else if (bar->progress > bar->minimum)
fakePos = maximum - 1;
- GtkObject *adjustment = QGtk::gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
- QGtk::gtk_progress_set_adjustment((GtkProgress*)(gtkProgressBar), (GtkAdjustment*)(adjustment));
+ GtkObject *adjustment = d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
+ d->gtk_progress_set_adjustment((GtkProgress*)(gtkProgressBar), (GtkAdjustment*)(adjustment));
QRect progressBar;
@@ -2928,8 +2938,10 @@ void QGtkStyle::drawControl(ControlElement element,
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 (!QGtk::isThemeAvailable())
+ if (!d->isThemeAvailable())
return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
switch (control) {
@@ -2995,7 +3007,7 @@ QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComple
case CC_SpinBox:
if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- GtkWidget *gtkSpinButton = QGtk::gtkWidget(QLS("GtkSpinButton"));
+ GtkWidget *gtkSpinButton = d->gtkWidget(QLS("GtkSpinButton"));
int center = spinbox->rect.height() / 2;
int xt = spinbox->frame ? gtkSpinButton->style->xthickness : 0;
int yt = spinbox->frame ? gtkSpinButton->style->ythickness : 0;
@@ -3003,7 +3015,7 @@ QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComple
QSize bs;
bs.setHeight(qMax(8, spinbox->rect.height()/2 - y));
- bs.setWidth(spinboxArrowSize());
+ bs.setWidth(d->getSpinboxArrowSize());
int x, lx, rx;
x = spinbox->rect.width() - y - bs.width() + 2;
lx = xt;
@@ -3049,17 +3061,17 @@ QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComple
if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
// We employ the gtk widget to position arrows and separators for us
QString comboBoxPath = box->editable ? QLS("GtkComboBoxEntry") : QLS("GtkComboBox");
- GtkWidget *gtkCombo = QGtk::gtkWidget(comboBoxPath);
- QGtk::gtk_widget_set_direction(gtkCombo, (option->direction == Qt::RightToLeft) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath);
+ 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())};
- QGtk::gtk_widget_size_allocate(gtkCombo, &geometry);
+ d->gtk_widget_size_allocate(gtkCombo, &geometry);
int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, option, widget);
QString arrowPath = comboBoxPath + QLS(".GtkToggleButton");
if (!box->editable && !appears_as_list)
arrowPath += QLS(".GtkHBox.GtkArrow");
- GtkWidget *arrowWidget = QGtk::gtkWidget(arrowPath);
+ GtkWidget *arrowWidget = d->gtkWidget(arrowPath);
if (!arrowWidget)
return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
@@ -3104,27 +3116,27 @@ QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComple
\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 (!QGtk::isThemeAvailable())
+ if (!d->isThemeAvailable())
return newSize;
switch (type) {
case CT_ToolButton:
if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
- newSize = size + QSize(2 * gtkButton->style->xthickness, 1 + 2 * gtkButton->style->ythickness);
+ GtkWidget *gtkButton = d->gtkWidget(QLS("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);
}
@@ -3135,10 +3147,10 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
int textMargin = 8;
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
- GtkWidget *gtkMenuSeparator = QGtk::gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem"));
+ GtkWidget *gtkMenuSeparator = d->gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem"));
gboolean wide_separators;
gint separator_height;
- QGtk::gtk_widget_style_get(gtkMenuSeparator,
+ d->gtk_widget_style_get(gtkMenuSeparator,
"wide-separators", &wide_separators,
"separator-height", &separator_height,
NULL);
@@ -3147,14 +3159,14 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
break;
}
- GtkWidget *gtkMenuItem = QGtk::gtkWidget(QLS("GtkMenu.GtkMenuItem"));
+ GtkWidget *gtkMenuItem = d->gtkWidget(QLS("GtkMenu.GtkMenuItem"));
GtkStyle* style = gtkMenuItem->style;
- newSize += QSize(textMargin + style->xthickness - 2, style->ythickness - 4);
+ newSize += QSize(textMargin + style->xthickness - 1, style->ythickness - 3);
// Cleanlooks assumes a check column of 20 pixels so we need to
// expand it a bit
gint checkSize;
- QGtk::gtk_widget_style_get(QGtk::gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")), "indicator-size", &checkSize, NULL);
+ d->gtk_widget_style_get(d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")), "indicator-size", &checkSize, NULL);
newSize.setHeight(qMax(newSize.height(), checkSize + 2));
newSize.setWidth(newSize.width() + qMax(0, checkSize - 20));
}
@@ -3169,22 +3181,22 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
case CT_SpinBox:
// QSpinBox does some nasty things that depends on CT_LineEdit
- newSize = size + QSize(0, -QGtk::gtkWidget(QLS("GtkSpinButton"))->style->ythickness * 2 + 2);
+ newSize = size + QSize(0, -d->gtkWidget(QLS("GtkSpinButton"))->style->ythickness * 2);
break;
case CT_PushButton:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- GtkWidget *gtkButton = QGtk::gtkWidget(QLS("GtkButton"));
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton"));
gint focusPadding, focusWidth;
- QGtk::gtk_widget_style_get(gtkButton, "focus-padding", &focusPadding, NULL);
- QGtk::gtk_widget_style_get(gtkButton, "focus-line-width", &focusWidth, NULL);
+ 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 = QGtk::gtkWidget(QLS("GtkHButtonBox"));
+ GtkWidget *gtkButtonBox = d->gtkWidget(QLS("GtkHButtonBox"));
gint minWidth = 85, minHeight = 0;
- QGtk::gtk_widget_style_get(gtkButtonBox, "child-min-width", &minWidth,
+ 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);
@@ -3195,18 +3207,14 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
break;
case CT_Slider: {
- GtkWidget *gtkSlider = QGtk::gtkWidget(QLS("GtkHScale"));
+ GtkWidget *gtkSlider = d->gtkWidget(QLS("GtkHScale"));
newSize = size + QSize(2*gtkSlider->style->xthickness, 2*gtkSlider->style->ythickness);
}
break;
- case CT_MenuBarItem://cleanlooks adds 2 pixels
- newSize = QWindowsStyle::sizeFromContents(type, option, size, widget) + QSize(0, 1);
- break;
-
case CT_LineEdit: {
- GtkWidget *gtkEntry = QGtk::gtkWidget(QLS("GtkEntry"));
- newSize = size + QSize(2*gtkEntry->style->xthickness, 2*gtkEntry->style->ythickness);
+ GtkWidget *gtkEntry = d->gtkWidget(QLS("GtkEntry"));
+ newSize = size + QSize(2*gtkEntry->style->xthickness, 2 + 2*gtkEntry->style->ythickness);
}
break;
@@ -3216,12 +3224,12 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
case CT_ComboBox:
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- GtkWidget *gtkCombo = QGtk::gtkWidget(QLS("GtkComboBox"));
+ GtkWidget *gtkCombo = d->gtkWidget(QLS("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, 3);
+ newSize += QSize(0, 2);
}
break;
@@ -3234,7 +3242,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
if (!tab->icon.isNull())
newSize += QSize(6, 0);
}
- newSize += QSize(1, 0);
+ newSize += QSize(1, 1);
break;
default:
@@ -3249,7 +3257,9 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
const QWidget *widget) const
{
- if (!QGtk::isThemeAvailable())
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
return QCleanlooksStyle::standardPixmap(sp, option, widget);
QPixmap pixmap;
@@ -3316,7 +3326,9 @@ QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon,
const QStyleOption *option,
const QWidget *widget) const
{
- if (!QGtk::isThemeAvailable())
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
switch (standardIcon) {
case SP_DialogDiscardButton:
diff --git a/src/gui/styles/qgtkstyle.h b/src/gui/styles/qgtkstyle.h
index 20c2b52b83..5c3bad18c8 100644
--- a/src/gui/styles/qgtkstyle.h
+++ b/src/gui/styles/qgtkstyle.h
@@ -45,6 +45,7 @@
#include <QtGui/QCleanlooksStyle>
#include <QtGui/QPalette>
#include <QtGui/QFont>
+#include <QtGui/QFileDialog>
QT_BEGIN_HEADER
@@ -64,6 +65,8 @@ class Q_GUI_EXPORT QGtkStyle : public QCleanlooksStyle
public:
QGtkStyle();
+ QGtkStyle(QGtkStylePrivate &dd);
+
~QGtkStyle();
QPalette standardPalette() const;
@@ -107,12 +110,15 @@ public:
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
diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp
new file mode 100644
index 0000000000..5f4ebae031
--- /dev/null
+++ b/src/gui/styles/qgtkstyle_p.cpp
@@ -0,0 +1,1083 @@
+/****************************************************************************
+**
+** 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 "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 <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 QGtkStylePrivate::gtk_menu_item_new = 0;
+Ptr_gtk_check_menu_item_new QGtkStylePrivate::gtk_check_menu_item_new = 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_set_adjustment QGtkStylePrivate::gtk_progress_set_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_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_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_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*);
+
+Q_DECLARE_METATYPE(QGtkStylePrivate*);
+
+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 QString classPath(GtkWidget *widget)
+{
+ char* class_path;
+ QGtkStylePrivate::gtk_widget_path (widget, NULL, &class_path, NULL);
+ QString path = QLS(class_path);
+ g_free(class_path);
+
+ // Remove the prefixes
+ path.remove(QLS("GtkWindow."));
+ path.remove(QLS("GtkFixed."));
+ return path;
+}
+
+
+
+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::QGtkStylePrivate()
+ : QCleanlooksStylePrivate()
+ , filter(this)
+{
+ instances.append(this);
+}
+
+QGtkStylePrivate::~QGtkStylePrivate()
+{
+ instances.removeOne(this);
+}
+
+void QGtkStylePrivate::init()
+{
+ resolveGtk();
+ initGtkWidgets();
+ if (isThemeAvailable())
+ qApp->installEventFilter(&filter);
+}
+
+GtkWidget* QGtkStylePrivate::gtkWidget(const QString &path)
+{
+ GtkWidget *widget = gtkWidgetMap()->value(path);
+ if (!widget) {
+ // Theme might have rearranged widget internals
+ widget = gtkWidgetMap()->value(path);
+ }
+ return widget;
+}
+
+GtkStyle* QGtkStylePrivate::gtkStyle(const QString &path)
+{
+ if (gtkWidgetMap()->contains(path))
+ return gtkWidgetMap()->value(path)->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 = (Ptr_gtk_menu_item_new)libgtk.resolve("gtk_menu_item_new");
+ gtk_check_menu_item_new = (Ptr_gtk_check_menu_item_new)libgtk.resolve("gtk_check_menu_item_new");
+ 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_set_adjustment = (Ptr_gtk_progress_set_adjustment)libgtk.resolve("gtk_progress_set_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_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_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");
+ 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();
+ 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();
+ gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem);
+ gtk_widget_realize(gtkMenuItem);
+
+ GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new();
+ 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(QLS("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);
+ gtkWidgetMap()->insert(QLS("GtkWindow"), 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(QLS("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, NULL));
+ 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<QString, GtkWidget*> oldMap = *gtkWidgetMap();
+ gtkWidgetMap()->clear();
+ QHashIterator<QString, GtkWidget*> it(oldMap);
+ while (it.hasNext()) {
+ it.next();
+ if (!it.key().contains(QLatin1Char('.'))) {
+ addAllSubWidgets(it.value());
+ }
+ }
+ }
+ } 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 (gtkWidgetMap()->contains(QLS("GtkWindow"))) // Gtk will destroy all children
+ gtk_widget_destroy(gtkWidgetMap()->value(QLS("GtkWindow")));
+}
+
+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(QLS("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(QLS("GtkMenu"));
+ GdkColor gdkBg = gtkWidget(QLS("GtkMenu"))->style->bg[GTK_STATE_NORMAL];
+ QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ menuPal.setBrush(QPalette::Base, bgColor);
+ menuPal.setBrush(QPalette::Window, bgColor);
+ qApp->setPalette(menuPal, "QMenu");
+
+ QPalette toolbarPal = gtkWidgetPalette(QLS("GtkToolbar"));
+ qApp->setPalette(toolbarPal, "QToolBar");
+
+ QPalette menuBarPal = gtkWidgetPalette(QLS("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(QLS("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(QLS("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::addWidgetToMap(GtkWidget *widget)
+{
+ if (Q_GTK_IS_WIDGET(widget)) {
+ gtk_widget_realize(widget);
+ gtkWidgetMap()->insert(classPath(widget), widget);
+ }
+ }
+
+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 QString &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;
+}
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_STYLE_GTK)
diff --git a/src/gui/styles/gtksymbols_p.h b/src/gui/styles/qgtkstyle_p.h
index 313d948805..f6ab8a3134 100644
--- a/src/gui/styles/gtksymbols_p.h
+++ b/src/gui/styles/qgtkstyle_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef GTKSYMBOLS_H
-#define GTKSYMBOLS_H
+#ifndef QGTKSTYLE_P_H
+#define QGTKSTYLE_P_H
//
// W A R N I N G
@@ -56,19 +56,19 @@
#include <QtCore/qglobal.h>
#if !defined(QT_NO_STYLE_GTK)
+#include <QtGui/QFileDialog>
+
+#include <QtGui/QGtkStyle>
+#include <private/qcleanlooksstyle_p.h>
+
#undef signals // Collides with GTK stymbols
#include <gtk/gtk.h>
-#include <QtCore/QLibrary>
-#include <QtGui/QFont>
-#include <QtGui/QFileDialog>
+
typedef unsigned long XID;
#undef GTK_OBJECT_FLAGS
#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
-#define Q_GTK_TYPE_WIDGET QGtk::gtk_widget_get_type()
-#define Q_GTK_IS_WIDGET(widget) widget && GTK_CHECK_TYPE ((widget), Q_GTK_TYPE_WIDGET)
-#define Q_GTK_TYPE_WINDOW QGtk::gtk_window_get_type()
-#define Q_GTK_TYPE_CONTAINER QGtk::gtk_container_get_type()
+#define Q_GTK_IS_WIDGET(widget) widget && GTK_CHECK_TYPE ((widget), QGtkStylePrivate::gtk_widget_get_type())
#define QLS(x) QLatin1String(x)
@@ -96,6 +96,7 @@ 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 *);
@@ -197,6 +198,35 @@ 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,
@@ -219,21 +249,42 @@ typedef char* (*Ptr_gnome_icon_lookup_sync) (
GnomeIconLookupFlags flags,
GnomeIconLookupResultFlags *result);
-QT_BEGIN_NAMESPACE
-class QGtk
+class QGtkStylePrivate : public QCleanlooksStylePrivate
{
+ Q_DECLARE_PUBLIC(QGtkStyle)
public:
+ QGtkStylePrivate();
+ ~QGtkStylePrivate();
+
+ QGtkStyleFilter filter;
+
static GtkWidget* gtkWidget(const QString &path);
static GtkStyle* gtkStyle(const QString &path = QLatin1String("GtkWindow"));
- static void cleanup_gtk_widgets();
- static void initGtkWidgets();
+ virtual void resolveGtk() const;
+ virtual void initGtkMenu() const;
+ virtual void initGtkTreeview() const;
+ virtual void initGtkWidgets() const;
+
+ static void cleanupGtkWidgets();
+
static bool isKDE4Session();
- static void applyCustomPaletteHash();
+ 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,
@@ -241,8 +292,6 @@ public:
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 QString getGConfString(const QString &key, const QString &fallback = QString());
- static bool getGConfBool(const QString &key, bool fallback = 0);
static QIcon getFilesystemIcon(const QFileInfo &);
static Ptr_gtk_container_forall gtk_container_forall;
@@ -261,6 +310,7 @@ public:
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;
@@ -362,6 +412,33 @@ public:
static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync;
static Ptr_gnome_vfs_init gnome_vfs_init;
+
+ virtual QPalette gtkWidgetPalette(const QString &gtkWidgetName) const;
+
+protected:
+ typedef QHash<QString, GtkWidget*> WidgetMap;
+
+ static inline WidgetMap *gtkWidgetMap()
+ {
+ static WidgetMap *map = 0;
+ if (!map)
+ map = new WidgetMap();
+ return map;
+ }
+
+ 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);
+
+ virtual void init();
+
+private:
+ static QList<QGtkStylePrivate *> instances;
+ friend class QGtkStyleUpdateScheduler;
};
// Helper to ensure that we have polished all our gtk widgets
@@ -376,4 +453,4 @@ public slots:
QT_END_NAMESPACE
#endif // !QT_NO_STYLE_GTK
-#endif // GTKSYMBOLS_H
+#endif // QGTKSTYLE_P_H
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 63ba641906..38c3feb887 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -342,12 +342,12 @@ void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget
borderHighlightTop = QColor(207, 207, 207);
}
p->setPen(borderHighlightTop);
- p->drawLine(0, 0, width, 0);
+ p->drawLine(tabRect.x(), 0, width, 0);
p->setPen(borderTop);
- p->drawLine(0, 1, width, 1);
+ p->drawLine(tabRect.x(), 1, width, 1);
// center block
- QRect centralRect(0, 2, width, height - 2);
+ QRect centralRect(tabRect.x(), 2, width, height - 2);
if (active) {
QColor mainColor = QColor(120, 120, 120);
p->fillRect(centralRect, mainColor);
@@ -370,9 +370,9 @@ void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget
borderBottom = QColor(127, 127, 127);
}
p->setPen(borderHighlightBottom);
- p->drawLine(0, height - 2, width, height - 2);
+ p->drawLine(tabRect.x(), height - 2, width, height - 2);
p->setPen(borderBottom);
- p->drawLine(0, height - 1, width, height - 1);
+ p->drawLine(tabRect.x(), height - 1, width, height - 1);
}
/*
@@ -3637,17 +3637,19 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
break;
}
}
+ bool stretchTabs = (!verticalTabs && tabRect.height() > 22 || verticalTabs && tabRect.width() > 22);
+
switch (tp) {
case QStyleOptionTab::Beginning:
tdi.position = kHIThemeTabPositionFirst;
- if (sp != QStyleOptionTab::NextIsSelected)
+ if (sp != QStyleOptionTab::NextIsSelected || stretchTabs)
tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
break;
case QStyleOptionTab::Middle:
tdi.position = kHIThemeTabPositionMiddle;
if (selected)
tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
- if (sp != QStyleOptionTab::NextIsSelected) // Also when we're selected.
+ if (sp != QStyleOptionTab::NextIsSelected || stretchTabs) // Also when we're selected.
tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
break;
case QStyleOptionTab::End:
@@ -3659,9 +3661,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
tdi.position = kHIThemeTabPositionOnly;
break;
}
-
// HITheme doesn't stretch its tabs. Therefore we have to cheat and do the job ourselves.
- if ((!verticalTabs && tabRect.height() > 21 || verticalTabs && tabRect.width() > 21)) {
+ if (stretchTabs) {
HIRect hirect = CGRectMake(0, 0, 23, 23);
QPixmap pm(23, 23);
pm.fill(Qt::transparent);
diff --git a/src/gui/styles/qmotifstyle.cpp b/src/gui/styles/qmotifstyle.cpp
index e6c60cf9ea..b65d45c8ad 100644
--- a/src/gui/styles/qmotifstyle.cpp
+++ b/src/gui/styles/qmotifstyle.cpp
@@ -1154,7 +1154,7 @@ void QMotifStyle::drawControl(ControlElement element, const QStyleOption *opt, Q
menuitem->palette, menuitem->state & State_Enabled, menuitem->text,
QPalette::Text);
textWidth = menuitem->fontMetrics.width(menuitem->text) + 10;
- y += menuitem->fontMetrics.lineSpacing() / 2;
+ y += menuitem->fontMetrics.height() / 2;
p->setFont(oldFont);
}
p->setPen(opt->palette.dark().color());
@@ -2056,7 +2056,7 @@ QMotifStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
w = 10;
- h = (mi->text.isEmpty()) ? motifSepHeight : mi->fontMetrics.lineSpacing();
+ h = (mi->text.isEmpty()) ? motifSepHeight : mi->fontMetrics.height();
}
// a little bit of border can never harm
diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp
index ce2109a2c0..be4fff25be 100644
--- a/src/gui/styles/qplastiquestyle.cpp
+++ b/src/gui/styles/qplastiquestyle.cpp
@@ -1094,8 +1094,6 @@ void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption
QColor borderColor = option->palette.background().color().darker(178);
QColor gradientStartColor = option->palette.button().color().lighter(104);
QColor gradientStopColor = option->palette.button().color().darker(105);
- QColor baseGradientStartColor = option->palette.base().color().darker(101);
- QColor baseGradientStopColor = option->palette.base().color().darker(106);
QColor highlightedGradientStartColor = option->palette.button().color().lighter(101);
QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85);
QColor highlightedBaseGradientStartColor = option->palette.base().color();
@@ -1978,7 +1976,13 @@ void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption
QRect gradientRect(adjustedRect.left() + 1, adjustedRect.top() + 1,
adjustedRect.right() - adjustedRect.left() - 1,
adjustedRect.bottom() - adjustedRect.top() - 1);
- qt_plastique_draw_gradient(painter, gradientRect, baseGradientStartColor, baseGradientStopColor);
+ if (option->palette.base().style() == Qt::SolidPattern) {
+ QColor baseGradientStartColor = option->palette.base().color().darker(101);
+ QColor baseGradientStopColor = option->palette.base().color().darker(106);
+ qt_plastique_draw_gradient(painter, gradientRect, baseGradientStartColor, baseGradientStopColor);
+ } else {
+ painter->fillRect(gradientRect, option->palette.base());
+ }
// draw "+" or "-"
painter->setPen(alphaTextColor);
painter->drawLine(center.x() - 2, center.y(), center.x() + 2, center.y());
@@ -5027,7 +5031,7 @@ QSize QPlastiqueStyle::sizeFromContents(ContentsType type, const QStyleOption *o
case CT_MenuItem:
if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator)
- newSize.setHeight(menuItem->text.isEmpty() ? 2 : menuItem->fontMetrics.lineSpacing());
+ newSize.setHeight(menuItem->text.isEmpty() ? 2 : menuItem->fontMetrics.height());
}
break;
case CT_MenuBarItem:
@@ -5514,9 +5518,6 @@ int QPlastiqueStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_MenuHMargin:
ret = 0;
break;
- case PM_ToolBarIconSize:
- ret = 24;
- break;
case PM_ButtonShiftHorizontal:
case PM_ButtonShiftVertical:
ret = 1;
@@ -5607,11 +5608,11 @@ int QPlastiqueStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
#ifdef QT3_SUPPORT
if (widget && widget->inherits("Q3DockWindowTitleBar")) {
// Q3DockWindow has smaller title bars than QDockWidget
- ret = qMax(widget->fontMetrics().lineSpacing(), 20);
+ ret = qMax(widget->fontMetrics().height(), 20);
} else
#endif
- ret = qMax(widget ? widget->fontMetrics().lineSpacing() :
- (option ? option->fontMetrics.lineSpacing() : 0), 30);
+ ret = qMax(widget ? widget->fontMetrics().height() :
+ (option ? option->fontMetrics.height() : 0), 30);
break;
case PM_MaximumDragDistance:
return -1;
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 4fa1d03276..7c3e11fd01 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -66,7 +66,6 @@
#include "qtextedit.h"
#include "qtoolbar.h"
#include "qtoolbutton.h"
-#include "qtreeview.h"
#include "qfocusframe.h"
#include "private/qtoolbarextension_p.h"
@@ -91,14 +90,14 @@ static const qreal goldenRatio = 1.618;
const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
// *** generated layout data ***
-{240,320,1,14,true,"QVGA Landscape Mirrored"},
-{240,320,1,14,false,"QVGA Landscape"},
-{320,240,1,14,true,"QVGA Portrait Mirrored"},
-{320,240,1,14,false,"QVGA Portrait"},
-{360,640,1,14,true,"NHD Landscape Mirrored"},
-{360,640,1,14,false,"NHD Landscape"},
-{640,360,1,14,true,"NHD Portrait Mirrored"},
-{640,360,1,14,false,"NHD Portrait"},
+{240,320,1,15,true,"QVGA Landscape Mirrored"},
+{240,320,1,15,false,"QVGA Landscape"},
+{320,240,1,15,true,"QVGA Portrait Mirrored"},
+{320,240,1,15,false,"QVGA Portrait"},
+{360,640,1,15,true,"NHD Landscape Mirrored"},
+{360,640,1,15,false,"NHD Landscape"},
+{640,360,1,15,true,"NHD Portrait Mirrored"},
+{640,360,1,15,false,"NHD Portrait"},
{352,800,1,12,true,"E90 Landscape Mirrored"},
{352,800,1,12,false,"E90 Landscape"}
// *** End of generated data ***
@@ -108,16 +107,16 @@ const int QS60StylePrivate::m_numberOfLayouts =
const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
// *** generated pixel metrics ***
-{5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
-{5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
-{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
-{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
-{7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1},
-{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}
+{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,6,3,3,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
+{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
+{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
+{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
+{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
+{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
+{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
+{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
+{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1},
+{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}
// *** End of generated data ***
};
@@ -282,7 +281,7 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter,
drawFrame(SF_ButtonInactive, painter, rect, flags | SF_PointNorth);
break;
case SE_Editor:
- drawFrame(SF_Editor, painter, rect, flags | SF_PointNorth);
+ drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth);
break;
default:
break;
@@ -302,32 +301,6 @@ short QS60StylePrivate::pixelMetric(int metric)
return returnValue;
}
-void QS60StylePrivate::setStyleProperty(const char *name, const QVariant &value)
-{
- if (name == propertyKeyCurrentlayout) {
- static const QStringList layouts = styleProperty(propertyKeyLayouts).toStringList();
- const QString layout = value.toString();
- Q_ASSERT(layouts.contains(layout));
- const int layoutIndex = layouts.indexOf(layout);
- setCurrentLayout(layoutIndex);
- QApplication::setLayoutDirection(m_layoutHeaders[layoutIndex].mirroring ? Qt::RightToLeft : Qt::LeftToRight);
- clearCaches();
- refreshUI();
- }
-}
-
-QVariant QS60StylePrivate::styleProperty(const char *name) const
-{
- if (name == propertyKeyLayouts) {
- static QStringList layouts;
- if (layouts.isEmpty())
- for (int i = 0; i < m_numberOfLayouts; i++)
- layouts.append(QLatin1String(m_layoutHeaders[i].layoutName));
- return layouts;
- }
- return QVariant();
-}
-
QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *option)
{
QColor retColor (color);
@@ -434,7 +407,7 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
return Qt::black;
const QRgb *pixelRgb = (const QRgb*)frameImage.bits();
- const int pixels = frameImage.numBytes()/sizeof(QRgb);
+ const int pixels = frameImage.byteCount()/sizeof(QRgb);
int estimatedRed = 0;
int estimatedGreen = 0;
@@ -500,7 +473,7 @@ void QS60StylePrivate::setBackgroundTexture(QApplication *app) const
Q_UNUSED(app)
QPalette applicationPalette = QApplication::palette();
applicationPalette.setBrush(QPalette::Window, backgroundTexture());
- QApplication::setPalette(applicationPalette);
+ setThemePalette(&applicationPalette);
}
void QS60StylePrivate::deleteBackground()
@@ -526,7 +499,8 @@ void QS60StylePrivate::drawPart(QS60StyleEnums::SkinParts skinPart,
#else
true;
#endif
- const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), flags));
+
+ const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), painter, flags));
if (!skinPartPixMap.isNull())
painter->drawPixmap(rect.topLeft(), skinPartPixMap);
}
@@ -593,14 +567,14 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start,
}
QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part,
- const QSize &size, SkinElementFlags flags)
+ const QSize &size, QPainter *painter, SkinElementFlags flags)
{
QPixmap result;
const QString cacheKey =
QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4")
.arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags);
if (!QPixmapCache::find(cacheKey, result)) {
- result = QS60StylePrivate::part(part, size, flags);
+ result = QS60StylePrivate::part(part, size, painter, flags);
QPixmapCache::insert(cacheKey, result);
}
return result;
@@ -694,7 +668,7 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
s60Color(QS60StyleEnums::CL_QsnTextColors, 55, 0));
palette->setColor(QPalette::BrightText, palette->color(QPalette::WindowText).lighter());
palette->setColor(QPalette::HighlightedText,
- s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0));
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
palette->setColor(QPalette::Link,
s60Color(QS60StyleEnums::CL_QsnHighlightColors, 3, 0));
palette->setColor(QPalette::LinkVisited, palette->color(QPalette::Link).darker());
@@ -743,7 +717,7 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
const QColor mainAreaTextColor =
s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0);
- widgetPalette.setColor(QPalette::All, QPalette::WindowText,
+ widgetPalette.setColor(QPalette::WindowText,
s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0));
QApplication::setPalette(widgetPalette, "QSlider");
// return to original palette after each widget
@@ -767,34 +741,34 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
QApplication::setPalette(widgetPalette, "QHeaderView");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::ButtonText,
+ widgetPalette.setColor(QPalette::ButtonText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0));
QApplication::setPalette(widgetPalette, "QMenuBar");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::Active, QPalette::WindowText,
+ widgetPalette.setColor(QPalette::WindowText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0));
QApplication::setPalette(widgetPalette, "QTabBar");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::Text,
+ widgetPalette.setColor(QPalette::Text,
s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0));
QApplication::setPalette(widgetPalette, "QTableView");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
+ widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QLineEdit");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::Text,
+ widgetPalette.setColor(QPalette::Text,
s60Color(QS60StyleEnums::CL_QsnTextColors, 34, 0));
- widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
+ widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QTextEdit");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
+ widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QComboBox");
widgetPalette = *palette;
@@ -809,6 +783,14 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
widgetPalette.setBrush(QPalette::Window, QBrush());
QApplication::setPalette(widgetPalette, "QScrollArea");
widgetPalette = *palette;
+
+ //Webpages should not use S60 theme colors as they are designed to work
+ //with themeBackground and do not generally mesh well with web page backgrounds.
+ QPalette webPalette = *palette;
+ webPalette.setColor(QPalette::WindowText, Qt::black);
+ webPalette.setColor(QPalette::Text, Qt::black);
+ QApplication::setPalette(webPalette, "QWebView");
+ QApplication::setPalette(webPalette, "QGraphicsWebView");
}
QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags)
@@ -825,12 +807,20 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag
case QS60StyleEnums::SP_QgnGrafTabPassiveR:
case QS60StyleEnums::SP_QgnGrafTabPassiveL:
case QS60StyleEnums::SP_QgnGrafTabActiveL:
+ //Returned QSize for tabs must not be square, but narrow rectangle with width:height
+ //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones).
+ result.setWidth(10);
break;
case QS60StyleEnums::SP_QgnIndiSliderEdit:
result.scale(pixelMetric(QStyle::PM_SliderLength),
pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio);
break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
+ result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth));
+ break;
+
case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
@@ -994,6 +984,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
const State bflags = toolBtn->state;
const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget));
+ QRect menuRect = QRect();
+ if (toolBtn->subControls & SC_ToolButtonMenu)
+ menuRect = subControlRect(control, toolBtn, SC_ToolButtonMenu, widget);
+
QStyleOptionToolButton toolButton = *toolBtn;
if (sub&SC_ToolButton) {
@@ -1006,7 +1000,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
toolBar = qobject_cast<QToolBar *>(widget->parentWidget());
if (bflags & (State_Sunken | State_On | State_Raised)) {
- tool.rect = button;
+ tool.rect = button.unite(menuRect);
tool.state = bflags;
// todo: I'd like to move extension button next to where last button is
@@ -1061,6 +1055,12 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
} else {
drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
}
+
+ if (toolButton.subControls & SC_ToolButtonMenu) {
+ tool.rect = menuRect;
+ tool.state = bflags;
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+ }
}
}
@@ -1313,15 +1313,15 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->save();
painter->setClipRect(voptAdj.rect);
- const bool isSelected = (voptAdj.state & QStyle::State_HasFocus);
+ const bool isSelected = (vopt->state & QStyle::State_Selected);
- bool isVisible = false;
+ bool isScrollBarVisible = false;
int scrollBarWidth = 0;
QList<QScrollBar *> scrollBars = qFindChildren<QScrollBar *>(widget);
for (int i = 0; i < scrollBars.size(); ++i) {
QScrollBar *scrollBar = scrollBars.at(i);
if (scrollBar && scrollBar->orientation() == Qt::Vertical) {
- isVisible = scrollBar->isVisible();
+ isScrollBarVisible = scrollBar->isVisible();
scrollBarWidth = scrollBar->size().width();
break;
}
@@ -1329,7 +1329,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
int rightValue = widget ? widget->contentsRect().right() : 0;
- if (isVisible)
+ if (isScrollBarVisible)
rightValue -= scrollBarWidth;
if (voptAdj.rect.right() > rightValue)
@@ -1337,29 +1337,51 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
const QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &voptAdj, widget);
QRect textRect = subElementRect(SE_ItemViewItemText, &voptAdj, widget);
+ const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget);
// draw themed background for table unless background brush has been defined.
if (vopt->backgroundBrush == Qt::NoBrush) {
- const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option);
- const QTableView *table = qobject_cast<const QTableView *>(widget);
- if (table && tableOption) {
- const QModelIndex index = tableOption->index;
+ if (itemView) {
+ const QModelIndex index = vopt->index;
//todo: Draw cell background only once - for the first cell.
QStyleOptionViewItemV4 voptAdj2 = voptAdj;
- const QModelIndex indexFirst = table->model()->index(0,0);
- const QModelIndex indexLast = table->model()->index(
- table->model()->rowCount()-1,table->model()->columnCount()-1);
- if (table->viewport())
- voptAdj2.rect = QRect( table->visualRect(indexFirst).topLeft(),
- table->visualRect(indexLast).bottomRight()).intersect(table->viewport()->rect());
- drawPrimitive(PE_PanelItemViewItem, &voptAdj2, painter, widget);
+ const QModelIndex indexFirst = itemView->model()->index(0,0);
+ const QModelIndex indexLast = itemView->model()->index(
+ itemView->model()->rowCount()-1,itemView->model()->columnCount()-1);
+ if (itemView->viewport())
+ voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(),
+ itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect());
+ drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);
}
- } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);}
+ } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);}
// draw the focus rect
if (isSelected) {
- const QRect highlightRect = option->rect.adjusted(1,1,-1,-1);
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags);
+ QRect highlightRect = option->rect.adjusted(1,1,-1,-1);
+ QAbstractItemView::SelectionBehavior selectionBehavior =
+ itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems;
+ if (selectionBehavior != QAbstractItemView::SelectItems) {
+ // set highlight rect so that it is continuous from cell to cell, yet sligthly
+ // smaller than cell rect
+ int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0;
+ if (selectionBehavior == QAbstractItemView::SelectRows) {
+ yBeginning = 1; yEnd = -1;
+ if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+ xBeginning = 1;
+ else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
+ xEnd = -1;
+ } else if (selectionBehavior == QAbstractItemView::SelectColumns) {
+ xBeginning = 1; xEnd = -1;
+ if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+ yBeginning = 1;
+ else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
+ yEnd = -1;
+ }
+ highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd);
+ }
+ if (vopt->showDecorationSelected &&
+ (vopt->palette.highlight().color() == d->themePalette()->highlight().color()))
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags);
}
// draw the icon
@@ -1368,48 +1390,44 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state);
// Draw selection check mark. Show check mark only in multi selection modes.
- if (const QListView *listView = (qobject_cast<const QListView *>(widget))) {
+ if (itemView) {
const bool singleSelection =
- listView &&
- (listView->selectionMode() == QAbstractItemView::SingleSelection ||
- listView->selectionMode() == QAbstractItemView::NoSelection);
+ (itemView->selectionMode() == QAbstractItemView::SingleSelection ||
+ itemView->selectionMode() == QAbstractItemView::NoSelection);
const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget);
+
+ QStyleOptionViewItemV4 checkMarkOption(voptAdj);
+ // Draw selection mark.
if (voptAdj.state & QStyle::State_Selected && !singleSelection) {
- QStyleOptionViewItemV4 option(voptAdj);
- option.rect = selectionRect;
- // Draw selection mark.
- drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget);
+ checkMarkOption.rect = selectionRect;
+ drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
if ( textRect.right() > selectionRect.left() )
textRect.setRight(selectionRect.left());
} else if (singleSelection &&
- voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) {
- // draw the check mark
- if (selectionRect.isValid()) {
- QStyleOptionViewItemV4 option(*vopt);
- option.rect = selectionRect;
- option.state = option.state & ~QStyle::State_HasFocus;
-
- switch (vopt->checkState) {
- case Qt::Unchecked:
- option.state |= QStyle::State_Off;
- break;
- case Qt::PartiallyChecked:
- option.state |= QStyle::State_NoChange;
- break;
- case Qt::Checked:
- option.state |= QStyle::State_On;
- break;
- }
- drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget);
+ voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator &&
+ selectionRect.isValid()) {
+ checkMarkOption.rect = selectionRect;
+ checkMarkOption.state = checkMarkOption.state & ~QStyle::State_HasFocus;
+
+ switch (vopt->checkState) {
+ case Qt::Unchecked:
+ checkMarkOption.state |= QStyle::State_Off;
+ break;
+ case Qt::PartiallyChecked:
+ checkMarkOption.state |= QStyle::State_NoChange;
+ break;
+ case Qt::Checked:
+ checkMarkOption.state |= QStyle::State_On;
+ break;
}
+ drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
}
}
// draw the text
if (!voptAdj.text.isEmpty()) {
- const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option);
if (isSelected) {
- if (qobject_cast<const QTableView *>(widget) && tableOption)
+ if (qobject_cast<const QTableView *>(widget))
voptAdj.palette.setColor(
QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
else
@@ -1648,18 +1666,18 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (!styleHint(SH_UnderlineShortcut, menuItem, widget))
text_flags |= Qt::TextHideMnemonic;
- QRect iconRect =
- subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget);
- QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget);
-
if ((option->state & State_Selected) && (option->state & State_Enabled))
QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
+ QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget);
+ QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget);
+
//todo: move the vertical spacing stuff into subElementRect
const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
if (checkable){
+ const int hSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
QStyleOptionMenuItem optionCheckBox;
- optionCheckBox.QStyleOption::operator=(*menuItem);
+ optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
const int moveByX = optionCheckBox.rect.width()+vSpacing;
@@ -1668,6 +1686,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
iconRect.translate(moveByX, 0);
iconRect.setWidth(iconRect.width()+vSpacing);
textRect.setWidth(textRect.width()-moveByX-vSpacing);
+ optionCheckBox.rect.translate(vSpacing/2, hSpacing/2);
} else {
textRect.setWidth(textRect.width()-moveByX);
iconRect.setWidth(iconRect.width()+vSpacing);
@@ -1702,8 +1721,11 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
// direction is set to north (and south when in RightToLeft)
const QS60StylePrivate::SkinElementFlag arrowDirection = (arrowOptions.direction == Qt::LeftToRight) ?
QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointSouth;
+ painter->save();
+ painter->setPen(option->palette.windowText().color());
QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubMenu, painter, arrowOptions.rect,
(flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection));
+ painter->restore();
}
//draw text
@@ -1731,7 +1753,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
#endif //QT_NO_MENUBAR
case CE_HeaderSection:
- if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
painter->save();
QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header));
const int penWidth = (header->orientation == Qt::Horizontal) ?
@@ -1749,6 +1771,25 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
}
}
painter->restore();
+
+ //Draw corner button as normal pushButton.
+ if (qobject_cast<const QAbstractButton *>(widget)) {
+ //Make cornerButton slightly smaller so that it is not on top of table border graphic.
+ QStyleOptionHeader subopt = *header;
+ const int borderTweak =
+ QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1;
+ if (subopt.direction == Qt::LeftToRight)
+ subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak);
+ else
+ subopt.rect.adjust(0, borderTweak, -borderTweak, -borderTweak);
+ drawPrimitive(PE_PanelButtonBevel, &subopt, painter, widget);
+ } else if ((header->palette.brush(QPalette::Button) != Qt::transparent)) {
+ //Draw non-themed background. Background for theme is drawn in CE_ShapedFrame
+ //to get continuous theme graphic across all the header cells.
+ qDrawShadePanel(painter, header->rect, header->palette,
+ header->state & (State_Sunken | State_On), penWidth,
+ &header->palette.brush(QPalette::Button));
+ }
}
break;
case CE_HeaderEmptyArea: // no need to draw this
@@ -1810,22 +1851,35 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
break;
#endif //QT_NO_TOOLBAR
case CE_ShapedFrame:
- if (qobject_cast<const QTextEdit *>(widget)) {
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags);
+ if (const QTextEdit *textEdit = qobject_cast<const QTextEdit *>(widget)) {
+ const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option);
+ if (frame->palette.base().color()==Qt::transparent)
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags);
+ else
+ QCommonStyle::drawControl(element, option, painter, widget);
} else if (qobject_cast<const QTableView *>(widget)) {
QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableItem, painter, option->rect, flags);
} else if (const QHeaderView *header = qobject_cast<const QHeaderView *>(widget)) {
- if (header->orientation() == Qt::Horizontal) {
- QRect headerRect = option->rect;
- const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- headerRect.adjust(0,frameWidth,-2*frameWidth,0);
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, flags);
- } else {
+ //QS60style draws header background here instead of in each headersection, to get
+ //continuous graphic from section to section.
+ QS60StylePrivate::SkinElementFlags adjustableFlags = flags;
+ QRect headerRect = option->rect;
+ if (header->orientation() != Qt::Horizontal) {
//todo: update to horizontal table graphic
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, option->rect, flags | QS60StylePrivate::SF_PointWest);
+ adjustableFlags = (adjustableFlags | QS60StylePrivate::SF_PointWest);
+ } else {
+ const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ if (option->direction == Qt::LeftToRight)
+ headerRect.adjust(-2*frameWidth, 0, 0, 0);
+ else
+ headerRect.adjust(0, 0, 2*frameWidth, 0);
}
- } else if (qobject_cast<const QFrame *>(widget)) {
- QCommonStyle::drawControl(element, option, painter, widget);
+ if (option->palette.brush(QPalette::Button).color() == Qt::transparent)
+ QS60StylePrivate::drawSkinElement(
+ QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, adjustableFlags);
+
+ } else if (qobject_cast<const QFrame *>(widget)) {
+ QCommonStyle::drawControl(element, option, painter, widget);
}
break;
case CE_MenuScroller:
@@ -1869,6 +1923,17 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->restore();
}
break;
+ case CE_Splitter:
+ if (option->state & State_Sunken && option->state & State_Enabled) {
+ painter->save();
+ painter->setOpacity(0.5);
+ painter->setBrush(d->themePalette()->light());
+ painter->setRenderHint(QPainter::Antialiasing);
+ const qreal roundRectRadius = 4 * goldenRatio;
+ painter->drawRoundedRect(option->rect, roundRectRadius, roundRectRadius);
+ painter->restore();
+ }
+ break;
default:
QCommonStyle::drawControl(element, option, painter, widget);
}
@@ -1879,6 +1944,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
*/
void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
+ Q_D(const QS60Style);
const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
switch (element) {
#ifndef QT_NO_LINEEDIT
@@ -1888,19 +1954,27 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
if (widget && qobject_cast<const QComboBox *>(widget->parentWidget()))
break;
#endif
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit,
- painter, option->rect, flags);
+ QBrush editBrush = option->palette.brush(QPalette::Base);
+ if (editBrush.color() == Qt::transparent)
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit,
+ painter, option->rect, flags);
+ else
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
}
break;
#endif // QT_NO_LINEEDIT
case PE_IndicatorCheckBox:
{
- const QRect indicatorRect = option->rect;
// Draw checkbox indicator as color skinned graphics.
const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff;
- QS60StylePrivate::drawSkinPart(skinPart, painter, indicatorRect,
- (flags | QS60StylePrivate::SF_ColorSkinned));
+ painter->save();
+ QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnIconColors, 13, option);
+ QColor buttonTextColor = option->palette.buttonText().color();
+ if (themeColor != buttonTextColor)
+ painter->setPen(buttonTextColor);
+ QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags | QS60StylePrivate::SF_ColorSkinned );
+ painter->restore();
}
break;
case PE_IndicatorViewItemCheck:
@@ -1940,21 +2014,33 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ;
buttonRect.adjust(0,-newY,0,-newY);
+ painter->save();
+ QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option);
+ QColor buttonTextColor = option->palette.buttonText().color();
+ if (themeColor != buttonTextColor)
+ painter->setPen(buttonTextColor);
+
// Draw radiobutton indicator as color skinned graphics.
QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff;
QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect,
(flags | QS60StylePrivate::SF_ColorSkinned));
+ painter->restore();
}
break;
case PE_PanelButtonCommand:
case PE_PanelButtonTool:
case PE_PanelButtonBevel:
case PE_FrameButtonBevel: {
- const bool isPressed = option->state & QStyle::State_Sunken;
- const QS60StylePrivate::SkinElements skinElement =
- isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
- QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
+ QBrush editBrush = option->palette.brush(QPalette::Base);
+ if (editBrush.color() == Qt::transparent) {
+ const bool isPressed = option->state & QStyle::State_Sunken;
+ const QS60StylePrivate::SkinElements skinElement =
+ isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
+ QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
+ } else {
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+ }
}
break;
#ifndef QT_NO_TOOLBUTTON
@@ -1981,21 +2067,29 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_IndicatorSpinUp:
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
QStyleOptionSpinBox optionSpinBox = *spinBox;
- const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ?
- QS60StyleEnums::SP_QgnGrafScrollArrowUp :
- QS60StyleEnums::SP_QgnGrafScrollArrowDown;
- const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6;
- optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
- QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags);
+ if (optionSpinBox.palette.base().color()==Qt::transparent) {
+ const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ?
+ QS60StyleEnums::SP_QgnGrafScrollArrowUp :
+ QS60StyleEnums::SP_QgnGrafScrollArrowDown;
+ const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6;
+ optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
+ QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags);
+ } else {
+ QCommonStyle::drawPrimitive(element, &optionSpinBox, painter, widget);
+ }
}
#ifndef QT_NO_COMBOBOX
else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- // We want to draw down arrow here for comboboxes as well.
- const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
- QStyleOptionFrame comboBox = *cmb;
- const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6;
- comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
- QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags);
+ if (cmb->palette.base().color()==Qt::transparent) {
+ // We want to draw down arrow here for comboboxes as well.
+ const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
+ QStyleOptionFrame comboBox = *cmb;
+ const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6;
+ comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
+ QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags);
+ } else {
+ QCommonStyle::drawPrimitive(element, cmb, painter, widget);
+ }
}
#endif //QT_NO_COMBOBOX
break;
@@ -2025,8 +2119,12 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
|| qobject_cast<const QMenu *> (widget)
#endif //QT_NO_MENU
) {
- QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_OptionsMenu;
- QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
+ if (option->palette.base().color()==Qt::transparent) {
+ QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_OptionsMenu;
+ QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
+ } else {
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+ }
}
break;
case PE_FrameWindow:
@@ -2113,7 +2211,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
drawSkinPart = true;
}
- if ( drawSkinPart )
+ if (drawSkinPart)
QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
if (option->state & State_Children) {
@@ -2135,7 +2233,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
// todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
case PE_FrameLineEdit:
- case PE_IndicatorButtonDropDown:
case PE_IndicatorDockWidgetResizeHandle:
case PE_PanelTipLabel:
case PE_PanelScrollAreaCorner:
@@ -2170,7 +2267,7 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const
if (metricValue == KNotFound)
metricValue = QCommonStyle::pixelMetric(metric, option, widget);
- if (metric == PM_SubMenuOverlap && widget){
+ if (metric == PM_SubMenuOverlap && widget) {
const QMenu *menu = qobject_cast<const QMenu *>(widget);
if (menu && menu->activeAction() && menu->activeAction()->menu()) {
const int menuWidth = menu->activeAction()->menu()->sizeHint().width();
@@ -2186,8 +2283,18 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
{
QSize sz(csz);
switch (ct) {
+ case CT_ToolButton:
+ sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ //FIXME properly - style should calculate the location of border frame-part
+ sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
+ if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
+ if (toolBtn->subControls & SC_ToolButtonMenu)
+ sz += QSize(pixelMetric(PM_MenuButtonIndicator),0);
+ break;
case CT_PushButton:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ //FIXME properly - style should calculate the location of border frame-part
+ sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget)))
if (buttonWidget->isCheckable())
sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0);
@@ -2196,6 +2303,21 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
sz += QSize(2*f->lineWidth, 4*f->lineWidth);
break;
+ case CT_TabBarTab:
+ {
+ const QSize naviPaneSize = QS60StylePrivate::naviPaneSize();
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ if (naviPaneSize.height() > sz.height())
+ sz.setHeight(naviPaneSize.height());
+ }
+ break;
+ case CT_ItemViewItem:
+ sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ if (QS60StylePrivate::isTouchSupported())
+ //Make itemview easier to use in touch devices
+ //QCommonStyle does not adjust height with horizontal margin, it only adjusts width
+ sz.setHeight(sz.height() + 2*pixelMetric(QStyle::PM_FocusFrameVMargin));
+ break;
default:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
break;
@@ -2405,8 +2527,8 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
case SC_ComboBoxArrow:
ret.setRect(
ret.x() + ret.width() - buttonMargin - buttonWidth,
- ret.y() + buttonMargin,
- buttonWidth,
+ ret.y() + buttonMargin,
+ buttonWidth,
height - 2*buttonMargin);
break;
case SC_ComboBoxEditField: {
@@ -2449,6 +2571,29 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
}
}
break;
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolButton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin);
+ const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth);
+ ret = toolButton->rect;
+ const bool popup = (toolButton->features &
+ (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
+ == QStyleOptionToolButton::MenuButtonPopup;
+ switch (scontrol) {
+ case SC_ToolButton:
+ if (popup)
+ ret.adjust(0, 0, -indicatorRect, 0);
+ break;
+ case SC_ToolButtonMenu:
+ if (popup)
+ ret.adjust(ret.width() - indicatorRect, border, -pixelMetric(PM_ButtonMargin), -border);
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(toolButton->direction, toolButton->rect, ret);
+ }
+ break;
default:
ret = QCommonStyle::subControlRect(control, option, scontrol, widget);
}
@@ -2463,8 +2608,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
QRect ret;
switch (element) {
case SE_LineEditContents: {
- // in S60 the input text box doesn't start from line Edit's TL, but
- // a bit indented.
+ // in S60 the input text box doesn't start from line Edit's TL, but
+ // a bit indented.
QRect lineEditRect = opt->rect;
const int adjustment = opt->rect.height()>>2;
lineEditRect.adjust(adjustment,0,0,0);
@@ -2713,24 +2858,6 @@ void QS60Style::unpolish(QApplication *application)
}
/*!
- Sets the style property \a name to the \a value.
- */
-void QS60Style::setStyleProperty(const char *name, const QVariant &value)
-{
- Q_D(QS60Style);
- d->setStyleProperty_specific(name, value);
-}
-
-/*!
- Returns the value of style property \a name.
- */
-QVariant QS60Style::styleProperty(const char *name) const
-{
- Q_D(const QS60Style);
- return d->styleProperty_specific(name);
-}
-
-/*!
\reimp
*/
bool QS60Style::event(QEvent *e)
@@ -2852,7 +2979,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
return QCommonStyle::standardIconImplementation(standardIcon, option, widget);
}
const QS60StylePrivate::SkinElementFlags flags = adjustedFlags;
- const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), flags));
+ const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), 0, flags));
return cachedPixMap.isNull() ?
QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap);
}
diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h
index 6be31978b9..cd63431285 100644
--- a/src/gui/styles/qs60style.h
+++ b/src/gui/styles/qs60style.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -79,10 +79,6 @@ public:
#ifndef Q_NO_USING_KEYWORD
using QCommonStyle::polish;
#endif
-
- void setStyleProperty(const char *name, const QVariant &value);
- QVariant styleProperty(const char *name) const;
-
bool event(QEvent *e);
#ifndef Q_WS_S60
@@ -101,7 +97,7 @@ protected Q_SLOTS:
private:
Q_DISABLE_COPY(QS60Style)
friend class QStyleFactory;
- friend class QApplication;
+ friend class QApplicationPrivate;
};
#endif // QT_NO_STYLE_S60
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 5422ff642c..cfe87acbee 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -361,7 +361,6 @@ public:
SF_ToolBarButtonPressed,
SF_PanelBackground,
SF_ButtonInactive,
- SF_Editor,
};
enum SkinElementFlag {
@@ -372,7 +371,7 @@ public:
SF_StateEnabled = 0x0010, // Enabled = the default
SF_StateDisabled = 0x0020,
- SF_ColorSkinned = 0x0040,
+ SF_ColorSkinned = 0x0040, // pixmap is colored with foreground pen color
};
enum CacheClearReason {
@@ -389,14 +388,6 @@ public:
// draws a specific skin part
static void drawSkinPart(QS60StyleEnums::SkinParts part, QPainter *painter,
const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
- // sets style property
- void setStyleProperty(const char *name, const QVariant &value);
- // sets specific style property
- void setStyleProperty_specific(const char *name, const QVariant &value);
- // gets style property
- QVariant styleProperty(const char *name) const;
- // gets specific style property
- QVariant styleProperty_specific(const char *name) const;
// gets pixel metrics value
static short pixelMetric(int metric);
// gets color. 'index' is NOT 0-based.
@@ -460,6 +451,8 @@ public:
void handleSkinChange();
#endif // Q_WS_S60
+ static QSize naviPaneSize();
+
private:
static void drawPart(QS60StyleEnums::SkinParts part, QPainter *painter,
const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
@@ -470,7 +463,7 @@ private:
const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
static QPixmap cachedPart(QS60StyleEnums::SkinParts part, const QSize &size,
- SkinElementFlags flags = KDefaultSkinElementFlags);
+ QPainter *painter, SkinElementFlags flags = KDefaultSkinElementFlags);
static QPixmap cachedFrame(SkinFrameElements frame, const QSize &size,
SkinElementFlags flags = KDefaultSkinElementFlags);
@@ -487,7 +480,7 @@ private:
static QSize partSize(QS60StyleEnums::SkinParts part,
SkinElementFlags flags = KDefaultSkinElementFlags);
static QPixmap part(QS60StyleEnums::SkinParts part, const QSize &size,
- SkinElementFlags flags = KDefaultSkinElementFlags);
+ QPainter *painter, SkinElementFlags flags = KDefaultSkinElementFlags);
static QFont s60Font_specific(QS60StyleEnums::FontCategories fontCategory, int pointSize);
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index cde48d8982..a8dbf8deea 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -61,6 +61,7 @@
#include <AknFontAccess.h>
#include <AknLayoutFont.h>
#include <aknutils.h>
+#include <aknnavi.h>
#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
@@ -98,26 +99,25 @@ public:
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, QS60StylePrivate::SkinElementFlags flags);
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex);
static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, QImage::Format format);
static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part);
static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame);
static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QSize naviPaneSize();
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, QS60StylePrivate::SkinElementFlags flags);
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId);
static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect);
static void checkAndUnCompressBitmapL(CFbsBitmap*& aOriginalBitmap);
static void checkAndUnCompressBitmap(CFbsBitmap*& aOriginalBitmap);
static void unCompressBitmapL(const TRect& aTrgRect, CFbsBitmap* aTrgBitmap, CFbsBitmap* aSrcBitmap);
- static void colorGroupAndIndex(QS60StyleEnums::SkinParts skinID,
- TAknsItemID &colorGroup, int &colorIndex);
static void fallbackInfo(const QS60StyleEnums::SkinParts &stylepart, TDes& fallbackFileName, TInt& fallbackIndex);
static bool checkSupport(const int supportedRelease);
static TAknsItemID checkAndUpdateReleaseSpecificGraphics(int part);
@@ -319,16 +319,6 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
/* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b8},
/* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b9},
- /* SP_QsnFrNotepadCornerTl */ {KAknsIIDQsnFrNotepadContCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCornerTr */ {KAknsIIDQsnFrNotepadContCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCornerBl */ {KAknsIIDQsnFrNotepadCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCornerBr */ {KAknsIIDQsnFrNotepadCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideT */ {KAknsIIDQsnFrNotepadContSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideB */ {KAknsIIDQsnFrNotepadSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideL */ {KAknsIIDQsnFrNotepadSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideR */ {KAknsIIDQsnFrNotepadSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCenter */ {KAknsIIDQsnFrNotepadCenter, EDrawIcon, ES60_AllReleases, -1,-1},
-
};
QPixmap QS60StyleModeSpecifics::skinnedGraphics(
@@ -359,11 +349,11 @@ QPixmap QS60StyleModeSpecifics::skinnedGraphics(
}
QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
- const QS60StyleEnums::SkinParts &stylepart,
- const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+ const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter,
+ QS60StylePrivate::SkinElementFlags flags)
{
QPixmap colorGraphics;
- TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, flags)));
+ TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, painter, flags)));
return error ? QPixmap() : colorGraphics;
}
@@ -523,7 +513,7 @@ void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &style
QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
const QS60StyleEnums::SkinParts &stylepart,
- const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+ 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;
@@ -535,8 +525,13 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
fallbackInfo(stylepart, fileNamePtr, fallbackGraphicID);
TAknsItemID colorGroup = KAknsIIDQsnIconColors;
- int colorIndex = 0;
- colorGroupAndIndex(stylepart, colorGroup, colorIndex);
+ 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));
@@ -548,7 +543,7 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
AknsUtils::CreateColorIconLC(
- skinInstance, skinId, colorGroup, colorIndex, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID, KRgbBlack);
+ skinInstance, skinId, colorGroup, colorIndex, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID, defaultColor);
User::LeaveIfError(AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved));
User::LeaveIfError(AknIconUtils::SetSize(iconMask, targetSize, EAspectRatioNotPreserved));
QPixmap result = fromFbsBitmap(icon, iconMask, flags, qt_TDisplayMode2Format(icon->DisplayMode()));
@@ -650,8 +645,8 @@ QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
}
QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
- QS60StyleEnums::SkinParts part,
- const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+ 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())
@@ -698,13 +693,13 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
CleanupStack::PushL(background);
User::LeaveIfError(background->Create(targetSize, EColor16MA));
- CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(background);
+ CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background);
CleanupStack::PushL(dev);
- CFbsBitGc* gc = NULL;
+ CFbsBitGc *gc = NULL;
User::LeaveIfError(dev->CreateContext(gc));
CleanupStack::PushL(gc);
- CAknsBasicBackgroundControlContext* bgContext = CAknsBasicBackgroundControlContext::NewL(
+ CAknsBasicBackgroundControlContext *bgContext = CAknsBasicBackgroundControlContext::NewL(
skinId,
targetSize,
EFalse);
@@ -747,9 +742,8 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr
QPixmap result;
// QS60WindowSurface::unlockBitmapHeap();
- static const bool canDoEColor16MAP = !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
- static const TDisplayMode displayMode = canDoEColor16MAP ? TDisplayMode(13) : EColor16MA; // 13 = EColor16MAP
- static const TInt drawParam = canDoEColor16MAP ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly;
+ 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);
@@ -776,7 +770,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr
frameSkinID, centerSkinID,
drawParam );
- if (canDoEColor16MAP) {
+ if (S60->supportsPremultipliedAlpha) {
if (drawn)
result = fromFbsBitmap(frame, NULL, flags, QImage::Format_ARGB32_Premultiplied);
} else {
@@ -848,10 +842,6 @@ void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameEleme
centerId.Set(KAknsIIDNone);
frameId.Set(KAknsIIDQsnFrSetOpt);
break;
- case QS60StylePrivate::SF_Editor:
- centerId.Set(KAknsIIDQsnFrNotepadCenter);
- frameId.Set(KAknsIIDQsnFrNotepadCont);
- break;
default:
// center should be correct here
frameId.iMinor = centerId.iMinor - 9;
@@ -1024,23 +1014,6 @@ QS60StylePrivate::QS60StylePrivate()
setActiveLayout();
}
-void QS60StylePrivate::setStyleProperty_specific(const char *name, const QVariant &value)
-{
- if (QLatin1String(name) == QLatin1String("foo")) {
- // BaR
- } else {
- setStyleProperty(name, value);
- }
-}
-
-QVariant QS60StylePrivate::styleProperty_specific(const char *name) const
-{
- if (QLatin1String(name) == QLatin1String("foo"))
- return QLatin1String("Bar");
- else
- return styleProperty(name);
-}
-
QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
int index, const QStyleOption *option)
{
@@ -1144,12 +1117,12 @@ QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::Skin
}
QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part,
- const QSize &size, SkinElementFlags flags)
+ const QSize &size, QPainter *painter, SkinElementFlags flags)
{
QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
QPixmap result = (flags & SF_ColorSkinned)?
- QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, flags)
+ QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, painter, flags)
: QS60StyleModeSpecifics::skinnedGraphics(part, size, flags);
lock.relock();
@@ -1188,7 +1161,7 @@ QPixmap QS60StylePrivate::backgroundTexture()
{
if (!m_background) {
QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
- QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), SkinElementFlags());
+ QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags());
m_background = new QPixmap(background);
}
return *m_background;
@@ -1342,26 +1315,6 @@ QSize QS60StylePrivate::screenSize()
return QSize(screenSize.iWidth, screenSize.iHeight);
}
-void QS60StyleModeSpecifics::colorGroupAndIndex(
- QS60StyleEnums::SkinParts skinID, TAknsItemID &colorGroup, int &colorIndex)
-{
- switch(skinID) {
- case QS60StyleEnums::SP_QgnIndiSubMenu:
- colorGroup = KAknsIIDQsnIconColors;
- colorIndex = EAknsCIQsnIconColorsCG1;
- break;
- case QS60StyleEnums::SP_QgnIndiRadiobuttOff:
- case QS60StyleEnums::SP_QgnIndiRadiobuttOn:
- case QS60StyleEnums::SP_QgnIndiCheckboxOff:
- case QS60StyleEnums::SP_QgnIndiCheckboxOn:
- colorGroup = KAknsIIDQsnIconColors;
- colorIndex = EAknsCIQsnIconColorsCG14;
- break;
- default:
- break;
- }
-}
-
QS60Style::QS60Style()
: QCommonStyle(*new QS60StylePrivate)
{
@@ -1389,6 +1342,24 @@ void QS60StylePrivate::handleSkinChange()
topLevelWidget->ensurePolished();
}
}
+
+QSize QS60StylePrivate::naviPaneSize()
+{
+ return QS60StyleModeSpecifics::naviPaneSize();
+}
+
+QSize QS60StyleModeSpecifics::naviPaneSize()
+{
+ CAknNavigationControlContainer* naviContainer;
+ if (S60->statusPane()) {
+ TRAPD(err, naviContainer = static_cast<CAknNavigationControlContainer*>
+ (S60->statusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi))));
+ if (err==KErrNone)
+ return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight);
+ }
+ return QSize(0,0);
+}
+
#endif // Q_WS_S60
QT_END_NAMESPACE
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index 89a91580b0..55d57718f1 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -189,8 +189,10 @@ QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
}
QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part, const QSize &size,
- QS60StylePrivate::SkinElementFlags flags)
+ QPainter *painter, QS60StylePrivate::SkinElementFlags flags)
{
+ Q_UNUSED(painter);
+
const QString partKey = QS60Style::partKeys().at(part);
const QPicture partPicture = QS60StyleModeSpecifics::m_partPictures.value(partKey);
QSize partSize(partPicture.boundingRect().size());
@@ -306,26 +308,20 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size,
return result;
}
-void QS60StylePrivate::setStyleProperty_specific(const char *name, const QVariant &value)
-{
- setStyleProperty(name, value);
-}
-
-QVariant QS60StylePrivate::styleProperty_specific(const char *name) const
-{
- return styleProperty(name);
-}
-
QPixmap QS60StylePrivate::backgroundTexture()
{
if (!m_background) {
const QSize size = QApplication::desktop()->screen()->size();
- QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, size);
+ QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, size, 0);
m_background = new QPixmap(background);
}
return *m_background;
}
+QSize QS60StylePrivate::naviPaneSize()
+{
+ return QSize(0, 0);
+}
bool QS60StylePrivate::isTouchSupported()
{
diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
index eef1573922..ec238a916c 100644
--- a/src/gui/styles/qstyle.cpp
+++ b/src/gui/styles/qstyle.cpp
@@ -2417,13 +2417,13 @@ int QStyle::layoutSpacingImplementation(QSizePolicy::ControlType /* control1 */,
return -1;
}
-#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
QT_BEGIN_INCLUDE_NAMESPACE
#include <QDebug>
QT_END_INCLUDE_NAMESPACE
QDebug operator<<(QDebug debug, QStyle::State state)
{
+#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
debug << "QStyle::State(";
QStringList states;
@@ -2455,9 +2455,9 @@ QDebug operator<<(QDebug debug, QStyle::State state)
qSort(states);
debug << states.join(QLatin1String(" | "));
debug << ')';
+#endif
return debug;
}
-#endif
/*!
\since 4.6
diff --git a/src/gui/styles/qstyle.h b/src/gui/styles/qstyle.h
index 1f8d5c8e5f..0014954a75 100644
--- a/src/gui/styles/qstyle.h
+++ b/src/gui/styles/qstyle.h
@@ -878,9 +878,7 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::State)
Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::SubControls)
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DEBUG)
Q_GUI_EXPORT QDebug operator<<(QDebug debug, QStyle::State state);
-#endif
QT_END_NAMESPACE
diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp
index 10a6b5b8b1..9188ee004d 100644
--- a/src/gui/styles/qstyleoption.cpp
+++ b/src/gui/styles/qstyleoption.cpp
@@ -45,9 +45,7 @@
# include "private/qt_mac_p.h"
# include "qmacstyle_mac.h"
#endif
-#ifndef QT_NO_DEBUG
#include <qdebug.h>
-#endif
#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE
@@ -1254,7 +1252,7 @@ QStyleOptionViewItemV4::QStyleOptionViewItemV4(int version)
\brief the features of the group box frame
The frame is flat by default.
-
+
\sa QStyleOptionFrameV2::FrameFeature
*/
@@ -4656,6 +4654,127 @@ QStyleOptionTabWidgetFrame::QStyleOptionTabWidgetFrame(int version)
The default value is QSize(-1, -1), i.e. an invalid size.
*/
+
+
+/*!
+
+ \class QStyleOptionTabWidgetFrameV2
+ \brief The QStyleOptionTabWidgetFrameV2 class is used to describe the
+ parameters for drawing the frame around a tab widget.
+
+ QStyleOptionTabWidgetFrameV2 contains all the information that
+ QStyle functions need to draw the frame around QTabWidget.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QTabWidget
+*/
+
+
+/*!
+ \variable QStyleOptionTabWidgetFrameV2::tabBarRect
+ \brief the rectangle containing all the tabs
+
+ The default value is a null rectangle, i.e. a rectangle with both
+ the width and the height set to 0.
+*/
+
+/*!
+ \variable QStyleOptionTabWidgetFrameV2::selectedTabRect
+ \brief the rectangle containing the selected tab
+
+ This rectangle is contained within the tabBarRect. The default
+ value is a null rectangle, i.e. a rectangle with both the width
+ and the height set to 0.
+*/
+
+
+/*!
+ Constructs a QStyleOptionTabWidgetFrameV2, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2()
+ : QStyleOptionTabWidgetFrame(Version)
+{
+}
+
+
+/*! \internal */
+QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(int version)
+ : QStyleOptionTabWidgetFrame(version)
+{
+}
+
+
+/*! \fn QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrameV2 &other)
+ Constructs a QStyleOptionTabWidgetFrameV2 copy of the \a other style option.
+
+ If the \a other style option's version is 1, the new style option's \l
+ selectedTabRect and tabBarRect will contain null rects
+
+ \sa version
+*/
+
+/*!
+ Constructs a QStyleOptionTabWidgetFrameV2 copy of the \a other style option.
+
+ If the \a other style option's version is 1, the new style option's \l
+ selectedTabRect and tabBarRect will contain null rects
+
+ \sa version
+*/
+QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrame &other)
+{
+ QStyleOptionTabWidgetFrameV2::operator=(other);
+
+}
+
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionFrameV2 or
+ QStyleOptionFrame types.
+
+ If the \a{other} style option's version is 1, this style option's
+ QStyleOptionFrameV2::FrameFeature value is set to
+ QStyleOptionFrameV2::None. If its version is 2, its
+ \l{QStyleOptionFrameV2::}{FrameFeature} value is simply copied to
+ this style option.
+*/
+QStyleOptionTabWidgetFrameV2 &QStyleOptionTabWidgetFrameV2::operator=(const QStyleOptionTabWidgetFrame &other)
+{
+ QStyleOptionTabWidgetFrame::operator=(other);
+ if (const QStyleOptionTabWidgetFrameV2 *f2 = qstyleoption_cast<const QStyleOptionTabWidgetFrameV2 *>(&other)) {
+ selectedTabRect = f2->selectedTabRect;
+ tabBarRect = f2->tabBarRect;
+ }
+ return *this;
+}
+
+
+/*!
+ \enum QStyleOptionTabWidgetFrameV2::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 2
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+
#endif // QT_NO_TABWIDGET
#ifndef QT_NO_TABBAR
@@ -5298,9 +5417,9 @@ QStyleHintReturnVariant::QStyleHintReturnVariant() : QStyleHintReturn(Version, T
Returns a T or 0 depending on the type of \a hint.
*/
-#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType)
{
+#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
switch (optionType) {
case QStyleOption::SO_Default:
debug << "SO_Default"; break;
@@ -5361,19 +5480,21 @@ QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType)
case QStyleOption::SO_GraphicsItem:
debug << "SO_GraphicsItem"; break;
}
+#endif
return debug;
}
QDebug operator<<(QDebug debug, const QStyleOption &option)
{
+#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
debug << "QStyleOption(";
debug << QStyleOption::OptionType(option.type);
debug << ',' << (option.direction == Qt::RightToLeft ? "RightToLeft" : "LeftToRight");
debug << ',' << option.state;
debug << ',' << option.rect;
debug << ')';
+#endif
return debug;
}
-#endif
QT_END_NAMESPACE
diff --git a/src/gui/styles/qstyleoption.h b/src/gui/styles/qstyleoption.h
index 2860664513..abd52bff2f 100644
--- a/src/gui/styles/qstyleoption.h
+++ b/src/gui/styles/qstyleoption.h
@@ -192,8 +192,28 @@ public:
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
{
@@ -938,10 +958,8 @@ T qstyleoption_cast(QStyleHintReturn *hint)
return 0;
}
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DEBUG)
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
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 707b05e4d4..8b409312d3 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -1180,7 +1180,7 @@ void QRenderRule::drawBackgroundImage(QPainter *p, const QRect &rect, QPoint off
QRect r = originRect(rect, background()->origin);
QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgp.size(), r);
- QRect inter = aligned.intersected(r);
+ QRect inter = aligned.translated(-off).intersected(r);
switch (background()->repeat) {
case Repeat_Y:
@@ -3325,9 +3325,14 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
break;
case CE_PushButton:
- ParentStyle::drawControl(ce, opt, p, w);
- return;
-
+ 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);
@@ -3370,7 +3375,9 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (rule.hasPosition() && rule.position()->textAlignment != 0) {
Qt::Alignment textAlignment = rule.position()->textAlignment;
QRect textRect = button->rect;
- uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
+ 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()) {
@@ -3599,6 +3606,27 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
}
} 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);
@@ -3668,7 +3696,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
}
if (!cb->currentText.isEmpty() && !cb->editable) {
drawItemText(p, editRect.adjusted(0, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, cb->palette,
- cb->state & State_Enabled, cb->currentText);
+ cb->state & State_Enabled, cb->currentText, QPalette::Text);
}
p->restore();
return;
@@ -4275,23 +4303,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
p->fillRect(v2->rect, v2->palette.alternateBase());
subRule.drawRule(p, opt->rect);
} else {
- QStyleOptionViewItemV2 v2Copy(*v2);
- if (v2->showDecorationSelected) {
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_ViewItem);
- if (v2->state & QStyle::State_Selected) {
- subRule2.configurePalette(&v2Copy.palette, QPalette::NoRole, QPalette::Highlight);
- } else if (v2->features & QStyleOptionViewItemV2::Alternate) {
- subRule2.configurePalette(&v2Copy.palette, QPalette::NoRole, QPalette::AlternateBase);
- } else if (subRule2.hasBackground()) {
- p->fillRect(v2->rect, subRule2.background()->brush);
- }
- } else if (v2->features & QStyleOptionViewItemV2::Alternate) {
- quint64 pc = v2->state & QStyle::State_Enabled ? PseudoClass_Enabled : PseudoClass_Disabled;
- pc |= PseudoClass_Alternate;
- QRenderRule subRule2 = renderRule(w, PseudoElement_ViewItem, pc);
- subRule2.configurePalette(&v2Copy.palette, QPalette::NoRole, QPalette::AlternateBase);
- }
- baseStyle()->drawPrimitive(pe, &v2Copy, p, w);
+ baseStyle()->drawPrimitive(pe, v2, p, w);
}
}
return;
@@ -4325,7 +4337,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
QRenderRule subRule = renderRule(w, opt, PseudoElement_TabWidgetPane);
if (subRule.hasNativeBorder()) {
subRule.drawBackground(p, opt->rect);
- QStyleOptionTabWidgetFrame frmCopy(*frm);
+ QStyleOptionTabWidgetFrameV2 frmCopy(*frm);
subRule.configurePalette(&frmCopy.palette, QPalette::WindowText, QPalette::Window);
baseStyle()->drawPrimitive(pe, &frmCopy, p, w);
} else {
@@ -4356,18 +4368,6 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
break;
case PE_PanelItemViewItem:
- if (!styleHint(SH_ItemView_ShowDecorationSelected, opt, w)) {
- rect = subElementRect(QStyle::SE_ItemViewItemText, opt, w)
- | subElementRect(QStyle::SE_ItemViewItemDecoration, opt, w)
- | subElementRect(QStyle::SE_ItemViewItemCheckIndicator, opt, w);
- }
- pseudoElement = PseudoElement_ViewItem;
- break;
-
- case PE_PanelItemViewRow:
- ParentStyle::drawPrimitive(pe, opt, p, w);
- if (!styleHint(SH_ItemView_ShowDecorationSelected, opt, w))
- return;
pseudoElement = PseudoElement_ViewItem;
break;
@@ -4637,6 +4637,7 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
}
break;
+#ifndef QT_NO_TABWIDGET
case PM_TabBarTabHSpace:
case PM_TabBarTabVSpace:
subRule = renderRule(w, opt, PseudoElement_TabBarTab);
@@ -4660,11 +4661,14 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
return 0;
break;
- case PM_TabBarBaseOverlap:
- if (hasStyleRule(w->parentWidget(), PseudoElement_TabWidgetPane)) {
+ 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
@@ -4722,7 +4726,7 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
return subRule.size().height();
else if (subRule.hasBox() || subRule.hasBorder()) {
QFontMetrics fm = opt ? opt->fontMetrics : w->fontMetrics();
- return subRule.size(QSize(0, fm.lineSpacing())).height();
+ return subRule.size(QSize(0, fm.height())).height();
}
break;
}
diff --git a/src/gui/styles/qstylesheetstyle_default.cpp b/src/gui/styles/qstylesheetstyle_default.cpp
index 406633ed5c..f79f8e06dc 100644
--- a/src/gui/styles/qstylesheetstyle_default.cpp
+++ b/src/gui/styles/qstylesheetstyle_default.cpp
@@ -203,49 +203,6 @@ StyleSheet QStyleSheetStyle::getDefaultStyleSheet() const
ADD_STYLE_RULE;
}
- /*QLineEdit[style="QCleanlooksStyle"] {
- padding-top: 2px;
- padding-bottom: 2px;
- }*/
- if (baseStyle()->inherits("QCleanlooksStyle"))
- {
- SET_ELEMENT_NAME(QLatin1String("QLineEdit"));
- ADD_BASIC_SELECTOR;
- ADD_SELECTOR;
-
-
- SET_PROPERTY(QLatin1String("padding-top"), PaddingTop);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("2px"));
- ADD_DECLARATION;
-
- SET_PROPERTY(QLatin1String("padding-bottom"), PaddingBottom);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("2px"));
- ADD_DECLARATION;
-
- ADD_STYLE_RULE;
- }
-
- /*QLineEdit[style="QWindowsXPStyle"],
- QLineEdit[style="QWindowsVistaStyle"],
- QLineEdit[style="QGtkStyle"] {
- padding-top: 1px;
- padding-bottom: 1px;
- }*/
- if (baseStyle()->inherits("QWindowsXPStyle") || baseStyle()->inherits("QGtkStyle"))
- {
- SET_ELEMENT_NAME(QLatin1String("QLineEdit"));
-
- SET_PROPERTY(QLatin1String("padding-top"), PaddingTop);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("1px"));
- ADD_DECLARATION;
-
- SET_PROPERTY(QLatin1String("padding-bottom"), PaddingBottom);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("1px"));
- ADD_DECLARATION;
-
- ADD_STYLE_RULE;
- }
-
/*QFrame {
border: native;
}*/
diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp
index d27b1ec4a4..86ba947016 100644
--- a/src/gui/styles/qwindowsmobilestyle.cpp
+++ b/src/gui/styles/qwindowsmobilestyle.cpp
@@ -4121,6 +4121,7 @@ void QWindowsMobileStylePrivate::setupWindowsMobileStyle65()
void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOptionTab *tab)
{
+#ifndef QT_NO_TABBAR
#ifdef Q_WS_WINCE_WM
if (wm65) {
tintImagesButton(tab->palette.button().color());
@@ -4207,6 +4208,7 @@ void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOp
}
}
painter->restore();
+#endif //QT_NO_TABBAR
}
void QWindowsMobileStylePrivate::drawPanelItemViewSelected(QPainter *painter, const QStyleOptionViewItemV4 *option, QRect rect)
@@ -4412,7 +4414,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOption
void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOptionSlider *opt, bool completeFrame, bool secondScrollBar)
{
-
+#ifndef QT_NO_SCROLLBAR
#ifdef Q_WS_WINCE_WM
if (wm65) {
tintImagesHigh(opt->palette.highlight().color());
@@ -4469,10 +4471,12 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOpti
arrowOpt.rect.adjust(1, 0, 1, 0);
q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOpt, p, 0);
}
+#endif //QT_NO_SCROLLBAR
}
void QWindowsMobileStylePrivate::drawScrollbarGroove(QPainter *p,const QStyleOptionSlider *opt)
{
+#ifndef QT_NO_SCROLLBAR
#ifdef Q_OS_WINCE_WM
if (wm65) {
p->fillRect(opt->rect, QColor(231, 231, 231));
@@ -4498,6 +4502,7 @@ void QWindowsMobileStylePrivate::drawScrollbarGroove(QPainter *p,const QStyleOpt
fill = opt->palette.light();
}
p->fillRect(opt->rect, fill);
+#endif //QT_NO_SCROLLBAR
}
QWindowsMobileStyle::QWindowsMobileStyle(QWindowsMobileStylePrivate &dd) : QWindowsStyle(dd) {
@@ -5347,10 +5352,8 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp
painter->drawLines(a);
break; }
case PE_Frame:
- if (d->doubleControls)
- qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),2,&option->palette.light());
- else
- qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),1,&option->palette.light());
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),
+ d->doubleControls ? 2 : 1, &option->palette.background());
break;
case PE_FrameLineEdit:
case PE_FrameMenu:
@@ -5592,8 +5595,43 @@ void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
}
#endif // QT_NO_SCROLLAREA
- break; }
-
+ break;
+ }
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ // This is copied from qcommonstyle.cpp with the difference, that
+ // the editRect isn't adjusted when calling drawItemText.
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, 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) {
+ proxy()->drawItemText(painter, editRect,
+ visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ cb->palette, cb->state & State_Enabled, cb->currentText);
+ }
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_COMBOBOX
#ifndef QT_NO_DOCKWIDGET
case CE_DockWidgetTitle:
if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
@@ -6003,7 +6041,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl
}
painter->restore();
break;
-#endif // QT_NO_SLIDER
+#endif // QT_NO_SCROLLBAR
case CC_ToolButton:
if (const QStyleOptionToolButton *toolbutton
= qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
@@ -6154,24 +6192,24 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl
qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget), &editBrush);
else
painter->fillRect(option->rect, editBrush);
- State flags = State_None;
- QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
- if ((option->state & State_On)) {
- painter->fillRect(ar.adjusted(0, 0, 1, 1),cmb->palette.brush(QPalette::Shadow));
- }
- if (d->doubleControls)
- ar.adjust(5, 0, 5, 0);
- else
- ar.adjust(2, 0, -2, 0);
- if (option->state & State_Enabled)
- flags |= State_Enabled;
- if (option->state & State_On)
- flags |= State_Sunken;
- QStyleOption arrowOpt(0);
- arrowOpt.rect = ar;
- arrowOpt.palette = cmb->palette;
- arrowOpt.state = flags;
- proxy()->drawPrimitive(PrimitiveElement(PE_IndicatorArrowDownBig), &arrowOpt, painter, widget);
+ State flags = State_None;
+ QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
+ if ((option->state & State_On)) {
+ painter->fillRect(ar.adjusted(0, 0, 1, 1),cmb->palette.brush(QPalette::Shadow));
+ }
+ if (d->doubleControls)
+ ar.adjust(5, 0, 5, 0);
+ else
+ ar.adjust(2, 0, -2, 0);
+ if (option->state & State_Enabled)
+ flags |= State_Enabled;
+ if (option->state & State_On)
+ flags |= State_Sunken;
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = ar;
+ arrowOpt.palette = cmb->palette;
+ arrowOpt.state = flags;
+ proxy()->drawPrimitive(PrimitiveElement(PE_IndicatorArrowDownBig), &arrowOpt, painter, widget);
if (cmb->subControls & SC_ComboBoxEditField) {
QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
if (cmb->state & State_HasFocus && !cmb->editable)
@@ -6292,16 +6330,20 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio
switch (type) {
case CT_PushButton:
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ newSize = QCommonStyle::sizeFromContents(type, option, size, widget);
int w = newSize.width(),
h = newSize.height();
int defwidth = 0;
if (button->features & QStyleOptionButton::AutoDefaultButton)
defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, button, widget);
- if (w < 75 + defwidth && button->icon.isNull())
- w = 75 + defwidth;
- if (h < 23 + defwidth)
- h = 23 + defwidth;
+
+ int minwidth = int(QStyleHelper::dpiScaled(55.0f));
+ int minheight = int(QStyleHelper::dpiScaled(19.0f));
+
+ if (w < minwidth + defwidth && button->icon.isNull())
+ w = minwidth + defwidth;
+ if (h < minheight + defwidth)
+ h = minheight + defwidth;
newSize = QSize(w + 4, h + 4);
}
break;
@@ -6335,7 +6377,7 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio
case CT_ComboBox:
if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
int fw = comboBox->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget) * 2 : 0;
- newSize = QSize(newSize.width() + fw + 9, newSize.height() + fw-4); //Nine is a magic Number - See CommonStyle for real magic (23)
+ newSize = QSize(newSize.width() + fw + 9, newSize.height() + fw); //Nine is a magic Number - See CommonStyle for real magic (23)
}
break;
#endif
@@ -6618,14 +6660,21 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp
switch (subControl) {
case SC_ComboBoxArrow:
rect.setRect(xpos, y + bmarg, he - 2*bmarg, he - 2*bmarg);
- rect.setRect(xpos, y + bmarg, int((he - 2*bmarg)), he - 2*bmarg);
break;
- case SC_ComboBoxEditField:
- rect.setRect(x + margin+4, y + margin+2, wi - 4 * margin - int((he - 2*bmarg) * 0.84f) -2, he - 2 * margin-4);
- break;
- case SC_ComboBoxFrame:
- rect = comboBox->rect;
- break;
+ case SC_ComboBoxEditField:
+ rect.setRect(x + margin, y + margin, wi - 2 * margin - int((he - 2*bmarg) * 0.84f), he - 2 * margin);
+ if (d->doubleControls) {
+ if (comboBox->editable)
+ rect.adjust(2, 0, 0, 0);
+ else
+ rect.adjust(4, 2, 0, -2);
+ } else if (!comboBox->editable) {
+ rect.adjust(2, 1, 0, -1);
+ }
+ break;
+ case SC_ComboBoxFrame:
+ rect = comboBox->rect;
+ break;
default:
break;
}
@@ -6798,34 +6847,11 @@ void QWindowsMobileStyle::polish(QWidget *widget) {
else
#endif //QT_NO_TOOLBAR
-#ifndef QT_NO_PROPERTIES
- if (QAbstractButton *pushButton = qobject_cast<QAbstractButton*>(widget)) {
- QVariant oldFont = widget->property("_q_styleWindowsMobileFont");
- if (!oldFont.isValid()) {
- QFont f = pushButton->font();
- widget->setProperty("_q_styleWindowsMobileFont", f);
- f.setBold(true);
- int p = f.pointSize();
- if (p > 2)
- f.setPointSize(p-1);
- pushButton->setFont(f);
- }
- }
-#endif
- QWindowsStyle::polish(widget);
+ QWindowsStyle::polish(widget);
}
void QWindowsMobileStyle::unpolish(QWidget *widget)
{
-#ifndef QT_NO_PROPERTIES
- if (QAbstractButton *pushButton = qobject_cast<QAbstractButton*>(widget)) {
- QVariant oldFont = widget->property("_q_styleWindowsMobileFont");
- if (oldFont.isValid()) {
- widget->setFont(qVariantValue<QFont>(oldFont));
- widget->setProperty("_q_styleWindowsMobileFont", QVariant());
- }
- }
-#endif
QWindowsStyle::unpolish(widget);
}
@@ -6999,7 +7025,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co
} else {
d->doubleControls ? ret = 36 : ret = 18;
}
- break;
+ break;
case PM_ScrollBarExtent: {
if (d->smartphone)
@@ -7055,7 +7081,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co
break;
case PM_TextCursorWidth:
ret = 2;
- break;
+ break;
case PM_TabBar_ScrollButtonOverlap:
ret = 0;
break;
@@ -7089,7 +7115,7 @@ int QWindowsMobileStyle::styleHint(StyleHint hint, const QStyleOption *opt, cons
#endif
case SH_ToolBar_Movable:
ret = false;
- break;
+ break;
case SH_ScrollBar_ContextMenu:
ret = false;
break;
diff --git a/src/gui/styles/qwindowsmobilestyle_p.h b/src/gui/styles/qwindowsmobilestyle_p.h
index 1e8c7ffb31..139a4ab01b 100644
--- a/src/gui/styles/qwindowsmobilestyle_p.h
+++ b/src/gui/styles/qwindowsmobilestyle_p.h
@@ -60,6 +60,10 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_STYLE_WINDOWSMOBILE
+class QStyleOptionTab;
+class QStyleOptionSlider;
+class QStyleOptionViewItemV4;
+
class QWindowsMobileStylePrivate : public QWindowsStylePrivate
{
Q_DECLARE_PUBLIC(QWindowsMobileStyle)
diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp
index 0f72440fef..f894b8278c 100644
--- a/src/gui/styles/qwindowsstyle.cpp
+++ b/src/gui/styles/qwindowsstyle.cpp
@@ -115,14 +115,6 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include <limits.h>
QT_END_INCLUDE_NAMESPACE
-static const int windowsItemFrame = 2; // menu item frame width
-static const int windowsSepHeight = 9; // separator item height
-static const int windowsItemHMargin = 3; // menu item hor text margin
-static const int windowsItemVMargin = 2; // menu item ver text margin
-static const int windowsArrowHMargin = 6; // arrow horizontal margin
-static const int windowsRightBorder = 15; // right border on windows
-static const int windowsCheckMarkWidth = 12; // checkmarks width on windows
-
enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
/*
@@ -454,9 +446,6 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
break;
- case PM_ToolBarIconSize:
- ret = int(QStyleHelper::dpiScaled(24.));
- break;
case PM_DockWidgetTitleMargin:
ret = int(QStyleHelper::dpiScaled(2.));
break;
@@ -1850,7 +1839,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
bool act = menuitem->state & State_Selected;
// windows always has a check column, regardless whether we have an icon or not
- int checkcol = qMax(menuitem->maxIconWidth, windowsCheckMarkWidth);
+ 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);
@@ -1906,8 +1895,10 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
newMi.state |= State_Enabled;
if (act)
newMi.state |= State_On;
- newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + windowsItemFrame, menuitem->rect.y() + windowsItemFrame,
- checkcol - 2 * windowsItemFrame, menuitem->rect.height() - 2*windowsItemFrame));
+ 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());
@@ -1918,9 +1909,10 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
p->setPen(discol);
}
- int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xm = QWindowsStylePrivate::windowsItemFrame + checkcol + QWindowsStylePrivate::windowsItemHMargin;
int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ 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
@@ -1954,10 +1946,10 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
p->restore();
}
if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
- int dim = (h - 2 * windowsItemFrame) / 2;
+ int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
PrimitiveElement arrow;
arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ 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;
@@ -2997,6 +2989,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp
#ifndef QT_NO_COMBOBOX
case CC_ComboBox:
if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ p->save();
QBrush editBrush = cmb->palette.brush(QPalette::Base);
if ((cmb->subControls & SC_ComboBoxFrame)) {
if (cmb->frame) {
@@ -3066,6 +3059,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp
proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
}
}
+ p->restore();
}
break;
#endif // QT_NO_COMBOBOX
@@ -3194,7 +3188,7 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
- sz = QSize(10, windowsSepHeight);
+ sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
}
else if (mi->icon.isNull()) {
sz.setHeight(sz.height() - 2);
@@ -3205,14 +3199,14 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
sz.setHeight(qMax(sz.height(),
mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
- + 2 * windowsItemFrame));
+ + 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 * windowsArrowHMargin;
+ 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!!
@@ -3223,9 +3217,9 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
w += fmBold.width(mi->text) - fm.width(mi->text);
}
- int checkcol = qMax(maxpmw, windowsCheckMarkWidth); // Windows always shows a check column
+ int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
w += checkcol;
- w += windowsRightBorder + 10;
+ w += QWindowsStylePrivate::windowsRightBorder + 10;
sz.setWidth(w);
}
break;
@@ -3233,7 +3227,7 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
#ifndef QT_NO_MENUBAR
case CT_MenuBarItem:
if (!sz.isEmpty())
- sz += QSize(windowsItemHMargin * 4, windowsItemVMargin * 2);
+ sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
break;
#endif
// Otherwise, fall through
diff --git a/src/gui/styles/qwindowsstyle_p.h b/src/gui/styles/qwindowsstyle_p.h
index fb84dcecd7..d81c82be41 100644
--- a/src/gui/styles/qwindowsstyle_p.h
+++ b/src/gui/styles/qwindowsstyle_p.h
@@ -87,7 +87,17 @@ public:
QColor activeGradientCaptionColor;
QColor inactiveCaptionColor;
QColor inactiveGradientCaptionColor;
+
+ enum {
+ windowsItemFrame = 2, // menu item frame width
+ windowsSepHeight = 9, // separator item height
+ windowsItemHMargin = 3, // menu item hor text margin
+ windowsItemVMargin = 2, // menu item ver text margin
+ windowsArrowHMargin = 6, // arrow horizontal margin
+ windowsRightBorder = 15, // right border on windows
+ windowsCheckMarkWidth = 12 // checkmarks width on windows
};
+};
QT_END_NAMESPACE
diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp
index 6cb8b40960..9f5440c777 100644
--- a/src/gui/styles/qwindowsvistastyle.cpp
+++ b/src/gui/styles/qwindowsvistastyle.cpp
@@ -159,7 +159,7 @@ QWindowsVistaStyle::QWindowsVistaStyle()
}
//convert Qt state flags to uxtheme button states
-int buttonStateId(int flags, int partId)
+static int buttonStateId(int flags, int partId)
{
int stateId = 0;
if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) {
@@ -190,7 +190,7 @@ int buttonStateId(int flags, int partId)
return stateId;
}
-void Animation::paint(QPainter *painter, const QStyleOption *option)
+void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option)
{
Q_UNUSED(option);
Q_UNUSED(painter);
@@ -205,7 +205,7 @@ void Animation::paint(QPainter *painter, const QStyleOption *option)
+ ((1-alpha)*_secondaryImage)
*/
-void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
+void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
if (_secondaryImage.isNull() || _primaryImage.isNull())
return;
@@ -251,7 +251,7 @@ void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
initial and final state of the transition, depending on the time
difference between _startTime and current time.
*/
-void Transition::paint(QPainter *painter, const QStyleOption *option)
+void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option)
{
float alpha = 1.0;
if (_duration > 0) {
@@ -278,7 +278,7 @@ void Transition::paint(QPainter *painter, const QStyleOption *option)
secondary pulse images depending on the time difference between
_startTime and current time.
*/
-void Pulse::paint(QPainter *painter, const QStyleOption *option)
+void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option)
{
float alpha = 1.0;
if (_duration > 0) {
@@ -393,8 +393,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
startImage.fill(0);
QPainter startPainter(&startImage);
- Animation *anim = d->widgetAnimation(widget);
- Transition *t = new Transition;
+ 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
@@ -531,7 +531,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
case PE_IndicatorCheckBox:
case PE_IndicatorRadioButton:
{
- if (Animation *a = d->widgetAnimation(widget)) {
+ if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
a->paint(painter, option);
} else {
QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
@@ -644,7 +644,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
break;
case PE_FrameLineEdit:
- if (Animation *anim = d->widgetAnimation(widget)) {
+ if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
anim->paint(painter, option);
} else {
QPainter *p = painter;
@@ -929,13 +929,13 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (doTransition) {
QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- Animation *anim = d->widgetAnimation(widget);
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
QStyleOptionButton opt = *button;
opt.state = (QStyle::State)oldState;
startImage.fill(0);
- Transition *t = new Transition;
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
t->setWidget(w);
QPainter startPainter(&startImage);
@@ -972,7 +972,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
{
- if (Animation *anim = d->widgetAnimation(widget)) {
+ if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
anim->paint(painter, option);
} else {
name = QLatin1String("BUTTON");
@@ -999,14 +999,14 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
!(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
(state & State_Enabled) && (state & State_Active))
{
- Animation *anim = d->widgetAnimation(widget);
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
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);
- Pulse *pulse = new Pulse;
+ QWindowsVistaPulse *pulse = new QWindowsVistaPulse;
pulse->setWidget(const_cast<QWidget*>(widget));
QPainter startPainter(&startImage);
@@ -1079,7 +1079,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) {
if (((progressbar->value() > 0 && d->transitionsEnabled()) || isIndeterminate)) {
if (!d->widgetAnimation(progressbar) && progressbar->value() < progressbar->maximum()) {
- Animation *a = new Animation;
+ QWindowsVistaAnimation *a = new QWindowsVistaAnimation;
a->setWidget(const_cast<QWidget*>(widget));
a->setStartTime(QTime::currentTime());
d->startAnimation(a);
@@ -1095,7 +1095,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QTime current = QTime::currentTime();
if (isIndeterminate) {
- if (Animation *a = d->widgetAnimation(widget)) {
+ 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;
@@ -1165,7 +1165,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
d->drawBackground(theme);
- if (Animation *a = d->widgetAnimation(widget)) {
+ 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;
@@ -1603,8 +1603,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
if (doTransition) {
QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- Animation *anim = d->widgetAnimation(widget);
- Transition *t = new Transition;
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
t->setWidget(w);
if (!anim) {
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
@@ -1651,7 +1651,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
t->setDuration(500);
}
- if (Animation *anim = d->widgetAnimation(widget)) {
+ if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
anim->paint(painter, option);
return;
}
@@ -2217,14 +2217,15 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
int xpos = x;
int margin = cb->frame ? 3 : 0;
int bmarg = cb->frame ? 2 : 0;
- xpos += wi - bmarg - 16;
+ int arrowButtonWidth = bmarg + 16;
+ xpos += wi - arrowButtonWidth;
switch (subControl) {
case SC_ComboBoxFrame:
rect = cb->rect;
break;
case SC_ComboBoxArrow:
- rect.setRect(xpos, y , wi - xpos, he);
+ rect.setRect(xpos, y , arrowButtonWidth, he);
break;
case SC_ComboBoxEditField:
rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
@@ -2533,7 +2534,7 @@ void QWindowsVistaStylePrivate::timerEvent()
!animations[i]->running() ||
!QWindowsVistaStylePrivate::useVista())
{
- Animation *a = animations.takeAt(i);
+ QWindowsVistaAnimation *a = animations.takeAt(i);
delete a;
}
}
@@ -2546,14 +2547,14 @@ void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w)
{
for (int i = animations.size() - 1 ; i >= 0 ; --i) {
if (animations[i]->widget() == w) {
- Animation *a = animations.takeAt(i);
+ QWindowsVistaAnimation *a = animations.takeAt(i);
delete a;
break;
}
}
}
-void QWindowsVistaStylePrivate::startAnimation(Animation *t)
+void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t)
{
Q_Q(QWindowsVistaStyle);
stopAnimation(t->widget());
@@ -2575,11 +2576,11 @@ bool QWindowsVistaStylePrivate::transitionsEnabled() const
}
-Animation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const
+QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const
{
if (!widget)
return 0;
- foreach (Animation *a, animations) {
+ foreach (QWindowsVistaAnimation *a, animations) {
if (a->widget() == widget)
return a;
}
diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h
index e9bbb77c9f..04823c1240 100644
--- a/src/gui/styles/qwindowsvistastyle_p.h
+++ b/src/gui/styles/qwindowsvistastyle_p.h
@@ -136,11 +136,11 @@ QT_BEGIN_NAMESPACE
#define TDLG_SECONDARYPANEL 8
#endif
-class Animation
+class QWindowsVistaAnimation
{
public :
- Animation() : _running(true) { }
- virtual ~Animation() { }
+ QWindowsVistaAnimation() : _running(true) { }
+ virtual ~QWindowsVistaAnimation() { }
QWidget * widget() const { return _widget; }
bool running() const { return _running; }
const QTime &startTime() const { return _startTime; }
@@ -161,11 +161,11 @@ protected:
// Handles state transition animations
-class Transition : public Animation
+class QWindowsVistaTransition : public QWindowsVistaAnimation
{
public :
- Transition() : Animation() {}
- virtual ~Transition() { }
+ QWindowsVistaTransition() : QWindowsVistaAnimation() {}
+ virtual ~QWindowsVistaTransition() { }
void setDuration(int duration) { _duration = duration; }
void setStartImage(const QImage &image) { _primaryImage = image; }
void setEndImage(const QImage &image) { _secondaryImage = image; }
@@ -176,11 +176,11 @@ public :
// Handles pulse animations (default buttons)
-class Pulse: public Animation
+class QWindowsVistaPulse: public QWindowsVistaAnimation
{
public :
- Pulse() : Animation() {}
- virtual ~Pulse() { }
+ QWindowsVistaPulse() : QWindowsVistaAnimation() {}
+ virtual ~QWindowsVistaPulse() { }
void setDuration(int duration) { _duration = duration; }
void setPrimaryImage(const QImage &image) { _primaryImage = image; }
void setAlternateImage(const QImage &image) { _secondaryImage = image; }
@@ -199,15 +199,15 @@ public:
~QWindowsVistaStylePrivate();
static bool resolveSymbols();
static inline bool useVista();
- void startAnimation(Animation *);
+ void startAnimation(QWindowsVistaAnimation *);
void stopAnimation(const QWidget *);
- Animation* widgetAnimation(const QWidget *) const;
+ QWindowsVistaAnimation* widgetAnimation(const QWidget *) const;
void timerEvent();
bool transitionsEnabled() const;
QWidget *treeViewHelper();
private:
- QList <Animation*> animations;
+ QList <QWindowsVistaAnimation*> animations;
QBasicTimer animationTimer;
QWidget *m_treeViewHelper;
};
diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp
index 9ef30e5953..fe7f5d7d13 100644
--- a/src/gui/styles/qwindowsxpstyle.cpp
+++ b/src/gui/styles/qwindowsxpstyle.cpp
@@ -47,6 +47,7 @@
#include <private/qpaintengine_raster_p.h>
#include <private/qapplication_p.h>
#include <private/qstylehelper_p.h>
+#include <private/qwidget_p.h>
#include <qlibrary.h>
#include <qpainter.h>
#include <qpaintengine.h>
@@ -299,7 +300,11 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget)
if (!limboWidget) {
limboWidget = new QWidget(0);
+ limboWidget->createWinId();
limboWidget->setObjectName(QLatin1String("xp_limbo_widget"));
+ // We dont need this internal widget to appear in QApplication::topLevelWidgets()
+ if (QWidgetPrivate::allWidgets)
+ QWidgetPrivate::allWidgets->remove(limboWidget);
}
return limboWidget->winId();
@@ -1577,7 +1582,7 @@ case PE_Frame:
// This should work, but currently there's an error in the ::drawBackgroundDirectly()
// code, when using the HDC directly..
if (useGradient) {
- QStyleOptionTabWidgetFrame frameOpt = *tab;
+ QStyleOptionTabWidgetFrameV2 frameOpt = *tab;
frameOpt.rect = widget->rect();
QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget);
QRegion reg = option->rect;
@@ -2836,8 +2841,8 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
State bflags = toolbutton->state & ~State_Sunken;
State mflags = bflags;
-
- if (bflags & State_AutoRaise) {
+ bool autoRaise = flags & State_AutoRaise;
+ if (autoRaise) {
if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
bflags &= ~State_Raised;
}
@@ -2856,8 +2861,8 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
QStyleOption tool(0);
tool.palette = toolbutton->palette;
if (toolbutton->subControls & SC_ToolButton) {
- if (flags & (State_Sunken | State_On | State_Raised) || !(flags & State_AutoRaise)) {
- if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) {
+ 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;
@@ -2876,13 +2881,12 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
theme.stateId = stateId;
d->drawBackground(theme);
} else {
- tool.rect = button;
+ tool.rect = option->rect;
tool.state = bflags;
- if (widget && !qobject_cast<QToolBar*>(widget->parentWidget())
- && !(bflags & State_AutoRaise))
- proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget);
- else
+ if (autoRaise) // for tool bars
proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ else
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget);
}
}
}
@@ -2899,13 +2903,40 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
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;
- proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
+ 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;
diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri
index 78d03590c3..9fb3928510 100644
--- a/src/gui/styles/styles.pri
+++ b/src/gui/styles/styles.pri
@@ -109,10 +109,10 @@ contains( styles, plastique ) {
contains( styles, gtk ) {
HEADERS += styles/qgtkstyle.h
HEADERS += styles/qgtkpainter_p.h
- HEADERS += styles/gtksymbols_p.h
+ HEADERS += styles/qgtkstyle_p.h
SOURCES += styles/qgtkstyle.cpp
SOURCES += styles/qgtkpainter.cpp
- SOURCES += styles/gtksymbols.cpp
+ SOURCES += styles/qgtkstyle_p.cpp
!contains( styles, cleanlooks ) {
styles += cleanlooks
DEFINES+= QT_STYLE_CLEANLOOKS
diff --git a/src/gui/symbian/qsymbianevent.cpp b/src/gui/symbian/qsymbianevent.cpp
new file mode 100644
index 0000000000..2799e6fdf3
--- /dev/null
+++ b/src/gui/symbian/qsymbianevent.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** 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 "qsymbianevent.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QSymbianEvent
+ \brief The QSymbianEvent class contains a Symbian event of any type.
+ \since 4.6
+
+ The class is used as a generic container type for all types of Symbian
+ events.
+
+ \note This class is only available on Symbian.
+
+ \sa QApplication::symbianEventFilter()
+*/
+
+/*!
+ \enum QSymbianEvent::Type
+
+ \value InvalidEvent The event is not valid.
+ \value WindowServerEvent Indicates an event of type \c TWsEvent.
+ \value CommandEvent Indicates that the event is a Symbian command.
+ \value ResourceChangeEvent Indicates that the event is a Symbian resource change type.
+*/
+
+/*!
+ \fn QSymbianEvent::type() const
+
+ Returns the event type contained in the QSymbianEvent instance.
+*/
+
+/*!
+ \fn QSymbianEvent::isValid() const
+
+ Returns whether this QSymbianEvent instance contains a valid event.
+*/
+
+/*!
+ Constructs a QSymbianEvent containing the given window server event
+ \a windowServerEvent.
+*/
+QSymbianEvent::QSymbianEvent(const TWsEvent *windowServerEvent)
+ : m_type(WindowServerEvent)
+ , m_eventPtr(windowServerEvent)
+{
+}
+
+/*!
+ Constructs a QSymbianEvent containing the given event value
+ \a value. The type of event is controlled by the \a eventType parameter.
+*/
+QSymbianEvent::QSymbianEvent(QSymbianEvent::Type eventType, int value)
+{
+ switch (eventType) {
+ case CommandEvent:
+ case ResourceChangeEvent:
+ m_type = eventType;
+ m_eventValue = value;
+ break;
+ default:
+ m_type = InvalidEvent;
+ m_eventValue = 0;
+ break;
+ }
+}
+
+/*!
+ Destroys the QSymbianEvent.
+*/
+QSymbianEvent::~QSymbianEvent()
+{
+}
+
+/*!
+ Returns the window server event contained in the class instance, or 0 if the event type
+ is not \c WindowServerEvent.
+*/
+const TWsEvent *QSymbianEvent::windowServerEvent() const
+{
+ return (m_type == WindowServerEvent) ? static_cast<const TWsEvent *>(m_eventPtr) : 0;
+}
+
+/*!
+ Returns the command contained in the class instance, or 0 if the event type
+ is not \c CommandEvent.
+*/
+int QSymbianEvent::command() const
+{
+ return (m_type == CommandEvent) ? m_eventValue : 0;
+}
+
+/*!
+ Returns the resource change type contained in the class instance, or 0 if the event type
+ is not \c ResourceChangeEvent.
+*/
+int QSymbianEvent::resourceChangeType() const
+{
+ return (m_type == ResourceChangeEvent) ? m_eventValue : 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/symbian/qsymbianevent.h b/src/gui/symbian/qsymbianevent.h
new file mode 100644
index 0000000000..74aa5d02b4
--- /dev/null
+++ b/src/gui/symbian/qsymbianevent.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef 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;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // Q_OS_SYMBIAN
+
+#endif // QSYMBIANEVENT_H
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 2f8a74611d..438b291c0a 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 QTextControl;
friend class QTextDocument;
friend class QTextDocumentPrivate;
friend class QTextEngine;
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 6db86bdaf3..93b9fc6c1a 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -1129,19 +1129,22 @@ static bool setFontWeightFromValue(const Value &value, QFont *font)
static bool setFontFamilyFromValues(const QVector<Value> &values, QFont *font, int start = 0)
{
QString family;
+ bool shouldAddSpace = false;
for (int i = start; i < values.count(); ++i) {
const Value &v = values.at(i);
if (v.type == Value::TermOperatorComma) {
family += QLatin1Char(',');
+ shouldAddSpace = false;
continue;
}
const QString str = v.variant.toString();
if (str.isEmpty())
break;
+ if (shouldAddSpace)
+ family += QLatin1Char(' ');
family += str;
- family += QLatin1Char(' ');
+ shouldAddSpace = true;
}
- family = family.simplified();
if (family.isEmpty())
return false;
font->setFamily(family);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 838fcaa83b..606390327e 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -1617,7 +1617,8 @@ bool QFont::operator==(const QFont &f) const
&& f.d->underline == d->underline
&& f.d->overline == d->overline
&& f.d->strikeOut == d->strikeOut
- && f.d->kerning == d->kerning));
+ && f.d->kerning == d->kerning
+ && f.d->capital == d->capital));
}
@@ -1649,6 +1650,7 @@ bool QFont::operator<(const QFont &f) const
#ifdef Q_WS_X11
if (r1.addStyle != r2.addStyle) return r1.addStyle < r2.addStyle;
#endif // Q_WS_X11
+ if (f.d->capital != d->capital) return f.d->capital < d->capital;
int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
@@ -2328,22 +2330,22 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
*/
QFontInfo::QFontInfo(const QFont &font)
: d(font.d.data())
-{ d->ref.ref(); }
+{
+}
/*!
Constructs a copy of \a fi.
*/
QFontInfo::QFontInfo(const QFontInfo &fi)
- : d(fi.d)
-{ d->ref.ref(); }
+ : d(fi.d.data())
+{
+}
/*!
Destroys the font info object.
*/
QFontInfo::~QFontInfo()
{
- if (!d->ref.deref())
- delete d;
}
/*!
@@ -2351,7 +2353,7 @@ QFontInfo::~QFontInfo()
*/
QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
{
- qAtomicAssign(d, fi.d);
+ d = fi.d.data();
return *this;
}
@@ -2636,7 +2638,7 @@ QFontCache::~QFontCache()
while (it != end) {
if (--it.value().data->cache_count == 0) {
if (it.value().data->ref == 0) {
- FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %d %d %d %d)",
+ FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)",
it.value().data, it.key().script, it.key().def.pointSize,
it.key().def.pixelSize, it.key().def.weight, it.key().def.style,
it.key().def.fixedPitch);
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index d74f0b4ddf..144a82d16e 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -86,7 +86,7 @@ struct QFontDef
#endif // Q_WS_X11
qreal pointSize;
- int pixelSize;
+ qreal pixelSize;
uint styleStrategy : 16;
uint styleHint : 8;
diff --git a/src/gui/text/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp
index 277d88f520..0375fdb345 100644
--- a/src/gui/text/qfont_s60.cpp
+++ b/src/gui/text/qfont_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index a4817ab7c6..7cda465a7d 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -535,7 +535,13 @@ static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
// Vietnamese,
{ 0, 127 }, // same as latin1
// Other,
- { 126, 127 }
+ { 126, 127 },
+ // Ogham,
+ { 78, 127 },
+ // Runic,
+ { 79, 127 },
+ // Nko,
+ { 14, 127 },
};
#define SimplifiedChineseCsbBit 18
@@ -875,7 +881,8 @@ static const int scriptForWritingSystem[] = {
QUnicodeTables::Common, // Braille
QUnicodeTables::Common, // Symbol
QUnicodeTables::Ogham, // Ogham
- QUnicodeTables::Runic // Runic
+ QUnicodeTables::Runic, // Runic
+ QUnicodeTables::Nko // Nko
};
@@ -883,12 +890,12 @@ static const int scriptForWritingSystem[] = {
static inline bool requiresOpenType(int writingSystem)
{
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
- || writingSystem == QFontDatabase::Khmer);
+ || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
}
static inline bool scriptRequiresOpenType(int script)
{
return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer);
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
}
#endif
@@ -1333,7 +1340,7 @@ static void match(int script, const QFontDef &request,
" family: %s [%s], script: %d\n"
" weight: %d, style: %d\n"
" stretch: %d\n"
- " pixelSize: %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(),
@@ -1560,6 +1567,7 @@ QFontDatabase::QFontDatabase()
\value Other (the same as Symbol)
\value Ogham
\value Runic
+ \value Nko
\omitvalue WritingSystemsCount
*/
@@ -2234,6 +2242,9 @@ QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
case Runic:
name = QT_TRANSLATE_NOOP("QFontDatabase", "Runic");
break;
+ case Nko:
+ name = QT_TRANSLATE_NOOP("QFontDatabase", "N'Ko");
+ break;
default:
Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
break;
@@ -2447,6 +2458,12 @@ QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
sample += QChar(0x16a2);
sample += QChar(0x16a3);
break;
+ case Nko:
+ sample += QChar(0x7ca);
+ sample += QChar(0x7cb);
+ sample += QChar(0x7cc);
+ sample += QChar(0x7cd);
+ break;
default:
break;
}
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index b612c36c9c..4304220702 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -108,6 +108,7 @@ public:
Ogham,
Runic,
+ Nko,
WritingSystemsCount
};
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
index 1a6bb11cb9..808dca6241 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/gui/text/qfontdatabase_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -136,6 +136,23 @@ QFontDatabaseS60StoreImplementation::~QFontDatabaseS60StoreImplementation()
m_heap->Close();
}
+#ifndef FNTSTORE_H_INLINES_SUPPORT_FMM
+/*
+ Workaround: fntstore.h has an inlined function 'COpenFont* CBitmapFont::OpenFont()'
+ that returns a private data member. The header will change between SDKs. But Qt has
+ to build on any SDK version and run on other versions of Symbian OS.
+ This function performs the needed pointer arithmetic to get the right COpenFont*
+*/
+COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont)
+{
+ const TInt offsetIOpenFont = 92; // '_FOFF(CBitmapFont, iOpenFont)' ..if iOpenFont weren't private
+ const TUint valueIOpenFont = *(TUint*)PtrAdd(aBitmapFont, offsetIOpenFont);
+ return (valueIOpenFont & 1) ?
+ (COpenFont*)PtrAdd(aBitmapFont, valueIOpenFont & ~1) : // New behavior: iOpenFont is offset
+ (COpenFont*)valueIOpenFont; // Old behavior: iOpenFont is pointer
+}
+#endif // FNTSTORE_H_INLINES_SUPPORT_FMM
+
const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(const QString &typeface) const
{
if (!m_extensions.contains(typeface)) {
@@ -144,8 +161,14 @@ const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(c
spec.iHeight = 1;
const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, spec);
Q_ASSERT(err == KErrNone && font);
- CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
- m_extensions.insert(typeface, new QFontEngineS60Extensions(font, bitmapFont->OpenFont()));
+ const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
+ COpenFont *openFont =
+#ifdef FNTSTORE_H_INLINES_SUPPORT_FMM
+ bitmapFont->openFont();
+#else
+ OpenFontFromBitmapFont(bitmapFont);
+#endif // FNTSTORE_H_INLINES_SUPPORT_FMM
+ m_extensions.insert(typeface, new QFontEngineS60Extensions(font, openFont));
}
return m_extensions.value(typeface);
}
diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp
index ae26dabb5e..6cde9edc9e 100644
--- a/src/gui/text/qfontdatabase_win.cpp
+++ b/src/gui/text/qfontdatabase_win.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qt_windows.h"
+#include <qmath.h>
#include <private/qapplication_p.h>
#include "qfont_p.h"
#include "qfontengine_p.h"
@@ -670,7 +671,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
break;
}
- lf.lfHeight = -request.pixelSize;
+ lf.lfHeight = -qRound(request.pixelSize);
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
@@ -899,7 +900,6 @@ static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &r
return fe;
}
-
void QFontDatabase::load(const QFontPrivate *d, int script)
{
// sanity checks
@@ -910,8 +910,9 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
// normalize the request to get better caching
QFontDef req = d->request;
if (req.pixelSize <= 0)
- req.pixelSize = qMax(1, qRound(req.pointSize * d->dpi / 72.));
- req.pointSize = 0;
+ req.pixelSize = qreal((req.pointSize * d->dpi) / 72.);
+ if (req.pixelSize < 1)
+ req.pixelSize = 1;
if (req.weight == 0)
req.weight = QFont::Normal;
if (req.stretch == 0)
@@ -928,7 +929,8 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QFontEngine *fe = QFontCache::instance()->findEngine(key);
// set it to the actual pointsize, so QFontInfo will do the right thing
- req.pointSize = req.pixelSize*72./d->dpi;
+ if (req.pointSize < 0)
+ req.pointSize = req.pixelSize*72./d->dpi;
if (!fe) {
if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index 382c4fea5f..dd575f97b4 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -51,6 +51,7 @@
#include <qfile.h>
#include <qtemporaryfile.h>
#include <qabstractfileengine.h>
+#include <qmath.h>
#include <ctype.h>
#include <stdlib.h>
@@ -154,187 +155,187 @@ static const char writingSystems_for_xlfd_encoding[sizeof(xlfd_encoding)][QFontD
{ 0, 1, 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 },
// iso8859-2
{ 0, 1, 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 },
// iso8859-3
{ 0, 1, 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 },
// iso8859-4
{ 0, 1, 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 },
// iso8859-9
{ 0, 1, 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 },
// iso8859-10
{ 0, 1, 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 },
// iso8859-13
{ 0, 1, 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 },
// iso8859-14
{ 0, 1, 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 },
// iso8859-15
{ 0, 1, 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 },
// hp-roman8
{ 0, 1, 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 },
// iso8859-5
{ 0, 0, 0, 1, 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 },
// *-cp1251
{ 0, 0, 0, 1, 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 },
// koi8-ru
{ 0, 0, 0, 1, 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 },
// koi8-u
{ 0, 0, 0, 1, 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 },
// koi8-r
{ 0, 0, 0, 1, 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 },
// iso8859-7
{ 0, 0, 1, 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 },
// iso8859-8
{ 0, 0, 0, 0, 0, 1, 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 },
// gb18030-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, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// gb18030.2000-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, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// gbk-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, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// gb2312.*-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, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// jisx0201*-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, 1, 0, 0,
- 0 },
+ 0, 0 },
// jisx0208*-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, 1, 0, 0,
- 0 },
+ 0, 0 },
// ksc5601*-*
{ 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, 1, 0,
- 0 },
+ 0, 0 },
// big5hkscs-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, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// hkscs-1
{ 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, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// big5*-*
{ 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, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// tscii-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// tis620*-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-11
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// mulelao-1
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// ethiopic-unicode
{ 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 },
// iso10646-1
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// unicode-*
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// *-symbol
{ 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,
- 1 },
+ 1, 0 },
// *-fontspecific
{ 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,
- 1 },
+ 1, 0 },
// fontspecific-*
{ 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,
- 1 }
+ 1, 0 }
};
@@ -752,12 +753,12 @@ QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &request)
if (X11->display)
dpi = QX11Info::appDpiY();
else
- dpi = 96; // ####
+ dpi = qt_defaultDpiY();
}
double size;
if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
- fontDef.pixelSize = qRound(size);
+ fontDef.pixelSize = size;
else
fontDef.pixelSize = 12;
@@ -834,7 +835,8 @@ static const char *specialLanguages[] = {
"ko", // Hangul
"", // Ogham
"", // Runic
- "km" // Khmer
+ "km", // Khmer
+ "" // N'Ko
};
enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
@@ -865,7 +867,8 @@ static const ushort specialChars[] = {
0, // Hangul
0x1681, // Ogham
0x16a0, // Runic
- 0 // Khmer
+ 0, // Khmer
+ 0x7ca // N'Ko
};
enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
@@ -904,7 +907,8 @@ static const char *languageForWritingSystem[] = {
"vi", // Vietnamese
0, // Symbol
0, // Ogham
- 0 // Runic
+ 0, // Runic
+ 0 // N'Ko
};
enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
@@ -943,7 +947,8 @@ static const ushort sampleCharForWritingSystem[] = {
0, // Vietnamese
0, // Symbol
0x1681, // Ogham
- 0x16a0 // Runic
+ 0x16a0, // Runic
+ 0x7ca // N'Ko
};
enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
@@ -983,7 +988,8 @@ static const char *openType[] = {
0, // Vietnamese
0, // Symbol
0, // Ogham
- 0 // Runic
+ 0, // Runic
+ "nko " // N'Ko
};
enum { OpenTypeCount = sizeof(openType) / sizeof(const char *) };
@@ -1455,7 +1461,7 @@ void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontD
slant_value = FC_SLANT_OBLIQUE;
FcPatternAddInteger(pattern, FC_SLANT, slant_value);
- double size_value = qMax(1, request.pixelSize);
+ double size_value = qMax(qreal(1.), request.pixelSize);
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
int stretch = request.stretch;
@@ -1471,7 +1477,7 @@ void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontD
!(request.styleStrategy & QFont::NoAntialias));
}
- if (script != QUnicodeTables::Common) {
+ if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
Q_ASSERT(script < QUnicodeTables::ScriptCount);
FcLangSet *ls = FcLangSetCreate();
FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
@@ -1614,7 +1620,7 @@ static QFontEngine *tryPatternLoad(FcPattern *p, int screen,
goto done;
if (!FcCharSetHasChar(cs, specialChars[script]))
goto done;
- } else {
+ } else if (*specialLanguages[script] != '\0'){
FcLangSet *langSet = 0;
if (FcPatternGetLangSet(match, FC_LANG, 0, &langSet) != FcResultMatch)
goto done;
@@ -1893,8 +1899,9 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
// normalize the request to get better caching
QFontDef req = d->request;
if (req.pixelSize <= 0)
- req.pixelSize = qRound(qt_pixelSize(req.pointSize, d->dpi));
- req.pointSize = 0;
+ req.pixelSize = floor(qt_pixelSize(req.pointSize, d->dpi) * 100 + 0.5) / 100;
+ if (req.pixelSize < 1)
+ req.pixelSize = 1;
if (req.weight == 0)
req.weight = QFont::Normal;
if (req.stretch == 0)
@@ -1909,7 +1916,9 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
return;
// set it to the actual pointsize, so QFontInfo will do the right thing
- req.pointSize = qt_pointSize(req.pixelSize, d->dpi);
+ if (req.pointSize < 0)
+ req.pointSize = qt_pointSize(req.pixelSize, d->dpi);
+
QFontEngine *fe = QFontCache::instance()->findEngine(key);
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 3da1593184..293eac76ac 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -327,7 +327,7 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id)
void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing)
{
- *ysize = fontDef.pixelSize << 6;
+ *ysize = qRound(fontDef.pixelSize * 64);
*xsize = *ysize * fontDef.stretch / 100;
*outline_drawing = false;
@@ -387,7 +387,9 @@ QFontEngine::Properties QFreetypeFace::properties() const
p.descent = QFixed::fromFixed(-face->size->metrics.descender);
p.leading = QFixed::fromFixed(face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender);
p.emSquare = face->size->metrics.y_ppem;
- p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
+// p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
+ p.boundingBox = QRectF(0, -p.ascent.toReal(),
+ face->size->metrics.max_advance/64, (p.ascent + p.descent).toReal() );
}
p.italicAngle = 0;
p.capHeight = p.ascent;
@@ -709,6 +711,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format)
hbFace = freetype->hbFace;
metrics = face->size->metrics;
+
#if defined(Q_WS_QWS)
/*
TrueType fonts with embedded bitmaps may have a bitmap font specific
@@ -752,9 +755,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph
load_flags = FT_LOAD_NO_BITMAP;
// apply our matrix to this, but note that the metrics will not be affected by this.
- FT_Matrix matrix = freetype->matrix;
FT_Face face = lockFace();
- matrix = this->matrix;
+ FT_Matrix matrix = this->matrix;
FT_Matrix_Multiply(&set->transformationMatrix, &matrix);
FT_Set_Transform(face, &matrix, 0);
freetype->matrix = matrix;
@@ -1219,7 +1221,8 @@ QFixed QFontEngineFT::ascent() const
QFixed QFontEngineFT::descent() const
{
- return QFixed::fromFixed(-metrics.descender);
+ // subtract a pixel to work around QFontMetrics's built-in + 1
+ return QFixed::fromFixed(-metrics.descender - 64);
}
QFixed QFontEngineFT::leading() const
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 758d8af658..a4e7c04568 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -119,6 +119,28 @@ OSStatus QMacFontPath::closePath(void *data)
}
+
+void qmacfontengine_gamma_correct(QImage *image)
+{
+ extern uchar qt_pow_rgb_gamma[256];
+
+ // gamma correct the pixels back to linear color space...
+ int h = image->height();
+ int w = image->width();
+
+ for (int y=0; y<h; ++y) {
+ uint *pixels = (uint *) image->scanLine(y);
+ for (int x=0; x<w; ++x) {
+ uint p = pixels[x];
+ uint r = qt_pow_rgb_gamma[qRed(p)];
+ uint g = qt_pow_rgb_gamma[qGreen(p)];
+ uint b = qt_pow_rgb_gamma[qBlue(p)];
+ pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
+ }
+ }
+}
+
+
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
@@ -524,7 +546,7 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1);
if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
+ cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
for (int i = 0; i < nGlyphs; ++i) {
@@ -534,7 +556,7 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
}
}
-QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
+QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
{
const glyph_metrics_t br = boundingBox(glyph);
QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32);
@@ -549,9 +571,10 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
8, im.bytesPerLine(), colorspace,
cgflags);
CGContextSetFontSize(ctx, fontDef.pixelSize);
- CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold
- && !(fontDef.styleStrategy & QFont::NoAntialias));
- CGContextSetShouldSmoothFonts(ctx, false);
+ CGContextSetShouldAntialias(ctx, aa ||
+ (fontDef.pointSize > qt_antialiasing_threshold
+ && !(fontDef.styleStrategy & QFont::NoAntialias)));
+ CGContextSetShouldSmoothFonts(ctx, aa);
CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
@@ -586,6 +609,13 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
CGContextRelease(ctx);
+ return im;
+}
+
+QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
+{
+ QImage im = imageForGlyph(glyph, 0, false);
+
QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
QVector<QRgb> colors(256);
for (int i=0; i<256; ++i)
@@ -605,6 +635,16 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
return indexed;
}
+QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &x)
+{
+ if (x.type() >= QTransform::TxScale)
+ return QFontEngine::alphaRGBMapForGlyph(glyph, margin, x);
+
+ QImage im = imageForGlyph(glyph, margin, true);
+ qmacfontengine_gamma_correct(&im);
+ return im;
+}
+
void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
{
Q_ASSERT(false);
@@ -790,7 +830,6 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS
surrogates += (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00
&& str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
}
- Q_ASSERT(*nfo->numGlyphs == item->length - surrogates);
#endif
for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop)
if (item->charAttributes[nextCharStop].charStop)
@@ -816,10 +855,13 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS
QFixed xAdvance = FixedToQFixed(layoutData[glyphIdx + 1].realPos - layoutData[glyphIdx].realPos);
if (glyphId != 0xffff || i == 0) {
- nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
+ if (i < nfo->glyphs->numGlyphs)
+ {
+ nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
- nfo->glyphs->advances_y[i] = yAdvance;
- nfo->glyphs->advances_x[i] = xAdvance;
+ nfo->glyphs->advances_y[i] = yAdvance;
+ nfo->glyphs->advances_x[i] = xAdvance;
+ }
} else {
// ATSUI gives us 0xffff as glyph id at the index in the glyph array for
// a character position that maps to a ligtature. Such a glyph id does not
@@ -989,6 +1031,8 @@ bool QFontEngineMacMulti::stringToCMapInternal(const QChar *str, int len, QGlyph
nfo.flags = flags;
nfo.shaperItem = shaperItem;
+ int prevNumGlyphs = *nglyphs;
+
QVarLengthArray<int> mappedFonts(len);
for (int i = 0; i < len; ++i)
mappedFonts[i] = 0;
@@ -1100,6 +1144,8 @@ bool QFontEngineMacMulti::stringToCMapInternal(const QChar *str, int len, QGlyph
}
ATSUClearLayoutCache(textLayout, kATSUFromTextBeginning);
+ if (prevNumGlyphs < *nfo.numGlyphs)
+ return false;
return true;
}
@@ -1505,19 +1551,7 @@ QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTra
im = im.transformed(t);
}
- extern uchar qt_pow_rgb_gamma[256];
-
- // gamma correct the pixels back to linear color space...
- for (int y=0; y<im.height(); ++y) {
- uint *pixels = (uint *) im.scanLine(y);
- for (int x=0; x<im.width(); ++x) {
- uint p = pixels[x];
- uint r = qt_pow_rgb_gamma[qRed(p)];
- uint g = qt_pow_rgb_gamma[qGreen(p)];
- uint b = qt_pow_rgb_gamma[qBlue(p)];
- pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
- }
- }
+ qmacfontengine_gamma_correct(&im);
return im;
}
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index bf0c28197f..771fe04b35 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -448,12 +448,13 @@ public:
virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
virtual QImage alphaMapForGlyph(glyph_t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
virtual qreal minRightBearing() const;
virtual qreal minLeftBearing() const;
-
private:
+ QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
CTFontRef ctfont;
CGFontRef cgFont;
QCoreTextFontEngineMulti *parentEngine;
diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
index ef3f2ae594..f978bd897c 100644
--- a/src/gui/text/qfontengine_qpf.cpp
+++ b/src/gui/text/qfontengine_qpf.cpp
@@ -819,7 +819,7 @@ FT_Face QFontEngineQPF::lockFace() const
FT_Face face = freetype->face;
// ### not perfect
- const int ysize = fontDef.pixelSize << 6;
+ const int ysize = qRound(fontDef.pixelSize * qreal(64));
const int xsize = ysize;
if (freetype->xsize != xsize || freetype->ysize != ysize) {
@@ -938,7 +938,7 @@ void QFontEngineQPF::loadGlyph(glyph_t glyph)
g.advance = qRound(metrics.xoff);
QT_WRITE(fd, &g, sizeof(g));
- QT_WRITE(fd, img.bits(), img.numBytes());
+ QT_WRITE(fd, img.bits(), img.byteCount());
glyphPos = oldSize - glyphDataOffset;
#if 0 && defined(DEBUG_FONTENGINE)
@@ -948,7 +948,7 @@ void QFontEngineQPF::loadGlyph(glyph_t glyph)
quint32 *gmap = (quint32 *)(fontData + glyphMapOffset);
gmap[glyph] = qToBigEndian(glyphPos);
- glyphDataSize = glyphPos + sizeof(g) + img.numBytes();
+ glyphDataSize = glyphPos + sizeof(g) + img.byteCount();
quint32 *blockSizePtr = (quint32 *)(fontData + glyphDataOffset - 4);
*blockSizePtr = qToBigEndian(glyphDataSize);
}
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index 88ae8f62ef..e279ad2278 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
index 44f8122143..9e22245575 100644
--- a/src/gui/text/qfontengine_s60_p.h
+++ b/src/gui/text/qfontengine_s60_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index cc555a39ff..6c367ab6fb 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -125,6 +125,7 @@ HDC shared_dc()
}
#endif
+#ifndef Q_WS_WINCE
typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
static PtrGetCharWidthI ptrGetCharWidthI = 0;
static bool resolvedGetCharWidthI = false;
@@ -136,6 +137,7 @@ static void resolveGetCharWidthI()
resolvedGetCharWidthI = true;
ptrGetCharWidthI = (PtrGetCharWidthI)QLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI");
}
+#endif // !defined(Q_WS_WINCE)
// defined in qtextengine_win.cpp
typedef void *SCRIPT_CACHE;
@@ -206,7 +208,7 @@ void QFontEngineWin::getCMap()
unitsPerEm = otm->otmEMSquare;
x_height = (int)otm->otmsXHeight;
loadKerningPairs(designToDevice);
- _faceId.filename = (char *)otm + (int)otm->otmpFullName;
+ _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFullName)).toLatin1();
lineWidth = otm->otmsUnderscoreSize;
fsType = otm->otmfsType;
free(otm);
@@ -340,8 +342,10 @@ QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont
designAdvances = 0;
designAdvancesSize = 0;
+#ifndef Q_WS_WINCE
if (!resolvedGetCharWidthI)
resolveGetCharWidthI();
+#endif
}
QFontEngineWin::~QFontEngineWin()
@@ -381,80 +385,18 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
if (flags & QTextEngine::GlyphIndicesOnly)
return true;
-#if defined(Q_WS_WINCE)
- HDC hdc = shared_dc();
- if (flags & QTextEngine::DesignMetrics) {
- HGDIOBJ oldFont = 0;
- int glyph_pos = 0;
- for(register int i = 0; i < len; i++) {
- bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
- && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
- unsigned int glyph = glyphs->glyphs[glyph_pos];
- 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();
- SIZE size = {0, 0};
- GetTextExtentPoint32(hdc, (wchar_t *)(str+i), surrogate ? 2 : 1, &size);
- designAdvances[glyph] = QFixed((int)size.cx)/designToDevice;
- }
- glyphs->advances_x[glyph_pos] = designAdvances[glyph];
- glyphs->advances_y[glyph_pos] = 0;
- if (surrogate)
- ++i;
- ++glyph_pos;
- }
- if(oldFont)
- DeleteObject(SelectObject(hdc, oldFont));
- } else {
- int glyph_pos = 0;
- HGDIOBJ oldFont = 0;
-
- for(register int i = 0; i < len; i++) {
- bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
- && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
- unsigned int glyph = glyphs->glyphs[glyph_pos];
-
- glyphs->advances_y[glyph_pos] = 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[glyph_pos] = widthCache[glyph];
- // font-width cache failed
- if (glyphs->advances_x[glyph_pos] == 0) {
- SIZE size = {0, 0};
- if (!oldFont)
- oldFont = SelectObject(hdc, hfont);
- GetTextExtentPoint32(hdc, (wchar_t *)str + i, surrogate ? 2 : 1, &size);
- glyphs->advances_x[glyph_pos] = size.cx;
- // if glyph's within cache range, store it for later
- if (size.cx > 0 && size.cx < 0x100)
- widthCache[glyph] = size.cx;
- }
-
- if (surrogate)
- ++i;
- ++glyph_pos;
- }
+ recalcAdvances(glyphs, flags);
+ return true;
+}
- if (oldFont)
- SelectObject(hdc, oldFont);
- }
+inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
+{
+#if defined(Q_WS_WINCE)
+ GetCharWidth32(hdc, glyph, glyph, &width);
#else
- recalcAdvances(glyphs, flags);
+ if (ptrGetCharWidthI)
+ ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
#endif
- return true;
}
void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
@@ -477,8 +419,7 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla
oldFont = selectDesignFont();
int width = 0;
- if (ptrGetCharWidthI)
- ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
+ calculateTTFGlyphWidth(hdc, glyph, width);
designAdvances[glyph] = QFixed(width) / designToDevice;
}
glyphs->advances_x[i] = designAdvances[glyph];
@@ -517,8 +458,8 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla
SIZE size = {0, 0};
GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size);
width = size.cx;
- } else if (ptrGetCharWidthI) {
- ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
+ } else {
+ calculateTTFGlyphWidth(hdc, glyph, width);
}
glyphs->advances_x[i] = width;
// if glyph's within cache range, store it for later
@@ -636,7 +577,9 @@ QFixed QFontEngineWin::ascent() const
QFixed QFontEngineWin::descent() const
{
- return tm.tmDescent;
+ // ### we substract 1 to even out the historical +1 in QFontMetrics's
+ // ### height=asc+desc+1 equation. Fix in Qt5.
+ return tm.tmDescent - 1;
}
QFixed QFontEngineWin::leading() const
@@ -1044,8 +987,8 @@ QFontEngine::Properties QFontEngineWin::properties() const
Properties p;
p.emSquare = unitsPerEm;
p.italicAngle = otm->otmItalicAngle;
- p.postscriptName = (char *)otm + (int)otm->otmpFamilyName;
- p.postscriptName += (char *)otm + (int)otm->otmpStyleName;
+ p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFamilyName)).toLatin1();
+ p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpStyleName)).toLatin1();
#ifndef QT_NO_PRINTER
p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName);
#endif
@@ -1167,7 +1110,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin
ih + 2 * margin + 4,
QNativeImage::systemFormat(), !qt_cleartype_enabled);
- /*If cleartype is enabled we use the standard system format even on Windows CE
+ /*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);
diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h
index 335d761fa6..0998949177 100644
--- a/src/gui/text/qfontinfo.h
+++ b/src/gui/text/qfontinfo.h
@@ -43,6 +43,7 @@
#define QFONTINFO_H
#include <QtGui/qfont.h>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_HEADER
@@ -77,7 +78,7 @@ public:
bool exactMatch() const;
private:
- QFontPrivate *d;
+ QExplicitlySharedDataPointer<QFontPrivate> d;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index ce122aa8aa..b8c1b3378f 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -165,7 +165,6 @@ extern int qt_defaultDpi();
QFontMetrics::QFontMetrics(const QFont &font)
: d(font.d.data())
{
- d->ref.ref();
}
/*!
@@ -196,7 +195,6 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
d->screen = screen;
} else {
d = font.d.data();
- d->ref.ref();
}
}
@@ -205,8 +203,9 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
Constructs a copy of \a fm.
*/
QFontMetrics::QFontMetrics(const QFontMetrics &fm)
- : d(fm.d)
-{ d->ref.ref(); }
+ : d(fm.d.data())
+{
+}
/*!
Destroys the font metrics object and frees all allocated
@@ -214,8 +213,6 @@ QFontMetrics::QFontMetrics(const QFontMetrics &fm)
*/
QFontMetrics::~QFontMetrics()
{
- if (!d->ref.deref())
- delete d;
}
/*!
@@ -223,7 +220,7 @@ QFontMetrics::~QFontMetrics()
*/
QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm)
{
- qAtomicAssign(d, fm.d);
+ d = fm.d.data();
return *this;
}
@@ -536,7 +533,7 @@ int QFontMetrics::width(const QString &text, int len) const
if (len == 0)
return 0;
- QTextEngine layout(text, d);
+ QTextEngine layout(text, d.data());
layout.ignoreBidi = true;
return qRound(layout.width(0, len));
}
@@ -612,7 +609,7 @@ int QFontMetrics::charWidth(const QString &text, int pos) const
int from = qMax(0, pos - 8);
int to = qMin(text.length(), pos + 8);
QString cstr = QString::fromRawData(text.unicode() + from, to - from);
- QTextEngine layout(cstr, d);
+ QTextEngine layout(cstr, d.data());
layout.ignoreBidi = true;
layout.itemize();
width = qRound(layout.width(pos-from, 1));
@@ -661,7 +658,7 @@ QRect QFontMetrics::boundingRect(const QString &text) const
if (text.length() == 0)
return QRect();
- QTextEngine layout(text, d);
+ QTextEngine layout(text, d.data());
layout.ignoreBidi = true;
layout.itemize();
glyph_metrics_t gm = layout.boundingBox(0, text.length());
@@ -770,7 +767,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te
QRectF rb;
QRectF rr(rect);
- qt_format_text(QFont(d), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
+ qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
tabArrayLen, 0);
return rb.toAlignedRect();
@@ -831,7 +828,7 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const
if (text.length() == 0)
return QRect();
- QTextEngine layout(text, d);
+ QTextEngine layout(text, d.data());
layout.ignoreBidi = true;
layout.itemize();
glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
@@ -876,7 +873,7 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in
}
_text = _text.mid(posA);
}
- QStackTextEngine engine(_text, QFont(d));
+ QStackTextEngine engine(_text, QFont(d.data()));
return engine.elidedText(mode, width, flags);
}
@@ -989,9 +986,8 @@ int QFontMetrics::lineWidth() const
from the given \a fontMetrics object.
*/
QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
- : d(fontMetrics.d)
+ : d(fontMetrics.d.data())
{
- d->ref.ref();
}
/*!
@@ -1001,7 +997,7 @@ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
*/
QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other)
{
- qAtomicAssign(d, other.d);
+ d = other.d.data();
return *this;
}
@@ -1021,7 +1017,6 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other)
QFontMetricsF::QFontMetricsF(const QFont &font)
: d(font.d.data())
{
- d->ref.ref();
}
/*!
@@ -1052,7 +1047,6 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
d->screen = screen;
} else {
d = font.d.data();
- d->ref.ref();
}
}
@@ -1061,8 +1055,9 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
Constructs a copy of \a fm.
*/
QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm)
- : d(fm.d)
-{ d->ref.ref(); }
+ : d(fm.d.data())
+{
+}
/*!
Destroys the font metrics object and frees all allocated
@@ -1070,8 +1065,6 @@ QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm)
*/
QFontMetricsF::~QFontMetricsF()
{
- if (!d->ref.deref())
- delete d;
}
/*!
@@ -1079,7 +1072,7 @@ QFontMetricsF::~QFontMetricsF()
*/
QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm)
{
- qAtomicAssign(d, fm.d);
+ d = fm.d.data();
return *this;
}
@@ -1374,7 +1367,7 @@ qreal QFontMetricsF::rightBearing(QChar ch) const
*/
qreal QFontMetricsF::width(const QString &text) const
{
- QTextEngine layout(text, d);
+ QTextEngine layout(text, d.data());
layout.ignoreBidi = true;
layout.itemize();
return layout.width(0, text.length()).toReal();
@@ -1451,7 +1444,7 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const
if (len == 0)
return QRectF();
- QTextEngine layout(text, d);
+ QTextEngine layout(text, d.data());
layout.ignoreBidi = true;
layout.itemize();
glyph_metrics_t gm = layout.boundingBox(0, len);
@@ -1559,7 +1552,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString&
tabArrayLen++;
QRectF rb;
- qt_format_text(QFont(d), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
+ qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
tabArrayLen, 0);
return rb;
}
@@ -1624,7 +1617,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const
if (text.length() == 0)
return QRect();
- QTextEngine layout(text, d);
+ QTextEngine layout(text, d.data());
layout.ignoreBidi = true;
layout.itemize();
glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
@@ -1649,7 +1642,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const
*/
QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const
{
- QStackTextEngine engine(text, QFont(d));
+ QStackTextEngine engine(text, QFont(d.data()));
return engine.elidedText(mode, QFixed::fromReal(width), flags);
}
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index 1147e3a0ca..23200c51fc 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -43,6 +43,7 @@
#define QFONTMETRICS_H
#include <QtGui/qfont.h>
+#include <QtCore/qsharedpointer.h>
#ifndef QT_INCLUDE_COMPAT
#include <QtCore/qrect.h>
#endif
@@ -131,7 +132,7 @@ private:
friend class QFontMetricsF;
friend class QStackTextEngine;
- QFontPrivate *d;
+ QExplicitlySharedDataPointer<QFontPrivate> d;
};
@@ -187,7 +188,7 @@ public:
inline bool operator !=(const QFontMetricsF &other) const { return !operator==(other); }
private:
- QFontPrivate *d;
+ QExplicitlySharedDataPointer<QFontPrivate> d;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index ee8b751472..be79773518 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -55,6 +55,7 @@
#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"
@@ -126,6 +127,7 @@ QTextControlPrivate::QTextControlPrivate()
#endif
isEnabled(true),
hadSelectionOnMousePress(false),
+ ignoreUnusedNavigationEvents(false),
openExternalLinks(false)
{}
@@ -264,19 +266,25 @@ bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
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();
- }
-#ifdef QT_KEYPAD_NAVIGATION
- else if (QApplication::keypadNavigationEnabled()
- && ((e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)
- || QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
- && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))) {
+ } else if (ignoreNavigationEvents && isNavigationEvent) {
return false;
}
-#endif
selectionChanged(/*forceEmitSelectionChanged =*/(mode == QTextCursor::KeepAnchor));
@@ -911,7 +919,7 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
break;
case QEvent::MouseButtonPress: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+ d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
ev->buttons(), ev->globalPos());
break; }
case QEvent::MouseMove: {
@@ -979,7 +987,7 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMousePress: {
QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+ d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
ev->screenPos());
break; }
case QEvent::GraphicsSceneMouseMove: {
@@ -1296,7 +1304,9 @@ QVariant QTextControl::loadResource(int type, const QUrl &name)
void QTextControlPrivate::_q_updateBlock(const QTextBlock &block)
{
Q_Q(QTextControl);
- emit q->updateRequest(q->blockBoundingRect(block));
+ QRectF br = q->blockBoundingRect(block);
+ br.setRight(qreal(INT_MAX)); // the block might have shrunk
+ emit q->updateRequest(br);
}
QRectF QTextControlPrivate::rectForPosition(int position) const
@@ -1465,7 +1475,7 @@ QRectF QTextControl::selectionRect() const
return selectionRect(d->cursor);
}
-void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
+void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
Qt::MouseButtons buttons, const QPoint &globalPos)
{
Q_Q(QTextControl);
@@ -1479,11 +1489,11 @@ void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF
cursor.clearSelection();
}
}
- if (!(button & Qt::LeftButton))
- return;
-
- if (!((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable)))
- return;
+ if (!(button & Qt::LeftButton) ||
+ !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) {
+ e->ignore();
+ return;
+ }
cursorIsFocusIndicator = false;
const QTextCursor oldSelection = cursor;
@@ -1507,8 +1517,10 @@ void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF
trippleClickTimer.stop();
} else {
int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
- if (cursorPos == -1)
+ if (cursorPos == -1) {
+ e->ignore();
return;
+ }
#if !defined(QT_NO_IM)
QTextLayout *layout = cursor.block().layout();
@@ -1519,8 +1531,10 @@ void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF
button, buttons, modifiers);
ctx->mouseHandler(cursorPos - cursor.position(), &ev);
}
- if (!layout->preeditAreaText().isEmpty())
+ if (!layout->preeditAreaText().isEmpty()) {
+ e->ignore();
return;
+ }
}
#endif
if (modifiers == Qt::ShiftModifier) {
@@ -1619,9 +1633,11 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF
if (cursor.position() != oldCursorPos)
emit q->cursorPositionChanged();
_q_updateCurrentCharFormatAndSelection();
+#ifndef QT_NO_IM
if (QInputContext *ic = inputContext()) {
ic->update();
}
+#endif //QT_NO_IM
} else {
//emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
if (cursor.position() != oldCursorPos)
@@ -1829,7 +1845,8 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
e->ignore();
return;
}
- bool isGettingInput = !e->commitString().isEmpty() || !e->preeditString().isEmpty()
+ bool isGettingInput = !e->commitString().isEmpty()
+ || e->preeditString() != cursor.block().layout()->preeditAreaText()
|| e->replacementLength() > 0;
if (isGettingInput) {
@@ -2254,6 +2271,18 @@ bool QTextControl::openExternalLinks() const
return d->openExternalLinks;
}
+bool QTextControl::ignoreUnusedNavigationEvents() const
+{
+ Q_D(const QTextControl);
+ return d->ignoreUnusedNavigationEvents;
+}
+
+void QTextControl::setIgnoreUnusedNavigationEvents(bool ignore)
+{
+ Q_D(QTextControl);
+ d->ignoreUnusedNavigationEvents = ignore;
+}
+
void QTextControl::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode)
{
Q_D(QTextControl);
@@ -2310,6 +2339,9 @@ void QTextControl::print(QPrinter *printer) const
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;
diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h
index 263af3194e..bc8e063f76 100644
--- a/src/gui/text/qtextcontrol_p.h
+++ b/src/gui/text/qtextcontrol_p.h
@@ -95,6 +95,7 @@ class Q_GUI_EXPORT QTextControl : public QObject
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 QTextControl(QObject *parent = 0);
explicit QTextControl(const QString &text, QObject *parent = 0);
@@ -163,6 +164,9 @@ public:
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;
diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h
index ca9db9f9d3..c2305122b2 100644
--- a/src/gui/text/qtextcontrol_p_p.h
+++ b/src/gui/text/qtextcontrol_p_p.h
@@ -131,10 +131,10 @@ public:
QString anchorForCursor(const QTextCursor &anchor) const;
void keyPressEvent(QKeyEvent *e);
- void mousePressEvent(Qt::MouseButton button, const QPointF &pos,
+ void mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
Qt::KeyboardModifiers modifiers,
Qt::MouseButtons buttons,
- const QPoint &globalPos = QPoint());
+ const QPoint &globalPos);
void mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &pos);
void mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos);
void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos);
@@ -206,6 +206,7 @@ public:
QString anchorOnMousePress;
bool hadSelectionOnMousePress;
+ bool ignoreUnusedNavigationEvents;
bool openExternalLinks;
QString linkToCopy;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index a8956b8338..048325c036 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -64,6 +64,7 @@
#include "qtextdocument_p.h"
#include <private/qprinter_p.h>
+#include <private/qabstracttextdocumentlayout_p.h>
#include <limits.h>
@@ -140,7 +141,7 @@ bool Qt::mightBeRichText(const QString& text)
/*!
Converts the plain text string \a plain to a HTML string with
- HTML metacharacters \c{<}, \c{>}, and \c{&} replaced by HTML
+ HTML metacharacters \c{<}, \c{>}, \c{&}, and \c{"} replaced by HTML
entities.
Example:
@@ -162,6 +163,8 @@ QString Qt::escape(const QString& plain)
rich += QLatin1String("&gt;");
else if (plain.at(i) == QLatin1Char('&'))
rich += QLatin1String("&amp;");
+ else if (plain.at(i) == QLatin1Char('"'))
+ rich += QLatin1String("&quot;");
else
rich += plain.at(i);
}
@@ -956,6 +959,8 @@ QString QTextDocument::defaultStyleSheet() const
/*!
Returns true if undo is available; otherwise returns false.
+
+ \sa isRedoAvailable(), availableUndoSteps()
*/
bool QTextDocument::isUndoAvailable() const
{
@@ -965,6 +970,8 @@ bool QTextDocument::isUndoAvailable() const
/*!
Returns true if redo is available; otherwise returns false.
+
+ \sa isUndoAvailable(), availableRedoSteps()
*/
bool QTextDocument::isRedoAvailable() const
{
@@ -972,6 +979,29 @@ bool QTextDocument::isRedoAvailable() const
return d->isRedoAvailable();
}
+/*! \since 4.6
+
+ Returns the number of available undo steps.
+
+ \sa isUndoAvailable()
+*/
+int QTextDocument::availableUndoSteps() const
+{
+ Q_D(const QTextDocument);
+ return d->availableUndoSteps();
+}
+
+/*! \since 4.6
+
+ Returns the number of available redo steps.
+
+ \sa isRedoAvailable()
+*/
+int QTextDocument::availableRedoSteps() const
+{
+ Q_D(const QTextDocument);
+ return d->availableRedoSteps();
+}
/*! \since 4.4
@@ -1693,6 +1723,9 @@ void QTextDocument::print(QPrinter *printer) const
QAbstractTextDocumentLayout *layout = doc->documentLayout();
layout->setPaintDevice(p.device());
+ // copy the custom object handlers
+ layout->d_func()->handlers = documentLayout()->d_func()->handlers;
+
int dpiy = p.device()->logicalDpiY();
int margin = 0;
if (printer->fullPage() && !printer->d_func()->hasCustomPageMargins) {
@@ -2038,7 +2071,7 @@ void QTextHtmlExporter::emitAttribute(const char *attribute, const QString &valu
html += QLatin1Char(' ');
html += QLatin1String(attribute);
html += QLatin1String("=\"");
- html += value;
+ html += Qt::escape(value);
html += QLatin1Char('"');
}
@@ -2302,12 +2335,12 @@ void QTextHtmlExporter::emitFontFamily(const QString &family)
{
html += QLatin1String(" font-family:");
- QLatin1Char quote('\'');
- if (family.contains(quote))
- quote = QLatin1Char('\"');
+ QLatin1String quote("\'");
+ if (family.contains(QLatin1Char('\'')))
+ quote = QLatin1String("&quot;");
html += quote;
- html += family;
+ html += Qt::escape(family);
html += quote;
html += QLatin1Char(';');
}
@@ -2341,13 +2374,13 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment)
const QString name = format.anchorName();
if (!name.isEmpty()) {
html += QLatin1String("<a name=\"");
- html += name;
+ html += Qt::escape(name);
html += QLatin1String("\"></a>");
}
const QString href = format.anchorHref();
if (!href.isEmpty()) {
html += QLatin1String("<a href=\"");
- html += href;
+ html += Qt::escape(href);
html += QLatin1String("\">");
closeAnchor = true;
}
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index e52716af65..d217a4dfb9 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -142,6 +142,9 @@ public:
bool isUndoAvailable() const;
bool isRedoAvailable() const;
+ int availableUndoSteps() const;
+ int availableRedoSteps() const;
+
int revision() const;
void setDocumentLayout(QAbstractTextDocumentLayout *layout);
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 2ad65127ec..18e1ffc989 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -1114,9 +1114,11 @@ void QTextDocumentPrivate::endEditBlock()
return;
if (undoEnabled && undoState > 0) {
+ const bool wasBlocking = !undoStack[undoState - 1].block_end;
if (undoStack[undoState - 1].block_part) {
undoStack[undoState - 1].block_end = true;
- emit document()->undoCommandAdded();
+ if (wasBlocking)
+ emit document()->undoCommandAdded();
}
}
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index ce25c5772d..c10855bcff 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -212,6 +212,9 @@ public:
inline bool isUndoAvailable() const { return undoEnabled && undoState > 0; }
inline bool isRedoAvailable() const { return undoEnabled && undoState < undoStack.size(); }
+ inline int availableUndoSteps() const { return undoEnabled ? undoState : 0; }
+ inline int availableRedoSteps() const { return undoEnabled ? qMax(undoStack.size() - undoState - 1, 0) : 0; }
+
inline QString buffer() const { return text; }
QString plainText() const;
inline int length() const { return fragments.length(); }
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index de83d39ac3..2604879e5e 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -1437,7 +1437,9 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
option.setTextDirection(dir);
layout.setTextOption(option);
layout.beginLayout();
- layout.createLine();
+ QTextLine line = layout.createLine();
+ if (line.isValid())
+ line.setLeadingIncluded(true);
layout.endLayout();
layout.draw(painter, QPointF(r.left(), pos.y()));
break;
@@ -1446,13 +1448,13 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
painter->fillRect(r, brush);
break;
case QTextListFormat::ListCircle:
- painter->drawEllipse(r);
+ painter->setPen(QPen(brush, 0));
+ painter->drawEllipse(r.translated(0.5, 0.5)); // pixel align for sharper rendering
break;
case QTextListFormat::ListDisc:
painter->setBrush(brush);
painter->setPen(Qt::NoPen);
painter->drawEllipse(r);
- painter->setBrush(Qt::NoBrush);
break;
case QTextListFormat::ListStyleUndefined:
break;
@@ -2579,6 +2581,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
QTextLine line = tl->createLine();
if (!line.isValid())
break;
+ line.setLeadingIncluded(true);
QFixed left, right;
floatMargins(layoutStruct->y, layoutStruct, &left, &right);
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 81c9142fc8..a91408f014 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1042,7 +1042,7 @@ void QTextEngine::shapeTextWithCE(int item) const
QScriptItem &si = layoutData->items[item];
si.glyph_data_offset = layoutData->used;
- QFontEngine *fe = fontEngine(si, &si.ascent, &si.descent);
+ QFontEngine *fe = fontEngine(si, &si.ascent, &si.descent, &si.leading);
QTextEngine::ShaperFlags flags;
if (si.analysis.bidiLevel % 2)
@@ -1119,7 +1119,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
si.glyph_data_offset = layoutData->used;
- QFontEngine *font = fontEngine(si, &si.ascent, &si.descent);
+ QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
bool kerningEnabled = this->font(si).d->kerning;
@@ -1350,8 +1350,11 @@ void QTextEngine::shape(int item) const
layoutData->items[item].position + block.position(), format);
}
} else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) {
- // set up at least the ascent/descent of the script item for the tab
- fontEngine(layoutData->items[item], &layoutData->items[item].ascent, &layoutData->items[item].descent);
+ // set up at least the ascent/descent/leading of the script item for the tab
+ fontEngine(layoutData->items[item],
+ &layoutData->items[item].ascent,
+ &layoutData->items[item].descent,
+ &layoutData->items[item].leading);
} else {
shapeText(item);
}
@@ -1737,7 +1740,7 @@ QFont QTextEngine::font(const QScriptItem &si) const
return font;
}
-QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent) const
+QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent, QFixed *leading) const
{
QFontEngine *engine = 0;
QFontEngine *scaledEngine = 0;
@@ -1777,6 +1780,7 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
if (ascent) {
*ascent = engine->ascent();
*descent = engine->descent();
+ *leading = engine->leading();
}
if (scaledEngine)
@@ -2009,8 +2013,12 @@ void QScriptLine::setDefaultHeight(QTextEngine *eng)
e = eng->fnt.d->engineForScript(QUnicodeTables::Common);
}
- ascent = qMax(ascent, e->ascent());
- descent = qMax(descent, e->descent());
+ QFixed other_ascent = e->ascent();
+ QFixed other_descent = e->descent();
+ QFixed other_leading = e->leading();
+ leading = qMax(leading + ascent, other_leading + other_ascent) - qMax(ascent, other_ascent);
+ ascent = qMax(ascent, other_ascent);
+ descent = qMax(descent, other_descent);
}
QTextEngine::LayoutData::LayoutData()
diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp
index 4f20094303..54be53b053 100644
--- a/src/gui/text/qtextengine_mac.cpp
+++ b/src/gui/text/qtextengine_mac.cpp
@@ -50,7 +50,6 @@ static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayou
{
// ### zeroWidth and justification are missing here!!!!!
- Q_ASSERT(num_glyphs <= length);
Q_UNUSED(num_glyphs);
// qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);
@@ -558,7 +557,7 @@ void QTextEngine::shapeTextMac(int item) const
si.glyph_data_offset = layoutData->used;
- QFontEngine *font = fontEngine(si, &si.ascent, &si.descent);
+ QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
if (font->type() != QFontEngine::Multi) {
shapeTextWithHarfbuzz(item);
return;
@@ -595,53 +594,50 @@ void QTextEngine::shapeTextMac(int item) const
str = reinterpret_cast<const QChar *>(uc);
}
- while (true) {
- ensureSpace(num_glyphs);
- num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
-
- QGlyphLayout g = availableGlyphs(&si);
- g.numGlyphs = num_glyphs;
- unsigned short *log_clusters = logClusters(&si);
-
- if (fe->stringToCMap(str,
- len,
- &g,
- &num_glyphs,
- flags,
- log_clusters,
- attributes())) {
-
- heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
- break;
- }
+ ensureSpace(num_glyphs);
+ num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
+
+ QGlyphLayout g = availableGlyphs(&si);
+ g.numGlyphs = num_glyphs;
+ unsigned short *log_clusters = logClusters(&si);
+
+ bool stringToCMapFailed = false;
+ if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
+ ensureSpace(num_glyphs);
+ stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
+ attributes());
}
- si.num_glyphs = num_glyphs;
+ if (!stringToCMapFailed) {
+ heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
- layoutData->used += si.num_glyphs;
+ si.num_glyphs = num_glyphs;
- QGlyphLayout g = shapedGlyphs(&si);
+ layoutData->used += si.num_glyphs;
- if (si.analysis.script == QUnicodeTables::Arabic) {
- QVarLengthArray<QArabicProperties> props(len + 2);
- QArabicProperties *properties = props.data();
- int f = si.position;
- int l = len;
- if (f > 0) {
- --f;
- ++l;
- ++properties;
- }
- if (f + l < layoutData->string.length()) {
- ++l;
- }
- qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
+ QGlyphLayout g = shapedGlyphs(&si);
- unsigned short *log_clusters = logClusters(&si);
+ if (si.analysis.script == QUnicodeTables::Arabic) {
+ QVarLengthArray<QArabicProperties> props(len + 2);
+ QArabicProperties *properties = props.data();
+ int f = si.position;
+ int l = len;
+ if (f > 0) {
+ --f;
+ ++l;
+ ++properties;
+ }
+ if (f + l < layoutData->string.length()) {
+ ++l;
+ }
+ qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
- for (int i = 0; i < len; ++i) {
- int gpos = log_clusters[i];
- g.attributes[gpos].justification = properties[i].justification;
+ unsigned short *log_clusters = logClusters(&si);
+
+ for (int i = 0; i < len; ++i) {
+ int gpos = log_clusters[i];
+ g.attributes[gpos].justification = properties[i].justification;
+ }
}
}
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 85c6928c4f..a1d363be73 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -345,11 +345,11 @@ struct Q_AUTOTEST_EXPORT QScriptItem
{
inline QScriptItem()
: position(0),
- num_glyphs(0), descent(-1), ascent(-1), width(-1),
+ num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1),
glyph_data_offset(0) {}
inline QScriptItem(int p, const QScriptAnalysis &a)
: position(p), analysis(a),
- num_glyphs(0), descent(-1), ascent(-1), width(-1),
+ num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1),
glyph_data_offset(0) {}
int position;
@@ -357,6 +357,7 @@ struct Q_AUTOTEST_EXPORT QScriptItem
unsigned short num_glyphs;
QFixed descent;
QFixed ascent;
+ QFixed leading;
QFixed width;
int glyph_data_offset;
QFixed height() const { return ascent + descent + 1; }
@@ -373,9 +374,10 @@ struct Q_AUTOTEST_EXPORT QScriptLine
QScriptLine()
: from(0), length(0),
justified(0), gridfitted(0),
- hasTrailingSpaces(0) {}
+ hasTrailingSpaces(0), leadingIncluded(0) {}
QFixed descent;
QFixed ascent;
+ QFixed leading;
QFixed x;
QFixed y;
QFixed width;
@@ -385,7 +387,11 @@ struct Q_AUTOTEST_EXPORT QScriptLine
mutable uint justified : 1;
mutable uint gridfitted : 1;
uint hasTrailingSpaces : 1;
- QFixed height() const { return ascent + descent + 1; }
+ uint leadingIncluded : 1;
+ QFixed height() const { return ascent + descent + 1
+ + (leadingIncluded? qMax(QFixed(),leading) : QFixed()); }
+ QFixed base() const { return ascent
+ + (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); }
void setDefaultHeight(QTextEngine *eng);
void operator+=(const QScriptLine &other);
};
@@ -394,6 +400,7 @@ Q_DECLARE_TYPEINFO(QScriptLine, Q_PRIMITIVE_TYPE);
inline void QScriptLine::operator+=(const QScriptLine &other)
{
+ leading= qMax(leading + ascent, other.leading + other.ascent) - qMax(ascent, other.ascent);
descent = qMax(descent, other.descent);
ascent = qMax(ascent, other.ascent);
textWidth += other.textWidth;
@@ -476,7 +483,7 @@ public:
return end - si->position;
}
- QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = 0, QFixed *descent = 0) const;
+ QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = 0, QFixed *descent = 0, QFixed *leading = 0) const;
QFont font(const QScriptItem &si) const;
inline QFont font() const { return fnt; }
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index d05d9e584d..deda39fe9c 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -265,21 +265,55 @@ private:
friend QDataStream &operator>>(QDataStream &, QTextFormat &);
};
-static uint variantHash(const QVariant &variant)
+// this is only safe if sizeof(int) == sizeof(float)
+static inline uint hash(float d)
{
- switch (variant.userType()) {
- case QVariant::Invalid: return 0;
- case QVariant::Bool: return variant.toBool();
- case QVariant::Int: return variant.toInt();
- case QMetaType::Float: return static_cast<int>(variant.toFloat());
- case QVariant::Double: return static_cast<int>(variant.toDouble());
+ return reinterpret_cast<uint&>(d);
+}
+
+static inline uint hash(const QColor &color)
+{
+ return (color.isValid()) ? color.rgba() : 0x234109;
+}
+
+static inline uint hash(const QPen &pen)
+{
+ return hash(pen.color()) + hash(pen.widthF());
+}
+
+static inline uint hash(const QBrush &brush)
+{
+ return hash(brush.color()) + (brush.style() << 3);
+}
+
+static inline uint variantHash(const QVariant &variant)
+{
+ // simple and fast hash functions to differentiate between type and value
+ switch (variant.userType()) { // sorted by occurrence frequency
case QVariant::String: return qHash(variant.toString());
- case QVariant::Color: return qHash(qvariant_cast<QColor>(variant).rgb());
+ case QVariant::Double: return hash(variant.toDouble());
+ case QVariant::Int: return 0x811890 + variant.toInt();
+ case QVariant::Brush:
+ return 0x01010101 + hash(qvariant_cast<QBrush>(variant));
+ case QVariant::Bool: return 0x371818 + variant.toBool();
+ case QVariant::Pen: return 0x02020202 + hash(qvariant_cast<QPen>(variant));
+ case QVariant::List:
+ return 0x8377 + qvariant_cast<QVariantList>(variant).count();
+ case QVariant::Color: return hash(qvariant_cast<QColor>(variant));
+ case QVariant::TextLength:
+ return 0x377 + hash(qvariant_cast<QTextLength>(variant).rawValue());
+ case QMetaType::Float: return hash(variant.toFloat());
+ case QVariant::Invalid: return 0;
default: break;
}
return qHash(variant.typeName());
}
+static inline int getHash(const QTextFormatPrivate *d, int format)
+{
+ return (d ? d->hash() : 0) + format;
+}
+
uint QTextFormatPrivate::recalcHash() const
{
hashValue = 0;
@@ -3033,13 +3067,15 @@ QTextFormatCollection::~QTextFormatCollection()
int QTextFormatCollection::indexForFormat(const QTextFormat &format)
{
- uint hash = format.d ? format.d->hash() : 0;
- if (hashes.contains(hash)) {
- for (int i = 0; i < formats.size(); ++i) {
- if (formats.at(i) == format)
- return i;
+ uint hash = getHash(format.d, format.format_type);
+ QMultiHash<uint, int>::const_iterator i = hashes.find(hash);
+ while (i != hashes.end() && i.key() == hash) {
+ if (formats.value(i.value()) == format) {
+ return i.value();
}
+ ++i;
}
+
int idx = formats.size();
formats.append(format);
@@ -3049,7 +3085,7 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format)
f.d = new QTextFormatPrivate;
f.d->resolveFont(defaultFnt);
- hashes.insert(hash);
+ hashes.insert(hash, idx);
} QT_CATCH(...) {
formats.pop_back();
@@ -3060,11 +3096,13 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format)
bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const
{
- uint hash = format.d ? format.d->hash() : 0;
- if (hashes.contains(hash)) {
- for (int i = 0; i < formats.size(); ++i)
- if (formats.at(i) == format)
- return true;
+ uint hash = getHash(format.d, format.format_type);
+ QMultiHash<uint, int>::const_iterator i = hashes.find(hash);
+ while (i != hashes.end() && i.key() == hash) {
+ if (formats.value(i.value()) == format) {
+ return true;
+ }
+ ++i;
}
return false;
}
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index c796343df2..73ca0ce73d 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -55,7 +55,7 @@
#include "QtGui/qtextformat.h"
#include "QtCore/qvector.h"
-#include "QtCore/qset.h"
+#include "QtCore/qhash.h"
QT_BEGIN_NAMESPACE
@@ -97,7 +97,7 @@ public:
FormatVector formats;
QVector<qint32> objFormats;
- QSet<uint> hashes;
+ QMultiHash<uint,int> hashes;
inline QFont defaultFont() const { return defaultFnt; }
void setDefaultFont(const QFont &f);
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index c5f0e35c61..4600a291d9 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -860,7 +860,7 @@ QRectF QTextLayout::boundingRect() const
ymin = qMin(ymin, si.y);
xmax = qMax(xmax, si.x+qMax(si.width, si.textWidth));
// ### shouldn't the ascent be used in ymin???
- ymax = qMax(ymax, si.y+si.ascent+si.descent+1);
+ ymax = qMax(ymax, si.y+si.height());
}
return QRectF(xmin.toReal(), ymin.toReal(), (xmax-xmin).toReal(), (ymax-ymin).toReal());
}
@@ -1071,10 +1071,10 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo
QTextLineItemIterator iterator(eng, lineNumber, pos, selection);
- const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent;
+
+ const qreal selectionY = pos.y() + line.y.toReal();
const qreal lineHeight = line.height().toReal();
- const qreal selectionY = (y - line.ascent).toReal();
QFixed lastSelectionX = iterator.x;
QFixed lastSelectionWidth;
@@ -1334,23 +1334,23 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
const qreal x = position.x() + l.cursorToX(cursorPosition);
int itm = d->findItem(cursorPosition - 1);
- QFixed ascent = sl.ascent;
+ QFixed base = sl.base();
QFixed descent = sl.descent;
bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft);
if (itm >= 0) {
const QScriptItem &si = d->layoutData->items.at(itm);
if (si.ascent > 0)
- ascent = si.ascent;
+ base = si.ascent;
if (si.descent > 0)
descent = si.descent;
rightToLeft = si.analysis.bidiLevel % 2;
}
- qreal y = position.y() + (sl.y + sl.ascent - ascent).toReal();
+ qreal y = position.y() + (sl.y + sl.base() - base).toReal();
bool toggleAntialiasing = !(p->renderHints() & QPainter::Antialiasing)
&& (p->transform().type() > QTransform::TxTranslate);
if (toggleAntialiasing)
p->setRenderHint(QPainter::Antialiasing);
- p->fillRect(QRectF(x, y, qreal(width), (ascent + descent).toReal()), p->pen().brush());
+ p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush());
if (toggleAntialiasing)
p->setRenderHint(QPainter::Antialiasing, false);
if (d->layoutData->hasBidi) {
@@ -1500,9 +1500,11 @@ qreal QTextLine::descent() const
}
/*!
- Returns the line's height. This is equal to ascent() + descent() + 1.
+ Returns the line's height. This is equal to ascent() + descent() + 1
+ if leading is not included. If leading is included, this equals to
+ ascent() + descent() + leading() + 1.
- \sa ascent() descent()
+ \sa ascent() descent() leading() setLeadingIncluded()
*/
qreal QTextLine::height() const
{
@@ -1510,6 +1512,51 @@ qreal QTextLine::height() const
}
/*!
+ \since 4.6
+
+ Returns the line's leading.
+
+ \sa ascent() descent() height()
+*/
+qreal QTextLine::leading() const
+{
+ return eng->lines[i].leading.toReal();
+}
+
+/*! \since 4.6
+
+ Includes positive leading into the line's height if \a included is true;
+ otherwise does not include leading.
+
+ By default, leading is not included.
+
+ Note that negative leading is ignored, it must be handled
+ in the code using the text lines by letting the lines overlap.
+
+ \sa leadingIncluded()
+
+*/
+void QTextLine::setLeadingIncluded(bool included)
+{
+ eng->lines[i].leadingIncluded= included;
+
+}
+
+/*! \since 4.6
+
+ Returns true if positive leading is included into the line's height; otherwise returns false.
+
+ By default, leading is not included.
+
+ \sa setLeadingIncluded()
+*/
+bool QTextLine::leadingIncluded() const
+{
+ return eng->lines[i].leadingIncluded;
+}
+
+
+/*!
Returns the width of the line that is occupied by text. This is
always \<= to width(), and is the minimum width that could be used
by layout() without changing the line break position.
@@ -1712,6 +1759,9 @@ void QTextLine::layout_helper(int maxGlyphs)
}
const QScriptItem &current = eng->layoutData->items[item];
+ lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
+ current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
+ current.ascent);
lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
@@ -2042,7 +2092,9 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
QTextLineItemIterator iterator(eng, i, pos, selection);
- const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent;
+ QFixed lineBase = line.base();
+
+ const QFixed y = QFixed::fromReal(pos.y()) + line.y + lineBase;
bool suppressColors = (eng->option.flags() & QTextOption::SuppressColors);
while (!iterator.atEnd()) {
@@ -2065,7 +2117,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
if (selection)
format.merge(selection->format);
- setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - line.ascent).toReal(),
+ setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - lineBase).toReal(),
iterator.itemWidth.toReal(), line.height().toReal()));
QTextCharFormat::VerticalAlignment valign = format.verticalAlignment();
@@ -2086,7 +2138,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
if (si.analysis.flags == QScriptAnalysis::Object && eng->block.docHandle()) {
QFixed itemY = y - si.ascent;
if (format.verticalAlignment() == QTextCharFormat::AlignTop) {
- itemY = y - line.ascent;
+ itemY = y - lineBase;
}
QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal());
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index 90afac8d6f..9f170f50c5 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -196,6 +196,10 @@ public:
qreal ascent() const;
qreal descent() const;
qreal height() const;
+ qreal leading() const;
+
+ void setLeadingIncluded(bool included);
+ bool leadingIncluded() const;
qreal naturalTextWidth() const;
QRectF naturalTextRect() const;
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index 2375f08ae1..a6b50847a0 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -78,6 +78,7 @@ win32 {
unix:x11 {
HEADERS += \
text/qfontengine_x11_p.h \
+ text/qfontdatabase_x11.cpp \
text/qfontengine_ft_p.h
SOURCES += \
text/qfont_x11.cpp \
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index edeabf5694..835b33f915 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -293,17 +293,6 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme)
have desktop concept, DesktopLocation returns same path as DocumentsLocation.
Rest of the standard locations point to folder on same drive with executable, except
that if executable is in ROM the folder from C drive is returned.
-
- \note On Mac OS X, DataLocation does not include QCoreApplication::organizationName.
- Use code like this to add it:
-
- \code
- QString location = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
- #ifdef Q_WS_MAC
- location.insert(location.count() - QCoreApplication::applicationName().count(),
- QCoreApplication::organizationName() + "/");
- #endif
- \endcode
*/
/*!
diff --git a/src/gui/util/qdesktopservices_mac.cpp b/src/gui/util/qdesktopservices_mac.cpp
index 0626e0a8b3..23f9e60d62 100644
--- a/src/gui/util/qdesktopservices_mac.cpp
+++ b/src/gui/util/qdesktopservices_mac.cpp
@@ -153,9 +153,12 @@ QString QDesktopServices::storageLocation(StandardLocation type)
QString path = getFullPath(ref);
- QString appName = QCoreApplication::applicationName();
- if (!appName.isEmpty() && (type == DataLocation || type == CacheLocation))
- path += QLatin1Char('/') + appName;
+ if (type == DataLocation || type == CacheLocation) {
+ if (QCoreApplication::organizationName().isEmpty() == false)
+ path += QLatin1Char('/') + QCoreApplication::organizationName();
+ if (QCoreApplication::applicationName().isEmpty() == false)
+ path += QLatin1Char('/') + QCoreApplication::applicationName();
+ }
return path;
}
diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp
index fd06cf3135..1890d569ce 100644
--- a/src/gui/util/qdesktopservices_s60.cpp
+++ b/src/gui/util/qdesktopservices_s60.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtGui of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 08962567d2..35639b705e 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -51,6 +51,7 @@
#include "qdebug.h"
#include "qboxlayout.h"
#include "qpainter.h"
+#include "qmargins.h"
#include "qabstractscrollarea_p.h"
#include <qwidget.h>
@@ -293,13 +294,16 @@ void QAbstractScrollAreaPrivate::init()
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
+ viewport->grabGesture(Qt::PanGesture);
}
#ifdef Q_WS_WIN
void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
{
singleFingerPanEnabled = on;
- winSetupGestures();
+ QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
+ if (dd)
+ dd->winSetupGestures();
}
#endif // Q_WS_WIN
@@ -539,6 +543,7 @@ void QAbstractScrollArea::setViewport(QWidget *widget)
d->viewport->setParent(this);
d->viewport->setFocusProxy(this);
d->viewport->installEventFilter(d->viewportFilter.data());
+ d->viewport->grabGesture(Qt::PanGesture);
d->layoutChildren();
if (isVisible())
d->viewport->show();
@@ -864,6 +869,22 @@ void QAbstractScrollArea::setViewportMargins(int left, int top, int right, int b
}
/*!
+ \since 4.6
+ Sets \a margins around the scrolling area. This is useful for
+ applications such as spreadsheets with "locked" rows and columns.
+ The marginal space is is left blank; put widgets in the unused
+ area.
+
+ By default all margins are zero.
+
+*/
+void QAbstractScrollArea::setViewportMargins(const QMargins &margins)
+{
+ setViewportMargins(margins.left(), margins.top(),
+ margins.right(), margins.bottom());
+}
+
+/*!
\fn bool QAbstractScrollArea::event(QEvent *event)
\reimp
@@ -935,6 +956,26 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
return false;
+ case 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();
+ QPointF delta = g->delta();
+ if (!delta.isNull()) {
+ if (QApplication::isRightToLeft())
+ delta.rx() *= -1;
+ int newX = hBar->value() - delta.x();
+ int newY = vBar->value() - delta.y();
+ hBar->setValue(newX);
+ vBar->setValue(newY);
+ }
+ return true;
+ }
+ return false;
+ }
case QEvent::StyleChange:
case QEvent::LayoutDirectionChange:
case QEvent::ApplicationLayoutDirectionChange:
@@ -990,6 +1031,8 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e)
#endif
return QFrame::event(e);
case QEvent::LayoutRequest:
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
return event(e);
default:
break;
@@ -1087,10 +1130,13 @@ void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e)
void QAbstractScrollArea::wheelEvent(QWheelEvent *e)
{
Q_D(QAbstractScrollArea);
- if (static_cast<QWheelEvent*>(e)->orientation() == Qt::Horizontal)
- QApplication::sendEvent(d->hbar, e);
- else
- QApplication::sendEvent(d->vbar, e);
+ QScrollBar *const bars[2] = { d->hbar, d->vbar };
+ int idx = (e->orientation() == Qt::Vertical) ? 1 : 0;
+ int other = (idx + 1) % 2;
+ if (!bars[idx]->isVisible() && bars[other]->isVisible())
+ idx = other; // If the scrollbar of the event orientation is hidden, fallback to the other.
+
+ QApplication::sendEvent(bars[idx], e);
}
#endif
@@ -1266,11 +1312,13 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y)
void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
{
layoutChildren();
-#ifdef Q_OS_WIN
+#ifdef Q_WS_WIN
// Need to re-subscribe to gestures as the content changes to make sure we
// enable/disable panning when needed.
- winSetupGestures();
-#endif // Q_OS_WIN
+ QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
+ if (dd)
+ dd->winSetupGestures();
+#endif // Q_WS_WIN
}
QPoint QAbstractScrollAreaPrivate::contentsOffset() const
@@ -1335,25 +1383,6 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
-//void QAbstractScrollAreaPrivate::_q_gestureTriggered()
-//{
-// Q_Q(QAbstractScrollArea);
-// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
-// if (!g)
-// return;
-// QScrollBar *hBar = q->horizontalScrollBar();
-// QScrollBar *vBar = q->verticalScrollBar();
-// QSizeF delta = g->lastOffset();
-// if (!delta.isNull()) {
-// if (QApplication::isRightToLeft())
-// delta.rwidth() *= -1;
-// int newX = hBar->value() - delta.width();
-// int newY = vBar->value() - delta.height();
-// hbar->setValue(newX);
-// vbar->setValue(newY);
-// }
-//}
-
QT_END_NAMESPACE
#include "moc_qabstractscrollarea.cpp"
diff --git a/src/gui/widgets/qabstractscrollarea.h b/src/gui/widgets/qabstractscrollarea.h
index b3a18616c6..18d1e96e62 100644
--- a/src/gui/widgets/qabstractscrollarea.h
+++ b/src/gui/widgets/qabstractscrollarea.h
@@ -52,6 +52,7 @@ QT_MODULE(Gui)
#ifndef QT_NO_SCROLLAREA
+class QMargins;
class QScrollBar;
class QAbstractScrollAreaPrivate;
@@ -95,6 +96,7 @@ protected Q_SLOTS:
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 *);
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index 588a48ee8a..e0db9c29e2 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -690,32 +690,28 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
{
Q_D(QAbstractSlider);
e->ignore();
- if (e->orientation() != d->orientation && !rect().contains(e->pos()))
- return;
- qreal currentOffset = qreal(e->delta()) / 120;
- d->offset_accumulated += currentOffset;
- if (int(d->offset_accumulated) == 0) {
- // QAbstractSlider works on integer values. So if the accumulated
- // offset is less than +/- 1, we need to wait until we get more
- // wheel events (this means that the wheel resolution is higher than
- // 15 degrees, e.g. when using mac mighty mouse/trackpad):
- return;
- }
+ int stepsToScroll = 0;
+ qreal offset = qreal(e->delta()) / 120;
- int stepsToScroll;
if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
- stepsToScroll = currentOffset > 0 ? d->pageStep : -d->pageStep;
+ // Scroll one page regardless of delta:
+ stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep);
+ d->offset_accumulated = 0;
} else {
- // Calculate the number of steps to scroll (per 15 degrees of rotate):
-#ifdef Q_OS_MAC
- // On mac, since mouse wheel scrolling is accelerated and
- // fine tuned by the OS, we skip applying acceleration:
- stepsToScroll = int(d->offset_accumulated);
-#else
- stepsToScroll = int(d->offset_accumulated) * QApplication::wheelScrollLines() * d->singleStep;
-#endif
- stepsToScroll = qBound(-d->pageStep, stepsToScroll, d->pageStep);
+ // Calculate how many lines to scroll. Depending on what delta is (and
+ // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
+ // only scroll whole lines, so we keep the reminder until next event.
+ qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->singleStep;
+ // Check if wheel changed direction since last event:
+ if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0)
+ d->offset_accumulated = 0;
+
+ d->offset_accumulated += stepsToScrollF;
+ stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep);
+ d->offset_accumulated -= int(d->offset_accumulated);
+ if (stepsToScroll == 0)
+ return;
}
if (d->invertedControls)
@@ -725,12 +721,10 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
triggerAction(SliderMove);
- if (prevValue == d->value) {
+ if (prevValue == d->value)
d->offset_accumulated = 0;
- } else {
- d->offset_accumulated -= int(d->offset_accumulated);
+ else
e->accept();
- }
}
#endif
#ifdef QT_KEYPAD_NAVIGATION
diff --git a/src/gui/widgets/qcalendarwidget.cpp b/src/gui/widgets/qcalendarwidget.cpp
index 08ed7f6a22..ee536ee43c 100644
--- a/src/gui/widgets/qcalendarwidget.cpp
+++ b/src/gui/widgets/qcalendarwidget.cpp
@@ -2297,7 +2297,21 @@ int QCalendarWidget::monthShown() const
void QCalendarWidget::setCurrentPage(int year, int month)
{
Q_D(QCalendarWidget);
+ QDate currentDate = d->getCurrentDate();
+ int day = currentDate.day();
+ int daysInMonths = QDate(year, month, 1).daysInMonth();
+ if (day > daysInMonths)
+ day = daysInMonths;
+
d->showMonth(year, month);
+
+ QDate newDate(year, month, day);
+ int row = -1, col = -1;
+ d->m_model->cellForDate(newDate, &row, &col);
+ if (row != -1 && col != -1) {
+ d->m_view->selectionModel()->setCurrentIndex(d->m_model->index(row, col),
+ QItemSelectionModel::NoUpdate);
+ }
}
/*!
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index b60653812c..bd1d8ba1f2 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -192,6 +192,8 @@ void QComboBoxPrivate::_q_modelReset()
lineEdit->setText(QString());
updateLineEditGeometry();
}
+ if (currentIndex.row() != indexBeforeChange)
+ _q_emitCurrentIndexChanged(currentIndex);
q->update();
}
@@ -314,7 +316,7 @@ QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const
// height
- sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
+ sh.setHeight(qMax(fm.height(), 14) + 2);
if (hasIcon) {
sh.setHeight(qMax(sh.height(), iconSize.height() + 2));
}
@@ -402,13 +404,6 @@ QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView
layout->setSpacing(0);
layout->setMargin(0);
-#ifdef QT_SOFTKEYS_ENABLED
- selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, this);
- cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, this);
- addAction(selectAction);
- addAction(cancelAction);
-#endif
-
// set item view
setItemView(itemView);
@@ -494,18 +489,6 @@ void QComboBoxPrivateContainer::viewDestroyed()
}
/*
- Sets currentIndex on entered if the LeftButton is not pressed. This
- means that if mouseTracking(...) is on, we setCurrentIndex and select
- even when LeftButton is not pressed.
-*/
-void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index)
-{
- if (QComboBoxDelegate::isSeparator(index))
- return;
- view->setCurrentIndex(index);
-}
-
-/*
Returns the item view used for the combobox popup.
*/
QAbstractItemView *QComboBoxPrivateContainer::itemView() const
@@ -530,8 +513,6 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
this, SLOT(updateScrollers()));
#endif
- disconnect(view, SIGNAL(entered(QModelIndex)),
- this, SLOT(setCurrentIndex(QModelIndex)));
disconnect(view, SIGNAL(destroyed()),
this, SLOT(viewDestroyed()));
@@ -568,10 +549,15 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
this, SLOT(updateScrollers()));
#endif
- connect(view, SIGNAL(entered(QModelIndex)),
- this, SLOT(setCurrentIndex(QModelIndex)));
connect(view, SIGNAL(destroyed()),
this, SLOT(viewDestroyed()));
+
+#ifdef QT_SOFTKEYS_ENABLED
+ selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, itemView);
+ cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, itemView);
+ addAction(selectAction);
+ addAction(cancelAction);
+#endif
}
/*!
@@ -653,16 +639,20 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
break;
}
break;
- case QEvent::MouseMove: {
+ case QEvent::MouseMove:
if (isVisible()) {
QMouseEvent *m = static_cast<QMouseEvent *>(e);
QWidget *widget = static_cast<QWidget *>(o);
QPoint vector = widget->mapToGlobal(m->pos()) - initialClickPosition;
if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())
blockMouseReleaseTimer.stop();
+ QModelIndex indexUnderMouse = view->indexAt(m->pos());
+ if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex()
+ && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
+ view->setCurrentIndex(indexUnderMouse);
+ }
}
break;
- }
case QEvent::MouseButtonRelease: {
QMouseEvent *m = static_cast<QMouseEvent *>(e);
if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid()
@@ -992,14 +982,6 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn
}
}
-void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent,
- int /*start*/, int /*end*/)
-{
- if (parent != root)
- return;
- indexBeforeChange = currentIndex.row();
-}
-
void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end)
{
Q_Q(QComboBox);
@@ -1022,11 +1004,8 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int
}
}
-void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
+void QComboBoxPrivate::_q_updateIndexBeforeChange()
{
- if (parent != root)
- return;
-
indexBeforeChange = currentIndex.row();
}
@@ -1132,6 +1111,32 @@ void QComboBoxPrivate::updateLineEditGeometry()
lineEdit->setGeometry(editRect);
}
+Qt::MatchFlags QComboBoxPrivate::matchFlags() const
+{
+ // Base how duplicates are determined on the autocompletion case sensitivity
+ Qt::MatchFlags flags = Qt::MatchFixedString;
+#ifndef QT_NO_COMPLETER
+ if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
+#endif
+ flags |= Qt::MatchCaseSensitive;
+ return flags;
+}
+
+
+void QComboBoxPrivate::_q_editingFinished()
+{
+ Q_Q(QComboBox);
+ if (lineEdit && !lineEdit->text().isEmpty()) {
+ //here we just check if the current item was entered
+ const int index = q_func()->findText(lineEdit->text(), matchFlags());
+ if (index != -1 && itemText(currentIndex) != lineEdit->text()) {
+ q->setCurrentIndex(index);
+ emitActivated(currentIndex);
+ }
+ }
+
+}
+
void QComboBoxPrivate::_q_returnPressed()
{
Q_Q(QComboBox);
@@ -1144,13 +1149,7 @@ void QComboBoxPrivate::_q_returnPressed()
// check for duplicates (if not enabled) and quit
int index = -1;
if (!duplicatesEnabled) {
- // Base how duplicates are determined on the autocompletion case sensitivity
- Qt::MatchFlags flags = Qt::MatchFixedString;
-#ifndef QT_NO_COMPLETER
- if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
-#endif
- flags |= Qt::MatchCaseSensitive;
- index = q->findText(text, flags);
+ index = q->findText(text, matchFlags());
if (index != -1) {
q->setCurrentIndex(index);
emitActivated(currentIndex);
@@ -1685,6 +1684,7 @@ void QComboBox::setLineEdit(QLineEdit *edit)
if (d->lineEdit->parent() != this)
d->lineEdit->setParent(this);
connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
+ connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished()));
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString)));
#ifdef QT3_SUPPORT
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
@@ -1868,15 +1868,17 @@ void QComboBox::setModel(QAbstractItemModel *model)
disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(destroyed()),
this, SLOT(_q_modelDestroyed()));
+ disconnect(d->model, SIGNAL(modelAboutToBeReset()),
+ this, SLOT(_q_updateIndexBeforeChange()));
disconnect(d->model, SIGNAL(modelReset()),
this, SLOT(_q_modelReset()));
if (d->model->QObject::parent() == this)
@@ -1888,15 +1890,17 @@ void QComboBox::setModel(QAbstractItemModel *model)
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
connect(model, SIGNAL(destroyed()),
this, SLOT(_q_modelDestroyed()));
+ connect(model, SIGNAL(modelAboutToBeReset()),
+ this, SLOT(_q_updateIndexBeforeChange()));
connect(model, SIGNAL(modelReset()),
this, SLOT(_q_modelReset()));
@@ -1977,7 +1981,7 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
if (lineEdit) {
QString newText = q->itemText(currentIndex.row());
if (lineEdit->text() != newText)
- lineEdit->setText(q->itemText(currentIndex.row()));
+ lineEdit->setText(newText);
updateLineEditGeometry();
}
if (indexChanged) {
@@ -2174,11 +2178,14 @@ void QComboBox::insertSeparator(int index)
/*!
Removes the item at the given \a index from the combobox.
This will update the current index if the index is removed.
+
+ This function does nothing if \a index is out of range.
*/
void QComboBox::removeItem(int index)
{
- Q_ASSERT(index >= 0 && index < count());
Q_D(QComboBox);
+ if (index < 0 || index >= count())
+ return;
d->model->removeRows(index, 1, d->root);
}
@@ -2449,15 +2456,15 @@ void QComboBox::showPopup()
#if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS)
bool scrollDown = (listRect.topLeft() == below);
- if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo)
+ if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo)
&& !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen))
qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150);
#endif
// Don't disable updates on Mac OS X. Windows are displayed immediately on this platform,
// which means that the window will be visible before the call to container->show() returns.
-// If updates are disabled at this point we'll miss our chance at painting the popup
-// menu before it's shown, causing flicker since the window then displays the standard gray
+// If updates are disabled at this point we'll miss our chance at painting the popup
+// menu before it's shown, causing flicker since the window then displays the standard gray
// background.
#ifndef Q_WS_MAC
container->setUpdatesEnabled(false);
diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h
index 6a85096467..5d5ea21287 100644
--- a/src/gui/widgets/qcombobox.h
+++ b/src/gui/widgets/qcombobox.h
@@ -52,7 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-
#ifndef QT_NO_COMBOBOX
class QAbstractItemView;
@@ -305,12 +304,12 @@ private:
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_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end))
+ 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_rowsAboutToBeRemoved(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())
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
index f7458c44b4..f6ba57cd84 100644
--- a/src/gui/widgets/qcombobox_p.h
+++ b/src/gui/widgets/qcombobox_p.h
@@ -231,7 +231,6 @@ public:
public Q_SLOTS:
void scrollItemView(int action);
void updateScrollers();
- void setCurrentIndex(const QModelIndex &index);
void viewDestroyed();
protected:
@@ -343,6 +342,8 @@ public:
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);
@@ -357,9 +358,8 @@ public:
#endif
void _q_resetButton();
void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end);
+ void _q_updateIndexBeforeChange();
void _q_rowsInserted(const QModelIndex & parent, int start, int end);
- void _q_rowsAboutToBeRemoved(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);
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 280ca6340b..2ee5751782 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -315,9 +315,9 @@ void QDialogButtonBoxPrivate::initLayout()
buttonLayout = new QVBoxLayout(q);
}
- int left, top, right, bottom;
+ int left, top, right, bottom;
setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem);
- getLayoutItemMargins(&left, &top, &right, &bottom);
+ getLayoutItemMargins(&left, &top, &right, &bottom);
buttonLayout->setContentsMargins(-left, -top, -right, -bottom);
if (!q->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
@@ -356,7 +356,7 @@ void QDialogButtonBoxPrivate::addButtonsToLayout(const QList<QAbstractButton *>
void QDialogButtonBoxPrivate::layoutButtons()
{
Q_Q(QDialogButtonBox);
- const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
+ 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);
@@ -560,7 +560,7 @@ QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialog
Q_Q(QDialogButtonBox);
QAction::SoftKeyRole softkeyRole;
- QAction *action = new QAction(button->text(), q);
+ QAction *action = new QAction(button->text(), button);
switch (role) {
case ApplyRole:
@@ -581,7 +581,22 @@ QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialog
}
QObject::connect(action, SIGNAL(triggered()), button, SIGNAL(clicked()));
action->setSoftKeyRole(softkeyRole);
- action->setEnabled(button->isEnabled());
+
+
+ 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
@@ -874,6 +889,11 @@ void QDialogButtonBox::setOrientation(Qt::Orientation orientation)
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();
@@ -1026,6 +1046,11 @@ QPushButton *QDialogButtonBox::addButton(StandardButton button)
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();
@@ -1184,12 +1209,8 @@ bool QDialogButtonBox::event(QEvent *event)
if (!hasDefault && firstAcceptButton)
firstAcceptButton->setDefault(true);
#ifdef QT_SOFTKEYS_ENABLED
- if (dialog) {
+ if (dialog)
setFixedSize(0,0);
- dialog->addActions(d->softKeyActions.values());
- } else {
- addActions(d->softKeyActions.values());
- }
#endif
}else if (event->type() == QEvent::LanguageChange) {
d->retranslateStrings();
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index 5a0a9d4815..07914b292f 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -1556,9 +1556,10 @@ void QDockAreaLayoutInfo::apply(bool animate)
}
}
}
-
+#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)
@@ -1840,7 +1841,6 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
}
}
-#ifdef Q_WS_MAC
static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
{
switch (pos) {
@@ -1852,7 +1852,6 @@ static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
}
return Qt::NoDockWidgetArea;
}
-#endif
static QRect constrainedRect(QRect rect, const QRect &desktop)
{
@@ -1969,19 +1968,19 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
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) {
- item_list.append(item);
- }
}
} else if (nextMarker == SequenceMarker) {
int dummy;
@@ -2008,13 +2007,14 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
updateTabBar();
setCurrentTabId(tabId(item_list.at(index)));
}
-#endif
if (!testing && sep == 1)
updateSeparatorWidgets();
+#endif
return true;
}
+#ifndef QT_NO_TABBAR
void QDockAreaLayoutInfo::updateSeparatorWidgets() const
{
if (tabbed) {
@@ -2065,6 +2065,7 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const
separatorWidgets.resize(j);
Q_ASSERT(separatorWidgets.size() == j);
}
+#endif //QT_NO_TABBAR
#ifndef QT_NO_TABBAR
void QDockAreaLayoutInfo::updateTabBar() const
@@ -2259,7 +2260,7 @@ QRect QDockAreaLayoutInfo::tabContentRect() const
** QDockAreaLayout
*/
-QDockAreaLayout::QDockAreaLayout(QMainWindow *win)
+QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true)
{
mainWindow = win;
sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, win);
@@ -2346,6 +2347,9 @@ bool QDockAreaLayout::restoreState(QDataStream &stream, const QList<QDockWidget*
for (int i = 0; i < 4; ++i)
corners[i] = static_cast<Qt::DockWidgetArea>(cornerData[i]);
}
+
+ if (!testing)
+ fallbackToSizeHints = false;
}
return ok;
@@ -2582,7 +2586,7 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list,
{
QSize center_hint(0, 0);
QSize center_min(0, 0);
- bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
+ const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
if (have_central) {
center_hint = centralWidgetRect.size();
if (!center_hint.isValid())
@@ -2601,33 +2605,35 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list,
center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep);
QSize left_hint = docks[QInternal::LeftDock].size();
- if (left_hint.isNull())
+ 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())
+ 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())
+ 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())
+ 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 = !have_central;
+
if (_ver_struct_list != 0) {
QVector<QLayoutStruct> &ver_struct_list = *_ver_struct_list;
ver_struct_list.resize(3);
@@ -3073,9 +3079,10 @@ void QDockAreaLayout::apply(bool animate)
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,
@@ -3153,6 +3160,7 @@ int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &or
return delta;
}
+#ifndef QT_NO_TABBAR
// Sets the correct positions for the seperator widgets
// Allocates new sepearator widgets with getSeparatorWidget
void QDockAreaLayout::updateSeparatorWidgets() const
@@ -3186,6 +3194,7 @@ void QDockAreaLayout::updateSeparatorWidgets() const
separatorWidgets.resize(j);
}
+#endif //QT_NO_TABBAR
QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const
{
@@ -3238,7 +3247,6 @@ QSet<QTabBar*> QDockAreaLayout::usedTabBars() const
}
return result;
}
-#endif
// Returns the set of all used separator widgets
QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
@@ -3253,6 +3261,7 @@ QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
}
return result;
}
+#endif
QRect QDockAreaLayout::gapRect(const QList<int> &path) const
{
diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h
index 99a9dbb9b9..bd2067b3e8 100644
--- a/src/gui/widgets/qdockarealayout_p.h
+++ b/src/gui/widgets/qdockarealayout_p.h
@@ -196,9 +196,10 @@ public:
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;
@@ -233,6 +234,7 @@ public:
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;
@@ -278,7 +280,9 @@ public:
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);
@@ -292,9 +296,10 @@ public:
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
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp
index a574262f27..9cf6af1245 100644
--- a/src/gui/widgets/qdockwidget.cpp
+++ b/src/gui/widgets/qdockwidget.cpp
@@ -456,7 +456,7 @@ int QDockWidgetLayout::titleHeight() const
int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
- return qMax(buttonHeight + 2, titleFontMetrics.lineSpacing() + 2*mw);
+ return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
}
void QDockWidgetLayout::setGeometry(const QRect &geometry)
@@ -685,8 +685,6 @@ void QDockWidgetPrivate::_q_toggleTopLevel()
void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
{
- Q_Q(QDockWidget);
-
if (state != 0)
return;
@@ -694,8 +692,6 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
Q_ASSERT(win != 0);
QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
Q_ASSERT(layout != 0);
- if (layout->layoutState.indexOf(q).isEmpty()) //The dock widget has not been added into the main window
- return;
if (layout->pluggingWidget != 0) // the main window is animating a docking operation
return;
@@ -1012,6 +1008,12 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
{
Q_Q(QDockWidget);
+ if (!floating && parent) {
+ QMainWindowLayout *mwlayout = qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout());
+ if (!mwlayout || mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea)
+ return; // this dockwidget can't be redocked
+ }
+
bool wasFloating = q->isFloating();
bool hidden = q->isHidden();
@@ -1223,6 +1225,7 @@ void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
features &= DockWidgetFeatureMask;
if (d->features == features)
return;
+ const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
d->features = features;
QDockWidgetLayout *layout
= qobject_cast<QDockWidgetLayout*>(this->layout());
@@ -1231,6 +1234,10 @@ void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
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
diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp
index 7b39823583..d601f81eb6 100644
--- a/src/gui/widgets/qfontcombobox.cpp
+++ b/src/gui/widgets/qfontcombobox.cpp
@@ -194,7 +194,7 @@ QSize QFontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option,
// font.setFamily(text);
font.setPointSize(QFontInfo(font).pointSize() * 3/2);
QFontMetrics fontMetrics(font);
- return QSize(fontMetrics.width(text), fontMetrics.lineSpacing());
+ return QSize(fontMetrics.width(text), fontMetrics.height());
}
@@ -247,7 +247,14 @@ void QFontComboBoxPrivate::_q_updateModel()
}
list = result;
+ //we need to block the signals so that the model doesn't emit reset
+ //this prevents the current index from changing
+ //it will be updated just after this
+ ///TODO: we should finda way to avoid blocking signals and have a real update of the model
+ const bool old = m->blockSignals(true);
m->setStringList(list);
+ m->blockSignals(old);
+
if (list.isEmpty()) {
if (currentFont != QFont()) {
currentFont = QFont();
@@ -420,8 +427,10 @@ void QFontComboBox::setCurrentFont(const QFont &font)
Q_D(QFontComboBox);
if (font != d->currentFont) {
d->currentFont = font;
- emit currentFontChanged(d->currentFont);
d->_q_updateModel();
+ if (d->currentFont == font) { //else the signal has already be emitted by _q_updateModel
+ emit currentFontChanged(d->currentFont);
+ }
}
}
diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp
index 3d908a160b..ea711e805b 100644
--- a/src/gui/widgets/qlabel.cpp
+++ b/src/gui/widgets/qlabel.cpp
@@ -1170,22 +1170,10 @@ void QLabelPrivate::updateShortcut()
// But then we do want to hide the ampersands, so we can't use shortcutId.
hasShortcut = false;
- if (control) {
- ensureTextPopulated();
- // Underline the first character that follows an ampersand
- shortcutCursor = control->document()->find(QLatin1String("&"));
- if (shortcutCursor.isNull())
- return;
- hasShortcut = true;
- shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
- shortcutCursor.deleteChar(); // remove the ampersand
- shortcutCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
- } else {
- if (!text.contains(QLatin1Char('&')))
- return;
- hasShortcut = true;
- shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
- }
+ if (!text.contains(QLatin1Char('&')))
+ return;
+ hasShortcut = true;
+ shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
}
#endif // QT_NO_SHORTCUT
@@ -1456,6 +1444,24 @@ void QLabelPrivate::ensureTextPopulated() const
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;
diff --git a/src/gui/widgets/qlabel_p.h b/src/gui/widgets/qlabel_p.h
index c5a74e2855..ca17a359e0 100644
--- a/src/gui/widgets/qlabel_p.h
+++ b/src/gui/widgets/qlabel_p.h
@@ -113,7 +113,7 @@ public:
mutable uint hasShortcut : 1;
Qt::TextFormat textformat;
mutable QTextControl *control;
- QTextCursor shortcutCursor;
+ mutable QTextCursor shortcutCursor;
Qt::TextInteractionFlags textInteractionFlags;
inline bool needTextControl() const {
diff --git a/src/gui/widgets/qlcdnumber.cpp b/src/gui/widgets/qlcdnumber.cpp
index 9f9e353906..69c52cfc49 100644
--- a/src/gui/widgets/qlcdnumber.cpp
+++ b/src/gui/widgets/qlcdnumber.cpp
@@ -85,7 +85,7 @@ public:
decimal point with setSmallDecimalPoint().
QLCDNumber emits the overflow() signal when it is asked to display
- something beyond its range. The range is set by setNumDigits(),
+ something beyond its range. The range is set by setDigitCount(),
but setSmallDecimalPoint() also influences it. If the display is
set to hexadecimal, octal or binary, the integer equivalent of the
value is displayed.
@@ -160,7 +160,7 @@ public:
This signal is emitted whenever the QLCDNumber is asked to display
a too-large number or a too-long string.
- It is never emitted by setNumDigits().
+ It is never emitted by setDigitCount().
*/
@@ -345,7 +345,7 @@ static const char *getSegments(char ch) // gets list of segments f
The \a parent and \a name arguments are passed to the QFrame
constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(QWidget *parent, const char *name)
@@ -367,7 +367,7 @@ QLCDNumber::QLCDNumber(QWidget *parent, const char *name)
The \a parent and \a name arguments are passed to the QFrame
constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent, const char *name)
@@ -387,7 +387,7 @@ QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent, const char *name)
The \a parent argument is passed to the QFrame constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(QWidget *parent)
@@ -407,7 +407,7 @@ QLCDNumber::QLCDNumber(QWidget *parent)
The \a parent argument is passed to the QFrame constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent)
@@ -426,7 +426,7 @@ void QLCDNumberPrivate::init()
val = 0;
base = QLCDNumber::Dec;
smallPoint = false;
- q->setNumDigits(ndigits);
+ q->setDigitCount(ndigits);
q->setSegmentStyle(QLCDNumber::Filled);
q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
}
@@ -441,8 +441,21 @@ QLCDNumber::~QLCDNumber()
/*!
+ \deprecated
\property QLCDNumber::numDigits
\brief the current number of digits displayed
+ \sa digitCount
+*/
+
+void QLCDNumber::setNumDigits(int numDigits)
+{
+ setDigitCount(numDigits);
+}
+
+/*!
+ \since 4.6
+ \property QLCDNumber::digitCount
+ \brief the current number of digits displayed
Corresponds to the current number of digits. If \l
QLCDNumber::smallDecimalPoint is false, the decimal point occupies
@@ -453,7 +466,11 @@ QLCDNumber::~QLCDNumber()
\sa smallDecimalPoint
*/
-void QLCDNumber::setNumDigits(int numDigits)
+/*!
+ Sets the current number of digits to \a numDigits. Must
+ be in the range 0..99.
+ */
+void QLCDNumber::setDigitCount(int numDigits)
{
Q_D(QLCDNumber);
if (numDigits > 99) {
@@ -470,7 +487,7 @@ void QLCDNumber::setNumDigits(int numDigits)
d->ndigits = numDigits;
d->digitStr.fill(QLatin1Char(' '), d->ndigits);
d->points.fill(0, d->ndigits);
- d->digitStr[d->ndigits - 1] = QLatin1Char('0'); // "0" is the default number
+ d->digitStr[d->ndigits - 1] = QLatin1Char('0'); // "0" is the default number
} else {
bool doDisplay = d->ndigits == 0;
if (numDigits == d->ndigits) // no change
@@ -509,12 +526,21 @@ int QLCDNumber::numDigits() const
}
/*!
+ Returns the current number of digits.
+ */
+int QLCDNumber::digitCount() const
+{
+ Q_D(const QLCDNumber);
+ return d->ndigits;
+}
+
+/*!
\overload
Returns true if \a num is too big to be displayed in its entirety;
otherwise returns false.
- \sa display(), numDigits(), smallDecimalPoint()
+ \sa display(), digitCount(), smallDecimalPoint()
*/
bool QLCDNumber::checkOverflow(int num) const
@@ -530,7 +556,7 @@ bool QLCDNumber::checkOverflow(int num) const
Returns true if \a num is too big to be displayed in its entirety;
otherwise returns false.
- \sa display(), numDigits(), smallDecimalPoint()
+ \sa display(), digitCount(), smallDecimalPoint()
*/
bool QLCDNumber::checkOverflow(double num) const
@@ -1256,7 +1282,7 @@ QLCDNumber::SegmentStyle QLCDNumber::segmentStyle() const
*/
QSize QLCDNumber::sizeHint() const
{
- return QSize(10 + 9 * (numDigits() + (smallDecimalPoint() ? 0 : 1)), 23);
+ return QSize(10 + 9 * (digitCount() + (smallDecimalPoint() ? 0 : 1)), 23);
}
/*! \reimp */
diff --git a/src/gui/widgets/qlcdnumber.h b/src/gui/widgets/qlcdnumber.h
index 9753f312ba..e65637deef 100644
--- a/src/gui/widgets/qlcdnumber.h
+++ b/src/gui/widgets/qlcdnumber.h
@@ -60,6 +60,7 @@ class Q_GUI_EXPORT QLCDNumber : public QFrame // LCD number widget
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)
@@ -82,8 +83,10 @@ public:
bool smallDecimalPoint() const;
- int numDigits() const;
- void setNumDigits(int nDigits);
+ QT_DEPRECATED int numDigits() const;
+ QT_DEPRECATED void setNumDigits(int nDigits);
+ int digitCount() const;
+ void setDigitCount(int nDigits);
bool checkOverflow(double num) const;
bool checkOverflow(int num) const;
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 194df05895..ac3609cf12 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -401,7 +401,8 @@ void QLineControl::moveCursor(int pos, bool mark)
void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
{
int priorState = 0;
- bool isGettingInput = !event->commitString().isEmpty() || !event->preeditString().isEmpty()
+ bool isGettingInput = !event->commitString().isEmpty()
+ || event->preeditString() != preeditAreaText()
|| event->replacementLength() > 0;
bool cursorPositionChanged = false;
@@ -413,7 +414,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
int c = m_cursor; // cursor position after insertion of commit string
- if (event->replacementStart() <= 0)
+ if (event->replacementStart() == 0)
c += event->commitString().length() + qMin(-event->replacementStart(), event->replacementLength());
m_cursor += event->replacementStart();
@@ -447,8 +448,9 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
cursorPositionChanged = true;
}
}
-
+#ifndef QT_NO_IM
setPreeditArea(m_cursor, event->preeditString());
+#endif //QT_NO_IM
m_preeditCursor = event->preeditString().length();
m_hideCursor = false;
QList<QTextLayout::FormatRange> formats;
@@ -1290,7 +1292,7 @@ void QLineControl::setCursorBlinkPeriod(int msec)
m_blinkStatus = 1;
} else {
m_blinkTimer = 0;
- if (m_blinkStatus == 0)
+ if (m_blinkStatus == 1)
emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
}
m_blinkPeriod = msec;
@@ -1509,6 +1511,18 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
}
#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()
@@ -1529,17 +1543,6 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
clear();
}
- 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;
- }
bool unknown = false;
if (false) {
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
index 68898b6098..f8e1a5d168 100644
--- a/src/gui/widgets/qlinecontrol_p.h
+++ b/src/gui/widgets/qlinecontrol_p.h
@@ -174,8 +174,10 @@ public:
void setMaxLength(int maxLength);
int maxLength() const;
+#ifndef QT_NO_VALIDATOR
const QValidator *validator() const;
void setValidator(const QValidator *);
+#endif
#ifndef QT_NO_COMPLETER
QCompleter *completer() const;
@@ -282,7 +284,9 @@ private:
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);
@@ -623,6 +627,7 @@ inline int QLineControl::maxLength() const
return m_maxLength;
}
+#ifndef QT_NO_VALIDATOR
inline const QValidator *QLineControl::validator() const
{
return m_validator;
@@ -632,6 +637,7 @@ inline void QLineControl::setValidator(const QValidator *v)
{
m_validator = const_cast<QValidator*>(v);
}
+#endif
#ifndef QT_NO_COMPLETER
inline QCompleter *QLineControl::completer() const
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 629e839408..9f3fe4f98e 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -624,7 +624,7 @@ QSize QLineEdit::sizeHint() const
Q_D(const QLineEdit);
ensurePolished();
QFontMetrics fm(font());
- int h = qMax(fm.lineSpacing(), 14) + 2*d->verticalMargin
+ 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
@@ -1102,6 +1102,17 @@ void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
}
/*!
+ \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
@@ -1121,6 +1132,18 @@ void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) con
}
/*!
+ \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
@@ -1492,7 +1515,8 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
}
#endif
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
@@ -1571,7 +1595,9 @@ void QLineEdit::keyPressEvent(QKeyEvent *event)
&& !isReadOnly())
{
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
clear();
+#endif
} else {
event->ignore();
return;
@@ -1628,7 +1654,9 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
&& hasFocus() && !hasEditFocus()
&& !e->preeditString().isEmpty()) {
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
selectAll(); // so text is replaced rather than appended to
+#endif
}
#endif
diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h
index 214509a505..ac918c716e 100644
--- a/src/gui/widgets/qlineedit.h
+++ b/src/gui/widgets/qlineedit.h
@@ -44,6 +44,7 @@
#include <QtGui/qframe.h>
#include <QtCore/qstring.h>
+#include <QtCore/qmargins.h>
QT_BEGIN_HEADER
@@ -158,7 +159,9 @@ public:
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 &);
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index 027a5d6527..fa6f7a1777 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -1641,6 +1641,9 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
savedState.clear();
currentGapPos.clear();
pluggingWidget = 0;
+ //applying the state will make sure that the currentGap is updated correctly
+ //and all the geometries (especially the one from the central widget) is correct
+ layoutState.apply(false);
}
if (!widgetAnimator.animating()) {
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 687e1bc3b4..fc88d06600 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -180,6 +180,21 @@ int QMenuPrivate::scrollerHeight() const
}
//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
@@ -234,7 +249,7 @@ void QMenuPrivate::updateActionRects() const
}
int max_column_width = 0,
- dh = popupGeometry(QApplication::desktop()->screenNumber(q)).height(),
+ dh = popupGeometry(q).height(),
y = 0;
QStyle *style = q->style();
QStyleOption opt;
@@ -258,7 +273,7 @@ void QMenuPrivate::updateActionRects() const
for (int i = 0; i < actions.count(); ++i) {
QAction *action = actions.at(i);
- if (action->isSeparator() || !action->isVisible() || widgetItems.at(i))
+ if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
continue;
//..and some members
hasCheckableItems |= action->isCheckable();
@@ -286,7 +301,7 @@ void QMenuPrivate::updateActionRects() const
const QFontMetrics &fm = opt.fontMetrics;
QSize sz;
- if (QWidget *w = widgetItems.at(i)) {
+ 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..
@@ -355,7 +370,7 @@ void QMenuPrivate::updateActionRects() const
rect.setWidth(max_column_width); //uniform width
//we need to update the widgets geometry
- if (QWidget *widget = widgetItems.at(i)) {
+ if (QWidget *widget = widgetItems.value(actions.at(i))) {
widget->setGeometry(rect);
widget->setVisible(actions.at(i)->isVisible());
}
@@ -568,8 +583,7 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
q->update(actionRect(action));
if (reason == SelectedFromKeyboard) {
- const int actionIndex = actions.indexOf(action);
- QWidget *widget = widgetItems.at(actionIndex);
+ QWidget *widget = widgetItems.value(action);
if (widget) {
if (widget->focusPolicy() != Qt::NoFocus)
widget->setFocus(Qt::TabFocusReason);
@@ -588,14 +602,7 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
}
#ifndef QT_NO_STATUSTIP
} else if (previousAction) {
- QWidget *w = causedPopup.widget;
- while (QMenu *m = qobject_cast<QMenu*>(w))
- w = m->d_func()->causedPopup.widget;
- if (w) {
- QString empty;
- QStatusTipEvent tip(empty);
- QApplication::sendEvent(w, &tip);
- }
+ previousAction->d_func()->showStatusText(topCausedWidget(), QString());
#endif
}
if (hideActiveMenu) {
@@ -609,6 +616,15 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
}
}
+//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
@@ -744,7 +760,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
if (newScrollFlags & QMenuScroller::ScrollUp)
newOffset -= vmargin;
- QRect screen = popupGeometry(QApplication::desktop()->screenNumber(q));
+ 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();
@@ -785,7 +801,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
current.moveTop(current.top() + delta);
//we need to update the widgets geometry
- if (QWidget *w = widgetItems.at(i))
+ if (QWidget *w = widgetItems.value(actions.at(i)))
w->setGeometry(current);
}
}
@@ -960,10 +976,19 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
return false;
}
+class ExceptionGuard
+{
+public:
+ inline ExceptionGuard(bool *w = 0) : watched(w) { Q_ASSERT(!(*watched)); *watched = true; }
+ inline ~ExceptionGuard() { *watched = false; }
+ inline operator bool() { return *watched; }
+private:
+ bool *watched;
+};
+
void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self)
{
- Q_ASSERT(!activationRecursionGuard);
- activationRecursionGuard = true;
+ ExceptionGuard guard(&activationRecursionGuard);
#ifdef QT3_SUPPORT
const int actionId = q_func()->findIdForAction(action);
#endif
@@ -1008,7 +1033,6 @@ void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedSt
#endif
}
}
- activationRecursionGuard = false;
}
void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e, bool self)
@@ -1072,10 +1096,7 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e
QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection);
}
#endif
- QWidget *w = causedPopup.widget;
- while (QMenu *m = qobject_cast<QMenu*>(w))
- w = m->d_func()->causedPopup.widget;
- action->showStatusText(w);
+ action->showStatusText(topCausedWidget());
} else {
actionAboutToTrigger = 0;
}
@@ -1085,6 +1106,7 @@ 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);
@@ -1094,7 +1116,7 @@ void QMenuPrivate::_q_actionTriggered()
emit q->activated(id);
#endif
- if (!activationRecursionGuard) {
+ if (!activationRecursionGuard && actionGuard) {
//in case the action has not been activated by the mouse
//we check the parent hierarchy
QList< QPointer<QWidget> > list;
@@ -1369,11 +1391,12 @@ QMenu::QMenu(QMenuPrivate &dd, QWidget *parent)
QMenu::~QMenu()
{
Q_D(QMenu);
- for (int i = 0; i < d->widgetItems.count(); ++i) {
- if (QWidget *widget = d->widgetItems.at(i)) {
- QWidgetAction *action = static_cast<QWidgetAction *>(d->actions.at(i));
+ 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);
- d->widgetItems[i] = 0;
+ *it = 0;
}
}
@@ -1778,10 +1801,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
#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
- QWidget* top = this;
- while (QMenu* m = qobject_cast<QMenu *>(top))
- top = m->d_func()->causedPopup.widget;
- setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(top) != 0);
+ setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0);
#endif
ensurePolished(); // Get the right font
@@ -1789,7 +1809,15 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->updateActionRects();
QPoint pos = p;
QSize size = sizeHint();
- QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
+ QRect screen;
+#ifndef QT_NO_GRAPHICSVIEW
+ bool isEmbedded = 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);
#ifdef QT_KEYPAD_NAVIGATION
@@ -1847,6 +1875,12 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
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)
@@ -2116,7 +2150,7 @@ void QMenu::paintEvent(QPaintEvent *e)
QAction *action = d->actions.at(i);
QRect adjustedActionRect = d->actionRects.at(i);
if (!e->rect().intersects(adjustedActionRect)
- || d->widgetItems.at(i))
+ || d->widgetItems.value(action))
continue;
//set the clip region to be extra safe (and adjust for the scrollers)
QRegion adjustedActionReg(adjustedActionRect);
@@ -2715,18 +2749,14 @@ void QMenu::keyPressEvent(QKeyEvent *e)
}
}
if (!key_consumed) {
- if (QWidget *caused = d->causedPopup.widget) {
- while(QMenu *m = qobject_cast<QMenu*>(caused))
- caused = m->d_func()->causedPopup.widget;
#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
- QAction *oldAct = mb->d_func()->currentAction;
- QApplication::sendEvent(mb, e);
- if (mb->d_func()->currentAction != oldAct)
- key_consumed = true;
- }
-#endif
+ 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
@@ -2827,25 +2857,20 @@ void QMenu::actionEvent(QActionEvent *e)
connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
}
- QWidget *widget = 0;
- if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action()))
- widget = wa->requestWidget(this);
-
- int index = d->actions.indexOf(e->action());
- Q_ASSERT(index != -1);
- d->widgetItems.insert(index, widget);
-
+ 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;
- int index = d->actions.indexOf(e->before()) + 1;
if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
- if (QWidget *widget = d->widgetItems.at(index))
+ if (QWidget *widget = d->widgetItems.value(wa))
wa->releaseWidget(widget);
}
- Q_ASSERT(index != -1);
- d->widgetItems.removeAt(index);
+ d->widgetItems.remove(e->action());
}
#ifdef Q_WS_MAC
@@ -2927,7 +2952,7 @@ void QMenu::internalDelayedPopup()
QPoint pos(rightPos);
QMenu *caused = qobject_cast<QMenu*>(d->activeMenu->d_func()->causedPopup.widget);
- const QRect availGeometry(d->popupGeometry(QApplication::desktop()->screenNumber(caused)));
+ const QRect availGeometry(d->popupGeometry(caused));
if (isRightToLeft()) {
pos = leftPos;
if ((caused && caused->x() < x()) || pos.x() < availGeometry.left()) {
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 4fc3d3d589..9510cc666d 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -1191,7 +1191,7 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction
#endif
}
- QWidget *widget = qmenu ? qmenu->widgetItems.value(qmenu->actions.indexOf(action->action)) : 0;
+ QWidget *widget = qmenu ? qmenu->widgetItems.value(action->action) : 0;
if (widget) {
#ifndef QT_MAC_USE_COCOA
ChangeMenuAttributes(action->menu, kMenuAttrDoNotCacheImage, 0);
@@ -1425,7 +1425,7 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action)
SetMenuItemProperty(data.submenuHandle, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
#else
NSMenu *subMenu = static_cast<NSMenu *>(action->action->menu()->macMenu());
- if ([subMenu supermenu] != nil) {
+ 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.
@@ -1718,7 +1718,7 @@ QMenuBarPrivate::QMacMenuBarPrivate::syncAction(QMacMenuAction *action)
GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(caused), 0, &caused);
SetMenuItemProperty(submenu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
#else
- if ([submenu supermenu] != nil)
+ if ([submenu supermenu] && [submenu supermenu] != [item menu])
return;
else
[item setSubmenu:submenu];
@@ -1771,6 +1771,16 @@ QMenuBarPrivate::QMacMenuBarPrivate::removeAction(QMacMenuAction *action)
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)
{
@@ -1778,16 +1788,22 @@ QMenuBarPrivate::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.
+ // 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) {
+ 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) {
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 9c4f260896..c021063309 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -190,13 +190,14 @@ public:
QRect actionRect(QAction *) const;
mutable QVector<QRect> actionRects;
- mutable QWidgetList widgetItems;
+ mutable QHash<QAction *, QWidget *> widgetItems;
void updateActionRects() const;
- QRect popupGeometry(int screen=-1) 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;
- uint activationRecursionGuard : 1;
+ bool activationRecursionGuard;
//selection
static QPointer<QMenu> mouseDown;
@@ -214,6 +215,7 @@ public:
SelectedFromKeyboard,
SelectedFromElsewhere
};
+ QWidget *topCausedWidget() const;
QAction *actionAt(QPoint p) const;
void setFirstActionActive();
void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index d757f98818..94c4177871 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -243,11 +243,14 @@ void qt_symbian_show_submenu( CEikMenuPane* menuPane, int id)
}
#endif // Q_WS_S60
-void QMenuBarPrivate::symbianCommands(int command)
+int QMenuBarPrivate::symbianCommands(int command)
{
+ int ret = 0;
+
if (command == contexMenuCommand && !widgetWithContextMenu.isNull()) {
QContextMenuEvent* event = new QContextMenuEvent(QContextMenuEvent::Keyboard, QPoint(0,0));
QCoreApplication::postEvent(widgetWithContextMenu, event);
+ ret = 1;
}
int size = nativeMenuBars.size();
@@ -258,8 +261,11 @@ void QMenuBarPrivate::symbianCommands(int command)
emit nativeMenuBars.at(i)->triggered(menu->action);
menu->action->activate(QAction::Trigger);
+ ret = 1;
break;
}
+
+ return ret;
}
void QMenuBarPrivate::symbianCreateMenuBar(QWidget *parent)
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 13e7de4fd2..b1ff662cb0 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -332,34 +332,31 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
QSize popup_size = activeMenu->sizeHint();
- QRect screenRect = QApplication::desktop()->screenGeometry(pos);
+ //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 = !q->isRightToLeft();
- if (q->isRightToLeft() && popup_size.width() > pos.x())
+ 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;
- else
- pos.rx() -= popup_size.width();
- } else if (q->isRightToLeft()) {
- pos.setX(pos.x()-(popup_size.width() - actionWidth));
- }
-
- if(pos.x() < screenRect.x()) {
- pos.setX(screenRect.x());
- } else {
- const int off = pos.x()+popup_size.width() - screenRect.right();
- if(off > 0)
- pos.setX(qMax(screenRect.x(), pos.x()-off));
-
+ 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))
@@ -1370,8 +1367,13 @@ void QMenuBarPrivate::handleReparent()
oldWindow = newWindow;
#ifdef Q_WS_MAC
- macDestroyMenuBar();
- macCreateMenuBar(newParent);
+ 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
diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h
index 0b27b97f12..da2b8d7f19 100644
--- a/src/gui/widgets/qmenubar_p.h
+++ b/src/gui/widgets/qmenubar_p.h
@@ -196,6 +196,7 @@ public:
return 0;
}
} *mac_menubar;
+ bool macWidgetHasNativeMenubar(QWidget *widget);
void macCreateMenuBar(QWidget *);
void macDestroyMenuBar();
OSMenuRef macMenu();
@@ -265,7 +266,7 @@ public:
void insertNativeMenuItems(const QList<QAction*> &actions);
} *symbian_menubar;
- static void symbianCommands(int command);
+ static int symbianCommands(int command);
#endif
};
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index 22438bff17..c7759e854f 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -357,10 +357,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
Q_D(QPlainTextDocumentLayout);
QTextDocument *doc = document();
qreal margin = doc->documentMargin();
- QFontMetrics fm(doc->defaultFont());
qreal blockMaximumWidth = 0;
- int leading = qMax(0, fm.leading());
qreal height = 0;
QTextLayout *tl = block.layout();
QTextOption option = doc->defaultTextOption();
@@ -381,9 +379,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
QTextLine line = tl->createLine();
if (!line.isValid())
break;
+ line.setLeadingIncluded(true);
line.setLineWidth(availableWidth);
-
- height += leading;
line.setPosition(QPointF(margin, height));
height += line.height();
blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
@@ -733,9 +730,6 @@ QPlainTextEditPrivate::QPlainTextEditPrivate()
backgroundVisible = false;
centerOnScroll = false;
inDrag = false;
-#ifdef Q_WS_WIN
- singleFingerPanEnabled = true;
-#endif
}
@@ -792,6 +786,9 @@ void QPlainTextEditPrivate::init(const QString &txt)
viewport->setCursor(Qt::IBeamCursor);
#endif
originalOffsetY = 0;
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
}
void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -1453,6 +1450,29 @@ bool QPlainTextEdit::event(QEvent *e)
d->sendControlEvent(e);
}
#endif
+ 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;
+ }
return QAbstractScrollArea::event(e);
}
@@ -1602,7 +1622,6 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
return;
}
}
-#endif // QT_NO_SHORTCUT
if (!(tif & Qt::TextEditable)) {
switch (e->key()) {
@@ -1630,6 +1649,7 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
}
return;
}
+#endif // QT_NO_SHORTCUT
d->sendControlEvent(e);
#ifdef QT_KEYPAD_NAVIGATION
@@ -1946,7 +1966,8 @@ void QPlainTextEdit::mouseReleaseEvent(QMouseEvent *e)
d->ensureCursorVisible();
}
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
@@ -2932,30 +2953,6 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons
(\a available is true) or unavailable (\a available is false).
*/
-//void QPlainTextEditPrivate::_q_gestureTriggered()
-//{
-// Q_Q(QPlainTextEdit);
-// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
-// if (!g)
-// return;
-// QScrollBar *hBar = q->horizontalScrollBar();
-// QScrollBar *vBar = q->verticalScrollBar();
-// if (g->state() == Qt::GestureStarted)
-// originalOffsetY = vBar->value();
-// QSizeF totalOffset = g->totalOffset();
-// if (!totalOffset.isNull()) {
-// if (QApplication::isRightToLeft())
-// totalOffset.rwidth() *= -1;
-// // QPlainTextEdit scrolls by lines only in vertical direction
-// QFontMetrics fm(q->document()->defaultFont());
-// int lineHeight = fm.height();
-// int newX = hBar->value() - g->lastOffset().width();
-// int newY = originalOffsetY - totalOffset.height()/lineHeight;
-// hbar->setValue(newX);
-// vbar->setValue(newY);
-// }
-//}
-
QT_END_NAMESPACE
#include "moc_qplaintextedit.cpp"
diff --git a/src/gui/widgets/qprintpreviewwidget.cpp b/src/gui/widgets/qprintpreviewwidget.cpp
index d92b1ea3a2..0074c91cc7 100644
--- a/src/gui/widgets/qprintpreviewwidget.cpp
+++ b/src/gui/widgets/qprintpreviewwidget.cpp
@@ -663,7 +663,9 @@ void QPrintPreviewWidget::setZoomFactor(qreal factor)
}
/*!
+ \obsolete
Returns the number of pages in the preview.
+ \sa pageCount()
*/
int QPrintPreviewWidget::numPages() const
{
@@ -672,6 +674,16 @@ int QPrintPreviewWidget::numPages() const
}
/*!
+ \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
diff --git a/src/gui/widgets/qprintpreviewwidget.h b/src/gui/widgets/qprintpreviewwidget.h
index 2823873a6c..08e596d43a 100644
--- a/src/gui/widgets/qprintpreviewwidget.h
+++ b/src/gui/widgets/qprintpreviewwidget.h
@@ -82,7 +82,8 @@ public:
ViewMode viewMode() const;
ZoomMode zoomMode() const;
int currentPage() const;
- int numPages() const;
+ QT_DEPRECATED int numPages() const;
+ int pageCount() const;
void setVisible(bool visible);
public Q_SLOTS:
diff --git a/src/gui/widgets/qpushbutton.cpp b/src/gui/widgets/qpushbutton.cpp
index 1352e1b614..eb34336a53 100644
--- a/src/gui/widgets/qpushbutton.cpp
+++ b/src/gui/widgets/qpushbutton.cpp
@@ -590,7 +590,7 @@ void QPushButtonPrivate::_q_popupPressed()
int x = globalPos.x();
int y = globalPos.y();
if (horizontal) {
- if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->height()) {
+ if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->availableGeometry(q).height()) {
y += rect.height();
} else {
y -= menuSize.height();
@@ -598,7 +598,7 @@ void QPushButtonPrivate::_q_popupPressed()
if (q->layoutDirection() == Qt::RightToLeft)
x += rect.width() - menuSize.width();
} else {
- if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->width())
+ if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->availableGeometry(q).width())
x += rect.width();
else
x -= menuSize.width();
diff --git a/src/gui/widgets/qsplitter.cpp b/src/gui/widgets/qsplitter.cpp
index e3121ae534..520a8022fe 100644
--- a/src/gui/widgets/qsplitter.cpp
+++ b/src/gui/widgets/qsplitter.cpp
@@ -360,13 +360,26 @@ void QSplitterPrivate::recalc(bool update)
before a hidden widget must be hidden.
*/
bool first = true;
+ bool allInvisible = n != 0;
for (int i = 0; i < n ; ++i) {
QSplitterLayoutStruct *s = list.at(i);
- s->handle->setHidden(first || s->widget->isHidden());
- if (!s->widget->isHidden())
+ bool widgetHidden = s->widget->isHidden();
+ if (allInvisible && !widgetHidden && !s->collapsed)
+ allInvisible = false;
+ s->handle->setHidden(first || widgetHidden);
+ if (!widgetHidden)
first = false;
}
+ if (allInvisible)
+ for (int i = 0; i < n ; ++i) {
+ QSplitterLayoutStruct *s = list.at(i);
+ if (!s->widget->isHidden()) {
+ s->collapsed = false;
+ break;
+ }
+ }
+
int fi = 2 * q->frameWidth();
int maxl = fi;
int minl = fi;
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index 6c9761c94a..3935c55626 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -1694,6 +1694,9 @@ void QTabBar::mousePressEvent(QMouseEvent *event)
d->moveTabFinished(d->pressedIndex);
d->pressedIndex = d->indexAtPos(event->pos());
+#ifdef Q_WS_MAC
+ d->previousPressedIndex = d->pressedIndex;
+#endif
if (d->validIndex(d->pressedIndex)) {
QStyleOptionTabBarBaseV2 optTabBase;
optTabBase.init(this);
@@ -1774,6 +1777,17 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
update();
}
+#ifdef Q_WS_MAC
+ } else if (!d->documentMode && event->buttons() == Qt::LeftButton && d->previousPressedIndex != -1) {
+ int newPressedIndex = d->indexAtPos(event->pos());
+ if (d->pressedIndex == -1 && d->previousPressedIndex == newPressedIndex) {
+ d->pressedIndex = d->previousPressedIndex;
+ update(tabRect(d->pressedIndex));
+ } else if(d->pressedIndex != newPressedIndex) {
+ d->pressedIndex = -1;
+ update(tabRect(d->previousPressedIndex));
+ }
+#endif
}
if (event->buttons() != Qt::LeftButton) {
@@ -1798,6 +1812,7 @@ void QTabBarPrivate::setupMovableTab()
QPixmap grabImage(grabRect.size());
grabImage.fill(Qt::transparent);
QStylePainter p(&grabImage, q);
+ p.initFrom(q);
QStyleOptionTabV3 tab;
q->initStyleOption(&tab, pressedIndex);
@@ -1865,7 +1880,9 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event)
event->ignore();
return;
}
-
+#ifdef Q_WS_MAC
+ d->previousPressedIndex = -1;
+#endif
if (d->movable && d->dragInProgress && d->validIndex(d->pressedIndex)) {
int length = d->tabList[d->pressedIndex].dragOffset;
int width = verticalTabs(d->shape)
diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h
index 494a340205..9f3285ba1b 100644
--- a/src/gui/widgets/qtabbar_p.h
+++ b/src/gui/widgets/qtabbar_p.h
@@ -77,7 +77,11 @@ public:
:currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false),
drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false),
selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false),
- dragInProgress(false), documentMode(false), movingTab(0) {}
+ dragInProgress(false), documentMode(false), movingTab(0)
+#ifdef Q_WS_MAC
+ , previousPressedIndex(-1)
+#endif
+ {}
int currentIndex;
int pressedIndex;
@@ -195,7 +199,9 @@ public:
bool documentMode;
QWidget *movingTab;
-
+#ifdef Q_WS_MAC
+ int previousPressedIndex;
+#endif
// shared by tabwidget and qtabbar
static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size)
{
diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp
index 9aeb033f61..d22bd54e87 100644
--- a/src/gui/widgets/qtabwidget.cpp
+++ b/src/gui/widgets/qtabwidget.cpp
@@ -313,7 +313,16 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
: QTabBar::TriangularEast;
break;
}
+
option->tabBarSize = t;
+
+ if (QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<QStyleOptionTabWidgetFrameV2*>(option)) {
+ QRect tbRect = tabBar()->geometry();
+ QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
+ tabframe->tabBarRect = tbRect;
+ selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft());
+ tabframe->selectedTabRect = selectedTabRect;
+ }
}
/*!
@@ -756,7 +765,7 @@ void QTabWidget::setUpLayout(bool onlyCheck)
if (onlyCheck && !d->dirty)
return; // nothing to do
- QStyleOptionTabWidgetFrame option;
+ QStyleOptionTabWidgetFrameV2 option;
initStyleOption(&option);
// this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
@@ -1167,8 +1176,8 @@ void QTabWidget::tabRemoved(int index)
void QTabWidget::paintEvent(QPaintEvent *)
{
Q_D(QTabWidget);
- QStylePainter p(this);
if (documentMode()) {
+ QStylePainter p(this, tabBar());
if (QWidget *w = cornerWidget(Qt::TopLeftCorner)) {
QStyleOptionTabBarBaseV2 opt;
QTabBarPrivate::initStyleBaseOption(&opt, tabBar(), w->size());
@@ -1185,8 +1194,9 @@ void QTabWidget::paintEvent(QPaintEvent *)
}
return;
}
+ QStylePainter p(this);
- QStyleOptionTabWidgetFrame opt;
+ QStyleOptionTabWidgetFrameV2 opt;
initStyleOption(&opt);
opt.rect = d->panelRect;
p.drawPrimitive(QStyle::PE_FrameTabWidget, opt);
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index b894aa8292..1c49ef0491 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -116,9 +116,6 @@ QTextEditPrivate::QTextEditPrivate()
preferRichText = false;
showCursorOnInitialShow = true;
inDrag = false;
-#ifdef Q_WS_WIN
- setSingleFingerPanEnabled(true);
-#endif
}
void QTextEditPrivate::createAutoBulletList()
@@ -186,6 +183,9 @@ void QTextEditPrivate::init(const QString &html)
#ifndef QT_NO_CURSOR
viewport->setCursor(Qt::IBeamCursor);
#endif
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
}
void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -530,7 +530,9 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
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().
+ 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.
@@ -1210,7 +1212,9 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
if (e->text()[0].isPrint()) {
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
clear();
+#endif
} else {
e->ignore();
return;
@@ -1246,7 +1250,6 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
return;
}
}
-#endif // QT_NO_SHORTCUT
if (!(tif & Qt::TextEditable)) {
switch (e->key()) {
@@ -1274,6 +1277,7 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
}
return;
}
+#endif // QT_NO_SHORTCUT
{
QTextCursor cursor = d->control->textCursor();
@@ -1574,7 +1578,8 @@ void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
d->autoScrollTimer.stop();
ensureCursorVisible();
}
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
@@ -1672,7 +1677,9 @@ void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
&& QApplication::keypadNavigationEnabled()
&& !hasEditFocus()) {
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
selectAll(); // so text is replaced rather than appended to
+#endif
}
#endif
d->sendControlEvent(e);
@@ -1899,7 +1906,7 @@ void QTextEdit::setOverwriteMode(bool overwrite)
\brief the tab stop width in pixels
\since 4.1
- By default, this property contains a value of 80.
+ By default, this property contains a value of 80 pixels.
*/
int QTextEdit::tabStopWidth() const
@@ -2079,8 +2086,8 @@ void QTextEdit::setReadOnly(bool ro)
} else {
flags = Qt::TextEditorInteraction;
}
- setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
d->control->setTextInteractionFlags(flags);
+ setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
}
/*!
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index 40c0b02fd5..58a3d280c1 100644
--- a/src/gui/widgets/qtoolbar.cpp
+++ b/src/gui/widgets/qtoolbar.cpp
@@ -183,6 +183,9 @@ void QToolBarPrivate::setWindowState(bool floating, bool unplug, const QRect &re
if (visible)
q->show();
+
+ if (floating != wasFloating)
+ emit q->topLevelChanged(floating);
}
void QToolBarPrivate::initDrag(const QPoint &pos)
@@ -393,7 +396,7 @@ bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event)
void QToolBarPrivate::unplug(const QRect &_r)
{
Q_Q(QToolBar);
- layout->setExpanded(false, false);
+ layout->setExpanded(false);
QRect r = _r;
r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
setWindowState(true, true, r);
@@ -518,6 +521,19 @@ void QToolBarPrivate::plug(const QRect &r)
*/
/*!
+ \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()
+*/
+
+
+/*!
Constructs a QToolBar with the given \a parent.
*/
QToolBar::QToolBar(QWidget *parent)
diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h
index a084673093..a1a24f0d3e 100644
--- a/src/gui/widgets/qtoolbar.h
+++ b/src/gui/widgets/qtoolbar.h
@@ -142,6 +142,7 @@ Q_SIGNALS:
void orientationChanged(Qt::Orientation orientation);
void iconSizeChanged(const QSize &iconSize);
void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
+ void topLevelChanged(bool topLevel);
protected:
void actionEvent(QActionEvent *event);
diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp
index de11625dd5..b7e985cf3d 100644
--- a/src/gui/widgets/qtoolbararealayout.cpp
+++ b/src/gui/widgets/qtoolbararealayout.cpp
@@ -480,7 +480,7 @@ void QToolBarAreaLayoutInfo::moveToolBar(QToolBar *toolbar, int pos)
}
-QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos) const
+QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance) const
{
int p = pick(o, pos);
@@ -509,12 +509,19 @@ QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos) const
QList<int> result;
result << j << k;
+ *minDistance = 0; //we found a perfect match
+ return result;
+ }
+ } else {
+ const int dist = distance(pos);
+ //it will only return a path if the minDistance is higher than the current distance
+ if (dist >= 0 && *minDistance > dist) {
+ *minDistance = dist;
+
+ QList<int> result;
+ result << lines.count() << 0;
return result;
}
- } else if (appendLineDropRect().contains(pos)) {
- QList<int> result;
- result << lines.count() << 0;
- return result;
}
return QList<int>();
@@ -587,32 +594,20 @@ QRect QToolBarAreaLayoutInfo::itemRect(const QList<int> &path) const
return result;
}
-QRect QToolBarAreaLayoutInfo::appendLineDropRect() const
+int QToolBarAreaLayoutInfo::distance(const QPoint &pos) const
{
- QRect result;
-
switch (dockPos) {
case QInternal::LeftDock:
- result = QRect(rect.right(), rect.top(),
- EmptyDockAreaSize, rect.height());
- break;
+ return pos.x() - rect.right();
case QInternal::RightDock:
- result = QRect(rect.left() - EmptyDockAreaSize, rect.top(),
- EmptyDockAreaSize, rect.height());
- break;
+ return rect.left() - pos.x();
case QInternal::TopDock:
- result = QRect(rect.left(), rect.bottom() + 1,
- rect.width(), EmptyDockAreaSize);
- break;
+ return pos.y() - rect.bottom();
case QInternal::BottomDock:
- result = QRect(rect.left(), rect.top() - EmptyDockAreaSize,
- rect.width(), EmptyDockAreaSize);
- break;
+ return rect.top() - pos.y();
default:
- break;
+ return -1;
}
-
- return result;
}
/******************************************************************************
@@ -1022,21 +1017,24 @@ QList<int> QToolBarAreaLayout::indexOf(QWidget *toolBar) const
return result;
}
+//this functions returns the path to the possible gapindex for the position pos
QList<int> QToolBarAreaLayout::gapIndex(const QPoint &pos) const
{
Qt::LayoutDirection dir = mainWindow->layoutDirection();
+ int minDistance = 80; // when a dock area is empty, how "wide" is it?
+ QList<int> ret; //return value
for (int i = 0; i < QInternal::DockCount; ++i) {
QPoint p = pos;
if (docks[i].o == Qt::Horizontal)
p = QStyle::visualPos(dir, docks[i].rect, p);
- QList<int> result = docks[i].gapIndex(p);
+ QList<int> result = docks[i].gapIndex(p, &minDistance);
if (!result.isEmpty()) {
result.prepend(i);
- return result;
+ ret = result;
}
}
- return QList<int>();
+ return ret;
}
QList<int> QToolBarAreaLayout::currentGapIndex() const
diff --git a/src/gui/widgets/qtoolbararealayout_p.h b/src/gui/widgets/qtoolbararealayout_p.h
index 1e113b7c74..f0ab80c350 100644
--- a/src/gui/widgets/qtoolbararealayout_p.h
+++ b/src/gui/widgets/qtoolbararealayout_p.h
@@ -155,8 +155,6 @@ public:
class QToolBarAreaLayoutInfo
{
public:
- enum { EmptyDockAreaSize = 80 }; // when a dock area is empty, how "wide" is it?
-
QToolBarAreaLayoutInfo(QInternal::DockPosition pos = QInternal::TopDock);
QList<QToolBarAreaLayoutLine> lines;
@@ -173,11 +171,11 @@ public:
void removeToolBarBreak(QToolBar *before);
void moveToolBar(QToolBar *toolbar, int pos);
- QList<int> gapIndex(const QPoint &pos) const;
+ QList<int> gapIndex(const QPoint &pos, int *maxDistance) const;
bool insertGap(const QList<int> &path, QLayoutItem *item);
void clear();
QRect itemRect(const QList<int> &path) const;
- QRect appendLineDropRect() const;
+ int distance(const QPoint &pos) const;
QRect rect;
Qt::Orientation o;
diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/gui/widgets/qtoolbarlayout.cpp
index 7dc1e01949..0afe5d8e56 100644
--- a/src/gui/widgets/qtoolbarlayout.cpp
+++ b/src/gui/widgets/qtoolbarlayout.cpp
@@ -642,7 +642,7 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const
return result;
}
-void QToolBarLayout::setExpanded(bool exp, bool animated)
+void QToolBarLayout::setExpanded(bool exp)
{
if (exp == expanded)
return;
@@ -654,7 +654,6 @@ void QToolBarLayout::setExpanded(bool exp, bool animated)
if (!tb)
return;
if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) {
- animating = true;
QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
if (expanded) {
tb->raise();
@@ -665,7 +664,7 @@ void QToolBarLayout::setExpanded(bool exp, bool animated)
layoutActions(rect.size());
}
}
- layout->layoutState.toolBarAreaLayout.apply(animated);
+ layout->layoutState.toolBarAreaLayout.apply(win->isAnimated());
}
}
diff --git a/src/gui/widgets/qtoolbarlayout_p.h b/src/gui/widgets/qtoolbarlayout_p.h
index d49a5dfffc..afd0227194 100644
--- a/src/gui/widgets/qtoolbarlayout_p.h
+++ b/src/gui/widgets/qtoolbarlayout_p.h
@@ -112,7 +112,7 @@ public:
bool hasExpandFlag() const;
public Q_SLOTS:
- void setExpanded(bool b, bool animated = true);
+ void setExpanded(bool b);
private:
QList<QToolBarItem*> items;
diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp
index f440961954..13ee346445 100644
--- a/src/gui/widgets/qwidgetanimator.cpp
+++ b/src/gui/widgets/qwidgetanimator.cpp
@@ -88,8 +88,6 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
- if (r == final_geometry)
- return; //the widget is already where it should be
#ifndef QT_NO_ANIMATION
AnimationMap::const_iterator it = m_animation_map.constFind(widget);
if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
@@ -105,7 +103,9 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
#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
}
@@ -114,9 +114,4 @@ bool QWidgetAnimator::animating() const
return !m_animation_map.isEmpty();
}
-bool QWidgetAnimator::animating(QWidget *widget) const
-{
- return m_animation_map.contains(widget);
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h
index 68d93441ea..095380feb1 100644
--- a/src/gui/widgets/qwidgetanimator_p.h
+++ b/src/gui/widgets/qwidgetanimator_p.h
@@ -70,7 +70,6 @@ public:
QWidgetAnimator(QMainWindowLayout *layout);
void animate(QWidget *widget, const QRect &final_geometry, bool animate);
bool animating() const;
- bool animating(QWidget *widget) const;
void abort(QWidget *widget);