summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-10-23 14:01:35 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-10-23 14:45:03 +0200
commit790aef362fd195adf97d8c780a7cbbbade27d51f (patch)
tree8be464687ab21806cfe9f7ada27098b563aa41b2 /src
parent9720efbd1035c2e939b0581163e6d804c713dd96 (diff)
parent07475c662eb73c833da2d461b8ef2702ca1e2cfb (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: .qmake.conf configure src/corelib/global/qglobal.h src/tools/qdoc/node.cpp src/tools/qdoc/qdocdatabase.cpp tests/auto/corelib/io/qsettings/tst_qsettings.cpp tools/configure/configureapp.cpp Change-Id: I66028ae5e441a06b73ee85ba72a03a3af3e8593f
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/easing/easing.cpp18
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java94
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java33
-rw-r--r--src/concurrent/doc/qtconcurrent.qdocconf2
-rw-r--r--src/corelib/doc/qtcore.qdocconf2
-rw-r--r--src/corelib/global/global.pri31
-rw-r--r--src/corelib/global/qglobal.h5
-rw-r--r--src/corelib/global/qsystemdetection.h2
-rw-r--r--src/corelib/global/qversiontagging.cpp79
-rw-r--r--src/corelib/global/qversiontagging.h86
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp2
-rw-r--r--src/corelib/io/qtextstream.cpp147
-rw-r--r--src/corelib/io/qtextstream.h1
-rw-r--r--src/corelib/io/qtextstream_p.h10
-rw-r--r--src/corelib/kernel/kernel.pri13
-rw-r--r--src/corelib/kernel/qcfsocketnotifier.cpp (renamed from src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp)11
-rw-r--r--src/corelib/kernel/qcfsocketnotifier_p.h (renamed from src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h)4
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm (renamed from src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm)2
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf_p.h (renamed from src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h)6
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp63
-rw-r--r--src/corelib/kernel/qjnihelpers_p.h20
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp2
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp51
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp5
-rw-r--r--src/corelib/thread/qbasicatomic.h12
-rw-r--r--src/corelib/tools/qeasingcurve.cpp8
-rw-r--r--src/corelib/tools/qlocale.cpp5
-rw-r--r--src/corelib/tools/qsimd.cpp2
-rw-r--r--src/corelib/tools/qstring.cpp19
-rw-r--r--src/corelib/tools/qstring.h53
-rw-r--r--src/dbus/doc/qtdbus.qdocconf2
-rw-r--r--src/dbus/qdbusconnection_p.h3
-rw-r--r--src/dbus/qdbuspendingcall.cpp1
-rw-r--r--src/dbus/qdbuspendingcall_p.h1
-rw-r--r--src/dbus/qdbusserver.cpp6
-rw-r--r--src/gui/doc/qtgui.qdocconf2
-rw-r--r--src/gui/image/qicon.cpp51
-rw-r--r--src/gui/image/qicon.h2
-rw-r--r--src/gui/image/qpixmap_win.cpp28
-rw-r--r--src/gui/image/qpixmapcache.cpp3
-rw-r--r--src/gui/kernel/qguiapplication.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.cpp3
-rw-r--r--src/gui/kernel/qplatformwindow.h2
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow.cpp13
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow_p.h2
-rw-r--r--src/gui/kernel/qshortcutmap.cpp4
-rw-r--r--src/gui/kernel/qsimpledrag.cpp3
-rw-r--r--src/gui/kernel/qsimpledrag_p.h4
-rw-r--r--src/gui/kernel/qwindow.cpp60
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp2
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp257
-rw-r--r--src/gui/opengl/qopengltextureblitter_p.h4
-rw-r--r--src/gui/painting/qcolor.cpp4
-rw-r--r--src/gui/painting/qdrawhelper.cpp15
-rw-r--r--src/gui/painting/qpdf.cpp6
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp29
-rw-r--r--src/gui/text/qtextimagehandler.cpp16
-rw-r--r--src/gui/util/qdesktopservices.cpp4
-rw-r--r--src/network/doc/qtnetwork.qdocconf2
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp6
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp35
-rw-r--r--src/opengl/doc/qtopengl.qdocconf2
-rw-r--r--src/platformheaders/doc/qtplatformheaders.qdocconf2
-rw-r--r--src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri4
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri6
-rw-r--r--src/platformsupport/eglconvenience/qeglstreamconvenience.cpp112
-rw-r--r--src/platformsupport/eglconvenience/qeglstreamconvenience_p.h175
-rw-r--r--src/platformsupport/eventdispatchers/eventdispatchers.pri8
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp58
-rw-r--r--src/platformsupport/platformsupport.pro1
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp3
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm7
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp103
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h44
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp1
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h3
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.h2
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json14
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp33
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h6
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp28
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp54
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h25
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp103
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp24
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp45
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h8
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h2
-rw-r--r--src/printsupport/doc/qtprintsupport.qdocconf2
-rw-r--r--src/sql/doc/qtsql.qdocconf2
-rw-r--r--src/src.pro8
-rw-r--r--src/testlib/doc/qttestlib.qdocconf2
-rw-r--r--src/tools/bootstrap/bootstrap.pro1
-rw-r--r--src/tools/moc/moc.cpp1
-rw-r--r--src/tools/moc/preprocessor.cpp5
-rw-r--r--src/tools/qdoc/TODO.txt87
-rw-r--r--src/tools/qdoc/atom.cpp460
-rw-r--r--src/tools/qdoc/atom.h257
-rw-r--r--src/tools/qdoc/codechunk.cpp142
-rw-r--r--src/tools/qdoc/codechunk.h116
-rw-r--r--src/tools/qdoc/codemarker.cpp668
-rw-r--r--src/tools/qdoc/codemarker.h187
-rw-r--r--src/tools/qdoc/codeparser.cpp437
-rw-r--r--src/tools/qdoc/codeparser.h97
-rw-r--r--src/tools/qdoc/config.cpp1221
-rw-r--r--src/tools/qdoc/config.h319
-rw-r--r--src/tools/qdoc/cppcodemarker.cpp1326
-rw-r--r--src/tools/qdoc/cppcodemarker.h85
-rw-r--r--src/tools/qdoc/cppcodeparser.cpp2607
-rw-r--r--src/tools/qdoc/cppcodeparser.h255
-rw-r--r--src/tools/qdoc/doc.cpp3380
-rw-r--r--src/tools/qdoc/doc.h196
-rw-r--r--src/tools/qdoc/doc/config/qdoc.qdocconf72
-rw-r--r--src/tools/qdoc/doc/corefeatures.qdoc35
-rw-r--r--src/tools/qdoc/doc/examples/componentset/ProgressBar.qml135
-rw-r--r--src/tools/qdoc/doc/examples/componentset/Switch.qml142
-rw-r--r--src/tools/qdoc/doc/examples/componentset/TabWidget.qml183
-rw-r--r--src/tools/qdoc/doc/examples/componentset/componentset.pro5
-rw-r--r--src/tools/qdoc/doc/examples/componentset/uicomponents.qdoc.sample38
-rw-r--r--src/tools/qdoc/doc/examples/cpp.qdoc.sample126
-rw-r--r--src/tools/qdoc/doc/examples/examples.qdoc97
-rw-r--r--src/tools/qdoc/doc/examples/layoutmanagement.qdocinc13
-rw-r--r--src/tools/qdoc/doc/examples/main.cpp46
-rw-r--r--src/tools/qdoc/doc/examples/mainwindow.cpp243
-rw-r--r--src/tools/qdoc/doc/examples/minimum.qdocconf38
-rw-r--r--src/tools/qdoc/doc/examples/objectmodel.qdocinc11
-rw-r--r--src/tools/qdoc/doc/examples/qml.qdoc.sample116
-rw-r--r--src/tools/qdoc/doc/examples/samples.qdocinc109
-rw-r--r--src/tools/qdoc/doc/examples/signalandslots.qdocinc9
-rw-r--r--src/tools/qdoc/doc/files/basicqt.qdoc.sample67
-rw-r--r--src/tools/qdoc/doc/files/compat.qdocconf12
-rw-r--r--src/tools/qdoc/doc/files/qtgui.qdocconf49
-rw-r--r--src/tools/qdoc/doc/images/happy.gifbin11526 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/images/happyguy.jpgbin53442 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/images/link-to-qquickitem.pngbin46571 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/images/links-to-broken-links.pngbin16569 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/images/links-to-links.pngbin10042 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/images/qa-table.pngbin7057 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/images/qt-logo.pngbin1495 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/images/training.jpgbin8368 -> 0 bytes
-rw-r--r--src/tools/qdoc/doc/qa-pages.qdoc109
-rw-r--r--src/tools/qdoc/doc/qdoc-guide/qdoc-guide.qdoc632
-rw-r--r--src/tools/qdoc/doc/qdoc-guide/qtwritingstyle-cpp.qdoc187
-rw-r--r--src/tools/qdoc/doc/qdoc-guide/qtwritingstyle-qml.qdoc164
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-DITA.qdoc164
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc156
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc1058
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-intro.qdoc325
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc4081
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc1714
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc1594
-rw-r--r--src/tools/qdoc/doc/qdoc-manual.qdoc78
-rw-r--r--src/tools/qdoc/doc/qdoc-minimum-qdocconf.qdoc89
-rw-r--r--src/tools/qdoc/doc/qtgui-qdocconf.qdoc299
-rw-r--r--src/tools/qdoc/editdistance.cpp106
-rw-r--r--src/tools/qdoc/editdistance.h51
-rw-r--r--src/tools/qdoc/generator.cpp2171
-rw-r--r--src/tools/qdoc/generator.h260
-rw-r--r--src/tools/qdoc/helpprojectwriter.cpp858
-rw-r--r--src/tools/qdoc/helpprojectwriter.h118
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp4907
-rw-r--r--src/tools/qdoc/htmlgenerator.h290
-rw-r--r--src/tools/qdoc/jscodemarker.cpp141
-rw-r--r--src/tools/qdoc/jscodemarker.h69
-rw-r--r--src/tools/qdoc/location.cpp448
-rw-r--r--src/tools/qdoc/location.h133
-rw-r--r--src/tools/qdoc/main.cpp794
-rw-r--r--src/tools/qdoc/node.cpp3049
-rw-r--r--src/tools/qdoc/node.h1167
-rw-r--r--src/tools/qdoc/openedlist.cpp220
-rw-r--r--src/tools/qdoc/openedlist.h86
-rw-r--r--src/tools/qdoc/plaincodemarker.cpp119
-rw-r--r--src/tools/qdoc/plaincodemarker.h69
-rw-r--r--src/tools/qdoc/puredocparser.cpp225
-rw-r--r--src/tools/qdoc/puredocparser.h69
-rw-r--r--src/tools/qdoc/qdoc.pro99
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp1740
-rw-r--r--src/tools/qdoc/qdocdatabase.h455
-rw-r--r--src/tools/qdoc/qdocindexfiles.cpp1644
-rw-r--r--src/tools/qdoc/qdocindexfiles.h86
-rw-r--r--src/tools/qdoc/qdoctagfiles.cpp385
-rw-r--r--src/tools/qdoc/qdoctagfiles.h68
-rw-r--r--src/tools/qdoc/qmlcodemarker.cpp273
-rw-r--r--src/tools/qdoc/qmlcodemarker.h78
-rw-r--r--src/tools/qdoc/qmlcodeparser.cpp331
-rw-r--r--src/tools/qdoc/qmlcodeparser.h84
-rw-r--r--src/tools/qdoc/qmlmarkupvisitor.cpp844
-rw-r--r--src/tools/qdoc/qmlmarkupvisitor.h171
-rw-r--r--src/tools/qdoc/qmlparser/parser.pri22
-rw-r--r--src/tools/qdoc/qmlparser/qqmljs.g3142
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsast.cpp968
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsast_p.h2781
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsastfwd_p.h186
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsastvisitor.cpp50
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsastvisitor_p.h333
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsengine_p.cpp158
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsengine_p.h124
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsglobal_p.h63
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsgrammar.cpp1078
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsgrammar_p.h207
-rw-r--r--src/tools/qdoc/qmlparser/qqmljskeywords_p.h887
-rw-r--r--src/tools/qdoc/qmlparser/qqmljslexer.cpp1438
-rw-r--r--src/tools/qdoc/qmlparser/qqmljslexer_p.h250
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsmemorypool_p.h191
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsparser.cpp1916
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsparser_p.h251
-rw-r--r--src/tools/qdoc/qmlvisitor.cpp825
-rw-r--r--src/tools/qdoc/qmlvisitor.h119
-rw-r--r--src/tools/qdoc/quoter.cpp374
-rw-r--r--src/tools/qdoc/quoter.h86
-rw-r--r--src/tools/qdoc/separator.cpp69
-rw-r--r--src/tools/qdoc/separator.h50
-rw-r--r--src/tools/qdoc/text.cpp300
-rw-r--r--src/tools/qdoc/text.h99
-rw-r--r--src/tools/qdoc/tokenizer.cpp799
-rw-r--r--src/tools/qdoc/tokenizer.h177
-rw-r--r--src/tools/qdoc/tree.cpp1525
-rw-r--r--src/tools/qdoc/tree.h255
-rw-r--r--src/tools/qdoc/yyindent.cpp1182
-rw-r--r--src/tools/uic/ui4.cpp334
-rw-r--r--src/tools/uic/ui4.h40
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp53
-rw-r--r--src/widgets/doc/qtwidgets.qdocconf2
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp8
-rw-r--r--src/widgets/kernel/qdesktopwidget.h2
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp2
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp9
-rw-r--r--src/widgets/util/qcompleter.cpp19
-rw-r--r--src/widgets/widgets/qlineedit.cpp2
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp6
-rw-r--r--src/widgets/widgets/qlineedit_p.h1
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp5
-rw-r--r--src/winmain/qtmain_winrt.cpp1
-rw-r--r--src/xml/doc/qtxml.qdocconf2
248 files changed, 1896 insertions, 66499 deletions
diff --git a/src/3rdparty/easing/easing.cpp b/src/3rdparty/easing/easing.cpp
index 7d70a4d24b..04a59445e5 100644
--- a/src/3rdparty/easing/easing.cpp
+++ b/src/3rdparty/easing/easing.cpp
@@ -102,7 +102,7 @@ static qreal easeInCubic(qreal t)
}
/**
- * Easing equation function for a cubic (t^3) easing out: decelerating from zero velocity.
+ * Easing equation function for a cubic (t^3) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @return The correct value.
@@ -154,7 +154,7 @@ static qreal easeInQuart(qreal t)
}
/**
- * Easing equation function for a quartic (t^4) easing out: decelerating from zero velocity.
+ * Easing equation function for a quartic (t^4) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @return The correct value.
@@ -205,7 +205,7 @@ static qreal easeInQuint(qreal t)
}
/**
- * Easing equation function for a quintic (t^5) easing out: decelerating from zero velocity.
+ * Easing equation function for a quintic (t^5) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @return The correct value.
@@ -256,7 +256,7 @@ static qreal easeInSine(qreal t)
}
/**
- * Easing equation function for a sinusoidal (sin(t)) easing out: decelerating from zero velocity.
+ * Easing equation function for a sinusoidal (sin(t)) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @return The correct value.
@@ -301,7 +301,7 @@ static qreal easeInExpo(qreal t)
}
/**
- * Easing equation function for an exponential (2^t) easing out: decelerating from zero velocity.
+ * Easing equation function for an exponential (2^t) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @return The correct value.
@@ -350,7 +350,7 @@ static qreal easeInCirc(qreal t)
}
/**
- * Easing equation function for a circular (sqrt(1-t^2)) easing out: decelerating from zero velocity.
+ * Easing equation function for a circular (sqrt(1-t^2)) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @return The correct value.
@@ -438,7 +438,7 @@ static qreal easeOutElastic_helper(qreal t, qreal /*b*/, qreal c, qreal /*d*/, q
}
/**
- * Easing equation function for an elastic (exponentially decaying sine wave) easing out: decelerating from zero velocity.
+ * Easing equation function for an elastic (exponentially decaying sine wave) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @param a Amplitude.
@@ -503,7 +503,7 @@ static qreal easeInBack(qreal t, qreal s)
}
/**
- * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out: decelerating from zero velocity.
+ * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent).
@@ -566,7 +566,7 @@ static qreal easeOutBounce_helper(qreal t, qreal c, qreal a)
}
/**
- * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity.
+ * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating to zero velocity.
*
* @param t Current time (in frames or seconds).
* @param a Amplitude.
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 15d3b136c5..f22e3d7a70 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -59,6 +59,7 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewConfiguration;
@@ -76,7 +77,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
public class QtActivityDelegate
{
@@ -89,6 +89,7 @@ public class QtActivityDelegate
private Method m_super_onKeyUp = null;
private Method m_super_onConfigurationChanged = null;
private Method m_super_onActivityResult = null;
+ private Method m_super_dispatchGenericMotionEvent = null;
private static final String NATIVE_LIBRARIES_KEY = "native.libraries";
private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
@@ -131,37 +132,32 @@ public class QtActivityDelegate
if (m_fullScreen = enterFullScreen) {
m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
- if (Build.VERSION.SDK_INT >= 19) {
- try {
- int ui_flag_immersive_sticky = View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
- int ui_flag_layout_stable = View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_STABLE").getInt(null);
- int ui_flag_layout_hide_navigation = View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION").getInt(null);
- int ui_flag_layout_fullscreen = View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN").getInt(null);
- int ui_flag_hide_navigation = View.class.getDeclaredField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
- int ui_flag_fullscreen = View.class.getDeclaredField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(null);
-
+ try {
+ if (Build.VERSION.SDK_INT >= 14) {
+ int flags = View.class.getDeclaredField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
+ if (Build.VERSION.SDK_INT >= 16) {
+ flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_STABLE").getInt(null);
+ flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION").getInt(null);
+ flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN").getInt(null);
+ flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(null);
+
+ if (Build.VERSION.SDK_INT >= 19)
+ flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
+ }
Method m = View.class.getMethod("setSystemUiVisibility", int.class);
- m.invoke(m_activity.getWindow().getDecorView(),
- ui_flag_layout_stable
- | ui_flag_layout_hide_navigation
- | ui_flag_layout_fullscreen
- | ui_flag_hide_navigation
- | ui_flag_fullscreen
- | ui_flag_immersive_sticky
- | View.INVISIBLE);
- } catch (Exception e) {
- e.printStackTrace();
+ m.invoke(m_activity.getWindow().getDecorView(), flags | View.INVISIBLE);
}
+ } catch (Exception e) {
+ e.printStackTrace();
}
} else {
m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- if (Build.VERSION.SDK_INT >= 19) {
+ if (Build.VERSION.SDK_INT >= 14) {
try {
int ui_flag_visible = View.class.getDeclaredField("SYSTEM_UI_FLAG_VISIBLE").getInt(null);
Method m = View.class.getMethod("setSystemUiVisibility", int.class);
- m.invoke(m_activity.getWindow().getDecorView(),
- ui_flag_visible);
+ m.invoke(m_activity.getWindow().getDecorView(), ui_flag_visible);
} catch (Exception e) {
e.printStackTrace();
}
@@ -214,10 +210,10 @@ public class QtActivityDelegate
private final int EnterKeyPrevious = 7;
// application state
- private final int ApplicationSuspended = 0x0;
- private final int ApplicationHidden = 0x1;
- private final int ApplicationInactive = 0x2;
- private final int ApplicationActive = 0x4;
+ public static final int ApplicationSuspended = 0x0;
+ public static final int ApplicationHidden = 0x1;
+ public static final int ApplicationInactive = 0x2;
+ public static final int ApplicationActive = 0x4;
public boolean setKeyboardVisibility(boolean visibility, long timeStamp)
@@ -475,6 +471,13 @@ public class QtActivityDelegate
m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class);
m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class);
m_super_onActivityResult = m_activity.getClass().getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class);
+ if (Build.VERSION.SDK_INT >= 12) {
+ try {
+ m_super_dispatchGenericMotionEvent = m_activity.getClass().getMethod("super_dispatchGenericMotionEvent", MotionEvent.class);
+ } catch (Exception e) {
+ }
+ }
+
} catch (Exception e) {
e.printStackTrace();
return false;
@@ -915,24 +918,15 @@ public class QtActivityDelegate
public void onPause()
{
- QtNative.updateApplicationState(ApplicationInactive);
+ QtNative.setApplicationState(ApplicationInactive);
}
public void onResume()
{
- // fire all lostActions
- synchronized (QtNative.m_mainActivityMutex)
- {
- Iterator<Runnable> itr = QtNative.getLostActions().iterator();
- while (itr.hasNext())
- m_activity.runOnUiThread(itr.next());
-
- QtNative.updateApplicationState(ApplicationActive);
- if (m_started) {
- QtNative.clearLostActions();
- QtNative.updateWindow();
- updateFullScreen(); // Suspending the app clears the immersive mode, so we need to set it again.
- }
+ QtNative.setApplicationState(ApplicationActive);
+ if (m_started) {
+ QtNative.updateWindow();
+ updateFullScreen(); // Suspending the app clears the immersive mode, so we need to set it again.
}
}
@@ -955,7 +949,7 @@ public class QtActivityDelegate
public void onStop()
{
- QtNative.updateApplicationState(ApplicationSuspended);
+ QtNative.setApplicationState(ApplicationSuspended);
}
public Object onRetainNonConfigurationInstance()
@@ -1060,6 +1054,9 @@ public class QtActivityDelegate
QtNative.keyUp(0, event.getCharacters().charAt(0), event.getMetaState(), event.getRepeatCount() > 0);
}
+ if (QtNative.dispatchKeyEvent(event))
+ return true;
+
try {
return (Boolean) m_super_dispatchKeyEvent.invoke(m_activity, event);
} catch (Exception e) {
@@ -1328,4 +1325,17 @@ public class QtActivityDelegate
m_layout.moveChild(view, index);
}
}
+
+ public boolean dispatchGenericMotionEvent (MotionEvent ev)
+ {
+ if (m_started && QtNative.dispatchGenericMotionEvent(ev))
+ return true;
+
+ try {
+ return (Boolean) m_super_dispatchGenericMotionEvent.invoke(m_activity, ev);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 0c01e67637..07ef6d657d 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -48,12 +48,14 @@ import android.text.ClipboardManager;
import android.os.Build;
import android.util.Log;
import android.view.ContextMenu;
+import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
+import java.util.Iterator;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
@@ -61,6 +63,7 @@ import javax.net.ssl.X509TrustManager;
public class QtNative
{
private static Activity m_activity = null;
+ private static boolean m_activityPaused = false;
private static QtActivityDelegate m_activityDelegate = null;
public static Object m_mainActivityMutex = new Object(); // mutex used to synchronize runnable operations
@@ -165,14 +168,23 @@ public class QtNative
}
}
- static public ArrayList<Runnable> getLostActions()
+ public static void setApplicationState(int state)
{
- return m_lostActions;
- }
-
- static public void clearLostActions()
- {
- m_lostActions.clear();
+ synchronized (m_mainActivityMutex) {
+ switch (state) {
+ case QtActivityDelegate.ApplicationActive:
+ m_activityPaused = false;
+ Iterator<Runnable> itr = m_lostActions.iterator();
+ while (itr.hasNext())
+ runAction(itr.next());
+ m_lostActions.clear();
+ break;
+ default:
+ m_activityPaused = true;
+ break;
+ }
+ }
+ updateApplicationState(state);
}
private static void runAction(Runnable action)
@@ -180,7 +192,7 @@ public class QtNative
synchronized (m_mainActivityMutex) {
final Looper mainLooper = Looper.getMainLooper();
final Handler handler = new Handler(mainLooper);
- final boolean actionIsQueued = m_activity != null && mainLooper != null && handler.post(action);
+ final boolean actionIsQueued = !m_activityPaused && m_activity != null && mainLooper != null && handler.post(action);
if (!actionIsQueued)
m_lostActions.add(action);
}
@@ -633,6 +645,11 @@ public class QtNative
public static native void keyboardVisibilityChanged(boolean visibility);
// keyboard methods
+ // dispatch events methods
+ public static native boolean dispatchGenericMotionEvent(MotionEvent ev);
+ public static native boolean dispatchKeyEvent(KeyEvent event);
+ // dispatch events methods
+
// surface methods
public static native void setSurface(int id, Object surface, int w, int h);
// surface methods
diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf
index d8ee963ef5..3cd2fac075 100644
--- a/src/concurrent/doc/qtconcurrent.qdocconf
+++ b/src/concurrent/doc/qtconcurrent.qdocconf
@@ -4,7 +4,7 @@ project = QtConcurrent
description = Qt Concurrent Reference Documentation
version = $QT_VERSION
-examplesinstallpath = qtconcurrent
+examplesinstallpath = qtbase/qtconcurrent
qhp.projects = QtConcurrent
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 3d64708def..e98f06d47d 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -4,7 +4,7 @@ project = QtCore
description = Qt Core Reference Documentation
version = $QT_VERSION
-examplesinstallpath = corelib
+examplesinstallpath = qtbase/corelib
qhp.projects = QtCore
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index eb8600f796..aa4945f90e 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -17,7 +17,8 @@ HEADERS += \
global/qisenum.h \
global/qtypetraits.h \
global/qflags.h \
- global/qhooks_p.h
+ global/qhooks_p.h \
+ global/qversiontagging.h
SOURCES += \
global/archdetect.cpp \
@@ -27,7 +28,8 @@ SOURCES += \
global/qmalloc.cpp \
global/qnumeric.cpp \
global/qlogging.cpp \
- global/qhooks.cpp
+ global/qhooks.cpp \
+ global/qversiontagging.cpp
# qlibraryinfo.cpp includes qconfig.cpp
INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
@@ -58,28 +60,3 @@ journald {
syslog {
DEFINES += QT_USE_SYSLOG
}
-
-linux|freebsd {
- VERSIONTAGGING_SOURCES = global/qversiontagging.cpp
- ltcg|clang {
- versiontagging_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $(INCPATH)
-
- # Disable LTO, as the global inline assembly may not get processed
- versiontagging_compiler.commands += -fno-lto
-
- # Disable the integrated assembler for Clang, since it can't parse with
- # the alternate macro syntax in use in qversiontagging.cpp
- clang: versiontagging_compiler.commands += -no-integrated-as
-
- versiontagging_compiler.commands += -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
- versiontagging_compiler.dependency_type = TYPE_C
- versiontagging_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
- versiontagging_compiler.input = VERSIONTAGGING_SOURCES
- versiontagging_compiler.variable_out = OBJECTS
- versiontagging_compiler.name = compiling[versiontagging] ${QMAKE_FILE_IN}
- silent: versiontagging_compiler.commands = @echo compiling[versiontagging] ${QMAKE_FILE_IN} && $$versiontagging_compiler.commands
- QMAKE_EXTRA_COMPILERS += versiontagging_compiler
- } else {
- SOURCES += $$VERSIONTAGGING_SOURCES
- }
-}
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index d4bbbe833c..d86e410194 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -41,11 +41,10 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.7.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050700
+#define QT_VERSION QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH)
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -55,6 +54,7 @@
#include <QtCore/qconfig.h>
#include <QtCore/qfeatures.h>
#endif
+
#ifdef _MSC_VER
# define QT_SUPPORTS(FEATURE) (!defined QT_NO_##FEATURE)
#else
@@ -1126,6 +1126,7 @@ QT_END_NAMESPACE
#include <QtCore/qatomic.h>
#include <QtCore/qglobalstatic.h>
#include <QtCore/qnumeric.h>
+#include <QtCore/qversiontagging.h>
#endif /* __cplusplus */
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index f043f6c5c9..9ca376b84a 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -130,7 +130,7 @@
# if defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
# define Q_OS_WINPHONE
# define Q_OS_WINRT
-# elif WINAPI_FAMILY==WINAPI_FAMILY_APP
+# elif WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
# define Q_OS_WINRT
# else
# define Q_OS_WIN32
diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp
index 66d3f8d00f..fc81d9bb93 100644
--- a/src/corelib/global/qversiontagging.cpp
+++ b/src/corelib/global/qversiontagging.cpp
@@ -33,37 +33,54 @@
#include "qglobal.h"
-#if defined(Q_CC_GNU) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)) && defined(Q_PROCESSOR_X86) && !defined(QT_STATIC)
-# define SYM QT_MANGLE_NAMESPACE(qt_version_tag)
-# define SSYM QT_STRINGIFY(SYM)
+#define SYM QT_MANGLE_NAMESPACE(qt_version_tag)
+//#define SSYM QT_STRINGIFY(SYM)
-asm(
-// ASM macro that makes one ELF versioned symbol
-".macro make_versioned_symbol plainsym versionedsym\n"
-".globl plainsym\n"
-".type plainsym, @object\n"
-".size plainsym, 1\n"
-".symver plainsym, versionedsym\n"
-"plainsym :\n"
-".endm\n"
-
-// ASM macro that makes one ELF versioned symbol qt_version_tag{sep}Qt_{major}.{minor}
-// that is an alias to qt_version_tag_{major}_{minor}.
-// The {sep} parameter must be @ for all old versions and @@ for the current version.
-".macro make_one_tag major minor sep\n"
-" make_versioned_symbol " SSYM "_\\major\\()_\\minor, " SSYM "\\sep\\()Qt_\\major\\().\\minor\n"
-".endm\n"
-
-".altmacro\n"
-".bss\n"
-".set qt_version_major, " QT_STRINGIFY(QT_VERSION) " >> 16\n" // set qt_version_major
-".set qt_version_minor, 0\n" // set qt_version_minor to 0 (it will grow to the current)
-".rept (" QT_STRINGIFY(QT_VERSION) " >> 8) & 0xff\n" // repeat minor version times (0 to N-1)
-" make_one_tag %qt_version_major, %qt_version_minor, @\n"
-" .set qt_version_minor, (qt_version_minor + 1)\n"
-".endr\n"
-" make_one_tag %qt_version_major, %qt_version_minor, @@\n" // call the macro for the current version
-" .space 1\n" // variable is 1 byte, value 0
-);
+#if defined(Q_CC_GNU) && defined(Q_OF_ELF)
+# define make_versioned_symbol2(sym, m, n, separator) \
+ Q_CORE_EXPORT extern const char sym ## _ ## m ## _ ## n = 0; \
+ asm(".symver " QT_STRINGIFY(sym) "_" QT_STRINGIFY(m) "_" QT_STRINGIFY(n) ", " \
+ QT_STRINGIFY(sym) separator "Qt_" QT_STRINGIFY(m) "." QT_STRINGIFY(n))
+#else
+# define make_versioned_symbol2(sym, m, n, separator)
+#endif
+#define make_versioned_symbol(sym, m, n, separator) make_versioned_symbol2(sym, m, n, separator)
+extern "C" {
+#if QT_VERSION_MINOR > 0
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 0, "@");
+#endif
+#if QT_VERSION_MINOR > 1
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 1, "@");
+#endif
+#if QT_VERSION_MINOR > 2
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 2, "@");
+#endif
+#if QT_VERSION_MINOR > 3
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 3, "@");
+#endif
+#if QT_VERSION_MINOR > 4
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 4, "@");
#endif
+#if QT_VERSION_MINOR > 5
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 5, "@");
+#endif
+#if QT_VERSION_MINOR > 6
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 6, "@");
+#endif
+#if QT_VERSION_MINOR > 7
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 7, "@");
+#endif
+#if QT_VERSION_MINOR > 8
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 8, "@");
+#endif
+#if QT_VERSION_MINOR > 9
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 9, "@");
+#endif
+#if QT_VERSION_MINOR > 10
+# error "Please update this file with more Qt versions."
+#endif
+
+// the default version:
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, QT_VERSION_MINOR, "@@");
+}
diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h
new file mode 100644
index 0000000000..22e6e82a58
--- /dev/null
+++ b/src/corelib/global/qversiontagging.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// qglobal.h includes this header, so keep it outside of our include guards
+#include <QtCore/qglobal.h>
+
+#if !defined(QVERSIONTAGGING_H)
+#define QVERSIONTAGGING_H
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Ugly hack warning and explanation:
+ *
+ * This file causes all ELF modules, be they libraries or applications, to use the
+ * qt_version_tag symbol that is present in QtCore. Such symbol is versioned,
+ * so the linker will automatically pull the current Qt version and add it to
+ * the ELF header of the library/application. The assembly produces one section
+ * called ".qtversion" containing two pointer-sized values. The first is a
+ * relocation to the qt_version_tag symbol (which is what causes the ELF
+ * version to get used). The second value is the current Qt version at the time
+ * of compilation.
+ *
+ * There will only be one copy of the section in the output library or application.
+ */
+
+#if defined(QT_BUILD_CORE_LIB) || defined(QT_BOOTSTRAPPED) || defined(QT_NO_VERSION_TAGGING)
+// don't make tags in QtCore, bootstrapped systems or if the user asked not to
+#elif defined(Q_CC_GNU)
+# if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL))
+# ifdef __LP64__
+# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n"
+# elif defined(Q_PROCESSOR_X86_64) // x32
+# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n"
+# else // x86
+# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
+# endif
+# define QT_VERSION_TAG(sym) \
+ asm ( \
+ ".section .qtversion, \"aG\", @progbits, qt_version_tag, comdat\n" \
+ ".align 8\n" \
+ QT_VERSION_TAG_RELOC(sym) \
+ ".long " QT_STRINGIFY(QT_VERSION) "\n" \
+ ".align 8\n" \
+ ".previous" \
+ )
+# endif
+#endif
+
+#if defined(QT_VERSION_TAG)
+QT_VERSION_TAG(qt_version_tag);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QVERSIONTAGGING_H
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 54a2855239..262703b9e6 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -238,7 +238,7 @@ inline QByteArray QStorageIterator::device() const
#elif defined(Q_OS_ANDROID)
-static const char pathMounted[] = "/proc/mounts";
+static const QLatin1String pathMounted("/proc/mounts");
inline QStorageIterator::QStorageIterator()
{
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index ccf832e2e8..a8fd2dd7ab 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -222,6 +222,8 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
#include "qbuffer.h"
#include "qfile.h"
#include "qnumeric.h"
+#include "qvarlengtharray.h"
+
#ifndef Q_OS_WINCE
#include <locale.h>
#endif
@@ -845,6 +847,21 @@ inline void QTextStreamPrivate::write(QChar ch)
/*!
\internal
*/
+void QTextStreamPrivate::write(QLatin1String data)
+{
+ if (string) {
+ // ### What about seek()??
+ string->append(data);
+ } else {
+ writeBuffer += data;
+ if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
+ flushWriteBuffer();
+ }
+}
+
+/*!
+ \internal
+*/
inline bool QTextStreamPrivate::getChar(QChar *ch)
{
if ((string && stringOffset == string->size())
@@ -891,45 +908,97 @@ inline void QTextStreamPrivate::putChar(QChar ch)
write(ch);
}
+
+/*!
+ \internal
+*/
+QTextStreamPrivate::PaddingResult QTextStreamPrivate::padding(int len) const
+{
+ Q_ASSERT(params.fieldWidth > len); // calling padding() when no padding is needed is an error
+
+ // Do NOT break NRVO in this function or kittens will die!
+
+ PaddingResult result;
+
+ const int padSize = params.fieldWidth - len;
+
+ result.padding.resize(padSize);
+ std::fill_n(result.padding.begin(), padSize, params.padChar);
+
+ switch (params.fieldAlignment) {
+ case QTextStream::AlignLeft:
+ result.left = 0;
+ result.right = padSize;
+ break;
+ case QTextStream::AlignRight:
+ case QTextStream::AlignAccountingStyle:
+ result.left = padSize;
+ result.right = 0;
+ break;
+ case QTextStream::AlignCenter:
+ result.left = padSize/2;
+ result.right = padSize - padSize/2;
+ break;
+ }
+
+ return result;
+}
+
/*!
\internal
*/
void QTextStreamPrivate::putString(const QChar *data, int len, bool number)
{
- QString pad;
- int padLeft = 0, padRight = 0;
+ if (Q_UNLIKELY(params.fieldWidth > len)) {
- // handle padding
- int padSize = params.fieldWidth - len;
- if (padSize > 0) {
- pad = QString(padSize, params.padChar);
- switch (params.fieldAlignment) {
- case QTextStream::AlignLeft:
- padRight = padSize;
- break;
- case QTextStream::AlignRight:
- case QTextStream::AlignAccountingStyle:
- padLeft = padSize;
- if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
- const QChar sign = len > 0 ? data[0] : QChar();
- if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
- // write the sign before the padding, then skip it later
- write(&sign, 1);
- ++data;
- --len;
- }
+ // handle padding:
+
+ const PaddingResult pad = padding(len);
+
+ if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
+ const QChar sign = len > 0 ? data[0] : QChar();
+ if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
+ // write the sign before the padding, then skip it later
+ write(&sign, 1);
+ ++data;
+ --len;
}
- break;
- case QTextStream::AlignCenter:
- padLeft = padSize/2;
- padRight = padSize - padSize/2;
- break;
}
+
+ write(pad.padding.constData(), pad.left);
+ write(data, len);
+ write(pad.padding.constData(), pad.right);
+ } else {
+ write(data, len);
}
+}
+
+/*!
+ \internal
+*/
+void QTextStreamPrivate::putString(QLatin1String data, bool number)
+{
+ if (Q_UNLIKELY(params.fieldWidth > data.size())) {
- write(pad.constData(), padLeft);
- write(data, len);
- write(pad.constData(), padRight);
+ // handle padding
+
+ const PaddingResult pad = padding(data.size());
+
+ if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
+ const QChar sign = data.size() > 0 ? QLatin1Char(*data.data()) : QChar();
+ if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
+ // write the sign before the padding, then skip it later
+ write(&sign, 1);
+ data = QLatin1String(data.data() + 1, data.size() - 1);
+ }
+ }
+
+ write(pad.padding.constData(), pad.left);
+ write(data);
+ write(pad.padding.constData(), pad.right);
+ } else {
+ write(data);
+ }
}
/*!
@@ -2503,14 +2572,28 @@ QTextStream &QTextStream::operator<<(const QString &string)
\overload
Writes \a string to the stream, and returns a reference to the
- QTextStream. The contents of \a string are converted with the
- QString constructor that takes a QLatin1String as argument.
+ QTextStream.
*/
QTextStream &QTextStream::operator<<(QLatin1String string)
{
Q_D(QTextStream);
CHECK_VALID_STREAM(*this);
- d->putString(QString(string));
+ d->putString(string);
+ return *this;
+}
+
+/*!
+ \since 5.6
+ \overload
+
+ Writes \a string to the stream, and returns a reference to the
+ QTextStream.
+*/
+QTextStream &QTextStream::operator<<(const QStringRef &string)
+{
+ Q_D(QTextStream);
+ CHECK_VALID_STREAM(*this);
+ d->putString(string.data(), string.size());
return *this;
}
diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h
index eb33db63d7..d7566e6f7b 100644
--- a/src/corelib/io/qtextstream.h
+++ b/src/corelib/io/qtextstream.h
@@ -179,6 +179,7 @@ public:
QTextStream &operator<<(double f);
QTextStream &operator<<(const QString &s);
QTextStream &operator<<(QLatin1String s);
+ QTextStream &operator<<(const QStringRef &s);
QTextStream &operator<<(const QByteArray &array);
QTextStream &operator<<(const char *c);
QTextStream &operator<<(const void *ptr);
diff --git a/src/corelib/io/qtextstream_p.h b/src/corelib/io/qtextstream_p.h
index 01289d7dc6..115408a6dd 100644
--- a/src/corelib/io/qtextstream_p.h
+++ b/src/corelib/io/qtextstream_p.h
@@ -168,11 +168,21 @@ public:
inline void write(const QString &data) { write(data.begin(), data.length()); }
inline void write(QChar ch);
void write(const QChar *data, int len);
+ void write(QLatin1String data);
inline void putString(const QString &ch, bool number = false) { putString(ch.constData(), ch.length(), number); }
void putString(const QChar *data, int len, bool number = false);
+ void putString(QLatin1String data, bool number = false);
inline void putChar(QChar ch);
void putNumber(qulonglong number, bool negative);
+ struct PaddingResult {
+ enum { PreallocatedPadding = 80 }; // typical line length
+
+ int left, right;
+ QVarLengthArray<QChar, PreallocatedPadding> padding;
+ };
+ PaddingResult padding(int len) const;
+
// buffers
bool fillReadBuffer(qint64 maxBytes = -1);
void resetReadBuffer();
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 65dc44def2..600c28b5d7 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -100,9 +100,11 @@ winrt {
mac {
HEADERS += \
+ kernel/qcfsocketnotifier_p.h \
kernel/qcore_mac_p.h
SOURCES += \
+ kernel/qcfsocketnotifier.cpp \
kernel/qcoreapplication_mac.cpp \
kernel/qcore_mac.cpp
@@ -113,8 +115,15 @@ mac {
osx: LIBS_PRIVATE += -framework CoreServices
- # We need UIKit for UIDevice
- ios: LIBS_PRIVATE += -framework UIKit
+ ios {
+ OBJECTIVE_SOURCES += \
+ kernel/qeventdispatcher_cf.mm
+ HEADERS += \
+ kernel/qeventdispatcher_cf_p.h
+
+ # We need UIKit for UIDevice
+ LIBS_PRIVATE += -framework UIKit
+ }
}
nacl {
diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp b/src/corelib/kernel/qcfsocketnotifier.cpp
index c58e0ea78d..24e1e0ac9a 100644
--- a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp
+++ b/src/corelib/kernel/qcfsocketnotifier.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -32,10 +32,11 @@
****************************************************************************/
#include "qcfsocketnotifier_p.h"
-#include <QtGui/qguiapplication.h>
+#include <QtCore/qcoreapplication.h>
#include <QtCore/qsocketnotifier.h>
#include <QtCore/qthread.h>
+QT_BEGIN_NAMESPACE
/**************************************************************************
Socket Notifiers
@@ -57,12 +58,12 @@ void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CF
if (callbackType == kCFSocketReadCallBack) {
if (socketInfo->readNotifier && socketInfo->readEnabled) {
socketInfo->readEnabled = false;
- QGuiApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
+ QCoreApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
}
} else if (callbackType == kCFSocketWriteCallBack) {
if (socketInfo->writeNotifier && socketInfo->writeEnabled) {
socketInfo->writeEnabled = false;
- QGuiApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
+ QCoreApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
}
}
@@ -301,3 +302,5 @@ void QCFSocketNotifier::enableSocketNotifiers(CFRunLoopObserverRef ref, CFRunLoo
}
}
}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h b/src/corelib/kernel/qcfsocketnotifier_p.h
index 9bccc1bf98..947efecca3 100644
--- a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h
+++ b/src/corelib/kernel/qcfsocketnotifier_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -75,7 +75,7 @@ typedef void (*MaybeCancelWaitForMoreEventsFn)(QAbstractEventDispatcher *hostEve
// setHostEventDispatcher() should be called at startup.
// removeSocketNotifiers() should be called at shutdown.
//
-class QCFSocketNotifier
+class Q_CORE_EXPORT QCFSocketNotifier
{
public:
QCFSocketNotifier();
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm
index 0273fe5ed4..5b9ad38b28 100644
--- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
+++ b/src/corelib/kernel/qeventdispatcher_cf.mm
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h b/src/corelib/kernel/qeventdispatcher_cf_p.h
index 2fe5dea3d8..5e8d2f0c85 100644
--- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
+++ b/src/corelib/kernel/qeventdispatcher_cf_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -83,8 +83,8 @@
#include <QtCore/qabstracteventdispatcher.h>
#include <QtCore/private/qtimerinfo_unix_p.h>
+#include <QtCore/private/qcfsocketnotifier_p.h>
#include <QtCore/qdebug.h>
-#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
#include <CoreFoundation/CoreFoundation.h>
#ifdef __OBJC__
@@ -196,7 +196,7 @@ private:
CFRunLoopObserverRef m_observer;
};
-class QEventDispatcherCoreFoundation : public QAbstractEventDispatcher
+class Q_CORE_EXPORT QEventDispatcherCoreFoundation : public QAbstractEventDispatcher
{
Q_OBJECT
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index f77fc4220c..0a5a5dffb9 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -34,6 +34,7 @@
#include "qjnihelpers_p.h"
#include "qmutex.h"
#include "qlist.h"
+#include "qvector.h"
#include <QtCore/qrunnable.h>
QT_BEGIN_NAMESPACE
@@ -57,6 +58,40 @@ static void onAndroidUiThread(JNIEnv *, jclass, jlong thiz)
}
namespace {
+ struct GenericMotionEventListeners {
+ QMutex mutex;
+ QVector<QtAndroidPrivate::GenericMotionEventListener *> listeners;
+ };
+}
+Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners)
+
+static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event)
+{
+ jboolean ret = JNI_FALSE;
+ QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
+ foreach (auto listener, g_genericMotionEventListeners()->listeners)
+ ret |= listener->handleGenericMotionEvent(event);
+ return ret;
+}
+
+namespace {
+ struct KeyEventListeners {
+ QMutex mutex;
+ QVector<QtAndroidPrivate::KeyEventListener *> listeners;
+ };
+}
+Q_GLOBAL_STATIC(KeyEventListeners, g_keyEventListeners)
+
+static jboolean dispatchKeyEvent(JNIEnv *, jclass, jobject event)
+{
+ jboolean ret = JNI_FALSE;
+ QMutexLocker locker(&g_keyEventListeners()->mutex);
+ foreach (auto listener, g_keyEventListeners()->listeners)
+ ret |= listener->handleKeyEvent(event);
+ return ret;
+}
+
+namespace {
class ActivityResultListeners
{
public:
@@ -227,7 +262,9 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
g_javaVM = vm;
static const JNINativeMethod methods[] = {
- {"onAndroidUiThread", "(J)V", reinterpret_cast<void *>(onAndroidUiThread)}
+ {"onAndroidUiThread", "(J)V", reinterpret_cast<void *>(onAndroidUiThread)},
+ {"dispatchGenericMotionEvent", "(Landroid/view/MotionEvent;)Z", reinterpret_cast<void *>(dispatchGenericMotionEvent)},
+ {"dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z", reinterpret_cast<void *>(dispatchKeyEvent)},
};
const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK);
@@ -274,4 +311,28 @@ void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env)
delete runnable;
}
+void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
+{
+ QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
+ g_genericMotionEventListeners()->listeners.push_back(listener);
+}
+
+void QtAndroidPrivate::unregisterGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
+{
+ QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
+ g_genericMotionEventListeners()->listeners.removeOne(listener);
+}
+
+void QtAndroidPrivate::registerKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
+{
+ QMutexLocker locker(&g_keyEventListeners()->mutex);
+ g_keyEventListeners()->listeners.push_back(listener);
+}
+
+void QtAndroidPrivate::unregisterKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
+{
+ QMutexLocker locker(&g_keyEventListeners()->mutex);
+ g_keyEventListeners()->listeners.removeOne(listener);
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h
index 883b08ef60..536989b4fc 100644
--- a/src/corelib/kernel/qjnihelpers_p.h
+++ b/src/corelib/kernel/qjnihelpers_p.h
@@ -76,6 +76,20 @@ namespace QtAndroidPrivate
virtual void handleResume() {};
};
+ class Q_CORE_EXPORT GenericMotionEventListener
+ {
+ public:
+ virtual ~GenericMotionEventListener() {}
+ virtual bool handleGenericMotionEvent(jobject event) = 0;
+ };
+
+ class Q_CORE_EXPORT KeyEventListener
+ {
+ public:
+ virtual ~KeyEventListener() {}
+ virtual bool handleKeyEvent(jobject event) = 0;
+ };
+
Q_CORE_EXPORT jobject activity();
Q_CORE_EXPORT JavaVM *javaVM();
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
@@ -95,6 +109,12 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT void handleResume();
Q_CORE_EXPORT void registerResumePauseListener(ResumePauseListener *listener);
Q_CORE_EXPORT void unregisterResumePauseListener(ResumePauseListener *listener);
+
+ Q_CORE_EXPORT void registerGenericMotionEventListener(GenericMotionEventListener *listener);
+ Q_CORE_EXPORT void unregisterGenericMotionEventListener(GenericMotionEventListener *listener);
+
+ Q_CORE_EXPORT void registerKeyEventListener(KeyEventListener *listener);
+ Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener);
}
QT_END_NAMESPACE
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index a8a1331053..ebaa1b069c 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -591,7 +591,7 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
if (xml.name() != QLatin1String("mime-type")) {
continue;
}
- const QString name = xml.attributes().value(QLatin1String("type")).toString();
+ const QStringRef name = xml.attributes().value(QLatin1String("type"));
if (name.isEmpty())
continue;
if (name != data.name) {
diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp
index 5a7a95883b..56f2a15fdb 100644
--- a/src/corelib/statemachine/qabstracttransition.cpp
+++ b/src/corelib/statemachine/qabstracttransition.cpp
@@ -252,26 +252,55 @@ QList<QAbstractState*> QAbstractTransition::targetStates() const
void QAbstractTransition::setTargetStates(const QList<QAbstractState*> &targets)
{
Q_D(QAbstractTransition);
- QVector<QPointer<QAbstractState> > copy(d->targetStates);
- bool sameList = true;
+
+ // Verify if any of the new target states is a null-pointer:
for (int i = 0; i < targets.size(); ++i) {
- QAbstractState *target = targets.at(i);
- if (!target) {
+ if (targets.at(i) == Q_NULLPTR) {
qWarning("QAbstractTransition::setTargetStates: target state(s) cannot be null");
return;
+ }
+ }
+
+ // First clean out any target states that got destroyed, but for which we still have a QPointer
+ // around.
+ for (int i = 0; i < d->targetStates.size(); ) {
+ if (d->targetStates.at(i).isNull()) {
+ d->targetStates.remove(i);
} else {
- sameList &= copy.removeOne(target);
+ ++i;
+ }
+ }
+
+ // Easy check: if both lists are empty, we're done.
+ if (targets.isEmpty() && d->targetStates.isEmpty())
+ return;
+
+ bool sameList = true;
+
+ if (targets.size() != d->targetStates.size()) {
+ // If the sizes of the lists are different, we don't need to be smart: they're different. So
+ // we can just set the new list as the targetStates.
+ sameList = false;
+ } else {
+ QVector<QPointer<QAbstractState> > copy(d->targetStates);
+ for (int i = 0; i < targets.size(); ++i) {
+ sameList &= copy.removeOne(targets.at(i));
+ if (!sameList)
+ break; // ok, we now know the lists are not the same, so stop the loop.
}
+
+ sameList &= copy.isEmpty();
}
- sameList &= copy.isEmpty();
+ if (sameList)
+ return;
- d->targetStates.clear();
- for (int i = 0; i < targets.size(); ++i)
- d->targetStates.append(targets.at(i));
+ d->targetStates.resize(targets.size());
+ for (int i = 0; i < targets.size(); ++i) {
+ d->targetStates[i] = targets.at(i);
+ }
- if (!sameList)
- emit targetStatesChanged(QPrivateSignal());
+ emit targetStatesChanged(QPrivateSignal());
}
/*!
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 3ffe191093..31b079af0c 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -406,6 +406,10 @@ QStateMachinePrivate::~QStateMachinePrivate()
{
qDeleteAll(internalEventQueue);
qDeleteAll(externalEventQueue);
+
+ for (QHash<int, DelayedEvent>::const_iterator it = delayedEvents.begin(), eit = delayedEvents.end(); it != eit; ++it) {
+ delete it.value().event;
+ }
}
QState *QStateMachinePrivate::rootState() const
@@ -1944,6 +1948,7 @@ void QStateMachinePrivate::_q_startDelayedEventTimer(int id, int delay)
e.timerId = q->startTimer(delay);
if (!e.timerId) {
qWarning("QStateMachine::postDelayedEvent: failed to start timer (id=%d, delay=%d)", id, delay);
+ delete e.event;
delayedEvents.erase(it);
delayedEventIdFreeList.release(id);
} else {
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index ecf39d699f..a747134df3 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -39,11 +39,13 @@
#if defined(QT_BOOTSTRAPPED)
# include <QtCore/qatomic_bootstrap.h>
-// The following two are used for testing only.
-// Note that we don't check the compiler support -- you had better
-// know what you're doing if you set them
-#elif defined(QT_ATOMIC_FORCE_CXX11)
+// If C++11 atomics are supported, use them!
+#elif defined(Q_COMPILER_ATOMICS) && defined(Q_COMPILER_CONSTEXPR) && !defined(QT_ATOMIC_FORCE_NO_CXX11)
# include <QtCore/qatomic_cxx11.h>
+
+// The following is used for testing only.
+// Note that we don't check the compiler support -- you had better
+// know what you're doing if you set it
#elif defined(QT_ATOMIC_FORCE_GCC)
# include <QtCore/qatomic_gcc.h>
@@ -66,8 +68,6 @@
# include <QtCore/qatomic_x86.h>
// Fallback compiler dependent implementation
-#elif defined(Q_COMPILER_ATOMICS) && defined(Q_COMPILER_CONSTEXPR)
-# include <QtCore/qatomic_cxx11.h>
#elif defined(Q_CC_GNU)
# include <QtCore/qatomic_gcc.h>
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index 22f5c65a40..012e6a95e8 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -170,7 +170,7 @@
\value OutSine \image qeasingcurve-outsine.png
\caption
Easing curve for a sinusoidal (sin(t)) function:
- decelerating from zero velocity.
+ decelerating to zero velocity.
\value InOutSine \image qeasingcurve-inoutsine.png
\caption
Easing curve for a sinusoidal (sin(t)) function:
@@ -186,7 +186,7 @@
\value OutExpo \image qeasingcurve-outexpo.png
\caption
Easing curve for an exponential (2^t) function:
- decelerating from zero velocity.
+ decelerating to zero velocity.
\value InOutExpo \image qeasingcurve-inoutexpo.png
\caption
Easing curve for an exponential (2^t) function:
@@ -202,7 +202,7 @@
\value OutCirc \image qeasingcurve-outcirc.png
\caption
Easing curve for a circular (sqrt(1-t^2)) function:
- decelerating from zero velocity.
+ decelerating to zero velocity.
\value InOutCirc \image qeasingcurve-inoutcirc.png
\caption
Easing curve for a circular (sqrt(1-t^2)) function:
@@ -222,7 +222,7 @@
\caption
Easing curve for an elastic
(exponentially decaying sine wave) function:
- decelerating from zero velocity. The peak amplitude
+ decelerating to zero velocity. The peak amplitude
can be set with the \e amplitude parameter, and the
period of decay by the \e period parameter.
\value InOutElastic \image qeasingcurve-inoutelastic.png
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 57ef53eea4..b1f53dc7a2 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -526,7 +526,7 @@ static uint default_number_options = 0;
static const QLocaleData *const c_data = locale_data;
static QLocalePrivate *c_private()
{
- static QLocalePrivate c_locale = { c_data, Q_BASIC_ATOMIC_INITIALIZER(1), 0 };
+ static QLocalePrivate c_locale = { c_data, Q_BASIC_ATOMIC_INITIALIZER(1), QLocale::OmitGroupSeparator };
return &c_locale;
}
@@ -698,7 +698,8 @@ static QLocalePrivate *localePrivateByName(const QString &name)
{
if (name == QLatin1String("C"))
return c_private();
- return QLocalePrivate::create(findLocaleData(name));
+ const QLocaleData *data = findLocaleData(name);
+ return QLocalePrivate::create(data, data->m_language_id == QLocale::C ? QLocale::OmitGroupSeparator : 0);
}
static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Script script,
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index d0c65a04b1..ad02d2c147 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -676,7 +676,7 @@ void qDetectCpuFeatures()
disable.prepend(' ');
for (int i = 0; i < features_count; ++i) {
if (disable.contains(features_string + features_indices[i]))
- f &= ~(1 << i);
+ f &= ~(Q_UINT64_C(1) << i);
}
}
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index ea220ed557..39e0f6825e 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -8222,14 +8222,25 @@ QString &QString::setRawData(const QChar *unicode, int size)
\snippet code/src_corelib_tools_qstring.cpp 6
+ \note If the function you're calling with a QLatin1String
+ argument isn't actually overloaded to take QLatin1String, the
+ implicit conversion to QString will trigger a memory allocation,
+ which is usually what you want to avoid by using QLatin1String
+ in the first place. In those cases, using QStringLiteral may be
+ the better option.
+
\sa QString, QLatin1Char, {QStringLiteral()}{QStringLiteral}
*/
+/*! \fn QLatin1String::QLatin1String()
+ \since 5.6
+
+ Constructs a QLatin1String object that stores a nullptr.
+*/
+
/*! \fn QLatin1String::QLatin1String(const char *str)
- Constructs a QLatin1String object that stores \a str. Note that if
- \a str is 0, an empty string is created; this case is handled by
- QString.
+ Constructs a QLatin1String object that stores \a str.
The string data is \e not copied. The caller must be able to
guarantee that \a str will not be deleted or modified as long as
@@ -8241,8 +8252,6 @@ QString &QString::setRawData(const QChar *unicode, int size)
/*! \fn QLatin1String::QLatin1String(const char *str, int size)
Constructs a QLatin1String object that stores \a str with \a size.
- Note that if \a str is 0, an empty string is created; this case
- is handled by QString.
The string data is \e not copied. The caller must be able to
guarantee that \a str will not be deleted or modified as long as
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 47c4272389..ba07259e77 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -83,20 +83,21 @@ template <typename T> class QVector;
class QLatin1String
{
public:
- Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) : m_size(s ? int(strlen(s)) : 0), m_data(s) {}
- Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) : m_size(sz), m_data(s) {}
- inline explicit QLatin1String(const QByteArray &s) : m_size(s.size()), m_data(s.constData()) {}
-
- inline const char *latin1() const { return m_data; }
- inline int size() const { return m_size; }
- inline const char *data() const { return m_data; }
-
- inline bool operator==(const QString &s) const;
- inline bool operator!=(const QString &s) const;
- inline bool operator>(const QString &s) const;
- inline bool operator<(const QString &s) const;
- inline bool operator>=(const QString &s) const;
- inline bool operator<=(const QString &s) const;
+ Q_DECL_CONSTEXPR inline QLatin1String() Q_DECL_NOTHROW : m_size(0), m_data(Q_NULLPTR) {}
+ Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) Q_DECL_NOTHROW : m_size(s ? int(strlen(s)) : 0), m_data(s) {}
+ Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) Q_DECL_NOTHROW : m_size(sz), m_data(s) {}
+ inline explicit QLatin1String(const QByteArray &s) Q_DECL_NOTHROW : m_size(s.size()), m_data(s.constData()) {}
+
+ Q_DECL_CONSTEXPR const char *latin1() const Q_DECL_NOTHROW { return m_data; }
+ Q_DECL_CONSTEXPR int size() const Q_DECL_NOTHROW { return m_size; }
+ Q_DECL_CONSTEXPR const char *data() const Q_DECL_NOTHROW { return m_data; }
+
+ inline bool operator==(const QString &s) const Q_DECL_NOTHROW;
+ inline bool operator!=(const QString &s) const Q_DECL_NOTHROW;
+ inline bool operator>(const QString &s) const Q_DECL_NOTHROW;
+ inline bool operator<(const QString &s) const Q_DECL_NOTHROW;
+ inline bool operator>=(const QString &s) const Q_DECL_NOTHROW;
+ inline bool operator<=(const QString &s) const Q_DECL_NOTHROW;
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
@@ -1130,34 +1131,34 @@ inline bool operator!=(QString::Null, QString::Null) { return false; }
inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); }
inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); }
-inline bool operator==(QLatin1String s1, QLatin1String s2)
+inline bool operator==(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
{ return (s1.size() == s2.size() && !memcmp(s1.latin1(), s2.latin1(), s1.size())); }
-inline bool operator!=(QLatin1String s1, QLatin1String s2)
+inline bool operator!=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
{ return (s1.size() != s2.size() || memcmp(s1.latin1(), s2.latin1(), s1.size())); }
-inline bool operator<(QLatin1String s1, QLatin1String s2)
+inline bool operator<(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
return (r < 0) || (r == 0 && s1.size() < s2.size()); }
-inline bool operator<=(QLatin1String s1, QLatin1String s2)
+inline bool operator<=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
return (r < 0) || (r == 0 && s1.size() <= s2.size()); }
-inline bool operator>(QLatin1String s1, QLatin1String s2)
+inline bool operator>(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
return (r > 0) || (r == 0 && s1.size() > s2.size()); }
-inline bool operator>=(QLatin1String s1, QLatin1String s2)
+inline bool operator>=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
return (r > 0) || (r == 0 && s1.size() >= s2.size()); }
-inline bool QLatin1String::operator==(const QString &s) const
+inline bool QLatin1String::operator==(const QString &s) const Q_DECL_NOTHROW
{ return s == *this; }
-inline bool QLatin1String::operator!=(const QString &s) const
+inline bool QLatin1String::operator!=(const QString &s) const Q_DECL_NOTHROW
{ return s != *this; }
-inline bool QLatin1String::operator>(const QString &s) const
+inline bool QLatin1String::operator>(const QString &s) const Q_DECL_NOTHROW
{ return s < *this; }
-inline bool QLatin1String::operator<(const QString &s) const
+inline bool QLatin1String::operator<(const QString &s) const Q_DECL_NOTHROW
{ return s > *this; }
-inline bool QLatin1String::operator>=(const QString &s) const
+inline bool QLatin1String::operator>=(const QString &s) const Q_DECL_NOTHROW
{ return s <= *this; }
-inline bool QLatin1String::operator<=(const QString &s) const
+inline bool QLatin1String::operator<=(const QString &s) const Q_DECL_NOTHROW
{ return s >= *this; }
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf
index ff46cc5961..fc8921ff35 100644
--- a/src/dbus/doc/qtdbus.qdocconf
+++ b/src/dbus/doc/qtdbus.qdocconf
@@ -19,7 +19,7 @@ sourcedirs += .. \
../../../examples/dbus/doc/src
excludedirs += ../../../examples/widgets/doc
-examplesinstallpath = dbus
+examplesinstallpath = qtbase/dbus
depends += qtdoc qtcore
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 49c7564566..91824c5c79 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -323,9 +323,6 @@ public:
MetaObjectHash cachedMetaObjects;
PendingCallList pendingCalls;
- QMutex callDeliveryMutex;
- QDBusCallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex
-
bool anonymousAuthenticationAllowed;
public:
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp
index ad5632be5a..c93d6acf84 100644
--- a/src/dbus/qdbuspendingcall.cpp
+++ b/src/dbus/qdbuspendingcall.cpp
@@ -181,7 +181,6 @@ bool QDBusPendingCallPrivate::setReplyCallback(QObject *target, const char *memb
void QDBusPendingCallPrivate::setMetaTypes(int count, const int *types)
{
- expectedReplyCount = count;
if (count == 0) {
expectedReplySignature = QLatin1String(""); // not null
return;
diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h
index dcf733679c..571a0eb028 100644
--- a/src/dbus/qdbuspendingcall_p.h
+++ b/src/dbus/qdbuspendingcall_p.h
@@ -89,7 +89,6 @@ public:
QDBusMessage replyMessage;
DBusPendingCall *pending;
QString expectedReplySignature;
- int expectedReplyCount;
// }
QDBusPendingCallPrivate(const QDBusMessage &sent, QDBusConnectionPrivate *connection)
diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp
index 6c1b4c10ef..babb270da0 100644
--- a/src/dbus/qdbusserver.cpp
+++ b/src/dbus/qdbusserver.cpp
@@ -54,15 +54,13 @@ QT_BEGIN_NAMESPACE
\a parent.
*/
QDBusServer::QDBusServer(const QString &address, QObject *parent)
- : QObject(parent)
+ : QObject(parent), d(0)
{
if (address.isEmpty())
return;
- if (!qdbus_loadLibDBus()) {
- d = 0;
+ if (!qdbus_loadLibDBus())
return;
- }
emit QDBusConnectionManager::instance()->serverRequested(address, this);
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 436e2e0b34..e34347b801 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -4,7 +4,7 @@ project = QtGui
description = Qt GUI Reference Documentation
version = $QT_VERSION
-examplesinstallpath = gui
+examplesinstallpath = qtbase/gui
qhp.projects = QtGui
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 7ae081adfb..cebe5ce5f9 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -45,6 +45,7 @@
#include "qcache.h"
#include "qdebug.h"
#include "qpalette.h"
+#include "qmath.h"
#include "private/qhexstring_p.h"
#include "private/qguiapplication_p.h"
@@ -1029,19 +1030,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
d->engine = new QPixmapIconEngine;
}
}
+
d->engine->addFile(fileName, size, mode, state);
- // Check if a "@2x" file exists and add it.
- static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
- if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) {
- QString at2xfileName = fileName;
- int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
- if (dotIndex == -1) /* no dot */
- dotIndex = fileName.size(); /* append */
- at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName))
- d->engine->addFile(at2xfileName, size, mode, state);
- }
+ // Check if a "@Nx" file exists and add it.
+ QString atNxFileName = qt_findAtNxFile(fileName, qApp->devicePixelRatio());
+ if (atNxFileName != fileName)
+ d->engine->addFile(atNxFileName, size, mode, state);
}
/*!
@@ -1395,5 +1390,39 @@ QDebug operator<<(QDebug dbg, const QIcon &i)
\internal
*/
+/*!
+ \internal
+ \since 5.6
+ Attempts to find a suitable @Nx file for the given \a targetDevicePixelRatio
+ Returns the the \a baseFileName if no such file was found.
+
+ Given base foo.png and a target dpr of 2.5, this function will look for
+ foo@3x.png, then foo@2x, then fall back to foo.png if not found.
+*/
+QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio)
+{
+ if (targetDevicePixelRatio <= 1.0)
+ return baseFileName;
+
+ static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
+ if (disableNxImageLoading)
+ return baseFileName;
+
+ QString atNx = QLatin1String("@%1x");
+ int dotIndex = baseFileName.lastIndexOf(QLatin1Char('.'));
+ if (dotIndex == -1) /* no dot */
+ dotIndex = baseFileName.size(); /* append */
+
+ // Check for @Nx, ..., @3x, @2x file versions,
+ for (int n = qCeil(targetDevicePixelRatio); n > 1; --n) {
+ QString atNxfileName = baseFileName;
+ atNxfileName.insert(dotIndex, atNx.arg(n));
+ if (QFile::exists(atNxfileName))
+ return atNxfileName;
+ }
+
+ return baseFileName;
+}
+
QT_END_NAMESPACE
#endif //QT_NO_ICON
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 329ae3deb3..6808bc2828 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -140,6 +140,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QIcon &);
#endif
+Q_GUI_EXPORT QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio);
+
QT_END_NAMESPACE
#endif // QICON_H
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 12e19440dc..a7a9b375ff 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -345,9 +345,22 @@ static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
return image;
}
+static inline bool hasAlpha(const QImage &image)
+{
+ const int w = image.width();
+ const int h = image.height();
+ for (int y = 0; y < h; ++y) {
+ const QRgb *scanLine = reinterpret_cast<const QRgb *>(image.scanLine(y));
+ for (int x = 0; x < w; ++x) {
+ if (qAlpha(scanLine[x]) != 0)
+ return true;
+ }
+ }
+ return false;
+}
+
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
{
- bool foundAlpha = false;
HDC screenDevice = GetDC(0);
HDC hdc = CreateCompatibleDC(screenDevice);
ReleaseDC(0, screenDevice);
@@ -356,6 +369,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
if (!result) {
qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+ DeleteDC(hdc);
return QPixmap();
}
@@ -371,17 +385,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
- for (int y = 0 ; y < h && !foundAlpha ; y++) {
- const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y));
- for (int x = 0; x < w ; x++) {
- if (qAlpha(scanLine[x]) != 0) {
- foundAlpha = true;
- break;
- }
- }
- }
- if (!foundAlpha) {
- //If no alpha was found, we use the mask to set alpha values
+ if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values
DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 2df813367d..6265a0c16d 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -652,7 +652,8 @@ void QPixmapCache::remove(const Key &key)
void QPixmapCache::clear()
{
QT_TRY {
- pm_cache()->clear();
+ if (pm_cache.exists())
+ pm_cache->clear();
} QT_CATCH(const std::bad_alloc &) {
// if we ran out of memory during pm_cache(), it's no leak,
// so just ignore it.
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index b717585b54..35e880fc5b 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -902,7 +902,7 @@ QWindowList QGuiApplication::topLevelWindows()
if (!list.at(i)->parent() && list.at(i)->type() != Qt::Desktop) {
// Top windows of embedded QAxServers do not have QWindow parents,
// but they are not true top level windows, so do not include them.
- const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded(0);
+ const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded();
if (!embedded)
topLevelWindows.prepend(list.at(i));
}
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 457a420148..14633d8b30 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -208,8 +208,7 @@ QPlatformServices *QPlatformIntegration::services() const
behavior for desktop platforms.
\value ForeignWindows The platform allows creating QWindows which represent
- native windows created by other processes or anyway created by using native
- libraries.
+ native windows created by other processes or by using native libraries.
\value NonFullScreenWindows The platform supports top-level windows which do not
fill the screen. The default implementation returns \c true. Returning false for
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 9c2817906f..850e2b4bfe 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -95,7 +95,7 @@ public:
virtual bool isExposed() const;
virtual bool isActive() const;
- virtual bool isEmbedded(const QPlatformWindow *parentWindow) const;
+ virtual bool isEmbedded(const QPlatformWindow *parentWindow = 0) const;
virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const;
diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp
index 5736c41e25..d77b6dc262 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow.cpp
+++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
@@ -35,12 +35,16 @@
#include <QtGui/QPainter>
#include <QtGui/QCursor>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QPalette>
+#include <QtGui/QBitmap>
QT_BEGIN_NAMESPACE
QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
: QWindow(screen),
- m_backingStore(0)
+ m_backingStore(0),
+ m_useCompositing(true)
{
QSurfaceFormat format;
format.setAlphaBufferSize(8);
@@ -68,7 +72,10 @@ void QShapedPixmapWindow::render()
{
QPainter p(device);
- p.setCompositionMode(QPainter::CompositionMode_Source);
+ if (m_useCompositing)
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ else
+ p.fillRect(rect, QGuiApplication::palette().base());
p.drawPixmap(0, 0, m_pixmap);
}
@@ -79,6 +86,8 @@ void QShapedPixmapWindow::render()
void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
+ if (!m_useCompositing)
+ setMask(m_pixmap.mask());
}
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h
index 7536c09165..3d7974fa82 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow_p.h
+++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h
@@ -60,6 +60,7 @@ public:
void render();
+ void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot);
@@ -72,6 +73,7 @@ private:
QBackingStore *m_backingStore;
QPixmap m_pixmap;
QPoint m_hotSpot;
+ bool m_useCompositing;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 3b2e6ffd29..9c8218b7b5 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -84,7 +84,7 @@ struct QShortcutEntry
QShortcutMap::ContextMatcher contextMatcher;
};
-#if 0 //ndef QT_NO_DEBUG_STREAM
+#ifdef Dump_QShortcutMap
/*! \internal
QDebug operator<< for easy debug output of the shortcut entries.
*/
@@ -99,7 +99,7 @@ static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se)
<< "), owner(" << se->owner << ')';
return dbg;
}
-#endif // QT_NO_DEBUGSTREAM
+#endif // Dump_QShortcutMap
/* \internal
Private data for QShortcutMap
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index d2efeaca28..706786385b 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -88,7 +88,7 @@ static QWindow* topLevelAt(const QPoint &pos)
QBasicDrag::QBasicDrag() :
m_restoreCursor(false), m_eventLoop(0),
m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
- m_drag(0), m_drag_icon_window(0)
+ m_drag(0), m_drag_icon_window(0), m_useCompositing(true)
{
}
@@ -234,6 +234,7 @@ void QBasicDrag::recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos)
// when QDrag is used without a pixmap - QDrag::setPixmap()
m_drag_icon_window = new QShapedPixmapWindow(screen);
+ m_drag_icon_window->setUseCompositing(m_useCompositing);
m_drag_icon_window->setPixmap(m_drag->pixmap());
m_drag_icon_window->setHotspot(m_drag->hotSpot());
m_drag_icon_window->updateGeometry(pos);
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 34679a7540..d5dacd8fd2 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -88,6 +88,9 @@ protected:
bool canDrop() const { return m_can_drop; }
void setCanDrop(bool c) { m_can_drop = c; }
+ bool useCompositing() const { return m_useCompositing; }
+ void setUseCompositing(bool on) { m_useCompositing = on; }
+
Qt::DropAction executedDropAction() const { return m_executed_drop_action; }
void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; }
@@ -105,6 +108,7 @@ private:
bool m_can_drop;
QDrag *m_drag;
QShapedPixmapWindow *m_drag_icon_window;
+ bool m_useCompositing;
};
class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index d4edc0fca1..e262f3f8a4 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -389,25 +389,31 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
void QWindowPrivate::create(bool recursive)
{
Q_Q(QWindow);
+ if (platformWindow)
+ return;
+
+ platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
+ Q_ASSERT(platformWindow);
+
if (!platformWindow) {
- platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
- QObjectList childObjects = q->children();
- for (int i = 0; i < childObjects.size(); i ++) {
- QObject *object = childObjects.at(i);
- if (object->isWindowType()) {
- QWindow *window = static_cast<QWindow *>(object);
- if (recursive)
- window->d_func()->create(true);
- if (window->d_func()->platformWindow)
- window->d_func()->platformWindow->setParent(platformWindow);
- }
- }
+ qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
+ return;
+ }
- if (platformWindow) {
- QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
- QGuiApplication::sendEvent(q, &e);
+ QObjectList childObjects = q->children();
+ for (int i = 0; i < childObjects.size(); i ++) {
+ QObject *object = childObjects.at(i);
+ if (object->isWindowType()) {
+ QWindow *window = static_cast<QWindow *>(object);
+ if (recursive)
+ window->d_func()->create(true);
+ if (window->d_func()->platformWindow)
+ window->d_func()->platformWindow->setParent(platformWindow);
}
}
+
+ QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
+ QGuiApplication::sendEvent(q, &e);
}
void QWindowPrivate::clearFocusObject()
@@ -588,8 +594,7 @@ QWindow *QWindow::parent() const
Setting \a parent to be 0 will make the window become a top level window.
If \a parent is a window created by fromWinId(), then the current window
- will be embedded inside \a parent, if the platform supports it. Window
- embedding is currently supported only by the X11 platform plugin.
+ will be embedded inside \a parent, if the platform supports it.
*/
void QWindow::setParent(QWindow *parent)
{
@@ -2292,10 +2297,10 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapToGlobal(pos);
}
- return pos + d_func()->globalPosition();
+ return pos + d->globalPosition();
}
@@ -2312,10 +2317,10 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapFromGlobal(pos);
}
- return pos - d_func()->globalPosition();
+ return pos - d->globalPosition();
}
@@ -2377,9 +2382,16 @@ QWindow *QWindowPrivate::topLevelWindow() const
Given the handle \a id to a native window, this method creates a QWindow
object which can be used to represent the window when invoking methods like
setParent() and setTransientParent().
- This can be used, on platforms which support it, to embed a window inside a
- container or to make a window stick on top of a window created by another
- process.
+
+ This can be used, on platforms which support it, to embed a QWindow inside a
+ native window, or to embed a native window inside a QWindow.
+
+ If foreign windows are not supported, this function returns 0.
+
+ \note The resulting QWindow should not be used to manipulate the underlying
+ native window (besides re-parenting), or to observe state changes of the
+ native window. Any support for these kind of operations is incidental, highly
+ platform dependent and untested.
\sa setParent()
\sa setTransientParent()
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index a9a4adaddc..4836dde343 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -2076,7 +2076,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->device->ensureActiveTarget();
- if (d->device->context() != QOpenGLContext::currentContext()) {
+ if (d->device->context() != QOpenGLContext::currentContext() || !d->device->context()) {
qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current");
return false;
}
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index 0f9fa6400d..1c6a7937e5 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -39,6 +39,10 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif
+
QT_BEGIN_NAMESPACE
static const char vertex_shader150[] =
@@ -88,6 +92,18 @@ static const char fragment_shader[] =
" gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
"}";
+static const char fragment_shader_external_oes[] =
+ "#extension GL_OES_EGL_image_external : require\n"
+ "varying highp vec2 uv;"
+ "uniform samplerExternalOES textureSampler;\n"
+ "uniform bool swizzle;"
+ "uniform highp float opacity;"
+ "void main() {"
+ " highp vec4 tmpFragColor = texture2D(textureSampler, uv);"
+ " tmpFragColor.a *= opacity;"
+ " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
+ "}";
+
static const GLfloat vertex_buffer_data[] = {
-1,-1, 0,
-1, 1, 0,
@@ -109,14 +125,17 @@ static const GLfloat texture_buffer_data[] = {
class TextureBinder
{
public:
- TextureBinder(GLuint textureId)
+ TextureBinder(GLenum target, GLuint textureId) : m_target(target)
{
- QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, textureId);
+ QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, textureId);
}
~TextureBinder()
{
- QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0);
+ QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, 0);
}
+
+private:
+ GLenum m_target;
};
class QOpenGLTextureBlitterPrivate
@@ -128,74 +147,106 @@ public:
IdentityFlipped
};
- QOpenGLTextureBlitterPrivate()
- : program(0)
- , vertexCoordAttribPos(0)
- , vertexTransformUniformPos(0)
- , textureCoordAttribPos(0)
- , textureTransformUniformPos(0)
- , swizzle(false)
- , swizzleOld(false)
- , opacity(1.0f)
- , opacityOld(0.0f)
- , textureMatrixUniformState(User)
- , vao(new QOpenGLVertexArrayObject())
+ enum ProgramIndex {
+ TEXTURE_2D,
+ TEXTURE_EXTERNAL_OES
+ };
+
+ QOpenGLTextureBlitterPrivate() :
+ swizzle(false),
+ opacity(1.0f),
+ vao(new QOpenGLVertexArrayObject),
+ currentTarget(TEXTURE_2D)
{ }
+ bool buildProgram(ProgramIndex idx, const char *vs, const char *fs);
+
void blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform);
void blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin);
- void prepareProgram(const QMatrix4x4 &vertexTransform)
- {
- vertexBuffer.bind();
- program->setAttributeBuffer(vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
- program->enableAttributeArray(vertexCoordAttribPos);
- vertexBuffer.release();
-
- program->setUniformValue(vertexTransformUniformPos, vertexTransform);
-
- textureBuffer.bind();
- program->setAttributeBuffer(textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
- program->enableAttributeArray(textureCoordAttribPos);
- textureBuffer.release();
-
- if (swizzle != swizzleOld) {
- program->setUniformValue(swizzleUniformPos, swizzle);
- swizzleOld = swizzle;
- }
-
- if (opacity != opacityOld) {
- program->setUniformValue(opacityUniformPos, opacity);
- opacityOld = opacity;
- }
- }
+ void prepareProgram(const QMatrix4x4 &vertexTransform);
QOpenGLBuffer vertexBuffer;
QOpenGLBuffer textureBuffer;
- QScopedPointer<QOpenGLShaderProgram> program;
- GLuint vertexCoordAttribPos;
- GLuint vertexTransformUniformPos;
- GLuint textureCoordAttribPos;
- GLuint textureTransformUniformPos;
- GLuint swizzleUniformPos;
- GLuint opacityUniformPos;
+ struct Program {
+ Program() :
+ vertexCoordAttribPos(0),
+ vertexTransformUniformPos(0),
+ textureCoordAttribPos(0),
+ textureTransformUniformPos(0),
+ swizzleUniformPos(0),
+ opacityUniformPos(0),
+ swizzle(false),
+ opacity(0.0f),
+ textureMatrixUniformState(User)
+ { }
+ QScopedPointer<QOpenGLShaderProgram> glProgram;
+ GLuint vertexCoordAttribPos;
+ GLuint vertexTransformUniformPos;
+ GLuint textureCoordAttribPos;
+ GLuint textureTransformUniformPos;
+ GLuint swizzleUniformPos;
+ GLuint opacityUniformPos;
+ bool swizzle;
+ float opacity;
+ TextureMatrixUniform textureMatrixUniformState;
+ } programs[2];
bool swizzle;
- bool swizzleOld;
float opacity;
- float opacityOld;
- TextureMatrixUniform textureMatrixUniformState;
QScopedPointer<QOpenGLVertexArrayObject> vao;
+ GLenum currentTarget;
};
+static inline QOpenGLTextureBlitterPrivate::ProgramIndex targetToProgramIndex(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D:
+ return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
+ case GL_TEXTURE_EXTERNAL_OES:
+ return QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES;
+ default:
+ qWarning("Unsupported texture target 0x%x", target);
+ return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
+ }
+}
+
+void QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransform)
+{
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
+
+ vertexBuffer.bind();
+ program->glProgram->setAttributeBuffer(program->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ program->glProgram->enableAttributeArray(program->vertexCoordAttribPos);
+ vertexBuffer.release();
+
+ program->glProgram->setUniformValue(program->vertexTransformUniformPos, vertexTransform);
+
+ textureBuffer.bind();
+ program->glProgram->setAttributeBuffer(program->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ program->glProgram->enableAttributeArray(program->textureCoordAttribPos);
+ textureBuffer.release();
+
+ if (swizzle != program->swizzle) {
+ program->glProgram->setUniformValue(program->swizzleUniformPos, swizzle);
+ program->swizzle = swizzle;
+ }
+
+ if (opacity != program->opacity) {
+ program->glProgram->setUniformValue(program->opacityUniformPos, opacity);
+ program->opacity = opacity;
+ }
+}
+
void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
const QMatrix4x4 &vertexTransform,
const QMatrix3x3 &textureTransform)
{
- TextureBinder binder(texture);
+ TextureBinder binder(currentTarget, texture);
prepareProgram(vertexTransform);
- program->setUniformValue(textureTransformUniformPos, textureTransform);
- textureMatrixUniformState = User;
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, textureTransform);
+ program->textureMatrixUniformState = User;
QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6);
}
@@ -204,25 +255,54 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
const QMatrix4x4 &vertexTransform,
QOpenGLTextureBlitter::Origin origin)
{
- TextureBinder binder(texture);
+ TextureBinder binder(currentTarget, texture);
prepareProgram(vertexTransform);
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
if (origin == QOpenGLTextureBlitter::OriginTopLeft) {
- if (textureMatrixUniformState != IdentityFlipped) {
+ if (program->textureMatrixUniformState != IdentityFlipped) {
QMatrix3x3 flipped;
flipped(1,1) = -1;
flipped(1,2) = 1;
- program->setUniformValue(textureTransformUniformPos, flipped);
- textureMatrixUniformState = IdentityFlipped;
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, flipped);
+ program->textureMatrixUniformState = IdentityFlipped;
}
- } else if (textureMatrixUniformState != Identity) {
- program->setUniformValue(textureTransformUniformPos, QMatrix3x3());
- textureMatrixUniformState = Identity;
+ } else if (program->textureMatrixUniformState != Identity) {
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, QMatrix3x3());
+ program->textureMatrixUniformState = Identity;
}
QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6);
}
+bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs, const char *fs)
+{
+ Program *p = &programs[idx];
+
+ p->glProgram.reset(new QOpenGLShaderProgram);
+
+ p->glProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vs);
+ p->glProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fs);
+ p->glProgram->link();
+ if (!p->glProgram->isLinked()) {
+ qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << p->glProgram->log();
+ return false;
+ }
+
+ p->glProgram->bind();
+
+ p->vertexCoordAttribPos = p->glProgram->attributeLocation("vertexCoord");
+ p->vertexTransformUniformPos = p->glProgram->uniformLocation("vertexTransform");
+ p->textureCoordAttribPos = p->glProgram->attributeLocation("textureCoord");
+ p->textureTransformUniformPos = p->glProgram->uniformLocation("textureTransform");
+ p->swizzleUniformPos = p->glProgram->uniformLocation("swizzle");
+ p->opacityUniformPos = p->glProgram->uniformLocation("opacity");
+
+ p->glProgram->setUniformValue(p->swizzleUniformPos, false);
+
+ return true;
+}
+
QOpenGLTextureBlitter::QOpenGLTextureBlitter()
: d_ptr(new QOpenGLTextureBlitterPrivate)
{
@@ -241,28 +321,21 @@ bool QOpenGLTextureBlitter::create()
Q_D(QOpenGLTextureBlitter);
- if (d->program)
+ if (d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram)
return true;
- d->program.reset(new QOpenGLShaderProgram());
-
QSurfaceFormat format = currentContext->format();
-
if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) {
- d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader150);
- d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader150);
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader150, fragment_shader150))
+ return false;
} else {
- d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader);
- d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader);
- }
- d->program->link();
- if (!d->program->isLinked()) {
- qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << d->program->log();
- return false;
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader, fragment_shader))
+ return false;
+ if (supportsExternalOESTarget())
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES, vertex_shader, fragment_shader_external_oes))
+ return false;
}
- d->program->bind();
-
// Create and bind the VAO, if supported.
QOpenGLVertexArrayObject::Binder vaoBinder(d->vao.data());
@@ -276,22 +349,13 @@ bool QOpenGLTextureBlitter::create()
d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data));
d->textureBuffer.release();
- d->vertexCoordAttribPos = d->program->attributeLocation("vertexCoord");
- d->vertexTransformUniformPos = d->program->uniformLocation("vertexTransform");
- d->textureCoordAttribPos = d->program->attributeLocation("textureCoord");
- d->textureTransformUniformPos = d->program->uniformLocation("textureTransform");
- d->swizzleUniformPos = d->program->uniformLocation("swizzle");
- d->opacityUniformPos = d->program->uniformLocation("opacity");
-
- d->program->setUniformValue(d->swizzleUniformPos,false);
-
return true;
}
bool QOpenGLTextureBlitter::isCreated() const
{
Q_D(const QOpenGLTextureBlitter);
- return d->program;
+ return d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram;
}
void QOpenGLTextureBlitter::destroy()
@@ -299,36 +363,45 @@ void QOpenGLTextureBlitter::destroy()
if (!isCreated())
return;
Q_D(QOpenGLTextureBlitter);
- d->program.reset();
+ d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram.reset();
+ d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES].glProgram.reset();
d->vertexBuffer.destroy();
d->textureBuffer.destroy();
d->vao.reset();
}
-void QOpenGLTextureBlitter::bind()
+bool QOpenGLTextureBlitter::supportsExternalOESTarget() const
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ return ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external");
+}
+
+void QOpenGLTextureBlitter::bind(GLenum target)
{
Q_D(QOpenGLTextureBlitter);
if (d->vao->isCreated())
d->vao->bind();
- d->program->bind();
+ d->currentTarget = target;
+ QOpenGLTextureBlitterPrivate::Program *p = &d->programs[targetToProgramIndex(target)];
+ p->glProgram->bind();
d->vertexBuffer.bind();
- d->program->setAttributeBuffer(d->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
- d->program->enableAttributeArray(d->vertexCoordAttribPos);
+ p->glProgram->setAttributeBuffer(p->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ p->glProgram->enableAttributeArray(p->vertexCoordAttribPos);
d->vertexBuffer.release();
d->textureBuffer.bind();
- d->program->setAttributeBuffer(d->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
- d->program->enableAttributeArray(d->textureCoordAttribPos);
+ p->glProgram->setAttributeBuffer(p->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ p->glProgram->enableAttributeArray(p->textureCoordAttribPos);
d->textureBuffer.release();
}
void QOpenGLTextureBlitter::release()
{
Q_D(QOpenGLTextureBlitter);
- d->program->release();
+ d->programs[targetToProgramIndex(d->currentTarget)].glProgram->release();
if (d->vao->isCreated())
d->vao->release();
}
diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h
index 8f7eae1c32..ebf3a4bfbb 100644
--- a/src/gui/opengl/qopengltextureblitter_p.h
+++ b/src/gui/opengl/qopengltextureblitter_p.h
@@ -68,7 +68,9 @@ public:
bool isCreated() const;
void destroy();
- void bind();
+ bool supportsExternalOESTarget() const;
+
+ void bind(GLenum target = GL_TEXTURE_2D);
void release();
void setSwizzleRB(bool swizzle);
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 1012ed7c6d..3f30c061dc 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -2075,7 +2075,7 @@ QColor QColor::fromHsl(int h, int s, int l, int a)
|| s < 0 || s > 255
|| l < 0 || l > 255
|| a < 0 || a > 255) {
- qWarning("QColor::fromHsv: HSV parameters out of range");
+ qWarning("QColor::fromHsl: HSL parameters out of range");
return QColor();
}
@@ -2107,7 +2107,7 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a)
|| (s < qreal(0.0) || s > qreal(1.0))
|| (l < qreal(0.0) || l > qreal(1.0))
|| (a < qreal(0.0) || a > qreal(1.0))) {
- qWarning("QColor::fromHsvF: HSV parameters out of range");
+ qWarning("QColor::fromHslF: HSL parameters out of range");
return QColor();
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 64a363868a..6cfc4b9307 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -503,14 +503,16 @@ static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const
template<bool RGBA, bool maskAlpha>
static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
{
+ if (count <= 0)
+ return;
+
const __m128i amask = _mm_set1_epi32(0xff000000);
int i = 0;
- if (((uintptr_t)buffer & 0xf) && count > 0) {
+ for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) {
uint s = *src++;
if (RGBA)
s = RGBA2ARGB(s);
*buffer++ = QRgba64::fromArgb32(s);
- i++;
}
for (; i < count-3; i += 4) {
__m128i vs = _mm_loadu_si128((const __m128i*)src);
@@ -641,15 +643,18 @@ static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const ui
template<QtPixelOrder PixelOrder>
static inline void qConvertA2RGB30PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
{
+ if (count <= 0)
+ return;
+
const __m128i rmask = _mm_set1_epi32(0x3ff00000);
const __m128i gmask = _mm_set1_epi32(0x000ffc00);
const __m128i bmask = _mm_set1_epi32(0x000003ff);
const __m128i afactor = _mm_set1_epi16(0x5555);
int i = 0;
- if (((uintptr_t)buffer & 0xf) && count > 0) {
+
+ for (; ((uintptr_t)buffer & 0xf) && i < count; ++i)
*buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
- i++;
- }
+
for (; i < count-3; i += 4) {
__m128i vs = _mm_loadu_si128((const __m128i*)src);
src += 4;
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 0f81f09f60..47483b2869 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -377,8 +377,8 @@ QByteArray QPdf::generateDashes(const QPen &pen)
s << dw;
}
s << ']';
- //qDebug() << "dasharray: pen has" << dasharray;
- //qDebug() << " => " << result;
+ s << pen.dashOffset() * w;
+ s << " d\n";
return result;
}
@@ -1209,7 +1209,7 @@ void QPdfEngine::setPen()
}
*d->currentPage << pdfJoinStyle << "j ";
- *d->currentPage << QPdf::generateDashes(d->pen) << " 0 d\n";
+ *d->currentPage << QPdf::generateDashes(d->pen);
}
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index c86fdebea5..dd02e24676 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -48,6 +48,16 @@
#include <qpa/qplatformgraphicsbuffer.h>
#include <qpa/qplatformgraphicsbufferhelper.h>
+#ifndef GL_TEXTURE_BASE_LEVEL
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#endif
+#ifndef GL_TEXTURE_MAX_LEVEL
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#endif
+#ifndef GL_UNPACK_ROW_LENGTH
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#endif
+
QT_BEGIN_NAMESPACE
class QPlatformBackingStorePrivate
@@ -311,12 +321,11 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
-#endif
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -435,18 +444,16 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
image = image.convertToFormat(QImage::Format_RGBA8888);
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
-
if (resized) {
if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
-#endif
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -459,15 +466,13 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect;
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- } else
-#endif
- {
+ } else {
// if the rect is wide enough it's cheaper to just
// extend it instead of doing an image copy
if (rect.width() >= imageRect.width() / 2) {
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index 54d7fe1738..686a00e42a 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -45,6 +45,7 @@
QT_BEGIN_NAMESPACE
+extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio);
static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio)
{
// We might use the fileName for loading if url loading fails
@@ -63,19 +64,8 @@ static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePi
if (targetDevicePixelRatio <= 1.0)
return fileName;
- // try to find a 2x version
-
- const int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
- if (dotIndex != -1) {
- QString at2xfileName = fileName;
- at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName)) {
- fileName = at2xfileName;
- *url = QUrl(fileName);
- }
- }
-
- return fileName;
+ // try to find a Nx version
+ return qt_findAtNxFile(fileName, targetDevicePixelRatio);
}
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index 4c92e5d000..354dfeb78c 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -231,13 +231,13 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
QOpenUrlHandlerRegistry *registry = handlerRegistry();
QMutexLocker locker(&registry->mutex);
if (!receiver) {
- registry->handlers.remove(scheme);
+ registry->handlers.remove(scheme.toLower());
return;
}
QOpenUrlHandlerRegistry::Handler h;
h.receiver = receiver;
h.name = method;
- registry->handlers.insert(scheme, h);
+ registry->handlers.insert(scheme.toLower(), h);
QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
registry, SLOT(handlerDestroyed(QObject*)));
}
diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf
index 2a8e577dda..87e322d6c0 100644
--- a/src/network/doc/qtnetwork.qdocconf
+++ b/src/network/doc/qtnetwork.qdocconf
@@ -4,7 +4,7 @@ project = QtNetwork
description = Qt Network Reference Documentation
version = $QT_VERSION
-examplesinstallpath = network
+examplesinstallpath = qtbase/network
qhp.projects = QtNetwork
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index fab4d1c532..cba1ac52be 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -806,7 +806,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS
QAbstractSocketEngine::PacketHeaderOptions options)
{
// we use quintptr to force the alignment
- quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int)) + sizeof(quintptr) - 1) / sizeof(quintptr)];
+ quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))
+#if !defined(IP_PKTINFO) && defined(IP_RECVIF) && defined(Q_OS_BSD4)
+ + CMSG_SPACE(sizeof(sockaddr_dl))
+#endif
+ + sizeof(quintptr) - 1) / sizeof(quintptr)];
struct msghdr msg;
struct iovec vec;
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index 44de7f8526..d41bd4d313 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -420,6 +420,16 @@ void QNativeSocketEngine::close()
{
Q_D(QNativeSocketEngine);
+ if (d->closingDown)
+ return;
+
+ d->closingDown = true;
+
+
+ d->notifyOnRead = false;
+ d->notifyOnWrite = false;
+ d->notifyOnException = false;
+
if (d->connectOp) {
ComPtr<IAsyncInfo> info;
d->connectOp.As(&info);
@@ -440,7 +450,6 @@ void QNativeSocketEngine::close()
}
if (socket) {
- d->closingDown = true;
socket->Close();
d->socketDescriptor = -1;
}
@@ -498,6 +507,14 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen)
if (d->socketType != QAbstractSocket::TcpSocket)
return -1;
+ // There will be a read notification when the socket was closed by the remote host. If that
+ // happens and there isn't anything left in the buffer, we have to return -1 in order to signal
+ // the closing of the socket.
+ if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) {
+ close();
+ return -1;
+ }
+
QMutexLocker mutexLocker(&d->readMutex);
return d->readBytes.read(data, maxlen);
}
@@ -1184,8 +1201,16 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async
if (wasDeleted || isDeletingChildren)
return S_OK;
- if (status == Error || status == Canceled)
+ // A read in UnconnectedState will close the socket and return -1 and thus tell the caller,
+ // that the connection was closed. The socket cannot be closed here, as the subsequent read
+ // might fail then.
+ if (status == Error || status == Canceled) {
+ setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ if (notifyOnRead)
+ emit q->readReady();
return S_OK;
+ }
ComPtr<IBuffer> buffer;
HRESULT hr = asyncInfo->GetResults(&buffer);
@@ -1194,7 +1219,13 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async
UINT32 bufferLength;
hr = buffer->get_Length(&bufferLength);
Q_ASSERT_SUCCEEDED(hr);
+ // A zero sized buffer length signals, that the remote host closed the connection. The socket
+ // cannot be closed though, as the following read might have socket descriptor -1 and thus and
+ // the closing of the socket won't be communicated to the caller. So only the error is set. The
+ // actual socket close happens inside of read.
if (!bufferLength) {
+ setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
if (notifyOnRead)
emit q->readReady();
return S_OK;
diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf
index 6ff6cae2cb..3c5fc280bd 100644
--- a/src/opengl/doc/qtopengl.qdocconf
+++ b/src/opengl/doc/qtopengl.qdocconf
@@ -21,7 +21,7 @@ imagedirs += images \
depends += qtdoc qtcore qtgui qtwidgets qmake
-examplesinstallpath = opengl
+examplesinstallpath = qtbase/opengl
# The following parameters are for creating a qhp file, the qhelpgenerator
# program can convert the qhp file into a qch file which can be opened in
diff --git a/src/platformheaders/doc/qtplatformheaders.qdocconf b/src/platformheaders/doc/qtplatformheaders.qdocconf
index 1c09971e23..fc8a9d8731 100644
--- a/src/platformheaders/doc/qtplatformheaders.qdocconf
+++ b/src/platformheaders/doc/qtplatformheaders.qdocconf
@@ -4,7 +4,7 @@ project = QtPlatformHeaders
description = Qt Platform Headers Reference Documentation
version = $QT_VERSION
-examplesinstallpath = qtplatformheaders
+examplesinstallpath = qtbase/qtplatformheaders
qhp.projects = QtPlatformHeaders
diff --git a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri b/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri
deleted file mode 100644
index 9a19d3c278..0000000000
--- a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-mac {
- HEADERS += $$PWD/qcfsocketnotifier_p.h
- SOURCES += $$PWD/qcfsocketnotifier.cpp
-}
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index 457efd68fb..1cab1e556f 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -1,9 +1,11 @@
contains(QT_CONFIG,egl) {
HEADERS += \
- $$PWD/qeglconvenience_p.h
+ $$PWD/qeglconvenience_p.h \
+ $$PWD/qeglstreamconvenience_p.h
SOURCES += \
- $$PWD/qeglconvenience.cpp
+ $$PWD/qeglconvenience.cpp \
+ $$PWD/qeglstreamconvenience.cpp
contains(QT_CONFIG,opengl) {
HEADERS += $$PWD/qeglplatformcontext_p.h \
diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp b/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp
new file mode 100644
index 0000000000..2ace144811
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglstreamconvenience_p.h"
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+QEGLStreamConvenience::QEGLStreamConvenience()
+ : initialized(false),
+ has_egl_platform_device(false),
+ has_egl_device_base(false),
+ has_egl_stream(false),
+ has_egl_stream_producer_eglsurface(false),
+ has_egl_stream_consumer_egloutput(false),
+ has_egl_output_drm(false),
+ has_egl_output_base(false),
+ has_egl_stream_cross_process_fd(false),
+ has_egl_stream_consumer_gltexture(false)
+{
+ const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (!extensions) {
+ qWarning("Failed to query EGL extensions");
+ return;
+ }
+
+ query_devices = reinterpret_cast<PFNEGLQUERYDEVICESEXTPROC>(eglGetProcAddress("eglQueryDevicesEXT"));
+ query_device_string = reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(eglGetProcAddress("eglQueryDeviceStringEXT"));
+ get_platform_display = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+
+ has_egl_device_base = strstr(extensions, "EGL_EXT_device_base");
+ has_egl_platform_device = strstr(extensions, "EGL_EXT_platform_device");
+}
+
+void QEGLStreamConvenience::initialize(EGLDisplay dpy)
+{
+ if (initialized)
+ return;
+
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ qWarning("Failed to bind OpenGL ES API");
+ return;
+ }
+
+ const char *extensions = eglQueryString(dpy, EGL_EXTENSIONS);
+ if (!extensions) {
+ qWarning("Failed to query EGL extensions");
+ return;
+ }
+
+ create_stream = reinterpret_cast<PFNEGLCREATESTREAMKHRPROC>(eglGetProcAddress("eglCreateStreamKHR"));
+ destroy_stream = reinterpret_cast<PFNEGLDESTROYSTREAMKHRPROC>(eglGetProcAddress("eglDestroyStreamKHR"));
+ stream_attrib = reinterpret_cast<PFNEGLSTREAMATTRIBKHRPROC>(eglGetProcAddress("eglStreamAttribKHR"));
+ query_stream = reinterpret_cast<PFNEGLQUERYSTREAMKHRPROC>(eglGetProcAddress("eglQueryStreamKHR"));
+ query_stream_u64 = reinterpret_cast<PFNEGLQUERYSTREAMU64KHRPROC>(eglGetProcAddress("eglQueryStreamu64KHR"));
+ create_stream_producer_surface = reinterpret_cast<PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC>(eglGetProcAddress("eglCreateStreamProducerSurfaceKHR"));
+ stream_consumer_output = reinterpret_cast<PFNEGLSTREAMCONSUMEROUTPUTEXTPROC>(eglGetProcAddress("eglStreamConsumerOutputEXT"));
+ get_output_layers = reinterpret_cast<PFNEGLGETOUTPUTLAYERSEXTPROC>(eglGetProcAddress("eglGetOutputLayersEXT"));
+ get_output_ports = reinterpret_cast<PFNEGLGETOUTPUTPORTSEXTPROC>(eglGetProcAddress("eglGetOutputPortsEXT"));
+ output_layer_attrib = reinterpret_cast<PFNEGLOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglOutputLayerAttribEXT"));
+ query_output_layer_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputLayerAttribEXT"));
+ query_output_layer_string = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputLayerStringEXT"));
+ query_output_port_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputPortAttribEXT"));
+ query_output_port_string = reinterpret_cast<PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputPortStringEXT"));
+ get_stream_file_descriptor = reinterpret_cast<PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglGetStreamFileDescriptorKHR"));
+ create_stream_from_file_descriptor = reinterpret_cast<PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglCreateStreamFromFileDescriptorKHR"));
+ stream_consumer_gltexture = reinterpret_cast<PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC>(eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR"));
+ stream_consumer_acquire = reinterpret_cast<PFNEGLSTREAMCONSUMERACQUIREKHRPROC>(eglGetProcAddress("eglStreamConsumerAcquireKHR"));
+ stream_consumer_release = reinterpret_cast<PFNEGLSTREAMCONSUMERRELEASEKHRPROC>(eglGetProcAddress("eglStreamConsumerReleaseKHR"));
+
+ has_egl_stream = strstr(extensions, "EGL_KHR_stream");
+ has_egl_stream_producer_eglsurface = strstr(extensions, "EGL_KHR_stream_producer_eglsurface");
+ has_egl_stream_consumer_egloutput = strstr(extensions, "EGL_EXT_stream_consumer_egloutput");
+ has_egl_output_drm = strstr(extensions, "EGL_EXT_output_drm");
+ has_egl_output_base = strstr(extensions, "EGL_EXT_output_base");
+ has_egl_stream_cross_process_fd = strstr(extensions, "EGL_KHR_stream_cross_process_fd");
+ has_egl_stream_consumer_gltexture = strstr(extensions, "EGL_KHR_stream_consumer_gltexture");
+
+ initialized = true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
new file mode 100644
index 0000000000..12787d03ae
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLSTREAMCONVENIENCE_H
+#define QEGLSTREAMCONVENIENCE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qglobal.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+// This provides runtime EGLDevice/Output/Stream support even when eglext.h in
+// the sysroot is not up-to-date.
+
+#ifndef EGL_VERSION_1_5
+typedef intptr_t EGLAttrib;
+#endif
+
+#ifndef EGL_EXT_platform_base
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
+#endif
+
+#ifndef EGL_EXT_device_base
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0))
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+#endif
+
+#ifndef EGL_EXT_output_base
+typedef void *EGLOutputLayerEXT;
+typedef void *EGLOutputPortEXT;
+#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0)
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#endif
+
+#ifndef EGL_KHR_stream
+typedef void *EGLStreamKHR;
+typedef quint64 EGLuint64KHR;
+#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_STREAM_BIT_KHR 0x0800
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+
+#ifndef EGL_KHR_stream_cross_process_fd
+typedef int EGLNativeFileDescriptorKHR;
+#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+
+#ifndef EGL_KHR_stream_consumer_gltexture
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+
+#ifndef EGL_EXT_stream_consumer_egloutput
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#endif
+
+#ifndef EGL_EXT_platform_device
+#define EGL_PLATFORM_DEVICE_EXT 0x313F
+#endif
+
+#ifndef EGL_EXT_device_drm
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
+#endif
+
+#ifndef EGL_EXT_output_drm
+#define EGL_DRM_CRTC_EXT 0x3234
+#define EGL_DRM_PLANE_EXT 0x3235
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QEGLStreamConvenience
+{
+public:
+ QEGLStreamConvenience();
+ void initialize(EGLDisplay dpy);
+
+ PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display;
+ PFNEGLQUERYDEVICESEXTPROC query_devices;
+ PFNEGLQUERYDEVICESTRINGEXTPROC query_device_string;
+ PFNEGLCREATESTREAMKHRPROC create_stream;
+ PFNEGLDESTROYSTREAMKHRPROC destroy_stream;
+ PFNEGLSTREAMATTRIBKHRPROC stream_attrib;
+ PFNEGLQUERYSTREAMKHRPROC query_stream;
+ PFNEGLQUERYSTREAMU64KHRPROC query_stream_u64;
+ PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC create_stream_producer_surface;
+ PFNEGLSTREAMCONSUMEROUTPUTEXTPROC stream_consumer_output;
+ PFNEGLGETOUTPUTLAYERSEXTPROC get_output_layers;
+ PFNEGLGETOUTPUTPORTSEXTPROC get_output_ports;
+ PFNEGLOUTPUTLAYERATTRIBEXTPROC output_layer_attrib;
+ PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC query_output_layer_attrib;
+ PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC query_output_layer_string;
+ PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC query_output_port_attrib;
+ PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC query_output_port_string;
+ PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC get_stream_file_descriptor;
+ PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC create_stream_from_file_descriptor;
+ PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC stream_consumer_gltexture;
+ PFNEGLSTREAMCONSUMERACQUIREKHRPROC stream_consumer_acquire;
+ PFNEGLSTREAMCONSUMERRELEASEKHRPROC stream_consumer_release;
+
+ bool initialized;
+
+ bool has_egl_platform_device;
+ bool has_egl_device_base;
+ bool has_egl_stream;
+ bool has_egl_stream_producer_eglsurface;
+ bool has_egl_stream_consumer_egloutput;
+ bool has_egl_output_drm;
+ bool has_egl_output_base;
+ bool has_egl_stream_cross_process_fd;
+ bool has_egl_stream_consumer_gltexture;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/platformsupport/eventdispatchers/eventdispatchers.pri b/src/platformsupport/eventdispatchers/eventdispatchers.pri
index c9bbe1f5b7..6e16a46b34 100644
--- a/src/platformsupport/eventdispatchers/eventdispatchers.pri
+++ b/src/platformsupport/eventdispatchers/eventdispatchers.pri
@@ -8,14 +8,6 @@ HEADERS +=\
$$PWD/qgenericunixeventdispatcher_p.h\
}
-ios {
-OBJECTIVE_SOURCES +=\
- $$PWD/qeventdispatcher_cf.mm
-
-HEADERS +=\
- $$PWD/qeventdispatcher_cf_p.h
-}
-
contains(QT_CONFIG, glib) {
SOURCES +=$$PWD/qeventdispatcher_glib.cpp
HEADERS +=$$PWD/qeventdispatcher_glib_p.h
diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
index 8ce1ed2d2b..bb3ea6981a 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
+++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
@@ -39,6 +39,10 @@
#include "qopenglcompositorbackingstore_p.h"
#include "qopenglcompositor_p.h"
+#ifndef GL_UNPACK_ROW_LENGTH
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -100,29 +104,39 @@ void QOpenGLCompositorBackingStore::updateTexture()
QRegion fixed;
QRect imageRect = m_image.rect();
- foreach (const QRect &rect, m_dirty.rects()) {
- // intersect with image rect to be sure
- QRect r = imageRect & rect;
-
- // if the rect is wide enough it's cheaper to just
- // extend it instead of doing an image copy
- if (r.width() >= imageRect.width() / 2) {
- r.setX(0);
- r.setWidth(imageRect.width());
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ foreach (const QRect &rect, m_dirty.rects()) {
+ QRect r = imageRect & rect;
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image.width());
+ glTexSubImage2D(GL_TEXTURE_2D, 0, r.x(), r.y(), r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.constScanLine(r.y()) + r.x() * 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
-
- fixed |= r;
- }
-
- foreach (const QRect &rect, fixed.rects()) {
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there's no gap between scanlines
- if (rect.width() == imageRect.width()) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.constScanLine(rect.y()));
- } else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.copy(rect).constBits());
+ } else {
+ foreach (const QRect &rect, m_dirty.rects()) {
+ // intersect with image rect to be sure
+ QRect r = imageRect & rect;
+
+ // if the rect is wide enough it's cheaper to just
+ // extend it instead of doing an image copy
+ if (r.width() >= imageRect.width() / 2) {
+ r.setX(0);
+ r.setWidth(imageRect.width());
+ }
+
+ fixed |= r;
+ }
+ foreach (const QRect &rect, fixed.rects()) {
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's no gap between scanlines
+ if (rect.width() == imageRect.width()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.copy(rect).constBits());
+ }
}
}
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
index 34e2ed3c9b..1ea6d0eb69 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -7,7 +7,6 @@ mac:LIBS_PRIVATE += -lz
DEFINES += QT_NO_CAST_FROM_ASCII
PRECOMPILED_HEADER = ../corelib/global/qt_pch.h
-include(cfsocketnotifier/cfsocketnotifier.pri)
include(cglconvenience/cglconvenience.pri)
include(eglconvenience/eglconvenience.pri)
include(eventdispatchers/eventdispatchers.pri)
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index c7c82e255c..99cb58830c 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -432,7 +432,6 @@ static void *startMainMethod(void */*data*/)
params[i] = static_cast<const char *>(m_applicationParams[i].constData());
int ret = m_main(m_applicationParams.length(), const_cast<char **>(params.data()));
- Q_UNUSED(ret);
if (m_mainLibraryHnd) {
int res = dlclose(m_mainLibraryHnd);
@@ -448,6 +447,8 @@ static void *startMainMethod(void */*data*/)
if (vm != 0)
vm->DetachCurrentThread();
+ // We must call exit() to ensure that all global objects will be destructed
+ exit(ret);
return 0;
}
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index 4466d28128..8aa7a6b583 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -127,16 +127,17 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
dragBoard.setMimeData(m_drag->mimeData(), QMacPasteboard::LazyRequest);
NSPoint event_location = [m_lastEvent locationInWindow];
- NSPoint local_point = [m_lastView convertPoint:event_location fromView:nil];
- local_point.x -= hotSpot.x();
+ NSWindow *theWindow = [m_lastEvent window];
+ Q_ASSERT(theWindow != nil);
+ event_location.x -= hotSpot.x();
CGFloat flippedY = pm.height() - hotSpot.y();
- local_point.y += flippedY;
- NSSize mouseOffset = NSMakeSize(0.0, 0.0);
+ event_location.y -= flippedY;
+ NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0);
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- [m_lastView dragImage:nsimage
- at:local_point
- offset:mouseOffset
+ [theWindow dragImage:nsimage
+ at:event_location
+ offset:mouseOffset_unused
event:m_lastEvent
pasteboard:pboard
source:m_lastView
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 4a2cb42f87..8a2a478a72 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -83,8 +83,8 @@
#include <QtCore/qstack.h>
#include <QtGui/qwindowdefs.h>
#include <QtCore/private/qabstracteventdispatcher_p.h>
+#include <QtCore/private/qcfsocketnotifier_p.h>
#include <QtCore/private/qtimerinfo_unix_p.h>
-#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
#include <CoreFoundation/CoreFoundation.h>
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 8ad80333f8..f51c21ee9b 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -634,10 +634,14 @@ QString qt_mac_applicationName()
int qt_mac_mainScreenHeight()
{
QMacAutoReleasePool pool;
- // The first screen in the screens array is documented
- // to have the (0,0) origin.
- NSRect screenFrame = [[[NSScreen screens] firstObject] frame];
- return screenFrame.size.height;
+ NSArray *screens = [NSScreen screens];
+ if ([screens count] > 0) {
+ // The first screen in the screens array is documented
+ // to have the (0,0) origin.
+ NSRect screenFrame = [[screens objectAtIndex: 0] frame];
+ return screenFrame.size.height;
+ }
+ return 0;
}
int qt_mac_flipYCoordinate(int y)
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index adfef81117..4c6b1bac9f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -894,10 +894,13 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
Qt::WindowType type = window()->type();
if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) {
NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior];
- if (flags & Qt::WindowFullscreenButtonHint)
+ if (flags & Qt::WindowFullscreenButtonHint) {
behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
- else
+ behavior &= ~NSWindowCollectionBehaviorFullScreenAuxiliary;
+ } else {
+ behavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
+ }
[m_nsWindow setCollectionBehavior:behavior];
}
setWindowZoomButton(flags);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
index 2274c5b228..393ddd14a5 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
@@ -8,6 +8,8 @@ QT += core-private gui-private platformsupport-private eglfs_device_lib-private
INCLUDEPATH += $$PWD/../..
+DEFINES += MESA_EGL_NO_X11_HEADERS
+
CONFIG += egl
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index 2f32bd73a3..1ddcb3b862 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -45,6 +45,7 @@ QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration()
, m_drm_connector(Q_NULLPTR)
, m_drm_encoder(Q_NULLPTR)
, m_drm_crtc(0)
+ , m_funcs(Q_NULLPTR)
{
qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created");
}
@@ -54,7 +55,7 @@ void QEglFSKmsEglDeviceIntegration::platformInit()
if (!query_egl_device())
qFatal("Could not set up EGL device!");
- const char *deviceName = m_query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT);
+ const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT);
if (!deviceName)
qFatal("Failed to query device name from EGLDevice");
@@ -76,6 +77,9 @@ void QEglFSKmsEglDeviceIntegration::platformDestroy()
qErrnoWarning("Could not close DRM device");
m_dri_fd = -1;
+
+ delete m_funcs;
+ m_funcs = Q_NULLPTR;
}
EGLNativeDisplayType QEglFSKmsEglDeviceIntegration::platformDisplay() const
@@ -87,18 +91,13 @@ EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nat
{
qCDebug(qLcEglfsKmsDebug, "Creating display");
- const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
-
- m_get_platform_display = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
- m_has_egl_platform_device = extensions && strstr(extensions, "EGL_EXT_platform_device");
-
EGLDisplay display;
- if (!m_has_egl_platform_device) {
+ if (m_funcs->has_egl_platform_device) {
+ display = m_funcs->get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, Q_NULLPTR);
+ } else {
qWarning("EGL_EXT_platform_device not available, falling back to legacy path!");
display = eglGetDisplay(nativeDisplay);
- } else {
- display = m_get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, Q_NULLPTR);
}
if (display == EGL_NO_DISPLAY)
@@ -165,7 +164,7 @@ public:
void QEglJetsonTK1Window::invalidateSurface()
{
QEglFSWindow::invalidateSurface();
- m_integration->m_destroy_stream(screen()->display(), m_egl_stream);
+ m_integration->m_funcs->destroy_stream(screen()->display(), m_egl_stream);
}
void QEglJetsonTK1Window::resetSurface()
@@ -176,7 +175,7 @@ void QEglJetsonTK1Window::resetSurface()
EGLOutputLayerEXT layer = EGL_NO_OUTPUT_LAYER_EXT;
EGLint count;
- m_egl_stream = m_integration->m_create_stream(display, Q_NULLPTR);
+ m_egl_stream = m_integration->m_funcs->create_stream(display, Q_NULLPTR);
if (m_egl_stream == EGL_NO_STREAM_KHR) {
qWarning("resetSurface: Couldn't create EGLStream for native window");
return;
@@ -184,7 +183,7 @@ void QEglJetsonTK1Window::resetSurface()
qCDebug(qLcEglfsKmsDebug, "Created stream %p on display %p", m_egl_stream, display);
- if (!m_integration->m_get_output_layers(display, Q_NULLPTR, Q_NULLPTR, 0, &count) || count == 0) {
+ if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, Q_NULLPTR, 0, &count) || count == 0) {
qWarning("No output layers found");
return;
}
@@ -194,20 +193,20 @@ void QEglJetsonTK1Window::resetSurface()
QVector<EGLOutputLayerEXT> layers;
layers.resize(count);
EGLint actualCount;
- if (!m_integration->m_get_output_layers(display, Q_NULLPTR, layers.data(), count, &actualCount)) {
+ if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, layers.data(), count, &actualCount)) {
qWarning("Failed to get layers");
return;
}
for (int i = 0; i < actualCount; ++i) {
EGLAttrib id;
- if (m_integration->m_query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) {
- qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], id);
+ if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) {
+ qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], (int) id);
if (id == EGLAttrib(m_integration->m_drm_crtc))
layer = layers[i];
- } else if (m_integration->m_query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) {
+ } else if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) {
// Not used yet, just for debugging.
- qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], id);
+ qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], (int) id);
} else {
qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - unknown", i, layers[i]);
}
@@ -227,7 +226,7 @@ void QEglJetsonTK1Window::resetSurface()
qCDebug(qLcEglfsKmsDebug, "Using layer %p", layer);
- if (!m_integration->m_stream_consumer_output(display, m_egl_stream, layer))
+ if (!m_integration->m_funcs->stream_consumer_output(display, m_egl_stream, layer))
qWarning("resetSurface: Unable to connect stream");
m_config = QEglFSIntegration::chooseConfig(display, m_integration->surfaceFormatFor(window()->requestedFormat()));
@@ -244,7 +243,7 @@ void QEglJetsonTK1Window::resetSurface()
EGL_NONE
};
- m_surface = m_integration->m_create_stream_producer_surface(display, m_config, m_egl_stream, stream_producer_attribs);
+ m_surface = m_integration->m_funcs->create_stream_producer_surface(display, m_config, m_egl_stream, stream_producer_attribs);
if (m_surface == EGL_NO_SURFACE)
return;
@@ -255,7 +254,9 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
{
QEglJetsonTK1Window *eglWindow = new QEglJetsonTK1Window(window, this);
- if (!const_cast<QEglFSKmsEglDeviceIntegration *>(this)->query_egl_extensions(eglWindow->screen()->display()))
+ m_funcs->initialize(eglWindow->screen()->display());
+ if (!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream
+ && m_funcs->has_egl_stream_producer_eglsurface && m_funcs->has_egl_stream_consumer_egloutput))
qFatal("Required extensions missing!");
return eglWindow;
@@ -385,21 +386,12 @@ bool QEglFSKmsEglDeviceIntegration::setup_kms()
bool QEglFSKmsEglDeviceIntegration::query_egl_device()
{
- const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
- if (!extensions) {
- qWarning("eglQueryString failed");
- return false;
- }
-
- m_has_egl_device_base = strstr(extensions, "EGL_EXT_device_base");
- m_query_devices = reinterpret_cast<PFNEGLQUERYDEVICESEXTPROC>(eglGetProcAddress("eglQueryDevicesEXT"));
- m_query_device_string = reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(eglGetProcAddress("eglQueryDeviceStringEXT"));
-
- if (!m_has_egl_device_base || !m_query_devices || !m_query_device_string)
+ m_funcs = new QEGLStreamConvenience;
+ if (!m_funcs->has_egl_device_base)
qFatal("EGL_EXT_device_base missing");
EGLint num_devices = 0;
- if (m_query_devices(1, &m_egl_device, &num_devices) != EGL_TRUE) {
+ if (m_funcs->query_devices(1, &m_egl_device, &num_devices) != EGL_TRUE) {
qWarning("eglQueryDevicesEXT failed: eglError: %x", eglGetError());
return false;
}
@@ -414,51 +406,4 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device()
return true;
}
-bool QEglFSKmsEglDeviceIntegration::query_egl_extensions(EGLDisplay display)
-{
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- qWarning() << Q_FUNC_INFO << "failed to bind EGL_OPENGL_ES_API";
- return false;
- }
-
- m_create_stream = reinterpret_cast<PFNEGLCREATESTREAMKHRPROC>(eglGetProcAddress("eglCreateStreamKHR"));
- m_destroy_stream = reinterpret_cast<PFNEGLDESTROYSTREAMKHRPROC>(eglGetProcAddress("eglDestroyStreamKHR"));
- m_stream_attrib = reinterpret_cast<PFNEGLSTREAMATTRIBKHRPROC>(eglGetProcAddress("eglStreamAttribKHR"));
- m_query_stream = reinterpret_cast<PFNEGLQUERYSTREAMKHRPROC>(eglGetProcAddress("eglQueryStreamKHR"));
- m_query_stream_u64 = reinterpret_cast<PFNEGLQUERYSTREAMU64KHRPROC>(eglGetProcAddress("eglQueryStreamu64KHR"));
- m_create_stream_producer_surface = reinterpret_cast<PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC>(eglGetProcAddress("eglCreateStreamProducerSurfaceKHR"));
- m_stream_consumer_output = reinterpret_cast<PFNEGLSTREAMCONSUMEROUTPUTEXTPROC>(eglGetProcAddress("eglStreamConsumerOutputEXT"));
- m_get_output_layers = reinterpret_cast<PFNEGLGETOUTPUTLAYERSEXTPROC>(eglGetProcAddress("eglGetOutputLayersEXT"));
- m_get_output_ports = reinterpret_cast<PFNEGLGETOUTPUTPORTSEXTPROC>(eglGetProcAddress("eglGetOutputPortsEXT"));
- m_output_layer_attrib = reinterpret_cast<PFNEGLOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglOutputLayerAttribEXT"));
- m_query_output_layer_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputLayerAttribEXT"));
- m_query_output_layer_string = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputLayerStringEXT"));
- m_query_output_port_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputPortAttribEXT"));
- m_query_output_port_string = reinterpret_cast<PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputPortStringEXT"));
- m_get_stream_file_descriptor = reinterpret_cast<PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglGetStreamFileDescriptorKHR"));
- m_create_stream_from_file_descriptor = reinterpret_cast<PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglCreateStreamFromFileDescriptorKHR"));
- m_stream_consumer_gltexture = reinterpret_cast<PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC>(eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR"));
- m_stream_consumer_acquire = reinterpret_cast<PFNEGLSTREAMCONSUMERACQUIREKHRPROC>(eglGetProcAddress("eglStreamConsumerAcquireKHR"));
-
- const char *extensions = eglQueryString(display, EGL_EXTENSIONS);
- if (!extensions) {
- qWarning() << Q_FUNC_INFO << "eglQueryString failed";
- return false;
- }
-
- m_has_egl_stream = strstr(extensions, "EGL_KHR_stream");
- m_has_egl_stream_producer_eglsurface = strstr(extensions, "EGL_KHR_stream_producer_eglsurface");
- m_has_egl_stream_consumer_egloutput = strstr(extensions, "EGL_EXT_stream_consumer_egloutput");
- m_has_egl_output_drm = strstr(extensions, "EGL_EXT_output_drm");
- m_has_egl_output_base = strstr(extensions, "EGL_EXT_output_base");
- m_has_egl_stream_cross_process_fd = strstr(extensions, "EGL_KHR_stream_cross_process_fd");
- m_has_egl_stream_consumer_gltexture = strstr(extensions, "EGL_KHR_stream_consumer_gltexture");
-
- return m_has_egl_output_base &&
- m_has_egl_output_drm &&
- m_has_egl_stream &&
- m_has_egl_stream_producer_eglsurface &&
- m_has_egl_stream_consumer_egloutput;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
index c6132354a8..a89a65ca55 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
@@ -49,8 +49,7 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
+#include <QtPlatformSupport/private/qeglstreamconvenience_p.h>
QT_BEGIN_NAMESPACE
@@ -75,9 +74,7 @@ public:
bool supportsSurfacelessContexts() const Q_DECL_OVERRIDE;
bool setup_kms();
-
bool query_egl_device();
- bool query_egl_extensions(EGLDisplay display);
// device bits
QByteArray m_device;
@@ -92,44 +89,7 @@ public:
quint32 m_drm_crtc;
// EGLStream infrastructure
- PFNEGLGETPLATFORMDISPLAYEXTPROC m_get_platform_display;
- bool m_has_egl_platform_device;
-
- PFNEGLQUERYDEVICESEXTPROC m_query_devices;
- PFNEGLQUERYDEVICESTRINGEXTPROC m_query_device_string;
- bool m_has_egl_device_base;
-
- PFNEGLCREATESTREAMKHRPROC m_create_stream;
- PFNEGLDESTROYSTREAMKHRPROC m_destroy_stream;
- PFNEGLSTREAMATTRIBKHRPROC m_stream_attrib;
- PFNEGLQUERYSTREAMKHRPROC m_query_stream;
- PFNEGLQUERYSTREAMU64KHRPROC m_query_stream_u64;
- bool m_has_egl_stream;
-
- PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC m_create_stream_producer_surface;
- bool m_has_egl_stream_producer_eglsurface;
-
- PFNEGLSTREAMCONSUMEROUTPUTEXTPROC m_stream_consumer_output;
- bool m_has_egl_stream_consumer_egloutput;
-
- bool m_has_egl_output_drm;
-
- PFNEGLGETOUTPUTLAYERSEXTPROC m_get_output_layers;
- PFNEGLGETOUTPUTPORTSEXTPROC m_get_output_ports;
- PFNEGLOUTPUTLAYERATTRIBEXTPROC m_output_layer_attrib;
- PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC m_query_output_layer_attrib;
- PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC m_query_output_layer_string;
- PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC m_query_output_port_attrib;
- PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC m_query_output_port_string;
- bool m_has_egl_output_base;
-
- PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC m_get_stream_file_descriptor;
- PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC m_create_stream_from_file_descriptor;
- bool m_has_egl_stream_cross_process_fd;
-
- PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC m_stream_consumer_gltexture;
- PFNEGLSTREAMCONSUMERACQUIREKHRPROC m_stream_consumer_acquire;
- bool m_has_egl_stream_consumer_gltexture;
+ QEGLStreamConvenience *m_funcs;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 22ec424451..6f8d0b88dd 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -45,7 +45,6 @@ QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
: m_dpy(dpy),
- m_pointerWindow(0),
m_surface(EGL_NO_SURFACE),
m_cursor(0)
{
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index dc291285ad..44e9da4a5a 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -35,6 +35,7 @@
#define QEGLFSSCREEN_H
#include "qeglfsglobal.h"
+#include <QtCore/QPointer>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@@ -73,7 +74,7 @@ private:
void setPrimarySurface(EGLSurface surface);
EGLDisplay m_dpy;
- QWindow *m_pointerWindow;
+ QPointer<QWindow> m_pointerWindow;
EGLSurface m_surface;
QPlatformCursor *m_cursor;
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h
index e8ea1cc28b..98977eb670 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.h
+++ b/src/plugins/platforms/ios/qioseventdispatcher.h
@@ -34,7 +34,7 @@
#ifndef QIOSEVENTDISPATCHER_H
#define QIOSEVENTDISPATCHER_H
-#include <QtPlatformSupport/private/qeventdispatcher_cf_p.h>
+#include <QtCore/private/qeventdispatcher_cf_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index f1500409fe..5d8bd56a1e 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -54,6 +54,18 @@
"features": [
"disable_desktopgl"
]
- }
+ },
+ {
+ "id": 5,
+ "description": "Intel GMA 3150 crashes (QTBUG-43243)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0xA001", "0xA011" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl", "disable_angle"
+ ]
+ }
]
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 4ec34c05bd..4d18e7ea58 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -860,6 +860,11 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr)
return result;
}
+static inline QWindowsInputContext *windowsInputContext()
+{
+ return qobject_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+}
+
/*!
\brief Main windows procedure registered for windows.
@@ -909,8 +914,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
}
}
if (et & QtWindows::InputMethodEventFlag) {
- QWindowsInputContext *windowsInputContext =
- qobject_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+ QWindowsInputContext *windowsInputContext = ::windowsInputContext();
// Disable IME assuming this is a special implementation hooking into keyboard input.
// "Real" IME implementations should use a native event filter intercepting IME events.
if (!windowsInputContext) {
@@ -1006,11 +1010,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
}
switch (et) {
+ case QtWindows::KeyboardLayoutChangeEvent:
+ if (QWindowsInputContext *wic = windowsInputContext())
+ wic->handleInputLanguageChanged(wParam, lParam); // fallthrough intended.
case QtWindows::KeyDownEvent:
case QtWindows::KeyEvent:
case QtWindows::InputMethodKeyEvent:
case QtWindows::InputMethodKeyDownEvent:
- case QtWindows::KeyboardLayoutChangeEvent:
case QtWindows::AppCommandEvent:
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index a7c14ed2ac..e372acc747 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -856,16 +856,11 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
{
QWindowsOpenGLContextFormat result;
const QByteArray version = QOpenGLStaticContext::getGlString(GL_VERSION);
- const int majorDot = version.indexOf('.');
- if (majorDot != -1) {
- int minorDot = version.indexOf('.', majorDot + 1);
- if (minorDot == -1)
- minorDot = version.size();
- result.version = (version.mid(0, majorDot).toInt() << 8)
- + version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
- } else {
+ int major, minor;
+ if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor))
+ result.version = (major << 8) + minor;
+ else
result.version = 0x0200;
- }
result.profile = QSurfaceFormat::NoProfile;
if (result.version < 0x0300) {
result.options |= QSurfaceFormat::DeprecatedFunctions;
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index e016b84bba..7e1cc563cb 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -84,6 +84,18 @@ static inline void imeNotifyCancelComposition(HWND hwnd)
ImmReleaseContext(hwnd, himc);
}
+static inline LCID languageIdFromLocaleId(LCID localeId)
+{
+ return localeId & 0xFFFF;
+}
+
+static inline LCID currentInputLanguageId()
+{
+ return languageIdFromLocaleId(reinterpret_cast<quintptr>(GetKeyboardLayout(0)));
+}
+
+Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp
+
/*!
\class QWindowsInputContext
\brief Windows Input context implementation
@@ -153,7 +165,9 @@ QWindowsInputContext::CompositionContext::CompositionContext() :
QWindowsInputContext::QWindowsInputContext() :
m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")),
- m_endCompositionRecursionGuard(false)
+ m_endCompositionRecursionGuard(false),
+ m_languageId(currentInputLanguageId()),
+ m_locale(qt_localeFromLCID(m_languageId))
{
connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
this, &QWindowsInputContext::cursorRectChanged);
@@ -371,7 +385,7 @@ bool QWindowsInputContext::startComposition(HWND hwnd)
QWindow *window = QGuiApplication::focusWindow();
if (!window)
return false;
- qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window << "language=" << m_languageId;
if (!fo || QWindowsWindow::handleOf(window) != hwnd)
return false;
initContext(hwnd, fo);
@@ -555,6 +569,21 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam,
return false;
}
+void QWindowsInputContext::handleInputLanguageChanged(WPARAM wparam, LPARAM lparam)
+{
+ const LCID newLanguageId = languageIdFromLocaleId(lparam);
+ if (newLanguageId == m_languageId)
+ return;
+ const LCID oldLanguageId = m_languageId;
+ m_languageId = newLanguageId;
+ m_locale = qt_localeFromLCID(m_languageId);
+ emitLocaleChanged();
+
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << hex << showbase
+ << oldLanguageId << "->" << newLanguageId << "Character set:"
+ << DWORD(wparam) << dec << noshowbase << m_locale;
+}
+
/*!
\brief Determines the string for reconversion with selection.
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
index eb4e3a3faa..636d481e70 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.h
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -36,6 +36,7 @@
#include "qtwindows_additional.h"
+#include <QtCore/QLocale>
#include <QtCore/QPointer>
#include <qpa/qplatforminputcontext.h>
@@ -66,6 +67,8 @@ public:
static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled);
bool hasCapability(Capability capability) const Q_DECL_OVERRIDE;
+ QLocale locale() const Q_DECL_OVERRIDE { return m_locale; }
+
void reset() Q_DECL_OVERRIDE;
void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE;
@@ -79,6 +82,7 @@ public:
int reconvertString(RECONVERTSTRING *reconv);
bool handleIME_Request(WPARAM wparam, LPARAM lparam, LRESULT *result);
+ void handleInputLanguageChanged(WPARAM wparam, LPARAM lparam);
private slots:
void cursorRectChanged();
@@ -94,6 +98,8 @@ private:
static HIMC m_defaultContext;
CompositionContext m_compositionContext;
bool m_endCompositionRecursionGuard;
+ LCID m_languageId;
+ QLocale m_locale;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index abfddcfed6..5cb34e7fd3 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1062,7 +1062,7 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w)
if (const QPlatformWindow *handle = w->handle()) {
const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(handle);
- if (ww->isEmbedded(0)) {
+ if (ww->isEmbedded()) {
HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
const HWND desktopHwnd = GetDesktopWindow();
const QWindowsContext *ctx = QWindowsContext::instance();
@@ -1140,7 +1140,7 @@ bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const
}
if (!m_data.embedded && parent())
- return parent()->isEmbedded(0);
+ return parent()->isEmbedded();
return m_data.embedded;
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index d96022e3a5..c73c8ca8f3 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -152,7 +152,7 @@ public:
bool isVisible() const;
bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); }
bool isActive() const Q_DECL_OVERRIDE;
- bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE;
+ bool isEmbedded(const QPlatformWindow *parentWindow = 0) const Q_DECL_OVERRIDE;
QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
index f3b390b4d6..750233c94f 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -131,7 +131,7 @@ HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane)
return S_OK;
}
-#ifdef Q_OS_WINPHONE
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2)
{
@@ -160,13 +160,11 @@ static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2)
void QWinRTInputContext::showInputPanel()
{
- ComPtr<IInputPane2> inputPane;
- HRESULT hr = getInputPane(&inputPane);
- if (FAILED(hr))
- return;
-
- QEventDispatcherWinRT::runOnXamlThread([&inputPane]() {
- HRESULT hr;
+ QEventDispatcherWinRT::runOnXamlThread([&]() {
+ ComPtr<IInputPane2> inputPane;
+ HRESULT hr = getInputPane(&inputPane);
+ if (FAILED(hr))
+ return hr;
boolean success;
hr = inputPane->TryShow(&success);
if (FAILED(hr) || !success)
@@ -177,13 +175,11 @@ void QWinRTInputContext::showInputPanel()
void QWinRTInputContext::hideInputPanel()
{
- ComPtr<IInputPane2> inputPane;
- HRESULT hr = getInputPane(&inputPane);
- if (FAILED(hr))
- return;
-
- QEventDispatcherWinRT::runOnXamlThread([&inputPane]() {
- HRESULT hr;
+ QEventDispatcherWinRT::runOnXamlThread([&]() {
+ ComPtr<IInputPane2> inputPane;
+ HRESULT hr = getInputPane(&inputPane);
+ if (FAILED(hr))
+ return hr;
boolean success;
hr = inputPane->TryHide(&success);
if (FAILED(hr) || !success)
@@ -192,6 +188,6 @@ void QWinRTInputContext::hideInputPanel()
});
}
-#endif // Q_OS_WINPHONE
+#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h
index cc3bce435f..6f88ff46e6 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.h
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h
@@ -68,7 +68,7 @@ public:
bool isInputPanelVisible() const;
-#ifdef Q_OS_WINPHONE
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
void showInputPanel();
void hideInputPanel();
#endif
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index fce77c56d1..7ee3bf8593 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -45,7 +45,6 @@
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
-#include <QtCore/QCoreApplication>
#include <QtGui/QSurface>
#include <QtGui/QOpenGLContext>
#include <qfunctions_winrt.h>
@@ -133,24 +132,14 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
Q_ASSERT_SUCCEEDED(hr);
#endif // Q_OS_WINPHONE
- hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
- HRESULT hr;
- ComPtr<Xaml::IWindowStatics> windowStatics;
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(),
- IID_PPV_ARGS(&windowStatics));
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<Xaml::IWindow> window;
- hr = windowStatics->get_Current(&window);
- Q_ASSERT_SUCCEEDED(hr);
- hr = window->Activate();
- Q_ASSERT_SUCCEEDED(hr);
-
- d->mainScreen = new QWinRTScreen(window.Get());
- d->inputContext.reset(new QWinRTInputContext(d->mainScreen));
- screenAdded(d->mainScreen);
+ QEventDispatcherWinRT::runOnXamlThread([d]() {
+ d->mainScreen = new QWinRTScreen;
return S_OK;
});
- Q_ASSERT_SUCCEEDED(hr);
+
+ d->inputContext.reset(new QWinRTInputContext(d->mainScreen));
+ screenAdded(d->mainScreen);
+ d->platformServices = new QWinRTServices;
}
QWinRTIntegration::~QWinRTIntegration()
@@ -182,6 +171,15 @@ QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const
return new QWinRTEventDispatcher;
}
+void QWinRTIntegration::initialize()
+{
+ Q_D(const QWinRTIntegration);
+ QEventDispatcherWinRT::runOnXamlThread([d]() {
+ d->mainScreen->initialize();
+ return S_OK;
+ });
+}
+
bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
@@ -245,8 +243,7 @@ QStringList QWinRTIntegration::themeNames() const
return QStringList(QLatin1String("winrt"));
}
-QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString &
-name) const
+QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString &name) const
{
if (name == QLatin1String("winrt"))
return new QWinRTTheme();
@@ -260,21 +257,12 @@ name) const
HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
{
Q_D(QWinRTIntegration);
-
- QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
- QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
- backPress.setAccepted(false);
- backRelease.setAccepted(false);
-
QWindow *window = d->mainScreen->topWindow();
- QObject *receiver = window ? static_cast<QObject *>(window)
- : static_cast<QObject *>(QCoreApplication::instance());
-
- // If the event is ignored, the app go to the background
- QCoreApplication::sendEvent(receiver, &backPress);
- QCoreApplication::sendEvent(receiver, &backRelease);
- args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
-
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
+ const bool pressed = QWindowSystemInterface::handleKeyEvent(window, QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
+ const bool released = QWindowSystemInterface::handleKeyEvent(window, QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(false);
+ args->put_Handled(pressed || released);
return S_OK;
}
#endif // Q_OS_WINPHONE
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
index 0115e034b5..3a151e1ed8 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.h
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -81,20 +81,21 @@ public:
bool succeeded() const;
- bool hasCapability(QPlatformIntegration::Capability cap) const;
- QVariant styleHint(StyleHint hint) const;
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE;
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
- QAbstractEventDispatcher *createEventDispatcher() const;
- QPlatformFontDatabase *fontDatabase() const;
- QPlatformInputContext *inputContext() const;
- QPlatformServices *services() const;
- Qt::KeyboardModifiers queryKeyboardModifiers() const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+ void initialize() Q_DECL_OVERRIDE;
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+ QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
+ QPlatformServices *services() const Q_DECL_OVERRIDE;
+ Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
- QStringList themeNames() const;
- QPlatformTheme *createPlatformTheme(const QString &name) const;
+ QStringList themeNames() const Q_DECL_OVERRIDE;
+ QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE;
private:
#ifdef Q_OS_WINPHONE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 563753cfcb..0fe3262398 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -447,7 +447,7 @@ public:
};
// To be called from the XAML thread
-QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
+QWinRTScreen::QWinRTScreen()
: d_ptr(new QWinRTScreenPrivate)
{
Q_D(QWinRTScreen);
@@ -455,7 +455,17 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
d->touchDevice = Q_NULLPTR;
HRESULT hr;
- hr = xamlWindow->get_CoreWindow(&d->coreWindow);
+ ComPtr<Xaml::IWindowStatics> windowStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(),
+ IID_PPV_ARGS(&windowStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IWindow> window;
+ hr = windowStatics->get_Current(&window);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = window->Activate();
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = window->get_CoreWindow(&d->coreWindow);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->Activate();
Q_ASSERT_SUCCEEDED(hr);
@@ -465,35 +475,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
Q_ASSERT_SUCCEEDED(hr);
d->logicalSize = QSizeF(rect.Width, rect.Height);
- hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
- Q_ASSERT_SUCCEEDED(hr);
-#ifndef Q_OS_WINPHONE
- hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
- Q_ASSERT_SUCCEEDED(hr);
-#endif
- hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]);
- Q_ASSERT_SUCCEEDED(hr);
-
// Orientation handling
ComPtr<IDisplayInformationStatics> displayInformationStatics;
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(),
@@ -509,12 +490,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
Q_ASSERT_SUCCEEDED(hr);
d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
- hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
- Q_ASSERT_SUCCEEDED(hr);
-
// Set initial orientation & pixel density
onDpiChanged(Q_NULLPTR, Q_NULLPTR);
d->orientation = d->nativeOrientation;
@@ -542,7 +517,7 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
ComPtr<Xaml::IUIElement> uiElement;
hr = canvas.As(&uiElement);
Q_ASSERT_SUCCEEDED(hr);
- hr = xamlWindow->put_Content(uiElement.Get());
+ hr = window->put_Content(uiElement.Get());
Q_ASSERT_SUCCEEDED(hr);
hr = canvas.As(&d->canvas);
Q_ASSERT_SUCCEEDED(hr);
@@ -556,10 +531,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
Q_ASSERT_SUCCEEDED(hr);
hr = statusBarStatics->GetForCurrentView(&d->statusBar);
Q_ASSERT_SUCCEEDED(hr);
- hr = d->statusBar->add_Showing(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->statusBar->add_Hiding(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]);
- Q_ASSERT_SUCCEEDED(hr);
#endif // Q_OS_WINPHONE
}
@@ -726,6 +697,50 @@ void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window)
}
#endif //Q_OS_WINPHONE
+void QWinRTScreen::initialize()
+{
+ Q_D(QWinRTScreen);
+ HRESULT hr;
+ hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+#ifndef Q_OS_WINPHONE
+ hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+#else
+ hr = d->statusBar->add_Showing(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->statusBar->add_Hiding(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]);
+ Q_ASSERT_SUCCEEDED(hr);
+#endif
+ hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+ onVisibilityChanged(nullptr, nullptr);
+}
+
QWindow *QWinRTScreen::topWindow() const
{
Q_D(const QWinRTScreen);
@@ -1089,8 +1104,10 @@ HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEventArgs *args)
{
+ Q_D(QWinRTScreen);
boolean visible;
- args->get_Visible(&visible);
+ HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible);
+ RETURN_OK_IF_FAILED("Failed to get visbile.");
QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
if (visible)
handleExpose();
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index 3297617740..0043b2cfa3 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -83,7 +83,7 @@ class QWinRTScreenPrivate;
class QWinRTScreen : public QPlatformScreen
{
public:
- explicit QWinRTScreen(ABI::Windows::UI::Xaml::IWindow *xamlWindow);
+ explicit QWinRTScreen();
~QWinRTScreen();
QRect geometry() const Q_DECL_OVERRIDE;
#ifdef Q_OS_WINPHONE
@@ -115,6 +115,8 @@ public:
void setStatusBarVisibility(bool visible, QWindow *window);
#endif
+ void initialize();
+
private:
void handleExpose();
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index 248d1b4bbb..8b75c130fb 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -275,22 +275,8 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
m_clientClipboard[QClipboard::Selection] = 0;
m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
+ m_owner = connection()->getQtSelectionOwner();
- QXcbScreen *platformScreen = screen();
-
- int x = 0, y = 0, w = 3, h = 3;
-
- m_owner = xcb_generate_id(xcb_connection());
- Q_XCB_CALL(xcb_create_window(xcb_connection(),
- XCB_COPY_FROM_PARENT, // depth -- same as root
- m_owner, // window id
- platformScreen->screen()->root, // parent window id
- x, y, w, h,
- 0, // border width
- XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
- platformScreen->screen()->root_visual, // visual
- 0, // value mask
- 0)); // value list
#ifndef QT_NO_DEBUG
QByteArray ba("Qt clipboard window");
Q_XCB_CALL(xcb_change_property(xcb_connection(),
@@ -353,13 +339,7 @@ void QXcbClipboard::incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepte
xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const
{
- xcb_connection_t *c = xcb_connection();
- xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom);
- xcb_get_selection_owner_reply_t *reply;
- reply = xcb_get_selection_owner_reply(c, cookie, 0);
- xcb_window_t win = reply->owner;
- free(reply);
- return win;
+ return connection()->getSelectionOwner(atom);
}
xcb_atom_t QXcbClipboard::atomForMode(QClipboard::Mode mode) const
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 13d73c7194..a20d957138 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -449,6 +449,9 @@ void QXcbConnection::initializeScreens()
++xcbScreenNumber;
} // for each xcb screen
+ foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops)
+ virtualDesktop->subscribeToXFixesSelectionNotify();
+
// If there's no randr extension, or there was some error above, or we found a
// screen which doesn't have outputs for some other reason (e.g. on VNC or ssh -X),
// but the dimensions are known anyway, and we don't already have any lingering
@@ -507,6 +510,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
, m_systemTrayTracker(0)
, m_glIntegration(Q_NULLPTR)
, m_xiGrab(false)
+ , m_qtSelectionOwner(0)
{
#ifdef XCB_USE_XLIB
Display *dpy = XOpenDisplay(m_displayName.constData());
@@ -551,12 +555,12 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_netWmUserTime = XCB_CURRENT_TIME;
initializeXRandr();
+ initializeXFixes();
initializeScreens();
if (m_screens.isEmpty())
qFatal("QXcbConnection: no screens available");
- initializeXFixes();
initializeXRender();
m_xi2Enabled = false;
#if defined(XCB_USE_XINPUT2)
@@ -1139,10 +1143,14 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
if (!handled) {
if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
- setTime(((xcb_xfixes_selection_notify_event_t *)event)->timestamp);
+ xcb_xfixes_selection_notify_event_t *notify_event = (xcb_xfixes_selection_notify_event_t *)event;
+ setTime(notify_event->timestamp);
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleXFixesSelectionRequest((xcb_xfixes_selection_notify_event_t *)event);
+ m_clipboard->handleXFixesSelectionRequest(notify_event);
#endif
+ foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops)
+ virtualDesktop->handleXFixesSelectionNotify(notify_event);
+
handled = true;
} else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
updateScreens((xcb_randr_notify_event_t *)event);
@@ -1371,6 +1379,37 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
return timestamp;
}
+xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const
+{
+ xcb_connection_t *c = xcb_connection();
+ xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom);
+ xcb_get_selection_owner_reply_t *reply;
+ reply = xcb_get_selection_owner_reply(c, cookie, 0);
+ xcb_window_t win = reply->owner;
+ free(reply);
+ return win;
+}
+
+xcb_window_t QXcbConnection::getQtSelectionOwner()
+{
+ if (!m_qtSelectionOwner) {
+ xcb_screen_t *xcbScreen = primaryVirtualDesktop()->screen();
+ int x = 0, y = 0, w = 3, h = 3;
+ m_qtSelectionOwner = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_qtSelectionOwner, // window id
+ xcbScreen->root, // parent window id
+ x, y, w, h,
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ xcbScreen->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
+ }
+ return m_qtSelectionOwner;
+}
+
xcb_window_t QXcbConnection::rootWindow()
{
QXcbScreen *s = primaryScreen();
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index fb5b941fff..3c82170679 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -460,6 +460,8 @@ public:
bool threadedEventHandling() const { return m_reader->isRunning(); }
xcb_timestamp_t getTimestamp();
+ xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
+ xcb_window_t getQtSelectionOwner();
void setButton(Qt::MouseButton button, bool down) { if (down) m_buttons |= button; else m_buttons &= ~button; }
Qt::MouseButtons buttons() const { return m_buttons; }
@@ -650,6 +652,8 @@ private:
QXcbGlIntegration *m_glIntegration;
bool m_xiGrab;
+ xcb_window_t m_qtSelectionOwner;
+
friend class QXcbEventReader;
};
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index f9c3aa7fed..d19ea241f1 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -191,6 +191,8 @@ void QXcbDrag::startDrag()
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(),
atom(QXcbAtom::XdndTypelist),
XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData());
+
+ setUseCompositing(current_virtual_desktop->compositingActive());
QBasicDrag::startDrag();
}
@@ -316,6 +318,7 @@ void QXcbDrag::move(const QPoint &globalPos)
QPoint deviceIndependentPos = QHighDpiScaling::mapPositionFromNative(globalPos, screen);
if (virtualDesktop != current_virtual_desktop) {
+ setUseCompositing(virtualDesktop->compositingActive());
recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos);
current_virtual_desktop = virtualDesktop;
} else {
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index da4db5edcb..4f71ac8693 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -54,6 +54,10 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
, m_number(number)
, m_xSettings(Q_NULLPTR)
{
+ QByteArray cmAtomName("_NET_WM_CM_S");
+ cmAtomName += QByteArray::number(m_number);
+ m_net_wm_cm_atom = connection->internAtom(cmAtomName.constData());
+ m_compositingActive = connection->getSelectionOwner(m_net_wm_cm_atom);
}
QXcbVirtualDesktop::~QXcbVirtualDesktop()
@@ -79,6 +83,30 @@ QXcbXSettings *QXcbVirtualDesktop::xSettings() const
return m_xSettings;
}
+bool QXcbVirtualDesktop::compositingActive() const
+{
+ if (connection()->hasXFixes())
+ return m_compositingActive;
+ else
+ return connection()->getSelectionOwner(m_net_wm_cm_atom);
+}
+
+void QXcbVirtualDesktop::handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event)
+{
+ if (notify_event->selection == m_net_wm_cm_atom)
+ m_compositingActive = notify_event->owner;
+}
+
+void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify()
+{
+ if (connection()->hasXFixes()) {
+ const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
+ Q_XCB_CALL(xcb_xfixes_select_selection_input_checked(xcb_connection(), connection()->getQtSelectionOwner(), m_net_wm_cm_atom, mask));
+ }
+}
+
QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop,
xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output,
QString outputName)
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index d8d63608e7..51c92a40ae 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -39,6 +39,7 @@
#include <xcb/xcb.h>
#include <xcb/randr.h>
+#include <xcb/xfixes.h>
#include "qxcbobject.h"
#include "qxcbscreen.h"
@@ -69,11 +70,18 @@ public:
QXcbXSettings *xSettings() const;
+ bool compositingActive() const;
+
+ void handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event);
+ void subscribeToXFixesSelectionNotify();
+
private:
xcb_screen_t *m_screen;
int m_number;
QXcbXSettings *m_xSettings;
+ xcb_atom_t m_net_wm_cm_atom;
+ bool m_compositingActive;
};
class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index e7f5bbf0e9..bde8826792 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -389,7 +389,8 @@ void QXcbWindow::create()
resolveFormat();
#ifdef XCB_USE_XLIB
- if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
+ if (window()->surfaceType() != QSurface::RasterSurface
+ && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
XVisualInfo *visualInfo = Q_NULLPTR;
if (connection()->hasDefaultVisualId())
visualInfo = CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(this);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 8968664bad..b2c5fa7d4d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -81,7 +81,7 @@ public:
void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE;
bool isExposed() const Q_DECL_OVERRIDE;
- bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE;
+ bool isEmbedded(const QPlatformWindow *parentWindow = 0) const Q_DECL_OVERRIDE;
QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
diff --git a/src/printsupport/doc/qtprintsupport.qdocconf b/src/printsupport/doc/qtprintsupport.qdocconf
index fbb6f8d1a9..d8fbc23c0a 100644
--- a/src/printsupport/doc/qtprintsupport.qdocconf
+++ b/src/printsupport/doc/qtprintsupport.qdocconf
@@ -4,7 +4,7 @@ project = QtPrintSupport
description = Qt Print Support Reference Documentation
version = $QT_VERSION
-examplesinstallpath = printsupport
+examplesinstallpath = qtbase/printsupport
qhp.projects = QtPrintSupport
diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf
index 5a224adeb9..ceaa75f455 100644
--- a/src/sql/doc/qtsql.qdocconf
+++ b/src/sql/doc/qtsql.qdocconf
@@ -4,7 +4,7 @@ project = QtSql
description = Qt SQL Reference Documentation
version = $QT_VERSION
-examplesinstallpath = sql
+examplesinstallpath = qtbase/sql
qhp.projects = QtSql
diff --git a/src/src.pro b/src/src.pro
index 07ace99144..a970391382 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -28,12 +28,6 @@ src_tools_uic.CONFIG = host_build
force_bootstrap: src_tools_uic.depends = src_tools_bootstrap
else: src_tools_uic.depends = src_corelib
-src_tools_qdoc.subdir = tools/qdoc
-src_tools_qdoc.target = sub-qdoc
-src_tools_qdoc.CONFIG = host_build
-force_bootstrap: src_tools_qdoc.depends = src_tools_bootstrap
-else: src_tools_qdoc.depends = src_corelib src_xml
-
src_tools_bootstrap_dbus.subdir = tools/bootstrap-dbus
src_tools_bootstrap_dbus.target = sub-bootstrap_dbus
src_tools_bootstrap_dbus.depends = src_tools_bootstrap
@@ -182,7 +176,7 @@ contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
}
}
}
-SUBDIRS += src_plugins src_tools_qdoc
+SUBDIRS += src_plugins
nacl: SUBDIRS -= src_network src_testlib
diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf
index 0fafc733b1..72db51b925 100644
--- a/src/testlib/doc/qttestlib.qdocconf
+++ b/src/testlib/doc/qttestlib.qdocconf
@@ -4,7 +4,7 @@ project = QtTestLib
description = Qt Test Reference Documentation
version = $QT_VERSION
-examplesinstallpath = testlib
+examplesinstallpath = qtbase/testlib
qhp.projects = QtTestLib
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index d5909e68a3..b6b16dcd3d 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -103,6 +103,7 @@ SOURCES += \
../../corelib/tools/qsize.cpp \
../../corelib/tools/qline.cpp \
../../corelib/tools/qstring.cpp \
+ ../../corelib/tools/qstringbuilder.cpp \
../../corelib/tools/qstring_compat.cpp \
../../corelib/tools/qstringlist.cpp \
../../corelib/tools/qvector.cpp \
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 7300429fe0..726d1972f1 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -1060,6 +1060,7 @@ void Moc::createPropertyDef(PropertyDef &propDef)
QByteArray v, v2;
if (test(LPAREN)) {
v = lexemUntil(RPAREN);
+ v = v.mid(1, v.length() - 2); // removes the '(' and ')'
} else if (test(INTEGER_LITERAL)) {
v = lexem();
if (l != "REVISION")
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp
index 0a80c0242b..590f17c24f 100644
--- a/src/tools/moc/preprocessor.cpp
+++ b/src/tools/moc/preprocessor.cpp
@@ -663,9 +663,12 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym
expansion += s;
}
} else if (mode == Hash) {
- if (index < 0 || index >= arguments.size()) {
+ if (index < 0) {
that->error("'#' is not followed by a macro parameter");
continue;
+ } else if (index >= arguments.size()) {
+ that->error("Macro invoked with too few parameters for a use of '#'");
+ continue;
}
const Symbols &arg = arguments.at(index);
diff --git a/src/tools/qdoc/TODO.txt b/src/tools/qdoc/TODO.txt
deleted file mode 100644
index 9bf4a2864f..0000000000
--- a/src/tools/qdoc/TODO.txt
+++ /dev/null
@@ -1,87 +0,0 @@
- * fix QWSPointerCalibrationData::devPoints and qwsServer
- * Fix QMenu::addAction(QAction *) overload, "using" etc.
- * fix space between two tables using <p></p>
- * qpixmap-qt3.html; remove 8 public functions inherited from QPaintDevice
- * \variable array
- * Added support for parameterless macros (e.g. \macro Q_OBJECT).
- * Made qdoc stricter regarding the data types (e.g. can't use \enum to document a typedef).
- * Parse QT_MODULE() macro and generate proper warnings for the various editions.
- * Fix parsing of \image following \value (e.g. qt.html).
- * Don't turn X11 and similar names into links.
- * Added automatic links from getters to setters and vice versa.
- * Support \module and show which module each class is from.
- * Fix occasional crash caused by misuse of const_cast().
- * Provide clearer error messages when resolves fail.
-
-
-
-
-CHECK:
-
- * Identify editions
- * Automatic \sa getter setter
- * \macro Q_OBJECT
-
-MUST HAVES:
-
- * resolve [gs]etters for \sa using base class
-
- * fix \overload when one is a signal and the other a normal function
- * use "project" for .dcf files
- * functions.html: include the types from QtGlobal as well as the functions (whatever that means)
-
- * nice template function/class syntax
- * spellchecker: built-in vs. builtin
-
- * verbose mode for functions that don't exist
- * No links to Porting Guide sections (e.g. QStringList)
- * link toggled(bool)
- * autolink foo(1)
- * handle using correctly
- * QObject "reentrant" list: duplicates
- * operator<< \overload
- * \compat \overload
- * qWarning() link
- * operator<<() autolink
-
- * get rid of spurious 'global' functions
- * Make automatic links in code work
-
- * Fix encoding bug (see Important email from Simon Hausmann)
- * Make links to QFoo::bar().baz() work
- * Fix automatic links in \sectionX (e.g. qt4-getting-started.html)
- * Provide a "List of all properties" page.
-
- * expand QObjectList -> QList<QObject *>
- * warning for unnamed parameters in property access functions
- * \center...\endcenter
-
-LINKS:
-
- * explanation following nonstandard wording warning
-
- * omit \overload in operator<< and operator>>
- * make operator-() unary and binary independent functions (no \overload)
- * fix \overload
- * fix \legalese
- * remove warning for undocumented enum item like QLocale::LastLanguage
- * improve the \a warnings for overloads; if one overload documents a para, fine
-
- * implement \sidebar
-
- * implement \legalesefile
-
- * show in which module each class is
- * list namespaces, list header files
-
-
-NICE FEATURES:
- * implement inheritance tree for each class (as a PNG)
- * avoid <p>...</p> in table/item cells without relying on horrible kludge
- * prevent macros from having same name as commands
- * be smart about enum types Foo::Bar vs. Bar when comparing functions
- * be smart about const & non-const when comparing functions
-
-OTHER:
- * make qdoc run faster
- * make sure \headerfile works even if specified after \relates
diff --git a/src/tools/qdoc/atom.cpp b/src/tools/qdoc/atom.cpp
deleted file mode 100644
index f50f401c5b..0000000000
--- a/src/tools/qdoc/atom.cpp
+++ /dev/null
@@ -1,460 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qregexp.h>
-#include "atom.h"
-#include "location.h"
-#include "qdocdatabase.h"
-#include <stdio.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-/*! \class Atom
- \brief The Atom class is the fundamental unit for representing
- documents internally.
-
- Atoms have a \i type and are completed by a \i string whose
- meaning depends on the \i type. For example, the string
- \quotation
- \i italic text looks nicer than \bold bold text
- \endquotation
- is represented by the following atoms:
- \quotation
- (FormattingLeft, ATOM_FORMATTING_ITALIC)
- (String, "italic")
- (FormattingRight, ATOM_FORMATTING_ITALIC)
- (String, " text is more attractive than ")
- (FormattingLeft, ATOM_FORMATTING_BOLD)
- (String, "bold")
- (FormattingRight, ATOM_FORMATTING_BOLD)
- (String, " text")
- \endquotation
-
- \also Text
-*/
-
-/*! \enum Atom::AtomType
-
- \value AnnotatedList
- \value AutoLink
- \value BaseName
- \value BriefLeft
- \value BriefRight
- \value C
- \value CaptionLeft
- \value CaptionRight
- \value Code
- \value CodeBad
- \value CodeNew
- \value CodeOld
- \value CodeQuoteArgument
- \value CodeQuoteCommand
- \value DivLeft
- \value DivRight
- \value EndQmlText
- \value FormatElse
- \value FormatEndif
- \value FormatIf
- \value FootnoteLeft
- \value FootnoteRight
- \value FormattingLeft
- \value FormattingRight
- \value GeneratedList
- \value Image
- \value ImageText
- \value ImportantNote
- \value InlineImage
- \value JavaScript
- \value EndJavaScript
- \value Keyword
- \value LineBreak
- \value Link
- \value LinkNode
- \value ListLeft
- \value ListItemNumber
- \value ListTagLeft
- \value ListTagRight
- \value ListItemLeft
- \value ListItemRight
- \value ListRight
- \value NavAutoLink
- \value NavLink
- \value Nop
- \value Note
- \value ParaLeft
- \value ParaRight
- \value Qml
- \value QmlText
- \value QuotationLeft
- \value QuotationRight
- \value RawString
- \value SectionLeft
- \value SectionRight
- \value SectionHeadingLeft
- \value SectionHeadingRight
- \value SidebarLeft
- \value SidebarRight
- \value SinceList
- \value String
- \value TableLeft
- \value TableRight
- \value TableHeaderLeft
- \value TableHeaderRight
- \value TableRowLeft
- \value TableRowRight
- \value TableItemLeft
- \value TableItemRight
- \value TableOfContents
- \value Target
- \value UnhandledFormat
- \value UnknownCommand
-*/
-
-QString Atom::noError_ = QString();
-
-static const struct {
- const char *english;
- int no;
-} atms[] = {
- { "AnnotatedList", Atom::AnnotatedList },
- { "AutoLink", Atom::AutoLink },
- { "BaseName", Atom::BaseName },
- { "br", Atom::BR},
- { "BriefLeft", Atom::BriefLeft },
- { "BriefRight", Atom::BriefRight },
- { "C", Atom::C },
- { "CaptionLeft", Atom::CaptionLeft },
- { "CaptionRight", Atom::CaptionRight },
- { "Code", Atom::Code },
- { "CodeBad", Atom::CodeBad },
- { "CodeNew", Atom::CodeNew },
- { "CodeOld", Atom::CodeOld },
- { "CodeQuoteArgument", Atom::CodeQuoteArgument },
- { "CodeQuoteCommand", Atom::CodeQuoteCommand },
- { "DivLeft", Atom::DivLeft },
- { "DivRight", Atom::DivRight },
- { "EndQmlText", Atom::EndQmlText },
- { "FootnoteLeft", Atom::FootnoteLeft },
- { "FootnoteRight", Atom::FootnoteRight },
- { "FormatElse", Atom::FormatElse },
- { "FormatEndif", Atom::FormatEndif },
- { "FormatIf", Atom::FormatIf },
- { "FormattingLeft", Atom::FormattingLeft },
- { "FormattingRight", Atom::FormattingRight },
- { "GeneratedList", Atom::GeneratedList },
- { "GuidLink", Atom::GuidLink},
- { "hr", Atom::HR},
- { "Image", Atom::Image },
- { "ImageText", Atom::ImageText },
- { "ImportantLeft", Atom::ImportantLeft },
- { "ImportantRight", Atom::ImportantRight },
- { "InlineImage", Atom::InlineImage },
- { "JavaScript", Atom::JavaScript },
- { "EndJavaScript", Atom::EndJavaScript },
- { "Keyword", Atom::Keyword },
- { "LegaleseLeft", Atom::LegaleseLeft },
- { "LegaleseRight", Atom::LegaleseRight },
- { "LineBreak", Atom::LineBreak },
- { "Link", Atom::Link },
- { "LinkNode", Atom::LinkNode },
- { "ListLeft", Atom::ListLeft },
- { "ListItemNumber", Atom::ListItemNumber },
- { "ListTagLeft", Atom::ListTagLeft },
- { "ListTagRight", Atom::ListTagRight },
- { "ListItemLeft", Atom::ListItemLeft },
- { "ListItemRight", Atom::ListItemRight },
- { "ListRight", Atom::ListRight },
- { "NavAutoLink", Atom::NavAutoLink },
- { "NavLink", Atom::NavLink },
- { "Nop", Atom::Nop },
- { "NoteLeft", Atom::NoteLeft },
- { "NoteRight", Atom::NoteRight },
- { "ParaLeft", Atom::ParaLeft },
- { "ParaRight", Atom::ParaRight },
- { "Qml", Atom::Qml},
- { "QmlText", Atom::QmlText },
- { "QuotationLeft", Atom::QuotationLeft },
- { "QuotationRight", Atom::QuotationRight },
- { "RawString", Atom::RawString },
- { "SectionLeft", Atom::SectionLeft },
- { "SectionRight", Atom::SectionRight },
- { "SectionHeadingLeft", Atom::SectionHeadingLeft },
- { "SectionHeadingRight", Atom::SectionHeadingRight },
- { "SidebarLeft", Atom::SidebarLeft },
- { "SidebarRight", Atom::SidebarRight },
- { "SinceList", Atom::SinceList },
- { "SnippetCommand", Atom::SnippetCommand },
- { "SnippetIdentifier", Atom::SnippetIdentifier },
- { "SnippetLocation", Atom::SnippetLocation },
- { "String", Atom::String },
- { "TableLeft", Atom::TableLeft },
- { "TableRight", Atom::TableRight },
- { "TableHeaderLeft", Atom::TableHeaderLeft },
- { "TableHeaderRight", Atom::TableHeaderRight },
- { "TableRowLeft", Atom::TableRowLeft },
- { "TableRowRight", Atom::TableRowRight },
- { "TableItemLeft", Atom::TableItemLeft },
- { "TableItemRight", Atom::TableItemRight },
- { "TableOfContents", Atom::TableOfContents },
- { "Target", Atom::Target },
- { "UnhandledFormat", Atom::UnhandledFormat },
- { "UnknownCommand", Atom::UnknownCommand },
- { 0, 0 }
-};
-
-/*! \fn Atom::Atom(AtomType type, const QString& string)
-
- Constructs an atom of the specified \a type with the single
- parameter \a string and does not put the new atom in a list.
-*/
-
-/*! \fn Atom::Atom(AtomType type, const QString& p1, const QString& p2)
-
- Constructs an atom of the specified \a type with the two
- parameters \a p1 and \a p2 and does not put the new atom
- in a list.
-*/
-
-/*! \fn Atom(Atom *previous, AtomType type, const QString& string)
-
- Constructs an atom of the specified \a type with the single
- parameter \a string and inserts the new atom into the list
- after the \a previous atom.
-*/
-
-/*! \fn Atom::Atom(Atom* previous, AtomType type, const QString& p1, const QString& p2)
-
- Constructs an atom of the specified \a type with the two
- parameters \a p1 and \a p2 and inserts the new atom into
- the list after the \a previous atom.
-*/
-
-/*! \fn void Atom::appendChar(QChar ch)
-
- Appends \a ch to the string parameter of this atom.
-
- \also string()
-*/
-
-/*! \fn void Atom::appendString(const QString& string)
-
- Appends \a string to the string parameter of this atom.
-
- \also string()
-*/
-
-/*! \fn void Atom::chopString()
-
- \also string()
-*/
-
-/*! \fn Atom *Atom::next()
- Return the next atom in the atom list.
- \also type(), string()
-*/
-
-/*!
- Return the next Atom in the list if it is of AtomType \a t.
- Otherwise return 0.
- */
-const Atom* Atom::next(AtomType t) const
-{
- return (next_ && (next_->type() == t)) ? next_ : 0;
-}
-
-/*!
- Return the next Atom in the list if it is of AtomType \a t
- and its string part is \a s. Otherwise return 0.
- */
-const Atom* Atom::next(AtomType t, const QString& s) const
-{
- return (next_ && (next_->type() == t) && (next_->string() == s)) ? next_ : 0;
-}
-
-/*! \fn const Atom *Atom::next() const
- Return the next atom in the atom list.
- \also type(), string()
-*/
-
-/*! \fn AtomType Atom::type() const
- Return the type of this atom.
- \also string(), next()
-*/
-
-/*!
- Return the type of this atom as a string. Return "Invalid" if
- type() returns an impossible value.
-
- This is only useful for debugging.
-
- \also type()
-*/
-QString Atom::typeString() const
-{
- static bool deja = false;
-
- if (!deja) {
- int i = 0;
- while (atms[i].english != 0) {
- if (atms[i].no != i)
- Location::internalError(QCoreApplication::translate("QDoc::Atom", "atom %1 missing").arg(i));
- i++;
- }
- deja = true;
- }
-
- int i = (int) type();
- if (i < 0 || i > (int) Last)
- return QLatin1String("Invalid");
- return QLatin1String(atms[i].english);
-}
-
-/*! \fn const QString& Atom::string() const
-
- Returns the string parameter that together with the type
- characterizes this atom.
-
- \also type(), next()
-*/
-
-/*!
- Dumps this Atom to stderr in printer friendly form.
- */
-void Atom::dump() const
-{
- QString str = string();
- str.replace(QLatin1String("\\"), QLatin1String("\\\\"));
- str.replace(QLatin1String("\""), QLatin1String("\\\""));
- str.replace(QLatin1String("\n"), QLatin1String("\\n"));
- str.replace(QRegExp(QLatin1String("[^\x20-\x7e]")), QLatin1String("?"));
- if (!str.isEmpty())
- str = QLatin1String(" \"") + str + QLatin1Char('"');
- fprintf(stderr,
- " %-15s%s\n",
- typeString().toLatin1().data(),
- str.toLatin1().data());
-}
-
-/*!
- The only constructor for LinkAtom. It creates an Atom of
- type Atom::Link. \a p1 being the link target. \a p2 is the
- parameters in square brackets. Normally there is just one
- word in the square brackets, but there can be up to three
- words separated by spaces. The constructor splits \a p2 on
- the space character.
- */
-LinkAtom::LinkAtom(const QString& p1, const QString& p2)
- : Atom(p1),
- resolved_(false),
- genus_(Node::DontCare),
- goal_(Node::NoType),
- domain_(0),
- squareBracketParams_(p2)
-{
- // nada.
-}
-
-/*!
- This function resolves the parameters that were enclosed in
- square brackets. If the parameters have already been resolved,
- it does nothing and returns immediately.
- */
-void LinkAtom::resolveSquareBracketParams()
-{
- if (resolved_)
- return;
- QStringList params = squareBracketParams_.toLower().split(QLatin1Char(' '));
- foreach (const QString& p, params) {
- if (!domain_) {
- domain_ = QDocDatabase::qdocDB()->findTree(p);
- if (domain_) {
- continue;
- }
- }
- if (goal_ == Node::NoType) {
- goal_ = Node::goal(p);
- if (goal_ != Node::NoType)
- continue;
- }
- if (p == "qml") {
- genus_ = Node::QML;
- continue;
- }
- if (p == "cpp") {
- genus_ = Node::CPP;
- continue;
- }
- if (p == "doc") {
- genus_ = Node::DOC;
- continue;
- }
- error_ = squareBracketParams_;
- break;
- }
- resolved_ = true;
-}
-
-/*!
- Standard copy constructor of LinkAtom \a t.
- */
-LinkAtom::LinkAtom(const LinkAtom& t)
- : Atom(Link, t.string()),
- resolved_(t.resolved_),
- genus_(t.genus_),
- goal_(t.goal_),
- domain_(t.domain_),
- error_(t.error_),
- squareBracketParams_(t.squareBracketParams_)
-{
- // nothing
-}
-
-/*!
- Special copy constructor of LinkAtom \a t, where
- where the new LinkAtom will not be the first one
- in the list.
- */
-LinkAtom::LinkAtom(Atom* previous, const LinkAtom& t)
- : Atom(previous, Link, t.string()),
- resolved_(t.resolved_),
- genus_(t.genus_),
- goal_(t.goal_),
- domain_(t.domain_),
- error_(t.error_),
- squareBracketParams_(t.squareBracketParams_)
-{
- previous->next_ = this;
-}
-
-QT_END_NAMESPACE
diff --git a/src/tools/qdoc/atom.h b/src/tools/qdoc/atom.h
deleted file mode 100644
index 86b8ba7b3c..0000000000
--- a/src/tools/qdoc/atom.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef ATOM_H
-#define ATOM_H
-
-#include <qstringlist.h>
-#include "node.h"
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-class Tree;
-class LinkAtom;
-
-class Atom
-{
-public:
- enum AtomType {
- AnnotatedList,
- AutoLink,
- BaseName,
- BR,
- BriefLeft,
- BriefRight,
- C,
- CaptionLeft,
- CaptionRight,
- Code,
- CodeBad,
- CodeNew,
- CodeOld,
- CodeQuoteArgument,
- CodeQuoteCommand,
- DivLeft,
- DivRight,
- EndQmlText,
- FootnoteLeft,
- FootnoteRight,
- FormatElse,
- FormatEndif,
- FormatIf,
- FormattingLeft,
- FormattingRight,
- GeneratedList,
- GuidLink,
- HR,
- Image,
- ImageText,
- ImportantLeft,
- ImportantRight,
- InlineImage,
- JavaScript,
- EndJavaScript,
- Keyword,
- LegaleseLeft,
- LegaleseRight,
- LineBreak,
- Link,
- LinkNode,
- ListLeft,
- ListItemNumber,
- ListTagLeft,
- ListTagRight,
- ListItemLeft,
- ListItemRight,
- ListRight,
- NavAutoLink,
- NavLink,
- Nop,
- NoteLeft,
- NoteRight,
- ParaLeft,
- ParaRight,
- Qml,
- QmlText,
- QuotationLeft,
- QuotationRight,
- RawString,
- SectionLeft,
- SectionRight,
- SectionHeadingLeft,
- SectionHeadingRight,
- SidebarLeft,
- SidebarRight,
- SinceList,
- SnippetCommand,
- SnippetIdentifier,
- SnippetLocation,
- String,
- TableLeft,
- TableRight,
- TableHeaderLeft,
- TableHeaderRight,
- TableRowLeft,
- TableRowRight,
- TableItemLeft,
- TableItemRight,
- TableOfContents,
- Target,
- UnhandledFormat,
- UnknownCommand,
- Last = UnknownCommand
- };
-
- friend class LinkAtom;
-
- Atom(const QString& string)
- : next_(0), type_(Link)
- {
- strs << string;
- }
-
- Atom(AtomType type, const QString& string = "")
- : next_(0), type_(type)
- {
- strs << string;
- }
-
- Atom(AtomType type, const QString& p1, const QString& p2)
- : next_(0), type_(type)
- {
- strs << p1;
- if (!p2.isEmpty())
- strs << p2;
- }
-
- Atom(Atom* previous, AtomType type, const QString& string = "")
- : next_(previous->next_), type_(type)
- {
- strs << string;
- previous->next_ = this;
- }
-
- Atom(Atom* previous, AtomType type, const QString& p1, const QString& p2)
- : next_(previous->next_), type_(type)
- {
- strs << p1;
- if (!p2.isEmpty())
- strs << p2;
- previous->next_ = this;
- }
-
- virtual ~Atom() { }
-
- void appendChar(QChar ch) { strs[0] += ch; }
- void appendString(const QString& string) { strs[0] += string; }
- void chopString() { strs[0].chop(1); }
- void setString(const QString& string) { strs[0] = string; }
- Atom* next() { return next_; }
- void setNext(Atom* newNext) { next_ = newNext; }
-
- const Atom* next() const { return next_; }
- const Atom* next(AtomType t) const;
- const Atom* next(AtomType t, const QString& s) const;
- AtomType type() const { return type_; }
- QString typeString() const;
- const QString& string() const { return strs[0]; }
- const QString& string(int i) const { return strs[i]; }
- int count() const { return strs.size(); }
- void dump() const;
- const QStringList& strings() const { return strs; }
-
- virtual bool isLinkAtom() const { return false; }
- virtual Node::Genus genus() { return Node::DontCare; }
- virtual bool specifiesDomain() { return false; }
- virtual Tree* domain() { return 0; }
- virtual Node::NodeType goal() { return Node::NoType; }
- virtual const QString& error() { return noError_; }
- virtual void resolveSquareBracketParams() { }
-
- protected:
- static QString noError_;
- Atom* next_;
- AtomType type_;
- QStringList strs;
-};
-
-class LinkAtom : public Atom
-{
- public:
- LinkAtom(const QString& p1, const QString& p2);
- LinkAtom(const LinkAtom& t);
- LinkAtom(Atom* previous, const LinkAtom& t);
- virtual ~LinkAtom() { }
-
- virtual bool isLinkAtom() const Q_DECL_OVERRIDE { return true; }
- virtual Node::Genus genus() Q_DECL_OVERRIDE { resolveSquareBracketParams(); return genus_; }
- virtual bool specifiesDomain() Q_DECL_OVERRIDE { resolveSquareBracketParams(); return (domain_ != 0); }
- virtual Tree* domain() Q_DECL_OVERRIDE { resolveSquareBracketParams(); return domain_; }
- virtual Node::NodeType goal() Q_DECL_OVERRIDE { resolveSquareBracketParams(); return goal_; }
- virtual const QString& error() Q_DECL_OVERRIDE { return error_; }
- virtual void resolveSquareBracketParams() Q_DECL_OVERRIDE;
-
- protected:
- bool resolved_;
- Node::Genus genus_;
- Node::NodeType goal_;
- Tree* domain_;
- QString error_;
- QString squareBracketParams_;
-};
-
-#define ATOM_FORMATTING_BOLD "bold"
-#define ATOM_FORMATTING_INDEX "index"
-#define ATOM_FORMATTING_ITALIC "italic"
-#define ATOM_FORMATTING_LINK "link"
-#define ATOM_FORMATTING_PARAMETER "parameter"
-#define ATOM_FORMATTING_SPAN "span "
-#define ATOM_FORMATTING_SUBSCRIPT "subscript"
-#define ATOM_FORMATTING_SUPERSCRIPT "superscript"
-#define ATOM_FORMATTING_TELETYPE "teletype"
-#define ATOM_FORMATTING_UICONTROL "uicontrol"
-#define ATOM_FORMATTING_UNDERLINE "underline"
-
-#define ATOM_LIST_BULLET "bullet"
-#define ATOM_LIST_TAG "tag"
-#define ATOM_LIST_VALUE "value"
-#define ATOM_LIST_LOWERALPHA "loweralpha"
-#define ATOM_LIST_LOWERROMAN "lowerroman"
-#define ATOM_LIST_NUMERIC "numeric"
-#define ATOM_LIST_UPPERALPHA "upperalpha"
-#define ATOM_LIST_UPPERROMAN "upperroman"
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/tools/qdoc/codechunk.cpp b/src/tools/qdoc/codechunk.cpp
deleted file mode 100644
index 5799e0bac0..0000000000
--- a/src/tools/qdoc/codechunk.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- codechunk.cpp
-*/
-
-#include <qregexp.h>
-#include <qstringlist.h>
-
-#include "codechunk.h"
-
-QT_BEGIN_NAMESPACE
-
-enum { Other, Alnum, Gizmo, Comma, LParen, RParen, RAngle, Colon };
-
-// entries 128 and above are Other
-static const int charCategory[256] = {
- Other, Other, Other, Other, Other, Other, Other, Other,
- Other, Other, Other, Other, Other, Other, Other, Other,
- Other, Other, Other, Other, Other, Other, Other, Other,
- Other, Other, Other, Other, Other, Other, Other, Other,
- // ! " # $ % & '
- Other, Other, Other, Other, Other, Gizmo, Gizmo, Other,
- // ( ) * + , - . /
- LParen, RParen, Gizmo, Gizmo, Comma, Other, Other, Gizmo,
- // 0 1 2 3 4 5 6 7
- Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
- // 8 9 : ; < = > ?
- Alnum, Alnum, Colon, Other, Other, Gizmo, RAngle, Gizmo,
- // @ A B C D E F G
- Other, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
- // H I J K L M N O
- Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
- // P Q R S T U V W
- Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
- // X Y Z [ \ ] ^ _
- Alnum, Alnum, Alnum, Other, Other, Other, Gizmo, Alnum,
- // ` a b c d e f g
- Other, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
- // h i j k l m n o
- Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
- // p q r s t u v w
- Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
- // x y z { | } ~
- Alnum, Alnum, Alnum, LParen, Gizmo, RParen, Other, Other
-};
-
-static const bool needSpace[8][8] = {
- /* [ a + , ( ) > : */
- /* [ */ { false, false, false, false, false, true, false, false },
- /* a */ { false, true, true, false, false, true, false, false },
- /* + */ { false, true, false, false, false, true, false, true },
- /* , */ { true, true, true, true, true, true, true, true },
- /* ( */ { true, true, true, false, true, false, true, true },
- /* ) */ { true, true, true, false, true, true, true, true },
- /* > */ { true, true, true, false, true, true, true, false },
- /* : */ { false, false, true, true, true, true, true, false }
-};
-
-static int category( QChar ch )
-{
- return charCategory[(int)ch.toLatin1()];
-}
-
-CodeChunk::CodeChunk()
- : hotspot( -1 )
-{
-}
-
-CodeChunk::CodeChunk( const QString& str )
- : s( str ), hotspot( -1 )
-{
-}
-
-void CodeChunk::append( const QString& lexeme )
-{
- if ( !s.isEmpty() && !lexeme.isEmpty() ) {
- /*
- Should there be a space or not between the code chunk so far and the
- new lexeme?
- */
- int cat1 = category(s.at(s.size() - 1));
- int cat2 = category(lexeme[0]);
- if ( needSpace[cat1][cat2] )
- s += QLatin1Char( ' ' );
- }
- s += lexeme;
-}
-
-void CodeChunk::appendHotspot()
-{
- /*
- The first hotspot is the right one.
- */
- if ( hotspot == -1 )
- hotspot = s.length();
-}
-
-QString CodeChunk::toString() const
-{
- return s;
-}
-
-QStringList CodeChunk::toPath() const
-{
- QString t = s;
- t.remove(QRegExp(QLatin1String("<([^<>]|<([^<>]|<[^<>]*>)*>)*>")));
- return t.split(QLatin1String("::"));
-}
-
-QT_END_NAMESPACE
diff --git a/src/tools/qdoc/codechunk.h b/src/tools/qdoc/codechunk.h
deleted file mode 100644
index 259012df90..0000000000
--- a/src/tools/qdoc/codechunk.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- codechunk.h
-*/
-
-#ifndef CODECHUNK_H
-#define CODECHUNK_H
-
-#include <qstring.h>
-
-QT_BEGIN_NAMESPACE
-
-// ### get rid of that class
-
-/*
- The CodeChunk class represents a tiny piece of C++ code.
-
- The class provides conversion between a list of lexemes and a string. It adds
- spaces at the right place for consistent style. The tiny pieces of code it
- represents are data types, enum values, and default parameter values.
-
- Apart from the piece of code itself, there are two bits of metainformation
- stored in CodeChunk: the base and the hotspot. The base is the part of the
- piece that may be a hypertext link. The base of
-
- QMap<QString, QString>
-
- is QMap.
-
- The hotspot is the place the variable name should be inserted in the case of a
- variable (or parameter) declaration. The base of
-
- char * []
-
- is between '*' and '[]'.
-*/
-class CodeChunk
-{
-public:
- CodeChunk();
- CodeChunk( const QString& str );
-
- void append( const QString& lexeme );
- void appendHotspot();
-
- bool isEmpty() const { return s.isEmpty(); }
- void clear() { s.clear(); }
- QString toString() const;
- QStringList toPath() const;
- QString left() const { return s.left(hotspot == -1 ? s.length() : hotspot); }
- QString right() const { return s.mid(hotspot == -1 ? s.length() : hotspot); }
-
-private:
- QString s;
- int hotspot;
-};
-
-inline bool operator==( const CodeChunk& c, const CodeChunk& d ) {
- return c.toString() == d.toString();
-}
-
-inline bool operator!=( const CodeChunk& c, const CodeChunk& d ) {
- return !( c == d );
-}
-
-inline bool operator<( const CodeChunk& c, const CodeChunk& d ) {
- return c.toString() < d.toString();
-}
-
-inline bool operator>( const CodeChunk& c, const CodeChunk& d ) {
- return d < c;
-}
-
-inline bool operator<=( const CodeChunk& c, const CodeChunk& d ) {
- return !( c > d );
-}
-
-inline bool operator>=( const CodeChunk& c, const CodeChunk& d ) {
- return !( c < d );
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp
deleted file mode 100644
index a668205a66..0000000000
--- a/src/tools/qdoc/codemarker.cpp
+++ /dev/null
@@ -1,668 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qobjectdefs.h>
-#include "codemarker.h"
-#include "config.h"
-#include "node.h"
-#include <qdebug.h>
-#include <stdio.h>
-
-QT_BEGIN_NAMESPACE
-
-QString CodeMarker::defaultLang;
-QList<CodeMarker *> CodeMarker::markers;
-
-/*!
- When a code marker constructs itself, it puts itself into
- the static list of code markers. All the code markers in
- the static list get initialized in initialize(), which is
- not called until after the qdoc configuration file has
- been read.
- */
-CodeMarker::CodeMarker()
-{
- markers.prepend(this);
-}
-
-/*!
- When a code marker destroys itself, it removes itself from
- the static list of code markers.
- */
-CodeMarker::~CodeMarker()
-{
- markers.removeAll(this);
-}
-
-/*!
- A code market performs no initialization by default. Marker-specific
- initialization is performed in subclasses.
- */
-void CodeMarker::initializeMarker(const Config& ) // config
-{
-}
-
-/*!
- Terminating a code marker is trivial.
- */
-void CodeMarker::terminateMarker()
-{
- // nothing.
-}
-
-/*!
- All the code markers in the static list are initialized
- here, after the qdoc configuration file has been loaded.
- */
-void CodeMarker::initialize(const Config& config)
-{
- defaultLang = config.getString(CONFIG_LANGUAGE);
- QList<CodeMarker *>::ConstIterator m = markers.constBegin();
- while (m != markers.constEnd()) {
- (*m)->initializeMarker(config);
- ++m;
- }
-}
-
-/*!
- All the code markers in the static list are terminated here.
- */
-void CodeMarker::terminate()
-{
- QList<CodeMarker *>::ConstIterator m = markers.constBegin();
- while (m != markers.constEnd()) {
- (*m)->terminateMarker();
- ++m;
- }
-}
-
-CodeMarker *CodeMarker::markerForCode(const QString& code)
-{
- CodeMarker *defaultMarker = markerForLanguage(defaultLang);
- if (defaultMarker != 0 && defaultMarker->recognizeCode(code))
- return defaultMarker;
-
- QList<CodeMarker *>::ConstIterator m = markers.constBegin();
- while (m != markers.constEnd()) {
- if ((*m)->recognizeCode(code))
- return *m;
- ++m;
- }
- return defaultMarker;
-}
-
-CodeMarker *CodeMarker::markerForFileName(const QString& fileName)
-{
- CodeMarker *defaultMarker = markerForLanguage(defaultLang);
- int dot = -1;
- while ((dot = fileName.lastIndexOf(QLatin1Char('.'), dot)) != -1) {
- QString ext = fileName.mid(dot + 1);
- if (defaultMarker != 0 && defaultMarker->recognizeExtension(ext))
- return defaultMarker;
- QList<CodeMarker *>::ConstIterator m = markers.constBegin();
- while (m != markers.constEnd()) {
- if ((*m)->recognizeExtension(ext))
- return *m;
- ++m;
- }
- --dot;
- }
- return defaultMarker;
-}
-
-CodeMarker *CodeMarker::markerForLanguage(const QString& lang)
-{
- QList<CodeMarker *>::ConstIterator m = markers.constBegin();
- while (m != markers.constEnd()) {
- if ((*m)->recognizeLanguage(lang))
- return *m;
- ++m;
- }
- return 0;
-}
-
-const Node *CodeMarker::nodeForString(const QString& string)
-{
- if (sizeof(const Node *) == sizeof(uint)) {
- return reinterpret_cast<const Node *>(string.toUInt());
- }
- else {
- return reinterpret_cast<const Node *>(string.toULongLong());
- }
-}
-
-QString CodeMarker::stringForNode(const Node *node)
-{
- if (sizeof(const Node *) == sizeof(ulong)) {
- return QString::number(reinterpret_cast<quintptr>(node));
- }
- else {
- return QString::number(reinterpret_cast<qulonglong>(node));
- }
-}
-
-static const QString samp = QLatin1String("&amp;");
-static const QString slt = QLatin1String("&lt;");
-static const QString sgt = QLatin1String("&gt;");
-static const QString squot = QLatin1String("&quot;");
-
-QString CodeMarker::protect(const QString& str)
-{
- int n = str.length();
- QString marked;
- marked.reserve(n * 2 + 30);
- const QChar *data = str.constData();
- for (int i = 0; i != n; ++i) {
- switch (data[i].unicode()) {
- case '&': marked += samp; break;
- case '<': marked += slt; break;
- case '>': marked += sgt; break;
- case '"': marked += squot; break;
- default : marked += data[i];
- }
- }
- return marked;
-}
-
-void CodeMarker::appendProtectedString(QString *output, const QStringRef &str)
-{
- int n = str.length();
- output->reserve(output->size() + n * 2 + 30);
- const QChar *data = str.constData();
- for (int i = 0; i != n; ++i) {
- switch (data[i].unicode()) {
- case '&': *output += samp; break;
- case '<': *output += slt; break;
- case '>': *output += sgt; break;
- case '"': *output += squot; break;
- default : *output += data[i];
- }
- }
-}
-
-QString CodeMarker::typified(const QString &string, bool trailingSpace)
-{
- QString result;
- QString pendingWord;
-
- for (int i = 0; i <= string.size(); ++i) {
- QChar ch;
- if (i != string.size())
- ch = string.at(i);
-
- QChar lower = ch.toLower();
- if ((lower >= QLatin1Char('a') && lower <= QLatin1Char('z'))
- || ch.digitValue() >= 0 || ch == QLatin1Char('_')
- || ch == QLatin1Char(':')) {
- pendingWord += ch;
- }
- else {
- if (!pendingWord.isEmpty()) {
- bool isProbablyType = (pendingWord != QLatin1String("const"));
- if (isProbablyType)
- result += QLatin1String("<@type>");
- result += pendingWord;
- if (isProbablyType)
- result += QLatin1String("</@type>");
- }
- pendingWord.clear();
-
- switch (ch.unicode()) {
- case '\0':
- break;
- case '&':
- result += QLatin1String("&amp;");
- break;
- case '<':
- result += QLatin1String("&lt;");
- break;
- case '>':
- result += QLatin1String("&gt;");
- break;
- default:
- result += ch;
- }
- }
- }
- if (trailingSpace && string.size()) {
- if (!string.endsWith(QLatin1Char('*'))
- && !string.endsWith(QLatin1Char('&')))
- result += QLatin1Char(' ');
- }
- return result;
-}
-
-QString CodeMarker::taggedNode(const Node* node)
-{
- QString tag;
- QString name = node->name();
-
- switch (node->type()) {
- case Node::Namespace:
- tag = QLatin1String("@namespace");
- break;
- case Node::Class:
- tag = QLatin1String("@class");
- break;
- case Node::Enum:
- tag = QLatin1String("@enum");
- break;
- case Node::Typedef:
- tag = QLatin1String("@typedef");
- break;
- case Node::Function:
- tag = QLatin1String("@function");
- break;
- case Node::Property:
- tag = QLatin1String("@property");
- break;
- case Node::QmlType:
- /*
- Remove the "QML:" prefix, if present.
- There shouldn't be any of these "QML:"
- prefixes in the documentation sources
- after the switch to using QML module
- qualifiers, but this code is kept to
- be backward compatible.
- */
- if (node->name().startsWith(QLatin1String("QML:")))
- name = name.mid(4);
- tag = QLatin1String("@property");
- break;
- case Node::Document:
- tag = QLatin1String("@property");
- break;
- case Node::QmlMethod:
- case Node::QmlSignal:
- case Node::QmlSignalHandler:
- tag = QLatin1String("@function");
- break;
- default:
- tag = QLatin1String("@unknown");
- break;
- }
- return (QLatin1Char('<') + tag + QLatin1Char('>') + protect(name)
- + QLatin1String("</") + tag + QLatin1Char('>'));
-}
-
-QString CodeMarker::taggedQmlNode(const Node* node)
-{
- QString tag;
- switch (node->type()) {
- case Node::QmlProperty:
- tag = QLatin1String("@property");
- break;
- case Node::QmlSignal:
- tag = QLatin1String("@signal");
- break;
- case Node::QmlSignalHandler:
- tag = QLatin1String("@signalhandler");
- break;
- case Node::QmlMethod:
- tag = QLatin1String("@method");
- break;
- default:
- tag = QLatin1String("@unknown");
- break;
- }
- return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
- + QLatin1String("</") + tag + QLatin1Char('>');
-}
-
-QString CodeMarker::linkTag(const Node *node, const QString& body)
-{
- return QLatin1String("<@link node=\"") + stringForNode(node)
- + QLatin1String("\">") + body + QLatin1String("</@link>");
-}
-
-QString CodeMarker::sortName(const Node *node, const QString* name)
-{
- QString nodeName;
- if (name != 0)
- nodeName = *name;
- else
- nodeName = node->name();
- int numDigits = 0;
- for (int i = nodeName.size() - 1; i > 0; --i) {
- if (nodeName.at(i).digitValue() == -1)
- break;
- ++numDigits;
- }
-
- // we want 'qint8' to appear before 'qint16'
- if (numDigits > 0) {
- for (int i = 0; i < 4 - numDigits; ++i)
- nodeName.insert(nodeName.size()-numDigits-1, QLatin1Char('0'));
- }
-
- if (node->type() == Node::Function) {
- const FunctionNode *func = static_cast<const FunctionNode *>(node);
- QString sortNo;
- if (func->metaness() == FunctionNode::Ctor) {
- sortNo = QLatin1String("C");
- }
- else if (func->metaness() == FunctionNode::Dtor) {
- sortNo = QLatin1String("D");
- }
- else {
- if (nodeName.startsWith(QLatin1String("operator"))
- && nodeName.length() > 8
- && !nodeName[8].isLetterOrNumber())
- sortNo = QLatin1String("F");
- else
- sortNo = QLatin1String("E");
- }
- return sortNo + nodeName + QLatin1Char(' ') + QString::number(func->overloadNumber(), 36);
- }
-
- if (node->type() == Node::Class)
- return QLatin1Char('A') + nodeName;
-
- if (node->type() == Node::Property || node->type() == Node::Variable)
- return QLatin1Char('E') + nodeName;
-
- if ((node->type() == Node::QmlMethod) ||
- (node->type() == Node::QmlSignal) ||
- (node->type() == Node::QmlSignalHandler)) {
- //const FunctionNode* func = static_cast<const FunctionNode *>(node);
- //return QLatin1Char('E') + func->name();
- return QLatin1Char('E') + nodeName;
- }
-
- return QLatin1Char('B') + nodeName;
-}
-
-void CodeMarker::insert(FastSection &fastSection,
- Node *node,
- SynopsisStyle style,
- Status status)
-{
- bool irrelevant = false;
- bool inheritedMember = false;
- if (!node->relates()) {
- Aggregate* p = node->parent();
- if (p->isQmlPropertyGroup())
- p = p->parent();
- if (p != fastSection.parent_) {
- if ((!p->isQmlType() && !p->isJsType()) || !p->isAbstract())
- inheritedMember = true;
- }
- }
-
- if (node->access() == Node::Private) {
- irrelevant = true;
- }
- else if (node->type() == Node::Function) {
- FunctionNode *func = (FunctionNode *) node;
- irrelevant = (inheritedMember
- && (func->metaness() == FunctionNode::Ctor ||
- func->metaness() == FunctionNode::Dtor));
- }
- else if (node->type() == Node::Class || node->type() == Node::Enum
- || node->type() == Node::Typedef) {
- irrelevant = (inheritedMember && style != Subpage);
- if (!irrelevant && style == Detailed && node->type() == Node::Typedef) {
- const TypedefNode* typedeffe = static_cast<const TypedefNode*>(node);
- if (typedeffe->associatedEnum())
- irrelevant = true;
- }
- }
-
- if (!irrelevant) {
- if (status == Compat) {
- irrelevant = (node->status() != Node::Compat);
- }
- else if (status == Obsolete) {
- irrelevant = (node->status() != Node::Obsolete);
- }
- else {
- irrelevant = (node->status() == Node::Compat ||
- node->status() == Node::Obsolete);
- }
- }
-
- if (!irrelevant) {
- if (!inheritedMember || style == Subpage) {
- QString key = sortName(node);
- fastSection.memberMap.insertMulti(key, node);
- }
- else {
- if (node->parent()->isClass() || node->parent()->isNamespace()) {
- if (fastSection.inherited.isEmpty()
- || fastSection.inherited.last().first != node->parent()) {
- QPair<Aggregate *, int> p(node->parent(), 0);
- fastSection.inherited.append(p);
- }
- fastSection.inherited.last().second++;
- }
- }
- }
-}
-
-/*!
- Returns \c true if \a node represents a reimplemented member
- function in the class of the FastSection \a fs. If it is
- a reimplemented function, then it is inserted into the
- reimplemented member map in \a fs. The test is performed
- only if \a status is \e OK. True is returned if \a node
- is inserted into the map. Otherwise, false is returned.
- */
-bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status)
-{
- if ((node->access() != Node::Private) && (node->relates() == 0)) {
- const FunctionNode* fn = static_cast<const FunctionNode*>(node);
- if ((fn->reimplementedFrom() != 0) && (status == Okay)) {
- if (fn->parent() == fs.parent_) {
- QString key = sortName(fn);
- if (!fs.reimpMemberMap.contains(key)) {
- fs.reimpMemberMap.insert(key,node);
- return true;
- }
- }
- }
- }
- return false;
-}
-
-/*!
- If \a fs is not empty, convert it to a Section and append
- the new Section to \a sectionList.
- */
-void CodeMarker::append(QList<Section>& sectionList, const FastSection& fs, bool includeKeys)
-{
- if (!fs.isEmpty()) {
- if (fs.classMapList_.isEmpty()) {
- Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember);
- if (includeKeys) {
- section.keys = fs.memberMap.keys();
- }
- section.members = fs.memberMap.values();
- section.reimpMembers = fs.reimpMemberMap.values();
- section.inherited = fs.inherited;
- sectionList.append(section);
- }
- else {
- Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember);
- sectionList.append(section);
- Section* s = &sectionList[sectionList.size()-1];
- for (int i=0; i<fs.classMapList_.size(); i++) {
- ClassMap* classMap = fs.classMapList_[i];
- ClassKeysNodes* ckn = new ClassKeysNodes;
- ckn->first = classMap->first;
- ckn->second.second = classMap->second.values();
- ckn->second.first = classMap->second.keys();
- s->classKeysNodesList_.append(ckn);
- }
- }
- }
-}
-
-/*!
- The destructor must delete each member of the
- list of QML class lists, if it is not empty;
- */
-Section::~Section()
-{
- if (!classKeysNodesList_.isEmpty()) {
- for (int i=0; i<classKeysNodesList_.size(); i++) {
- ClassKeysNodes* classKeysNodes = classKeysNodesList_[i];
- classKeysNodesList_[i] = 0;
- delete classKeysNodes;
- }
- }
-}
-
-/*!
- The destructor must delete the QML class maps in the class
- map list, if the class map list is not empty.
- */
-FastSection::~FastSection()
-{
- if (!classMapList_.isEmpty()) {
- for (int i=0; i<classMapList_.size(); i++) {
- ClassMap* classMap = classMapList_[i];
- classMapList_[i] = 0;
- delete classMap;
- }
- }
-}
-
-static QString encode(const QString &string)
-{
- return string;
-}
-
-QStringList CodeMarker::macRefsForNode(Node *node)
-{
- QString result = QLatin1String("cpp/");
- switch (node->type()) {
- case Node::Class:
- {
- const ClassNode *classe = static_cast<const ClassNode *>(node);
- {
- result += QLatin1String("cl/");
- }
- result += macName(classe); // ### Maybe plainName?
- }
- break;
- case Node::Enum:
- {
- QStringList stringList;
- stringList << encode(result + QLatin1String("tag/") +
- macName(node));
- foreach (const QString &enumName, node->doc().enumItemNames()) {
- // ### Write a plainEnumValue() and use it here
- stringList << encode(result + QLatin1String("econst/") +
- macName(node->parent(), enumName));
- }
- return stringList;
- }
- case Node::Typedef:
- result += QLatin1String("tdef/") + macName(node);
- break;
- case Node::Function:
- {
- bool isMacro = false;
- Q_UNUSED(isMacro)
- const FunctionNode *func = static_cast<const FunctionNode *>(node);
-
- // overloads are too clever for the Xcode documentation browser
- if (func->isOverload())
- return QStringList();
-
- if (func->metaness() == FunctionNode::MacroWithParams
- || func->metaness() == FunctionNode::MacroWithoutParams) {
- result += QLatin1String("macro/");
- }
- else if (func->isStatic()) {
- result += QLatin1String("clm/");
- }
- else if (!func->parent()->name().isEmpty()) {
- result += QLatin1String("instm/");
- }
- else {
- result += QLatin1String("func/");
- }
-
- result += macName(func);
- if (result.endsWith(QLatin1String("()")))
- result.chop(2);
- }
- break;
- case Node::Variable:
- result += QLatin1String("data/") + macName(node);
- break;
- case Node::Property:
- {
- NodeList list = static_cast<const PropertyNode*>(node)->functions();
- QStringList stringList;
- foreach (Node* node, list) {
- stringList += macRefsForNode(node);
- }
- return stringList;
- }
- case Node::Namespace:
- case Node::Document:
- case Node::QmlType:
- default:
- return QStringList();
- }
-
- return QStringList(encode(result));
-}
-
-QString CodeMarker::macName(const Node *node, const QString &name)
-{
- QString myName = name;
- if (myName.isEmpty()) {
- myName = node->name();
- node = node->parent();
- }
-
- if (node->name().isEmpty()) {
- return QLatin1Char('/') + protect(myName);
- }
- else {
- return node->plainFullName() + QLatin1Char('/') + protect(myName);
- }
-}
-
-/*!
- Returns an empty list of documentation sections.
- */
-QList<Section> CodeMarker::qmlSections(QmlTypeNode* , SynopsisStyle , Status )
-{
- return QList<Section>();
-}
-
-QT_END_NAMESPACE
diff --git a/src/tools/qdoc/codemarker.h b/src/tools/qdoc/codemarker.h
deleted file mode 100644
index 011c8623dd..0000000000
--- a/src/tools/qdoc/codemarker.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- codemarker.h
-*/
-
-#ifndef CODEMARKER_H
-#define CODEMARKER_H
-
-#include <qpair.h>
-
-#include "atom.h"
-#include "node.h"
-
-QT_BEGIN_NAMESPACE
-
-class Config;
-
-typedef QMultiMap<QString, Node*> MemberMap; // the string is the member signature
-typedef QPair<const QmlTypeNode*, MemberMap> ClassMap; // the node is the QML type
-typedef QList<ClassMap*> ClassMapList;
-
-typedef QPair<QStringList, NodeList> KeysAndNodes;
-typedef QPair<const QmlTypeNode*, KeysAndNodes> ClassKeysNodes;
-typedef QList<ClassKeysNodes*> ClassKeysNodesList;
-
-struct Section
-{
- QString name;
- QString divClass;
- QString singularMember;
- QString pluralMember;
- QStringList keys;
- NodeList members;
- NodeList reimpMembers;
- QList<QPair<Aggregate *, int> > inherited;
- ClassKeysNodesList classKeysNodesList_;
-
- Section() { }
- Section(const QString& name0,
- const QString& divClass0,
- const QString& singularMember0,
- const QString& pluralMember0)
- : name(name0),
- divClass(divClass0),
- singularMember(singularMember0),
- pluralMember(pluralMember0) { }
- ~Section();
- void appendMember(Node* node) { members.append(node); }
- void appendReimpMember(Node* node) { reimpMembers.append(node); }
-};
-
-struct FastSection
-{
- const Aggregate *parent_;
- QString name;
- QString divClass;
- QString singularMember;
- QString pluralMember;
- QMultiMap<QString, Node *> memberMap;
- QMultiMap<QString, Node *> reimpMemberMap;
- ClassMapList classMapList_;
- QList<QPair<Aggregate *, int> > inherited;
-
- FastSection(const Aggregate *parent,
- const QString& name0,
- const QString& divClass0,
- const QString& singularMember0,
- const QString& pluralMember0)
- : parent_(parent),
- name(name0),
- divClass(divClass0),
- singularMember(singularMember0),
- pluralMember(pluralMember0) { }
- ~FastSection();
- bool isEmpty() const {
- return (memberMap.isEmpty() &&
- inherited.isEmpty() &&
- reimpMemberMap.isEmpty() &&
- classMapList_.isEmpty());
- }
-
-};
-
-class CodeMarker
-{
-public:
- enum SynopsisStyle { Summary, Detailed, Subpage, Accessors };
- enum Status { Compat, Obsolete, Okay };
-
- CodeMarker();
- virtual ~CodeMarker();
-
- virtual void initializeMarker(const Config& config);
- virtual void terminateMarker();
- virtual bool recognizeCode(const QString& code) = 0;
- virtual bool recognizeExtension(const QString& ext) = 0;
- virtual bool recognizeLanguage(const QString& lang) = 0;
- virtual Atom::AtomType atomType() const = 0;
- virtual QString markedUpCode(const QString& code,
- const Node *relative,
- const Location &location) = 0;
- virtual QString markedUpSynopsis(const Node *node,
- const Node *relative,
- SynopsisStyle style) = 0;
- virtual QString markedUpQmlItem(const Node* , bool) { return QString(); }
- virtual QString markedUpName(const Node *node) = 0;
- virtual QString markedUpFullName(const Node *node,
- const Node *relative = 0) = 0;
- virtual QString markedUpEnumValue(const QString &enumValue,
- const Node *relative) = 0;
- virtual QString markedUpIncludes(const QStringList& includes) = 0;
- virtual QString functionBeginRegExp(const QString& funcName) = 0;
- virtual QString functionEndRegExp(const QString& funcName) = 0;
- virtual QList<Section> sections(const Aggregate *inner,
- SynopsisStyle style,
- Status status) = 0;
- virtual QList<Section> qmlSections(QmlTypeNode* qmlTypeNode,
- SynopsisStyle style,
- Status status = Okay);
- virtual QStringList macRefsForNode(Node* node);
-
- static void initialize(const Config& config);
- static void terminate();
- static CodeMarker *markerForCode(const QString& code);
- static CodeMarker *markerForFileName(const QString& fileName);
- static CodeMarker *markerForLanguage(const QString& lang);
- static const Node *nodeForString(const QString& string);
- static QString stringForNode(const Node *node);
-
- QString typified(const QString &string, bool trailingSpace = false);
-
-protected:
- virtual QString sortName(const Node *node, const QString* name = 0);
- static QString protect(const QString &string);
- static void appendProtectedString(QString *output, const QStringRef &str);
- QString taggedNode(const Node* node);
- QString taggedQmlNode(const Node* node);
- QString linkTag(const Node *node, const QString& body);
- void insert(FastSection &fastSection,
- Node *node,
- SynopsisStyle style,
- Status status);
- bool insertReimpFunc(FastSection& fs, Node* node, Status status);
- void append(QList<Section>& sectionList, const FastSection& fastSection, bool includeKeys = false);
-
-private:
- QString macName(const Node *parent, const QString &name = QString());
-
- static QString defaultLang;
- static QList<CodeMarker *> markers;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/tools/qdoc/codeparser.cpp b/src/tools/qdoc/codeparser.cpp
deleted file mode 100644
index 92a0d52129..0000000000
--- a/src/tools/qdoc/codeparser.cpp
+++ /dev/null
@@ -1,437 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- codeparser.cpp
-*/
-
-#include "codeparser.h"
-#include "node.h"
-#include "tree.h"
-#include "config.h"
-#include "generator.h"
-#include "qdocdatabase.h"
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-#define COMMAND_COMPAT Doc::alias(QLatin1String("compat"))
-#define COMMAND_DEPRECATED Doc::alias(QLatin1String("deprecated")) // ### don't document
-#define COMMAND_INGROUP Doc::alias(QLatin1String("ingroup"))
-#define COMMAND_INMODULE Doc::alias(QLatin1String("inmodule")) // ### don't document
-#define COMMAND_INQMLMODULE Doc::alias(QLatin1String("inqmlmodule"))
-#define COMMAND_INJSMODULE Doc::alias(QLatin1String("injsmodule"))
-#define COMMAND_INTERNAL Doc::alias(QLatin1String("internal"))
-#define COMMAND_MAINCLASS Doc::alias(QLatin1String("mainclass"))
-#define COMMAND_NONREENTRANT Doc::alias(QLatin1String("nonreentrant"))
-#define COMMAND_OBSOLETE Doc::alias(QLatin1String("obsolete"))
-#define COMMAND_PAGEKEYWORDS Doc::alias(QLatin1String("pagekeywords"))
-#define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary"))
-#define COMMAND_INPUBLICGROUP Doc::alias(QLatin1String("inpublicgroup"))
-#define COMMAND_QTVARIABLE Doc::alias(QLatin1String("qtvariable"))
-#define COMMAND_REENTRANT Doc::alias(QLatin1String("reentrant"))
-#define COMMAND_SINCE Doc::alias(QLatin1String("since"))
-#define COMMAND_SUBTITLE Doc::alias(QLatin1String("subtitle"))
-#define COMMAND_THREADSAFE Doc::alias(QLatin1String("threadsafe"))
-#define COMMAND_TITLE Doc::alias(QLatin1String("title"))
-#define COMMAND_WRAPPER Doc::alias(QLatin1String("wrapper"))
-#define COMMAND_NOAUTOLIST Doc::alias(QLatin1String("noautolist"))
-
-QList<CodeParser *> CodeParser::parsers;
-bool CodeParser::showInternal_ = false;
-bool CodeParser::singleExec_ = false;
-
-/*!
- The constructor adds this code parser to the static
- list of code parsers.
- */
-CodeParser::CodeParser()
-{
- qdb_ = QDocDatabase::qdocDB();
- parsers.prepend(this);
-}
-
-/*!
- The destructor removes this code parser from the static
- list of code parsers.
- */
-CodeParser::~CodeParser()
-{
- parsers.removeAll(this);
-}
-
-/*!
- Initialize the code parser base class.
- */
-void CodeParser::initializeParser(const Config& config)
-{
- showInternal_ = config.getBool(CONFIG_SHOWINTERNAL);
- singleExec_ = config.getBool(CONFIG_SINGLEEXEC);
-}
-
-/*!
- Terminating a code parser is trivial.
- */
-void CodeParser::terminateParser()
-{
- // nothing.
-}
-
-QStringList CodeParser::headerFileNameFilter()
-{
- return sourceFileNameFilter();
-}
-
-void CodeParser::parseHeaderFile(const Location& location, const QString& filePath)
-{
- parseSourceFile(location, filePath);
-}
-
-void CodeParser::doneParsingHeaderFiles()
-{
- doneParsingSourceFiles();
-}
-
-/*!
- All the code parsers in the static list are initialized here,
- after the qdoc configuration variables have been set.
- */
-void CodeParser::initialize(const Config& config)
-{
- QList<CodeParser *>::ConstIterator p = parsers.constBegin();
- while (p != parsers.constEnd()) {
- (*p)->initializeParser(config);
- ++p;
- }
-}
-
-/*!
- All the code parsers in the static list are terminated here.
- */
-void CodeParser::terminate()
-{
- QList<CodeParser *>::ConstIterator p = parsers.constBegin();
- while (p != parsers.constEnd()) {
- (*p)->terminateParser();
- ++p;
- }
-}
-
-CodeParser *CodeParser::parserForLanguage(const QString& language)
-{
- QList<CodeParser *>::ConstIterator p = parsers.constBegin();
- while (p != parsers.constEnd()) {
- if ((*p)->language() == language)
- return *p;
- ++p;
- }
- return 0;
-}
-
-CodeParser *CodeParser::parserForHeaderFile(const QString &filePath)
-{
- QString fileName = QFileInfo(filePath).fileName();
-
- QList<CodeParser *>::ConstIterator p = parsers.constBegin();
- while (p != parsers.constEnd()) {
-
- QStringList headerPatterns = (*p)->headerFileNameFilter();
- foreach (const QString &pattern, headerPatterns) {
- QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
- if (re.exactMatch(fileName))
- return *p;
- }
- ++p;
- }
- return 0;
-}
-
-CodeParser *CodeParser::parserForSourceFile(const QString &filePath)
-{
- QString fileName = QFileInfo(filePath).fileName();
-
- QList<CodeParser *>::ConstIterator p = parsers.constBegin();
- while (p != parsers.constEnd()) {
-
- QStringList sourcePatterns = (*p)->sourceFileNameFilter();
- foreach (const QString &pattern, sourcePatterns) {
- QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
- if (re.exactMatch(fileName))
- return *p;
- }
- ++p;
- }
- return 0;
-}
-
-static QSet<QString> commonMetaCommands_;
-/*!
- Returns the set of strings representing the common metacommands.
- */
-const QSet<QString>& CodeParser::commonMetaCommands()
-{
- if (commonMetaCommands_.isEmpty()) {
- commonMetaCommands_ << COMMAND_COMPAT
- << COMMAND_DEPRECATED
- << COMMAND_INGROUP
- << COMMAND_INMODULE
- << COMMAND_INQMLMODULE
- << COMMAND_INTERNAL
- << COMMAND_MAINCLASS
- << COMMAND_NONREENTRANT
- << COMMAND_OBSOLETE
- << COMMAND_PAGEKEYWORDS
- << COMMAND_PRELIMINARY
- << COMMAND_INPUBLICGROUP
- << COMMAND_QTVARIABLE
- << COMMAND_REENTRANT
- << COMMAND_SINCE
- << COMMAND_SUBTITLE
- << COMMAND_THREADSAFE
- << COMMAND_TITLE
- << COMMAND_WRAPPER
- << COMMAND_INJSMODULE
- << COMMAND_NOAUTOLIST;
- }
- return commonMetaCommands_;
-}
-
-/*!
- The topic command has been processed. Now process the other
- metacommands that were found. These are not the text markup
- commands.
- */
-void CodeParser::processCommonMetaCommand(const Location& location,
- const QString& command,
- const ArgLocPair& arg,
- Node* node)
-{
- if (command == COMMAND_COMPAT) {
- location.warning(tr("\\compat command used, but Qt3 compatibility is no longer supported"));
- node->setStatus(Node::Compat);
- }
- else if (command == COMMAND_DEPRECATED) {
- node->setStatus(Node::Obsolete);
- }
- else if ((command == COMMAND_INGROUP) || (command == COMMAND_INPUBLICGROUP)) {
- // Note: \ingroup and \inpublicgroup are now the same.
- // Not that they were ever different.
- qdb_->addToGroup(arg.first, node);
- }
- else if (command == COMMAND_INMODULE) {
- qdb_->addToModule(arg.first,node);
- }
- else if (command == COMMAND_INQMLMODULE) {
- qdb_->addToQmlModule(arg.first,node);
- }
- else if (command == COMMAND_INJSMODULE) {
- qdb_->addToJsModule(arg.first, node);
- }
- else if (command == COMMAND_MAINCLASS) {
- node->doc().location().warning(tr("'\\mainclass' is deprecated. Consider '\\ingroup mainclasses'"));
- }
- else if (command == COMMAND_OBSOLETE) {
- node->setStatus(Node::Obsolete);
- }
- else if (command == COMMAND_NONREENTRANT) {
- node->setThreadSafeness(Node::NonReentrant);
- }
- else if (command == COMMAND_PRELIMINARY) {
- node->setStatus(Node::Preliminary);
- }
- else if (command == COMMAND_INTERNAL) {
- if (!showInternal_) {
- node->setAccess(Node::Private);
- node->setStatus(Node::Internal);
- if (node->type() == Node::QmlPropertyGroup) {
- const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
- NodeList::ConstIterator p = qpgn->childNodes().constBegin();
- while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- (*p)->setAccess(Node::Private);
- (*p)->setStatus(Node::Internal);
- }
- ++p;
- }
- }
- }
- }
- else if (command == COMMAND_REENTRANT) {
- node->setThreadSafeness(Node::Reentrant);
- }
- else if (command == COMMAND_SINCE) {
- node->setSince(arg.first);
- }
- else if (command == COMMAND_WRAPPER) {
- node->setWrapper();
- }
- else if (command == COMMAND_PAGEKEYWORDS) {
- node->addPageKeywords(arg.first);
- }
- else if (command == COMMAND_THREADSAFE) {
- node->setThreadSafeness(Node::ThreadSafe);
- }
- else if (command == COMMAND_TITLE) {
- node->setTitle(arg.first);
- if (!node->isDocumentNode() && !node->isCollectionNode())
- location.warning(tr("Ignored '\\%1'").arg(COMMAND_SUBTITLE));
- else if (node->isExample())
- qdb_->addExampleNode(static_cast<ExampleNode*>(node));
- }
- else if (command == COMMAND_SUBTITLE) {
- node->setSubTitle(arg.first);
- if (!node->isDocumentNode() && !node->isCollectionNode())
- location.warning(tr("Ignored '\\%1'").arg(COMMAND_SUBTITLE));
- }
- else if (command == COMMAND_QTVARIABLE) {
- node->setQtVariable(arg.first);
- if (!node->isModule() && !node->isQmlModule())
- location.warning(tr("Command '\\%1' is only meanigfule in '\\module' and '\\qmlmodule'.")
- .arg(COMMAND_QTVARIABLE));
- }
- else if (command == COMMAND_NOAUTOLIST) {
- node->setNoAutoList(true);
- }
-}
-
-/*!
- \internal
- */
-void CodeParser::extractPageLinkAndDesc(const QString& arg,
- QString* link,
- QString* desc)
-{
- QRegExp bracedRegExp(QLatin1String("\\{([^{}]*)\\}(?:\\{([^{}]*)\\})?"));
-
- if (bracedRegExp.exactMatch(arg)) {
- *link = bracedRegExp.cap(1);
- *desc = bracedRegExp.cap(2);
- if (desc->isEmpty())
- *desc = *link;
- }
- else {
- int spaceAt = arg.indexOf(QLatin1Char(' '));
- if (arg.contains(QLatin1String(".html")) && spaceAt != -1) {
- *link = arg.leftRef(spaceAt).trimmed().toString();
- *desc = arg.midRef(spaceAt).trimmed().toString();
- }
- else {
- *link = arg;
- *desc = arg;
- }
- }
-}
-
-/*!
- \internal
- */
-void CodeParser::setLink(Node* node, Node::LinkType linkType, const QString& arg)
-{
- QString link;
- QString desc;
- extractPageLinkAndDesc(arg, &link, &desc);
- node->setLink(linkType, link, desc);
-}
-
-/*!
- Returns \c true if the file being parsed is a .h file.
- */
-bool CodeParser::isParsingH() const
-{
- return currentFile_.endsWith(".h");
-}
-
-/*!
- Returns \c true if the file being parsed is a .cpp file.
- */
-bool CodeParser::isParsingCpp() const
-{
- return currentFile_.endsWith(".cpp");
-}
-
-/*!
- Returns \c true if the file being parsed is a .qdoc file.
- */
-bool CodeParser::isParsingQdoc() const
-{
- return currentFile_.endsWith(".qdoc");
-}
-
-/*!
- For each node that will produce a documentation page, this function
- ensures that the node belongs to a module. Normally, the qdoc comment
- for an entity that will produce a documentation page will contain an
- \inmodule command to tell qdoc which module the entity belongs to.
-
- But now we normally run qdoc on each module in two passes. The first
- produces an index file; the second pass generates the docs after
- reading all the index files it needs.
-
- This means that all the pages generated during each pass 2 run of
- qdoc almost certainly belong to a single module, and the name of
- that module is, as a rule, used as the project name in the qdocconf
- file used when running qdoc on the module.
-
- So this function first asks if the node \a n has a non-empty module
- name. If it it does not have a non-empty module name, it sets the
- module name to be the project name.
-
- In some cases it prints a qdoc warning that it has done this. Namely,
- for C++ classes and namespaces.
- */
-void CodeParser::checkModuleInclusion(Node* n)
-{
- if (n->physicalModuleName().isEmpty()) {
- n->setPhysicalModuleName(Generator::defaultModuleName());
- switch (n->type()) {
- case Node::Class:
- if (n->access() != Node::Private && !n->doc().isEmpty()) {
- n->doc().location().warning(tr("Class %1 has no \\inmodule command; "
- "using project name by default: %2")
- .arg(n->name()).arg(Generator::defaultModuleName()));
- }
- break;
- case Node::Namespace:
- if (n->access() != Node::Private && !n->name().isEmpty() && !n->doc().isEmpty()) {
- n->doc().location().warning(tr("Namespace %1 has no \\inmodule command; "
- "using project name by default: %2")
- .arg(n->name()).arg(Generator::defaultModuleName()));
- }
- break;
- default:
- break;
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/tools/qdoc/codeparser.h b/src/tools/qdoc/codeparser.h
deleted file mode 100644
index 9d9e9286ec..0000000000
--- a/src/tools/qdoc/codeparser.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef CODEPARSER_H
-#define CODEPARSER_H
-
-#include <qset.h>
-#include "node.h"
-
-QT_BEGIN_NAMESPACE
-
-class Config;
-class QString;
-class QDocDatabase;
-
-class CodeParser
-{
- Q_DECLARE_TR_FUNCTIONS(QDoc::CodeParser)
-
-public:
- CodeParser();
- virtual ~CodeParser();
-
- virtual void initializeParser(const Config& config);
- virtual void terminateParser();
- virtual QString language() = 0;
- virtual QStringList headerFileNameFilter();
- virtual QStringList sourceFileNameFilter() = 0;
- virtual void parseHeaderFile(const Location& location, const QString& filePath);
- virtual void parseSourceFile(const Location& location, const QString& filePath) = 0;
- virtual void doneParsingHeaderFiles();
- virtual void doneParsingSourceFiles() = 0;
-
- bool isParsingH() const;
- bool isParsingCpp() const;
- bool isParsingQdoc() const;
- const QString& currentFile() const { return currentFile_; }
- void checkModuleInclusion(Node* n);
-
- static void initialize(const Config& config);
- static void terminate();
- static CodeParser *parserForLanguage(const QString& language);
- static CodeParser *parserForHeaderFile(const QString &filePath);
- static CodeParser *parserForSourceFile(const QString &filePath);
- static void setLink(Node* node, Node::LinkType linkType, const QString& arg);
-
-protected:
- const QSet<QString>& commonMetaCommands();
- void processCommonMetaCommand(const Location& location,
- const QString& command,
- const ArgLocPair& arg,
- Node *node);
- static void extractPageLinkAndDesc(const QString& arg,
- QString* link,
- QString* desc);
- QString currentFile_;
- QDocDatabase* qdb_;
-
-private:
- static QList<CodeParser *> parsers;
- static bool showInternal_;
- static bool singleExec_;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp
deleted file mode 100644
index 6c47b86d22..0000000000
--- a/src/tools/qdoc/config.cpp
+++ /dev/null
@@ -1,1221 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- config.cpp
-*/
-
-#include <qdir.h>
-#include <qvariant.h>
-#include <qfile.h>
-#include <qtemporaryfile.h>
-#include <qtextstream.h>
-#include <qdebug.h>
-#include "config.h"
-#include "generator.h"
-#include <stdlib.h>
-
-QT_BEGIN_NAMESPACE
-
-QString ConfigStrings::ALIAS = QStringLiteral("alias");
-QString ConfigStrings::AUTOLINKERRORS = QStringLiteral("autolinkerrors");
-QString ConfigStrings::BASE = QStringLiteral("base");
-QString ConfigStrings::BASEDIR = QStringLiteral("basedir");
-QString ConfigStrings::BUILDVERSION = QStringLiteral("buildversion");
-QString ConfigStrings::CODEINDENT = QStringLiteral("codeindent");
-QString ConfigStrings::CODEPREFIX = QStringLiteral("codeprefix");
-QString ConfigStrings::CODESUFFIX = QStringLiteral("codesuffix");
-QString ConfigStrings::CPPCLASSESPAGE = QStringLiteral("cppclassespage");
-QString ConfigStrings::DEFINES = QStringLiteral("defines");
-QString ConfigStrings::DEPENDS = QStringLiteral("depends");
-QString ConfigStrings::DESCRIPTION = QStringLiteral("description");
-QString ConfigStrings::EDITION = QStringLiteral("edition");
-QString ConfigStrings::ENDHEADER = QStringLiteral("endheader");
-QString ConfigStrings::EXAMPLEDIRS = QStringLiteral("exampledirs");
-QString ConfigStrings::EXAMPLES = QStringLiteral("examples");
-QString ConfigStrings::EXAMPLESINSTALLPATH = QStringLiteral("examplesinstallpath");
-QString ConfigStrings::EXCLUDEDIRS = QStringLiteral("excludedirs");
-QString ConfigStrings::EXCLUDEFILES = QStringLiteral("excludefiles");
-QString ConfigStrings::EXTRAIMAGES = QStringLiteral("extraimages");
-QString ConfigStrings::FALSEHOODS = QStringLiteral("falsehoods");
-QString ConfigStrings::FORMATTING = QStringLiteral("formatting");
-QString ConfigStrings::GENERATEINDEX = QStringLiteral("generateindex");
-QString ConfigStrings::HEADERDIRS = QStringLiteral("headerdirs");
-QString ConfigStrings::HEADERS = QStringLiteral("headers");
-QString ConfigStrings::HEADERSCRIPTS = QStringLiteral("headerscripts");
-QString ConfigStrings::HEADERSTYLES = QStringLiteral("headerstyles");
-QString ConfigStrings::HOMEPAGE = QStringLiteral("homepage");
-QString ConfigStrings::IGNOREDIRECTIVES = QStringLiteral("ignoredirectives");
-QString ConfigStrings::IGNORETOKENS = QStringLiteral("ignoretokens");
-QString ConfigStrings::IMAGEDIRS = QStringLiteral("imagedirs");
-QString ConfigStrings::IMAGES = QStringLiteral("images");
-QString ConfigStrings::INDEXES = QStringLiteral("indexes");
-QString ConfigStrings::LANDINGPAGE = QStringLiteral("landingpage");
-QString ConfigStrings::LANGUAGE = QStringLiteral("language");
-QString ConfigStrings::MACRO = QStringLiteral("macro");
-QString ConfigStrings::MANIFESTMETA = QStringLiteral("manifestmeta");
-QString ConfigStrings::NATURALLANGUAGE = QStringLiteral("naturallanguage");
-QString ConfigStrings::NAVIGATION = QStringLiteral("navigation");
-QString ConfigStrings::NOLINKERRORS = QStringLiteral("nolinkerrors");
-QString ConfigStrings::OBSOLETELINKS = QStringLiteral("obsoletelinks");
-QString ConfigStrings::OUTPUTDIR = QStringLiteral("outputdir");
-QString ConfigStrings::OUTPUTENCODING = QStringLiteral("outputencoding");
-QString ConfigStrings::OUTPUTLANGUAGE = QStringLiteral("outputlanguage");
-QString ConfigStrings::OUTPUTFORMATS = QStringLiteral("outputformats");
-QString ConfigStrings::OUTPUTPREFIXES = QStringLiteral("outputprefixes");
-QString ConfigStrings::OUTPUTSUFFIXES = QStringLiteral("outputsuffixes");
-QString ConfigStrings::PROJECT = QStringLiteral("project");
-QString ConfigStrings::REDIRECTDOCUMENTATIONTODEVNULL = QStringLiteral("redirectdocumentationtodevnull");
-QString ConfigStrings::QHP = QStringLiteral("qhp");
-QString ConfigStrings::QUOTINGINFORMATION = QStringLiteral("quotinginformation");
-QString ConfigStrings::SCRIPTDIRS = QStringLiteral("scriptdirs");
-QString ConfigStrings::SCRIPTS = QStringLiteral("scripts");
-QString ConfigStrings::SHOWINTERNAL = QStringLiteral("showinternal");
-QString ConfigStrings::SINGLEEXEC = QStringLiteral("singleexec");
-QString ConfigStrings::SOURCEDIRS = QStringLiteral("sourcedirs");
-QString ConfigStrings::SOURCEENCODING = QStringLiteral("sourceencoding");
-QString ConfigStrings::SOURCES = QStringLiteral("sources");
-QString ConfigStrings::SPURIOUS = QStringLiteral("spurious");
-QString ConfigStrings::STYLEDIRS = QStringLiteral("styledirs");
-QString ConfigStrings::STYLE = QStringLiteral("style");
-QString ConfigStrings::STYLES = QStringLiteral("styles");
-QString ConfigStrings::STYLESHEETS = QStringLiteral("stylesheets");
-QString ConfigStrings::SYNTAXHIGHLIGHTING = QStringLiteral("syntaxhighlighting");
-QString ConfigStrings::TEMPLATEDIR = QStringLiteral("templatedir");
-QString ConfigStrings::TABSIZE = QStringLiteral("tabsize");
-QString ConfigStrings::TAGFILE = QStringLiteral("tagfile");
-QString ConfigStrings::TRANSLATORS = QStringLiteral("translators");
-QString ConfigStrings::URL = QStringLiteral("url");
-QString ConfigStrings::VERSION = QStringLiteral("version");
-QString ConfigStrings::VERSIONSYM = QStringLiteral("versionsym");
-QString ConfigStrings::FILEEXTENSIONS = QStringLiteral("fileextensions");
-QString ConfigStrings::IMAGEEXTENSIONS = QStringLiteral("imageextensions");
-QString ConfigStrings::QMLONLY = QStringLiteral("qmlonly");
-QString ConfigStrings::QMLTYPESPAGE = QStringLiteral("qmltypespage");
-QString ConfigStrings::WRITEQAPAGES = QStringLiteral("writeqapages");
-
-/*!
- An entry in a stack, where each entry is a list
- of string values.
- */
-class MetaStackEntry
-{
-public:
- void open();
- void close();
-
- QStringList accum;
- QStringList next;
-};
-Q_DECLARE_TYPEINFO(MetaStackEntry, Q_MOVABLE_TYPE);
-
-/*!
- Start accumulating values in a list by appending an empty
- string to the list.
- */
-void MetaStackEntry::open()
-{
- next.append(QString());
-}
-
-/*!
- Stop accumulating values and append the list of accumulated
- values to the complete list of accumulated values.
-
- */
-void MetaStackEntry::close()
-{
- accum += next;
- next.clear();
-}
-
-/*!
- \class MetaStack
-
- This class maintains a stack of values of config file variables.
-*/
-class MetaStack : private QStack<MetaStackEntry>
-{
- Q_DECLARE_TR_FUNCTIONS(QDoc::MetaStack)
-
-public:
- MetaStack();
-
- void process(QChar ch, const Location& location);
- QStringList getExpanded(const Location& location);
-};
-
-/*!
- The default constructor pushes a new stack entry and
- opens it.
- */
-MetaStack::MetaStack()
-{
- push(MetaStackEntry());
- top().open();
-}
-
-/*!
- Processes the character \a ch using the \a location.
- It really just builds up a name by appending \a ch to
- it.
- */
-void MetaStack::process(QChar ch, const Location& location)
-{
- if (ch == QLatin1Char('{')) {
- push(MetaStackEntry());
- top().open();
- } else if (ch == QLatin1Char('}')) {
- if (count() == 1)
- location.fatal(tr("Unexpected '}'"));
-
- top().close();
- QStringList suffixes = pop().accum;
- QStringList prefixes = top().next;
-
- top().next.clear();
- QStringList::ConstIterator pre = prefixes.constBegin();
- while (pre != prefixes.constEnd()) {
- QStringList::ConstIterator suf = suffixes.constBegin();
- while (suf != suffixes.constEnd()) {
- top().next << (*pre + *suf);
- ++suf;
- }
- ++pre;
- }
- } else if (ch == QLatin1Char(',') && count() > 1) {
- top().close();
- top().open();
- } else {
- /*
- This is where all the processing is done.
- */
- QStringList::Iterator pre = top().next.begin();
- while (pre != top().next.end()) {
- *pre += ch;
- ++pre;
- }
- }
-}
-
-/*!
- Returns the accumulated string values.
- */
-QStringList MetaStack::getExpanded(const Location& location)
-{
- if (count() > 1)
- location.fatal(tr("Missing '}'"));
-
- top().close();
- return top().accum;
-}
-
-const QString Config::dot = QLatin1String(".");
-bool Config::debug_ = false;
-bool Config::generateExamples = true;
-QString Config::overrideOutputDir;
-QString Config::installDir;
-QSet<QString> Config::overrideOutputFormats;
-QMap<QString, QString> Config::extractedDirs;
-int Config::numInstances;
-QStack<QString> Config::workingDirs_;
-QMap<QString, QStringList> Config::includeFilesMap_;
-
-/*!
- \class Config
- \brief The Config class contains the configuration variables
- for controlling how qdoc produces documentation.
-
- Its load() function, reads, parses, and processes a qdocconf file.
- */
-
-/*!
- The constructor sets the \a programName and initializes all
- internal state variables to empty values.
- */
-Config::Config(const QString& programName)
- : prog(programName)
-{
- loc = Location::null;
- lastLocation_ = Location::null;
- configVars_.clear();
- numInstances++;
- includeFilesMap_.clear();
-}
-
-/*!
- The destructor has nothing special to do.
- */
-Config::~Config()
-{
- includeFilesMap_.clear();
-}
-
-/*!
- Loads and parses the qdoc configuration file \a fileName.
- This function calls the other load() function, which does
- the loading, parsing, and processing of the configuration
- file.
-
- Intializes the location variables returned by location()
- and lastLocation().
- */
-void Config::load(const QString& fileName)
-{
- load(Location::null, fileName);
- if (loc.isEmpty())
- loc = Location(fileName);
- else
- loc.setEtc(true);
- lastLocation_ = Location::null;
-}
-
-/*!
- Joins all the strings in \a values into a single string with the
- individual \a values separated by ' '. Then it inserts the result
- into the string list map with \a var as the key.
-
- It also inserts the \a values string list into a separate map,
- also with \a var as the key.
- */
-void Config::setStringList(const QString& var, const QStringList& values)
-{
- configVars_.insert(var,ConfigVar(var, values, QDir::currentPath()));
-}
-
-/*!
- Looks up the configuarion variable \a var in the string
- map and returns the boolean value.
- */
-bool Config::getBool(const QString& var) const
-{
- return QVariant(getString(var)).toBool();
-}
-
-/*!
- Looks up the configuration variable \a var in the string list
- map. Iterates through the string list found, interpreting each
- string in the list as an integer and adding it to a total sum.
- Returns the sum or \c -1 if \a var is not set.
- */
-int Config::getInt(const QString& var) const
-{
- QStringList strs = getStringList(var);
- if (strs.isEmpty())
- return -1;
-
- QStringList::ConstIterator s = strs.constBegin();
- int sum = 0;
-
- while (s != strs.constEnd()) {
- sum += (*s).toInt();
- ++s;
- }
- return sum;
-}
-
-/*!
- Function to return the correct outputdir.
- outputdir can be set using the qdocconf or the command-line
- variable -outputdir.
- */
-QString Config::getOutputDir() const
-{
- QString t;
- if (overrideOutputDir.isNull())
- t = getString(CONFIG_OUTPUTDIR);
- else
- t = overrideOutputDir;
- if (Generator::singleExec()) {
- QString project = getString(CONFIG_PROJECT);
- t += QLatin1Char('/') + project.toLower();
- }
- if (!Generator::useOutputSubdirs()) {
- t = t.left(t.lastIndexOf('/'));
- QString singleOutputSubdir = getString("HTML.outputsubdir");
- if (singleOutputSubdir.isEmpty())
- singleOutputSubdir = "html";
- t += QLatin1Char('/') + singleOutputSubdir;
- }
- return t;
-}
-
-/*!
- Function to return the correct outputformats.
- outputformats can be set using the qdocconf or the command-line
- variable -outputformat.
- */
-QSet<QString> Config::getOutputFormats() const
-{
- if (overrideOutputFormats.isEmpty())
- return getStringSet(CONFIG_OUTPUTFORMATS);
- else
- return overrideOutputFormats;
-}
-
-/*!
- First, this function looks up the configuration variable \a var
- in the location map and, if found, sets the internal variable
- \c{lastLocation_} to the Location that \a var maps to.
-
- Then it looks up the configuration variable \a var in the string
- map and returns the string that \a var maps to.
- */
-QString Config::getString(const QString& var) const
-{
- QList<ConfigVar> configVars = configVars_.values(var);
- QString value;
- if (!configVars.empty()) {
- int i = configVars.size() - 1;
- while (i >= 0) {
- const ConfigVar& cv = configVars[i];
- if (!cv.location_.isEmpty())
- const_cast<Config *>(this)->lastLocation_ = cv.location_;
- if (!cv.values_.isEmpty()) {
- if (!cv.plus_)
- value.clear();
- for (int j=0; j<cv.values_.size(); ++j) {
- if (!value.isEmpty() && !value.endsWith(QChar('\n')))
- value.append(QChar(' '));
- value.append(cv.values_[j]);
- }
- }
- --i;
- }
- }
- return value;
-}
-
-/*!
- Looks up the configuration variable \a var in the string
- list map, converts the string list it maps to into a set
- of strings, and returns the set.
- */
-QSet<QString> Config::getStringSet(const QString& var) const
-{
- return QSet<QString>::fromList(getStringList(var));
-}
-
-/*!
- First, this function looks up the configuration variable \a var
- in the location map. If found, it sets the internal variable
- \c{lastLocation_} to the Location that \a var maps to.
-
- Then it looks up the configuration variable \a var in the map of
- configuration variable records. If found, it gets a list of all
- the records for \a var. Then it appends all the values for \a var
- to a list and returns the list. As it appends the values from each
- record, if the \a var used '=' instead of '+=' the list is cleared
- before the values are appended. \note '+=' should always be used.
- The final list is returned.
- */
-QStringList Config::getStringList(const QString& var) const
-{
- QList<ConfigVar> configVars = configVars_.values(var);
- QStringList values;
- if (!configVars.empty()) {
- int i = configVars.size() - 1;
- while (i >= 0) {
- if (!configVars[i].location_.isEmpty())
- const_cast<Config *>(this)->lastLocation_ = configVars[i].location_;
- if (configVars[i].plus_)
- values.append(configVars[i].values_);
- else
- values = configVars[i].values_;
- --i;
- }
- }
- return values;
-}
-
-/*!
- Returns the a path list where all paths from the config variable \a var
- are canonicalized. If \a validate is true, a warning for invalid paths is
- generated.
-
- First, this function looks up the configuration variable \a var
- in the location map and, if found, sets the internal variable
- \c{lastLocation_} the Location that \a var maps to.
-
- Then it looks up the configuration variable \a var in the string
- list map, which maps to one or more records that each contains a
- list of file paths.
-
- \sa Location::canonicalRelativePath()
- */
-QStringList Config::getCanonicalPathList(const QString& var, bool validate) const
-{
- QStringList t;
- QList<ConfigVar> configVars = configVars_.values(var);
- if (!configVars.empty()) {
- int i = configVars.size() - 1;
- while (i >= 0) {
- const ConfigVar& cv = configVars[i];
- if (!cv.location_.isEmpty())
- const_cast<Config *>(this)->lastLocation_ = cv.location_;
- if (!cv.plus_)
- t.clear();
- const QString d = cv.currentPath_;
- const QStringList& sl = cv.values_;
- if (!sl.isEmpty()) {
- t.reserve(t.size() + sl.size());
- for (int i=0; i<sl.size(); ++i) {
- QDir dir(sl[i].simplified());
- QString path = dir.path();
- if (dir.isRelative())
- dir.setPath(d + QLatin1Char('/') + path);
- if (validate && !QFileInfo::exists(dir.path()))
- lastLocation_.warning(tr("Cannot find file or directory: %1").arg(path));
- else
- t.append(dir.canonicalPath());
- }
- }
- --i;
- }
- }
- return t;
-}
-
-/*!
- Calls getRegExpList() with the control variable \a var and
- iterates through the resulting list of regular expressions,
- concatening them with some extras characters to form a single
- QRegExp, which is returned/
-
- \sa getRegExpList()
- */
-QRegExp Config::getRegExp(const QString& var) const
-{
- QString pattern;
- QList<QRegExp> subRegExps = getRegExpList(var);
- QList<QRegExp>::ConstIterator s = subRegExps.constBegin();
-
- while (s != subRegExps.constEnd()) {
- if (!(*s).isValid())
- return *s;
- if (!pattern.isEmpty())
- pattern += QLatin1Char('|');
- pattern += QLatin1String("(?:") + (*s).pattern() + QLatin1Char(')');
- ++s;
- }
- if (pattern.isEmpty())
- pattern = QLatin1String("$x"); // cannot match
- return QRegExp(pattern);
-}
-
-/*!
- Looks up the configuration variable \a var in the string list
- map, converts the string list to a list of regular expressions,
- and returns it.
- */
-QList<QRegExp> Config::getRegExpList(const QString& var) const
-{
- QStringList strs = getStringList(var);
- QStringList::ConstIterator s = strs.constBegin();
- QList<QRegExp> regExps;
-
- while (s != strs.constEnd()) {
- regExps += QRegExp(*s);
- ++s;
- }
- return regExps;
-}
-
-/*!
- This function is slower than it could be. What it does is
- find all the keys that begin with \a var + dot and return
- the matching keys in a set, stripped of the matching prefix
- and dot.
- */
-QSet<QString> Config::subVars(const QString& var) const
-{
- QSet<QString> result;
- QString varDot = var + QLatin1Char('.');
- ConfigVarMultimap::ConstIterator i = configVars_.constBegin();
- while (i != configVars_.constEnd()) {
- if (i.key().startsWith(varDot)) {
- QString subVar = i.key().mid(varDot.length());
- int dot = subVar.indexOf(QLatin1Char('.'));
- if (dot != -1)
- subVar.truncate(dot);
- if (!result.contains(subVar))
- result.insert(subVar);
- }
- ++i;
- }
- return result;
-}
-
-/*!
- Same as subVars(), but in this case we return a config var
- multimap with the matching keys (stripped of the prefix \a var
- and mapped to their values. The pairs are inserted into \a t
- */
-void Config::subVarsAndValues(const QString& var, ConfigVarMultimap& t) const
-{
- QString varDot = var + QLatin1Char('.');
- ConfigVarMultimap::ConstIterator v = configVars_.constBegin();
- while (v != configVars_.constEnd()) {
- if (v.key().startsWith(varDot)) {
- QString subVar = v.key().mid(varDot.length());
- int dot = subVar.indexOf(QLatin1Char('.'));
- if (dot != -1)
- subVar.truncate(dot);
- t.insert(subVar,v.value());
- }
- ++v;
- }
-}
-
-/*!
- Get all .qdocinc files.
- */
-QString Config::getIncludeFilePath(const QString& fileName) const
-{
- QString ext = fileName.mid(fileName.lastIndexOf('.'));
- ext.prepend('*');
-
- if (!includeFilesMap_.contains(ext)) {
- QSet<QString> t;
- QStringList result;
- QStringList dirs = getCanonicalPathList(CONFIG_SOURCEDIRS);
- QStringList::ConstIterator d = dirs.constBegin();
- while (d != dirs.constEnd()) {
- result += getFilesHere(*d, ext, location(), t, t);
- ++d;
- }
- includeFilesMap_.insert(ext, result);
- }
- const QStringList& paths = (*includeFilesMap_.find(ext));
- for (int i=0; i<paths.size(); ++i) {
- if (paths[i].endsWith(fileName))
- return paths[i];
- }
- return QString();
-}
-
-/*!
- Builds and returns a list of file pathnames for the file
- type specified by \a filesVar (e.g. "headers" or "sources").
- The files are found in the directories specified by
- \a dirsVar, and they are filtered by \a defaultNameFilter
- if a better filter can't be constructed from \a filesVar.
- The directories in \a excludedDirs are avoided. The files
- in \a excludedFiles are not included in the return list.
- */
-QStringList Config::getAllFiles(const QString &filesVar,
- const QString &dirsVar,
- const QSet<QString> &excludedDirs,
- const QSet<QString> &excludedFiles)
-{
- QStringList result = getCanonicalPathList(filesVar);
- QStringList dirs = getCanonicalPathList(dirsVar);
-
- QString nameFilter = getString(filesVar + dot + CONFIG_FILEEXTENSIONS);
-
- QStringList::ConstIterator d = dirs.constBegin();
- while (d != dirs.constEnd()) {
- result += getFilesHere(*d, nameFilter, location(), excludedDirs, excludedFiles);
- ++d;
- }
- return result;
-}
-
-QStringList Config::getExampleQdocFiles(const QSet<QString> &excludedDirs,
- const QSet<QString> &excludedFiles)
-{
- QStringList result;
- QStringList dirs = getCanonicalPathList("exampledirs");
- QString nameFilter = " *.qdoc";
-
- QStringList::ConstIterator d = dirs.constBegin();
- while (d != dirs.constEnd()) {
- result += getFilesHere(*d, nameFilter, location(), excludedDirs, excludedFiles);
- ++d;
- }
- return result;
-}
-
-QStringList Config::getExampleImageFiles(const QSet<QString> &excludedDirs,
- const QSet<QString> &excludedFiles)
-{
- QStringList result;
- QStringList dirs = getCanonicalPathList("exampledirs");
- QString nameFilter = getString(CONFIG_EXAMPLES + dot + CONFIG_IMAGEEXTENSIONS);
-
- QStringList::ConstIterator d = dirs.constBegin();
- while (d != dirs.constEnd()) {
- result += getFilesHere(*d, nameFilter, location(), excludedDirs, excludedFiles);
- ++d;
- }
- return result;
-}
-
-/*!
- \a fileName is the path of the file to find.
-
- \a files and \a dirs are the lists where we must find the
- components of \a fileName.
-
- \a location is used for obtaining the file and line numbers
- for report qdoc errors.
- */
-QString Config::findFile(const Location& location,
- const QStringList& files,
- const QStringList& dirs,
- const QString& fileName,
- QString& userFriendlyFilePath)
-{
- if (fileName.isEmpty() || fileName.startsWith(QLatin1Char('/'))) {
- userFriendlyFilePath = fileName;
- return fileName;
- }
-
- QFileInfo fileInfo;
- QStringList components = fileName.split(QLatin1Char('?'));
- QString firstComponent = components.first();
-
- QStringList::ConstIterator f = files.constBegin();
- while (f != files.constEnd()) {
- if (*f == firstComponent ||
- (*f).endsWith(QLatin1Char('/') + firstComponent)) {
- fileInfo.setFile(*f);
- if (!fileInfo.exists())
- location.fatal(tr("File '%1' does not exist").arg(*f));
- break;
- }
- ++f;
- }
-
- if (fileInfo.fileName().isEmpty()) {
- QStringList::ConstIterator d = dirs.constBegin();
- while (d != dirs.constEnd()) {
- fileInfo.setFile(QDir(*d), firstComponent);
- if (fileInfo.exists())
- break;
- ++d;
- }
- }
-
- userFriendlyFilePath = QString();
- if (!fileInfo.exists())
- return QString();
-
- QStringList::ConstIterator c = components.constBegin();
- for (;;) {
- bool isArchive = (c != components.constEnd() - 1);
- QString userFriendly = *c;
-
- userFriendlyFilePath += userFriendly;
-
- if (isArchive) {
- QString extracted = extractedDirs[fileInfo.filePath()];
- ++c;
- fileInfo.setFile(QDir(extracted), *c);
- } else {
- break;
- }
-
- userFriendlyFilePath += QLatin1Char('?');
- }
- return fileInfo.filePath();
-}
-
-/*!
- */
-QString Config::findFile(const Location& location,
- const QStringList& files,
- const QStringList& dirs,
- const QString& fileBase,
- const QStringList& fileExtensions,
- QString& userFriendlyFilePath)
-{
- QStringList::ConstIterator e = fileExtensions.constBegin();
- while (e != fileExtensions.constEnd()) {
- QString filePath = findFile(location,
- files,
- dirs,
- fileBase + QLatin1Char('.') + *e,
- userFriendlyFilePath);
- if (!filePath.isEmpty())
- return filePath;
- ++e;
- }
- return findFile(location, files, dirs, fileBase, userFriendlyFilePath);
-}
-
-/*!
- Copies the \a sourceFilePath to the file name constructed by
- concatenating \a targetDirPath and the file name from the
- \a userFriendlySourceFilePath. \a location is for identifying
- the file and line number where a qdoc error occurred. The
- constructed output file name is returned.
- */
-QString Config::copyFile(const Location& location,
- const QString& sourceFilePath,
- const QString& userFriendlySourceFilePath,
- const QString& targetDirPath)
-{
- QFile inFile(sourceFilePath);
- if (!inFile.open(QFile::ReadOnly)) {
- location.warning(tr("Cannot open input file for copy: '%1': %2")
- .arg(sourceFilePath).arg(inFile.errorString()));
- return QString();
- }
-
- QString outFileName = userFriendlySourceFilePath;
- int slash = outFileName.lastIndexOf(QLatin1Char('/'));
- if (slash != -1)
- outFileName = outFileName.mid(slash);
- if ((outFileName.size()) > 0 && (outFileName[0] != '/'))
- outFileName = targetDirPath + QLatin1Char('/') + outFileName;
- else
- outFileName = targetDirPath + outFileName;
- QFile outFile(outFileName);
- if (!outFile.open(QFile::WriteOnly)) {
- location.warning(tr("Cannot open output file for copy: '%1': %2")
- .arg(outFileName).arg(outFile.errorString()));
- return QString();
- }
-
- char buffer[1024];
- int len;
- while ((len = inFile.read(buffer, sizeof(buffer))) > 0)
- outFile.write(buffer, len);
- return outFileName;
-}
-
-/*!
- Finds the largest unicode digit in \a value in the range
- 1..7 and returns it.
- */
-int Config::numParams(const QString& value)
-{
- int max = 0;
- for (int i = 0; i != value.length(); i++) {
- uint c = value[i].unicode();
- if (c > 0 && c < 8)
- max = qMax(max, (int)c);
- }
- return max;
-}
-
-/*!
- Removes everything from \a dir. This function is recursive.
- It doesn't remove \a dir itself, but if it was called
- recursively, then the caller will remove \a dir.
- */
-bool Config::removeDirContents(const QString& dir)
-{
- QDir dirInfo(dir);
- QFileInfoList entries = dirInfo.entryInfoList();
-
- bool ok = true;
-
- QFileInfoList::Iterator it = entries.begin();
- while (it != entries.end()) {
- if ((*it).isFile()) {
- if (!dirInfo.remove((*it).fileName()))
- ok = false;
- }
- else if ((*it).isDir()) {
- if ((*it).fileName() != QLatin1String(".") && (*it).fileName() != QLatin1String("..")) {
- if (removeDirContents((*it).absoluteFilePath())) {
- if (!dirInfo.rmdir((*it).fileName()))
- ok = false;
- }
- else {
- ok = false;
- }
- }
- }
- ++it;
- }
- return ok;
-}
-
-/*!
- Returns \c true if \a ch is a letter, number, '_', '.',
- '{', '}', or ','.
- */
-bool Config::isMetaKeyChar(QChar ch)
-{
- return ch.isLetterOrNumber()
- || ch == QLatin1Char('_')
- || ch == QLatin1Char('.')
- || ch == QLatin1Char('{')
- || ch == QLatin1Char('}')
- || ch == QLatin1Char(',');
-}
-
-/*!
- \a fileName is a master qdocconf file. It contains a list of
- qdocconf files and nothing else. Read the list and return it.
- */
-QStringList Config::loadMaster(const QString& fileName)
-{
- Location location = Location::null;
- QFile fin(fileName);
- if (!fin.open(QFile::ReadOnly | QFile::Text)) {
- if (!Config::installDir.isEmpty()) {
- int prefix = location.filePath().length() - location.fileName().length();
- fin.setFileName(Config::installDir + QLatin1Char('/') + fileName.right(fileName.length() - prefix));
- }
- if (!fin.open(QFile::ReadOnly | QFile::Text))
- location.fatal(tr("Cannot open master qdocconf file '%1': %2").arg(fileName).arg(fin.errorString()));
- }
- QTextStream stream(&fin);
-#ifndef QT_NO_TEXTCODEC
- stream.setCodec("UTF-8");
-#endif
- QStringList qdocFiles;
- QString line = stream.readLine();
- while (!line.isNull()) {
- qdocFiles.append(line);
- line = stream.readLine();
- }
- fin.close();
- return qdocFiles;
-}
-
-/*!
- Load, parse, and process a qdoc configuration file. This
- function is only called by the other load() function, but
- this one is recursive, i.e., it calls itself when it sees
- an \c{include} statement in the qdoc configuration file.
- */
-void Config::load(Location location, const QString& fileName)
-{
- QFileInfo fileInfo(fileName);
- QString path = fileInfo.canonicalPath();
- pushWorkingDir(path);
- QDir::setCurrent(path);
- QRegExp keySyntax(QLatin1String("\\w+(?:\\.\\w+)*"));
-
-#define SKIP_CHAR() \
- do { \
- location.advance(c); \
- ++i; \
- c = text.at(i); \
- cc = c.unicode(); \
-} while (0)
-
-#define SKIP_SPACES() \
- while (c.isSpace() && cc != '\n') \
- SKIP_CHAR()
-
-#define PUT_CHAR() \
- word += c; \
- SKIP_CHAR();
-
- if (location.depth() > 16)
- location.fatal(tr("Too many nested includes"));
-
- QFile fin(fileInfo.fileName());
- if (!fin.open(QFile::ReadOnly | QFile::Text)) {
- if (!Config::installDir.isEmpty()) {
- int prefix = location.filePath().length() - location.fileName().length();
- fin.setFileName(Config::installDir + QLatin1Char('/') + fileName.right(fileName.length() - prefix));
- }
- if (!fin.open(QFile::ReadOnly | QFile::Text))
- location.fatal(tr("Cannot open file '%1': %2").arg(fileName).arg(fin.errorString()));
- }
-
- QTextStream stream(&fin);
-#ifndef QT_NO_TEXTCODEC
- stream.setCodec("UTF-8");
-#endif
- QString text = stream.readAll();
- text += QLatin1String("\n\n");
- text += QLatin1Char('\0');
- fin.close();
-
- location.push(fileName);
- location.start();
-
- int i = 0;
- QChar c = text.at(0);
- uint cc = c.unicode();
- while (i < (int) text.length()) {
- if (cc == 0) {
- ++i;
- } else if (c.isSpace()) {
- SKIP_CHAR();
- } else if (cc == '#') {
- do {
- SKIP_CHAR();
- } while (cc != '\n');
- } else if (isMetaKeyChar(c)) {
- Location keyLoc = location;
- bool plus = false;
- QString stringValue;
- QStringList rhsValues;
- QString word;
- bool inQuote = false;
- bool prevWordQuoted = true;
- bool metWord = false;
-
- MetaStack stack;
- do {
- stack.process(c, location);
- SKIP_CHAR();
- } while (isMetaKeyChar(c));
-
- QStringList keys = stack.getExpanded(location);
- SKIP_SPACES();
-
- if (keys.count() == 1 && keys.first() == QLatin1String("include")) {
- QString includeFile;
-
- if (cc != '(')
- location.fatal(tr("Bad include syntax"));
- SKIP_CHAR();
- SKIP_SPACES();
-
- while (!c.isSpace() && cc != '#' && cc != ')') {
-
- if (cc == '$') {
- QString var;
- SKIP_CHAR();
- while (c.isLetterOrNumber() || cc == '_') {
- var += c;
- SKIP_CHAR();
- }
- if (!var.isEmpty()) {
- const QByteArray val = qgetenv(var.toLatin1().data());
- if (val.isNull()) {
- location.fatal(tr("Environment variable '%1' undefined").arg(var));
- }
- else {
- includeFile += QString::fromLatin1(val);
- }
- }
- } else {
- includeFile += c;
- SKIP_CHAR();
- }
- }
- SKIP_SPACES();
- if (cc != ')')
- location.fatal(tr("Bad include syntax"));
- SKIP_CHAR();
- SKIP_SPACES();
- if (cc != '#' && cc != '\n')
- location.fatal(tr("Trailing garbage"));
-
- /*
- Here is the recursive call.
- */
- load(location, QFileInfo(QDir(path), includeFile).filePath());
- }
- else {
- /*
- It wasn't an include statement, so it's something else.
- We must see either '=' or '+=' next. If not, fatal error.
- */
- if (cc == '+') {
- plus = true;
- SKIP_CHAR();
- }
- if (cc != '=')
- location.fatal(tr("Expected '=' or '+=' after key"));
- SKIP_CHAR();
- SKIP_SPACES();
-
- for (;;) {
- if (cc == '\\') {
- int metaCharPos;
-
- SKIP_CHAR();
- if (cc == '\n') {
- SKIP_CHAR();
- }
- else if (cc > '0' && cc < '8') {
- word += QChar(c.digitValue());
- SKIP_CHAR();
- }
- else if ((metaCharPos = QString::fromLatin1("abfnrtv").indexOf(c)) != -1) {
- word += QLatin1Char("\a\b\f\n\r\t\v"[metaCharPos]);
- SKIP_CHAR();
- }
- else {
- PUT_CHAR();
- }
- }
- else if (c.isSpace() || cc == '#') {
- if (inQuote) {
- if (cc == '\n')
- location.fatal(tr("Unterminated string"));
- PUT_CHAR();
- }
- else {
- if (!word.isEmpty()) {
- if (metWord)
- stringValue += QLatin1Char(' ');
- stringValue += word;
-#if 0
- if (metWord)
- rhsValues << QString(" " + word);
- else
-#endif
- rhsValues << word;
- metWord = true;
- word.clear();
- prevWordQuoted = false;
- }
- if (cc == '\n' || cc == '#')
- break;
- SKIP_SPACES();
- }
- }
- else if (cc == '"') {
- if (inQuote) {
- if (!prevWordQuoted)
- stringValue += QLatin1Char(' ');
- stringValue += word;
- if (!word.isEmpty())
- rhsValues << word;
- metWord = true;
- word.clear();
- prevWordQuoted = true;
- }
- inQuote = !inQuote;
- SKIP_CHAR();
- }
- else if (cc == '$') {
- QString var;
- SKIP_CHAR();
- while (c.isLetterOrNumber() || cc == '_') {
- var += c;
- SKIP_CHAR();
- }
- if (!var.isEmpty()) {
- const QByteArray val = qgetenv(var.toLatin1().constData());
- if (val.isNull()) {
- location.fatal(tr("Environment variable '%1' undefined").arg(var));
- }
- else {
- word += QString::fromLatin1(val);
- }
- }
- }
- else {
- if (!inQuote && cc == '=')
- location.fatal(tr("Unexpected '='"));
- PUT_CHAR();
- }
- }
-
- QStringList::ConstIterator key = keys.constBegin();
- while (key != keys.constEnd()) {
- if (!keySyntax.exactMatch(*key))
- keyLoc.fatal(tr("Invalid key '%1'").arg(*key));
-
- ConfigVarMultimap::Iterator i;
- i = configVars_.insert(*key, ConfigVar(*key, rhsValues, QDir::currentPath(), keyLoc));
- i.value().plus_ = plus;
- ++key;
- }
- }
- } else {
- location.fatal(tr("Unexpected character '%1' at beginning of line").arg(c));
- }
- }
- popWorkingDir();
- if (!workingDirs_.isEmpty())
- QDir::setCurrent(workingDirs_.top());
-}
-
-QStringList Config::getFilesHere(const QString& uncleanDir,
- const QString& nameFilter,
- const Location &location,
- const QSet<QString> &excludedDirs,
- const QSet<QString> &excludedFiles)
-{
- QString dir = location.isEmpty() ? QDir::cleanPath(uncleanDir) : QDir(uncleanDir).canonicalPath();
- QStringList result;
- if (excludedDirs.contains(dir))
- return result;
-
- QDir dirInfo(dir);
- QStringList fileNames;
- QStringList::const_iterator fn;
-
- dirInfo.setNameFilters(nameFilter.split(QLatin1Char(' ')));
- dirInfo.setSorting(QDir::Name);
- dirInfo.setFilter(QDir::Files);
- fileNames = dirInfo.entryList();
- fn = fileNames.constBegin();
- while (fn != fileNames.constEnd()) {
- if (!fn->startsWith(QLatin1Char('~'))) {
- QString s = dirInfo.filePath(*fn);
- QString c = QDir::cleanPath(s);
- if (!excludedFiles.contains(c))
- result.append(c);
- }
- ++fn;
- }
-
- dirInfo.setNameFilters(QStringList(QLatin1String("*")));
- dirInfo.setFilter(QDir::Dirs|QDir::NoDotAndDotDot);
- fileNames = dirInfo.entryList();
- fn = fileNames.constBegin();
- while (fn != fileNames.constEnd()) {
- result += getFilesHere(dirInfo.filePath(*fn), nameFilter, location, excludedDirs, excludedFiles);
- ++fn;
- }
- return result;
-}
-
-/*!
- Push \a dir onto the stack of working directories.
- */
-void Config::pushWorkingDir(const QString& dir)
-{
- workingDirs_.push(dir);
-}
-
-/*!
- If the stack of working directories is not empty, pop the
- top entry and return it. Otherwise return an empty string.
- */
-QString Config::popWorkingDir()
-{
- if (!workingDirs_.isEmpty())
- return workingDirs_.pop();
-
- qDebug() << "RETURNED EMPTY WORKING DIR";
- return QString();
-}
-
-QT_END_NAMESPACE
diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h
deleted file mode 100644
index 740568ca0c..0000000000
--- a/src/tools/qdoc/config.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- config.h
-*/
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#include <qmap.h>
-#include <qset.h>
-#include <qstringlist.h>
-#include <qstack.h>
-#include <qpair.h>
-#include "location.h"
-
-QT_BEGIN_NAMESPACE
-
-/*
- This struct contains all the information for
- one config variable found in a qdocconf file.
- */
-struct ConfigVar {
- bool plus_;
- QString name_;
- QStringList values_;
- QString currentPath_;
- Location location_;
-
- ConfigVar() : plus_(false) { }
-
- ConfigVar(const QString& name, const QStringList& values, const QString& dir)
- : plus_(true), name_(name), values_(values), currentPath_(dir) { }
-
- ConfigVar(const QString& name, const QStringList& values, const QString& dir, const Location& loc)
- : plus_(false), name_(name), values_(values), currentPath_(dir), location_(loc) { }
-};
-
-/*
- In this multimap, the key is a config variable name.
- */
-typedef QMultiMap<QString, ConfigVar> ConfigVarMultimap;
-
-class Config
-{
- Q_DECLARE_TR_FUNCTIONS(QDoc::Config)
-
-public:
- Config(const QString& programName);
- ~Config();
-
- static bool debug_;
-
- void load(const QString& fileName);
- void setStringList(const QString& var, const QStringList& values);
-
- const QString& programName() const { return prog; }
- const Location& location() const { return loc; }
- const Location& lastLocation() const { return lastLocation_; }
- bool getBool(const QString& var) const;
- int getInt(const QString& var) const;
- QString getOutputDir() const;
- QSet<QString> getOutputFormats() const;
- QString getString(const QString& var) const;
- QSet<QString> getStringSet(const QString& var) const;
- QStringList getStringList(const QString& var) const;
- QStringList getCanonicalPathList(const QString& var, bool validate = false) const;
- QRegExp getRegExp(const QString& var) const;
- QList<QRegExp> getRegExpList(const QString& var) const;
- QSet<QString> subVars(const QString& var) const;
- void subVarsAndValues(const QString& var, ConfigVarMultimap& t) const;
- QStringList getAllFiles(const QString& filesVar,
- const QString& dirsVar,
- const QSet<QString> &excludedDirs = QSet<QString>(),
- const QSet<QString> &excludedFiles = QSet<QString>());
- QString getIncludeFilePath(const QString& fileName) const;
- QStringList getExampleQdocFiles(const QSet<QString> &excludedDirs, const QSet<QString> &excludedFiles);
- QStringList getExampleImageFiles(const QSet<QString> &excludedDirs, const QSet<QString> &excludedFiles);
-
- static QStringList loadMaster(const QString& fileName);
- static QStringList getFilesHere(const QString& dir,
- const QString& nameFilter,
- const Location &location = Location(),
- const QSet<QString> &excludedDirs = QSet<QString>(),
- const QSet<QString> &excludedFiles = QSet<QString>());
- static QString findFile(const Location& location,
- const QStringList &files,
- const QStringList& dirs,
- const QString& fileName,
- QString& userFriendlyFilePath);
- static QString findFile(const Location &location,
- const QStringList &files,
- const QStringList &dirs,
- const QString &fileBase,
- const QStringList &fileExtensions,
- QString &userFriendlyFilePath);
- static QString copyFile(const Location& location,
- const QString& sourceFilePath,
- const QString& userFriendlySourceFilePath,
- const QString& targetDirPath);
- static int numParams(const QString& value);
- static bool removeDirContents(const QString& dir);
- static void pushWorkingDir(const QString& dir);
- static QString popWorkingDir();
-
- static const QString dot;
-
- static bool generateExamples;
- static QString installDir;
- static QString overrideOutputDir;
- static QSet<QString> overrideOutputFormats;
-
-private:
- static bool isMetaKeyChar(QChar ch);
- void load(Location location, const QString& fileName);
-
- QString prog;
- Location loc;
- Location lastLocation_;
- ConfigVarMultimap configVars_;
-
- static QMap<QString, QString> uncompressedFiles;
- static QMap<QString, QString> extractedDirs;
- static int numInstances;
- static QStack<QString> workingDirs_;
- static QMap<QString, QStringList> includeFilesMap_;
-};
-
-struct ConfigStrings
-{
- static QString ALIAS;
- static QString AUTOLINKERRORS;
- static QString BASE;
- static QString BASEDIR;
- static QString BUILDVERSION;
- static QString CODEINDENT;
- static QString CODEPREFIX;
- static QString CODESUFFIX;
- static QString CPPCLASSESPAGE;
- static QString DEFINES;
- static QString DEPENDS;
- static QString DESCRIPTION;
- static QString EDITION;
- static QString ENDHEADER;
- static QString EXAMPLEDIRS;
- static QString EXAMPLES;
- static QString EXAMPLESINSTALLPATH;
- static QString EXCLUDEDIRS;
- static QString EXCLUDEFILES;
- static QString EXTRAIMAGES;
- static QString FALSEHOODS;
- static QString FORMATTING;
- static QString GENERATEINDEX;
- static QString HEADERDIRS;
- static QString HEADERS;
- static QString HEADERSCRIPTS;
- static QString HEADERSTYLES;
- static QString HOMEPAGE;
- static QString IGNOREDIRECTIVES;
- static QString IGNORETOKENS;
- static QString IMAGEDIRS;
- static QString IMAGES;
- static QString INDEXES;
- static QString LANDINGPAGE;
- static QString LANGUAGE;
- static QString MACRO;
- static QString MANIFESTMETA;
- static QString NATURALLANGUAGE;
- static QString NAVIGATION;
- static QString NOLINKERRORS;
- static QString OBSOLETELINKS;
- static QString OUTPUTDIR;
- static QString OUTPUTENCODING;
- static QString OUTPUTLANGUAGE;
- static QString OUTPUTFORMATS;
- static QString OUTPUTPREFIXES;
- static QString OUTPUTSUFFIXES;
- static QString PROJECT;
- static QString REDIRECTDOCUMENTATIONTODEVNULL;
- static QString QHP;
- static QString QUOTINGINFORMATION;
- static QString SCRIPTDIRS;
- static QString SCRIPTS;
- static QString SHOWINTERNAL;
- static QString SINGLEEXEC;
- static QString SOURCEDIRS;
- static QString SOURCEENCODING;
- static QString SOURCES;
- static QString SPURIOUS;
- static QString STYLEDIRS;
- static QString STYLE;
- static QString STYLES;
- static QString STYLESHEETS;
- static QString SYNTAXHIGHLIGHTING;
- static QString TEMPLATEDIR;
- static QString TABSIZE;
- static QString TAGFILE;
- static QString TRANSLATORS;
- static QString URL;
- static QString VERSION;
- static QString VERSIONSYM;
- static QString FILEEXTENSIONS;
- static QString IMAGEEXTENSIONS;
- static QString QMLONLY;
- static QString QMLTYPESPAGE;
- static QString WRITEQAPAGES;
-};
-
-#define CONFIG_ALIAS ConfigStrings::ALIAS
-#define CONFIG_AUTOLINKERRORS ConfigStrings::AUTOLINKERRORS
-#define CONFIG_BASE ConfigStrings::BASE
-#define CONFIG_BASEDIR ConfigStrings::BASEDIR
-#define CONFIG_BUILDVERSION ConfigStrings::BUILDVERSION
-#define CONFIG_CODEINDENT ConfigStrings::CODEINDENT
-#define CONFIG_CODEPREFIX ConfigStrings::CODEPREFIX
-#define CONFIG_CODESUFFIX ConfigStrings::CODESUFFIX
-#define CONFIG_CPPCLASSESPAGE ConfigStrings::CPPCLASSESPAGE
-#define CONFIG_DEFINES ConfigStrings::DEFINES
-#define CONFIG_DEPENDS ConfigStrings::DEPENDS
-#define CONFIG_DESCRIPTION ConfigStrings::DESCRIPTION
-#define CONFIG_EDITION ConfigStrings::EDITION
-#define CONFIG_ENDHEADER ConfigStrings::ENDHEADER
-#define CONFIG_EXAMPLEDIRS ConfigStrings::EXAMPLEDIRS
-#define CONFIG_EXAMPLES ConfigStrings::EXAMPLES
-#define CONFIG_EXAMPLESINSTALLPATH ConfigStrings::EXAMPLESINSTALLPATH
-#define CONFIG_EXCLUDEDIRS ConfigStrings::EXCLUDEDIRS
-#define CONFIG_EXCLUDEFILES ConfigStrings::EXCLUDEFILES
-#define CONFIG_EXTRAIMAGES ConfigStrings::EXTRAIMAGES
-#define CONFIG_FALSEHOODS ConfigStrings::FALSEHOODS
-#define CONFIG_FORMATTING ConfigStrings::FORMATTING
-#define CONFIG_GENERATEINDEX ConfigStrings::GENERATEINDEX
-#define CONFIG_HEADERDIRS ConfigStrings::HEADERDIRS
-#define CONFIG_HEADERS ConfigStrings::HEADERS
-#define CONFIG_HEADERSCRIPTS ConfigStrings::HEADERSCRIPTS
-#define CONFIG_HEADERSTYLES ConfigStrings::HEADERSTYLES
-#define CONFIG_HOMEPAGE ConfigStrings::HOMEPAGE
-#define CONFIG_IGNOREDIRECTIVES ConfigStrings::IGNOREDIRECTIVES
-#define CONFIG_IGNORETOKENS ConfigStrings::IGNORETOKENS
-#define CONFIG_IMAGEDIRS ConfigStrings::IMAGEDIRS
-#define CONFIG_IMAGES ConfigStrings::IMAGES
-#define CONFIG_INDEXES ConfigStrings::INDEXES
-#define CONFIG_LANDINGPAGE ConfigStrings::LANDINGPAGE
-#define CONFIG_LANGUAGE ConfigStrings::LANGUAGE
-#define CONFIG_MACRO ConfigStrings::MACRO
-#define CONFIG_MANIFESTMETA ConfigStrings::MANIFESTMETA
-#define CONFIG_NATURALLANGUAGE ConfigStrings::NATURALLANGUAGE
-#define CONFIG_NAVIGATION ConfigStrings::NAVIGATION
-#define CONFIG_NOLINKERRORS ConfigStrings::NOLINKERRORS
-#define CONFIG_OBSOLETELINKS ConfigStrings::OBSOLETELINKS
-#define CONFIG_OUTPUTDIR ConfigStrings::OUTPUTDIR
-#define CONFIG_OUTPUTENCODING ConfigStrings::OUTPUTENCODING
-#define CONFIG_OUTPUTLANGUAGE ConfigStrings::OUTPUTLANGUAGE
-#define CONFIG_OUTPUTFORMATS ConfigStrings::OUTPUTFORMATS
-#define CONFIG_OUTPUTPREFIXES ConfigStrings::OUTPUTPREFIXES
-#define CONFIG_OUTPUTSUFFIXES ConfigStrings::OUTPUTSUFFIXES
-#define CONFIG_PROJECT ConfigStrings::PROJECT
-#define CONFIG_REDIRECTDOCUMENTATIONTODEVNULL ConfigStrings::REDIRECTDOCUMENTATIONTODEVNULL
-#define CONFIG_QHP ConfigStrings::QHP
-#define CONFIG_QUOTINGINFORMATION ConfigStrings::QUOTINGINFORMATION
-#define CONFIG_SCRIPTDIRS ConfigStrings::SCRIPTDIRS
-#define CONFIG_SCRIPTS ConfigStrings::SCRIPTS
-#define CONFIG_SHOWINTERNAL ConfigStrings::SHOWINTERNAL
-#define CONFIG_SINGLEEXEC ConfigStrings::SINGLEEXEC
-#define CONFIG_SOURCEDIRS ConfigStrings::SOURCEDIRS
-#define CONFIG_SOURCEENCODING ConfigStrings::SOURCEENCODING
-#define CONFIG_SOURCES ConfigStrings::SOURCES
-#define CONFIG_SPURIOUS ConfigStrings::SPURIOUS
-#define CONFIG_STYLEDIRS ConfigStrings::STYLEDIRS
-#define CONFIG_STYLE ConfigStrings::STYLE
-#define CONFIG_STYLES ConfigStrings::STYLES
-#define CONFIG_STYLESHEETS ConfigStrings::STYLESHEETS
-#define CONFIG_SYNTAXHIGHLIGHTING ConfigStrings::SYNTAXHIGHLIGHTING
-#define CONFIG_TEMPLATEDIR ConfigStrings::TEMPLATEDIR
-#define CONFIG_TABSIZE ConfigStrings::TABSIZE
-#define CONFIG_TAGFILE ConfigStrings::TAGFILE
-#define CONFIG_TRANSLATORS ConfigStrings::TRANSLATORS
-#define CONFIG_URL ConfigStrings::URL
-#define CONFIG_VERSION ConfigStrings::VERSION
-#define CONFIG_VERSIONSYM ConfigStrings::VERSIONSYM
-#define CONFIG_FILEEXTENSIONS ConfigStrings::FILEEXTENSIONS
-#define CONFIG_IMAGEEXTENSIONS ConfigStrings::IMAGEEXTENSIONS
-#define CONFIG_QMLONLY ConfigStrings::QMLONLY
-#define CONFIG_QMLTYPESPAGE ConfigStrings::QMLTYPESPAGE
-#define CONFIG_WRITEQAPAGES ConfigStrings::WRITEQAPAGES
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp
deleted file mode 100644
index 01ff827d58..0000000000
--- a/src/tools/qdoc/cppcodemarker.cpp
+++ /dev/null
@@ -1,1326 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- cppcodemarker.cpp
-*/
-
-#include "atom.h"
-#include "cppcodemarker.h"
-#include "node.h"
-#include "text.h"
-#include "tree.h"
-#include <qdebug.h>
-#include <ctype.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- The constructor does nothing.
- */
-CppCodeMarker::CppCodeMarker()
-{
- // nothing.
-}
-
-/*!
- The destructor does nothing.
- */
-CppCodeMarker::~CppCodeMarker()
-{
- // nothing.
-}
-
-/*!
- Returns \c true.
- */
-bool CppCodeMarker::recognizeCode(const QString & /* code */)
-{
- return true;
-}
-
-/*!
- Returns \c true if \a ext is any of a list of file extensions
- for the C++ language.
- */
-bool CppCodeMarker::recognizeExtension(const QString& extension)
-{
- QByteArray ext = extension.toLatin1();
- return ext == "c" ||
- ext == "c++" ||
- ext == "qdoc" ||
- ext == "qtt" ||
- ext == "qtx" ||
- ext == "cc" ||
- ext == "cpp" ||
- ext == "cxx" ||
- ext == "ch" ||
- ext == "h" ||
- ext == "h++" ||
- ext == "hh" ||
- ext == "hpp" ||
- ext == "hxx";
-}
-
-/*!
- Returns \c true if \a lang is either "C" or "Cpp".
- */
-bool CppCodeMarker::recognizeLanguage(const QString &lang)
-{
- return lang == QLatin1String("C") || lang == QLatin1String("Cpp");
-}
-
-/*!
- Returns the type of atom used to represent C++ code in the documentation.
-*/
-Atom::AtomType CppCodeMarker::atomType() const
-{
- return Atom::Code;
-}
-
-QString CppCodeMarker::markedUpCode(const QString &code,
- const Node *relative,
- const Location &location)
-{
- return addMarkUp(code, relative, location);
-}
-
-QString CppCodeMarker::markedUpSynopsis(const Node *node,
- const Node * /* relative */,
- SynopsisStyle style)
-{
- const int MaxEnumValues = 6;
- const FunctionNode *func;
- const PropertyNode *property;
- const VariableNode *variable;
- const EnumNode *enume;
- const TypedefNode *typedeff;
- QString synopsis;
- QString extra;
- QString name;
-
- name = taggedNode(node);
- if (style != Detailed)
- name = linkTag(node, name);
- name = "<@name>" + name + "</@name>";
-
- if ((style == Detailed) && !node->parent()->name().isEmpty() &&
- (node->type() != Node::Property) && !node->isQmlNode() && !node->isJsNode())
- name.prepend(taggedNode(node->parent()) + "::");
-
- switch (node->type()) {
- case Node::Namespace:
- synopsis = "namespace " + name;
- break;
- case Node::Class:
- synopsis = "class " + name;
- break;
- case Node::Function:
- case Node::QmlSignal:
- case Node::QmlSignalHandler:
- case Node::QmlMethod:
- func = (const FunctionNode *) node;
-
- if (style != Subpage && !func->returnType().isEmpty())
- synopsis = typified(func->returnType(), true);
- synopsis += name;
- if (func->metaness() != FunctionNode::MacroWithoutParams) {
- synopsis += QLatin1Char('(');
- if (!func->parameters().isEmpty()) {
- QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
- while (p != func->parameters().constEnd()) {
- if (p != func->parameters().constBegin())
- synopsis += ", ";
- synopsis += typified((*p).dataType(), true);
- if (style != Subpage && !(*p).name().isEmpty())
- synopsis +=
- "<@param>" + protect((*p).name()) + "</@param>";
- synopsis += protect((*p).rightType());
- if (style != Subpage && !(*p).defaultValue().isEmpty())
- synopsis += " = " + protect((*p).defaultValue());
- ++p;
- }
- }
- synopsis += QLatin1Char(')');
- }
- if (func->isConst())
- synopsis += " const";
-
- if (style == Summary || style == Accessors) {
- if (func->virtualness() != FunctionNode::NonVirtual)
- synopsis.prepend("virtual ");
- if (func->virtualness() == FunctionNode::PureVirtual)
- synopsis.append(" = 0");
- }
- else if (style == Subpage) {
- if (!func->returnType().isEmpty() && func->returnType() != "void")
- synopsis += " : " + typified(func->returnType());
- }
- else {
- QStringList bracketed;
- if (func->isStatic()) {
- bracketed += "static";
- }
- else if (func->virtualness() != FunctionNode::NonVirtual) {
- if (func->virtualness() == FunctionNode::PureVirtual)
- bracketed += "pure";
- bracketed += "virtual";
- }
-
- if (func->access() == Node::Protected) {
- bracketed += "protected";
- }
- else if (func->access() == Node::Private) {
- bracketed += "private";
- }
-
- if (func->metaness() == FunctionNode::Signal) {
- bracketed += "signal";
- }
- else if (func->metaness() == FunctionNode::Slot) {
- bracketed += "slot";
- }
- if (!bracketed.isEmpty())
- extra += QLatin1Char('[') + bracketed.join(' ') + QStringLiteral("] ");
- }
- break;
- case Node::Enum:
- enume = static_cast<const EnumNode *>(node);
- synopsis = "enum " + name;
- if (style == Summary) {
- synopsis += " { ";
-
- QStringList documentedItems = enume->doc().enumItemNames();
- if (documentedItems.isEmpty()) {
- foreach (const EnumItem &item, enume->items())
- documentedItems << item.name();
- }
- QStringList omitItems = enume->doc().omitEnumItemNames();
- foreach (const QString &item, omitItems)
- documentedItems.removeAll(item);
-
- if (documentedItems.size() <= MaxEnumValues) {
- for (int i = 0; i < documentedItems.size(); ++i) {
- if (i != 0)
- synopsis += ", ";
- synopsis += documentedItems.at(i);
- }
- }
- else {
- for (int i = 0; i < documentedItems.size(); ++i) {
- if (i < MaxEnumValues-2 || i == documentedItems.size()-1) {
- if (i != 0)
- synopsis += ", ";
- synopsis += documentedItems.at(i);
- }
- else if (i == MaxEnumValues - 1) {
- synopsis += ", ...";
- }
- }
- }
- if (!documentedItems.isEmpty())
- synopsis += QLatin1Char(' ');
- synopsis += QLatin1Char('}');
- }
- break;
- case Node::Typedef:
- typedeff = static_cast<const TypedefNode *>(node);
- if (typedeff->associatedEnum()) {
- synopsis = "flags " + name;
- }
- else {
- synopsis = "typedef " + name;
- }
- break;
- case Node::Property:
- property = static_cast<const PropertyNode *>(node);
- synopsis = name + " : " + typified(property->qualifiedDataType());
- break;
- case Node::Variable:
- variable = static_cast<const VariableNode *>(node);
- if (style == Subpage) {
- synopsis = name + " : " + typified(variable->dataType());
- }
- else {
- synopsis = typified(variable->leftType(), true) +
- name + protect(variable->rightType());
- }
- break;
- default:
- synopsis = name;
- }
-
- if (style == Summary) {
- if (node->status() == Node::Preliminary) {
- extra += "(preliminary) ";
- }
- else if (node->status() == Node::Deprecated) {
- extra += "(deprecated) ";
- }
- else if (node->status() == Node::Obsolete) {
- extra += "(obsolete) ";
- }
- }
-
- if (!extra.isEmpty()) {
- extra.prepend("<@extra>");
- extra.append("</@extra>");
- }
- return extra + synopsis;
-}
-
-/*!
- */
-QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
-{
- QString name = taggedQmlNode(node);
- if (summary)
- name = linkTag(node,name);
- else if (node->isQmlProperty() || node->isJsProperty()) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
- if (pn->isAttached())
- name.prepend(pn->element() + QLatin1Char('.'));
- }
- name = "<@name>" + name + "</@name>";
- QString synopsis;
- if (node->isQmlProperty() || node->isJsProperty()) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
- synopsis = name + " : " + typified(pn->dataType());
- }
- else if ((node->type() == Node::QmlMethod) ||
- (node->type() == Node::QmlSignal) ||
- (node->type() == Node::QmlSignalHandler)) {
- const FunctionNode* func = static_cast<const FunctionNode*>(node);
- if (!func->returnType().isEmpty())
- synopsis = typified(func->returnType(), true) + name;
- else
- synopsis = name;
- synopsis += QLatin1Char('(');
- if (!func->parameters().isEmpty()) {
- QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
- while (p != func->parameters().constEnd()) {
- if (p != func->parameters().constBegin())
- synopsis += ", ";
- synopsis += typified((*p).dataType(), true);
- if (!(*p).name().isEmpty())
- synopsis += "<@param>" + protect((*p).name()) + "</@param>";
- synopsis += protect((*p).rightType());
- ++p;
- }
- }
- synopsis += QLatin1Char(')');
- }
- else
- synopsis = name;
-
- QString extra;
- if (summary) {
- if (node->status() == Node::Preliminary) {
- extra += " (preliminary)";
- }
- else if (node->status() == Node::Deprecated) {
- extra += " (deprecated)";
- }
- else if (node->status() == Node::Obsolete) {
- extra += " (obsolete)";
- }
- }
-
- if (!extra.isEmpty()) {
- extra.prepend("<@extra>");
- extra.append("</@extra>");
- }
- return synopsis + extra;
-}
-
-QString CppCodeMarker::markedUpName(const Node *node)
-{
- QString name = linkTag(node, taggedNode(node));
- if (node->type() == Node::Function)
- name += "()";
- return name;
-}
-
-QString CppCodeMarker::markedUpFullName(const Node *node, const Node *relative)
-{
- if (node->name().isEmpty()) {
- return "global";
- }
- else {
- QString fullName;
- for (;;) {
- fullName.prepend(markedUpName(node));
- if (node->parent() == relative || node->parent()->name().isEmpty())
- break;
- fullName.prepend("<@op>::</@op>");
- node = node->parent();
- }
- return fullName;
- }
-}
-
-QString CppCodeMarker::markedUpEnumValue(const QString &enumValue, const Node *relative)
-{
- if (relative->type() != Node::Enum)
- return enumValue;
-
- const Node *node = relative->parent();
- QString fullName;
- while (node->parent()) {
- fullName.prepend(markedUpName(node));
- if (node->parent() == relative || node->parent()->name().isEmpty())
- break;
- fullName.prepend("<@op>::</@op>");
- node = node->parent();
- }
- if (!fullName.isEmpty())
- fullName.append("<@op>::</@op>");
- fullName.append(enumValue);
- return fullName;
-}
-
-QString CppCodeMarker::markedUpIncludes(const QStringList& includes)
-{
- QString code;
-
- QStringList::ConstIterator inc = includes.constBegin();
- while (inc != includes.constEnd()) {
- code += "<@preprocessor>#include &lt;<@headerfile>" + *inc + "</@headerfile>&gt;</@preprocessor>\n";
- ++inc;
- }
- return code;
-}
-
-QString CppCodeMarker::functionBeginRegExp(const QString& funcName)
-{
- return QLatin1Char('^') + QRegExp::escape(funcName) + QLatin1Char('$');
-
-}
-
-QString CppCodeMarker::functionEndRegExp(const QString& /* funcName */)
-{
- return "^\\}$";
-}
-
-QList<Section> CppCodeMarker::sections(const Aggregate *inner,
- SynopsisStyle style,
- Status status)
-{
- QList<Section> sections;
-
- if (inner->isClass()) {
- if (style == Summary) {
- FastSection privateFunctions(inner,
- "Private Functions",
- QString(),
- "private function",
- "private functions");
- FastSection privateSlots(inner, "Private Slots", QString(), "private slot", "private slots");
- FastSection privateTypes(inner, "Private Types", QString(), "private type", "private types");
- FastSection protectedFunctions(inner,
- "Protected Functions",
- QString(),
- "protected function",
- "protected functions");
- FastSection protectedSlots(inner,
- "Protected Slots",
- QString(),
- "protected slot",
- "protected slots");
- FastSection protectedTypes(inner,
- "Protected Types",
- QString(),
- "protected type",
- "protected types");
- FastSection protectedVariables(inner,
- "Protected Variables",
- QString(),
- "protected type",
- "protected variables");
- FastSection publicFunctions(inner,
- "Public Functions",
- QString(),
- "public function",
- "public functions");
- FastSection publicSignals(inner, "Signals", QString(), "signal", "signals");
- FastSection publicSlots(inner, "Public Slots", QString(), "public slot", "public slots");
- FastSection publicTypes(inner, "Public Types", QString(), "public type", "public types");
- FastSection publicVariables(inner,
- "Public Variables",
- QString(),
- "public variable",
- "public variables");
- FastSection properties(inner, "Properties", QString(), "property", "properties");
- FastSection relatedNonMembers(inner,
- "Related Non-Members",
- QString(),
- "related non-member",
- "related non-members");
- FastSection staticPrivateMembers(inner,
- "Static Private Members",
- QString(),
- "static private member",
- "static private members");
- FastSection staticProtectedMembers(inner,
- "Static Protected Members",
- QString(),
- "static protected member",
- "static protected members");
- FastSection staticPublicMembers(inner,
- "Static Public Members",
- QString(),
- "static public member",
- "static public members");
- FastSection macros(inner, "Macros", QString(), "macro", "macros");
-
- NodeList::ConstIterator r = inner->relatedNodes().constBegin();
- while (r != inner->relatedNodes().constEnd()) {
- if ((*r)->type() == Node::Function) {
- FunctionNode *func = static_cast<FunctionNode *>(*r);
- if (func->isMacro())
- insert(macros, *r, style, status);
- else
- insert(relatedNonMembers, *r, style, status);
- }
- else {
- insert(relatedNonMembers, *r, style, status);
- }
- ++r;
- }
-
- QStack<const Aggregate *> stack;
- stack.push(inner);
- while (!stack.isEmpty()) {
- const Aggregate* ancestor = stack.pop();
-
- NodeList::ConstIterator c = ancestor->childNodes().constBegin();
- while (c != ancestor->childNodes().constEnd()) {
- bool isSlot = false;
- bool isSignal = false;
- bool isStatic = false;
- if ((*c)->type() == Node::Function) {
- const FunctionNode *func = (const FunctionNode *) *c;
- isSlot = (func->metaness() == FunctionNode::Slot);
- isSignal = (func->metaness() == FunctionNode::Signal);
- isStatic = func->isStatic();
- if (func->hasAssociatedProperties() && !func->hasActiveAssociatedProperty()) {
- ++c;
- continue;
- }
- }
- else if ((*c)->type() == Node::Variable) {
- const VariableNode *var = static_cast<const VariableNode *>(*c);
- isStatic = var->isStatic();
- }
-
- switch ((*c)->access()) {
- case Node::Public:
- if (isSlot) {
- insert(publicSlots, *c, style, status);
- }
- else if (isSignal) {
- insert(publicSignals, *c, style, status);
- }
- else if (isStatic) {
- if ((*c)->type() != Node::Variable || !(*c)->doc().isEmpty())
- insert(staticPublicMembers,*c,style,status);
- }
- else if ((*c)->type() == Node::Property) {
- insert(properties, *c, style, status);
- }
- else if ((*c)->type() == Node::Variable) {
- if (!(*c)->doc().isEmpty())
- insert(publicVariables, *c, style, status);
- }
- else if ((*c)->type() == Node::Function) {
- if (!insertReimpFunc(publicFunctions,*c,status)) {
- insert(publicFunctions, *c, style, status);
- }
- }
- else {
- insert(publicTypes, *c, style, status);
- }
- break;
- case Node::Protected:
- if (isSlot) {
- insert(protectedSlots, *c, style, status);
- }
- else if (isStatic) {
- if ((*c)->type() != Node::Variable || !(*c)->doc().isEmpty())
- insert(staticProtectedMembers,*c,style,status);
- }
- else if ((*c)->type() == Node::Variable) {
- if (!(*c)->doc().isEmpty())
- insert(protectedVariables,*c,style,status);
- }
- else if ((*c)->type() == Node::Function) {
- if (!insertReimpFunc(protectedFunctions,*c,status)) {
- insert(protectedFunctions, *c, style, status);
- }
- }
- else {
- insert(protectedTypes, *c, style, status);
- }
- break;
- case Node::Private:
- if (isSlot) {
- insert(privateSlots, *c, style, status);
- }
- else if (isStatic) {
- if ((*c)->type() != Node::Variable || !(*c)->doc().isEmpty())
- insert(staticPrivateMembers,*c,style,status);
- }
- else if ((*c)->type() == Node::Function) {
- if (!insertReimpFunc(privateFunctions,*c,status)) {
- insert(privateFunctions, *c, style, status);
- }
- }
- else {
- insert(privateTypes,*c,style,status);
- }
- }
- ++c;
- }
-
- if (ancestor->isClass()) {
- const ClassNode* cn = static_cast<const ClassNode*>(ancestor);
- QList<RelatedClass>::ConstIterator r = cn->baseClasses().constBegin();
- while (r != cn->baseClasses().constEnd()) {
- if ((*r).node_)
- stack.prepend((*r).node_);
- ++r;
- }
- }
- }
- append(sections, publicTypes);
- append(sections, properties);
- append(sections, publicFunctions);
- append(sections, publicSlots);
- append(sections, publicSignals);
- append(sections, publicVariables);
- append(sections, staticPublicMembers);
- append(sections, protectedTypes);
- append(sections, protectedFunctions);
- append(sections, protectedSlots);
- append(sections, protectedVariables);
- append(sections, staticProtectedMembers);
- append(sections, privateTypes);
- append(sections, privateFunctions);
- append(sections, privateSlots);
- append(sections, staticPrivateMembers);
- append(sections, relatedNonMembers);
- append(sections, macros);
- }
- else if (style == Detailed) {
- FastSection memberFunctions(inner,"Member Function Documentation","func","member","members");
- FastSection memberTypes(inner,"Member Type Documentation","types","member","members");
- FastSection memberVariables(inner,"Member Variable Documentation","vars","member","members");
- FastSection properties(inner,"Property Documentation","prop","member","members");
- FastSection relatedNonMembers(inner,"Related Non-Members","relnonmem","member","members");
- FastSection macros(inner,"Macro Documentation","macros","member","members");
-
- NodeList::ConstIterator r = inner->relatedNodes().constBegin();
- while (r != inner->relatedNodes().constEnd()) {
- if ((*r)->type() == Node::Function) {
- FunctionNode *func = static_cast<FunctionNode *>(*r);
- if (func->isMacro())
- insert(macros, *r, style, status);
- else
- insert(relatedNonMembers, *r, style, status);
- }
- else {
- insert(relatedNonMembers, *r, style, status);
- }
- ++r;
- }
-
- NodeList::ConstIterator c = inner->childNodes().constBegin();
- while (c != inner->childNodes().constEnd()) {
- if ((*c)->type() == Node::Enum ||
- (*c)->type() == Node::Typedef) {
- insert(memberTypes, *c, style, status);
- }
- else if ((*c)->type() == Node::Property) {
- insert(properties, *c, style, status);
- }
- else if ((*c)->type() == Node::Variable) {
- if (!(*c)->doc().isEmpty())
- insert(memberVariables, *c, style, status);
- }
- else if ((*c)->type() == Node::Function) {
- FunctionNode *function = static_cast<FunctionNode *>(*c);
- if (!function->hasAssociatedProperties() || !function->doc().isEmpty())
- insert(memberFunctions, function, style, status);
- }
- ++c;
- }
-
- append(sections, memberTypes);
- append(sections, properties);
- append(sections, memberFunctions);
- append(sections, memberVariables);
- append(sections, relatedNonMembers);
- append(sections, macros);
- }
- else {
- FastSection all(inner,QString(),QString(),"member","members");
-
- QStack<const Aggregate*> stack;
- stack.push(inner);
-
- while (!stack.isEmpty()) {
- const Aggregate* ancestor = stack.pop();
- NodeList::ConstIterator c = ancestor->childNodes().constBegin();
- while (c != ancestor->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private && (*c)->type() != Node::Property)
- insert(all, *c, style, status);
- ++c;
- }
-
- if (ancestor->isClass()) {
- const ClassNode* cn = static_cast<const ClassNode*>(ancestor);
- QList<RelatedClass>::ConstIterator r = cn->baseClasses().constBegin();
- while (r != cn->baseClasses().constEnd()) {
- if ((*r).node_)
- stack.prepend((*r).node_);
- ++r;
- }
- }
- }
- append(sections, all);
- }
- }
- else {
- if (style == Summary || style == Detailed) {
- FastSection namespaces(inner,
- "Namespaces",
- style == Detailed ? "nmspace" : QString(),
- "namespace",
- "namespaces");
- FastSection classes(inner,
- "Classes",
- style == Detailed ? "classes" : QString(),
- "class",
- "classes");
- FastSection types(inner,
- style == Summary ? "Types" : "Type Documentation",
- style == Detailed ? "types" : QString(),
- "type",
- "types");
- FastSection variables(inner,
- style == Summary ? "Variables" : "Variable Documentation",
- style == Detailed ? "vars" : QString(),
- "variable",
- "variables");
- FastSection staticVariables(inner,
- "Static Variables",
- QString(),
- "static variable",
- "static variables");
- FastSection functions(inner,
- style == Summary ?
- "Functions" : "Function Documentation",
- style == Detailed ? "func" : QString(),
- "function",
- "functions");
- FastSection macros(inner,
- style == Summary ?
- "Macros" : "Macro Documentation",
- style == Detailed ? "macros" : QString(),
- "macro",
- "macros");
-
- NodeList nodeList = inner->childNodes();
- nodeList += inner->relatedNodes();
-
- NodeList::ConstIterator n = nodeList.constBegin();
- while (n != nodeList.constEnd()) {
- switch ((*n)->type()) {
- case Node::Namespace:
- insert(namespaces, *n, style, status);
- break;
- case Node::Class:
- insert(classes, *n, style, status);
- break;
- case Node::Enum:
- case Node::Typedef:
- insert(types, *n, style, status);
- break;
- case Node::Function:
- {
- FunctionNode *func = static_cast<FunctionNode *>(*n);
- if (func->isMacro())
- insert(macros, *n, style, status);
- else
- insert(functions, *n, style, status);
- }
- break;
- case Node::Variable:
- {
- const VariableNode* var = static_cast<const VariableNode*>(*n);
- if (!var->doc().isEmpty()) {
- if (var->isStatic())
- insert(staticVariables,*n,style,status);
- else
- insert(variables, *n, style, status);
- }
- }
- break;
- default:
- break;
- }
- ++n;
- }
- if (inner->isNamespace()) {
- const NamespaceNode* ns = static_cast<const NamespaceNode*>(inner);
- if (!ns->orphans().isEmpty()) {
- foreach (Node* n, ns->orphans()) {
- // Use inner as a temporary parent when inserting orphans
- Aggregate* p = n->parent();
- n->setParent(const_cast<Aggregate*>(inner));
- if (n->isClass())
- insert(classes, n, style, status);
- else if (n->isNamespace())
- insert(namespaces, n, style, status);
- n->setParent(p);
- }
- }
- }
- append(sections, namespaces);
- append(sections, classes);
- append(sections, types);
- append(sections, variables);
- append(sections, staticVariables);
- append(sections, functions);
- append(sections, macros);
- }
- }
-
- return sections;
-}
-
-/*
- @char
- @class
- @comment
- @function
- @keyword
- @number
- @op
- @preprocessor
- @string
- @type
-*/
-
-QString CppCodeMarker::addMarkUp(const QString &in,
- const Node * /* relative */,
- const Location & /* location */)
-{
- static QSet<QString> types;
- static QSet<QString> keywords;
-
- if (types.isEmpty()) {
- // initialize statics
- Q_ASSERT(keywords.isEmpty());
- static const QString typeTable[] = {
- QLatin1String("bool"), QLatin1String("char"), QLatin1String("double"), QLatin1String("float"), QLatin1String("int"), QLatin1String("long"), QLatin1String("short"),
- QLatin1String("signed"), QLatin1String("unsigned"), QLatin1String("uint"), QLatin1String("ulong"), QLatin1String("ushort"), QLatin1String("uchar"), QLatin1String("void"),
- QLatin1String("qlonglong"), QLatin1String("qulonglong"),
- QLatin1String("qint"), QLatin1String("qint8"), QLatin1String("qint16"), QLatin1String("qint32"), QLatin1String("qint64"),
- QLatin1String("quint"), QLatin1String("quint8"), QLatin1String("quint16"), QLatin1String("quint32"), QLatin1String("quint64"),
- QLatin1String("qreal"), QLatin1String("cond")
- };
-
- static const QString keywordTable[] = {
- QLatin1String("and"), QLatin1String("and_eq"), QLatin1String("asm"), QLatin1String("auto"), QLatin1String("bitand"), QLatin1String("bitor"), QLatin1String("break"),
- QLatin1String("case"), QLatin1String("catch"), QLatin1String("class"), QLatin1String("compl"), QLatin1String("const"), QLatin1String("const_cast"),
- QLatin1String("continue"), QLatin1String("default"), QLatin1String("delete"), QLatin1String("do"), QLatin1String("dynamic_cast"), QLatin1String("else"),
- QLatin1String("enum"), QLatin1String("explicit"), QLatin1String("export"), QLatin1String("extern"), QLatin1String("false"), QLatin1String("for"), QLatin1String("friend"),
- QLatin1String("goto"), QLatin1String("if"), QLatin1String("include"), QLatin1String("inline"), QLatin1String("monitor"), QLatin1String("mutable"), QLatin1String("namespace"),
- QLatin1String("new"), QLatin1String("not"), QLatin1String("not_eq"), QLatin1String("operator"), QLatin1String("or"), QLatin1String("or_eq"), QLatin1String("private"), QLatin1String("protected"),
- QLatin1String("public"), QLatin1String("register"), QLatin1String("reinterpret_cast"), QLatin1String("return"), QLatin1String("sizeof"),
- QLatin1String("static"), QLatin1String("static_cast"), QLatin1String("struct"), QLatin1String("switch"), QLatin1String("template"), QLatin1String("this"),
- QLatin1String("throw"), QLatin1String("true"), QLatin1String("try"), QLatin1String("typedef"), QLatin1String("typeid"), QLatin1String("typename"), QLatin1String("union"),
- QLatin1String("using"), QLatin1String("virtual"), QLatin1String("volatile"), QLatin1String("wchar_t"), QLatin1String("while"), QLatin1String("xor"),
- QLatin1String("xor_eq"), QLatin1String("synchronized"),
- // Qt specific
- QLatin1String("signals"), QLatin1String("slots"), QLatin1String("emit")
- };
-
- types.reserve(sizeof(typeTable) / sizeof(QString));
- for (int j = sizeof(typeTable) / sizeof(QString) - 1; j; --j)
- types.insert(typeTable[j]);
-
- keywords.reserve(sizeof(keywordTable) / sizeof(QString));
- for (int j = sizeof(keywordTable) / sizeof(QString) - 1; j; --j)
- keywords.insert(keywordTable[j]);
- }
-#define readChar() \
- ch = (i < (int)code.length()) ? code[i++].cell() : EOF
-
- QString code = in;
- QString out;
- QStringRef text;
- int braceDepth = 0;
- int parenDepth = 0;
- int i = 0;
- int start = 0;
- int finish = 0;
- QChar ch;
- QRegExp classRegExp("Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)");
- QRegExp functionRegExp("q([A-Z][a-z]+)+");
- QRegExp findFunctionRegExp(QStringLiteral("^\\s*\\("));
-
- readChar();
-
- while (ch != EOF) {
- QString tag;
- bool target = false;
-
- if (ch.isLetter() || ch == '_') {
- QString ident;
- do {
- ident += ch;
- finish = i;
- readChar();
- } while (ch.isLetterOrNumber() || ch == '_');
-
- if (classRegExp.exactMatch(ident)) {
- tag = QStringLiteral("type");
- } else if (functionRegExp.exactMatch(ident)) {
- tag = QStringLiteral("func");
- target = true;
- } else if (types.contains(ident)) {
- tag = QStringLiteral("type");
- } else if (keywords.contains(ident)) {
- tag = QStringLiteral("keyword");
- } else if (braceDepth == 0 && parenDepth == 0) {
- if (code.indexOf(findFunctionRegExp, i - 1) == i - 1)
- tag = QStringLiteral("func");
- target = true;
- }
- } else if (ch.isDigit()) {
- do {
- finish = i;
- readChar();
- } while (ch.isLetterOrNumber() || ch == '.');
- tag = QStringLiteral("number");
- } else {
- switch (ch.unicode()) {
- case '+':
- case '-':
- case '!':
- case '%':
- case '^':
- case '&':
- case '*':
- case ',':
- case '.':
- case '<':
- case '=':
- case '>':
- case '?':
- case '[':
- case ']':
- case '|':
- case '~':
- finish = i;
- readChar();
- tag = QStringLiteral("op");
- break;
- case '"':
- finish = i;
- readChar();
-
- while (ch != EOF && ch != '"') {
- if (ch == '\\')
- readChar();
- readChar();
- }
- finish = i;
- readChar();
- tag = QStringLiteral("string");
- break;
- case '#':
- finish = i;
- readChar();
- while (ch != EOF && ch != '\n') {
- if (ch == '\\')
- readChar();
- finish = i;
- readChar();
- }
- tag = QStringLiteral("preprocessor");
- break;
- case '\'':
- finish = i;
- readChar();
-
- while (ch != EOF && ch != '\'') {
- if (ch == '\\')
- readChar();
- readChar();
- }
- finish = i;
- readChar();
- tag = QStringLiteral("char");
- break;
- case '(':
- finish = i;
- readChar();
- parenDepth++;
- break;
- case ')':
- finish = i;
- readChar();
- parenDepth--;
- break;
- case ':':
- finish = i;
- readChar();
- if (ch == ':') {
- finish = i;
- readChar();
- tag = QStringLiteral("op");
- }
- break;
- case '/':
- finish = i;
- readChar();
- if (ch == '/') {
- do {
- finish = i;
- readChar();
- } while (ch != EOF && ch != '\n');
- tag = QStringLiteral("comment");
- } else if (ch == '*') {
- bool metAster = false;
- bool metAsterSlash = false;
-
- finish = i;
- readChar();
-
- while (!metAsterSlash) {
- if (ch == EOF)
- break;
-
- if (ch == '*')
- metAster = true;
- else if (metAster && ch == '/')
- metAsterSlash = true;
- else
- metAster = false;
- finish = i;
- readChar();
- }
- tag = QStringLiteral("comment");
- } else {
- tag = QStringLiteral("op");
- }
- break;
- case '{':
- finish = i;
- readChar();
- braceDepth++;
- break;
- case '}':
- finish = i;
- readChar();
- braceDepth--;
- break;
- default:
- finish = i;
- readChar();
- }
- }
-
- text = code.midRef(start, finish - start);
- start = finish;
-
- if (!tag.isEmpty()) {
- out += QStringLiteral("<@");
- out += tag;
- if (target) {
- out += QStringLiteral(" target=\"");
- out += text;
- out += QStringLiteral("()\"");
- }
- out += QStringLiteral(">");
- }
-
- appendProtectedString(&out, text);
-
- if (!tag.isEmpty()) {
- out += QStringLiteral("</@");
- out += tag;
- out += QStringLiteral(">");
- }
- }
-
- if (start < code.length()) {
- appendProtectedString(&out, code.midRef(start));
- }
-
- return out;
-}
-
-/*!
- This function is for documenting QML properties. It returns
- the list of documentation sections for the children of the
- \a qmlTypeNode.
- */
-QList<Section> CppCodeMarker::qmlSections(QmlTypeNode* qmlTypeNode, SynopsisStyle style, Status status)
-{
- QList<Section> sections;
- if (qmlTypeNode) {
- if (style == Summary) {
- FastSection qmlproperties(qmlTypeNode,
- "Properties",
- QString(),
- "property",
- "properties");
- FastSection qmlattachedproperties(qmlTypeNode,
- "Attached Properties",
- QString(),
- "property",
- "properties");
- FastSection qmlsignals(qmlTypeNode,
- "Signals",
- QString(),
- "signal",
- "signals");
- FastSection qmlsignalhandlers(qmlTypeNode,
- "Signal Handlers",
- QString(),
- "signal handler",
- "signal handlers");
- FastSection qmlattachedsignals(qmlTypeNode,
- "Attached Signals",
- QString(),
- "signal",
- "signals");
- FastSection qmlmethods(qmlTypeNode,
- "Methods",
- QString(),
- "method",
- "methods");
- FastSection qmlattachedmethods(qmlTypeNode,
- "Attached Methods",
- QString(),
- "method",
- "methods");
-
- QmlTypeNode* qcn = qmlTypeNode;
- while (qcn != 0) {
- NodeList::ConstIterator c = qcn->childNodes().constBegin();
- while (c != qcn->childNodes().constEnd()) {
- if ((*c)->status() == Node::Internal) {
- ++c;
- continue;
- }
- if ((*c)->isQmlPropertyGroup() || (*c)->isJsPropertyGroup()) {
- insert(qmlproperties, *c, style, status);
- }
- else if ((*c)->isQmlProperty() || (*c)->isJsProperty()) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
- if (pn->isAttached())
- insert(qmlattachedproperties,*c,style, status);
- else {
- insert(qmlproperties,*c,style, status);
- }
- }
- else if ((*c)->isQmlSignal() || (*c)->isJsSignal()) {
- const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
- if (sn->isAttached())
- insert(qmlattachedsignals,*c,style, status);
- else
- insert(qmlsignals,*c,style, status);
- }
- else if ((*c)->isQmlSignalHandler() || (*c)->isJsSignalHandler()) {
- insert(qmlsignalhandlers,*c,style, status);
- }
- else if ((*c)->isQmlMethod() || (*c)->isJsMethod()) {
- const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
- if (mn->isAttached())
- insert(qmlattachedmethods,*c,style, status);
- else
- insert(qmlmethods,*c,style, status);
- }
- ++c;
- }
- if (qcn->qmlBaseNode() != 0) {
- qcn = static_cast<QmlTypeNode*>(qcn->qmlBaseNode());
- if (!qcn->isAbstract())
- qcn = 0;
- }
- else
- qcn = 0;
- }
- append(sections,qmlproperties);
- append(sections,qmlattachedproperties);
- append(sections,qmlsignals);
- append(sections,qmlsignalhandlers);
- append(sections,qmlattachedsignals);
- append(sections,qmlmethods);
- append(sections,qmlattachedmethods);
- }
- else if (style == Detailed) {
- FastSection qmlproperties(qmlTypeNode, "Property Documentation","qmlprop","member","members");
- FastSection qmlattachedproperties(qmlTypeNode,"Attached Property Documentation","qmlattprop",
- "member","members");
- FastSection qmlsignals(qmlTypeNode,"Signal Documentation","qmlsig","signal","signals");
- FastSection qmlsignalhandlers(qmlTypeNode,"Signal Handler Documentation","qmlsighan","signal handler","signal handlers");
- FastSection qmlattachedsignals(qmlTypeNode,"Attached Signal Documentation","qmlattsig",
- "signal","signals");
- FastSection qmlmethods(qmlTypeNode,"Method Documentation","qmlmeth","member","members");
- FastSection qmlattachedmethods(qmlTypeNode,"Attached Method Documentation","qmlattmeth",
- "member","members");
- QmlTypeNode* qcn = qmlTypeNode;
- while (qcn != 0) {
- NodeList::ConstIterator c = qcn->childNodes().constBegin();
- while (c != qcn->childNodes().constEnd()) {
- if ((*c)->status() == Node::Internal) {
- ++c;
- continue;
- }
- if ((*c)->isQmlPropertyGroup() || (*c)->isJsPropertyGroup()) {
- insert(qmlproperties,*c,style, status);
- }
- else if ((*c)->isQmlProperty() || (*c)->isJsProperty()) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
- if (pn->isAttached())
- insert(qmlattachedproperties,*c,style, status);
- else
- insert(qmlproperties,*c,style, status);
- }
- else if ((*c)->isQmlSignal() || (*c)->isJsSignal()) {
- const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
- if (sn->isAttached())
- insert(qmlattachedsignals,*c,style, status);
- else
- insert(qmlsignals,*c,style, status);
- }
- else if ((*c)->isQmlSignalHandler() || (*c)->isJsSignalHandler()) {
- insert(qmlsignalhandlers,*c,style, status);
- }
- else if ((*c)->isQmlMethod() || (*c)->isJsMethod()) {
- const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
- if (mn->isAttached())
- insert(qmlattachedmethods,*c,style, status);
- else
- insert(qmlmethods,*c,style, status);
- }
- ++c;
- }
- if (qcn->qmlBaseNode() != 0) {
- qcn = static_cast<QmlTypeNode*>(qcn->qmlBaseNode());
- if (!qcn->isAbstract())
- qcn = 0;
- }
- else
- qcn = 0;
- }
- append(sections,qmlproperties);
- append(sections,qmlattachedproperties);
- append(sections,qmlsignals);
- append(sections,qmlsignalhandlers);
- append(sections,qmlattachedsignals);
- append(sections,qmlmethods);
- append(sections,qmlattachedmethods);
- }
- else {
- /*
- This is where the list of all members including inherited
- members is prepared.
- */
- ClassMap* classMap = 0;
- FastSection all(qmlTypeNode,QString(),QString(),"member","members");
- QmlTypeNode* current = qmlTypeNode;
- while (current != 0) {
- /*
- If the QML type is abstract, do not create
- a new entry in the list for it. Instead,
- add its members to the current entry.
-
- However, if the first class is abstract,
- there is no current entry. In that case,
- create a new entry in the list anyway.
- I'm not sure that is correct, but it at
- least can prevent a crash.
- */
- if (!current->isAbstract() || !classMap) {
- classMap = new ClassMap;
- classMap->first = current;
- all.classMapList_.append(classMap);
- }
- NodeList::ConstIterator c = current->childNodes().constBegin();
- while (c != current->childNodes().constEnd()) {
- if ((*c)->isQmlPropertyGroup() || (*c)->isJsPropertyGroup()) {
- const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*c);
- NodeList::ConstIterator p = qpgn->childNodes().constBegin();
- while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->isQmlProperty() || (*c)->isJsProperty()) {
- QString key = (*p)->name();
- key = sortName(*p, &key);
- all.memberMap.insert(key,*p);
- classMap->second.insert(key,*p);
- }
- ++p;
- }
- }
- else {
- QString key = (*c)->name();
- key = sortName(*c, &key);
- all.memberMap.insert(key,*c);
- classMap->second.insert(key,*c);
- }
- ++c;
- }
- current = current->qmlBaseNode();
- while (current) {
- if (current->isAbstract())
- break;
- if (current->isInternal())
- current = current->qmlBaseNode();
- else
- break;
- }
- }
- append(sections, all, true);
- }
- }
-
- return sections;
-}
-
-QT_END_NAMESPACE
diff --git a/src/tools/qdoc/cppcodemarker.h b/src/tools/qdoc/cppcodemarker.h
deleted file mode 100644
index aa759f2993..0000000000
--- a/src/tools/qdoc/cppcodemarker.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- cppcodemarker.h
-*/
-
-#ifndef CPPCODEMARKER_H
-#define CPPCODEMARKER_H
-
-#include "codemarker.h"
-
-QT_BEGIN_NAMESPACE
-
-class CppCodeMarker : public CodeMarker
-{
- Q_DECLARE_TR_FUNCTIONS(QDoc::CppCodeMarker)
-
-public:
- CppCodeMarker();
- ~CppCodeMarker();
-
- virtual bool recognizeCode(const QString& code) Q_DECL_OVERRIDE;
- virtual bool recognizeExtension(const QString& ext) Q_DECL_OVERRIDE;
- virtual bool recognizeLanguage(const QString& lang) Q_DECL_OVERRIDE;
- virtual Atom::AtomType atomType() const Q_DECL_OVERRIDE;
- virtual QString markedUpCode(const QString& code,
- const Node *relative,
- const Location &location) Q_DECL_OVERRIDE;
- virtual QString markedUpSynopsis(const Node *node,
- const Node *relative,
- SynopsisStyle style) Q_DECL_OVERRIDE;
- virtual QString markedUpQmlItem(const Node *node, bool summary) Q_DECL_OVERRIDE;
- virtual QString markedUpName(const Node *node) Q_DECL_OVERRIDE;
- virtual QString markedUpFullName(const Node *node, const Node *relative) Q_DECL_OVERRIDE;
- virtual QString markedUpEnumValue(const QString &enumValue, const Node *relative) Q_DECL_OVERRIDE;
- virtual QString markedUpIncludes(const QStringList& includes) Q_DECL_OVERRIDE;
- virtual QString functionBeginRegExp(const QString& funcName) Q_DECL_OVERRIDE;
- virtual QString functionEndRegExp(const QString& funcName) Q_DECL_OVERRIDE;
- virtual QList<Section> sections(const Aggregate *innerNode,
- SynopsisStyle style,
- Status status) Q_DECL_OVERRIDE;
- virtual QList<Section> qmlSections(QmlTypeNode* qmlTypeNode,
- SynopsisStyle style,
- Status status = Okay) Q_DECL_OVERRIDE;
-
-private:
- QString addMarkUp(const QString& protectedCode,
- const Node *relative,
- const Location &location);
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp
deleted file mode 100644
index f20b998cc4..0000000000
--- a/src/tools/qdoc/cppcodeparser.cpp
+++ /dev/null
@@ -1,2607 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- cppcodeparser.cpp
-*/
-
-#include <qfile.h>
-#include <stdio.h>
-#include <errno.h>
-#include "codechunk.h"
-#include "config.h"
-#include "cppcodeparser.h"
-#include "tokenizer.h"
-#include "qdocdatabase.h"
-#include <qdebug.h>
-#include "generator.h"
-
-QT_BEGIN_NAMESPACE
-
-/* qmake ignore Q_OBJECT */
-
-static bool inMacroCommand_ = false;
-static bool parsingHeaderFile_ = false;
-QStringList CppCodeParser::exampleFiles;
-QStringList CppCodeParser::exampleDirs;
-CppCodeParser* CppCodeParser::cppParser_ = 0;
-
-/*!
- The constructor initializes some regular expressions
- and calls reset().
- */
-CppCodeParser::CppCodeParser()
- : varComment("/\\*\\s*([a-zA-Z_0-9]+)\\s*\\*/"), sep("(?:<[^>]+>)?::")
-{
- reset();
- cppParser_ = this;
-}
-
-/*!
- The destructor is trivial.
- */
-CppCodeParser::~CppCodeParser()
-{
- // nothing.
-}
-
-/*!
- The constructor initializes a map of special node types
- for identifying important nodes. And it initializes
- some filters for identifying certain kinds of files.
- */
-void CppCodeParser::initializeParser(const Config &config)
-{
- CodeParser::initializeParser(config);
-
- /*
- All these can appear in a C++ namespace. Don't add
- anything that can't be in a C++ namespace.
- */
- nodeTypeMap.insert(COMMAND_NAMESPACE, Node::Namespace);
- nodeTypeMap.insert(COMMAND_CLASS, Node::Class);
- nodeTypeMap.insert(COMMAND_ENUM, Node::Enum);
- nodeTypeMap.insert(COMMAND_TYPEDEF, Node::Typedef);
- nodeTypeMap.insert(COMMAND_PROPERTY, Node::Property);
- nodeTypeMap.insert(COMMAND_VARIABLE, Node::Variable);
-
- exampleFiles = config.getCanonicalPathList(CONFIG_EXAMPLES);
- exampleDirs = config.getCanonicalPathList(CONFIG_EXAMPLEDIRS);
- QStringList exampleFilePatterns = config.getStringList(
- CONFIG_EXAMPLES + Config::dot + CONFIG_FILEEXTENSIONS);
-
- if (!exampleFilePatterns.isEmpty())
- exampleNameFilter = exampleFilePatterns.join(' ');
- else
- exampleNameFilter = "*.cpp *.h *.js *.xq *.svg *.xml *.dita *.ui";
-
- QStringList exampleImagePatterns = config.getStringList(
- CONFIG_EXAMPLES + Config::dot + CONFIG_IMAGEEXTENSIONS);
-
- if (!exampleImagePatterns.isEmpty())
- exampleImageFilter = exampleImagePatterns.join(' ');
- else
- exampleImageFilter = "*.png";
-}
-
-/*!
- Clear the map of common node types and call
- the same function in the base class.
- */
-void CppCodeParser::terminateParser()
-{
- nodeTypeMap.clear();
- CodeParser::terminateParser();
-}
-
-/*!
- Returns "Cpp".
- */
-QString CppCodeParser::language()
-{
- return "Cpp";
-}
-
-/*!
- Returns a list of extensions for header files.
- */
-QStringList CppCodeParser::headerFileNameFilter()
-{
- return QStringList() << "*.ch" << "*.h" << "*.h++" << "*.hh" << "*.hpp" << "*.hxx";
-}
-
-/*!
- Returns a list of extensions for source files, i.e. not
- header files.
- */
-QStringList CppCodeParser::sourceFileNameFilter()
-{
- return QStringList() << "*.c++" << "*.cc" << "*.cpp" << "*.cxx" << "*.mm";
-}
-
-/*!
- Parse the C++ header file identified by \a filePath and add
- the parsed contents to the database. The \a location is used
- for reporting errors.
- */
-void CppCodeParser::parseHeaderFile(const Location& location, const QString& filePath)
-{
- QFile in(filePath);
- currentFile_ = filePath;
- if (!in.open(QIODevice::ReadOnly)) {
- location.error(tr("Cannot open C++ header file '%1'").arg(filePath));
- currentFile_.clear();
- return;
- }
-
- reset();
- Location fileLocation(filePath);
- Tokenizer fileTokenizer(fileLocation, in);
- tokenizer = &fileTokenizer;
- readToken();
- parsingHeaderFile_ = true;
- matchDeclList(qdb_->primaryTreeRoot());
- parsingHeaderFile_ = false;
- if (!fileTokenizer.version().isEmpty())
- qdb_->setVersion(fileTokenizer.version());
- in.close();
-
- if (fileLocation.fileName() == "qiterator.h")
- parseQiteratorDotH(location, filePath);
- currentFile_.clear();
-}
-
-/*!
- Get ready to parse the C++ cpp file identified by \a filePath
- and add its parsed contents to the database. \a location is
- used for reporting errors.
-
- Call matchDocsAndStuff() to do all the parsing and tree building.
- */
-void CppCodeParser::parseSourceFile(const Location& location, const QString& filePath)
-{
- QFile in(filePath);
- currentFile_ = filePath;
- if (!in.open(QIODevice::ReadOnly)) {
- location.error(tr("Cannot open C++ source file '%1' (%2)").arg(filePath).arg(strerror(errno)));
- currentFile_.clear();
- return;
- }
-
- reset();
- Location fileLocation(filePath);
- Tokenizer fileTokenizer(fileLocation, in);
- tokenizer = &fileTokenizer;
- readToken();
-
- /*
- The set of open namespaces is cleared before parsing
- each source file. The word "source" here means cpp file.
- */
- qdb_->clearOpenNamespaces();
-
- matchDocsAndStuff();
- in.close();
- currentFile_.clear();
-}
-
-/*!
- This is called after all the C++ header files have been
- parsed. The most important thing it does is resolve C++
- class inheritance links in the tree. It also initializes
- a bunch of other collections.
- */
-void CppCodeParser::doneParsingHeaderFiles()
-{
- QMapIterator<QString, QString> i(sequentialIteratorClasses);
- while (i.hasNext()) {
- i.next();
- instantiateIteratorMacro(i.key(), i.value(), sequentialIteratorDefinition);
- }
- i = mutableSequentialIteratorClasses;
- while (i.hasNext()) {
- i.next();
- instantiateIteratorMacro(i.key(), i.value(), mutableSequentialIteratorDefinition);
- }
- i = associativeIteratorClasses;
- while (i.hasNext()) {
- i.next();
- instantiateIteratorMacro(i.key(), i.value(), associativeIteratorDefinition);
- }
- i = mutableAssociativeIteratorClasses;
- while (i.hasNext()) {
- i.next();
- instantiateIteratorMacro(i.key(), i.value(), mutableAssociativeIteratorDefinition);
- }
- sequentialIteratorDefinition.clear();
- mutableSequentialIteratorDefinition.clear();
- associativeIteratorDefinition.clear();
- mutableAssociativeIteratorDefinition.clear();
- sequentialIteratorClasses.clear();
- mutableSequentialIteratorClasses.clear();
- associativeIteratorClasses.clear();
- mutableAssociativeIteratorClasses.clear();
-}
-
-/*!
- This is called after all the source files (i.e., not the
- header files) have been parsed. Currently nothing to do.
- */
-void CppCodeParser::doneParsingSourceFiles()
-{
- // contents moved to QdocDatabase::resolveIssues()
-}
-
-static QSet<QString> topicCommands_;
-/*!
- Returns the set of strings reopresenting the topic commands.
- */
-const QSet<QString>& CppCodeParser::topicCommands()
-{
- if (topicCommands_.isEmpty()) {
- topicCommands_ << COMMAND_CLASS
- << COMMAND_DITAMAP
- << COMMAND_ENUM
- << COMMAND_EXAMPLE
- << COMMAND_EXTERNALPAGE
- << COMMAND_FILE
- << COMMAND_FN
- << COMMAND_GROUP
- << COMMAND_HEADERFILE
- << COMMAND_MACRO
- << COMMAND_MODULE
- << COMMAND_NAMESPACE
- << COMMAND_PAGE
- << COMMAND_PROPERTY
- << COMMAND_TYPEDEF
- << COMMAND_VARIABLE
- << COMMAND_QMLTYPE
- << COMMAND_QMLPROPERTY
- << COMMAND_QMLPROPERTYGROUP
- << COMMAND_QMLATTACHEDPROPERTY
- << COMMAND_QMLSIGNAL
- << COMMAND_QMLATTACHEDSIGNAL
- << COMMAND_QMLMETHOD
- << COMMAND_QMLATTACHEDMETHOD
- << COMMAND_QMLBASICTYPE
- << COMMAND_QMLMODULE
- << COMMAND_JSTYPE
- << COMMAND_JSPROPERTY
- << COMMAND_JSPROPERTYGROUP
- << COMMAND_JSATTACHEDPROPERTY
- << COMMAND_JSSIGNAL
- << COMMAND_JSATTACHEDSIGNAL
- << COMMAND_JSMETHOD
- << COMMAND_JSATTACHEDMETHOD
- << COMMAND_JSBASICTYPE
- << COMMAND_JSMODULE;
- }
- return topicCommands_;
-}
-
-/*!
- Process the topic \a command found in the \a doc with argument \a arg.
- */
-Node* CppCodeParser::processTopicCommand(const Doc& doc,
- const QString& command,
- const ArgLocPair& arg)
-{
- ExtraFuncData extra;
- if (command == COMMAND_FN) {
- QStringList parentPath;
- FunctionNode *func = 0;
- FunctionNode *clone = 0;
-
- if (!makeFunctionNode(arg.first, &parentPath, &clone, extra) &&
- !makeFunctionNode("void " + arg.first, &parentPath, &clone, extra)) {
- doc.startLocation().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_FN));
- }
- else {
- func = qdb_->findFunctionNode(parentPath, clone);
- if (func == 0) {
- if (parentPath.isEmpty() && !lastPath_.isEmpty())
- func = qdb_->findFunctionNode(lastPath_, clone);
- }
-
- /*
- If the node was not found, then search for it in the
- open C++ namespaces. We don't expect this search to
- be necessary often. Nor do we expect it to succeed
- very often.
- */
- if (func == 0)
- func = qdb_->findNodeInOpenNamespace(parentPath, clone);
-
- if (func == 0) {
- doc.location().warning(tr("Cannot find '%1' in '\\%2' %3")
- .arg(clone->name() + "(...)")
- .arg(COMMAND_FN)
- .arg(arg.first),
- tr("I cannot find any function of that name with the "
- "specified signature. Make sure that the signature "
- "is identical to the declaration, including 'const' "
- "qualifiers."));
- }
- else
- lastPath_ = parentPath;
- if (func) {
- func->borrowParameterNames(clone);
- func->setParentPath(clone->parentPath());
- }
- delete clone;
- }
- return func;
- }
- else if (command == COMMAND_MACRO) {
- QStringList parentPath;
- FunctionNode *func = 0;
-
- extra.root = qdb_->primaryTreeRoot();
- extra.isMacro = true;
- if (makeFunctionNode(arg.first, &parentPath, &func, extra)) {
- if (!parentPath.isEmpty()) {
- doc.startLocation().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_MACRO));
- delete func;
- func = 0;
- }
- else {
- func->setMetaness(FunctionNode::MacroWithParams);
- QVector<Parameter> params = func->parameters();
- for (int i = 0; i < params.size(); ++i) {
- Parameter &param = params[i];
- if (param.name().isEmpty() && !param.dataType().isEmpty()
- && param.dataType() != "...")
- param = Parameter("", "", param.dataType());
- }
- func->setParameters(params);
- }
- return func;
- }
- else if (QRegExp("[A-Za-z_][A-Za-z0-9_]+").exactMatch(arg.first)) {
- func = new FunctionNode(qdb_->primaryTreeRoot(), arg.first);
- func->setAccess(Node::Public);
- func->setLocation(doc.startLocation());
- func->setMetaness(FunctionNode::MacroWithoutParams);
- }
- else {
- doc.location().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_MACRO));
-
- }
- return func;
- }
- else if (nodeTypeMap.contains(command)) {
- /*
- We should only get in here if the command refers to
- something that can appear in a C++ namespace,
- i.e. a class, another namespace, an enum, a typedef,
- a property or a variable. I think these are handled
- this way to allow the writer to refer to the entity
- without including the namespace qualifier.
- */
- Node::NodeType type = nodeTypeMap[command];
- QStringList paths = arg.first.split(QLatin1Char(' '));
- QStringList path = paths[0].split("::");
- Node *node = 0;
-
- node = qdb_->findNodeInOpenNamespace(path, type);
- if (node == 0)
- node = qdb_->findNodeByNameAndType(path, type);
- if (node == 0) {
- doc.location().warning(tr("Cannot find '%1' specified with '\\%2' in any header file")
- .arg(arg.first).arg(command));
- lastPath_ = path;
-
- }
- else if (node->isAggregate()) {
- if (type == Node::Namespace) {
- NamespaceNode* ns = static_cast<NamespaceNode*>(node);
- ns->markSeen();
- }
- /*
- This treats a class as a namespace.
- */
- if ((type == Node::Class) || (type == Node::Namespace)) {
- if (path.size() > 1) {
- path.pop_back();
- QString ns = path.join("::");
- qdb_->insertOpenNamespace(ns);
- }
- }
- }
- return node;
- }
- else if (command == COMMAND_EXAMPLE) {
- if (Config::generateExamples) {
- ExampleNode* en = new ExampleNode(qdb_->primaryTreeRoot(), arg.first);
- en->setLocation(doc.startLocation());
- createExampleFileNodes(en);
- return en;
- }
- }
- else if (command == COMMAND_EXTERNALPAGE) {
- DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
- arg.first,
- Node::ExternalPage,
- Node::ArticlePage);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if (command == COMMAND_FILE) {
- DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
- arg.first,
- Node::File,
- Node::NoPageType);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if (command == COMMAND_HEADERFILE) {
- DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
- arg.first,
- Node::HeaderFile,
- Node::ApiPage);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if (command == COMMAND_GROUP) {
- CollectionNode* cn = qdb_->addGroup(arg.first);
- cn->setLocation(doc.startLocation());
- cn->markSeen();
- return cn;
- }
- else if (command == COMMAND_MODULE) {
- CollectionNode* cn = qdb_->addModule(arg.first);
- cn->setLocation(doc.startLocation());
- cn->markSeen();
- return cn;
- }
- else if (command == COMMAND_QMLMODULE) {
- QStringList blankSplit = arg.first.split(QLatin1Char(' '));
- CollectionNode* cn = qdb_->addQmlModule(blankSplit[0]);
- cn->setLogicalModuleInfo(blankSplit);
- cn->setLocation(doc.startLocation());
- cn->markSeen();
- return cn;
- }
- else if (command == COMMAND_JSMODULE) {
- QStringList blankSplit = arg.first.split(QLatin1Char(' '));
- CollectionNode* cn = qdb_->addJsModule(blankSplit[0]);
- cn->setLogicalModuleInfo(blankSplit);
- cn->setLocation(doc.startLocation());
- cn->markSeen();
- return cn;
- }
- else if (command == COMMAND_PAGE) {
- Node::PageType ptype = Node::ArticlePage;
- QStringList args = arg.first.split(QLatin1Char(' '));
- if (args.size() > 1) {
- QString t = args[1].toLower();
- if (t == "howto")
- ptype = Node::HowToPage;
- else if (t == "api")
- ptype = Node::ApiPage;
- else if (t == "example")
- ptype = Node::ExamplePage;
- else if (t == "overview")
- ptype = Node::OverviewPage;
- else if (t == "tutorial")
- ptype = Node::TutorialPage;
- else if (t == "faq")
- ptype = Node::FAQPage;
- else if (t == "ditamap")
- ptype = Node::DitaMapPage;
- }
- DocumentNode* dn = 0;
- if (ptype == Node::DitaMapPage)
- dn = new DitaMapNode(qdb_->primaryTreeRoot(), args[0]);
- else
- dn = new DocumentNode(qdb_->primaryTreeRoot(), args[0], Node::Page, ptype);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if (command == COMMAND_DITAMAP) {
- DocumentNode* dn = new DitaMapNode(qdb_->primaryTreeRoot(), arg.first);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if ((command == COMMAND_QMLTYPE) || (command == COMMAND_JSTYPE)) {
- QmlTypeNode* qcn = new QmlTypeNode(qdb_->primaryTreeRoot(), arg.first);
- if (command == COMMAND_JSTYPE)
- qcn->setGenus(Node::JS);
- qcn->setLocation(doc.startLocation());
- return qcn;
- }
- else if ((command == COMMAND_QMLBASICTYPE) || (command == COMMAND_JSBASICTYPE)) {
- QmlBasicTypeNode* n = new QmlBasicTypeNode(qdb_->primaryTreeRoot(), arg.first);
- if (command == COMMAND_JSBASICTYPE)
- n->setGenus(Node::JS);
- n->setLocation(doc.startLocation());
- return n;
- }
- else if ((command == COMMAND_QMLSIGNAL) ||
- (command == COMMAND_QMLMETHOD) ||
- (command == COMMAND_QMLATTACHEDSIGNAL) ||
- (command == COMMAND_QMLATTACHEDMETHOD) ||
- (command == COMMAND_JSSIGNAL) ||
- (command == COMMAND_JSMETHOD) ||
- (command == COMMAND_JSATTACHEDSIGNAL) ||
- (command == COMMAND_JSATTACHEDMETHOD)) {
- QString module;
- QString qmlTypeName;
- QString type;
- if (splitQmlMethodArg(arg.first, type, module, qmlTypeName)) {
- QmlTypeNode* qmlType = qdb_->findQmlType(module, qmlTypeName);
- if (qmlType) {
- bool attached = false;
- Node::NodeType nodeType = Node::QmlMethod;
- if ((command == COMMAND_QMLSIGNAL) ||
- (command == COMMAND_JSSIGNAL))
- nodeType = Node::QmlSignal;
- else if ((command == COMMAND_QMLATTACHEDSIGNAL) ||
- (command == COMMAND_JSATTACHEDSIGNAL)) {
- nodeType = Node::QmlSignal;
- attached = true;
- }
- else if ((command == COMMAND_QMLMETHOD) ||
- (command == COMMAND_JSMETHOD)) {
- // do nothing
- }
- else if ((command == COMMAND_QMLATTACHEDMETHOD) ||
- (command == COMMAND_JSATTACHEDMETHOD))
- attached = true;
- else
- return 0; // never get here.
- FunctionNode* fn = makeFunctionNode(doc,
- arg.first,
- qmlType,
- nodeType,
- attached,
- command);
- if (fn) {
- fn->setLocation(doc.startLocation());
- if ((command == COMMAND_JSSIGNAL) ||
- (command == COMMAND_JSMETHOD) ||
- (command == COMMAND_JSATTACHEDSIGNAL) ||
- (command == COMMAND_JSATTACHEDMETHOD))
- fn->setGenus(Node::JS);
- }
- return fn;
- }
- }
- }
- return 0;
-}
-
-/*!
- A QML property group argument has the form...
-
- <QML-module>::<QML-type>::<name>
-
- This function splits the argument into those parts.
- A <QML-module> is the QML equivalent of a C++ namespace.
- So this function splits \a arg on "::" and stores the
- parts in \a module, \a qmlTypeName, and \a name, and returns
- true. If any part is not found, a qdoc warning is emitted
- and false is returned.
- */
-bool CppCodeParser::splitQmlPropertyGroupArg(const QString& arg,
- QString& module,
- QString& qmlTypeName,
- QString& name)
-{
- QStringList colonSplit = arg.split("::");
- if (colonSplit.size() == 3) {
- module = colonSplit[0];
- qmlTypeName = colonSplit[1];
- name = colonSplit[2];
- return true;
- }
- QString msg = "Unrecognizable QML module/component qualifier for " + arg;
- location().warning(tr(msg.toLatin1().data()));
- return false;
-}
-
-/*!
- A QML property argument has the form...
-
- <type> <QML-type>::<name>
- <type> <QML-module>::<QML-type>::<name>
-
- This function splits the argument into one of those
- two forms. The three part form is the old form, which
- was used before the creation of Qt Quick 2 and Qt
- Components. A <QML-module> is the QML equivalent of a
- C++ namespace. So this function splits \a arg on "::"
- and stores the parts in \a type, \a module, \a qmlTypeName,
- and \a name, and returns \c true. If any part other than
- \a module is not found, a qdoc warning is emitted and
- false is returned.
-
- \note The two QML types \e{Component} and \e{QtObject}
- never have a module qualifier.
- */
-bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
- QString& type,
- QString& module,
- QString& qmlTypeName,
- QString& name)
-{
- QStringList blankSplit = arg.split(QLatin1Char(' '));
- if (blankSplit.size() > 1) {
- type = blankSplit[0];
- QStringList colonSplit(blankSplit[1].split("::"));
- if (colonSplit.size() == 3) {
- module = colonSplit[0];
- qmlTypeName = colonSplit[1];
- name = colonSplit[2];
- return true;
- }
- if (colonSplit.size() == 2) {
- module.clear();
- qmlTypeName = colonSplit[0];
- name = colonSplit[1];
- return true;
- }
- QString msg = "Unrecognizable QML module/component qualifier for " + arg;
- location().warning(tr(msg.toLatin1().data()));
- }
- else {
- QString msg = "Missing property type for " + arg;
- location().warning(tr(msg.toLatin1().data()));
- }
- return false;
-}
-
-/*!
- A QML signal or method argument has the form...
-
- <type> <QML-type>::<name>(<param>, <param>, ...)
- <type> <QML-module>::<QML-type>::<name>(<param>, <param>, ...)
-
- This function splits the \a{arg}ument into one of those
- two forms, sets \a type, \a module, and \a qmlTypeName,
- and returns true. If the argument doesn't match either
- form, an error message is emitted and false is returned.
-
- \note The two QML types \e{Component} and \e{QtObject} never
- have a module qualifier.
- */
-bool CppCodeParser::splitQmlMethodArg(const QString& arg,
- QString& type,
- QString& module,
- QString& qmlTypeName)
-{
- QString name;
- int leftParen = arg.indexOf(QChar('('));
- if (leftParen > 0)
- name = arg.left(leftParen);
- else
- name = arg;
- int firstBlank = name.indexOf(QChar(' '));
- if (firstBlank > 0) {
- type = name.left(firstBlank);
- name = name.right(name.length() - firstBlank - 1);
- }
- else
- type.clear();
-
- QStringList colonSplit(name.split("::"));
- if (colonSplit.size() > 1) {
- if (colonSplit.size() > 2) {
- module = colonSplit[0];
- qmlTypeName = colonSplit[1];
- }
- else {
- module.clear();
- qmlTypeName = colonSplit[0];
- }
- return true;
- }
- QString msg = "Unrecognizable QML module/component qualifier for " + arg;
- location().warning(tr(msg.toLatin1().data()));
- return false;
-}
-
-/*!
- Process the topic \a command group found in the \a doc with arguments \a args.
-
- Currently, this function is called only for \e{qmlproperty}
- and \e{qmlattachedproperty}.
- */
-void CppCodeParser::processQmlProperties(const Doc& doc,
- NodeList& nodes,
- DocList& docs,
- bool jsProps)
-{
- QString arg;
- QString type;
- QString topic;
- QString module;
- QString qmlTypeName;
- QString property;
- QmlPropertyNode* qpn = 0;
- QmlTypeNode* qmlType = 0;
- QmlPropertyGroupNode* qpgn = 0;
-
- Topic qmlPropertyGroupTopic;
- const TopicList& topics = doc.topicsUsed();
- for (int i=0; i<topics.size(); ++i) {
- if ((topics.at(i).topic == COMMAND_QMLPROPERTYGROUP) ||
- (topics.at(i).topic == COMMAND_JSPROPERTYGROUP)) {
- qmlPropertyGroupTopic = topics.at(i);
- break;
- }
- }
- if (qmlPropertyGroupTopic.isEmpty() && topics.size() > 1) {
- qmlPropertyGroupTopic = topics.at(0);
- if (jsProps)
- qmlPropertyGroupTopic.topic = COMMAND_JSPROPERTYGROUP;
- else
- qmlPropertyGroupTopic.topic = COMMAND_QMLPROPERTYGROUP;
- arg = qmlPropertyGroupTopic.args;
- if (splitQmlPropertyArg(arg, type, module, qmlTypeName, property)) {
- int i = property.indexOf('.');
- if (i != -1) {
- property = property.left(i);
- qmlPropertyGroupTopic.args = module + "::" + qmlTypeName + "::" + property;
- doc.location().warning(tr("No QML property group command found; using \\%1 %2")
- .arg(COMMAND_QMLPROPERTYGROUP).arg(qmlPropertyGroupTopic.args));
- }
- else {
- /*
- Assumption: No '.' in the property name
- means there is no property group.
- */
- qmlPropertyGroupTopic.clear();
- }
- }
- }
-
- if (!qmlPropertyGroupTopic.isEmpty()) {
- arg = qmlPropertyGroupTopic.args;
- if (splitQmlPropertyGroupArg(arg, module, qmlTypeName, property)) {
- qmlType = qdb_->findQmlType(module, qmlTypeName);
- if (qmlType) {
- qpgn = new QmlPropertyGroupNode(qmlType, property);
- qpgn->setLocation(doc.startLocation());
- if (jsProps)
- qpgn->setGenus(Node::JS);
- nodes.append(qpgn);
- docs.append(doc);
- }
- }
- }
- for (int i=0; i<topics.size(); ++i) {
- if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP) {
- continue;
- }
- topic = topics.at(i).topic;
- arg = topics.at(i).args;
- if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY) ||
- (topic == COMMAND_JSPROPERTY) || (topic == COMMAND_JSATTACHEDPROPERTY)) {
- bool attached = ((topic == COMMAND_QMLATTACHEDPROPERTY) ||
- (topic == COMMAND_JSATTACHEDPROPERTY));
- if (splitQmlPropertyArg(arg, type, module, qmlTypeName, property)) {
- qmlType = qdb_->findQmlType(module, qmlTypeName);
- if (qmlType) {
- if (qmlType->hasQmlProperty(property, attached) != 0) {
- QString msg = tr("QML property documented multiple times: '%1'").arg(arg);
- doc.startLocation().warning(msg);
- }
- else if (qpgn) {
- qpn = new QmlPropertyNode(qpgn, property, type, attached);
- qpn->setLocation(doc.startLocation());
- if (jsProps)
- qpn->setGenus(Node::JS);
- }
- else {
- qpn = new QmlPropertyNode(qmlType, property, type, attached);
- qpn->setLocation(doc.startLocation());
- if (jsProps)
- qpn->setGenus(Node::JS);
- nodes.append(qpn);
- docs.append(doc);
- }
- }
- }
- }
- }
-}
-
-static QSet<QString> otherMetaCommands_;
-/*!
- Returns the set of strings representing the common metacommands
- plus some other metacommands.
- */
-const QSet<QString>& CppCodeParser::otherMetaCommands()
-{
- if (otherMetaCommands_.isEmpty()) {
- otherMetaCommands_ = commonMetaCommands();
- otherMetaCommands_ << COMMAND_INHEADERFILE
- << COMMAND_OVERLOAD
- << COMMAND_REIMP
- << COMMAND_RELATES
- << COMMAND_CONTENTSPAGE
- << COMMAND_NEXTPAGE
- << COMMAND_PREVIOUSPAGE
- << COMMAND_INDEXPAGE
- << COMMAND_STARTPAGE
- << COMMAND_QMLINHERITS
- << COMMAND_QMLINSTANTIATES
- << COMMAND_QMLDEFAULT
- << COMMAND_QMLREADONLY
- << COMMAND_QMLABSTRACT
- << COMMAND_ABSTRACT;
- }
- return otherMetaCommands_;
-}
-
-/*!
- Process the metacommand \a command in the context of the
- \a node associated with the topic command and the \a doc.
- \a arg is the argument to the metacommand.
- */
-void CppCodeParser::processOtherMetaCommand(const Doc& doc,
- const QString& command,
- const ArgLocPair& argLocPair,
- Node *node)
-{
- QString arg = argLocPair.first;
- if (command == COMMAND_INHEADERFILE) {
- if (node != 0 && node->isAggregate()) {
- ((Aggregate *) node)->addInclude(arg);
- }
- else {
- doc.location().warning(tr("Ignored '\\%1'").arg(COMMAND_INHEADERFILE));
- }
- }
- else if (command == COMMAND_OVERLOAD) {
- if (node && node->isFunction())
- ((FunctionNode *) node)->setOverloadFlag(true);
- else
- doc.location().warning(tr("Ignored '\\%1'").arg(COMMAND_OVERLOAD));
- }
- else if (command == COMMAND_REIMP) {
- if (node != 0 && node->parent() && !node->parent()->isInternal()) {
- if (node->type() == Node::Function) {
- FunctionNode *func = (FunctionNode *) node;
- const FunctionNode *from = func->reimplementedFrom();
- if (from == 0) {
- doc.location().warning(tr("Cannot find base function for '\\%1' in %2()")
- .arg(COMMAND_REIMP).arg(node->name()),
- tr("The function either doesn't exist in any "
- "base class with the same signature or it "
- "exists but isn't virtual."));
- }
- /*
- Ideally, we would enable this check to warn whenever
- \reimp is used incorrectly, and only make the node
- internal if the function is a reimplementation of
- another function in a base class.
- */
- else if (from->access() == Node::Private
- || from->parent()->access() == Node::Private) {
- doc.location().warning(tr("'\\%1' in %2() should be '\\internal' "
- "because its base function is private "
- "or internal").arg(COMMAND_REIMP).arg(node->name()));
- }
- func->setReimplemented(true);
- }
- else {
- doc.location().warning(tr("Ignored '\\%1' in %2").arg(COMMAND_REIMP).arg(node->name()));
- }
- }
- }
- else if (command == COMMAND_RELATES) {
- QStringList path = arg.split("::");
- Node* n = qdb_->findRelatesNode(path);
- if (!n) {
- // Store just a string to write to the index file
- if (Generator::preparing())
- node->setRelates(arg);
- else
- doc.location().warning(tr("Cannot find '%1' in '\\%2'").arg(arg).arg(COMMAND_RELATES));
-
- }
- else if (node->parent() != n)
- node->setRelates(static_cast<Aggregate*>(n));
- else
- doc.location().warning(tr("Invalid use of '\\%1' (already a member of '%2')")
- .arg(COMMAND_RELATES, arg));
- }
- else if (command == COMMAND_CONTENTSPAGE) {
- setLink(node, Node::ContentsLink, arg);
- }
- else if (command == COMMAND_NEXTPAGE) {
- setLink(node, Node::NextLink, arg);
- }
- else if (command == COMMAND_PREVIOUSPAGE) {
- setLink(node, Node::PreviousLink, arg);
- }
- else if (command == COMMAND_INDEXPAGE) {
- setLink(node, Node::IndexLink, arg);
- }
- else if (command == COMMAND_STARTPAGE) {
- setLink(node, Node::StartLink, arg);
- }
- else if (command == COMMAND_QMLINHERITS) {
- if (node->name() == arg)
- doc.location().warning(tr("%1 tries to inherit itself").arg(arg));
- else if (node->isQmlType() || node->isJsType()) {
- QmlTypeNode* qmlType = static_cast<QmlTypeNode*>(node);
- qmlType->setQmlBaseName(arg);
- QmlTypeNode::addInheritedBy(arg,node);
- }
- }
- else if (command == COMMAND_QMLINSTANTIATES) {
- if (node->isQmlType() || node->isJsType()) {
- ClassNode* classNode = qdb_->findClassNode(arg.split("::"));
- if (classNode)
- node->setClassNode(classNode);
- else
- doc.location().warning(tr("C++ class %1 not found: \\instantiates %1").arg(arg));
- }
- else
- doc.location().warning(tr("\\instantiates is only allowed in \\qmltype"));
- }
- else if (command == COMMAND_QMLDEFAULT) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- qpn->setDefault();
- }
- else if (node->type() == Node::QmlPropertyGroup) {
- QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
- NodeList::ConstIterator p = qpgn->childNodes().constBegin();
- while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(*p);
- qpn->setDefault();
- }
- ++p;
- }
- }
- }
- else if (command == COMMAND_QMLREADONLY) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- qpn->setReadOnly(1);
- }
- else if (node->type() == Node::QmlPropertyGroup) {
- QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
- NodeList::ConstIterator p = qpgn->childNodes().constBegin();
- while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(*p);
- qpn->setReadOnly(1);
- }
- ++p;
- }
- }
- }
- else if ((command == COMMAND_QMLABSTRACT) || (command == COMMAND_ABSTRACT)) {
- if (node->isQmlType() || node->isJsType())
- node->setAbstract(true);
- }
- else {
- processCommonMetaCommand(doc.location(),command,argLocPair,node);
- }
-}
-
-/*!
- The topic command has been processed resulting in the \a doc
- and \a node passed in here. Process the other meta commands,
- which are found in \a doc, in the context of the topic \a node.
- */
-void CppCodeParser::processOtherMetaCommands(const Doc& doc, Node *node)
-{
- const QSet<QString> metaCommands = doc.metaCommandsUsed();
- QSet<QString>::ConstIterator cmd = metaCommands.constBegin();
- while (cmd != metaCommands.constEnd()) {
- ArgList args = doc.metaCommandArgs(*cmd);
- ArgList::ConstIterator arg = args.constBegin();
- while (arg != args.constEnd()) {
- processOtherMetaCommand(doc, *cmd, *arg, node);
- ++arg;
- }
- ++cmd;
- }
-}
-
-/*!
- Resets the C++ code parser to its default initialized state.
- */
-void CppCodeParser::reset()
-{
- tokenizer = 0;
- tok = 0;
- access = Node::Public;
- metaness_ = FunctionNode::Plain;
- lastPath_.clear();
- physicalModuleName.clear();
-}
-
-/*!
- Get the next token from the file being parsed and store it
- in the token variable.
- */
-void CppCodeParser::readToken()
-{
- tok = tokenizer->getToken();
-}
-
-/*!
- Return the current location in the file being parsed,
- i.e. the file name, line number, and column number.
- */
-const Location& CppCodeParser::location()
-{
- return tokenizer->location();
-}
-
-/*!
- Return the previous string read from the file being parsed.
- */
-QString CppCodeParser::previousLexeme()
-{
- return tokenizer->previousLexeme();
-}
-
-/*!
- Return the current string string from the file being parsed.
- */
-QString CppCodeParser::lexeme()
-{
- return tokenizer->lexeme();
-}
-
-bool CppCodeParser::match(int target)
-{
- if (tok == target) {
- readToken();
- return true;
- }
- return false;
-}
-
-/*!
- Skip to \a target. If \a target is found before the end
- of input, return true. Otherwise return false.
- */
-bool CppCodeParser::skipTo(int target)
-{
- while ((tok != Tok_Eoi) && (tok != target))
- readToken();
- return tok == target;
-}
-
-/*!
- If the current token is one of the keyword thingees that
- are used in Qt, skip over it to the next token and return
- true. Otherwise just return false without reading the
- next token.
- */
-bool CppCodeParser::matchCompat()
-{
- switch (tok) {
- case Tok_QT_COMPAT:
- case Tok_QT_COMPAT_CONSTRUCTOR:
- case Tok_QT_DEPRECATED:
- case Tok_QT_MOC_COMPAT:
- case Tok_QT3_SUPPORT:
- case Tok_QT3_SUPPORT_CONSTRUCTOR:
- case Tok_QT3_MOC_SUPPORT:
- readToken();
- return true;
- default:
- return false;
- }
-}
-
-bool CppCodeParser::matchModuleQualifier(QString& name)
-{
- bool matches = (lexeme() == QString('.'));
- if (matches) {
- do {
- name += lexeme();
- readToken();
- } while ((tok == Tok_Ident) || (lexeme() == QString('.')));
- }
- return matches;
-}
-
-bool CppCodeParser::matchTemplateAngles(CodeChunk *dataType)
-{
- bool matches = (tok == Tok_LeftAngle);
- if (matches) {
- int leftAngleDepth = 0;
- int parenAndBraceDepth = 0;
- do {
- if (tok == Tok_LeftAngle) {
- leftAngleDepth++;
- }
- else if (tok == Tok_RightAngle) {
- leftAngleDepth--;
- }
- else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
- ++parenAndBraceDepth;
- }
- else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
- if (--parenAndBraceDepth < 0)
- return false;
- }
- if (dataType != 0)
- dataType->append(lexeme());
- readToken();
- } while (leftAngleDepth > 0 && tok != Tok_Eoi);
- }
- return matches;
-}
-
-/*
- This function is no longer used.
- */
-bool CppCodeParser::matchTemplateHeader()
-{
- readToken();
- return matchTemplateAngles();
-}
-
-bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var)
-{
- /*
- This code is really hard to follow... sorry. The loop is there to match
- Alpha::Beta::Gamma::...::Omega.
- */
- for (;;) {
- bool virgin = true;
-
- if (tok != Tok_Ident) {
- /*
- There is special processing for 'Foo::operator int()'
- and such elsewhere. This is the only case where we
- return something with a trailing gulbrandsen ('Foo::').
- */
- if (tok == Tok_operator)
- return true;
-
- /*
- People may write 'const unsigned short' or
- 'short unsigned const' or any other permutation.
- */
- while (match(Tok_const) || match(Tok_volatile))
- dataType->append(previousLexeme());
- while (match(Tok_signed) || match(Tok_unsigned) ||
- match(Tok_short) || match(Tok_long) || match(Tok_int64)) {
- dataType->append(previousLexeme());
- virgin = false;
- }
- while (match(Tok_const) || match(Tok_volatile))
- dataType->append(previousLexeme());
-
- if (match(Tok_Tilde))
- dataType->append(previousLexeme());
- }
-
- if (virgin) {
- if (match(Tok_Ident)) {
- /*
- This is a hack until we replace this "parser"
- with the real one used in Qt Creator.
- */
- if (!inMacroCommand_ && lexeme() == "(" &&
- ((previousLexeme() == "QT_PREPEND_NAMESPACE") || (previousLexeme() == "NS"))) {
- readToken();
- readToken();
- dataType->append(previousLexeme());
- readToken();
- }
- else
- dataType->append(previousLexeme());
- }
- else if (match(Tok_void) || match(Tok_int) || match(Tok_char) ||
- match(Tok_double) || match(Tok_Ellipsis)) {
- dataType->append(previousLexeme());
- }
- else {
- return false;
- }
- }
- else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
- dataType->append(previousLexeme());
- }
-
- matchTemplateAngles(dataType);
-
- while (match(Tok_const) || match(Tok_volatile))
- dataType->append(previousLexeme());
-
- if (match(Tok_Gulbrandsen))
- dataType->append(previousLexeme());
- else
- break;
- }
-
- while (match(Tok_Ampersand) || match(Tok_Aster) || match(Tok_const) ||
- match(Tok_Caret))
- dataType->append(previousLexeme());
-
- if (match(Tok_LeftParenAster)) {
- /*
- A function pointer. This would be rather hard to handle without a
- tokenizer hack, because a type can be followed with a left parenthesis
- in some cases (e.g., 'operator int()'). The tokenizer recognizes '(*'
- as a single token.
- */
- dataType->append(previousLexeme());
- dataType->appendHotspot();
- if (var != 0 && match(Tok_Ident))
- *var = previousLexeme();
- if (!match(Tok_RightParen) || tok != Tok_LeftParen) {
- return false;
- }
- dataType->append(previousLexeme());
-
- int parenDepth0 = tokenizer->parenDepth();
- while (tokenizer->parenDepth() >= parenDepth0 && tok != Tok_Eoi) {
- dataType->append(lexeme());
- readToken();
- }
- if (match(Tok_RightParen))
- dataType->append(previousLexeme());
- }
- else {
- /*
- The common case: Look for an optional identifier, then for
- some array brackets.
- */
- dataType->appendHotspot();
-
- if (var != 0) {
- if (match(Tok_Ident)) {
- *var = previousLexeme();
- }
- else if (match(Tok_Comment)) {
- /*
- A neat hack: Commented-out parameter names are
- recognized by qdoc. It's impossible to illustrate
- here inside a C-style comment, because it requires
- an asterslash. It's also impossible to illustrate
- inside a C++-style comment, because the explanation
- does not fit on one line.
- */
- if (varComment.exactMatch(previousLexeme()))
- *var = varComment.cap(1);
- }
- }
-
- if (tok == Tok_LeftBracket) {
- int bracketDepth0 = tokenizer->bracketDepth();
- while ((tokenizer->bracketDepth() >= bracketDepth0 &&
- tok != Tok_Eoi) ||
- tok == Tok_RightBracket) {
- dataType->append(lexeme());
- readToken();
- }
- }
- }
- return true;
-}
-
-/*!
- Parse the next function parameter, if there is one, and
- append it to parameter vector \a pvect. Return true if
- a parameter is parsed and appended to \a pvect.
- Otherwise return false.
- */
-bool CppCodeParser::matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal)
-{
- if (match(Tok_QPrivateSignal)) {
- isQPrivateSignal = true;
- return true;
- }
-
- Parameter p;
- CodeChunk chunk;
- if (!matchDataType(&chunk, &p.name_)) {
- return false;
- }
- p.dataType_ = chunk.toString();
- chunk.clear();
- match(Tok_Comment);
- if (match(Tok_Equal)) {
- int pdepth = tokenizer->parenDepth();
- while (tokenizer->parenDepth() >= pdepth &&
- (tok != Tok_Comma || (tokenizer->parenDepth() > pdepth)) &&
- tok != Tok_Eoi) {
- chunk.append(lexeme());
- readToken();
- }
- }
- p.defaultValue_ = chunk.toString();
- pvect.append(p);
- return true;
-}
-
-/*!
- If the current token is any of several function modifiers,
- return that token value after reading the next token. If it
- is not one of the function modieifer tokens, return -1 but
- don\t read the next token.
- */
-int CppCodeParser::matchFunctionModifier()
-{
- switch (tok) {
- case Tok_friend:
- case Tok_inline:
- case Tok_explicit:
- case Tok_static:
- case Tok_QT_DEPRECATED:
- readToken();
- return tok;
- case Tok_QT_COMPAT:
- case Tok_QT_COMPAT_CONSTRUCTOR:
- case Tok_QT_MOC_COMPAT:
- case Tok_QT3_SUPPORT:
- case Tok_QT3_SUPPORT_CONSTRUCTOR:
- case Tok_QT3_MOC_SUPPORT:
- readToken();
- return Tok_QT_COMPAT;
- default:
- break;
- }
- return -1;
-}
-
-bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
- QStringList *parentPathPtr,
- FunctionNode **funcPtr,
- const QString &templateStuff,
- ExtraFuncData& extra)
-{
- CodeChunk returnType;
- QStringList parentPath;
- QString name;
-
- bool matched_QT_DEPRECATED = false;
- bool matched_friend = false;
- bool matched_static = false;
- bool matched_inline = false;
- bool matched_explicit = false;
- bool matched_compat = false;
-
- int token = tok;
- while (token != -1) {
- switch (token) {
- case Tok_friend:
- matched_friend = true;
- break;
- case Tok_inline:
- matched_inline = true;
- break;
- case Tok_explicit:
- matched_explicit = true;
- break;
- case Tok_static:
- matched_static = true;
- break;
- case Tok_QT_DEPRECATED:
- // no break here.
- matched_QT_DEPRECATED = true;
- case Tok_QT_COMPAT:
- matched_compat = true;
- break;
- }
- token = matchFunctionModifier();
- }
-
- FunctionNode::Virtualness virtuality = FunctionNode::NonVirtual;
- if (match(Tok_virtual)) {
- virtuality = FunctionNode::NormalVirtual;
- if (!matched_compat)
- matched_compat = matchCompat();
- }
-
- if (!matchDataType(&returnType)) {
- if (tokenizer->parsingFnOrMacro()
- && (match(Tok_Q_DECLARE_FLAGS) ||
- match(Tok_Q_PROPERTY) ||
- match(Tok_Q_PRIVATE_PROPERTY)))
- returnType = CodeChunk(previousLexeme());
- else {
- return false;
- }
- }
-
- if (returnType.toString() == "QBool")
- returnType = CodeChunk("bool");
-
- if (!matched_compat)
- matched_compat = matchCompat();
-
- if (tok == Tok_operator &&
- (returnType.toString().isEmpty() ||
- returnType.toString().endsWith("::"))) {
- // 'QString::operator const char *()'
- parentPath = returnType.toString().split(sep);
- parentPath.removeAll(QString());
- returnType = CodeChunk();
- readToken();
-
- CodeChunk restOfName;
- if (tok != Tok_Tilde && matchDataType(&restOfName)) {
- name = "operator " + restOfName.toString();
- }
- else {
- name = previousLexeme() + lexeme();
- readToken();
- while (tok != Tok_LeftParen && tok != Tok_Eoi) {
- name += lexeme();
- readToken();
- }
- }
- if (tok != Tok_LeftParen) {
- return false;
- }
- }
- else if (tok == Tok_LeftParen) {
- // constructor or destructor
- parentPath = returnType.toString().split(sep);
- if (!parentPath.isEmpty()) {
- name = parentPath.last();
- parentPath.erase(parentPath.end() - 1);
- }
- returnType = CodeChunk();
- }
- else {
- while (match(Tok_Ident)) {
- name = previousLexeme();
- /*
- This is a hack to let QML module identifiers through.
- */
- matchModuleQualifier(name);
- matchTemplateAngles();
-
- if (match(Tok_Gulbrandsen))
- parentPath.append(name);
- else
- break;
- }
-
- if (tok == Tok_operator) {
- name = lexeme();
- readToken();
- while (tok != Tok_Eoi) {
- name += lexeme();
- readToken();
- if (tok == Tok_LeftParen)
- break;
- }
- }
- if (parent && (tok == Tok_Semicolon ||
- tok == Tok_LeftBracket ||
- tok == Tok_Colon)
- && access != Node::Private) {
- if (tok == Tok_LeftBracket) {
- returnType.appendHotspot();
-
- int bracketDepth0 = tokenizer->bracketDepth();
- while ((tokenizer->bracketDepth() >= bracketDepth0 &&
- tok != Tok_Eoi) ||
- tok == Tok_RightBracket) {
- returnType.append(lexeme());
- readToken();
- }
- if (tok != Tok_Semicolon) {
- return false;
- }
- }
- else if (tok == Tok_Colon) {
- returnType.appendHotspot();
-
- while (tok != Tok_Semicolon && tok != Tok_Eoi) {
- returnType.append(lexeme());
- readToken();
- }
- if (tok != Tok_Semicolon) {
- return false;
- }
- }
-
- VariableNode *var = new VariableNode(parent, name);
- var->setAccess(access);
- var->setLocation(location());
- var->setLeftType(returnType.left());
- var->setRightType(returnType.right());
- if (matched_compat)
- var->setStatus(Node::Compat);
- var->setStatic(matched_static);
- return false;
- }
- if (tok != Tok_LeftParen)
- return false;
- }
- readToken();
-
- // A left paren was seen. Parse the parameters
- bool isQPrivateSignal = false;
- QVector<Parameter> pvect;
- if (tok != Tok_RightParen) {
- do {
- if (!matchParameter(pvect, isQPrivateSignal))
- return false;
- } while (match(Tok_Comma));
- }
- // The parameters must end with a right paren
- if (!match(Tok_RightParen))
- return false;
-
- // look for const
- bool matchedConst = match(Tok_const);
-
- // look for 0 indicating pure virtual
- if (match(Tok_Equal) && match(Tok_Number))
- virtuality = FunctionNode::PureVirtual;
-
- // look for colon indicating ctors which must be skipped
- if (match(Tok_Colon)) {
- while (tok != Tok_LeftBrace && tok != Tok_Eoi)
- readToken();
- }
-
- // If no ';' expect a body, which must be skipped.
- bool body_expected = false;
- bool body_present = false;
- if (!match(Tok_Semicolon) && tok != Tok_Eoi) {
- body_expected = true;
- int nesting = tokenizer->braceDepth();
- if (!match(Tok_LeftBrace))
- return false;
- // skip the body
- while (tokenizer->braceDepth() >= nesting && tok != Tok_Eoi)
- readToken();
- body_present = true;
- match(Tok_RightBrace);
- }
-
- FunctionNode *func = 0;
- bool createFunctionNode = false;
- if (parsingHeaderFile_) {
- if (matched_friend) {
- if (matched_inline) {
- // nothing yet
- }
- if (body_present) {
- if (body_expected) {
- // nothing yet
- }
- createFunctionNode = true;
- if (parent && parent->parent())
- parent = parent->parent();
- else
- return false;
- }
- }
- else
- createFunctionNode = true;
- }
- else
- createFunctionNode = true;
-
- if (createFunctionNode) {
- func = new FunctionNode(extra.type, parent, name, extra.isAttached);
- if (matched_friend)
- access = Node::Public;
- func->setAccess(access);
- func->setLocation(location());
- func->setReturnType(returnType.toString());
- func->setParentPath(parentPath);
- func->setTemplateStuff(templateStuff);
- if (matched_compat)
- func->setStatus(Node::Compat);
- if (matched_QT_DEPRECATED)
- func->setStatus(Node::Deprecated);
- if (matched_explicit) { /* What can be done? */ }
- func->setMetaness(metaness_);
- if (parent) {
- if (name == parent->name())
- func->setMetaness(FunctionNode::Ctor);
- else if (name.startsWith(QLatin1Char('~')))
- func->setMetaness(FunctionNode::Dtor);
- }
- func->setStatic(matched_static);
- func->setConst(matchedConst);
- func->setVirtualness(virtuality);
- if (isQPrivateSignal)
- func->setPrivateSignal();
- if (!pvect.isEmpty()) {
- func->setParameters(pvect);
- }
- }
- if (parentPathPtr != 0)
- *parentPathPtr = parentPath;
- if (funcPtr != 0)
- *funcPtr = func;
- return true;
-}
-
-bool CppCodeParser::matchBaseSpecifier(ClassNode *classe, bool isClass)
-{
- Node::Access access;
-
- switch (tok) {
- case Tok_public:
- access = Node::Public;
- readToken();
- break;
- case Tok_protected:
- access = Node::Protected;
- readToken();
- break;
- case Tok_private:
- access = Node::Private;
- readToken();
- break;
- default:
- access = isClass ? Node::Private : Node::Public;
- }
-
- if (tok == Tok_virtual)
- readToken();
-
- CodeChunk baseClass;
- if (!matchDataType(&baseClass))
- return false;
-
- classe->addUnresolvedBaseClass(access, baseClass.toPath(), baseClass.toString());
- return true;
-}
-
-bool CppCodeParser::matchBaseList(ClassNode *classe, bool isClass)
-{
- for (;;) {
- if (!matchBaseSpecifier(classe, isClass))
- return false;
- if (tok == Tok_LeftBrace)
- return true;
- if (!match(Tok_Comma))
- return false;
- }
-}
-
-/*!
- Parse a C++ class, union, or struct declaration.
-
- This function only handles one level of class nesting, but that is
- sufficient for Qt because there are no cases of class nesting more
- than one level deep.
- */
-bool CppCodeParser::matchClassDecl(Aggregate *parent,
- const QString &templateStuff)
-{
- bool isClass = (tok == Tok_class);
- readToken();
-
- bool compat = matchCompat();
-
- if (tok != Tok_Ident)
- return false;
- while (tok == Tok_Ident)
- readToken();
- if (tok == Tok_Gulbrandsen) {
- Node* n = parent->findChildNode(previousLexeme(),Node::Class);
- if (n) {
- parent = static_cast<Aggregate*>(n);
- if (parent) {
- readToken();
- if (tok != Tok_Ident)
- return false;
- readToken();
- }
- }
- }
- if (tok != Tok_Colon && tok != Tok_LeftBrace)
- return false;
-
- /*
- So far, so good. We have 'class Foo {' or 'class Foo :'.
- This is enough to recognize a class definition.
- */
- ClassNode *classe = new ClassNode(parent, previousLexeme());
- classe->setAccess(access);
- classe->setLocation(location());
- if (compat)
- classe->setStatus(Node::Compat);
- if (!physicalModuleName.isEmpty())
- classe->setPhysicalModuleName(physicalModuleName);
- classe->setTemplateStuff(templateStuff);
-
- if (match(Tok_Colon) && !matchBaseList(classe, isClass))
- return false;
- if (!match(Tok_LeftBrace))
- return false;
-
- Node::Access outerAccess = access;
- access = isClass ? Node::Private : Node::Public;
- FunctionNode::Metaness outerMetaness = metaness_;
- metaness_ = FunctionNode::Plain;
-
- bool matches = (matchDeclList(classe) && match(Tok_RightBrace) &&
- match(Tok_Semicolon));
- access = outerAccess;
- metaness_ = outerMetaness;
- return matches;
-}
-
-bool CppCodeParser::matchNamespaceDecl(Aggregate *parent)
-{
- readToken(); // skip 'namespace'
- if (tok != Tok_Ident)
- return false;
- while (tok == Tok_Ident)
- readToken();
- if (tok != Tok_LeftBrace)
- return false;
-
- /*
- So far, so good. We have 'namespace Foo {'.
- */
- QString namespaceName = previousLexeme();
- NamespaceNode* ns = 0;
- if (parent)
- ns = static_cast<NamespaceNode*>(parent->findChildNode(namespaceName, Node::Namespace));
- if (!ns) {
- ns = new NamespaceNode(parent, namespaceName);
- ns->setAccess(access);
- ns->setLocation(location());
- }
-
- readToken(); // skip '{'
- bool matched = matchDeclList(ns);
- return matched && match(Tok_RightBrace);
-}
-
-/*!
- Match a C++ \c using clause. Return \c true if the match
- is successful. Otherwise false.
-
- If the \c using clause is for a namespace, an open namespace
- <is inserted for qdoc to look in to find things.
-
- If the \c using clause is a base class member function, the
- member function is added to \a parent as an unresolved
- \c using clause.
- */
-bool CppCodeParser::matchUsingDecl(Aggregate* parent)
-{
- bool usingNamespace = false;
- readToken(); // skip 'using'
-
- if (tok == Tok_namespace) {
- usingNamespace = true;
- readToken();
- }
-
- int openLeftAngles = 0;
- int openLeftParens = 0;
- bool usingOperator = false;
- QString name;
- while (tok != Tok_Semicolon) {
- if ((tok != Tok_Ident) && (tok != Tok_Gulbrandsen)) {
- if (tok == Tok_LeftAngle) {
- ++openLeftAngles;
- }
- else if (tok == Tok_RightAngle) {
- if (openLeftAngles <= 0)
- return false;
- --openLeftAngles;
- }
- else if (tok == Tok_Comma) {
- if (openLeftAngles <= 0)
- return false;
- }
- else if (tok == Tok_operator) {
- usingOperator = true;
- }
- else if (tok == Tok_SomeOperator) {
- if (!usingOperator)
- return false;
- }
- else if (tok == Tok_LeftParen) {
- ++openLeftParens;
- }
- else if (tok == Tok_RightParen) {
- if (openLeftParens <= 0)
- return false;
- --openLeftParens;
- }
- else {
- return false;
- }
- }
- name += lexeme();
- readToken();
- }
-
- if (usingNamespace) {
- // 'using namespace Foo;'.
- qdb_->insertOpenNamespace(name);
- }
- else if (parent && parent->isClass()) {
- ClassNode* cn = static_cast<ClassNode*>(parent);
- cn->addUnresolvedUsingClause(name);
- }
- return true;
-}
-
-bool CppCodeParser::matchEnumItem(Aggregate *parent, EnumNode *enume)
-{
- if (!match(Tok_Ident))
- return false;
-
- QString name = previousLexeme();
- CodeChunk val;
- int parenLevel = 0;
-
- if (match(Tok_Equal)) {
- while (tok != Tok_RightBrace && tok != Tok_Eoi) {
- if (tok == Tok_LeftParen)
- parenLevel++;
- else if (tok == Tok_RightParen)
- parenLevel--;
- else if (tok == Tok_Comma) {
- if (parenLevel <= 0)
- break;
- }
- val.append(lexeme());
- readToken();
- }
- }
-
- if (enume) {
- QString strVal = val.toString();
- if (strVal.isEmpty()) {
- if (enume->items().isEmpty()) {
- strVal = "0";
- }
- else {
- QString last = enume->items().last().value();
- bool ok;
- int n = last.toInt(&ok);
- if (ok) {
- if (last.startsWith(QLatin1Char('0')) && last.size() > 1) {
- if (last.startsWith("0x") || last.startsWith("0X"))
- strVal = last.left(2) + QString::number(n + 1, 16);
- else
- strVal = QLatin1Char('0') + QString::number(n + 1, 8);
- }
- else
- strVal = QString::number(n + 1);
- }
- }
- }
-
- enume->addItem(EnumItem(name, strVal));
- }
- else {
- VariableNode *var = new VariableNode(parent, name);
- var->setAccess(access);
- var->setLocation(location());
- var->setLeftType("const int");
- var->setStatic(true);
- }
- return true;
-}
-
-bool CppCodeParser::matchEnumDecl(Aggregate *parent)
-{
- QString name;
-
- if (!match(Tok_enum))
- return false;
- if (match(Tok_Ident))
- name = previousLexeme();
- if (tok != Tok_LeftBrace)
- return false;
-
- EnumNode *enume = 0;
-
- if (!name.isEmpty()) {
- enume = new EnumNode(parent, name);
- enume->setAccess(access);
- enume->setLocation(location());
- }
-
- readToken();
-
- if (!matchEnumItem(parent, enume))
- return false;
-
- while (match(Tok_Comma)) {
- if (!matchEnumItem(parent, enume))
- return false;
- }
- return match(Tok_RightBrace) && match(Tok_Semicolon);
-}
-
-bool CppCodeParser::matchTypedefDecl(Aggregate *parent)
-{
- CodeChunk dataType;
- QString name;
-
- if (!match(Tok_typedef))
- return false;
- if (!matchDataType(&dataType, &name))
- return false;
- if (!match(Tok_Semicolon))
- return false;
-
- if (parent && !parent->findChildNode(name, Node::Typedef)) {
- TypedefNode* td = new TypedefNode(parent, name);
- td->setAccess(access);
- td->setLocation(location());
- }
- return true;
-}
-
-bool CppCodeParser::matchProperty(Aggregate *parent)
-{
- int expected_tok = Tok_LeftParen;
- if (match(Tok_Q_PRIVATE_PROPERTY)) {
- expected_tok = Tok_Comma;
- if (!skipTo(Tok_Comma))
- return false;
- }
- else if (!match(Tok_Q_PROPERTY) &&
- !match(Tok_Q_OVERRIDE) &&
- !match(Tok_QDOC_PROPERTY)) {
- return false;
- }
-
- if (!match(expected_tok))
- return false;
-
- QString name;
- CodeChunk dataType;
- if (!matchDataType(&dataType, &name))
- return false;
-
- PropertyNode *property = new PropertyNode(parent, name);
- property->setAccess(Node::Public);
- property->setLocation(location());
- property->setDataType(dataType.toString());
-
- while (tok != Tok_RightParen && tok != Tok_Eoi) {
- if (!match(Tok_Ident))
- return false;
- QString key = previousLexeme();
- QString value;
-
- // Keywords with no associated values
- if (key == "CONSTANT") {
- property->setConstant();
- continue;
- }
- else if (key == "FINAL") {
- property->setFinal();
- continue;
- }
-
- if (match(Tok_Ident) || match(Tok_Number)) {
- value = previousLexeme();
- }
- else if (match(Tok_LeftParen)) {
- int depth = 1;
- while (tok != Tok_Eoi) {
- if (tok == Tok_LeftParen) {
- readToken();
- ++depth;
- } else if (tok == Tok_RightParen) {
- readToken();
- if (--depth == 0)
- break;
- } else {
- readToken();
- }
- }
- value = "?";
- }
-
- if (key == "READ")
- qdb_->addPropertyFunction(property, value, PropertyNode::Getter);
- else if (key == "WRITE") {
- qdb_->addPropertyFunction(property, value, PropertyNode::Setter);
- property->setWritable(true);
- }
- else if (key == "STORED")
- property->setStored(value.toLower() == "true");
- else if (key == "DESIGNABLE") {
- QString v = value.toLower();
- if (v == "true")
- property->setDesignable(true);
- else if (v == "false")
- property->setDesignable(false);
- else {
- property->setDesignable(false);
- property->setRuntimeDesFunc(value);
- }
- }
- else if (key == "RESET")
- qdb_->addPropertyFunction(property, value, PropertyNode::Resetter);
- else if (key == "NOTIFY") {
- qdb_->addPropertyFunction(property, value, PropertyNode::Notifier);
- } else if (key == "REVISION") {
- int revision;
- bool ok;
- revision = value.toInt(&ok);
- if (ok)
- property->setRevision(revision);
- else
- location().warning(tr("Invalid revision number: %1").arg(value));
- } else if (key == "SCRIPTABLE") {
- QString v = value.toLower();
- if (v == "true")
- property->setScriptable(true);
- else if (v == "false")
- property->setScriptable(false);
- else {
- property->setScriptable(false);
- property->setRuntimeScrFunc(value);
- }
- }
- }
- match(Tok_RightParen);
- return true;
-}
-
-/*!
- Parse a C++ declaration.
- */
-bool CppCodeParser::matchDeclList(Aggregate *parent)
-{
- ExtraFuncData extra;
- QString templateStuff;
- int braceDepth0 = tokenizer->braceDepth();
- if (tok == Tok_RightBrace) // prevents failure on empty body
- braceDepth0++;
-
- while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi) {
- switch (tok) {
- case Tok_Colon:
- readToken();
- break;
- case Tok_class:
- case Tok_struct:
- case Tok_union:
- matchClassDecl(parent, templateStuff);
- break;
- case Tok_namespace:
- matchNamespaceDecl(parent);
- break;
- case Tok_using:
- matchUsingDecl(parent);
- break;
- case Tok_template:
- {
- CodeChunk dataType;
- readToken();
- matchTemplateAngles(&dataType);
- templateStuff = dataType.toString();
- }
- continue;
- case Tok_enum:
- matchEnumDecl(parent);
- break;
- case Tok_typedef:
- matchTypedefDecl(parent);
- break;
- case Tok_private:
- readToken();
- access = Node::Private;
- metaness_ = FunctionNode::Plain;
- break;
- case Tok_protected:
- readToken();
- access = Node::Protected;
- metaness_ = FunctionNode::Plain;
- break;
- case Tok_public:
- readToken();
- access = Node::Public;
- metaness_ = FunctionNode::Plain;
- break;
- case Tok_signals:
- case Tok_Q_SIGNALS:
- readToken();
- access = Node::Public;
- metaness_ = FunctionNode::Signal;
- break;
- case Tok_slots:
- case Tok_Q_SLOTS:
- readToken();
- metaness_ = FunctionNode::Slot;
- break;
- case Tok_Q_OBJECT:
- readToken();
- break;
- case Tok_Q_OVERRIDE:
- case Tok_Q_PROPERTY:
- case Tok_Q_PRIVATE_PROPERTY:
- case Tok_QDOC_PROPERTY:
- if (!matchProperty(parent)) {
- location().warning(tr("Failed to parse token %1 in property declaration").arg(lexeme()));
- skipTo(Tok_RightParen);
- match(Tok_RightParen);
- }
- break;
- case Tok_Q_DECLARE_SEQUENTIAL_ITERATOR:
- readToken();
- if (match(Tok_LeftParen) && match(Tok_Ident))
- sequentialIteratorClasses.insert(previousLexeme(), location().fileName());
- match(Tok_RightParen);
- break;
- case Tok_Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR:
- readToken();
- if (match(Tok_LeftParen) && match(Tok_Ident))
- mutableSequentialIteratorClasses.insert(previousLexeme(), location().fileName());
- match(Tok_RightParen);
- break;
- case Tok_Q_DECLARE_ASSOCIATIVE_ITERATOR:
- readToken();
- if (match(Tok_LeftParen) && match(Tok_Ident))
- associativeIteratorClasses.insert(previousLexeme(), location().fileName());
- match(Tok_RightParen);
- break;
- case Tok_Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR:
- readToken();
- if (match(Tok_LeftParen) && match(Tok_Ident))
- mutableAssociativeIteratorClasses.insert(previousLexeme(), location().fileName());
- match(Tok_RightParen);
- break;
- case Tok_Q_DECLARE_FLAGS:
- readToken();
- if (match(Tok_LeftParen) && match(Tok_Ident)) {
- QString flagsType = previousLexeme();
- if (match(Tok_Comma) && match(Tok_Ident)) {
- QString name = previousLexeme();
- TypedefNode *flagsNode = new TypedefNode(parent, flagsType);
- flagsNode->setAccess(access);
- flagsNode->setLocation(location());
- EnumNode* en = static_cast<EnumNode*>(parent->findChildNode(name, Node::Enum));
- if (en)
- en->setFlagsType(flagsNode);
- }
- }
- match(Tok_RightParen);
- break;
- case Tok_QT_MODULE:
- readToken();
- if (match(Tok_LeftParen) && match(Tok_Ident))
- physicalModuleName = previousLexeme();
- if (!physicalModuleName.startsWith("Qt"))
- physicalModuleName.prepend("Qt");
- match(Tok_RightParen);
- break;
- default:
- if (!matchFunctionDecl(parent, 0, 0, templateStuff, extra)) {
- while (tok != Tok_Eoi &&
- (tokenizer->braceDepth() > braceDepth0 ||
- (!match(Tok_Semicolon) &&
- tok != Tok_public && tok != Tok_protected &&
- tok != Tok_private))) {
- readToken();
- }
- }
- }
- templateStuff.clear();
- }
- return true;
-}
-
-/*!
- This is called by parseSourceFile() to do the actual parsing
- and tree building.
- */
-bool CppCodeParser::matchDocsAndStuff()
-{
- ExtraFuncData extra;
- const QSet<QString>& topicCommandsAllowed = topicCommands();
- const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
- const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
-
- while (tok != Tok_Eoi) {
- if (tok == Tok_Doc) {
- /*
- lexeme() returns an entire qdoc comment.
- */
- QString comment = lexeme();
- Location start_loc(location());
- readToken();
-
- Doc::trimCStyleComment(start_loc,comment);
- Location end_loc(location());
-
- /*
- Doc parses the comment.
- */
- Doc doc(start_loc,end_loc,comment,metacommandsAllowed, topicCommandsAllowed);
- QString topic;
- bool isQmlPropertyTopic = false;
- bool isJsPropertyTopic = false;
-
- const TopicList& topics = doc.topicsUsed();
- if (!topics.isEmpty()) {
- topic = topics[0].topic;
- if ((topic == COMMAND_QMLPROPERTY) ||
- (topic == COMMAND_QMLPROPERTYGROUP) ||
- (topic == COMMAND_QMLATTACHEDPROPERTY)) {
- isQmlPropertyTopic = true;
- }
- else if ((topic == COMMAND_JSPROPERTY) ||
- (topic == COMMAND_JSPROPERTYGROUP) ||
- (topic == COMMAND_JSATTACHEDPROPERTY)) {
- isJsPropertyTopic = true;
- }
- }
- NodeList nodes;
- DocList docs;
-
- if (topic.isEmpty()) {
- QStringList parentPath;
- FunctionNode *clone;
- FunctionNode *func = 0;
-
- if (matchFunctionDecl(0, &parentPath, &clone, QString(), extra)) {
- func = qdb_->findFunctionNode(parentPath, clone);
- /*
- If the node was not found, then search for it in the
- open C++ namespaces. We don't expect this search to
- be necessary often. Nor do we expect it to succeed
- very often.
- */
- if (func == 0)
- func = qdb_->findNodeInOpenNamespace(parentPath, clone);
-
- if (func) {
- func->borrowParameterNames(clone);
- nodes.append(func);
- docs.append(doc);
- }
- delete clone;
- }
- else {
- doc.location().warning(tr("Cannot tie this documentation to anything"),
- tr("I found a /*! ... */ comment, but there was no "
- "topic command (e.g., '\\%1', '\\%2') in the "
- "comment and no function definition following "
- "the comment.")
- .arg(COMMAND_FN).arg(COMMAND_PAGE));
- }
- }
- else if (isQmlPropertyTopic || isJsPropertyTopic) {
- Doc nodeDoc = doc;
- processQmlProperties(nodeDoc, nodes, docs, isJsPropertyTopic);
- }
- else {
- ArgList args;
- const QSet<QString>& topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
- if (topicCommandsUsed.count() > 0) {
- topic = *topicCommandsUsed.constBegin();
- args = doc.metaCommandArgs(topic);
- }
- if (topicCommandsUsed.count() > 1) {
- QString topics;
- QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
- while (t != topicCommandsUsed.constEnd()) {
- topics += " \\" + *t + QLatin1Char(',');
- ++t;
- }
- topics[topics.lastIndexOf(',')] = '.';
- int i = topics.lastIndexOf(',');
- topics[i] = ' ';
- topics.insert(i+1,"and");
- doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
- }
- ArgList::ConstIterator a = args.constBegin();
- while (a != args.constEnd()) {
- Doc nodeDoc = doc;
- Node *node = processTopicCommand(nodeDoc,topic,*a);
- if (node != 0) {
- nodes.append(node);
- docs.append(nodeDoc);
- }
- ++a;
- }
- }
-
- NodeList::Iterator n = nodes.begin();
- QList<Doc>::Iterator d = docs.begin();
- while (n != nodes.end()) {
- processOtherMetaCommands(*d, *n);
- (*n)->setDoc(*d);
- checkModuleInclusion(*n);
- if ((*n)->isAggregate() && ((Aggregate *)*n)->includes().isEmpty()) {
- Aggregate *m = static_cast<Aggregate *>(*n);
- while (m->parent() && m->physicalModuleName().isEmpty()) {
- m = m->parent();
- }
- if (m == *n)
- ((Aggregate *)*n)->addInclude((*n)->name());
- else
- ((Aggregate *)*n)->setIncludes(m->includes());
- }
- ++d;
- ++n;
- }
- }
- else if (tok == Tok_using) {
- matchUsingDecl(0);
- }
- else {
- QStringList parentPath;
- FunctionNode *clone;
- FunctionNode *node = 0;
-
- if (matchFunctionDecl(0, &parentPath, &clone, QString(), extra)) {
- /*
- The location of the definition is more interesting
- than that of the declaration. People equipped with
- a sophisticated text editor can respond to warnings
- concerning undocumented functions very quickly.
-
- Signals are implemented in uninteresting files
- generated by moc.
- */
- node = qdb_->findFunctionNode(parentPath, clone);
- if (node != 0 && node->metaness() != FunctionNode::Signal)
- node->setLocation(clone->location());
- delete clone;
- }
- else {
- if (tok != Tok_Doc)
- readToken();
- }
- }
- }
- return true;
-}
-
-/*!
- This function uses a Tokenizer to parse the function \a signature
- in an attempt to match it to the signature of a child node of \a root.
- If a match is found, \a funcPtr is set to point to the matching node
- and true is returned.
- */
-bool CppCodeParser::makeFunctionNode(const QString& signature,
- QStringList* parentPathPtr,
- FunctionNode** funcPtr,
- ExtraFuncData& extra)
-{
- Tokenizer* outerTokenizer = tokenizer;
- int outerTok = tok;
-
- QByteArray latin1 = signature.toLatin1();
- Tokenizer stringTokenizer(location(), latin1);
- stringTokenizer.setParsingFnOrMacro(true);
- tokenizer = &stringTokenizer;
- readToken();
-
- inMacroCommand_ = extra.isMacro;
- bool ok = matchFunctionDecl(extra.root, parentPathPtr, funcPtr, QString(), extra);
- inMacroCommand_ = false;
- // potential memory leak with funcPtr
-
- tokenizer = outerTokenizer;
- tok = outerTok;
- return ok;
-}
-
-/*!
- This function uses a Tokenizer to parse the \a parameters of a
- function into the parameter vector \a {pvect}.
- */
-bool CppCodeParser::parseParameters(const QString& parameters,
- QVector<Parameter>& pvect,
- bool& isQPrivateSignal)
-{
- Tokenizer* outerTokenizer = tokenizer;
- int outerTok = tok;
-
- QByteArray latin1 = parameters.toLatin1();
- Tokenizer stringTokenizer(Location(), latin1);
- stringTokenizer.setParsingFnOrMacro(true);
- tokenizer = &stringTokenizer;
- readToken();
-
- inMacroCommand_ = false;
- do {
- if (!matchParameter(pvect, isQPrivateSignal))
- return false;
- } while (match(Tok_Comma));
-
- tokenizer = outerTokenizer;
- tok = outerTok;
- return true;
-}
-
-/*!
- Create a new FunctionNode for a QML method or signal, as
- specified by \a type, as a child of \a parent. \a sig is
- the complete signature, and if \a attached is true, the
- method or signal is "attached". \a qdoctag is the text of
- the \a type.
-
- \a parent is the QML class node. The QML module and QML
- type names have already been consumed to find \a parent.
- What remains in \a sig is the method signature. The method
- must be a child of \a parent.
- */
-FunctionNode* CppCodeParser::makeFunctionNode(const Doc& doc,
- const QString& sig,
- Aggregate* parent,
- Node::NodeType type,
- bool attached,
- QString qdoctag)
-{
- QStringList pp;
- FunctionNode* fn = 0;
- ExtraFuncData extra(parent, type, attached);
- if (!makeFunctionNode(sig, &pp, &fn, extra) && !makeFunctionNode("void " + sig, &pp, &fn, extra)) {
- doc.location().warning(tr("Invalid syntax in '\\%1'").arg(qdoctag));
- }
- return fn;
-}
-
-void CppCodeParser::parseQiteratorDotH(const Location &location, const QString &filePath)
-{
- QFile file(filePath);
- if (!file.open(QFile::ReadOnly))
- return;
-
- QString text = file.readAll();
- text.remove("\r");
- text.remove("\\\n");
- QStringList lines = text.split(QLatin1Char('\n'));
- lines = lines.filter("Q_DECLARE");
- lines.replaceInStrings(QRegExp("#define Q[A-Z_]*\\(C\\)"), QString());
-
- if (lines.size() == 4) {
- sequentialIteratorDefinition = lines[0];
- mutableSequentialIteratorDefinition = lines[1];
- associativeIteratorDefinition = lines[2];
- mutableAssociativeIteratorDefinition = lines[3];
- }
- else {
- location.warning(tr("The qiterator.h hack failed"));
- }
-}
-
-void CppCodeParser::instantiateIteratorMacro(const QString &container,
- const QString &includeFile,
- const QString &macroDef)
-{
- QString resultingCode = macroDef;
- resultingCode.replace(QRegExp("\\bC\\b"), container);
- resultingCode.remove(QRegExp("\\s*##\\s*"));
-
- Location loc(includeFile); // hack to get the include file for free
- QByteArray latin1 = resultingCode.toLatin1();
- Tokenizer stringTokenizer(loc, latin1);
- tokenizer = &stringTokenizer;
- readToken();
- matchDeclList(QDocDatabase::qdocDB()->primaryTreeRoot());
-}
-
-void CppCodeParser::createExampleFileNodes(DocumentNode *dn)
-{
- QString examplePath = dn->name();
- QString proFileName = examplePath + QLatin1Char('/') + examplePath.split(QLatin1Char('/')).last() + ".pro";
- QString userFriendlyFilePath;
-
- QString fullPath = Config::findFile(dn->doc().location(),
- exampleFiles,
- exampleDirs,
- proFileName,
- userFriendlyFilePath);
-
- if (fullPath.isEmpty()) {
- QString tmp = proFileName;
- proFileName = examplePath + QLatin1Char('/') + "qbuild.pro";
- userFriendlyFilePath.clear();
- fullPath = Config::findFile(dn->doc().location(),
- exampleFiles,
- exampleDirs,
- proFileName,
- userFriendlyFilePath);
- if (fullPath.isEmpty()) {
- proFileName = examplePath + QLatin1Char('/') + examplePath.split(QLatin1Char('/')).last() + ".qmlproject";
- userFriendlyFilePath.clear();
- fullPath = Config::findFile(dn->doc().location(),
- exampleFiles,
- exampleDirs,
- proFileName,
- userFriendlyFilePath);
- if (fullPath.isEmpty()) {
- QString details = QLatin1String("Example directories: ") + exampleDirs.join(QLatin1Char(' '));
- if (!exampleFiles.isEmpty())
- details += QLatin1String(", example files: ") + exampleFiles.join(QLatin1Char(' '));
- dn->location().warning(tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName), details);
- dn->location().warning(tr(" EXAMPLE PATH DOES NOT EXIST: %1").arg(examplePath), details);
- return;
- }
- }
- }
-
- int sizeOfBoringPartOfName = fullPath.size() - proFileName.size();
- if (fullPath.startsWith("./"))
- sizeOfBoringPartOfName = sizeOfBoringPartOfName - 2;
- fullPath.truncate(fullPath.lastIndexOf('/'));
-
- QStringList exampleFiles = Config::getFilesHere(fullPath,exampleNameFilter);
- QString imagesPath = fullPath + "/images";
- QStringList imageFiles = Config::getFilesHere(imagesPath,exampleImageFilter);
- if (!exampleFiles.isEmpty()) {
- // move main.cpp and to the end, if it exists
- QString mainCpp;
- QMutableStringListIterator i(exampleFiles);
- i.toBack();
- while (i.hasPrevious()) {
- QString fileName = i.previous();
- if (fileName.endsWith("/main.cpp")) {
- mainCpp = fileName;
- i.remove();
- }
- else if (fileName.contains("/qrc_") || fileName.contains("/moc_")
- || fileName.contains("/ui_"))
- i.remove();
- }
- if (!mainCpp.isEmpty())
- exampleFiles.append(mainCpp);
-
- // add any qmake Qt resource files and qmake project files
- exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro *.qmlproject qmldir");
- }
-
- foreach (const QString &exampleFile, exampleFiles) {
- new DocumentNode(dn,
- exampleFile.mid(sizeOfBoringPartOfName),
- Node::File,
- Node::NoPageType);
- }
- foreach (const QString &imageFile, imageFiles) {
- new DocumentNode(dn,
- imageFile.mid(sizeOfBoringPartOfName),
- Node::Image,
- Node::NoPageType);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h
deleted file mode 100644
index ec04482321..0000000000
--- a/src/tools/qdoc/cppcodeparser.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef CPPCODEPARSER_H
-#define CPPCODEPARSER_H
-
-#include <qregexp.h>
-
-#include "codeparser.h"
-
-QT_BEGIN_NAMESPACE
-
-class ClassNode;
-class CodeChunk;
-class CppCodeParserPrivate;
-class FunctionNode;
-class Aggregate;
-class Tokenizer;
-
-class CppCodeParser : public CodeParser
-{
- Q_DECLARE_TR_FUNCTIONS(QDoc::CppCodeParser)
-
- struct ExtraFuncData {
- Aggregate* root; // Used as the parent.
- Node::NodeType type; // The node type: Function, etc.
- bool isAttached; // If true, the method is attached.
- bool isMacro; // If true, we are parsing a macro signature.
- ExtraFuncData() : root(0), type(Node::Function), isAttached(false), isMacro(false) { }
- ExtraFuncData(Aggregate* r, Node::NodeType t, bool a)
- : root(r), type(t), isAttached(a), isMacro(false) { }
- };
-
-public:
- CppCodeParser();
- ~CppCodeParser();
- static CppCodeParser* cppParser() { return cppParser_; }
-
- virtual void initializeParser(const Config& config) Q_DECL_OVERRIDE;
- virtual void terminateParser() Q_DECL_OVERRIDE;
- virtual QString language() Q_DECL_OVERRIDE;
- virtual QStringList headerFileNameFilter() Q_DECL_OVERRIDE;
- virtual QStringList sourceFileNameFilter() Q_DECL_OVERRIDE;
- virtual void parseHeaderFile(const Location& location, const QString& filePath) Q_DECL_OVERRIDE;
- virtual void parseSourceFile(const Location& location, const QString& filePath) Q_DECL_OVERRIDE;
- virtual void doneParsingHeaderFiles() Q_DECL_OVERRIDE;
- virtual void doneParsingSourceFiles() Q_DECL_OVERRIDE;
- bool parseParameters(const QString& parameters, QVector<Parameter>& pvect, bool& isQPrivateSignal);
-
-protected:
- const QSet<QString>& topicCommands();
- const QSet<QString>& otherMetaCommands();
- virtual Node* processTopicCommand(const Doc& doc,
- const QString& command,
- const ArgLocPair& arg);
- void processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs, bool jsProps);
- bool splitQmlPropertyGroupArg(const QString& arg,
- QString& module,
- QString& element,
- QString& name);
- bool splitQmlPropertyArg(const QString& arg,
- QString& type,
- QString& module,
- QString& element,
- QString& name);
- bool splitQmlMethodArg(const QString& arg,
- QString& type,
- QString& module,
- QString& element);
- virtual void processOtherMetaCommand(const Doc& doc,
- const QString& command,
- const ArgLocPair& argLocPair,
- Node *node);
- void processOtherMetaCommands(const Doc& doc, Node *node);
-
- protected:
- void reset();
- void readToken();
- const Location& location();
- QString previousLexeme();
- QString lexeme();
-
- private:
- bool match(int target);
- bool skipTo(int target);
- bool matchCompat();
- bool matchModuleQualifier(QString& name);
- bool matchTemplateAngles(CodeChunk *type = 0);
- bool matchTemplateHeader();
- bool matchDataType(CodeChunk *type, QString *var = 0);
- bool matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal);
- bool matchFunctionDecl(Aggregate *parent,
- QStringList *parentPathPtr,
- FunctionNode **funcPtr,
- const QString &templateStuff,
- ExtraFuncData& extra);
- bool matchBaseSpecifier(ClassNode *classe, bool isClass);
- bool matchBaseList(ClassNode *classe, bool isClass);
- bool matchClassDecl(Aggregate *parent,
- const QString &templateStuff = QString());
- bool matchNamespaceDecl(Aggregate *parent);
- bool matchUsingDecl(Aggregate* parent);
- bool matchEnumItem(Aggregate *parent, EnumNode *enume);
- bool matchEnumDecl(Aggregate *parent);
- bool matchTypedefDecl(Aggregate *parent);
- bool matchProperty(Aggregate *parent);
- bool matchDeclList(Aggregate *parent);
- bool matchDocsAndStuff();
- bool makeFunctionNode(const QString &synopsis,
- QStringList *parentPathPtr,
- FunctionNode **funcPtr,
- ExtraFuncData& params);
- FunctionNode* makeFunctionNode(const Doc& doc,
- const QString& sig,
- Aggregate* parent,
- Node::NodeType type,
- bool attached,
- QString qdoctag);
- void parseQiteratorDotH(const Location &location, const QString &filePath);
- void instantiateIteratorMacro(const QString &container,
- const QString &includeFile,
- const QString &macroDef);
- void createExampleFileNodes(DocumentNode *dn);
- int matchFunctionModifier();
-
- protected:
- QMap<QString, Node::NodeType> nodeTypeMap;
- Tokenizer *tokenizer;
- int tok;
- Node::Access access;
- FunctionNode::Metaness metaness_;
- QString physicalModuleName;
- QStringList lastPath_;
- QRegExp varComment;
- QRegExp sep;
-
- private:
- QString sequentialIteratorDefinition;
- QString mutableSequentialIteratorDefinition;
- QString associativeIteratorDefinition;
- QString mutableAssociativeIteratorDefinition;
- QMap<QString, QString> sequentialIteratorClasses;
- QMap<QString, QString> mutableSequentialIteratorClasses;
- QMap<QString, QString> associativeIteratorClasses;
- QMap<QString, QString> mutableAssociativeIteratorClasses;
-
- static QStringList exampleFiles;
- static QStringList exampleDirs;
- static CppCodeParser* cppParser_;
- QString exampleNameFilter;
- QString exampleImageFilter;
-};
-
-#define COMMAND_ABSTRACT Doc::alias("abstract")
-#define COMMAND_CLASS Doc::alias("class")
-#define COMMAND_CONTENTSPAGE Doc::alias("contentspage")
-#define COMMAND_DITAMAP Doc::alias("ditamap")
-#define COMMAND_ENUM Doc::alias("enum")
-#define COMMAND_EXAMPLE Doc::alias("example")
-#define COMMAND_EXTERNALPAGE Doc::alias("externalpage")
-#define COMMAND_FILE Doc::alias("file")
-#define COMMAND_FN Doc::alias("fn")
-#define COMMAND_GROUP Doc::alias("group")
-#define COMMAND_HEADERFILE Doc::alias("headerfile")
-#define COMMAND_INDEXPAGE Doc::alias("indexpage")
-#define COMMAND_INHEADERFILE Doc::alias("inheaderfile")
-#define COMMAND_MACRO Doc::alias("macro")
-#define COMMAND_MODULE Doc::alias("module")
-#define COMMAND_NAMESPACE Doc::alias("namespace")
-#define COMMAND_OVERLOAD Doc::alias("overload")
-#define COMMAND_NEXTPAGE Doc::alias("nextpage")
-#define COMMAND_PAGE Doc::alias("page")
-#define COMMAND_PREVIOUSPAGE Doc::alias("previouspage")
-#define COMMAND_PROPERTY Doc::alias("property")
-#define COMMAND_REIMP Doc::alias("reimp")
-#define COMMAND_RELATES Doc::alias("relates")
-#define COMMAND_STARTPAGE Doc::alias("startpage")
-#define COMMAND_TYPEDEF Doc::alias("typedef")
-#define COMMAND_VARIABLE Doc::alias("variable")
-#define COMMAND_QMLABSTRACT Doc::alias("qmlabstract")
-#define COMMAND_QMLTYPE Doc::alias("qmltype")
-#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
-#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")
-#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
-#define COMMAND_QMLINHERITS Doc::alias("inherits")
-#define COMMAND_QMLINSTANTIATES Doc::alias("instantiates")
-#define COMMAND_QMLSIGNAL Doc::alias("qmlsignal")
-#define COMMAND_QMLATTACHEDSIGNAL Doc::alias("qmlattachedsignal")
-#define COMMAND_QMLMETHOD Doc::alias("qmlmethod")
-#define COMMAND_QMLATTACHEDMETHOD Doc::alias("qmlattachedmethod")
-#define COMMAND_QMLDEFAULT Doc::alias("default")
-#define COMMAND_QMLREADONLY Doc::alias("readonly")
-#define COMMAND_QMLBASICTYPE Doc::alias("qmlbasictype")
-#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
-#define COMMAND_AUDIENCE Doc::alias("audience")
-#define COMMAND_CATEGORY Doc::alias("category")
-#define COMMAND_PRODNAME Doc::alias("prodname")
-#define COMMAND_COMPONENT Doc::alias("component")
-#define COMMAND_AUTHOR Doc::alias("author")
-#define COMMAND_PUBLISHER Doc::alias("publisher")
-#define COMMAND_COPYRYEAR Doc::alias("copyryear")
-#define COMMAND_COPYRHOLDER Doc::alias("copyrholder")
-#define COMMAND_PERMISSIONS Doc::alias("permissions")
-#define COMMAND_LIFECYCLEVERSION Doc::alias("lifecycleversion")
-#define COMMAND_LIFECYCLEWSTATUS Doc::alias("lifecyclestatus")
-#define COMMAND_LICENSEYEAR Doc::alias("licenseyear")
-#define COMMAND_LICENSENAME Doc::alias("licensename")
-#define COMMAND_LICENSEDESCRIPTION Doc::alias("licensedescription")
-#define COMMAND_RELEASEDATE Doc::alias("releasedate")
-#define COMMAND_QTVARIABLE Doc::alias("qtvariable")
-// Some of these are not used currenmtly, but they are included now for completeness.
-#define COMMAND_JSTYPE Doc::alias("jstype")
-#define COMMAND_JSPROPERTY Doc::alias("jsproperty")
-#define COMMAND_JSPROPERTYGROUP Doc::alias("jspropertygroup")
-#define COMMAND_JSATTACHEDPROPERTY Doc::alias("jsattachedproperty")
-#define COMMAND_JSSIGNAL Doc::alias("jssignal")
-#define COMMAND_JSATTACHEDSIGNAL Doc::alias("jsattachedsignal")
-#define COMMAND_JSMETHOD Doc::alias("jsmethod")
-#define COMMAND_JSATTACHEDMETHOD Doc::alias("jsattachedmethod")
-#define COMMAND_JSBASICTYPE Doc::alias("jsbasictype")
-#define COMMAND_JSMODULE Doc::alias("jsmodule")
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp
deleted file mode 100644
index 4ed5894543..0000000000
--- a/src/tools/qdoc/doc.cpp
+++ /dev/null
@@ -1,3380 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "config.h"
-#include "doc.h"
-#include "codemarker.h"
-#include "editdistance.h"
-#include "openedlist.h"
-#include "quoter.h"
-#include "text.h"
-#include "atom.h"
-#include "tokenizer.h"
-#include <qdatetime.h>
-#include <qfile.h>
-#include <qfileinfo.h>
-#include <qhash.h>
-#include <qtextstream.h>
-#include <qregexp.h>
-#include <ctype.h>
-#include <limits.h>
-#include <qdebug.h>
-#include "generator.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QSet<QString>, null_Set_QString)
-Q_GLOBAL_STATIC(TopicList, nullTopicList)
-Q_GLOBAL_STATIC(QStringList, null_QStringList)
-Q_GLOBAL_STATIC(QList<Text>, null_QList_Text)
-Q_GLOBAL_STATIC(QStringMultiMap, null_QStringMultiMap)
-
-struct Macro
-{
- QString defaultDef;
- Location defaultDefLocation;
- QStringMap otherDefs;
- int numParams;
-};
-
-enum {
- CMD_A,
- CMD_ANNOTATEDLIST,
- CMD_B,
- CMD_BADCODE,
- CMD_BOLD,
- CMD_BR,
- CMD_BRIEF,
- CMD_C,
- CMD_CAPTION,
- CMD_CHAPTER,
- CMD_CODE,
- CMD_CODELINE,
- CMD_DIV,
- CMD_DOTS,
- CMD_E,
- CMD_ELSE,
- CMD_ENDCHAPTER,
- CMD_ENDCODE,
- CMD_ENDDIV,
- CMD_ENDFOOTNOTE,
- CMD_ENDIF,
- CMD_ENDLEGALESE,
- CMD_ENDLINK,
- CMD_ENDLIST,
- CMD_ENDMAPREF,
- CMD_ENDOMIT,
- CMD_ENDPART,
- CMD_ENDQUOTATION,
- CMD_ENDRAW,
- CMD_ENDSECTION1,
- CMD_ENDSECTION2,
- CMD_ENDSECTION3,
- CMD_ENDSECTION4,
- CMD_ENDSIDEBAR,
- CMD_ENDTABLE,
- CMD_ENDTOPICREF,
- CMD_FOOTNOTE,
- CMD_GENERATELIST,
- CMD_GRANULARITY,
- CMD_HEADER,
- CMD_HR,
- CMD_I,
- CMD_IF,
- CMD_IMAGE,
- CMD_IMPORTANT,
- CMD_INCLUDE,
- CMD_INLINEIMAGE,
- CMD_INDEX,
- CMD_INPUT,
- CMD_KEYWORD,
- CMD_L,
- CMD_LEGALESE,
- CMD_LI,
- CMD_LINK,
- CMD_LIST,
- CMD_MAPREF,
- CMD_META,
- CMD_NEWCODE,
- CMD_NOTE,
- CMD_O,
- CMD_OLDCODE,
- CMD_OMIT,
- CMD_OMITVALUE,
- CMD_OVERLOAD,
- CMD_PART,
- CMD_PRINTLINE,
- CMD_PRINTTO,
- CMD_PRINTUNTIL,
- CMD_QUOTATION,
- CMD_QUOTEFILE,
- CMD_QUOTEFROMFILE,
- CMD_QUOTEFUNCTION,
- CMD_RAW,
- CMD_ROW,
- CMD_SA,
- CMD_SECTION1,
- CMD_SECTION2,
- CMD_SECTION3,
- CMD_SECTION4,
- CMD_SIDEBAR,
- CMD_SINCELIST,
- CMD_SKIPLINE,
- CMD_SKIPTO,
- CMD_SKIPUNTIL,
- CMD_SNIPPET,
- CMD_SPAN,
- CMD_SUB,
- CMD_SUP,
- CMD_TABLE,
- CMD_TABLEOFCONTENTS,
- CMD_TARGET,
- CMD_TOPICREF,
- CMD_TT,
- CMD_UICONTROL,
- CMD_UNDERLINE,
- CMD_UNICODE,
- CMD_VALUE,
- CMD_WARNING,
- CMD_QML,
- CMD_ENDQML,
- CMD_CPP,
- CMD_ENDCPP,
- CMD_QMLTEXT,
- CMD_ENDQMLTEXT,
- CMD_CPPTEXT,
- CMD_ENDCPPTEXT,
- CMD_JS,
- CMD_ENDJS,
- NOT_A_CMD
-};
-
-static struct {
- const char *english;
- int no;
- QString *alias;
-} cmds[] = {
- { "a", CMD_A, 0 },
- { "annotatedlist", CMD_ANNOTATEDLIST, 0 },
- { "b", CMD_B, 0 },
- { "badcode", CMD_BADCODE, 0 },
- { "bold", CMD_BOLD, 0 },
- { "br", CMD_BR, 0 },
- { "brief", CMD_BRIEF, 0 },
- { "c", CMD_C, 0 },
- { "caption", CMD_CAPTION, 0 },
- { "chapter", CMD_CHAPTER, 0 },
- { "code", CMD_CODE, 0 },
- { "codeline", CMD_CODELINE, 0},
- { "div", CMD_DIV, 0 },
- { "dots", CMD_DOTS, 0 },
- { "e", CMD_E, 0 },
- { "else", CMD_ELSE, 0 },
- { "endchapter", CMD_ENDCHAPTER, 0 },
- { "endcode", CMD_ENDCODE, 0 },
- { "enddiv", CMD_ENDDIV, 0 },
- { "endfootnote", CMD_ENDFOOTNOTE, 0 },
- { "endif", CMD_ENDIF, 0 },
- { "endlegalese", CMD_ENDLEGALESE, 0 },
- { "endlink", CMD_ENDLINK, 0 },
- { "endlist", CMD_ENDLIST, 0 },
- { "endmapref", CMD_ENDMAPREF, 0 },
- { "endomit", CMD_ENDOMIT, 0 },
- { "endpart", CMD_ENDPART, 0 },
- { "endquotation", CMD_ENDQUOTATION, 0 },
- { "endraw", CMD_ENDRAW, 0 },
- { "endsection1", CMD_ENDSECTION1, 0 }, // ### don't document for now
- { "endsection2", CMD_ENDSECTION2, 0 }, // ### don't document for now
- { "endsection3", CMD_ENDSECTION3, 0 }, // ### don't document for now
- { "endsection4", CMD_ENDSECTION4, 0 }, // ### don't document for now
- { "endsidebar", CMD_ENDSIDEBAR, 0 },
- { "endtable", CMD_ENDTABLE, 0 },
- { "endtopicref", CMD_ENDTOPICREF, 0 },
- { "footnote", CMD_FOOTNOTE, 0 },
- { "generatelist", CMD_GENERATELIST, 0 },
- { "granularity", CMD_GRANULARITY, 0 }, // ### don't document for now
- { "header", CMD_HEADER, 0 },
- { "hr", CMD_HR, 0 },
- { "i", CMD_I, 0 },
- { "if", CMD_IF, 0 },
- { "image", CMD_IMAGE, 0 },
- { "important", CMD_IMPORTANT, 0 },
- { "include", CMD_INCLUDE, 0 },
- { "inlineimage", CMD_INLINEIMAGE, 0 },
- { "index", CMD_INDEX, 0 }, // ### don't document for now
- { "input", CMD_INPUT, 0 },
- { "keyword", CMD_KEYWORD, 0 },
- { "l", CMD_L, 0 },
- { "legalese", CMD_LEGALESE, 0 },
- { "li", CMD_LI, 0 },
- { "link", CMD_LINK, 0 },
- { "list", CMD_LIST, 0 },
- { "mapref", CMD_MAPREF, 0 },
- { "meta", CMD_META, 0 },
- { "newcode", CMD_NEWCODE, 0 },
- { "note", CMD_NOTE, 0 },
- { "o", CMD_O, 0 },
- { "oldcode", CMD_OLDCODE, 0 },
- { "omit", CMD_OMIT, 0 },
- { "omitvalue", CMD_OMITVALUE, 0 },
- { "overload", CMD_OVERLOAD, 0 },
- { "part", CMD_PART, 0 },
- { "printline", CMD_PRINTLINE, 0 },
- { "printto", CMD_PRINTTO, 0 },
- { "printuntil", CMD_PRINTUNTIL, 0 },
- { "quotation", CMD_QUOTATION, 0 },
- { "quotefile", CMD_QUOTEFILE, 0 },
- { "quotefromfile", CMD_QUOTEFROMFILE, 0 },
- { "quotefunction", CMD_QUOTEFUNCTION, 0 },
- { "raw", CMD_RAW, 0 },
- { "row", CMD_ROW, 0 },
- { "sa", CMD_SA, 0 },
- { "section1", CMD_SECTION1, 0 },
- { "section2", CMD_SECTION2, 0 },
- { "section3", CMD_SECTION3, 0 },
- { "section4", CMD_SECTION4, 0 },
- { "sidebar", CMD_SIDEBAR, 0 },
- { "sincelist", CMD_SINCELIST, 0 },
- { "skipline", CMD_SKIPLINE, 0 },
- { "skipto", CMD_SKIPTO, 0 },
- { "skipuntil", CMD_SKIPUNTIL, 0 },
- { "snippet", CMD_SNIPPET, 0 },
- { "span", CMD_SPAN, 0 },
- { "sub", CMD_SUB, 0 },
- { "sup", CMD_SUP, 0 },
- { "table", CMD_TABLE, 0 },
- { "tableofcontents", CMD_TABLEOFCONTENTS, 0 },
- { "target", CMD_TARGET, 0 },
- { "topicref", CMD_TOPICREF, 0 },
- { "tt", CMD_TT, 0 },
- { "uicontrol", CMD_UICONTROL, 0 },
- { "underline", CMD_UNDERLINE, 0 },
- { "unicode", CMD_UNICODE, 0 },
- { "value", CMD_VALUE, 0 },
- { "warning", CMD_WARNING, 0 },
- { "qml", CMD_QML, 0 },
- { "endqml", CMD_ENDQML, 0 },
- { "cpp", CMD_CPP, 0 },
- { "endcpp", CMD_ENDCPP, 0 },
- { "qmltext", CMD_QMLTEXT, 0 },
- { "endqmltext", CMD_ENDQMLTEXT, 0 },
- { "cpptext", CMD_CPPTEXT, 0 },
- { "endcpptext", CMD_ENDCPPTEXT, 0 },
- { "js", CMD_JS, 0 },
- { "endjs", CMD_ENDJS, 0 },
- { 0, 0, 0 }
-};
-
-typedef QHash<QString, int> QHash_QString_int;
-typedef QHash<QString, Macro> QHash_QString_Macro;
-
-Q_GLOBAL_STATIC(QStringMap, aliasMap)
-Q_GLOBAL_STATIC(QHash_QString_int, cmdHash)
-Q_GLOBAL_STATIC(QHash_QString_Macro, macroHash)
-
-class DocPrivateExtra
-{
-public:
- Doc::Sections granularity_;
- Doc::Sections section_; // ###
- QList<Atom*> tableOfContents_;
- QVector<int> tableOfContentsLevels_;
- QList<Atom*> keywords_;
- QList<Atom*> targets_;
- QStringMultiMap metaMap_;
-
- DocPrivateExtra()
- : granularity_(Doc::Part)
- , section_(Doc::NoSection)
- { }
-};
-
-struct Shared // ### get rid of
-{
- Shared()
- : count(1) { }
- void ref() { ++count; }
- bool deref() { return (--count == 0); }
-
- int count;
-};
-
-static QString cleanLink(const QString &link)
-{
- int colonPos = link.indexOf(':');
- if ((colonPos == -1) ||
- (!link.startsWith("file:") && !link.startsWith("mailto:")))
- return link;
- return link.mid(colonPos + 1).simplified();
-}
-
-typedef QMap<QString, ArgList> CommandMap;
-
-class DocPrivate : public Shared
-{
-public:
- DocPrivate(const Location& start = Location::null,
- const Location& end = Location::null,
- const QString& source = QString());
- ~DocPrivate();
-
- void addAlso(const Text& also);
- void constructExtra();
- bool isEnumDocSimplifiable() const;
-
- // ### move some of this in DocPrivateExtra
- Location start_loc;
- Location end_loc;
- QString src;
- Text text;
- QSet<QString> params;
- QList<Text> alsoList;
- QStringList enumItemList;
- QStringList omitEnumItemList;
- QSet<QString> metacommandsUsed;
- CommandMap metaCommandMap;
- bool hasLegalese : 1;
- bool hasSectioningUnits : 1;
- DocPrivateExtra *extra;
- TopicList topics_;
- DitaRefList ditamap_;
-};
-
-DocPrivate::DocPrivate(const Location& start,
- const Location& end,
- const QString& source)
- : start_loc(start),
- end_loc(end),
- src(source),
- hasLegalese(false),
- hasSectioningUnits(false),
- extra(0)
-{
- // nothing.
-}
-
-/*!
- If the doc is a ditamap, the destructor deletes each element
- in the ditamap structure. These were allocated as needed.
- */
-DocPrivate::~DocPrivate()
-{
- delete extra;
- foreach (DitaRef* t, ditamap_) {
- delete t;
- }
-}
-
-void DocPrivate::addAlso(const Text& also)
-{
- alsoList.append(also);
-}
-
-void DocPrivate::constructExtra()
-{
- if (extra == 0)
- extra = new DocPrivateExtra;
-}
-
-bool DocPrivate::isEnumDocSimplifiable() const
-{
- bool justMetColon = false;
- int numValueTables = 0;
-
- const Atom *atom = text.firstAtom();
- while (atom) {
- if (atom->type() == Atom::AutoLink || atom->type() == Atom::String) {
- justMetColon = atom->string().endsWith(QLatin1Char(':'));
- }
- else if ((atom->type() == Atom::ListLeft) &&
- (atom->string() == ATOM_LIST_VALUE)) {
- if (justMetColon || numValueTables > 0)
- return false;
- ++numValueTables;
- }
- atom = atom->next();
- }
- return true;
-}
-
-class DocParser
-{
- Q_DECLARE_TR_FUNCTIONS(QDoc::DocParser)
-
-public:
- void parse(const QString &source,
- DocPrivate *docPrivate,
- const QSet<QString> &metaCommandSet,
- const QSet<QString>& possibleTopics);
-
- static int endCmdFor(int cmd);
- static QString cmdName(int cmd);
- static QString endCmdName(int cmd);
- static QString untabifyEtc(const QString& str);
- static int indentLevel(const QString& str);
- static QString unindent(int level, const QString& str);
- static QString slashed(const QString& str);
-
- static int tabSize;
- static QStringList exampleFiles;
- static QStringList exampleDirs;
- static QStringList sourceFiles;
- static QStringList sourceDirs;
- static bool quoting;
-
-private:
- Location& location();
- QString detailsUnknownCommand(const QSet<QString>& metaCommandSet,
- const QString& str);
- void insertTarget(const QString& target, bool keyword);
- void include(const QString& fileName, const QString& identifier);
- void startFormat(const QString& format, int cmd);
- bool openCommand(int cmd);
- bool closeCommand(int endCmd);
- void startSection(Doc::Sections unit, int cmd);
- void endSection(int unit, int endCmd);
- void parseAlso();
- void append(const QString &string);
- void append(Atom::AtomType type, const QString& string = QString());
- void append(Atom::AtomType type, const QString& p1, const QString& p2);
- void append(const QString& p1, const QString& p2);
- void appendChar(QChar ch);
- void appendWord(const QString &word);
- void appendToCode(const QString &code);
- void appendToCode(const QString &code, Atom::AtomType defaultType);
- void startNewPara();
- void enterPara(Atom::AtomType leftType = Atom::ParaLeft,
- Atom::AtomType rightType = Atom::ParaRight,
- const QString& string = QString());
- void leavePara();
- void leaveValue();
- void leaveValueList();
- void leaveTableRow();
- CodeMarker *quoteFromFile();
- void expandMacro(const QString& name, const QString& def, int numParams);
- QString expandMacroToString(const QString &name, const QString &def, int numParams);
- Doc::Sections getSectioningUnit();
- QString getArgument(bool verbatim = false);
- QString getBracedArgument(bool verbatim);
- QString getBracketedArgument();
- QString getOptionalArgument();
- QString getRestOfLine();
- QString getMetaCommandArgument(const QString &cmdStr);
- QString getUntilEnd(int cmd);
- QString getCode(int cmd, CodeMarker *marker);
- QString getUnmarkedCode(int cmd);
-
- bool isBlankLine();
- bool isLeftBraceAhead();
- bool isLeftBracketAhead();
- void skipSpacesOnLine();
- void skipSpacesOrOneEndl();
- void skipAllSpaces();
- void skipToNextPreprocessorCommand();
-
- QStack<int> openedInputs;
-
- QString in;
- int pos;
- int len;
- Location cachedLoc;
- int cachedPos;
-
- DocPrivate* priv;
- enum ParagraphState {
- OutsideParagraph,
- InSingleLineParagraph,
- InMultiLineParagraph
- };
- ParagraphState paraState;
- bool inTableHeader;
- bool inTableRow;
- bool inTableItem;
- bool indexStartedPara; // ### rename
- Atom::AtomType pendingParaLeftType;
- Atom::AtomType pendingParaRightType;
- QString pendingParaString;
-
- int braceDepth;
- int minIndent;
- Doc::Sections currentSection;
- QMap<QString, Location> targetMap_;
- QMap<int, QString> pendingFormats;
- QStack<int> openedCommands;
- QStack<OpenedList> openedLists;
- Quoter quoter;
- QStack<DitaRef*> ditarefs_;
-};
-
-int DocParser::tabSize;
-QStringList DocParser::exampleFiles;
-QStringList DocParser::exampleDirs;
-QStringList DocParser::sourceFiles;
-QStringList DocParser::sourceDirs;
-bool DocParser::quoting;
-
-/*!
- Parse the \a source string to build a Text data structure
- in \a docPrivate. The Text data structure is a linked list
- of Atoms.
-
- \a metaCommandSet is the set of metacommands that may be
- found in \a source. These metacommands are not markup text
- commands. They are topic commands and related metacommands.
- */
-void DocParser::parse(const QString& source,
- DocPrivate *docPrivate,
- const QSet<QString>& metaCommandSet,
- const QSet<QString>& possibleTopics)
-{
- in = source;
- pos = 0;
- len = in.length();
- cachedLoc = docPrivate->start_loc;
- cachedPos = 0;
- priv = docPrivate;
- priv->text << Atom::Nop;
- priv->topics_.clear();
-
- paraState = OutsideParagraph;
- inTableHeader = false;
- inTableRow = false;
- inTableItem = false;
- indexStartedPara = false;
- pendingParaLeftType = Atom::Nop;
- pendingParaRightType = Atom::Nop;
-
- braceDepth = 0;
- minIndent = INT_MAX;
- currentSection = Doc::NoSection;
- openedCommands.push(CMD_OMIT);
- quoter.reset();
-
- CodeMarker *marker = 0;
- Atom *currentLinkAtom = 0;
- QString p1, p2;
- QStack<bool> preprocessorSkipping;
- int numPreprocessorSkipping = 0;
-
- while (pos < len) {
- QChar ch = in.at(pos);
-
- switch (ch.unicode()) {
- case '\\':
- {
- QString cmdStr;
- pos++;
- while (pos < len) {
- ch = in.at(pos);
- if (ch.isLetterOrNumber()) {
- cmdStr += ch;
- pos++;
- }
- else {
- break;
- }
- }
- if (cmdStr.isEmpty()) {
- if (pos < len) {
- enterPara();
- if (in.at(pos).isSpace()) {
- skipAllSpaces();
- appendChar(QLatin1Char(' '));
- }
- else {
- appendChar(in.at(pos++));
- }
- }
- }
- else {
- int cmd = cmdHash()->value(cmdStr,NOT_A_CMD);
- switch (cmd) {
- case CMD_A:
- enterPara();
- p1 = getArgument();
- append(Atom::FormattingLeft,ATOM_FORMATTING_PARAMETER);
- append(Atom::String, p1);
- append(Atom::FormattingRight,ATOM_FORMATTING_PARAMETER);
- priv->params.insert(p1);
- break;
- case CMD_BADCODE:
- leavePara();
- append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
- break;
- case CMD_BR:
- enterPara();
- append(Atom::BR);
- break;
- case CMD_BOLD:
- location().warning(tr("'\\bold' is deprecated. Use '\\b'"));
- case CMD_B:
- startFormat(ATOM_FORMATTING_BOLD, cmd);
- break;
- case CMD_BRIEF:
- leavePara();
- enterPara(Atom::BriefLeft, Atom::BriefRight);
- break;
- case CMD_C:
- enterPara();
- p1 = untabifyEtc(getArgument(true));
- marker = CodeMarker::markerForCode(p1);
- append(Atom::C, marker->markedUpCode(p1, 0, location()));
- break;
- case CMD_CAPTION:
- leavePara();
- enterPara(Atom::CaptionLeft, Atom::CaptionRight);
- break;
- case CMD_CHAPTER:
- startSection(Doc::Chapter, cmd);
- break;
- case CMD_CODE:
- leavePara();
- append(Atom::Code, getCode(CMD_CODE, 0));
- break;
- case CMD_QML:
- leavePara();
- append(Atom::Qml, getCode(CMD_QML, CodeMarker::markerForLanguage(QLatin1String("QML"))));
- break;
- case CMD_QMLTEXT:
- append(Atom::QmlText);
- break;
- case CMD_JS:
- leavePara();
- append(Atom::JavaScript, getCode(CMD_JS, CodeMarker::markerForLanguage(QLatin1String("JavaScript"))));
- break;
- case CMD_DIV:
- leavePara();
- p1 = getArgument(true);
- append(Atom::DivLeft, p1);
- openedCommands.push(cmd);
- break;
- case CMD_ENDDIV:
- leavePara();
- append(Atom::DivRight);
- closeCommand(cmd);
- break;
- case CMD_CODELINE:
- {
- if (!quoting) {
- if (priv->text.lastAtom()->type() == Atom::Code
- && priv->text.lastAtom()->string().endsWith("\n\n"))
- priv->text.lastAtom()->chopString();
- appendToCode("\n");
- }
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, " ");
- }
- }
- break;
- case CMD_DOTS:
- {
- if (!quoting) {
- if (priv->text.lastAtom()->type() == Atom::Code
- && priv->text.lastAtom()->string().endsWith("\n\n"))
- priv->text.lastAtom()->chopString();
-
- QString arg = getOptionalArgument();
- int indent = 4;
- if (!arg.isEmpty())
- indent = arg.toInt();
- for (int i = 0; i < indent; ++i)
- appendToCode(" ");
- appendToCode("...\n");
- }
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- QString arg = getOptionalArgument();
- if (arg.isEmpty())
- arg = "4";
- append(Atom::CodeQuoteArgument, arg);
- }
- }
- break;
- case CMD_ELSE:
- if (preprocessorSkipping.size() > 0) {
- if (preprocessorSkipping.top()) {
- --numPreprocessorSkipping;
- }
- else {
- ++numPreprocessorSkipping;
- }
- preprocessorSkipping.top() = !preprocessorSkipping.top();
- (void)getRestOfLine(); // ### should ensure that it's empty
- if (numPreprocessorSkipping)
- skipToNextPreprocessorCommand();
- }
- else {
- location().warning(tr("Unexpected '\\%1'").arg(cmdName(CMD_ELSE)));
- }
- break;
- case CMD_ENDCHAPTER:
- endSection(Doc::Chapter, cmd);
- break;
- case CMD_ENDCODE:
- closeCommand(cmd);
- break;
- case CMD_ENDQML:
- closeCommand(cmd);
- break;
- case CMD_ENDQMLTEXT:
- append(Atom::EndQmlText);
- break;
- case CMD_ENDJS:
- closeCommand(cmd);
- break;
- case CMD_ENDFOOTNOTE:
- if (closeCommand(cmd)) {
- leavePara();
- append(Atom::FootnoteRight);
- paraState = InMultiLineParagraph; // ###
- }
- break;
- case CMD_ENDIF:
- if (preprocessorSkipping.count() > 0) {
- if (preprocessorSkipping.pop())
- --numPreprocessorSkipping;
- (void)getRestOfLine(); // ### should ensure that it's empty
- if (numPreprocessorSkipping)
- skipToNextPreprocessorCommand();
- }
- else {
- location().warning(tr("Unexpected '\\%1'").arg(cmdName(CMD_ENDIF)));
- }
- break;
- case CMD_ENDLEGALESE:
- if (closeCommand(cmd)) {
- leavePara();
- append(Atom::LegaleseRight);
- }
- break;
- case CMD_ENDLINK:
- if (closeCommand(cmd)) {
- if (priv->text.lastAtom()->type() == Atom::String
- && priv->text.lastAtom()->string().endsWith(QLatin1Char(' ')))
- priv->text.lastAtom()->chopString();
- append(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- }
- break;
- case CMD_ENDLIST:
- if (closeCommand(cmd)) {
- leavePara();
- if (openedLists.top().isStarted()) {
- append(Atom::ListItemRight,
- openedLists.top().styleString());
- append(Atom::ListRight,
- openedLists.top().styleString());
- }
- openedLists.pop();
- }
- break;
- case CMD_ENDMAPREF:
- case CMD_ENDTOPICREF:
- if (closeCommand(cmd)) {
- ditarefs_.pop(); // zzz
- }
- break;
- case CMD_ENDOMIT:
- closeCommand(cmd);
- break;
- case CMD_ENDPART:
- endSection(Doc::Part, cmd);
- break;
- case CMD_ENDQUOTATION:
- if (closeCommand(cmd)) {
- leavePara();
- append(Atom::QuotationRight);
- }
- break;
- case CMD_ENDRAW:
- location().warning(tr("Unexpected '\\%1'").arg(cmdName(CMD_ENDRAW)));
- break;
- case CMD_ENDSECTION1:
- endSection(Doc::Section1, cmd);
- break;
- case CMD_ENDSECTION2:
- endSection(Doc::Section2, cmd);
- break;
- case CMD_ENDSECTION3:
- endSection(Doc::Section3, cmd);
- break;
- case CMD_ENDSECTION4:
- endSection(Doc::Section4, cmd);
- break;
- case CMD_ENDSIDEBAR:
- if (closeCommand(cmd)) {
- leavePara();
- append(Atom::SidebarRight);
- }
- break;
- case CMD_ENDTABLE:
- if (closeCommand(cmd)) {
- leaveTableRow();
- append(Atom::TableRight);
- }
- break;
- case CMD_FOOTNOTE:
- if (openCommand(cmd)) {
- enterPara();
- append(Atom::FootnoteLeft);
- paraState = OutsideParagraph; // ###
- }
- break;
- case CMD_ANNOTATEDLIST:
- append(Atom::AnnotatedList, getArgument());
- break;
- case CMD_SINCELIST:
- append(Atom::SinceList, getRestOfLine().simplified());
- break;
- case CMD_GENERATELIST:
- {
- QString arg1 = getArgument();
- QString arg2 = getOptionalArgument();
- if (!arg2.isEmpty())
- arg1 += " " + arg2;
- append(Atom::GeneratedList, arg1);
- }
- break;
- case CMD_GRANULARITY:
- priv->constructExtra();
- priv->extra->granularity_ = getSectioningUnit();
- break;
- case CMD_HEADER:
- if (openedCommands.top() == CMD_TABLE) {
- leaveTableRow();
- append(Atom::TableHeaderLeft);
- inTableHeader = true;
- }
- else {
- if (openedCommands.contains(CMD_TABLE)) {
- location().warning(tr("Cannot use '\\%1' within '\\%2'")
- .arg(cmdName(CMD_HEADER))
- .arg(cmdName(openedCommands.top())));
- }
- else {
- location().warning(tr("Cannot use '\\%1' outside of '\\%2'")
- .arg(cmdName(CMD_HEADER))
- .arg(cmdName(CMD_TABLE)));
- }
- }
- break;
- case CMD_I:
- location().warning(tr("'\\i' is deprecated. Use '\\e' for italic or '\\li' for list item"));
- case CMD_E:
- startFormat(ATOM_FORMATTING_ITALIC, cmd);
- break;
- case CMD_HR:
- leavePara();
- append(Atom::HR);
- break;
- case CMD_IF:
- preprocessorSkipping.push(!Tokenizer::isTrue(getRestOfLine()));
- if (preprocessorSkipping.top())
- ++numPreprocessorSkipping;
- if (numPreprocessorSkipping)
- skipToNextPreprocessorCommand();
- break;
- case CMD_IMAGE:
- leaveValueList();
- append(Atom::Image, getArgument());
- append(Atom::ImageText, getRestOfLine());
- break;
- case CMD_IMPORTANT:
- leavePara();
- enterPara(Atom::ImportantLeft, Atom::ImportantRight);
- break;
- case CMD_INCLUDE:
- case CMD_INPUT:
- {
- QString fileName = getArgument();
- QString identifier = getRestOfLine();
- include(fileName, identifier);
- }
- break;
- case CMD_INLINEIMAGE:
- enterPara();
- append(Atom::InlineImage, getArgument());
- append(Atom::ImageText, getRestOfLine());
- append(Atom::String, " ");
- break;
- case CMD_INDEX:
- if (paraState == OutsideParagraph) {
- enterPara();
- indexStartedPara = true;
- }
- else {
- const Atom *last = priv->text.lastAtom();
- if (indexStartedPara &&
- (last->type() != Atom::FormattingRight ||
- last->string() != ATOM_FORMATTING_INDEX))
- indexStartedPara = false;
- }
- startFormat(ATOM_FORMATTING_INDEX, cmd);
- break;
- case CMD_KEYWORD:
- insertTarget(getRestOfLine(),true);
- break;
- case CMD_L:
- enterPara();
- if (isLeftBracketAhead()) {
- p2 = getBracketedArgument();
- }
- if (isLeftBraceAhead()) {
- p1 = getArgument();
- append(p1, p2);
- if (!p2.isEmpty() && !(priv->text.lastAtom()->error().isEmpty())) {
- location().warning(tr("Check parameter in '[ ]' of '\\l' command: '%1', "
- "possible misspelling, or unrecognized module name")
- .arg(priv->text.lastAtom()->error()));
- }
- if (isLeftBraceAhead()) {
- currentLinkAtom = priv->text.lastAtom();
- startFormat(ATOM_FORMATTING_LINK, cmd);
- }
- else {
- append(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
- append(Atom::String, cleanLink(p1));
- append(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- }
- }
- else {
- p1 = getArgument();
- append(p1, p2);
- if (!p2.isEmpty() && !(priv->text.lastAtom()->error().isEmpty())) {
- location().warning(tr("Check parameter in '[ ]' of '\\l' command: '%1', "
- "possible misspelling, or unrecognized module name")
- .arg(priv->text.lastAtom()->error()));
- }
- append(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
- append(Atom::String, cleanLink(p1));
- append(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- }
- p2.clear();
- break;
- case CMD_LEGALESE:
- leavePara();
- if (openCommand(cmd))
- append(Atom::LegaleseLeft);
- docPrivate->hasLegalese = true;
- break;
- case CMD_LINK:
- if (openCommand(cmd)) {
- enterPara();
- p1 = getArgument();
- append(p1);
- append(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
- skipSpacesOrOneEndl();
- }
- break;
- case CMD_LIST:
- if (openCommand(cmd)) {
- leavePara();
- openedLists.push(OpenedList(location(),
- getOptionalArgument()));
- }
- break;
- case CMD_TOPICREF:
- case CMD_MAPREF:
- if (openCommand(cmd)) {
- DitaRef* t = 0;
- if (cmd == CMD_MAPREF)
- t = new MapRef();
- else
- t = new TopicRef();
- t->setNavtitle(getArgument(true));
- if (cmd == CMD_MAPREF)
- t->setHref(getArgument());
- else
- t->setHref(getOptionalArgument());
- if (ditarefs_.isEmpty())
- priv->ditamap_.append(t);
- else
- ditarefs_.top()->appendSubref(t);
- ditarefs_.push(t);
- }
- break;
- case CMD_META:
- priv->constructExtra();
- p1 = getArgument();
- priv->extra->metaMap_.insert(p1, getArgument());
- break;
- case CMD_NEWCODE:
- location().warning(tr("Unexpected '\\%1'").arg(cmdName(CMD_NEWCODE)));
- break;
- case CMD_NOTE:
- leavePara();
- enterPara(Atom::NoteLeft, Atom::NoteRight);
- break;
- case CMD_O:
- location().warning(tr("'\\o' is deprecated. Use '\\li'"));
- case CMD_LI:
- leavePara();
- if (openedCommands.top() == CMD_LIST) {
- if (openedLists.top().isStarted()) {
- append(Atom::ListItemRight,
- openedLists.top().styleString());
- }
- else {
- append(Atom::ListLeft,
- openedLists.top().styleString());
- }
- openedLists.top().next();
- append(Atom::ListItemNumber,
- openedLists.top().numberString());
- append(Atom::ListItemLeft,
- openedLists.top().styleString());
- enterPara();
- }
- else if (openedCommands.top() == CMD_TABLE) {
- p1 = "1,1";
- p2.clear();
- if (isLeftBraceAhead()) {
- p1 = getArgument();
- if (isLeftBraceAhead()) {
- p2 = getArgument();
- }
- }
-
- if (!inTableHeader && !inTableRow) {
- location().warning(tr("Missing '\\%1' or '\\%2' before '\\%3'")
- .arg(cmdName(CMD_HEADER))
- .arg(cmdName(CMD_ROW))
- .arg(cmdName(CMD_LI)));
- append(Atom::TableRowLeft);
- inTableRow = true;
- }
- else if (inTableItem) {
- append(Atom::TableItemRight);
- inTableItem = false;
- }
-
- append(Atom::TableItemLeft, p1, p2);
- inTableItem = true;
- }
- else {
- location().warning(tr("Command '\\%1' outside of '\\%2' and '\\%3'")
- .arg(cmdName(cmd))
- .arg(cmdName(CMD_LIST))
- .arg(cmdName(CMD_TABLE)));
- }
- break;
- case CMD_OLDCODE:
- leavePara();
- append(Atom::CodeOld, getCode(CMD_OLDCODE, marker));
- append(Atom::CodeNew, getCode(CMD_NEWCODE, marker));
- break;
- case CMD_OMIT:
- getUntilEnd(cmd);
- break;
- case CMD_OMITVALUE:
- p1 = getArgument();
- if (!priv->enumItemList.contains(p1))
- priv->enumItemList.append(p1);
- if (!priv->omitEnumItemList.contains(p1))
- priv->omitEnumItemList.append(p1);
- break;
- case CMD_PART:
- startSection(Doc::Part, cmd);
- break;
- case CMD_PRINTLINE:
- leavePara();
- if (!quoting)
- appendToCode(quoter.quoteLine(location(), cmdStr,
- getRestOfLine()));
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, getRestOfLine());
- }
- break;
- case CMD_PRINTTO:
- leavePara();
- if (!quoting)
- appendToCode(quoter.quoteTo(location(), cmdStr,
- getRestOfLine()));
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, getRestOfLine());
- }
- break;
- case CMD_PRINTUNTIL:
- leavePara();
- if (!quoting)
- appendToCode(quoter.quoteUntil(location(), cmdStr,
- getRestOfLine()));
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, getRestOfLine());
- }
- break;
- case CMD_QUOTATION:
- if (openCommand(cmd)) {
- leavePara();
- append(Atom::QuotationLeft);
- }
- break;
- case CMD_QUOTEFILE:
- {
- leavePara();
- QString fileName = getArgument();
- Doc::quoteFromFile(location(), quoter, fileName);
- if (!quoting) {
- append(Atom::Code,
- quoter.quoteTo(location(), cmdStr, QString()));
- quoter.reset();
- }
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, fileName);
- }
- break;
- }
- case CMD_QUOTEFROMFILE:
- leavePara();
- if (!quoting)
- quoteFromFile();
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, getArgument());
- }
- break;
- case CMD_QUOTEFUNCTION:
- leavePara();
- marker = quoteFromFile();
- p1 = getRestOfLine();
- if (!quoting) {
- quoter.quoteTo(location(), cmdStr,
- slashed(marker->functionBeginRegExp(p1)));
- append(Atom::Code,
- quoter.quoteUntil(location(), cmdStr,
- slashed(marker->functionEndRegExp(p1))));
- quoter.reset();
- }
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, slashed(marker->functionEndRegExp(p1)));
- }
- break;
- case CMD_RAW:
- leavePara();
- p1 = getRestOfLine();
- if (p1.isEmpty())
- location().warning(tr("Missing format name after '\\%1'")
- .arg(cmdName(CMD_RAW)));
- append(Atom::FormatIf, p1);
- append(Atom::RawString, untabifyEtc(getUntilEnd(cmd)));
- append(Atom::FormatElse);
- append(Atom::FormatEndif);
- break;
- case CMD_ROW:
- if (openedCommands.top() == CMD_TABLE) {
- p1.clear();
- if (isLeftBraceAhead())
- p1 = getArgument(true);
- leaveTableRow();
- append(Atom::TableRowLeft,p1);
- inTableRow = true;
- }
- else {
- if (openedCommands.contains(CMD_TABLE)) {
- location().warning(tr("Cannot use '\\%1' within '\\%2'")
- .arg(cmdName(CMD_ROW))
- .arg(cmdName(openedCommands.top())));
- }
- else {
- location().warning(tr("Cannot use '\\%1' outside of '\\%2'")
- .arg(cmdName(CMD_ROW))
- .arg(cmdName(CMD_TABLE)));
- }
- }
- break;
- case CMD_SA:
- parseAlso();
- break;
- case CMD_SECTION1:
- startSection(Doc::Section1, cmd);
- break;
- case CMD_SECTION2:
- startSection(Doc::Section2, cmd);
- break;
- case CMD_SECTION3:
- startSection(Doc::Section3, cmd);
- break;
- case CMD_SECTION4:
- startSection(Doc::Section4, cmd);
- break;
- case CMD_SIDEBAR:
- if (openCommand(cmd)) {
- leavePara();
- append(Atom::SidebarLeft);
- }
- break;
- case CMD_SKIPLINE:
- leavePara();
- if (!quoting)
- quoter.quoteLine(location(),
- cmdStr,
- getRestOfLine());
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, getRestOfLine());
- }
- break;
- case CMD_SKIPTO:
- leavePara();
- if (!quoting)
- quoter.quoteTo(location(),
- cmdStr,
- getRestOfLine());
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, getRestOfLine());
- }
- break;
- case CMD_SKIPUNTIL:
- leavePara();
- if (!quoting)
- quoter.quoteUntil(location(),
- cmdStr,
- getRestOfLine());
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, getRestOfLine());
- }
- break;
- case CMD_SPAN:
- p1 = ATOM_FORMATTING_SPAN + getArgument(true);
- startFormat(p1, cmd);
- break;
- case CMD_SNIPPET:
- leavePara();
- {
- QString snippet = getArgument();
- QString identifier = getRestOfLine();
- if (quoting) {
- append(Atom::SnippetCommand, cmdStr);
- append(Atom::SnippetLocation, snippet);
- append(Atom::SnippetIdentifier, identifier);
- }
- else {
- marker = Doc::quoteFromFile(location(),quoter,snippet);
- appendToCode(quoter.quoteSnippet(location(), identifier), marker->atomType());
- }
- }
- break;
- case CMD_SUB:
- startFormat(ATOM_FORMATTING_SUBSCRIPT, cmd);
- break;
- case CMD_SUP:
- startFormat(ATOM_FORMATTING_SUPERSCRIPT, cmd);
- break;
- case CMD_TABLE:
- //p1 = getRestOfLine();
- p1 = getOptionalArgument();
- p2 = getOptionalArgument();
- if (openCommand(cmd)) {
- leavePara();
- append(Atom::TableLeft, p1, p2);
- inTableHeader = false;
- inTableRow = false;
- inTableItem = false;
- }
- break;
- case CMD_TABLEOFCONTENTS:
- p1 = "1";
- if (isLeftBraceAhead())
- p1 = getArgument();
- p1 += QLatin1Char(',');
- p1 += QString::number((int)getSectioningUnit());
- append(Atom::TableOfContents, p1);
- break;
- case CMD_TARGET:
- insertTarget(getRestOfLine(),false);
- break;
- case CMD_TT:
- startFormat(ATOM_FORMATTING_TELETYPE, cmd);
- break;
- case CMD_UICONTROL:
- startFormat(ATOM_FORMATTING_UICONTROL, cmd);
- break;
- case CMD_UNDERLINE:
- startFormat(ATOM_FORMATTING_UNDERLINE, cmd);
- break;
- case CMD_UNICODE:
- enterPara();
- p1 = getArgument();
- {
- bool ok;
- uint unicodeChar = p1.toUInt(&ok, 0);
- if (!ok ||
- (unicodeChar == 0x0000) ||
- (unicodeChar > 0xFFFE)) {
- location().warning(tr("Invalid Unicode character '%1' specified "
- "with '%2'")
- .arg(p1, cmdName(CMD_UNICODE)));
- }
- else {
- append(Atom::String, QChar(unicodeChar));
- }
- }
- break;
- case CMD_VALUE:
- leaveValue();
- if (openedLists.top().style() == OpenedList::Value) {
- p1 = getArgument();
- if (!priv->enumItemList.contains(p1))
- priv->enumItemList.append(p1);
-
- openedLists.top().next();
- append(Atom::ListTagLeft, ATOM_LIST_VALUE);
- append(Atom::String, p1);
- append(Atom::ListTagRight, ATOM_LIST_VALUE);
- append(Atom::ListItemLeft, ATOM_LIST_VALUE);
-
- skipSpacesOrOneEndl();
- if (isBlankLine())
- append(Atom::Nop);
- }
- else {
- // ### problems
- }
- break;
- case CMD_WARNING:
- leavePara();
- enterPara();
- append(Atom::FormattingLeft, ATOM_FORMATTING_BOLD);
- append(Atom::String, "Warning:");
- append(Atom::FormattingRight, ATOM_FORMATTING_BOLD);
- append(Atom::String, " ");
- break;
- case CMD_OVERLOAD:
- priv->metacommandsUsed.insert(cmdStr);
- p1.clear();
- if (!isBlankLine())
- p1 = getRestOfLine();
- if (!p1.isEmpty()) {
- append(Atom::ParaLeft);
- append(Atom::String, "This function overloads ");
- append(Atom::AutoLink,p1);
- append(Atom::String, ".");
- append(Atom::ParaRight);
- }
- else {
- append(Atom::ParaLeft);
- append(Atom::String,"This is an overloaded function.");
- append(Atom::ParaRight);
- p1 = getMetaCommandArgument(cmdStr);
- }
- priv->metaCommandMap[cmdStr].append(ArgLocPair(p1,location()));
- break;
- case NOT_A_CMD:
- if (metaCommandSet.contains(cmdStr)) {
- priv->metacommandsUsed.insert(cmdStr);
- QString arg = getMetaCommandArgument(cmdStr);
- priv->metaCommandMap[cmdStr].append(ArgLocPair(arg,location()));
- if (possibleTopics.contains(cmdStr)) {
- priv->topics_.append(Topic(cmdStr,arg));
- }
- }
- else if (macroHash()->contains(cmdStr)) {
- const Macro &macro = macroHash()->value(cmdStr);
- int numPendingFi = 0;
- QStringMap::ConstIterator d;
- d = macro.otherDefs.constBegin();
- while (d != macro.otherDefs.constEnd()) {
- append(Atom::FormatIf, d.key());
- expandMacro(cmdStr, *d, macro.numParams);
- ++d;
-
- if (d == macro.otherDefs.constEnd()) {
- append(Atom::FormatEndif);
- }
- else {
- append(Atom::FormatElse);
- numPendingFi++;
- }
- }
- while (numPendingFi-- > 0)
- append(Atom::FormatEndif);
-
- if (!macro.defaultDef.isEmpty()) {
- if (!macro.otherDefs.isEmpty()) {
- macro.defaultDefLocation.warning(
- tr("Macro cannot have both "
- "format-specific and qdoc- "
- "syntax definitions"));
- }
- else {
- location().push(macro.defaultDefLocation.filePath());
- in.insert(pos, expandMacroToString(cmdStr, macro.defaultDef, macro.numParams));
- len = in.length();
- openedInputs.push(pos + macro.defaultDef.length());
- }
- }
- }
- else {
- location().warning(
- tr("Unknown command '\\%1'").arg(cmdStr),
- detailsUnknownCommand(metaCommandSet,cmdStr));
- enterPara();
- append(Atom::UnknownCommand, cmdStr);
- }
- }
- }
- }
- break;
- case '{':
- enterPara();
- appendChar('{');
- braceDepth++;
- pos++;
- break;
- case '}':
- {
- braceDepth--;
- pos++;
-
- QMap<int, QString>::Iterator f = pendingFormats.find(braceDepth);
- if (f == pendingFormats.end()) {
- enterPara();
- appendChar('}');
- }
- else {
- append(Atom::FormattingRight, *f);
- if (*f == ATOM_FORMATTING_INDEX) {
- if (indexStartedPara)
- skipAllSpaces();
- }
- else if (*f == ATOM_FORMATTING_LINK) {
- // hack for C++ to support links like
- // \l{QString::}{count()}
- if (currentLinkAtom &&
- currentLinkAtom->string().endsWith("::")) {
- QString suffix = Text::subText(currentLinkAtom,
- priv->text.lastAtom()).toString();
- currentLinkAtom->appendString(suffix);
- }
- currentLinkAtom = 0;
- }
- pendingFormats.erase(f);
- }
- }
- break;
- default:
- {
- bool newWord;
- switch (priv->text.lastAtom()->type()) {
- case Atom::ParaLeft:
- newWord = true;
- break;
- default:
- newWord = false;
- }
-
- if (paraState == OutsideParagraph) {
- if (ch.isSpace()) {
- ++pos;
- newWord = false;
- }
- else {
- enterPara();
- newWord = true;
- }
- }
- else {
- if (ch.isSpace()) {
- ++pos;
- if ((ch == '\n') &&
- (paraState == InSingleLineParagraph ||
- isBlankLine())) {
- leavePara();
- newWord = false;
- }
- else {
- appendChar(' ');
- newWord = true;
- }
- }
- else {
- newWord = true;
- }
- }
-
- if (newWord) {
- int startPos = pos;
- int numInternalUppercase = 0;
- int numLowercase = 0;
- int numStrangeSymbols = 0;
-
- while (pos < len) {
- unsigned char latin1Ch = in.at(pos).toLatin1();
- if (islower(latin1Ch)) {
- ++numLowercase;
- ++pos;
- }
- else if (isupper(latin1Ch)) {
- if (pos > startPos)
- ++numInternalUppercase;
- ++pos;
- }
- else if (isdigit(latin1Ch)) {
- if (pos > startPos) {
- ++pos;
- }
- else {
- break;
- }
- }
- else if (latin1Ch == '_' || latin1Ch == '@') {
- ++numStrangeSymbols;
- ++pos;
- }
- else if (latin1Ch == ':' && pos < len - 1
- && in.at(pos + 1) == QLatin1Char(':')) {
- ++numStrangeSymbols;
- pos += 2;
- }
- else if (latin1Ch == '(') {
- if (pos > startPos) {
- if (pos < len - 1 &&
- in.at(pos + 1) == QLatin1Char(')')) {
- ++numStrangeSymbols;
- pos += 2;
- break;
- }
- else {
- // ### handle functions with signatures
- // and function calls
- break;
- }
- }
- else {
- break;
- }
- }
- else {
- break;
- }
- }
-
- if (pos == startPos) {
- if (!ch.isSpace()) {
- appendChar(ch);
- ++pos;
- }
- }
- else {
- QString word = in.mid(startPos, pos - startPos);
- // is word a C++ symbol or an English word?
- if ((numInternalUppercase >= 1 && numLowercase >= 2)
- || numStrangeSymbols > 0) {
- if (word.startsWith(QString("__")))
- appendWord(word);
- else
- append(Atom::AutoLink, word);
- }
- else
- appendWord(word);
- }
- }
- }
- }
- }
- leaveValueList();
-
- // for compatibility
- if (openedCommands.top() == CMD_LEGALESE) {
- append(Atom::LegaleseRight);
- openedCommands.pop();
- }
-
- if (openedCommands.top() != CMD_OMIT) {
- location().warning(tr("Missing '\\%1'").arg(endCmdName(openedCommands.top())));
- }
- else if (preprocessorSkipping.count() > 0) {
- location().warning(tr("Missing '\\%1'").arg(cmdName(CMD_ENDIF)));
- }
-
- if (currentSection > Doc::NoSection) {
- append(Atom::SectionRight, QString::number(currentSection));
- currentSection = Doc::NoSection;
- }
-
- if (priv->extra && priv->extra->granularity_ < priv->extra->section_)
- priv->extra->granularity_ = priv->extra->section_;
- priv->text.stripFirstAtom();
-}
-
-/*!
- Returns the current location.
- */
-Location &DocParser::location()
-{
- while (!openedInputs.isEmpty() && openedInputs.top() <= pos) {
- cachedLoc.pop();
- cachedPos = openedInputs.pop();
- }
- while (cachedPos < pos)
- cachedLoc.advance(in.at(cachedPos++));
- return cachedLoc;
-}
-
-QString DocParser::detailsUnknownCommand(const QSet<QString> &metaCommandSet,
- const QString &str)
-{
- QSet<QString> commandSet = metaCommandSet;
- int i = 0;
- while (cmds[i].english != 0) {
- commandSet.insert(*cmds[i].alias);
- i++;
- }
-
- if (aliasMap()->contains(str))
- return tr("The command '\\%1' was renamed '\\%2' by the configuration"
- " file. Use the new name.")
- .arg(str).arg((*aliasMap())[str]);
-
- QString best = nearestName(str, commandSet);
- if (best.isEmpty())
- return QString();
- return tr("Maybe you meant '\\%1'?").arg(best);
-}
-
-void DocParser::insertTarget(const QString &target, bool keyword)
-{
- if (targetMap_.contains(target)) {
- location().warning(tr("Duplicate target name '%1'").arg(target));
- targetMap_[target].warning(tr("(The previous occurrence is here)"));
- }
- else {
- targetMap_.insert(target, location());
- priv->constructExtra();
- if (keyword) {
- append(Atom::Keyword, target);
- priv->extra->keywords_.append(priv->text.lastAtom());
- }
- else {
- append(Atom::Target, target);
- priv->extra->targets_.append(priv->text.lastAtom());
- }
- }
-}
-
-void DocParser::include(const QString& fileName, const QString& identifier)
-{
- if (location().depth() > 16)
- location().fatal(tr("Too many nested '\\%1's").arg(cmdName(CMD_INCLUDE)));
-
- QString userFriendlyFilePath;
- QString filePath = Doc::config()->getIncludeFilePath(fileName);
-#if 0
- QString filePath = Config::findFile(location(),
- sourceFiles,
- sourceDirs,
- fileName,
- userFriendlyFilePath);
-#endif
- if (filePath.isEmpty()) {
- location().warning(tr("Cannot find qdoc include file '%1'").arg(fileName));
- }
- else {
- QFile inFile(filePath);
- if (!inFile.open(QFile::ReadOnly)) {
- location().warning(tr("Cannot open qdoc include file '%1'")
- .arg(userFriendlyFilePath));
- }
- else {
- location().push(userFriendlyFilePath);
-
- QTextStream inStream(&inFile);
- QString includedStuff = inStream.readAll();
- inFile.close();
-
- if (identifier.isEmpty()) {
- in.insert(pos, includedStuff);
- len = in.length();
- openedInputs.push(pos + includedStuff.length());
- }
- else {
- QStringList lineBuffer = includedStuff.split(QLatin1Char('\n'));
- int i = 0;
- int startLine = -1;
- while (i < lineBuffer.size()) {
- if (lineBuffer[i].startsWith("//!")) {
- if (lineBuffer[i].contains(identifier)) {
- startLine = i+1;
- break;
- }
- }
- ++i;
- }
- if (startLine < 0) {
- location().warning(tr("Cannot find '%1' in '%2'")
- .arg(identifier)
- .arg(userFriendlyFilePath));
- return;
-
- }
- QString result;
- i = startLine;
- do {
- if (lineBuffer[i].startsWith("//!")) {
- if (i<lineBuffer.size()) {
- if (lineBuffer[i].contains(identifier)) {
- break;
- }
- }
- }
- else
- result += lineBuffer[i] + QLatin1Char('\n');
- ++i;
- } while (i < lineBuffer.size());
- if (result.isEmpty()) {
- location().warning(tr("Empty qdoc snippet '%1' in '%2'")
- .arg(identifier)
- .arg(userFriendlyFilePath));
- }
- else {
- in.insert(pos, result);<