summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--configure.json111
-rw-r--r--examples/assistant/remotecontrol/remotecontrol.h2
-rw-r--r--src/assistant/assistant.pro5
-rw-r--r--src/assistant/assistant/aboutdialog.cpp1
-rw-r--r--src/assistant/assistant/assistant.pro10
-rw-r--r--src/assistant/assistant/assistant_images.qrc4
-rw-r--r--src/assistant/assistant/bookmarkdialog.cpp2
-rw-r--r--src/assistant/assistant/centralwidget.cpp12
-rw-r--r--src/assistant/assistant/centralwidget.h6
-rw-r--r--src/assistant/assistant/doc/src/assistant-manual.qdoc1
-rw-r--r--src/assistant/assistant/doc/src/assistant-quick-guide.qdoc2
-rw-r--r--src/assistant/assistant/helpdocsettings.cpp231
-rw-r--r--src/assistant/assistant/helpdocsettings.h82
-rw-r--r--src/assistant/assistant/helpdocsettingswidget.cpp194
-rw-r--r--src/assistant/assistant/helpdocsettingswidget.h73
-rw-r--r--src/assistant/assistant/helpdocsettingswidget.ui76
-rw-r--r--src/assistant/assistant/helpenginewrapper.cpp11
-rw-r--r--src/assistant/assistant/helpenginewrapper.h6
-rw-r--r--src/assistant/assistant/helpviewer.h2
-rw-r--r--src/assistant/assistant/helpviewer_qwv.cpp6
-rw-r--r--src/assistant/assistant/indexwindow.cpp22
-rw-r--r--src/assistant/assistant/indexwindow.h4
-rw-r--r--src/assistant/assistant/main.cpp162
-rw-r--r--src/assistant/assistant/mainwindow.cpp9
-rw-r--r--src/assistant/assistant/mainwindow.h3
-rw-r--r--src/assistant/assistant/openpageswidget.cpp2
-rw-r--r--src/assistant/assistant/preferencesdialog.cpp486
-rw-r--r--src/assistant/assistant/preferencesdialog.h47
-rw-r--r--src/assistant/assistant/preferencesdialog.ui153
-rw-r--r--src/assistant/assistant/remotecontrol.cpp15
-rw-r--r--src/assistant/assistant/topicchooser.cpp12
-rw-r--r--src/assistant/assistant/topicchooser.h3
-rw-r--r--src/assistant/help/Qt5HelpConfigExtras.cmake.in11
-rw-r--r--src/assistant/help/help.pro19
-rw-r--r--src/assistant/help/helpsystem.qrc4
-rw-r--r--src/assistant/help/images/mac/minus.png (renamed from src/assistant/assistant/images/mac/minus.png)bin488 -> 488 bytes
-rw-r--r--src/assistant/help/images/mac/plus.png (renamed from src/assistant/assistant/images/mac/plus.png)bin810 -> 810 bytes
-rw-r--r--src/assistant/help/images/win/minus.png (renamed from src/assistant/assistant/images/win/minus.png)bin429 -> 429 bytes
-rw-r--r--src/assistant/help/images/win/plus.png (renamed from src/assistant/assistant/images/win/plus.png)bin709 -> 709 bytes
-rw-r--r--src/assistant/help/qcompressedhelpinfo.cpp12
-rw-r--r--src/assistant/help/qcompressedhelpinfo.h1
-rw-r--r--src/assistant/help/qfilternamedialog.cpp (renamed from src/assistant/assistant/filternamedialog.cpp)14
-rw-r--r--src/assistant/help/qfilternamedialog.ui (renamed from src/assistant/assistant/filternamedialog.ui)0
-rw-r--r--src/assistant/help/qfilternamedialog_p.h (renamed from src/assistant/assistant/filternamedialog.h)25
-rw-r--r--src/assistant/help/qhelpcollectionhandler.cpp51
-rw-r--r--src/assistant/help/qhelpcollectionhandler_p.h23
-rw-r--r--src/assistant/help/qhelpengine_p.h1
-rw-r--r--src/assistant/help/qhelpenginecore.cpp81
-rw-r--r--src/assistant/help/qhelpenginecore.h10
-rw-r--r--src/assistant/help/qhelpfilterengine.cpp41
-rw-r--r--src/assistant/help/qhelpfilterengine.h4
-rw-r--r--src/assistant/help/qhelpfiltersettings.cpp170
-rw-r--r--src/assistant/help/qhelpfiltersettings_p.h96
-rw-r--r--src/assistant/help/qhelpfiltersettingswidget.cpp424
-rw-r--r--src/assistant/help/qhelpfiltersettingswidget.h77
-rw-r--r--src/assistant/help/qhelpfiltersettingswidget.ui83
-rw-r--r--src/assistant/help/qhelpindexwidget.cpp70
-rw-r--r--src/assistant/help/qhelpindexwidget.h14
-rw-r--r--src/assistant/help/qhelplink.cpp60
-rw-r--r--src/assistant/help/qhelplink.h57
-rw-r--r--src/assistant/help/qhelpsearchindexwriter_default.cpp2
-rw-r--r--src/assistant/help/qhelpsearchquerywidget.cpp2
-rw-r--r--src/assistant/help/qoptionswidget.cpp (renamed from src/assistant/assistant/optionswidget.cpp)35
-rw-r--r--src/assistant/help/qoptionswidget_p.h (renamed from src/assistant/assistant/optionswidget.h)21
-rw-r--r--src/assistant/shared/collectionconfiguration.cpp4
-rw-r--r--src/designer/data/generate_header.xsl2
-rw-r--r--src/designer/data/generate_impl.xsl4
-rw-r--r--src/designer/designer.pro4
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor.cpp19
-rw-r--r--src/designer/src/components/formeditor/deviceprofiledialog.cpp2
-rw-r--r--src/designer/src/components/formeditor/dpi_chooser.cpp2
-rw-r--r--src/designer/src/components/formeditor/embeddedoptionspage.cpp7
-rw-r--r--src/designer/src/components/formeditor/formeditor.cpp2
-rw-r--r--src/designer/src/components/formeditor/formwindow.cpp33
-rw-r--r--src/designer/src/components/formeditor/formwindow_widgetstack.cpp2
-rw-r--r--src/designer/src/components/formeditor/formwindowmanager.cpp7
-rw-r--r--src/designer/src/components/formeditor/formwindowsettings.cpp9
-rw-r--r--src/designer/src/components/formeditor/layout_propertysheet.cpp2
-rw-r--r--src/designer/src/components/formeditor/previewactiongroup.cpp9
-rw-r--r--src/designer/src/components/formeditor/qdesigner_resource.cpp26
-rw-r--r--src/designer/src/components/formeditor/qmdiarea_container.cpp4
-rw-r--r--src/designer/src/components/formeditor/qwizard_container.cpp22
-rw-r--r--src/designer/src/components/formeditor/templateoptionspage.cpp17
-rw-r--r--src/designer/src/components/formeditor/tool_widgeteditor.cpp2
-rw-r--r--src/designer/src/components/objectinspector/objectinspector.cpp28
-rw-r--r--src/designer/src/components/objectinspector/objectinspectormodel.cpp53
-rw-r--r--src/designer/src/components/objectinspector/objectinspectormodel_p.h3
-rw-r--r--src/designer/src/components/propertyeditor/designerpropertymanager.cpp30
-rw-r--r--src/designer/src/components/propertyeditor/fontpropertymanager.cpp6
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditor.cpp247
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditor.h28
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditor.ui305
-rw-r--r--src/designer/src/components/propertyeditor/previewframe.cpp2
-rw-r--r--src/designer/src/components/propertyeditor/previewwidget.cpp15
-rw-r--r--src/designer/src/components/propertyeditor/previewwidget.ui404
-rw-r--r--src/designer/src/components/propertyeditor/propertyeditor.cpp38
-rw-r--r--src/designer/src/components/signalsloteditor/connectdialog.cpp24
-rw-r--r--src/designer/src/components/signalsloteditor/signalslot_utils.cpp6
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp35
-rw-r--r--src/designer/src/components/taskmenu/button_taskmenu.cpp12
-rw-r--r--src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp8
-rw-r--r--src/designer/src/components/taskmenu/layouttaskmenu.cpp2
-rw-r--r--src/designer/src/components/taskmenu/toolbar_taskmenu.cpp2
-rw-r--r--src/designer/src/components/widgetbox/widgetbox_dnditem.cpp2
-rw-r--r--src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp2
-rw-r--r--src/designer/src/components/widgetbox/widgetboxtreewidget.cpp15
-rw-r--r--src/designer/src/designer/appfontdialog.cpp10
-rw-r--r--src/designer/src/designer/assistantclient.cpp2
-rw-r--r--src/designer/src/designer/doc/src/designer-manual.qdoc19
-rw-r--r--src/designer/src/designer/mainwindow.cpp13
-rw-r--r--src/designer/src/designer/newform.cpp11
-rw-r--r--src/designer/src/designer/qdesigner.cpp2
-rw-r--r--src/designer/src/designer/qdesigner_actions.cpp2
-rw-r--r--src/designer/src/designer/qdesigner_appearanceoptions.cpp2
-rw-r--r--src/designer/src/designer/qdesigner_formwindow.cpp2
-rw-r--r--src/designer/src/designer/qdesigner_settings.cpp1
-rw-r--r--src/designer/src/designer/qdesigner_workbench.cpp22
-rw-r--r--src/designer/src/lib/sdk/abstractdialoggui_p.h10
-rw-r--r--src/designer/src/lib/shared/actioneditor.cpp37
-rw-r--r--src/designer/src/lib/shared/actioneditor_p.h4
-rw-r--r--src/designer/src/lib/shared/actionprovider_p.h2
-rw-r--r--src/designer/src/lib/shared/actionrepository.cpp15
-rw-r--r--src/designer/src/lib/shared/actionrepository_p.h4
-rw-r--r--src/designer/src/lib/shared/connectionedit.cpp23
-rw-r--r--src/designer/src/lib/shared/connectionedit_p.h5
-rw-r--r--src/designer/src/lib/shared/dialoggui.cpp6
-rw-r--r--src/designer/src/lib/shared/dialoggui_p.h10
-rw-r--r--src/designer/src/lib/shared/formlayoutmenu.cpp4
-rw-r--r--src/designer/src/lib/shared/formwindowbase.cpp8
-rw-r--r--src/designer/src/lib/shared/iconselector.cpp8
-rw-r--r--src/designer/src/lib/shared/layout.cpp8
-rw-r--r--src/designer/src/lib/shared/layoutinfo.cpp10
-rw-r--r--src/designer/src/lib/shared/morphmenu.cpp14
-rw-r--r--src/designer/src/lib/shared/newactiondialog.cpp27
-rw-r--r--src/designer/src/lib/shared/newactiondialog_p.h7
-rw-r--r--src/designer/src/lib/shared/newformwidget.cpp13
-rw-r--r--src/designer/src/lib/shared/newformwidget_p.h3
-rw-r--r--src/designer/src/lib/shared/plugindialog.cpp2
-rw-r--r--src/designer/src/lib/shared/pluginmanager.cpp6
-rw-r--r--src/designer/src/lib/shared/previewconfigurationwidget.cpp17
-rw-r--r--src/designer/src/lib/shared/previewmanager.cpp31
-rw-r--r--src/designer/src/lib/shared/promotionmodel.cpp6
-rw-r--r--src/designer/src/lib/shared/promotiontaskmenu.cpp8
-rw-r--r--src/designer/src/lib/shared/promotiontaskmenu_p.h3
-rw-r--r--src/designer/src/lib/shared/qdesigner_command.cpp27
-rw-r--r--src/designer/src/lib/shared/qdesigner_command2.cpp4
-rw-r--r--src/designer/src/lib/shared/qdesigner_command_p.h13
-rw-r--r--src/designer/src/lib/shared/qdesigner_dnditem.cpp4
-rw-r--r--src/designer/src/lib/shared/qdesigner_dockwidget.cpp12
-rw-r--r--src/designer/src/lib/shared/qdesigner_dockwidget_p.h19
-rw-r--r--src/designer/src/lib/shared/qdesigner_formbuilder.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp12
-rw-r--r--src/designer/src/lib/shared/qdesigner_introspection.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_membersheet.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_menu.cpp12
-rw-r--r--src/designer/src/lib/shared/qdesigner_menubar.cpp4
-rw-r--r--src/designer/src/lib/shared/qdesigner_objectinspector.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_promotion.cpp6
-rw-r--r--src/designer/src/lib/shared/qdesigner_promotiondialog.cpp4
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertycommand.cpp8
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertyeditor.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertyeditor_p.h2
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertysheet.cpp36
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertysheet_p.h9
-rw-r--r--src/designer/src/lib/shared/qdesigner_tabwidget.cpp6
-rw-r--r--src/designer/src/lib/shared/qdesigner_taskmenu.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_toolbar.cpp7
-rw-r--r--src/designer/src/lib/shared/qdesigner_toolbox.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_utils.cpp6
-rw-r--r--src/designer/src/lib/shared/qdesigner_widgetbox.cpp2
-rw-r--r--src/designer/src/lib/shared/qdesigner_widgetbox_p.h2
-rw-r--r--src/designer/src/lib/shared/qdesigner_widgetitem.cpp2
-rw-r--r--src/designer/src/lib/shared/qlayout_widget.cpp21
-rw-r--r--src/designer/src/lib/shared/qsimpleresource.cpp4
-rw-r--r--src/designer/src/lib/shared/qtresourceeditordialog.cpp34
-rw-r--r--src/designer/src/lib/shared/qtresourcemodel.cpp20
-rw-r--r--src/designer/src/lib/shared/rcc.cpp18
-rw-r--r--src/designer/src/lib/shared/richtexteditor.cpp4
-rw-r--r--src/designer/src/lib/shared/selectsignaldialog.cpp2
-rw-r--r--src/designer/src/lib/shared/shared_settings.cpp6
-rw-r--r--src/designer/src/lib/shared/shared_settings_p.h4
-rw-r--r--src/designer/src/lib/shared/signalslotdialog.cpp10
-rw-r--r--src/designer/src/lib/shared/textpropertyeditor.cpp2
-rw-r--r--src/designer/src/lib/shared/widgetdatabase.cpp16
-rw-r--r--src/designer/src/lib/shared/widgetfactory.cpp3
-rw-r--r--src/designer/src/lib/shared/zoomwidget.cpp26
-rw-r--r--src/designer/src/lib/uilib/abstractformbuilder.cpp226
-rw-r--r--src/designer/src/lib/uilib/abstractformbuilder.h9
-rw-r--r--src/designer/src/lib/uilib/formbuilder.cpp2
-rw-r--r--src/designer/src/lib/uilib/formbuilderextra.cpp240
-rw-r--r--src/designer/src/lib/uilib/formbuilderextra_p.h15
-rw-r--r--src/designer/src/lib/uilib/ui4.cpp178
-rw-r--r--src/designer/src/uitools/quiloader.cpp4
-rw-r--r--src/distancefieldgenerator/distancefieldgenerator.pro4
-rw-r--r--src/distancefieldgenerator/distancefieldmodel.cpp2
-rw-r--r--src/distancefieldgenerator/distancefieldmodel.h1
-rw-r--r--src/kmap2qmap/kmap2qmap.pro4
-rw-r--r--src/kmap2qmap/main.cpp14
-rw-r--r--src/linguist/Qt5LinguistToolsConfig.cmake.in11
-rw-r--r--src/linguist/Qt5LinguistToolsMacros.cmake22
-rw-r--r--src/linguist/linguist.pro4
-rw-r--r--src/linguist/linguist/doc/src/linguist-manual.qdoc6
-rw-r--r--src/linguist/linguist/linguist.pro2
-rw-r--r--src/linguist/linguist/main.cpp1
-rw-r--r--src/linguist/linguist/mainwindow.cpp7
-rw-r--r--src/linguist/linguist/messageeditorwidgets.cpp2
-rw-r--r--src/linguist/linguist/messagemodel.h2
-rw-r--r--src/linguist/linguist/phrase.cpp80
-rw-r--r--src/linguist/linguist/phrasemodel.cpp2
-rw-r--r--src/linguist/linguist/statistics.h2
-rw-r--r--src/linguist/lupdate/main.cpp2
-rw-r--r--src/linguist/lupdate/qdeclarative.cpp17
-rw-r--r--src/linguist/lupdate/ui.cpp99
-rw-r--r--src/linguist/shared/formats.pri10
-rw-r--r--src/linguist/shared/po.cpp8
-rw-r--r--src/linguist/shared/qm.cpp21
-rw-r--r--src/linguist/shared/qmakebuiltins.cpp6
-rw-r--r--src/linguist/shared/qmakeevaluator.cpp4
-rw-r--r--src/linguist/shared/qmakeglobals.cpp2
-rw-r--r--src/linguist/shared/ts.cpp2
-rw-r--r--src/linguist/shared/xliff.cpp122
-rw-r--r--src/linguist/shared/xmlparser.cpp109
-rw-r--r--src/linguist/shared/xmlparser.h63
-rw-r--r--src/macdeployqt/macdeployqt.pro4
-rw-r--r--src/macdeployqt/macdeployqt/main.cpp5
-rw-r--r--src/macdeployqt/shared/shared.cpp40
-rw-r--r--src/makeqpf/makeqpf.pro4
-rw-r--r--src/makeqpf/qpf2.cpp2
-rw-r--r--src/pixeltool/pixeltool.pro4
-rw-r--r--src/pixeltool/qpixeltool.cpp6
-rw-r--r--src/qdbus/qdbus.pro4
-rw-r--r--src/qdbus/qdbusviewer/propertydialog.h2
-rw-r--r--src/qdbus/qdbusviewer/qdbusmodel.cpp2
-rw-r--r--src/qdoc/Qt5DocToolsConfig.cmake.in11
-rw-r--r--src/qdoc/clangcodeparser.cpp135
-rw-r--r--src/qdoc/clangcodeparser.h3
-rw-r--r--src/qdoc/codemarker.cpp10
-rw-r--r--src/qdoc/codemarker.h6
-rw-r--r--src/qdoc/codeparser.cpp57
-rw-r--r--src/qdoc/codeparser.h6
-rw-r--r--src/qdoc/config.cpp167
-rw-r--r--src/qdoc/config.h107
-rw-r--r--src/qdoc/cppcodemarker.cpp29
-rw-r--r--src/qdoc/cppcodeparser.cpp85
-rw-r--r--src/qdoc/cppcodeparser.h6
-rw-r--r--src/qdoc/doc.cpp22
-rw-r--r--src/qdoc/doc.h5
-rw-r--r--src/qdoc/doc/files/basicqt.qdoc.sample3
-rw-r--r--src/qdoc/doc/qa-pages.qdoc3
-rw-r--r--src/qdoc/doc/qdoc-manual-DITA.qdoc164
-rw-r--r--src/qdoc/doc/qdoc-manual-cmdindex.qdoc2
-rw-r--r--src/qdoc/doc/qdoc-manual-contextcmds.qdoc18
-rw-r--r--src/qdoc/doc/qdoc-manual-intro.qdoc1
-rw-r--r--src/qdoc/doc/qdoc-manual-markupcmds.qdoc129
-rw-r--r--src/qdoc/doc/qdoc-manual-qdocconf.qdoc136
-rw-r--r--src/qdoc/doc/qdoc-manual-topiccmds.qdoc1
-rw-r--r--src/qdoc/doc/qdoc-manual.qdoc2
-rw-r--r--src/qdoc/docbookgenerator.cpp4216
-rw-r--r--src/qdoc/docbookgenerator.h178
-rw-r--r--src/qdoc/generator.cpp196
-rw-r--r--src/qdoc/generator.h36
-rw-r--r--src/qdoc/helpprojectwriter.cpp135
-rw-r--r--src/qdoc/helpprojectwriter.h9
-rw-r--r--src/qdoc/htmlgenerator.cpp318
-rw-r--r--src/qdoc/htmlgenerator.h9
-rw-r--r--src/qdoc/jscodemarker.cpp4
-rw-r--r--src/qdoc/location.cpp40
-rw-r--r--src/qdoc/location.h9
-rw-r--r--src/qdoc/main.cpp72
-rw-r--r--src/qdoc/node.cpp115
-rw-r--r--src/qdoc/node.h36
-rw-r--r--src/qdoc/qdoc.pro2
-rw-r--r--src/qdoc/qdoccommandlineparser.cpp7
-rw-r--r--src/qdoc/qdoccommandlineparser.h2
-rw-r--r--src/qdoc/qdocdatabase.cpp15
-rw-r--r--src/qdoc/qdocdatabase.h2
-rw-r--r--src/qdoc/qdocindexfiles.cpp33
-rw-r--r--src/qdoc/qdocindexfiles.h1
-rw-r--r--src/qdoc/qdoctagfiles.cpp23
-rw-r--r--src/qdoc/qmlcodemarker.cpp8
-rw-r--r--src/qdoc/qmlcodemarker.h11
-rw-r--r--src/qdoc/qmlcodeparser.cpp11
-rw-r--r--src/qdoc/qmlcodeparser.h3
-rw-r--r--src/qdoc/qmlmarkupvisitor.cpp16
-rw-r--r--src/qdoc/qmlmarkupvisitor.h20
-rw-r--r--src/qdoc/qmlvisitor.cpp22
-rw-r--r--src/qdoc/qmlvisitor.h15
-rw-r--r--src/qdoc/sections.cpp6
-rw-r--r--src/qdoc/sections.h2
-rw-r--r--src/qdoc/tokenizer.cpp3
-rw-r--r--src/qdoc/tokenizer.h2
-rw-r--r--src/qdoc/tree.cpp12
-rw-r--r--src/qdoc/webxmlgenerator.cpp26
-rw-r--r--src/qdoc/webxmlgenerator.h3
-rw-r--r--src/qev/qev.cpp2
-rw-r--r--src/qev/qev.pro4
-rw-r--r--src/qtattributionsscanner/Qt5AttributionsScannerTools.cmake.in11
-rw-r--r--src/qtattributionsscanner/qdocgenerator.cpp1
-rw-r--r--src/qtattributionsscanner/qtattributionsscanner.pro4
-rw-r--r--src/qtattributionsscanner/scanner.cpp2
-rw-r--r--src/qtdiag/main.cpp4
-rw-r--r--src/qtdiag/qtdiag.cpp170
-rw-r--r--src/qtdiag/qtdiag.h3
-rw-r--r--src/qtdiag/qtdiag.pro4
-rw-r--r--src/qtpaths/qtpaths.cpp10
-rw-r--r--src/qtpaths/qtpaths.pro4
-rw-r--r--src/qtplugininfo/qtplugininfo.pro4
-rw-r--r--src/shared/deviceskin/deviceskin.cpp8
-rw-r--r--src/shared/deviceskin/deviceskin.h4
-rw-r--r--src/shared/fontpanel/fontpanel.cpp20
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopscontroller.cpp12
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopsmodel.cpp8
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopswidget.cpp8
-rw-r--r--src/shared/qtgradienteditor/qtgradientwidget.cpp2
-rw-r--r--src/shared/qtpropertybrowser/qteditorfactory.cpp4
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.cpp36
-rw-r--r--src/shared/qtpropertybrowser/qtpropertymanager.cpp6
-rw-r--r--src/shared/qtpropertybrowser/qtvariantproperty.cpp90
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.cpp72
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.h2
-rw-r--r--src/windeployqt/main.cpp16
-rw-r--r--src/windeployqt/windeployqt.pro4
-rw-r--r--src/winrtrunner/winrtrunner.pro4
-rw-r--r--tests/auto/qdoc/config/config.pro16
-rw-r--r--tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf2
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt1
-rw-r--r--tests/auto/qdoc/config/tst_config.cpp114
-rw-r--r--tests/auto/qdoc/generatedoutput/TestCPP1
-rw-r--r--tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/TestModule.h3
-rw-r--r--tests/auto/qdoc/generatedoutput/bug80259/webxml_testmodule.qdocconf2
-rw-r--r--tests/auto/qdoc/generatedoutput/examples-qhp.qdocconf20
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html23
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html57
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoc-test-qmlmodule.xml44
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput-linking.xml16
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput.xml67
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-int.xml21
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-abstractparent.xml53
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-child.xml53
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-doctest.xml76
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-type.xml161
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-progressbar.xml94
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-switch.xml47
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-tabwidget.xml77
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/test-componentset-example.xml47
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/testcpp-module.xml43
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-test.xml199
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-testderived.xml54
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc.xml58
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/docbook/uicomponents-qmlmodule.xml34
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/dontdocument/classes.html22
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/dontdocument/seenclass.html33
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml5
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/first.webxml8
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/index.webxml4
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput-linking.webxml4
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput.webxml4
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/second.webxml4
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/test-componentset-example.webxml4
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-test.webxml42
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-testderived.webxml8
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc.webxml48
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/third.webxml4
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc-test.html94
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc.html64
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/index.html2
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent-members.html3
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent.html14
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/qdoc-test-qmlmodule.xml12
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/test-componentset-example.xml37
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/testcpp-module.xml15
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/noautolist/qdoc-test-qmlmodule.html16
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/noautolist/test-componentset-example.html51
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/noautolist/testcpp-module.html29
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html2
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html2
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/qml-int.html16
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-type.html2
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/scopedenum/testqdoc-test.html109
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/template/bar.html34
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/template/baz.html34
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/template/foo.html34
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/template/testqdoc-test.html97
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html22
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/test.qhp141
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/testcpp.index39
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html3
-rw-r--r--tests/auto/qdoc/generatedoutput/generatedoutput.pro2
-rw-r--r--tests/auto/qdoc/generatedoutput/test.qdocconf8
-rw-r--r--tests/auto/qdoc/generatedoutput/testcpp.qdocconf7
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/TestModule.h3
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/aaa.h (renamed from tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/aaa.h)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/bbb.h (renamed from tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/bbb.h)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/ccc.h (renamed from tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/ccc.h)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/src/main.cpp (renamed from tests/auto/qdoc/generatedoutput/bug80259/src/main.cpp)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/src/qdoc/index.qdoc (renamed from tests/auto/qdoc/generatedoutput/bug80259/src/qdoc/index.qdoc)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/testmodule.qdocconf (renamed from tests/auto/qdoc/generatedoutput/bug80259/testmodule.qdocconf)6
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/bug80259/webxml_testmodule.qdocconf2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/docbook.qdocconf7
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/docbook_test.qdocconf2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testcpp.qdocconf2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testqml.qdocconf2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf37
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/ignoresince.qdocconf8
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/noautolist.qdocconf13
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/scopedenum.qdocconf7
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/test.qdocconf12
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/testcpp.qdocconf14
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/testcpp_singleexec.qdocconf6
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf (renamed from tests/auto/qdoc/generatedoutput/testqml.qdocconf)10
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/testtemplate.qdocconf8
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/webxml.qdocconf (renamed from tests/auto/qdoc/generatedoutput/webxml.qdocconf)1
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/webxml_test.qdocconf (renamed from tests/auto/qdoc/generatedoutput/webxml_test.qdocconf)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/webxml_testcpp.qdocconf (renamed from tests/auto/qdoc/generatedoutput/webxml_testcpp.qdocconf)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/webxml_testqml.qdocconf (renamed from tests/auto/qdoc/generatedoutput/webxml_testqml.qdocconf)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/crossmodule/CrossModule2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule.qdocconf10
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule_singleexec.qdocconf4
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.cpp56
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.h37
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/dontdocument/TestCPP2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.cpp47
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.h41
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/dontdocument/dontdocument.qdocconf7
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/dontdocument/test.qdoc36
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/excludes/anotherindex.qdoc (renamed from tests/auto/qdoc/generatedoutput/includefromexampledirs/excludes/anotherindex.qdoc)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/excludes/parentinclude.qdoc (renamed from tests/auto/qdoc/generatedoutput/includefromexampledirs/excludes/parentinclude.qdoc)14
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/includefromexampledirs.qdocconf (renamed from tests/auto/qdoc/generatedoutput/includefromexampledirs/includefromexampledirs.qdocconf)5
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/src/includefromparent.qdoc (renamed from tests/auto/qdoc/generatedoutput/includefromexampledirs/src/includefromparent.qdoc)15
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/src/parent.qdocinc (renamed from tests/auto/qdoc/generatedoutput/includefromexampledirs/src/parent.qdocinc)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/outputfromqdocfiles/qdoctests-outputfromqdocfiles.qdoc (renamed from tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/DocTest.qml (renamed from tests/auto/qdoc/generatedoutput/qml/DocTest.qml)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc32
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp1
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/componentset/ProgressBar.qml (renamed from tests/auto/qdoc/generatedoutput/qml/componentset/ProgressBar.qml)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/componentset/Switch.qml (renamed from tests/auto/qdoc/generatedoutput/qml/componentset/Switch.qml)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/componentset/TabWidget.qml (renamed from tests/auto/qdoc/generatedoutput/qml/componentset/TabWidget.qml)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/componentset/componentset.pro (renamed from tests/auto/qdoc/generatedoutput/qml/componentset/componentset.pro)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/componentset/examples.qdoc (renamed from tests/auto/qdoc/generatedoutput/qml/componentset/examples.qdoc)20
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/componentset/uicomponents.qdoc.sample (renamed from tests/auto/qdoc/generatedoutput/qml/componentset/uicomponents.qdoc.sample)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/parent.qdoc (renamed from tests/auto/qdoc/generatedoutput/qml/parent.qdoc)5
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp (renamed from tests/auto/qdoc/generatedoutput/qml/type.cpp)2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qmlpropertygroups/parent.qdoc (renamed from tests/auto/qdoc/generatedoutput/qmlpropertygroups/parent.qdoc)0
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qmlpropertygroups/qmlpropertygroups.qdocconf (renamed from tests/auto/qdoc/generatedoutput/qmlpropertygroups/qmlpropertygroups.qdocconf)3
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/scopedenum/scopedenum.qdoc35
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/singleexec/singleexec.qdocconf2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/testcpp/TestCPP5
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.cpp (renamed from tests/auto/qdoc/generatedoutput/testcpp.cpp)34
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.h (renamed from tests/auto/qdoc/generatedoutput/testcpp.h)13
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.cpp47
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.h53
-rw-r--r--tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp202
-rw-r--r--tests/auto/qdoc/qdoc.pro4
-rw-r--r--tests/auto/qdoc/utilities/tst_utilities.cpp89
-rw-r--r--tests/auto/qdoc/utilities/utilities.pro12
-rw-r--r--tests/auto/windeployqt/tst_windeployqt.cpp2
462 files changed, 13572 insertions, 3865 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 858804d53..715105c47 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
DEFINES += QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST
-MODULE_VERSION = 5.14.2
+MODULE_VERSION = 5.15.0
diff --git a/configure.json b/configure.json
index cd111df83..2a7304a38 100644
--- a/configure.json
+++ b/configure.json
@@ -1,5 +1,116 @@
{
+ "module": "tools",
+
"subconfigs": [
"src/qdoc"
+ ],
+ "features": {
+ "assistant": {
+ "label": "Qt Assistant",
+ "purpose": "Qt Assistant is a tool for viewing on-line documentation in Qt help file format.",
+ "output": [ "privateFeature" ]
+ },
+ "designer": {
+ "label": "Qt Designer",
+ "purpose": "Qt Designer is the Qt tool for designing and building graphical user interfaces (GUIs) with Qt Widgets. You can compose and customize your windows or dialogs in a what-you-see-is-what-you-get (WYSIWYG) manner, and test them using different styles and resolutions.",
+ "output": [ "privateFeature" ]
+ },
+ "distancefieldgenerator": {
+ "label": "Qt Distance Field Generator",
+ "purpose": "The Qt Distance Field Generator tool can be used to pregenerate the font cache in order to optimize startup performance.",
+ "output": [ "privateFeature" ]
+ },
+ "kmap2qmap": {
+ "label": "kmap2qmap",
+ "purpose": "kmap2qmap is a tool to generate keymaps for use on Embedded Linux. The source files have to be in standard Linux kmap format that is e.g. understood by the kernel's loadkeys command.",
+ "output": [ "privateFeature" ]
+ },
+ "linguist": {
+ "label": "Qt Linguist",
+ "purpose": "Qt Linguist can be used by translator to translate text in Qt applications.",
+ "output": [ "privateFeature" ]
+ },
+ "macdeployqt": {
+ "label": "Mac Deployment Tool",
+ "purpose": "The Mac deployment tool automates the process of creating a deployable application bundle that contains the Qt libraries as private frameworks.",
+ "condition": "config.darwin",
+ "output": [ "privateFeature" ]
+ },
+ "makeqpf": {
+ "label": "makeqpf",
+ "purpose": "makeqpf is a tool to generate pre-rendered fonts in QPF2 format for use on Embedded Linux.",
+ "output": [ "privateFeature" ]
+ },
+ "pixeltool": {
+ "label": "pixeltool",
+ "purpose": "The Qt Pixel Zooming Tool is a graphical application that magnifies the screen around the mouse pointer so you can look more closely at individual pixels.",
+ "output": [ "privateFeature" ]
+ },
+ "qdbus": {
+ "label": "qdbus",
+ "purpose": "qdbus is a communication interface for Qt-based applications.",
+ "output": [ "privateFeature" ]
+ },
+ "qev": {
+ "label": "qev",
+ "purpose": "qev allows introspection of incoming events for a QWidget, similar to the X11 xev tool.",
+ "output": [ "privateFeature" ]
+ },
+ "qtattributionsscanner": {
+ "label": "Qt Attributions Scanner",
+ "purpose": "Qt Attributions Scanner generates attribution documents for third-party code in Qt.",
+ "output": [ "privateFeature" ]
+ },
+ "qtdiag": {
+ "label": "qtdiag",
+ "purpose": "qtdiag outputs information about the Qt installation it was built with.",
+ "output": [ "privateFeature" ]
+ },
+ "qtpaths": {
+ "label": "qtpaths",
+ "purpose": "qtpaths is a command line client to QStandardPaths.",
+ "output": [ "privateFeature" ]
+ },
+ "qtplugininfo": {
+ "label": "qtplugininfo",
+ "purpose": "qtplugininfo dumps metadata about Qt plugins in JSON format.",
+ "output": [ "privateFeature" ]
+ },
+ "windeployqt": {
+ "label": "Windows deployment tool",
+ "purpose": "The Windows deployment tool is designed to automate the process of creating a deployable folder containing the Qt-related dependencies (libraries, QML imports, plugins, and translations) required to run the application from that folder. It creates a sandbox for Universal Windows Platform (UWP) or an installation tree for Windows desktop applications, which can be easily bundled into an installation package.",
+ "condition": "config.win32 || config.winrt",
+ "output": [ "privateFeature" ]
+ },
+ "winrtrunner": {
+ "label": "WinRT Runner Tool",
+ "purpose": "The WinRT Runner Tool installs, runs, and collects test results for packages made with Qt.",
+ "condition": "config.winrt",
+ "output": [ "privateFeature" ]
+ }
+ },
+ "summary": [
+ {
+ "section": "Qt Tools",
+ "entries": [
+ "assistant",
+ "designer",
+ "distancefieldgenerator",
+ "kmap2qmap",
+ "linguist",
+ "macdeployqt",
+ "makeqpf",
+ "pixeltool",
+ "qdbus",
+ "qev",
+ "qtattributionsscanner",
+ "qtdiag",
+ "qtpaths",
+ "qtplugininfo",
+ "windeployqt",
+ "winrtrunner"
+ ]
+ }
]
}
+
diff --git a/examples/assistant/remotecontrol/remotecontrol.h b/examples/assistant/remotecontrol/remotecontrol.h
index 40e370f71..f59ffb7aa 100644
--- a/examples/assistant/remotecontrol/remotecontrol.h
+++ b/examples/assistant/remotecontrol/remotecontrol.h
@@ -64,7 +64,7 @@ class RemoteControl : public QMainWindow
Q_OBJECT
public:
- RemoteControl(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
+ RemoteControl(QWidget *parent = nullptr, Qt::WindowFlags flags = {});
~RemoteControl();
private:
diff --git a/src/assistant/assistant.pro b/src/assistant/assistant.pro
index 1529167c0..d34b5590e 100644
--- a/src/assistant/assistant.pro
+++ b/src/assistant/assistant.pro
@@ -1,4 +1,9 @@
requires(qtHaveModule(sql))
+
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(assistant))
+
TEMPLATE = subdirs
SUBDIRS += \
diff --git a/src/assistant/assistant/aboutdialog.cpp b/src/assistant/assistant/aboutdialog.cpp
index 3682f1291..59f87d65c 100644
--- a/src/assistant/assistant/aboutdialog.cpp
+++ b/src/assistant/assistant/aboutdialog.cpp
@@ -37,7 +37,6 @@
#include <QtWidgets/QPushButton>
#include <QtWidgets/QLayout>
#include <QtWidgets/QApplication>
-#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QMessageBox>
#include <QtGui/QDesktopServices>
#include <QtGui/QScreen>
diff --git a/src/assistant/assistant/assistant.pro b/src/assistant/assistant/assistant.pro
index b63be28c7..5da0b0077 100644
--- a/src/assistant/assistant/assistant.pro
+++ b/src/assistant/assistant/assistant.pro
@@ -23,14 +23,14 @@ HEADERS += aboutdialog.h \
cmdlineparser.h \
contentwindow.h \
findwidget.h \
- filternamedialog.h \
+ helpdocsettings.h \
+ helpdocsettingswidget.h \
helpenginewrapper.h \
helpbrowsersupport.h \
helpviewer.h \
helpviewer_p.h \
indexwindow.h \
mainwindow.h \
- optionswidget.h \
preferencesdialog.h \
qtdocinstaller.h \
remotecontrol.h \
@@ -56,14 +56,14 @@ SOURCES += aboutdialog.cpp \
cmdlineparser.cpp \
contentwindow.cpp \
findwidget.cpp \
- filternamedialog.cpp \
+ helpdocsettings.cpp \
+ helpdocsettingswidget.cpp \
helpenginewrapper.cpp \
helpbrowsersupport.cpp \
helpviewer.cpp \
indexwindow.cpp \
main.cpp \
mainwindow.cpp \
- optionswidget.cpp \
preferencesdialog.cpp \
qtdocinstaller.cpp \
remotecontrol.cpp \
@@ -97,7 +97,7 @@ win32 {
FORMS += bookmarkdialog.ui \
bookmarkmanagerwidget.ui \
bookmarkwidget.ui \
- filternamedialog.ui \
+ helpdocsettingswidget.ui \
preferencesdialog.ui \
topicchooser.ui
diff --git a/src/assistant/assistant/assistant_images.qrc b/src/assistant/assistant/assistant_images.qrc
index e55b6b27e..948de970f 100644
--- a/src/assistant/assistant/assistant_images.qrc
+++ b/src/assistant/assistant/assistant_images.qrc
@@ -10,9 +10,7 @@
<file>images/mac/editcopy.png</file>
<file>images/mac/find.png</file>
<file>images/mac/home.png</file>
- <file>images/mac/minus.png</file>
<file>images/mac/next.png</file>
- <file>images/mac/plus.png</file>
<file>images/mac/previous.png</file>
<file>images/mac/print.png</file>
<file>images/mac/synctoc.png</file>
@@ -25,9 +23,7 @@
<file>images/win/editcopy.png</file>
<file>images/win/find.png</file>
<file>images/win/home.png</file>
- <file>images/win/minus.png</file>
<file>images/win/next.png</file>
- <file>images/win/plus.png</file>
<file>images/win/previous.png</file>
<file>images/win/print.png</file>
<file>images/win/synctoc.png</file>
diff --git a/src/assistant/assistant/bookmarkdialog.cpp b/src/assistant/assistant/bookmarkdialog.cpp
index 8207da04e..1ffe6dc84 100644
--- a/src/assistant/assistant/bookmarkdialog.cpp
+++ b/src/assistant/assistant/bookmarkdialog.cpp
@@ -60,7 +60,7 @@ BookmarkDialog::BookmarkDialog(BookmarkModel *sourceModel, const QString &title,
bookmarkProxyModel = new BookmarkFilterModel(this);
bookmarkProxyModel->setSourceModel(bookmarkModel);
ui.bookmarkFolders->setModel(bookmarkProxyModel);
- connect(ui.bookmarkFolders, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(ui.bookmarkFolders, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, QOverload<int>::of(&BookmarkDialog::currentIndexChanged));
bookmarkTreeModel = new BookmarkTreeModel(this);
diff --git a/src/assistant/assistant/centralwidget.cpp b/src/assistant/assistant/centralwidget.cpp
index 34304f737..bac8f6fc8 100644
--- a/src/assistant/assistant/centralwidget.cpp
+++ b/src/assistant/assistant/centralwidget.cpp
@@ -545,10 +545,10 @@ void CentralWidget::highlightSearchTerms()
const bool wholePhrase = searchInput.startsWith(QLatin1Char('"')) &&
searchInput.endsWith(QLatin1Char('"'));
const QStringList &words = wholePhrase ? QStringList(searchInput.mid(1, searchInput.length() - 2)) :
- searchInput.split(QRegExp("\\W+"), QString::SkipEmptyParts);
+ searchInput.split(QRegExp("\\W+"), Qt::SkipEmptyParts);
HelpViewer *viewer = currentHelpViewer();
for (const QString &word : words)
- viewer->findText(word, nullptr, false, true);
+ viewer->findText(word, {}, false, true);
disconnect(viewer, &HelpViewer::loadFinished,
this, &CentralWidget::highlightSearchTerms);
}
@@ -568,12 +568,12 @@ void CentralWidget::handleSourceChanged(const QUrl &url)
emit sourceChanged(url);
}
-void CentralWidget::slotHighlighted(const QString &link)
+void CentralWidget::slotHighlighted(const QUrl &link)
{
TRACE_OBJ
- QString resolvedLink = m_resolvedLinks.value(link);
+ QUrl resolvedLink = m_resolvedLinks.value(link);
if (!link.isEmpty() && resolvedLink.isEmpty()) {
- resolvedLink = HelpEngineWrapper::instance().findFile(link).toString();
+ resolvedLink = HelpEngineWrapper::instance().findFile(link);
m_resolvedLinks.insert(link, resolvedLink);
}
emit highlighted(resolvedLink);
@@ -605,7 +605,7 @@ void CentralWidget::connectSignals(HelpViewer *page)
this, &CentralWidget::backwardAvailable);
connect(page, &HelpViewer::sourceChanged,
this, &CentralWidget::handleSourceChanged);
- connect(page, QOverload<const QString &>::of(&HelpViewer::highlighted),
+ connect(page, QOverload<const QUrl &>::of(&HelpViewer::highlighted),
this, &CentralWidget::slotHighlighted);
}
diff --git a/src/assistant/assistant/centralwidget.h b/src/assistant/assistant/centralwidget.h
index 34de716a4..4943c2ff3 100644
--- a/src/assistant/assistant/centralwidget.h
+++ b/src/assistant/assistant/centralwidget.h
@@ -129,7 +129,7 @@ signals:
void currentViewerChanged();
void copyAvailable(bool yes);
void sourceChanged(const QUrl &url);
- void highlighted(const QString &link);
+ void highlighted(const QUrl &link);
void forwardAvailable(bool available);
void backwardAvailable(bool available);
void addBookmark(const QString &title, const QString &url);
@@ -142,7 +142,7 @@ private slots:
void highlightSearchTerms();
void printPreviewToPrinter(QPrinter *printer);
void handleSourceChanged(const QUrl &url);
- void slotHighlighted(const QString &link);
+ void slotHighlighted(const QUrl& link);
private:
void initPrinter();
@@ -160,7 +160,7 @@ private:
FindWidget *m_findWidget;
QStackedWidget *m_stackedWidget;
TabBar *m_tabBar;
- QHash<QString, QString> m_resolvedLinks;
+ QHash<QUrl, QUrl> m_resolvedLinks;
};
QT_END_NAMESPACE
diff --git a/src/assistant/assistant/doc/src/assistant-manual.qdoc b/src/assistant/assistant/doc/src/assistant-manual.qdoc
index c86a19cac..b03cffeaa 100644
--- a/src/assistant/assistant/doc/src/assistant-manual.qdoc
+++ b/src/assistant/assistant/doc/src/assistant-manual.qdoc
@@ -62,7 +62,6 @@
\page assistant-custom-help-viewer.html
\title Customizing Qt Assistant
- \contentspage {Qt Assistant Manual}{Contents}
\previouspage Using Qt Assistant
Using \QA as custom help viewer requires more than just being able to
diff --git a/src/assistant/assistant/doc/src/assistant-quick-guide.qdoc b/src/assistant/assistant/doc/src/assistant-quick-guide.qdoc
index 411bf19e1..2a8dc01e1 100644
--- a/src/assistant/assistant/doc/src/assistant-quick-guide.qdoc
+++ b/src/assistant/assistant/doc/src/assistant-quick-guide.qdoc
@@ -27,7 +27,6 @@
/*!
\if !defined(ASSISTANT_INTERNAL)
- \contentspage {Qt Assistant Manual}{Contents}
\previouspage Qt Assistant Manual
\endif
\page assistant-quick-guide.html
@@ -99,7 +98,6 @@
/*!
\if !defined(ASSISTANT_INTERNAL)
- \contentspage {Qt Assistant Manual}{Contents}
\nextpage Customizing Qt Assistant
\endif
\page assistant-details.html
diff --git a/src/assistant/assistant/helpdocsettings.cpp b/src/assistant/assistant/helpdocsettings.cpp
new file mode 100644
index 000000000..dc4afdb86
--- /dev/null
+++ b/src/assistant/assistant/helpdocsettings.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpdocsettings.h"
+
+#include <QtHelp/QCompressedHelpInfo>
+#include <QtHelp/QHelpEngineCore>
+#include <QtHelp/QHelpFilterEngine>
+
+#include <QtCore/QVersionNumber>
+
+#include <QtDebug>
+
+QT_BEGIN_NAMESPACE
+
+class HelpDocSettingsPrivate : public QSharedData
+{
+public:
+ HelpDocSettingsPrivate() = default;
+ HelpDocSettingsPrivate(const HelpDocSettingsPrivate &other) = default;
+ ~HelpDocSettingsPrivate() = default;
+
+ QMap<QString, QString> m_namespaceToComponent;
+ QMap<QString, QStringList> m_componentToNamespace;
+
+ QMap<QString, QVersionNumber> m_namespaceToVersion;
+ QMap<QVersionNumber, QStringList> m_versionToNamespace;
+
+ QMap<QString, QString> m_namespaceToFileName;
+ QMap<QString, QString> m_fileNameToNamespace;
+};
+
+
+HelpDocSettings::HelpDocSettings()
+ : d(new HelpDocSettingsPrivate)
+{
+}
+
+HelpDocSettings::HelpDocSettings(const HelpDocSettings &) = default;
+
+HelpDocSettings::HelpDocSettings(HelpDocSettings &&) = default;
+
+HelpDocSettings::~HelpDocSettings() = default;
+
+HelpDocSettings &HelpDocSettings::operator=(const HelpDocSettings &) = default;
+
+HelpDocSettings &HelpDocSettings::operator=(HelpDocSettings &&) = default;
+
+bool HelpDocSettings::addDocumentation(const QString &fileName)
+{
+ const QCompressedHelpInfo info = QCompressedHelpInfo::fromCompressedHelpFile(fileName);
+
+ if (info.isNull())
+ return false;
+
+ const QString namespaceName = info.namespaceName();
+
+ if (d->m_namespaceToFileName.contains(namespaceName))
+ return false;
+
+ if (d->m_fileNameToNamespace.contains(fileName))
+ return false;
+
+ const QString component = info.component();
+ const QVersionNumber version = info.version();
+
+ d->m_namespaceToFileName.insert(namespaceName, fileName);
+ d->m_fileNameToNamespace.insert(fileName, namespaceName);
+
+ d->m_namespaceToComponent.insert(namespaceName, component);
+ d->m_componentToNamespace[component].append(namespaceName);
+
+ d->m_namespaceToVersion.insert(namespaceName, version);
+ d->m_versionToNamespace[version].append(namespaceName);
+
+ return true;
+}
+
+bool HelpDocSettings::removeDocumentation(const QString &namespaceName)
+{
+ if (namespaceName.isEmpty())
+ return false;
+
+ const QString fileName = d->m_namespaceToFileName.value(namespaceName);
+ if (fileName.isEmpty())
+ return false;
+
+ const QString component = d->m_namespaceToComponent.value(namespaceName);
+ const QVersionNumber version = d->m_namespaceToVersion.value(namespaceName);
+
+ d->m_namespaceToComponent.remove(namespaceName);
+ d->m_namespaceToVersion.remove(namespaceName);
+ d->m_namespaceToFileName.remove(namespaceName);
+ d->m_fileNameToNamespace.remove(fileName);
+ d->m_componentToNamespace[component].removeOne(namespaceName);
+ if (d->m_componentToNamespace[component].isEmpty())
+ d->m_componentToNamespace.remove(component);
+ d->m_versionToNamespace[version].removeOne(namespaceName);
+ if (d->m_versionToNamespace[version].isEmpty())
+ d->m_versionToNamespace.remove(version);
+
+ return true;
+}
+
+QString HelpDocSettings::namespaceName(const QString &fileName) const
+{
+ return d->m_fileNameToNamespace.value(fileName);
+}
+
+QStringList HelpDocSettings::components() const
+{
+ return d->m_componentToNamespace.keys();
+}
+
+QList<QVersionNumber> HelpDocSettings::versions() const
+{
+ return d->m_versionToNamespace.keys();
+}
+
+QStringList HelpDocSettings::namespaces() const
+{
+ return d->m_namespaceToFileName.keys();
+}
+
+QMap<QString, QString> HelpDocSettings::namespaceToFileName() const
+{
+ return d->m_namespaceToFileName;
+}
+
+HelpDocSettings HelpDocSettings::readSettings(QHelpEngineCore *helpEngine)
+{
+ QHelpFilterEngine *filterEngine = helpEngine->filterEngine();
+
+ HelpDocSettings docSettings;
+ docSettings.d->m_namespaceToComponent = filterEngine->namespaceToComponent();
+ docSettings.d->m_namespaceToVersion = filterEngine->namespaceToVersion();
+ for (auto it = docSettings.d->m_namespaceToComponent.constBegin();
+ it != docSettings.d->m_namespaceToComponent.constEnd(); ++it) {
+ const QString namespaceName = it.key();
+ const QString namespaceFileName = helpEngine->documentationFileName(namespaceName);
+ docSettings.d->m_namespaceToFileName.insert(namespaceName, namespaceFileName);
+ docSettings.d->m_fileNameToNamespace.insert(namespaceFileName, namespaceName);
+ docSettings.d->m_componentToNamespace[it.value()].append(namespaceName);
+ }
+ for (auto it = docSettings.d->m_namespaceToVersion.constBegin();
+ it != docSettings.d->m_namespaceToVersion.constEnd(); ++it) {
+ docSettings.d->m_versionToNamespace[it.value()].append(it.key());
+ }
+
+ return docSettings;
+}
+
+static QMap<QString, QString> subtract(const QMap<QString, QString> &minuend,
+ const QMap<QString, QString> &subtrahend)
+{
+ auto result = minuend;
+
+ for (auto itSubtrahend = subtrahend.cbegin(); itSubtrahend != subtrahend.cend(); ++itSubtrahend) {
+ auto itResult = result.find(itSubtrahend.key());
+ if (itResult != result.end() && itSubtrahend.value() == itResult.value())
+ result.erase(itResult);
+ }
+
+ return result;
+}
+
+bool HelpDocSettings::applySettings(QHelpEngineCore *helpEngine,
+ const HelpDocSettings &settings)
+{
+ const HelpDocSettings oldSettings = readSettings(helpEngine);
+
+ const QMap<QString, QString> docsToRemove = subtract(
+ oldSettings.namespaceToFileName(),
+ settings.namespaceToFileName());
+ const QMap<QString, QString> docsToAdd = subtract(
+ settings.namespaceToFileName(),
+ oldSettings.namespaceToFileName());
+
+ bool changed = false;
+ for (const QString &namespaceName : docsToRemove.keys()) {
+ if (!helpEngine->unregisterDocumentation(namespaceName))
+ qWarning() << "Cannot unregister documentation:" << namespaceName;
+ changed = true;
+ }
+
+ for (const QString &fileName : docsToAdd.values()) {
+ if (!helpEngine->registerDocumentation(fileName))
+ qWarning() << "Cannot register documentation file:" << fileName;
+ changed = true;
+ }
+
+ return changed;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/assistant/helpdocsettings.h b/src/assistant/assistant/helpdocsettings.h
new file mode 100644
index 000000000..7476eb63a
--- /dev/null
+++ b/src/assistant/assistant/helpdocsettings.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPDOCSETTINGS_H
+#define HELPDOCSETTINGS_H
+
+#include <QtCore/QSharedDataPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QVersionNumber;
+class QHelpEngineCore;
+class HelpDocSettingsPrivate;
+
+class HelpDocSettings final
+{
+public:
+ HelpDocSettings();
+ HelpDocSettings(const HelpDocSettings &other);
+ HelpDocSettings(HelpDocSettings &&other);
+ ~HelpDocSettings();
+
+ HelpDocSettings &operator=(const HelpDocSettings &other);
+ HelpDocSettings &operator=(HelpDocSettings &&other);
+
+ void swap(HelpDocSettings &other) noexcept
+ { d.swap(other.d); }
+
+ bool addDocumentation(const QString &fileName);
+ bool removeDocumentation(const QString &namespaceName);
+ QString namespaceName(const QString &fileName) const;
+ QStringList components() const;
+ QList<QVersionNumber> versions() const;
+ QStringList namespaces() const;
+ QMap<QString, QString> namespaceToFileName() const;
+
+ static HelpDocSettings readSettings(QHelpEngineCore *helpEngine);
+ static bool applySettings(QHelpEngineCore *helpEngine, const HelpDocSettings &settings);
+
+private:
+ QSharedDataPointer<HelpDocSettingsPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPDOCSETTINGS_H
diff --git a/src/assistant/assistant/helpdocsettingswidget.cpp b/src/assistant/assistant/helpdocsettingswidget.cpp
new file mode 100644
index 000000000..94ca2b25a
--- /dev/null
+++ b/src/assistant/assistant/helpdocsettingswidget.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpdocsettings.h"
+#include "helpdocsettingswidget.h"
+#include "ui_helpdocsettingswidget.h"
+
+#include <QtWidgets/QFileDialog>
+#include <QtWidgets/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+class HelpDocSettingsWidgetPrivate
+{
+ HelpDocSettingsWidget *q_ptr;
+ Q_DECLARE_PUBLIC(HelpDocSettingsWidget)
+public:
+ HelpDocSettingsWidgetPrivate() = default;
+
+ void addDocumentation();
+ void removeDocumentation();
+ void applyDocListFilter(QListWidgetItem *item);
+
+ QMap<QString, QListWidgetItem *> m_namespaceToItem;
+ QHash<QListWidgetItem *, QString> m_itemToNamespace;
+
+ Ui::HelpDocSettingsWidget m_ui;
+ HelpDocSettings m_settings;
+};
+
+void HelpDocSettingsWidgetPrivate::addDocumentation()
+{
+ Q_Q(HelpDocSettingsWidget);
+
+ const QStringList &fileNames = QFileDialog::getOpenFileNames(q,
+ q->tr("Add Documentation"), QString(), q->tr("Qt Compressed Help Files (*.qch)"));
+ if (fileNames.isEmpty())
+ return;
+
+ bool added = false;
+
+ for (const QString &fileName : fileNames) {
+ if (!m_settings.addDocumentation(fileName))
+ continue;
+
+ if (!added) {
+ added = true;
+ m_ui.registeredDocsListWidget->clearSelection();
+ }
+
+ const QString namespaceName = m_settings.namespaceName(fileName);
+ QListWidgetItem *item = new QListWidgetItem(namespaceName);
+ m_namespaceToItem.insert(namespaceName, item);
+ m_itemToNamespace.insert(item, namespaceName);
+ m_ui.registeredDocsListWidget->insertItem(m_namespaceToItem.keys().indexOf(namespaceName), item);
+
+ item->setSelected(true);
+ applyDocListFilter(item);
+ }
+
+ if (added)
+ emit q->docSettingsChanged(m_settings);
+}
+
+void HelpDocSettingsWidgetPrivate::removeDocumentation()
+{
+ Q_Q(HelpDocSettingsWidget);
+
+ const QList<QListWidgetItem *> selectedItems = m_ui.registeredDocsListWidget->selectedItems();
+ if (selectedItems.isEmpty())
+ return;
+
+ for (QListWidgetItem *item : selectedItems) {
+ const QString namespaceName = m_itemToNamespace.value(item);
+ m_itemToNamespace.remove(item);
+ m_namespaceToItem.remove(namespaceName);
+ delete item;
+
+ m_settings.removeDocumentation(namespaceName);
+ }
+
+ emit q->docSettingsChanged(m_settings);
+}
+
+void HelpDocSettingsWidgetPrivate::applyDocListFilter(QListWidgetItem *item)
+{
+ const QString namespaceName = m_itemToNamespace.value(item);
+ const QString nameFilter = m_ui.registeredDocsFilterLineEdit->text();
+
+ const bool matches = nameFilter.isEmpty() || namespaceName.contains(nameFilter);
+
+ if (!matches)
+ item->setSelected(false);
+ item->setHidden(!matches);
+}
+
+HelpDocSettingsWidget::HelpDocSettingsWidget(QWidget *parent)
+ : QWidget(parent)
+ , d_ptr(new HelpDocSettingsWidgetPrivate())
+{
+ Q_D(HelpDocSettingsWidget);
+ d->q_ptr = this;
+ d->m_ui.setupUi(this);
+
+ connect(d->m_ui.docAddButton, &QAbstractButton::clicked,
+ [this]() {
+ Q_D(HelpDocSettingsWidget);
+ d->addDocumentation();
+ });
+ connect(d->m_ui.docRemoveButton, &QAbstractButton::clicked,
+ [this]() {
+ Q_D(HelpDocSettingsWidget);
+ d->removeDocumentation();
+ });
+ connect(d->m_ui.registeredDocsFilterLineEdit, &QLineEdit::textChanged,
+ [this](const QString &) {
+ Q_D(HelpDocSettingsWidget);
+ for (const auto item : d->m_namespaceToItem)
+ d->applyDocListFilter(item);
+ });
+ connect(d->m_ui.registeredDocsListWidget, &QListWidget::itemSelectionChanged,
+ [this]() {
+ Q_D(HelpDocSettingsWidget);
+ d->m_ui.docRemoveButton->setEnabled(
+ !d->m_ui.registeredDocsListWidget->selectedItems().isEmpty());
+ });
+}
+
+HelpDocSettingsWidget::~HelpDocSettingsWidget() = default;
+
+void HelpDocSettingsWidget::setDocSettings(const HelpDocSettings &settings)
+{
+ Q_D(HelpDocSettingsWidget);
+ d->m_settings = settings;
+
+ d->m_ui.registeredDocsListWidget->clear();
+ d->m_namespaceToItem.clear();
+ d->m_itemToNamespace.clear();
+
+ for (const QString &namespaceName : d->m_settings.namespaces()) {
+ QListWidgetItem *item = new QListWidgetItem(namespaceName);
+ d->m_namespaceToItem.insert(namespaceName, item);
+ d->m_itemToNamespace.insert(item, namespaceName);
+ d->m_ui.registeredDocsListWidget->addItem(item);
+ d->applyDocListFilter(item);
+ }
+
+ d->m_ui.docRemoveButton->setEnabled(
+ !d->m_ui.registeredDocsListWidget->selectedItems().isEmpty());
+}
+
+HelpDocSettings HelpDocSettingsWidget::docSettings() const
+{
+ Q_D(const HelpDocSettingsWidget);
+ return d->m_settings;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/assistant/helpdocsettingswidget.h b/src/assistant/assistant/helpdocsettingswidget.h
new file mode 100644
index 000000000..3ed089353
--- /dev/null
+++ b/src/assistant/assistant/helpdocsettingswidget.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPDOCSETTINGSWIDGET_H
+#define HELPDOCSETTINGSWIDGET_H
+
+#include <QtWidgets/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class HelpDocSettings;
+class HelpDocSettingsWidgetPrivate;
+
+class HelpDocSettingsWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ HelpDocSettingsWidget(QWidget *parent = nullptr);
+
+ ~HelpDocSettingsWidget();
+
+ void setDocSettings(const HelpDocSettings &settings);
+ HelpDocSettings docSettings() const;
+
+Q_SIGNALS:
+ void docSettingsChanged(const HelpDocSettings &settings);
+
+private:
+ QScopedPointer<class HelpDocSettingsWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(HelpDocSettingsWidget)
+ Q_DISABLE_COPY_MOVE(HelpDocSettingsWidget)
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/assistant/assistant/helpdocsettingswidget.ui b/src/assistant/assistant/helpdocsettingswidget.ui
new file mode 100644
index 000000000..4897dfe86
--- /dev/null
+++ b/src/assistant/assistant/helpdocsettingswidget.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>HelpDocSettingsWidget</class>
+ <widget class="QWidget" name="HelpDocSettingsWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>268</width>
+ <height>128</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="docLabel">
+ <property name="text">
+ <string>Registered Documentation</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLineEdit" name="registeredDocsFilterLineEdit">
+ <property name="placeholderText">
+ <string>&lt;Filter&gt;</string>
+ </property>
+ <property name="clearButtonEnabled">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" rowspan="2">
+ <layout class="QVBoxLayout" name="buttonLayout">
+ <item>
+ <widget class="QPushButton" name="docAddButton">
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="docRemoveButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="buttonSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <widget class="QListWidget" name="registeredDocsListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/assistant/helpenginewrapper.cpp b/src/assistant/assistant/helpenginewrapper.cpp
index 17e4bde8c..c927a2ef1 100644
--- a/src/assistant/assistant/helpenginewrapper.cpp
+++ b/src/assistant/assistant/helpenginewrapper.cpp
@@ -41,6 +41,7 @@
#include <QtHelp/QHelpEngine>
#include <QtHelp/QHelpFilterEngine>
#include <QtHelp/QHelpIndexModel>
+#include <QtHelp/QHelpLink>
#include <QtHelp/QHelpSearchEngine>
QT_BEGIN_NAMESPACE
@@ -261,10 +262,10 @@ QByteArray HelpEngineWrapper::fileData(const QUrl &url) const
return d->m_helpEngine->fileData(url);
}
-QMap<QString, QUrl> HelpEngineWrapper::linksForIdentifier(const QString &id) const
+QList<QHelpLink> HelpEngineWrapper::documentsForIdentifier(const QString &id) const
{
TRACE_OBJ
- return d->m_helpEngine->linksForIdentifier(id);
+ return d->m_helpEngine->documentsForIdentifier(id);
}
QString HelpEngineWrapper::error() const
@@ -670,6 +671,12 @@ void HelpEngineWrapper::setTopicChooserGeometry(const QByteArray &geometry)
d->m_helpEngine->setCustomValue(TopicChooserGeometryKey, geometry);
}
+QHelpEngineCore *HelpEngineWrapper::helpEngine() const
+{
+ return d->m_helpEngine;
+}
+
+
// -- TimeoutForwarder
TimeoutForwarder::TimeoutForwarder(const QString &fileName)
diff --git a/src/assistant/assistant/helpenginewrapper.h b/src/assistant/assistant/helpenginewrapper.h
index 6026a0473..df2ec8a73 100644
--- a/src/assistant/assistant/helpenginewrapper.h
+++ b/src/assistant/assistant/helpenginewrapper.h
@@ -46,6 +46,8 @@ class QHelpIndexModel;
class QHelpIndexWidget;
class QHelpSearchEngine;
class QHelpFilterEngine;
+class QHelpEngineCore;
+struct QHelpLink;
enum {
ShowHomePage = 0,
@@ -79,7 +81,7 @@ public:
bool unregisterDocumentation(const QString &namespaceName);
QUrl findFile(const QUrl &url) const;
QByteArray fileData(const QUrl &url) const;
- QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
+ QList<QHelpLink> documentsForIdentifier(const QString &id) const;
QString error() const;
QHelpFilterEngine *filterEngine() const;
@@ -175,6 +177,8 @@ public:
const QByteArray topicChooserGeometry() const;
void setTopicChooserGeometry(const QByteArray &geometry);
+ QHelpEngineCore *helpEngine() const;
+
signals:
// For asynchronous doc updates triggered by external actions.
diff --git a/src/assistant/assistant/helpviewer.h b/src/assistant/assistant/helpviewer.h
index 00e941000..667fa05a4 100644
--- a/src/assistant/assistant/helpviewer.h
+++ b/src/assistant/assistant/helpviewer.h
@@ -117,7 +117,7 @@ signals:
void sourceChanged(const QUrl &url);
void forwardAvailable(bool enabled);
void backwardAvailable(bool enabled);
- void highlighted(const QString &link);
+ void highlighted(const QUrl &link);
void printRequested();
#elif !defined(BROWSER_QTWEBKIT)
// Provide signals present in QWebView for browsers that do not inherit QWebView
diff --git a/src/assistant/assistant/helpviewer_qwv.cpp b/src/assistant/assistant/helpviewer_qwv.cpp
index f8acb7b46..7d9cfc07f 100644
--- a/src/assistant/assistant/helpviewer_qwv.cpp
+++ b/src/assistant/assistant/helpviewer_qwv.cpp
@@ -166,8 +166,10 @@ HelpViewer::HelpViewer(qreal zoom, QWidget *parent)
SLOT(actionChanged()));
connect(pageAction(QWebPage::Forward), SIGNAL(changed()), this,
SLOT(actionChanged()));
- connect(page(), SIGNAL(linkHovered(QString,QString,QString)), this,
- SIGNAL(highlighted(QString)));
+ connect(page(), &QWebPage::linkHovered, this,
+ [this] (const QString &link, const QString &, const QString &) {
+ emit this->highlighted(QUrl(link));
+ });
connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(sourceChanged(QUrl)));
connect(this, SIGNAL(loadStarted()), this, SLOT(setLoadStarted()));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool)));
diff --git a/src/assistant/assistant/indexwindow.cpp b/src/assistant/assistant/indexwindow.cpp
index d8c0f8212..c0647ca6f 100644
--- a/src/assistant/assistant/indexwindow.cpp
+++ b/src/assistant/assistant/indexwindow.cpp
@@ -44,6 +44,8 @@
#include <QtWidgets/QListWidgetItem>
#include <QtHelp/QHelpIndexWidget>
+#include <QtHelp/QHelpEngineCore>
+#include <QtHelp/QHelpLink>
QT_BEGIN_NAMESPACE
@@ -71,10 +73,12 @@ IndexWindow::IndexWindow(QWidget *parent)
this, &IndexWindow::disableSearchLineEdit);
connect(helpEngine.indexModel(), &QHelpIndexModel::indexCreated,
this, &IndexWindow::enableSearchLineEdit);
- connect(m_indexWidget, &QHelpIndexWidget::linkActivated,
- this, &IndexWindow::linkActivated);
- connect(m_indexWidget, &QHelpIndexWidget::linksActivated,
- this, &IndexWindow::linksActivated);
+ connect(m_indexWidget, &QHelpIndexWidget::documentActivated,
+ this, [this](const QHelpLink &link) {
+ emit linkActivated(link.url);
+ });
+ connect(m_indexWidget, &QHelpIndexWidget::documentsActivated,
+ this, &IndexWindow::documentsActivated);
connect(m_searchLineEdit, &QLineEdit::returnPressed,
m_indexWidget, &QHelpIndexWidget::activateCurrentItem);
layout->addWidget(m_indexWidget);
@@ -196,15 +200,15 @@ void IndexWindow::open(QHelpIndexWidget* indexWidget, const QModelIndex &index)
QHelpIndexModel *model = qobject_cast<QHelpIndexModel*>(indexWidget->model());
if (model) {
const QString keyword = model->data(index, Qt::DisplayRole).toString();
- const QMap<QString, QUrl> links = model->linksForKeyword(keyword);
+ const QList<QHelpLink> docs = model->helpEngine()->documentsForKeyword(keyword);
QUrl url;
- if (links.count() > 1) {
- TopicChooser tc(this, keyword, links);
+ if (docs.count() > 1) {
+ TopicChooser tc(this, keyword, docs);
if (tc.exec() == QDialog::Accepted)
url = tc.link();
- } else if (!links.isEmpty()) {
- url = links.first();
+ } else if (!docs.isEmpty()) {
+ url = docs.first().url;
} else {
return;
}
diff --git a/src/assistant/assistant/indexwindow.h b/src/assistant/assistant/indexwindow.h
index 647d3b3b9..be82543dd 100644
--- a/src/assistant/assistant/indexwindow.h
+++ b/src/assistant/assistant/indexwindow.h
@@ -37,6 +37,7 @@ QT_BEGIN_NAMESPACE
class QHelpIndexWidget;
class QModelIndex;
+struct QHelpLink;
class IndexWindow : public QWidget
{
@@ -54,8 +55,7 @@ public:
signals:
void linkActivated(const QUrl &link);
- void linksActivated(const QMap<QString, QUrl> &links,
- const QString &keyword);
+ void documentsActivated(const QList<QHelpLink> &documents, const QString &keyword);
void escapePressed();
private slots:
diff --git a/src/assistant/assistant/main.cpp b/src/assistant/assistant/main.cpp
index 3ddbdbc29..cd6487751 100644
--- a/src/assistant/assistant/main.cpp
+++ b/src/assistant/assistant/main.cpp
@@ -265,69 +265,49 @@ void setupTranslations()
} // Anonymous namespace.
-int main(int argc, char *argv[])
-{
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
- TRACE_OBJ
- QScopedPointer<QCoreApplication> a(createApplication(argc, argv));
-#if QT_CONFIG(library)
- a->addLibraryPath(a->applicationDirPath() + QLatin1String("/plugins"));
-#endif
- setupTranslations();
-
-#if defined(BROWSER_QTWEBKIT)
- if (qobject_cast<QApplication *>(a.data())) {
- QFont f;
- f.setStyleHint(QFont::SansSerif);
- QWebSettings::globalSettings()->setFontFamily(QWebSettings::StandardFont, f.defaultFamily());
- }
-#endif // BROWSER_QTWEBKIT
-
- // Parse arguments.
- CmdLineParser cmd(a->arguments());
- CmdLineParser::Result res = cmd.parse();
- if (res == CmdLineParser::Help)
- return 0;
- else if (res == CmdLineParser::Error)
- return -1;
+enum ExitStatus {
+ ExitSuccess = 0,
+ ExitFailure,
+ NoExit
+};
+static ExitStatus preliminarySetup(CmdLineParser *cmd)
+{
/*
* Create the collection objects that we need. We always have the
* cached collection file. Depending on whether the user specified
* one, we also may have an input collection file.
*/
- const QString collectionFile = cmd.collectionFile();
+ const QString collectionFile = cmd->collectionFile();
const bool collectionFileGiven = !collectionFile.isEmpty();
QScopedPointer<QHelpEngineCore> collection;
if (collectionFileGiven) {
collection.reset(new QHelpEngineCore(collectionFile));
collection->setProperty("_q_readonly", QVariant::fromValue<bool>(true));
if (!collection->setupData()) {
- cmd.showMessage(QCoreApplication::translate("Assistant",
- "Error reading collection file '%1': %2.").
- arg(collectionFile).arg(collection->error()), true);
- return EXIT_FAILURE;
+ cmd->showMessage(QCoreApplication::translate("Assistant",
+ "Error reading collection file '%1': %2.")
+ .arg(collectionFile).arg(collection->error()), true);
+ return ExitFailure;
}
}
const QString &cachedCollectionFile = collectionFileGiven
- ? constructCachedCollectionFilePath(*collection)
- : MainWindow::defaultHelpCollectionFileName();
+ ? constructCachedCollectionFilePath(*collection)
+ : MainWindow::defaultHelpCollectionFileName();
if (collectionFileGiven && !QFileInfo(cachedCollectionFile).exists()
- && !collection->copyCollectionFile(cachedCollectionFile)) {
- cmd.showMessage(QCoreApplication::translate("Assistant",
- "Error creating collection file '%1': %2.").
- arg(cachedCollectionFile).arg(collection->error()), true);
- return EXIT_FAILURE;
+ && !collection->copyCollectionFile(cachedCollectionFile)) {
+ cmd->showMessage(QCoreApplication::translate("Assistant",
+ "Error creating collection file '%1': %2.")
+ .arg(cachedCollectionFile).arg(collection->error()), true);
+ return ExitFailure;
}
QHelpEngineCore cachedCollection(cachedCollectionFile);
if (!cachedCollection.setupData()) {
- cmd.showMessage(QCoreApplication::translate("Assistant",
- "Error reading collection file '%1': %2.").
- arg(cachedCollectionFile).
- arg(cachedCollection.error()), true);
- return EXIT_FAILURE;
+ cmd->showMessage(QCoreApplication::translate("Assistant",
+ "Error reading collection file '%1': %2.")
+ .arg(cachedCollectionFile)
+ .arg(cachedCollection.error()), true);
+ return ExitFailure;
}
stripNonexistingDocs(cachedCollection);
@@ -335,56 +315,94 @@ int main(int argc, char *argv[])
if (CollectionConfiguration::isNewer(*collection, cachedCollection))
CollectionConfiguration::copyConfiguration(*collection,
cachedCollection);
- if (!synchronizeDocs(*collection, cachedCollection, cmd))
- return EXIT_FAILURE;
+ if (!synchronizeDocs(*collection, cachedCollection, *cmd))
+ return ExitFailure;
}
- if (cmd.registerRequest() != CmdLineParser::None) {
+ if (cmd->registerRequest() != CmdLineParser::None) {
const QStringList &cachedDocs =
- cachedCollection.registeredDocumentations();
+ cachedCollection.registeredDocumentations();
const QString &namespaceName =
- QHelpEngineCore::namespaceName(cmd.helpFile());
- if (cmd.registerRequest() == CmdLineParser::Register) {
+ QHelpEngineCore::namespaceName(cmd->helpFile());
+ if (cmd->registerRequest() == CmdLineParser::Register) {
if (collectionFileGiven
- && !registerDocumentation(*collection, cmd, true))
- return EXIT_FAILURE;
+ && !registerDocumentation(*collection, *cmd, true))
+ return ExitFailure;
if (!cachedDocs.contains(namespaceName)
- && !registerDocumentation(cachedCollection, cmd, !collectionFileGiven))
- return EXIT_FAILURE;
- return EXIT_SUCCESS;
+ && !registerDocumentation(cachedCollection, *cmd, !collectionFileGiven))
+ return ExitFailure;
+ return ExitSuccess;
}
- if (cmd.registerRequest() == CmdLineParser::Unregister) {
+ if (cmd->registerRequest() == CmdLineParser::Unregister) {
if (collectionFileGiven
- && !unregisterDocumentation(*collection, namespaceName, cmd, true))
- return EXIT_FAILURE;
+ && !unregisterDocumentation(*collection, namespaceName, *cmd, true))
+ return ExitFailure;
if (cachedDocs.contains(namespaceName)
- && !unregisterDocumentation(cachedCollection, namespaceName,
- cmd, !collectionFileGiven))
- return EXIT_FAILURE;
- return EXIT_SUCCESS;
+ && !unregisterDocumentation(cachedCollection, namespaceName,
+ *cmd, !collectionFileGiven))
+ return ExitFailure;
+ return ExitSuccess;
}
}
- if (cmd.removeSearchIndex()) {
+ if (cmd->removeSearchIndex()) {
return removeSearchIndex(cachedCollectionFile)
- ? EXIT_SUCCESS : EXIT_FAILURE;
+ ? ExitSuccess : ExitFailure;
}
if (!QSqlDatabase::isDriverAvailable(QLatin1String("QSQLITE"))) {
- cmd.showMessage(QCoreApplication::translate("Assistant",
- "Cannot load sqlite database driver!"),
- true);
- return EXIT_FAILURE;
+ cmd->showMessage(QCoreApplication::translate("Assistant",
+ "Cannot load sqlite database driver!"),
+ true);
+ return ExitFailure;
}
- if (!cmd.currentFilter().isEmpty()) {
+ if (!cmd->currentFilter().isEmpty()) {
if (collectionFileGiven)
- collection->setCurrentFilter(cmd.currentFilter());
- cachedCollection.setCurrentFilter(cmd.currentFilter());
+ collection->setCurrentFilter(cmd->currentFilter());
+ cachedCollection.setCurrentFilter(cmd->currentFilter());
}
if (collectionFileGiven)
- cmd.setCollectionFile(cachedCollectionFile);
+ cmd->setCollectionFile(cachedCollectionFile);
+
+ return NoExit;
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
+ TRACE_OBJ
+ QScopedPointer<QCoreApplication> a(createApplication(argc, argv));
+#if QT_CONFIG(library)
+ a->addLibraryPath(a->applicationDirPath() + QLatin1String("/plugins"));
+#endif
+ setupTranslations();
+
+#if defined(BROWSER_QTWEBKIT)
+ if (qobject_cast<QApplication *>(a.data())) {
+ QFont f;
+ f.setStyleHint(QFont::SansSerif);
+ QWebSettings::globalSettings()->setFontFamily(QWebSettings::StandardFont, f.defaultFamily());
+ }
+#endif // BROWSER_QTWEBKIT
+
+ // Parse arguments.
+ CmdLineParser cmd(a->arguments());
+ CmdLineParser::Result res = cmd.parse();
+ if (res == CmdLineParser::Help)
+ return 0;
+ else if (res == CmdLineParser::Error)
+ return -1;
+
+ const ExitStatus status = preliminarySetup(&cmd);
+ switch (status) {
+ case ExitFailure: return EXIT_FAILURE;
+ case ExitSuccess: return EXIT_SUCCESS;
+ default: break;
+ }
MainWindow *w = new MainWindow(&cmd);
w->show();
diff --git a/src/assistant/assistant/mainwindow.cpp b/src/assistant/assistant/mainwindow.cpp
index 11eda313c..5b0163fb1 100644
--- a/src/assistant/assistant/mainwindow.cpp
+++ b/src/assistant/assistant/mainwindow.cpp
@@ -60,7 +60,6 @@
#include <QtWidgets/QAction>
#include <QtWidgets/QComboBox>
-#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QDockWidget>
#include <QtGui/QFontDatabase>
#include <QtGui/QImageReader>
@@ -677,12 +676,12 @@ void MainWindow::setupActions()
connect(m_centralWidget, &CentralWidget::backwardAvailable,
globalActions, &GlobalActions::updateActions);
connect(m_centralWidget, &CentralWidget::highlighted,
- this, [this](const QString &link) { statusBar()->showMessage(link);} );
+ this, [this](const QUrl &link) { statusBar()->showMessage(link.toString());} );
// index window
connect(m_indexWindow, &IndexWindow::linkActivated,
m_centralWidget, &CentralWidget::setSource);
- connect(m_indexWindow, &IndexWindow::linksActivated,
+ connect(m_indexWindow, &IndexWindow::documentsActivated,
this, &MainWindow::showTopicChooser);
connect(m_indexWindow, &IndexWindow::escapePressed,
this, &MainWindow::activateCurrentCentralWidgetTab);
@@ -822,11 +821,11 @@ void MainWindow::gotoAddress()
m_centralWidget->setSource(m_addressLineEdit->text());
}
-void MainWindow::showTopicChooser(const QMap<QString, QUrl> &links,
+void MainWindow::showTopicChooser(const QList<QHelpLink> &documents,
const QString &keyword)
{
TRACE_OBJ
- TopicChooser tc(this, keyword, links);
+ TopicChooser tc(this, keyword, documents);
if (tc.exec() == QDialog::Accepted) {
m_centralWidget->setSource(tc.link());
}
diff --git a/src/assistant/assistant/mainwindow.h b/src/assistant/assistant/mainwindow.h
index c5bf5837e..b9d86cfc7 100644
--- a/src/assistant/assistant/mainwindow.h
+++ b/src/assistant/assistant/mainwindow.h
@@ -46,6 +46,7 @@ class ContentWindow;
class IndexWindow;
class QtDocInstaller;
class SearchWidget;
+struct QHelpLink;
class MainWindow : public QMainWindow
{
@@ -88,7 +89,7 @@ private slots:
void showNewAddress();
void showAboutDialog();
void showNewAddress(const QUrl &url);
- void showTopicChooser(const QMap<QString, QUrl> &links, const QString &keyword);
+ void showTopicChooser(const QList<QHelpLink> &documents, const QString &keyword);
void updateApplicationFont();
void filterDocumentation(int filterIndex);
void setupFilterCombo();
diff --git a/src/assistant/assistant/openpageswidget.cpp b/src/assistant/assistant/openpageswidget.cpp
index 6400fd97d..933304757 100644
--- a/src/assistant/assistant/openpageswidget.cpp
+++ b/src/assistant/assistant/openpageswidget.cpp
@@ -184,7 +184,7 @@ void OpenPagesWidget::handleClicked(const QModelIndex &index)
QWidget *vp = viewport();
const QPoint &cursorPos = QCursor::pos();
QMouseEvent e(QEvent::MouseMove, vp->mapFromGlobal(cursorPos), cursorPos,
- Qt::NoButton, nullptr, nullptr);
+ Qt::NoButton, {}, {});
QCoreApplication::sendEvent(vp, &e);
}
}
diff --git a/src/assistant/assistant/preferencesdialog.cpp b/src/assistant/assistant/preferencesdialog.cpp
index 66d6381d3..5dd24a102 100644
--- a/src/assistant/assistant/preferencesdialog.cpp
+++ b/src/assistant/assistant/preferencesdialog.cpp
@@ -28,42 +28,24 @@
#include "preferencesdialog.h"
#include "centralwidget.h"
-#include "filternamedialog.h"
#include "fontpanel.h"
#include "helpenginewrapper.h"
#include "openpagesmanager.h"
+#include "helpdocsettingswidget.h"
#include <QtCore/QVersionNumber>
+
#include <QtGui/QFontDatabase>
-#include <QtWidgets/QMessageBox>
-#include <QtHelp/QCompressedHelpInfo>
#include <QtHelp/QHelpEngineCore>
#include <QtHelp/QHelpFilterData>
#include <QtHelp/QHelpFilterEngine>
-
-#include <QtWidgets/QFileDialog>
+#include <QtHelp/QHelpFilterSettingsWidget>
#include <QtDebug>
QT_BEGIN_NAMESPACE
-static QStringList versionsToStringList(const QList<QVersionNumber> &versions)
-{
- QStringList versionList;
- for (const QVersionNumber &version : versions)
- versionList.append(version.isNull() ? QString() : version.toString());
- return versionList;
-}
-
-static QList<QVersionNumber> stringListToVersions(const QStringList &versionList)
-{
- QList<QVersionNumber> versions;
- for (const QString &versionString : versionList)
- versions.append(QVersionNumber::fromString(versionString));
- return versions;
-}
-
PreferencesDialog::PreferencesDialog(QWidget *parent)
: QDialog(parent)
, m_appFontChanged(false)
@@ -74,18 +56,6 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
{
m_ui.setupUi(this);
- QString resourcePath = QLatin1String(":/qt-project.org/assistant/images/");
-#ifdef Q_OS_MACOS
- resourcePath.append(QLatin1String("mac"));
-#else
- resourcePath.append(QLatin1String("win"));
-#endif
-
- m_ui.filterAddButton->setIcon(QIcon(resourcePath + QLatin1String("/plus.png")));
- m_ui.filterRemoveButton->setIcon(QIcon(resourcePath + QLatin1String("/minus.png")));
-
- // TODO: filter docs via lineedit
-
connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked,
this, &PreferencesDialog::okClicked);
connect(m_ui.buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked,
@@ -93,56 +63,30 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked,
this, &QDialog::reject);
- m_originalSetup = readOriginalSetup();
- m_currentSetup = m_originalSetup;
+ m_docSettings = HelpDocSettings::readSettings(helpEngine.helpEngine());
if (m_hideDocsTab) {
m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.docsTab));
} else {
- connect(m_ui.docAddButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::addDocumentation);
- connect(m_ui.docRemoveButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::removeDocumentation);
- connect(m_ui.registeredDocsFilterLineEdit, &QLineEdit::textChanged,
- this, [this](const QString &) {
- for (const auto item : m_namespaceToItem)
- applyDocListFilter(item);
- });
- connect(m_ui.registeredDocsListWidget, &QListWidget::itemSelectionChanged,
- this, [this](){
- m_ui.docRemoveButton->setEnabled(
- !m_ui.registeredDocsListWidget->selectedItems().isEmpty());
+ connect(m_ui.docSettingsWidget, &HelpDocSettingsWidget::docSettingsChanged,
+ [this](const HelpDocSettings &settings) {
+ m_docSettings = settings;
+ if (m_hideFiltersTab)
+ return;
+
+ m_ui.filterSettingsWidget->setAvailableComponents(m_docSettings.components());
+ m_ui.filterSettingsWidget->setAvailableVersions(m_docSettings.versions());
});
- updateDocumentationPage();
+ m_ui.docSettingsWidget->setDocSettings(m_docSettings);
}
if (m_hideFiltersTab) {
m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.filtersTab));
} else {
- connect(m_ui.componentWidget, &OptionsWidget::optionSelectionChanged,
- this, &PreferencesDialog::componentsChanged);
- connect(m_ui.versionWidget, &OptionsWidget::optionSelectionChanged,
- this, &PreferencesDialog::versionsChanged);
- connect(m_ui.filterWidget, &QListWidget::currentItemChanged,
- this, &PreferencesDialog::filterSelected);
- connect(m_ui.filterWidget, &QListWidget::itemDoubleClicked,
- this, &PreferencesDialog::renameFilterClicked);
-
- // TODO: repeat these actions on context menu
- connect(m_ui.filterAddButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::addFilterClicked);
- connect(m_ui.filterRenameButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::renameFilterClicked);
- connect(m_ui.filterRemoveButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::removeFilterClicked);
-
- m_ui.componentWidget->setNoOptionText(tr("No Component"));
- m_ui.componentWidget->setInvalidOptionText(tr("Invalid Component"));
- m_ui.versionWidget->setNoOptionText(tr("No Version"));
- m_ui.versionWidget->setInvalidOptionText(tr("Invalid Version"));
-
- updateFilterPage();
+ m_ui.filterSettingsWidget->setAvailableComponents(m_docSettings.components());
+ m_ui.filterSettingsWidget->setAvailableVersions(m_docSettings.versions());
+ m_ui.filterSettingsWidget->readSettings(helpEngine.filterEngine());
}
updateFontSettingsPage();
@@ -152,331 +96,6 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
setFont(helpEngine.appFont());
}
-FilterSetup PreferencesDialog::readOriginalSetup() const
-{
- FilterSetup filterSetup;
-
- filterSetup.m_namespaceToComponent = helpEngine.filterEngine()->namespaceToComponent();
- filterSetup.m_namespaceToVersion = helpEngine.filterEngine()->namespaceToVersion();
- for (auto it = filterSetup.m_namespaceToComponent.constBegin();
- it != filterSetup.m_namespaceToComponent.constEnd(); ++it) {
- const QString namespaceName = it.key();
- const QString namespaceFileName = helpEngine.documentationFileName(namespaceName);
- filterSetup.m_namespaceToFileName.insert(namespaceName, namespaceFileName);
- filterSetup.m_fileNameToNamespace.insert(namespaceFileName, namespaceName);
- filterSetup.m_componentToNamespace[it.value()].append(namespaceName);
- }
- for (auto it = filterSetup.m_namespaceToVersion.constBegin();
- it != filterSetup.m_namespaceToVersion.constEnd(); ++it) {
- filterSetup.m_versionToNamespace[it.value()].append(it.key());
- }
-
- const QStringList allFilters = helpEngine.filterEngine()->filters();
- for (const QString &filter : allFilters)
- filterSetup.m_filterToData.insert(filter, helpEngine.filterEngine()->filterData(filter));
-
- filterSetup.m_currentFilter = helpEngine.filterEngine()->activeFilter();
-
- return filterSetup;
-}
-
-void PreferencesDialog::updateFilterPage()
-{
- if (m_hideFiltersTab)
- return;
-
- QString currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
- if (currentFilter.isEmpty())
- currentFilter = m_currentSetup.m_currentFilter;
-
- m_currentSetup = m_originalSetup;
-
- m_ui.filterWidget->clear();
- m_ui.componentWidget->clear();
- m_ui.versionWidget->clear();
- m_itemToFilter.clear();
- m_filterToItem.clear();
-
- for (const QString &filterName : m_currentSetup.m_filterToData.keys()) {
- QListWidgetItem *item = new QListWidgetItem(filterName);
- m_ui.filterWidget->addItem(item);
- m_itemToFilter.insert(item, filterName);
- m_filterToItem.insert(filterName, item);
- if (filterName == currentFilter)
- m_ui.filterWidget->setCurrentItem(item);
- }
-
- if (!m_ui.filterWidget->currentItem() && !m_filterToItem.isEmpty())
- m_ui.filterWidget->setCurrentItem(m_filterToItem.first());
-
- updateCurrentFilter();
-}
-
-void PreferencesDialog::updateCurrentFilter()
-{
- if (m_hideFiltersTab)
- return;
-
- const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
-
- const bool filterSelected = !currentFilter.isEmpty();
- m_ui.componentWidget->setEnabled(filterSelected);
- m_ui.versionWidget->setEnabled(filterSelected);
- m_ui.filterRenameButton->setEnabled(filterSelected);
- m_ui.filterRemoveButton->setEnabled(filterSelected);
-
- m_ui.componentWidget->setOptions(m_currentSetup.m_componentToNamespace.keys(),
- m_currentSetup.m_filterToData.value(currentFilter).components());
- m_ui.versionWidget->setOptions(versionsToStringList(m_currentSetup.m_versionToNamespace.keys()),
- versionsToStringList(m_currentSetup.m_filterToData.value(currentFilter).versions()));
-}
-
-void PreferencesDialog::updateDocumentationPage()
-{
- if (m_hideDocsTab)
- return;
-
- m_ui.registeredDocsListWidget->clear();
- m_namespaceToItem.clear();
- m_itemToNamespace.clear();
-
- for (const QString &namespaceName : m_currentSetup.m_namespaceToFileName.keys()) {
- QListWidgetItem *item = new QListWidgetItem(namespaceName);
- m_namespaceToItem.insert(namespaceName, item);
- m_itemToNamespace.insert(item, namespaceName);
- applyDocListFilter(item);
- m_ui.registeredDocsListWidget->addItem(item);
- }
- m_ui.docRemoveButton->setEnabled(
- !m_ui.registeredDocsListWidget->selectedItems().isEmpty());
-}
-
-void PreferencesDialog::applyDocListFilter(QListWidgetItem *item)
-{
- const QString namespaceName = m_itemToNamespace.value(item);
- const QString nameFilter = m_ui.registeredDocsFilterLineEdit->text();
-
- const bool matches = nameFilter.isEmpty() || namespaceName.contains(nameFilter);
-
- if (!matches)
- item->setSelected(false);
- item->setHidden(!matches);
-}
-
-void PreferencesDialog::filterSelected(QListWidgetItem *item)
-{
- Q_UNUSED(item)
-
- updateCurrentFilter();
-}
-
-void PreferencesDialog::componentsChanged(const QStringList &components)
-{
- const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
- if (currentFilter.isEmpty())
- return;
-
- m_currentSetup.m_filterToData[currentFilter].setComponents(components);
-}
-
-void PreferencesDialog::versionsChanged(const QStringList &versions)
-{
- const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
- if (currentFilter.isEmpty())
- return;
-
- m_currentSetup.m_filterToData[currentFilter].setVersions(stringListToVersions(versions));
-}
-
-QString PreferencesDialog::suggestedNewFilterName(const QString &initialFilterName) const
-{
- QString newFilterName = initialFilterName;
-
- int counter = 1;
- while (m_filterToItem.contains(newFilterName)) {
- newFilterName = initialFilterName + QLatin1Char(' ')
- + QString::number(++counter);
- }
-
- return newFilterName;
-}
-
-QString PreferencesDialog::getUniqueFilterName(const QString &windowTitle,
- const QString &initialFilterName)
-{
- QString newFilterName = initialFilterName;
- while (1) {
- FilterNameDialog dialog(this);
- dialog.setWindowTitle(windowTitle);
- dialog.setFilterName(newFilterName);
- if (dialog.exec() == QDialog::Rejected)
- return QString();
-
- newFilterName = dialog.filterName();
- if (!m_filterToItem.contains(newFilterName))
- break;
-
- if (QMessageBox::warning(this, tr("Filter Exists"),
- tr("The filter \"%1\" already exists.")
- .arg(newFilterName),
- QMessageBox::Retry | QMessageBox::Cancel)
- == QMessageBox::Cancel) {
- return QString();
- }
- }
-
- return newFilterName;
-}
-
-void PreferencesDialog::addFilterClicked()
-{
- const QString newFilterName = getUniqueFilterName(tr("Add Filter"),
- suggestedNewFilterName(tr("New Filter")));
- if (newFilterName.isEmpty())
- return;
-
- addFilter(newFilterName);
-}
-
-void PreferencesDialog::renameFilterClicked()
-{
- const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
- if (currentFilter.isEmpty())
- return;
-
- const QString newFilterName = getUniqueFilterName(tr("Rename Filter"), currentFilter);
- if (newFilterName.isEmpty())
- return;
-
- const QHelpFilterData oldFilterData = m_currentSetup.m_filterToData.value(currentFilter);
- removeFilter(currentFilter);
- addFilter(newFilterName, oldFilterData);
-
- if (m_currentSetup.m_currentFilter == currentFilter)
- m_currentSetup.m_currentFilter = newFilterName;
-}
-
-void PreferencesDialog::removeFilterClicked()
-{
- const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
- if (currentFilter.isEmpty())
- return;
-
- if (QMessageBox::question(this, tr("Remove Filter"),
- tr("Are you sure you want to remove the \"%1\" filter?")
- .arg(currentFilter),
- QMessageBox::Yes | QMessageBox::No)
- != QMessageBox::Yes) {
- return;
- }
-
- removeFilter(currentFilter);
-
- if (m_currentSetup.m_currentFilter == currentFilter)
- m_currentSetup.m_currentFilter.clear();
-}
-
-void PreferencesDialog::addFilter(const QString &filterName,
- const QHelpFilterData &filterData)
-{
- QListWidgetItem *item = new QListWidgetItem(filterName);
- m_currentSetup.m_filterToData.insert(filterName, filterData);
- m_filterToItem.insert(filterName, item);
- m_itemToFilter.insert(item, filterName);
- m_ui.filterWidget->insertItem(m_filterToItem.keys().indexOf(filterName), item);
-
- m_ui.filterWidget->setCurrentItem(item);
- updateCurrentFilter();
-}
-
-void PreferencesDialog::removeFilter(const QString &filterName)
-{
- QListWidgetItem *item = m_filterToItem.value(filterName);
- m_itemToFilter.remove(item);
- m_filterToItem.remove(filterName);
- delete item;
-
- m_currentSetup.m_filterToData.remove(filterName);
-}
-
-void PreferencesDialog::addDocumentation()
-{
- const QStringList &fileNames = QFileDialog::getOpenFileNames(this,
- tr("Add Documentation"), QString(), tr("Qt Compressed Help Files (*.qch)"));
- if (fileNames.isEmpty())
- return;
-
- bool added = false;
-
- for (const QString &fileName : fileNames) {
- const QCompressedHelpInfo info = QCompressedHelpInfo::fromCompressedHelpFile(fileName);
- const QString namespaceName = info.namespaceName();
-
- if (m_currentSetup.m_namespaceToFileName.contains(namespaceName))
- continue;
-
- if (m_currentSetup.m_fileNameToNamespace.contains(fileName))
- continue;
-
- const QString component = info.component();
- const QVersionNumber version = info.version();
-
- m_currentSetup.m_namespaceToFileName.insert(namespaceName, fileName);
- m_currentSetup.m_fileNameToNamespace.insert(fileName, namespaceName);
-
- m_currentSetup.m_namespaceToComponent.insert(namespaceName, component);
- m_currentSetup.m_componentToNamespace[component].append(namespaceName);
-
- m_currentSetup.m_namespaceToVersion.insert(namespaceName, version);
- m_currentSetup.m_versionToNamespace[version].append(namespaceName);
-
- if (!added) {
- added = true;
- m_ui.registeredDocsListWidget->clearSelection();
- }
-
- QListWidgetItem *item = new QListWidgetItem(namespaceName);
- m_namespaceToItem.insert(namespaceName, item);
- m_itemToNamespace.insert(item, namespaceName);
- m_ui.registeredDocsListWidget->insertItem(m_namespaceToItem.keys().indexOf(namespaceName), item);
- item->setSelected(true);
- applyDocListFilter(item);
- }
-
- if (added)
- updateCurrentFilter();
-}
-
-void PreferencesDialog::removeDocumentation()
-{
- const QList<QListWidgetItem *> selectedItems = m_ui.registeredDocsListWidget->selectedItems();
- if (selectedItems.isEmpty())
- return;
-
- for (QListWidgetItem *item : selectedItems) {
- const QString namespaceName = m_itemToNamespace.value(item);
- m_itemToNamespace.remove(item);
- m_namespaceToItem.remove(namespaceName);
- delete item;
-
- const QString fileName = m_currentSetup.m_namespaceToFileName.value(namespaceName);
- const QString component = m_currentSetup.m_namespaceToComponent.value(namespaceName);
- const QVersionNumber version = m_currentSetup.m_namespaceToVersion.value(namespaceName);
- m_currentSetup.m_namespaceToComponent.remove(namespaceName);
- m_currentSetup.m_namespaceToVersion.remove(namespaceName);
- m_currentSetup.m_namespaceToFileName.remove(namespaceName);
- m_currentSetup.m_fileNameToNamespace.remove(fileName);
- m_currentSetup.m_componentToNamespace[component].removeOne(namespaceName);
- if (m_currentSetup.m_componentToNamespace[component].isEmpty())
- m_currentSetup.m_componentToNamespace.remove(component);
- m_currentSetup.m_versionToNamespace[version].removeOne(namespaceName);
- if (m_currentSetup.m_versionToNamespace[version].isEmpty())
- m_currentSetup.m_versionToNamespace.remove(version);
- }
-
- updateCurrentFilter();
-}
-
void PreferencesDialog::okClicked()
{
applyChanges();
@@ -486,74 +105,27 @@ void PreferencesDialog::okClicked()
void PreferencesDialog::applyClicked()
{
applyChanges();
- m_originalSetup = readOriginalSetup();
- m_currentSetup = m_originalSetup;
- updateDocumentationPage();
- updateFilterPage();
-}
-template <class T>
-static QMap<QString, T> subtract(const QMap<QString, T> &minuend,
- const QMap<QString, T> &subtrahend)
-{
- QMap<QString, T> result = minuend;
+ m_docSettings = HelpDocSettings::readSettings(helpEngine.helpEngine());
- for (auto itSubtrahend = subtrahend.cbegin(); itSubtrahend != subtrahend.cend(); ++itSubtrahend) {
- auto itResult = result.find(itSubtrahend.key());
- if (itResult != result.end() && itSubtrahend.value() == itResult.value())
- result.erase(itResult);
+ if (!m_hideDocsTab)
+ m_ui.docSettingsWidget->setDocSettings(m_docSettings);
+ if (!m_hideFiltersTab) {
+ m_ui.filterSettingsWidget->setAvailableComponents(m_docSettings.components());
+ m_ui.filterSettingsWidget->setAvailableVersions(m_docSettings.versions());
+ m_ui.filterSettingsWidget->readSettings(helpEngine.filterEngine());
}
-
- return result;
}
void PreferencesDialog::applyChanges()
{
bool changed = false;
-
- const QMap<QString, QString> docsToRemove = subtract(
- m_originalSetup.m_namespaceToFileName,
- m_currentSetup.m_namespaceToFileName);
- const QMap<QString, QString> docsToAdd = subtract(
- m_currentSetup.m_namespaceToFileName,
- m_originalSetup.m_namespaceToFileName);
-
- for (const QString &namespaceName : docsToRemove.keys()) {
- if (!helpEngine.unregisterDocumentation(namespaceName))
- qWarning() << "Cannot unregister documentation:" << namespaceName;
- changed = true;
- }
-
- for (const QString &fileName : docsToAdd.values()) {
- if (!helpEngine.registerDocumentation(fileName))
- qWarning() << "Cannot register documentation file:" << fileName;
- changed = true;
- }
-
- const QMap<QString, QHelpFilterData> filtersToRemove = subtract(
- m_originalSetup.m_filterToData,
- m_currentSetup.m_filterToData);
- const QMap<QString, QHelpFilterData> filtersToAdd = subtract(
- m_currentSetup.m_filterToData,
- m_originalSetup.m_filterToData);
-
- const QString &currentFilter = helpEngine.filterEngine()->activeFilter();
-
- for (const QString &filter : filtersToRemove.keys()) {
- helpEngine.filterEngine()->removeFilter(filter);
- if (currentFilter == filter && !filtersToAdd.contains(filter))
- helpEngine.filterEngine()->setActiveFilter(QString());
- changed = true;
- }
-
- for (auto it = filtersToAdd.cbegin(); it != filtersToAdd.cend(); ++it) {
- helpEngine.filterEngine()->setFilterData(it.key(), it.value());
- changed = true;
- }
+ if (!m_hideDocsTab)
+ changed = HelpDocSettings::applySettings(helpEngine.helpEngine(), m_docSettings);
+ if (!m_hideFiltersTab)
+ changed = changed || m_ui.filterSettingsWidget->applySettings(helpEngine.filterEngine());
if (changed) {
- helpEngine.filterEngine()->setActiveFilter(m_currentSetup.m_currentFilter);
-
// In order to update the filtercombobox and indexwidget
// according to the new filter configuration.
helpEngine.setupData();
@@ -628,13 +200,13 @@ void PreferencesDialog::updateFontSettingsPage()
const QList<QComboBox*> &appCombos = m_appFontPanel->findChildren<QComboBox*>();
for (QComboBox* box : appCombos) {
- connect(box, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(box, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &PreferencesDialog::appFontSettingChanged);
}
const QList<QComboBox*> &browserCombos = m_browserFontPanel->findChildren<QComboBox*>();
for (QComboBox* box : browserCombos) {
- connect(box, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(box, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &PreferencesDialog::browserFontSettingChanged);
}
}
diff --git a/src/assistant/assistant/preferencesdialog.h b/src/assistant/assistant/preferencesdialog.h
index b0601e280..a65066fde 100644
--- a/src/assistant/assistant/preferencesdialog.h
+++ b/src/assistant/assistant/preferencesdialog.h
@@ -29,31 +29,17 @@
#ifndef PREFERENCESDIALOG_H
#define PREFERENCESDIALOG_H
-#include <QtCore/QVersionNumber>
+#include <QtCore/QMap>
#include <QtWidgets/QDialog>
#include <QtHelp/QHelpFilterData>
#include "ui_preferencesdialog.h"
+#include "helpdocsettings.h"
QT_BEGIN_NAMESPACE
class FontPanel;
class HelpEngineWrapper;
class QFileSystemWatcher;
-class QVersionNumber;
-
-struct FilterSetup {
- QMap<QString, QString> m_namespaceToComponent;
- QMap<QString, QStringList> m_componentToNamespace;
-
- QMap<QString, QVersionNumber> m_namespaceToVersion;
- QMap<QVersionNumber, QStringList> m_versionToNamespace;
-
- QMap<QString, QString> m_namespaceToFileName;
- QMap<QString, QString> m_fileNameToNamespace;
-
- QMap<QString, QHelpFilterData> m_filterToData;
- QString m_currentFilter;
-};
class PreferencesDialog : public QDialog
{
@@ -63,17 +49,6 @@ public:
PreferencesDialog(QWidget *parent = nullptr);
private slots:
- void filterSelected(QListWidgetItem *item);
- void componentsChanged(const QStringList &components);
- void versionsChanged(const QStringList &versions);
- void addFilterClicked();
- void renameFilterClicked();
- void removeFilterClicked();
- void addFilter(const QString &filterName,
- const QHelpFilterData &filterData = QHelpFilterData());
- void removeFilter(const QString &filterName);
- void addDocumentation();
- void removeDocumentation();
void okClicked();
void applyClicked();
void applyChanges();
@@ -92,28 +67,12 @@ signals:
void updateUserInterface();
private:
- QString suggestedNewFilterName(const QString &initialFilterName) const;
- QString getUniqueFilterName(const QString &windowTitle,
- const QString &initialFilterName = QString());
- void applyDocListFilter(QListWidgetItem *item);
-
- void updateFilterPage();
- void updateCurrentFilter();
- void updateDocumentationPage();
void updateFontSettingsPage();
void updateOptionsPage();
- FilterSetup readOriginalSetup() const;
Ui::PreferencesDialogClass m_ui;
- FilterSetup m_originalSetup;
- FilterSetup m_currentSetup;
-
- QMap<QString, QListWidgetItem *> m_namespaceToItem;
- QHash<QListWidgetItem *, QString> m_itemToNamespace;
-
- QMap<QString, QListWidgetItem *> m_filterToItem;
- QHash<QListWidgetItem *, QString> m_itemToFilter;
+ HelpDocSettings m_docSettings;
FontPanel *m_appFontPanel;
FontPanel *m_browserFontPanel;
diff --git a/src/assistant/assistant/preferencesdialog.ui b/src/assistant/assistant/preferencesdialog.ui
index 68dbf68e2..2d1c480a6 100644
--- a/src/assistant/assistant/preferencesdialog.ui
+++ b/src/assistant/assistant/preferencesdialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>395</width>
- <height>341</height>
+ <height>376</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,7 +17,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
- <number>1</number>
+ <number>2</number>
</property>
<widget class="QWidget" name="fontsTab">
<attribute name="title">
@@ -69,60 +69,21 @@
<attribute name="title">
<string>Filters</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="3">
- <widget class="QLabel" name="componentsLabel">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="text">
- <string>Components:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QLabel" name="versionsLabel">
- <property name="text">
- <string>Versions:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="3">
- <widget class="QListWidget" name="filterWidget"/>
- </item>
- <item row="1" column="3" rowspan="2">
- <widget class="OptionsWidget" name="componentWidget" native="true"/>
- </item>
- <item row="1" column="4" rowspan="2">
- <widget class="OptionsWidget" name="versionWidget" native="true"/>
- </item>
- <item row="2" column="0">
- <widget class="QToolButton" name="filterAddButton">
- <property name="text">
- <string>Add...</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QToolButton" name="filterRenameButton">
- <property name="text">
- <string>Rename...</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QToolButton" name="filterRemoveButton">
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="3">
- <widget class="QLabel" name="filterLabel">
- <property name="text">
- <string>Filter:</string>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QHelpFilterSettingsWidget" name="filterSettingsWidget" native="true"/>
</item>
</layout>
</widget>
@@ -130,61 +91,21 @@
<attribute name="title">
<string>Documentation</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Registered Documentation:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLineEdit" name="registeredDocsFilterLineEdit">
- <property name="placeholderText">
- <string>&lt;Filter&gt;</string>
- </property>
- <property name="clearButtonEnabled">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1" rowspan="2">
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <widget class="QPushButton" name="docAddButton">
- <property name="text">
- <string>Add...</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="docRemoveButton">
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="2" column="0">
- <widget class="QListWidget" name="registeredDocsListWidget">
- <property name="selectionMode">
- <enum>QAbstractItemView::ExtendedSelection</enum>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="HelpDocSettingsWidget" name="docSettingsWidget" native="true"/>
</item>
</layout>
</widget>
@@ -359,9 +280,15 @@
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
- <class>OptionsWidget</class>
+ <class>HelpDocSettingsWidget</class>
+ <extends>QWidget</extends>
+ <header>helpdocsettingswidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QHelpFilterSettingsWidget</class>
<extends>QWidget</extends>
- <header>optionswidget.h</header>
+ <header>qhelpfiltersettingswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
diff --git a/src/assistant/assistant/remotecontrol.cpp b/src/assistant/assistant/remotecontrol.cpp
index 7fdbee41e..0c9cc6c14 100644
--- a/src/assistant/assistant/remotecontrol.cpp
+++ b/src/assistant/assistant/remotecontrol.cpp
@@ -44,6 +44,7 @@
#include <QtHelp/QHelpEngine>
#include <QtHelp/QHelpFilterEngine>
#include <QtHelp/QHelpIndexWidget>
+#include <QtHelp/QHelpLink>
#include <QtHelp/QHelpSearchQueryWidget>
#ifdef Q_OS_WIN
@@ -199,9 +200,9 @@ void RemoteControl::handleActivateIdentifierCommand(const QString &arg)
clearCache();
m_activateIdentifier = arg;
} else {
- const QMap<QString, QUrl> links = helpEngine.linksForIdentifier(arg);
- if (!links.isEmpty())
- CentralWidget::instance()->setSource(links.first());
+ const auto docs = helpEngine.documentsForIdentifier(arg);
+ if (!docs.isEmpty())
+ CentralWidget::instance()->setSource(docs.first().url);
}
}
@@ -266,10 +267,10 @@ void RemoteControl::applyCache()
m_mainWindow->setIndexString(m_activateKeyword);
helpEngine.indexWidget()->activateCurrentItem();
} else if (!m_activateIdentifier.isEmpty()) {
- const QMap<QString, QUrl> links =
- helpEngine.linksForIdentifier(m_activateIdentifier);
- if (!links.isEmpty())
- CentralWidget::instance()->setSource(links.first());
+ const auto docs =
+ helpEngine.documentsForIdentifier(m_activateIdentifier);
+ if (!docs.isEmpty())
+ CentralWidget::instance()->setSource(docs.first().url);
} else if (!m_currentFilter.isEmpty()) {
helpEngine.filterEngine()->setActiveFilter(m_currentFilter);
}
diff --git a/src/assistant/assistant/topicchooser.cpp b/src/assistant/assistant/topicchooser.cpp
index d058646c5..ec9faddb6 100644
--- a/src/assistant/assistant/topicchooser.cpp
+++ b/src/assistant/assistant/topicchooser.cpp
@@ -35,9 +35,11 @@
#include <QSortFilterProxyModel>
#include <QUrl>
+#include <QtHelp/QHelpLink>
+
QT_BEGIN_NAMESPACE
-TopicChooser::TopicChooser(QWidget *parent, const QString &keyword, const QMap<QString, QUrl> &links)
+TopicChooser::TopicChooser(QWidget *parent, const QString &keyword, const QList<QHelpLink> &docs)
: QDialog(parent)
, m_filterModel(new QSortFilterProxyModel(this))
{
@@ -53,10 +55,10 @@ TopicChooser::TopicChooser(QWidget *parent, const QString &keyword, const QMap<Q
m_filterModel->setSourceModel(model);
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
- for (auto it = links.cbegin(), end = links.cend(); it != end; ++it) {
- m_links.append(it.value());
- QStandardItem *item = new QStandardItem(it.key());
- item->setToolTip(it.value().toString());
+ for (const auto &doc : docs) {
+ m_links.append(doc.url);
+ QStandardItem *item = new QStandardItem(doc.title);
+ item->setToolTip(doc.url.toString());
model->appendRow(item);
}
diff --git a/src/assistant/assistant/topicchooser.h b/src/assistant/assistant/topicchooser.h
index 730ad68a0..2406ef99f 100644
--- a/src/assistant/assistant/topicchooser.h
+++ b/src/assistant/assistant/topicchooser.h
@@ -36,13 +36,14 @@
QT_BEGIN_NAMESPACE
class QSortFilterProxyModel;
+struct QHelpLink;
class TopicChooser : public QDialog
{
Q_OBJECT
public:
- TopicChooser(QWidget *parent, const QString &keyword, const QMap<QString, QUrl> &links);
+ TopicChooser(QWidget *parent, const QString &keyword, const QList<QHelpLink> &docs);
~TopicChooser() override;
QUrl link() const;
diff --git a/src/assistant/help/Qt5HelpConfigExtras.cmake.in b/src/assistant/help/Qt5HelpConfigExtras.cmake.in
index 3b97923a9..1f7544b62 100644
--- a/src/assistant/help/Qt5HelpConfigExtras.cmake.in
+++ b/src/assistant/help/Qt5HelpConfigExtras.cmake.in
@@ -28,3 +28,14 @@ if (NOT TARGET Qt5::qhelpgenerator)
IMPORTED_LOCATION ${imported_location}
)
endif()
+
+# Create versionless tool targets.
+foreach(__qt_tool qcollectiongenerator qhelpgenerator)
+ if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::${__qt_tool}
+ AND TARGET Qt5::${__qt_tool})
+ add_executable(Qt::${__qt_tool} IMPORTED)
+ get_target_property(__qt_imported_location Qt5::${__qt_tool} IMPORTED_LOCATION)
+ set_target_properties(Qt::${__qt_tool}
+ PROPERTIES IMPORTED_LOCATION \"${__qt_imported_location}\")
+ endif()
+endforeach()
diff --git a/src/assistant/help/help.pro b/src/assistant/help/help.pro
index cd7781dde..800c4a38d 100644
--- a/src/assistant/help/help.pro
+++ b/src/assistant/help/help.pro
@@ -12,13 +12,17 @@ DEFINES -= QT_ASCII_CAST_WARNINGS
RESOURCES += helpsystem.qrc
SOURCES += \
qcompressedhelpinfo.cpp \
+ qfilternamedialog.cpp \
qhelpenginecore.cpp \
qhelpengine.cpp \
qhelpfilterdata.cpp \
qhelpfilterengine.cpp \
+ qhelpfiltersettings.cpp \
+ qhelpfiltersettingswidget.cpp \
qhelpdbreader.cpp \
qhelpcontentwidget.cpp \
qhelpindexwidget.cpp \
+ qhelplink.cpp \
qhelpcollectionhandler.cpp \
qhelpsearchengine.cpp \
qhelpsearchquerywidget.cpp \
@@ -26,25 +30,36 @@ SOURCES += \
qhelpsearchindexwriter_default.cpp \
qhelpsearchindexreader_default.cpp \
qhelpsearchindexreader.cpp \
- qhelp_global.cpp
+ qhelp_global.cpp \
+ qoptionswidget.cpp
HEADERS += \
qcompressedhelpinfo.h \
+ qfilternamedialog_p.h \
qhelpenginecore.h \
qhelpengine.h \
qhelpengine_p.h \
qhelpfilterdata.h \
qhelpfilterengine.h \
+ qhelpfiltersettings_p.h \
+ qhelpfiltersettingswidget.h \
qhelp_global.h \
qhelpdbreader_p.h \
qhelpcontentwidget.h \
qhelpindexwidget.h \
+ qhelplink.h \
qhelpcollectionhandler_p.h \
qhelpsearchengine.h \
qhelpsearchquerywidget.h \
qhelpsearchresultwidget.h \
qhelpsearchindexwriter_default_p.h \
qhelpsearchindexreader_default_p.h \
- qhelpsearchindexreader_p.h
+ qhelpsearchindexreader_p.h \
+ qoptionswidget_p.h
+
+FORMS += \
+ qhelpfiltersettingswidget.ui \
+ qfilternamedialog.ui
+
load(qt_module)
diff --git a/src/assistant/help/helpsystem.qrc b/src/assistant/help/helpsystem.qrc
index 785923aad..611008639 100644
--- a/src/assistant/help/helpsystem.qrc
+++ b/src/assistant/help/helpsystem.qrc
@@ -4,5 +4,9 @@
<file>images/1rightarrow.png</file>
<file>images/3leftarrow.png</file>
<file>images/3rightarrow.png</file>
+ <file>images/mac/minus.png</file>
+ <file>images/mac/plus.png</file>
+ <file>images/win/minus.png</file>
+ <file>images/win/plus.png</file>
</qresource>
</RCC>
diff --git a/src/assistant/assistant/images/mac/minus.png b/src/assistant/help/images/mac/minus.png
index 8d2eaed52..8d2eaed52 100644
--- a/src/assistant/assistant/images/mac/minus.png
+++ b/src/assistant/help/images/mac/minus.png
Binary files differ
diff --git a/src/assistant/assistant/images/mac/plus.png b/src/assistant/help/images/mac/plus.png
index 1ee45423e..1ee45423e 100644
--- a/src/assistant/assistant/images/mac/plus.png
+++ b/src/assistant/help/images/mac/plus.png
Binary files differ
diff --git a/src/assistant/assistant/images/win/minus.png b/src/assistant/help/images/win/minus.png
index c0dc274bb..c0dc274bb 100644
--- a/src/assistant/assistant/images/win/minus.png
+++ b/src/assistant/help/images/win/minus.png
Binary files differ
diff --git a/src/assistant/assistant/images/win/plus.png b/src/assistant/help/images/win/plus.png
index ecf058941..ecf058941 100644
--- a/src/assistant/assistant/images/win/plus.png
+++ b/src/assistant/help/images/win/plus.png
Binary files differ
diff --git a/src/assistant/help/qcompressedhelpinfo.cpp b/src/assistant/help/qcompressedhelpinfo.cpp
index bbdc64157..a3c5b75d5 100644
--- a/src/assistant/help/qcompressedhelpinfo.cpp
+++ b/src/assistant/help/qcompressedhelpinfo.cpp
@@ -55,12 +55,14 @@ public:
, m_namespaceName(other.m_namespaceName)
, m_component(other.m_component)
, m_version(other.m_version)
+ , m_isNull(other.m_isNull)
{ }
~QCompressedHelpInfoPrivate() = default;
QString m_namespaceName;
QString m_component;
QVersionNumber m_version;
+ bool m_isNull = true;
};
/*!
@@ -151,6 +153,15 @@ QVersionNumber QCompressedHelpInfo::version() const
}
/*!
+ Returns \c true if the info is invalid, otherwise returns
+ \c false.
+*/
+bool QCompressedHelpInfo::isNull() const
+{
+ return d->m_isNull;
+}
+
+/*!
Returns the QCompressedHelpInfo instance for the
\a documentationFileName of the existing qch file.
*/
@@ -164,6 +175,7 @@ QCompressedHelpInfo QCompressedHelpInfo::fromCompressedHelpFile(const QString &d
info.d->m_namespaceName = reader.namespaceName();
info.d->m_component = reader.virtualFolder();
info.d->m_version = QVersionNumber::fromString(reader.version());
+ info.d->m_isNull = false;
return info;
}
return QCompressedHelpInfo();
diff --git a/src/assistant/help/qcompressedhelpinfo.h b/src/assistant/help/qcompressedhelpinfo.h
index c392bb74c..7b3c78c12 100644
--- a/src/assistant/help/qcompressedhelpinfo.h
+++ b/src/assistant/help/qcompressedhelpinfo.h
@@ -66,6 +66,7 @@ public:
QString namespaceName() const;
QString component() const;
QVersionNumber version() const;
+ bool isNull() const;
static QCompressedHelpInfo fromCompressedHelpFile(const QString &documentationFileName);
diff --git a/src/assistant/assistant/filternamedialog.cpp b/src/assistant/help/qfilternamedialog.cpp
index 4c17d3332..8563a3355 100644
--- a/src/assistant/assistant/filternamedialog.cpp
+++ b/src/assistant/help/qfilternamedialog.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Assistant of the Qt Toolkit.
@@ -28,11 +28,11 @@
#include <QtWidgets/QPushButton>
-#include "filternamedialog.h"
+#include "qfilternamedialog_p.h"
QT_BEGIN_NAMESPACE
-FilterNameDialog::FilterNameDialog(QWidget *parent)
+QFilterNameDialog::QFilterNameDialog(QWidget *parent)
: QDialog(parent)
{
m_ui.setupUi(this);
@@ -41,22 +41,22 @@ FilterNameDialog::FilterNameDialog(QWidget *parent)
connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked,
this, &QDialog::reject);
connect(m_ui.lineEdit, &QLineEdit::textChanged,
- this, &FilterNameDialog::updateOkButton);
+ this, &QFilterNameDialog::updateOkButton);
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true);
}
-void FilterNameDialog::setFilterName(const QString &filter)
+void QFilterNameDialog::setFilterName(const QString &filter)
{
m_ui.lineEdit->setText(filter);
m_ui.lineEdit->selectAll();
}
-QString FilterNameDialog::filterName() const
+QString QFilterNameDialog::filterName() const
{
return m_ui.lineEdit->text();
}
-void FilterNameDialog::updateOkButton()
+void QFilterNameDialog::updateOkButton()
{
m_ui.buttonBox->button(QDialogButtonBox::Ok)
->setDisabled(m_ui.lineEdit->text().isEmpty());
diff --git a/src/assistant/assistant/filternamedialog.ui b/src/assistant/help/qfilternamedialog.ui
index 1da584a80..1da584a80 100644
--- a/src/assistant/assistant/filternamedialog.ui
+++ b/src/assistant/help/qfilternamedialog.ui
diff --git a/src/assistant/assistant/filternamedialog.h b/src/assistant/help/qfilternamedialog_p.h
index 522b611af..76a495d78 100644
--- a/src/assistant/assistant/filternamedialog.h
+++ b/src/assistant/help/qfilternamedialog_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Assistant of the Qt Toolkit.
@@ -26,20 +26,31 @@
**
****************************************************************************/
-#ifndef FILTERNAMEDIALOG_H
-#define FILTERNAMEDIALOG_H
+#ifndef QFILTERNAMEDIALOG_H
+#define QFILTERNAMEDIALOG_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
#include <QtWidgets/QDialog>
-#include "ui_filternamedialog.h"
+#include "ui_qfilternamedialog.h"
QT_BEGIN_NAMESPACE
-class FilterNameDialog : public QDialog
+class QFilterNameDialog : public QDialog
{
Q_OBJECT
public:
- FilterNameDialog(QWidget *parent = nullptr);
+ QFilterNameDialog(QWidget *parent = nullptr);
void setFilterName(const QString &filter);
QString filterName() const;
@@ -53,4 +64,4 @@ private:
QT_END_NAMESPACE
-#endif // FILTERNAMEDIALOG_H
+#endif // QFILTERNAMEDIALOG_H
diff --git a/src/assistant/help/qhelpcollectionhandler.cpp b/src/assistant/help/qhelpcollectionhandler.cpp
index a7bea5494..29178bb55 100644
--- a/src/assistant/help/qhelpcollectionhandler.cpp
+++ b/src/assistant/help/qhelpcollectionhandler.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QVector>
#include <QtCore/QVersionNumber>
+#include <QtHelp/QHelpLink>
+
#include <QtSql/QSqlError>
#include <QtSql/QSqlDriver>
@@ -588,13 +590,13 @@ QStringList QHelpCollectionHandler::availableComponents() const
return list;
}
-QStringList QHelpCollectionHandler::availableVersions() const
+QList<QVersionNumber> QHelpCollectionHandler::availableVersions() const
{
- QStringList list;
+ QList<QVersionNumber> list;
if (m_query) {
m_query->exec(QLatin1String("SELECT DISTINCT Version FROM VersionTable ORDER BY Version"));
while (m_query->next())
- list.append(m_query->value(0).toString());
+ list.append(QVersionNumber::fromString(m_query->value(0).toString()));
}
return list;
}
@@ -2354,7 +2356,8 @@ QMap<QString, QUrl> QHelpCollectionHandler::linksForField(const QString &fieldNa
if (title.isEmpty()) // generate a title + corresponding path
title = fieldValue + QLatin1String(" : ") + m_query->value(3).toString();
- linkMap.insertMulti(title, buildQUrl(m_query->value(1).toString(),
+ static_cast<QMultiMap<QString, QUrl> &>(linkMap).insert(title, buildQUrl(
+ m_query->value(1).toString(),
m_query->value(2).toString(),
m_query->value(3).toString(),
m_query->value(4).toString()));
@@ -2374,14 +2377,38 @@ QMap<QString, QUrl> QHelpCollectionHandler::linksForKeyword(const QString &keywo
return linksForField(QLatin1String("Name"), keyword, filterName);
}
+QList<QHelpLink> QHelpCollectionHandler::documentsForIdentifier(const QString &id,
+ const QString &filterName) const
+{
+ return documentsForField(QLatin1String("Identifier"), id, filterName);
+}
+
+QList<QHelpLink> QHelpCollectionHandler::documentsForKeyword(const QString &keyword,
+ const QString &filterName) const
+{
+ return documentsForField(QLatin1String("Name"), keyword, filterName);
+}
+
QMap<QString, QUrl> QHelpCollectionHandler::linksForField(const QString &fieldName,
const QString &fieldValue,
const QString &filterName) const
{
QMap<QString, QUrl> linkMap;
+ const auto documents = documentsForField(fieldName, fieldValue, filterName);
+ for (const auto &document : documents)
+ static_cast<QMultiMap<QString, QUrl> &>(linkMap).insert(document.title, document.url);
+
+ return linkMap;
+}
+
+QList<QHelpLink> QHelpCollectionHandler::documentsForField(const QString &fieldName,
+ const QString &fieldValue,
+ const QString &filterName) const
+{
+ QList<QHelpLink> docList;
if (!isDBOpened())
- return linkMap;
+ return docList;
const QString filterlessQuery = QString::fromLatin1(
"SELECT "
@@ -2401,7 +2428,8 @@ QMap<QString, QUrl> QHelpCollectionHandler::linksForField(const QString &fieldNa
"AND IndexTable.%1 = ?").arg(fieldName);
const QString filterQuery = filterlessQuery
- + prepareFilterQuery(filterName);
+ + prepareFilterQuery(filterName)
+ + QLatin1String(" ORDER BY LOWER(FileNameTable.Title), FileNameTable.Title");
m_query->prepare(filterQuery);
m_query->bindValue(0, fieldValue);
@@ -2414,12 +2442,13 @@ QMap<QString, QUrl> QHelpCollectionHandler::linksForField(const QString &fieldNa
if (title.isEmpty()) // generate a title + corresponding path
title = fieldValue + QLatin1String(" : ") + m_query->value(3).toString();
- linkMap.insertMulti(title, buildQUrl(m_query->value(1).toString(),
- m_query->value(2).toString(),
- m_query->value(3).toString(),
- m_query->value(4).toString()));
+ const QUrl url = buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(),
+ m_query->value(3).toString(),
+ m_query->value(4).toString());
+ docList.append(QHelpLink {url, title});
}
- return linkMap;
+ return docList;
}
QStringList QHelpCollectionHandler::namespacesForFilter(const QString &filterName) const
diff --git a/src/assistant/help/qhelpcollectionhandler_p.h b/src/assistant/help/qhelpcollectionhandler_p.h
index 7679fccf7..83178f388 100644
--- a/src/assistant/help/qhelpcollectionhandler_p.h
+++ b/src/assistant/help/qhelpcollectionhandler_p.h
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
class QVersionNumber;
class QHelpFilterData;
+struct QHelpLink;
class QHelpCollectionHandler : public QObject
{
@@ -153,12 +154,19 @@ public:
QMap<QString, QUrl> linksForKeyword(const QString &keyword,
const QStringList &filterAttributes) const;
+ // use documentsForIdentifier instead
+ QMap<QString, QUrl> linksForIdentifier(const QString &id,
+ const QString &filterName) const;
+
+ // use documentsForKeyword instead
+ QMap<QString, QUrl> linksForKeyword(const QString &keyword,
+ const QString &filterName) const;
// *** Legacy block end ***
QStringList filters() const;
QStringList availableComponents() const;
- QStringList availableVersions() const;
+ QList<QVersionNumber> availableVersions() const;
QMap<QString, QString> namespaceToComponent() const;
QMap<QString, QVersionNumber> namespaceToVersion() const;
QHelpFilterData filterData(const QString &filterName) const;
@@ -196,10 +204,11 @@ public:
int registerComponent(const QString &componentName, int namespaceId);
bool registerVersion(const QString &version, int namespaceId);
- QMap<QString, QUrl> linksForIdentifier(const QString &id,
- const QString &filterName) const;
- QMap<QString, QUrl> linksForKeyword(const QString &keyword,
- const QString &filterName) const;
+ QList<QHelpLink> documentsForIdentifier(const QString &id,
+ const QString &filterName) const;
+ QList<QHelpLink> documentsForKeyword(const QString &keyword,
+ const QString &filterName) const;
+
QStringList namespacesForFilter(const QString &filterName) const;
void setReadOnly(bool readOnly);
@@ -217,6 +226,10 @@ private:
QMap<QString, QUrl> linksForField(const QString &fieldName,
const QString &fieldValue,
const QString &filterName) const;
+ QList<QHelpLink> documentsForField(const QString &fieldName,
+ const QString &fieldValue,
+ const QString &filterName) const;
+
bool isDBOpened() const;
bool createTables(QSqlQuery *query);
void closeDB();
diff --git a/src/assistant/help/qhelpengine_p.h b/src/assistant/help/qhelpengine_p.h
index 558013e77..4d2773b83 100644
--- a/src/assistant/help/qhelpengine_p.h
+++ b/src/assistant/help/qhelpengine_p.h
@@ -97,7 +97,6 @@ private slots:
void errorReceived(const QString &msg);
};
-
class QHelpEnginePrivate : public QHelpEngineCorePrivate
{
Q_OBJECT
diff --git a/src/assistant/help/qhelpenginecore.cpp b/src/assistant/help/qhelpenginecore.cpp
index f61c2207d..6f1a7a840 100644
--- a/src/assistant/help/qhelpenginecore.cpp
+++ b/src/assistant/help/qhelpenginecore.cpp
@@ -48,6 +48,7 @@
#include <QtCore/QPluginLoader>
#include <QtCore/QFileInfo>
#include <QtCore/QThread>
+#include <QtHelp/QHelpLink>
#include <QtWidgets/QApplication>
#include <QtSql/QSqlQuery>
@@ -110,12 +111,9 @@ void QHelpEngineCorePrivate::errorReceived(const QString &msg)
undefined meaning unusable state.
The core help engine can be used to perform different tasks.
- By calling linksForIdentifier() the engine returns
+ By calling documentsForIdentifier() the engine returns
URLs specifying the file locations inside the help system. The
- actual file data can then be retrived by calling fileData(). In
- contrast to all other functions in this class, linksForIdentifier()
- depends on the currently set custom filter. Depending on the filter,
- the function may return different results.
+ actual file data can then be retrived by calling fileData().
The help engine can contain any number of custom filters.
The management of the filters, including adding new filters,
@@ -612,7 +610,12 @@ QByteArray QHelpEngineCore::fileData(const QUrl &url) const
return d->collectionHandler->fileData(url);
}
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
+ \obsolete
+
+ Use documentsForIdentifier() instead.
+
Returns a map of the documents found for the \a id. The map contains the
document titles and their URLs. The returned map contents depend on
the current filter, and therefore only the identifiers registered for
@@ -629,8 +632,44 @@ QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id) const
// obsolete
return d->collectionHandler->linksForIdentifier(id, filterAttributes(d->currentFilter));
}
+#endif
+
+/*!
+ \since 5.15
+
+ Returns a list of all the document links found for the \a id.
+ The returned list contents depend on the current filter, and therefore only the keywords
+ registered for the current filter will be returned.
+*/
+QList<QHelpLink> QHelpEngineCore::documentsForIdentifier(const QString &id) const
+{
+ return documentsForIdentifier(id, d->usesFilterEngine
+ ? d->filterEngine->activeFilter()
+ : d->currentFilter);
+}
/*!
+ \since 5.15
+
+ Returns a list of the document links found for the \a id, filtered by \a filterName.
+ The returned list contents depend on the passed filter, and therefore only the keywords
+ registered for this filter will be returned. If you want to get all results unfiltered,
+ pass empty string as \a filterName.
+*/
+QList<QHelpLink> QHelpEngineCore::documentsForIdentifier(const QString &id, const QString &filterName) const
+{
+ if (!d->setup() || !d->usesFilterEngine)
+ return QList<QHelpLink>();
+
+ return d->collectionHandler->documentsForIdentifier(id, filterName);
+}
+
+#if QT_DEPRECATED_SINCE(5, 15)
+/*!
+ \obsolete
+
+ Use documentsForKeyword() instead.
+
Returns a map of all the documents found for the \a keyword. The map
contains the document titles and URLs. The returned map contents depend
on the current filter, and therefore only the keywords registered for
@@ -644,8 +683,40 @@ QMap<QString, QUrl> QHelpEngineCore::linksForKeyword(const QString &keyword) con
if (d->usesFilterEngine)
return d->collectionHandler->linksForKeyword(keyword, d->filterEngine->activeFilter());
+ // obsolete
return d->collectionHandler->linksForKeyword(keyword, filterAttributes(d->currentFilter));
}
+#endif
+
+/*!
+ \since 5.15
+
+ Returns a list of all the document links found for the \a keyword.
+ The returned list contents depend on the current filter, and therefore only the keywords
+ registered for the current filter will be returned.
+*/
+QList<QHelpLink> QHelpEngineCore::documentsForKeyword(const QString &keyword) const
+{
+ return documentsForKeyword(keyword, d->usesFilterEngine
+ ? d->filterEngine->activeFilter()
+ : d->currentFilter);
+}
+
+/*!
+ \since 5.15
+
+ Returns a list of the document links found for the \a keyword, filtered by \a filterName.
+ The returned list contents depend on the passed filter, and therefore only the keywords
+ registered for this filter will be returned. If you want to get all results unfiltered,
+ pass empty string as \a filterName.
+*/
+QList<QHelpLink> QHelpEngineCore::documentsForKeyword(const QString &keyword, const QString &filterName) const
+{
+ if (!d->setup() || !d->usesFilterEngine)
+ return QList<QHelpLink>();
+
+ return d->collectionHandler->documentsForKeyword(keyword, filterName);
+}
/*!
Removes the \a key from the settings section in the
diff --git a/src/assistant/help/qhelpenginecore.h b/src/assistant/help/qhelpenginecore.h
index 91950290e..0a5faca55 100644
--- a/src/assistant/help/qhelpenginecore.h
+++ b/src/assistant/help/qhelpenginecore.h
@@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE
class QHelpEngineCorePrivate;
class QHelpFilterEngine;
+struct QHelpLink;
class QHELP_EXPORT QHelpEngineCore : public QObject
{
@@ -102,8 +103,17 @@ public:
const QString &extensionFilter = QString());
QUrl findFile(const QUrl &url) const;
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use documentsForIdentifier() instead")
QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
+ QT_DEPRECATED_X("Use documentsForKeyword() instead")
QMap<QString, QUrl> linksForKeyword(const QString &keyword) const;
+#endif
+
+ QList<QHelpLink> documentsForIdentifier(const QString &id) const;
+ QList<QHelpLink> documentsForIdentifier(const QString &id, const QString &filterName) const;
+ QList<QHelpLink> documentsForKeyword(const QString &keyword) const;
+ QList<QHelpLink> documentsForKeyword(const QString &keyword, const QString &filterName) const;
bool removeCustomValue(const QString &key);
QVariant customValue(const QString &key,
diff --git a/src/assistant/help/qhelpfilterengine.cpp b/src/assistant/help/qhelpfilterengine.cpp
index a53be506e..a25976269 100644
--- a/src/assistant/help/qhelpfilterengine.cpp
+++ b/src/assistant/help/qhelpfilterengine.cpp
@@ -204,6 +204,19 @@ QStringList QHelpFilterEngine::availableComponents() const
}
/*!
+ \since 5.15
+
+ Returns the list of all available versions defined in all
+ registered documentation files.
+*/
+QList<QVersionNumber> QHelpFilterEngine::availableVersions() const
+{
+ if (!d->setup())
+ return QList<QVersionNumber>();
+ return d->m_collectionHandler->availableVersions();
+}
+
+/*!
Returns the filter details associated with \a filterName.
*/
QHelpFilterData QHelpFilterEngine::filterData(const QString &filterName) const
@@ -287,4 +300,32 @@ QStringList QHelpFilterEngine::namespacesForFilter(const QString &filterName) co
return d->m_collectionHandler->namespacesForFilter(filterName);
}
+/*!
+ \since 5.15
+
+ Returns a sorted list of available indices.
+ The returned list contents depend on the active filter, and therefore only
+ the indices registered for the active filter will be returned.
+*/
+QStringList QHelpFilterEngine::indices() const
+{
+ return indices(activeFilter());
+}
+
+/*!
+ \since 5.15
+
+ Returns a sorted list of available indices, filtered by \a filterName.
+ The returned list contents depend on the passed filter, and therefore only
+ the indices registered for this filter will be returned.
+ If you want to get all available indices unfiltered,
+ pass empty string as \a filterName.
+*/
+QStringList QHelpFilterEngine::indices(const QString &filterName) const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->m_collectionHandler->indicesForFilter(filterName);
+}
+
QT_END_NAMESPACE
diff --git a/src/assistant/help/qhelpfilterengine.h b/src/assistant/help/qhelpfilterengine.h
index c4bd139f2..d06d18b04 100644
--- a/src/assistant/help/qhelpfilterengine.h
+++ b/src/assistant/help/qhelpfilterengine.h
@@ -68,6 +68,7 @@ public:
bool setActiveFilter(const QString &filterName);
QStringList availableComponents() const;
+ QList<QVersionNumber> availableVersions() const;
QHelpFilterData filterData(const QString &filterName) const;
bool setFilterData(const QString &filterName, const QHelpFilterData &filterData);
@@ -76,6 +77,9 @@ public:
QStringList namespacesForFilter(const QString &filterName) const;
+ QStringList indices() const;
+ QStringList indices(const QString &filterName) const;
+
Q_SIGNALS:
void filterActivated(const QString &newFilter);
diff --git a/src/assistant/help/qhelpfiltersettings.cpp b/src/assistant/help/qhelpfiltersettings.cpp
new file mode 100644
index 000000000..206692179
--- /dev/null
+++ b/src/assistant/help/qhelpfiltersettings.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpfiltersettings_p.h"
+#include "qhelpfilterdata.h"
+
+#include <QtCore/QMap>
+#include <QtHelp/QHelpFilterEngine>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpFilterSettingsPrivate : public QSharedData
+{
+public:
+ QHelpFilterSettingsPrivate() = default;
+ QHelpFilterSettingsPrivate(const QHelpFilterSettingsPrivate &other) = default;
+ ~QHelpFilterSettingsPrivate() = default;
+
+ QMap<QString, QHelpFilterData> m_filterToData;
+ QString m_currentFilter;
+};
+
+QHelpFilterSettings::QHelpFilterSettings()
+ : d(new QHelpFilterSettingsPrivate)
+{
+}
+
+QHelpFilterSettings::QHelpFilterSettings(const QHelpFilterSettings &) = default;
+
+QHelpFilterSettings::QHelpFilterSettings(QHelpFilterSettings &&) = default;
+
+QHelpFilterSettings::~QHelpFilterSettings() = default;
+
+QHelpFilterSettings &QHelpFilterSettings::operator=(const QHelpFilterSettings &) = default;
+
+QHelpFilterSettings &QHelpFilterSettings::operator=(QHelpFilterSettings &&) = default;
+
+void QHelpFilterSettings::setFilter(const QString &filterName,
+ const QHelpFilterData &filterData)
+{
+ d->m_filterToData.insert(filterName, filterData);
+}
+
+void QHelpFilterSettings::removeFilter(const QString &filterName)
+{
+ d->m_filterToData.remove(filterName);
+}
+
+QStringList QHelpFilterSettings::filterNames() const
+{
+ return d->m_filterToData.keys();
+}
+
+QHelpFilterData QHelpFilterSettings::filterData(const QString &filterName) const
+{
+ return d->m_filterToData.value(filterName);
+}
+
+QMap<QString, QHelpFilterData> QHelpFilterSettings::filters() const
+{
+ return d->m_filterToData;
+}
+
+void QHelpFilterSettings::setCurrentFilter(const QString &filterName)
+{
+ d->m_currentFilter = filterName;
+}
+
+QString QHelpFilterSettings::currentFilter() const
+{
+ return d->m_currentFilter;
+}
+
+QHelpFilterSettings QHelpFilterSettings::readSettings(const QHelpFilterEngine *filterEngine)
+{
+ QHelpFilterSettings filterSettings;
+
+ const QStringList allFilters = filterEngine->filters();
+ for (const QString &filter : allFilters)
+ filterSettings.setFilter(filter, filterEngine->filterData(filter));
+
+ filterSettings.setCurrentFilter(filterEngine->activeFilter());
+
+ return filterSettings;
+}
+
+static QMap<QString, QHelpFilterData> subtract(const QMap<QString, QHelpFilterData> &minuend,
+ const QMap<QString, QHelpFilterData> &subtrahend)
+{
+ QMap<QString, QHelpFilterData> result = minuend;
+
+ for (auto itSubtrahend = subtrahend.cbegin(); itSubtrahend != subtrahend.cend(); ++itSubtrahend) {
+ auto itResult = result.find(itSubtrahend.key());
+ if (itResult != result.end() && itSubtrahend.value() == itResult.value())
+ result.erase(itResult);
+ }
+
+ return result;
+}
+
+bool QHelpFilterSettings::applySettings(QHelpFilterEngine *filterEngine,
+ const QHelpFilterSettings &settings)
+{
+ bool changed = false;
+ const QHelpFilterSettings oldSettings = readSettings(filterEngine);
+
+ const QMap<QString, QHelpFilterData> filtersToRemove = subtract(
+ oldSettings.filters(),
+ settings.filters());
+ const QMap<QString, QHelpFilterData> filtersToAdd = subtract(
+ settings.filters(),
+ oldSettings.filters());
+
+ const QString &currentFilter = filterEngine->activeFilter();
+
+ for (const QString &filter : filtersToRemove.keys()) {
+ filterEngine->removeFilter(filter);
+ if (currentFilter == filter && !filtersToAdd.contains(filter))
+ filterEngine->setActiveFilter(QString());
+ changed = true;
+ }
+
+ for (auto it = filtersToAdd.cbegin(); it != filtersToAdd.cend(); ++it) {
+ filterEngine->setFilterData(it.key(), it.value());
+ changed = true;
+ }
+
+ if (changed)
+ filterEngine->setActiveFilter(settings.currentFilter());
+
+ return changed;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/help/qhelpfiltersettings_p.h b/src/assistant/help/qhelpfiltersettings_p.h
new file mode 100644
index 000000000..cf5622b6d
--- /dev/null
+++ b/src/assistant/help/qhelpfiltersettings_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPFILTERSETTINGS_H
+#define QHELPFILTERSETTINGS_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QSharedDataPointer>
+
+QT_BEGIN_NAMESPACE
+
+template <class K, class T>
+class QMap;
+class QHelpFilterData;
+class QHelpFilterEngine;
+class QHelpFilterSettingsPrivate;
+
+class QHelpFilterSettings final
+{
+public:
+ QHelpFilterSettings();
+ QHelpFilterSettings(const QHelpFilterSettings &other);
+ QHelpFilterSettings(QHelpFilterSettings &&other);
+ ~QHelpFilterSettings();
+
+ QHelpFilterSettings &operator=(const QHelpFilterSettings &other);
+ QHelpFilterSettings &operator=(QHelpFilterSettings &&other);
+
+ void swap(QHelpFilterSettings &other) noexcept
+ { d.swap(other.d); }
+
+ void setFilter(const QString &filterName, const QHelpFilterData &filterData);
+ void removeFilter(const QString &filterName);
+ QStringList filterNames() const;
+ QHelpFilterData filterData(const QString &filterName) const;
+ QMap<QString, QHelpFilterData> filters() const;
+
+ void setCurrentFilter(const QString &filterName);
+ QString currentFilter() const;
+
+ static QHelpFilterSettings readSettings(const QHelpFilterEngine *filterEngine);
+ static bool applySettings(QHelpFilterEngine *filterEngine, const QHelpFilterSettings &settings);
+
+private:
+ QSharedDataPointer<QHelpFilterSettingsPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QHELPFILTERSETTINGS_H
diff --git a/src/assistant/help/qhelpfiltersettingswidget.cpp b/src/assistant/help/qhelpfiltersettingswidget.cpp
new file mode 100644
index 000000000..660420f1b
--- /dev/null
+++ b/src/assistant/help/qhelpfiltersettingswidget.cpp
@@ -0,0 +1,424 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpfilterdata.h"
+#include "qhelpfiltersettings_p.h"
+#include "qhelpfiltersettingswidget.h"
+#include "ui_qhelpfiltersettingswidget.h"
+#include "qfilternamedialog_p.h"
+
+#include <QtWidgets/QMessageBox>
+#include <QtCore/QVersionNumber>
+
+QT_BEGIN_NAMESPACE
+
+static QStringList versionsToStringList(const QList<QVersionNumber> &versions)
+{
+ QStringList versionList;
+ for (const QVersionNumber &version : versions)
+ versionList.append(version.isNull() ? QString() : version.toString());
+ return versionList;
+}
+
+static QList<QVersionNumber> stringListToVersions(const QStringList &versionList)
+{
+ QList<QVersionNumber> versions;
+ for (const QString &versionString : versionList)
+ versions.append(QVersionNumber::fromString(versionString));
+ return versions;
+}
+
+class QHelpFilterSettingsWidgetPrivate
+{
+ QHelpFilterSettingsWidget *q_ptr;
+ Q_DECLARE_PUBLIC(QHelpFilterSettingsWidget)
+public:
+ QHelpFilterSettingsWidgetPrivate() = default;
+
+ QHelpFilterSettings filterSettings() const;
+ void setFilterSettings(const QHelpFilterSettings &settings);
+
+ void updateCurrentFilter();
+ void componentsChanged(const QStringList &components);
+ void versionsChanged(const QStringList &versions);
+ void addFilterClicked();
+ void renameFilterClicked();
+ void removeFilterClicked();
+ void addFilter(const QString &filterName,
+ const QHelpFilterData &filterData = QHelpFilterData());
+ void removeFilter(const QString &filterName);
+ QString getUniqueFilterName(const QString &windowTitle,
+ const QString &initialFilterName);
+ QString suggestedNewFilterName(const QString &initialFilterName) const;
+
+ QMap<QString, QListWidgetItem *> m_filterToItem;
+ QHash<QListWidgetItem *, QString> m_itemToFilter;
+
+ Ui::QHelpFilterSettingsWidget m_ui;
+ QStringList m_components;
+ QList<QVersionNumber> m_versions;
+ QHelpFilterSettings m_filterSettings;
+};
+
+void QHelpFilterSettingsWidgetPrivate::setFilterSettings(const QHelpFilterSettings &settings)
+{
+ QString currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty()) {
+ if (!m_filterSettings.currentFilter().isEmpty())
+ currentFilter = m_filterSettings.currentFilter();
+ else
+ currentFilter = settings.currentFilter();
+ }
+
+ m_filterSettings = settings;
+
+ m_ui.filterWidget->clear();
+ m_ui.componentWidget->clear();
+ m_ui.versionWidget->clear();
+ m_itemToFilter.clear();
+ m_filterToItem.clear();
+
+ for (const QString &filterName : m_filterSettings.filterNames()) {
+ QListWidgetItem *item = new QListWidgetItem(filterName);
+ m_ui.filterWidget->addItem(item);
+ m_itemToFilter.insert(item, filterName);
+ m_filterToItem.insert(filterName, item);
+ if (filterName == currentFilter)
+ m_ui.filterWidget->setCurrentItem(item);
+ }
+
+ if (!m_ui.filterWidget->currentItem() && !m_filterToItem.isEmpty())
+ m_ui.filterWidget->setCurrentItem(m_filterToItem.first());
+
+ updateCurrentFilter();
+}
+
+QHelpFilterSettings QHelpFilterSettingsWidgetPrivate::filterSettings() const
+{
+ return m_filterSettings;
+}
+
+void QHelpFilterSettingsWidgetPrivate::updateCurrentFilter()
+{
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+
+ const bool filterSelected = !currentFilter.isEmpty();
+ m_ui.componentWidget->setEnabled(filterSelected);
+ m_ui.versionWidget->setEnabled(filterSelected);
+ m_ui.renameButton->setEnabled(filterSelected);
+ m_ui.removeButton->setEnabled(filterSelected);
+
+ m_ui.componentWidget->setOptions(m_components,
+ m_filterSettings.filterData(currentFilter).components());
+ m_ui.versionWidget->setOptions(versionsToStringList(m_versions),
+ versionsToStringList(m_filterSettings.filterData(currentFilter).versions()));
+}
+
+void QHelpFilterSettingsWidgetPrivate::componentsChanged(const QStringList &components)
+{
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty())
+ return;
+
+ QHelpFilterData filterData = m_filterSettings.filterData(currentFilter);
+ filterData.setComponents(components);
+ m_filterSettings.setFilter(currentFilter, filterData);
+}
+
+void QHelpFilterSettingsWidgetPrivate::versionsChanged(const QStringList &versions)
+{
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty())
+ return;
+
+ QHelpFilterData filterData = m_filterSettings.filterData(currentFilter);
+ filterData.setVersions(stringListToVersions(versions));
+ m_filterSettings.setFilter(currentFilter, filterData);
+}
+
+void QHelpFilterSettingsWidgetPrivate::addFilterClicked()
+{
+ const QString newFilterName = getUniqueFilterName(QHelpFilterSettingsWidget::tr("Add Filter"),
+ suggestedNewFilterName(QHelpFilterSettingsWidget::tr("New Filter")));
+ if (newFilterName.isEmpty())
+ return;
+
+ addFilter(newFilterName);
+}
+
+void QHelpFilterSettingsWidgetPrivate::renameFilterClicked()
+{
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty())
+ return;
+
+ const QString newFilterName = getUniqueFilterName(QHelpFilterSettingsWidget::tr("Rename Filter"), currentFilter);
+ if (newFilterName.isEmpty())
+ return;
+
+ const QHelpFilterData oldFilterData = m_filterSettings.filterData(currentFilter);
+ removeFilter(currentFilter);
+ addFilter(newFilterName, oldFilterData);
+
+ if (m_filterSettings.currentFilter() == currentFilter)
+ m_filterSettings.setCurrentFilter(newFilterName);
+}
+
+void QHelpFilterSettingsWidgetPrivate::removeFilterClicked()
+{
+ Q_Q(QHelpFilterSettingsWidget);
+
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty())
+ return;
+
+ if (QMessageBox::question(q, QHelpFilterSettingsWidget::tr("Remove Filter"),
+ QHelpFilterSettingsWidget::tr("Are you sure you want to remove the \"%1\" filter?")
+ .arg(currentFilter),
+ QMessageBox::Yes | QMessageBox::No)
+ != QMessageBox::Yes) {
+ return;
+ }
+
+ removeFilter(currentFilter);
+
+ if (m_filterSettings.currentFilter() == currentFilter)
+ m_filterSettings.setCurrentFilter(QString());
+}
+
+void QHelpFilterSettingsWidgetPrivate::addFilter(const QString &filterName,
+ const QHelpFilterData &filterData)
+{
+ QListWidgetItem *item = new QListWidgetItem(filterName);
+ m_filterSettings.setFilter(filterName, filterData);
+ m_filterToItem.insert(filterName, item);
+ m_itemToFilter.insert(item, filterName);
+ m_ui.filterWidget->insertItem(m_filterToItem.keys().indexOf(filterName), item);
+
+ m_ui.filterWidget->setCurrentItem(item);
+ updateCurrentFilter();
+}
+
+void QHelpFilterSettingsWidgetPrivate::removeFilter(const QString &filterName)
+{
+ QListWidgetItem *item = m_filterToItem.value(filterName);
+ m_itemToFilter.remove(item);
+ m_filterToItem.remove(filterName);
+ delete item;
+
+ m_filterSettings.removeFilter(filterName);
+}
+
+QString QHelpFilterSettingsWidgetPrivate::getUniqueFilterName(const QString &windowTitle,
+ const QString &initialFilterName)
+{
+ Q_Q(QHelpFilterSettingsWidget);
+
+ QString newFilterName = initialFilterName;
+ while (1) {
+ QFilterNameDialog dialog(q);
+ dialog.setWindowTitle(windowTitle);
+ dialog.setFilterName(newFilterName);
+ if (dialog.exec() == QDialog::Rejected)
+ return QString();
+
+ newFilterName = dialog.filterName();
+ if (!m_filterToItem.contains(newFilterName))
+ break;
+
+ if (QMessageBox::warning(q, QHelpFilterSettingsWidget::tr("Filter Exists"),
+ QHelpFilterSettingsWidget::tr("The filter \"%1\" already exists.")
+ .arg(newFilterName),
+ QMessageBox::Retry | QMessageBox::Cancel)
+ == QMessageBox::Cancel) {
+ return QString();
+ }
+ }
+
+ return newFilterName;
+}
+
+QString QHelpFilterSettingsWidgetPrivate::suggestedNewFilterName(const QString &initialFilterName) const
+{
+ QString newFilterName = initialFilterName;
+
+ int counter = 1;
+ while (m_filterToItem.contains(newFilterName)) {
+ newFilterName = initialFilterName + QLatin1Char(' ')
+ + QString::number(++counter);
+ }
+
+ return newFilterName;
+}
+
+/*!
+ \class QHelpFilterSettingsWidget
+ \inmodule QtHelp
+ \since 5.15
+ \brief The QHelpFilterSettingsWidget class provides a widget that allows
+ for creating, editing and removing filters.
+
+ The instance of QHelpFilterSettingsWidget may be a part of
+ a preferences dialog. Before showing the dialog, \l setAvailableComponents()
+ and \l setAvailableVersions() should be called, otherwise the filter
+ settings widget will only offer a creation of empty filters,
+ which wouldn't be useful. In addition, \l readSettings should also
+ be called to fill up the filter settings widget with the list of filters
+ already stored in the filter engine. The creation of new filters,
+ modifications to existing filters and removal of unneeded filters are
+ handled by the widget automatically. If you want to store the current
+ state of the widget and apply it to the filter engine e.g. after
+ the user clicked the apply button - call \l applySettings().
+*/
+
+/*!
+ Constructs a filter settings widget with \a parent as parent widget.
+*/
+QHelpFilterSettingsWidget::QHelpFilterSettingsWidget(QWidget *parent)
+ : QWidget(parent)
+ , d_ptr(new QHelpFilterSettingsWidgetPrivate())
+{
+ Q_D(QHelpFilterSettingsWidget);
+ d->q_ptr = this;
+ d->m_ui.setupUi(this);
+
+ // TODO: make resources configurable
+ QString resourcePath = QLatin1String(":/qt-project.org/assistant/images/");
+#ifdef Q_OS_MACOS
+ resourcePath.append(QLatin1String("mac"));
+#else
+ resourcePath.append(QLatin1String("win"));
+#endif
+ d->m_ui.addButton->setIcon(QIcon(resourcePath + QLatin1String("/plus.png")));
+ d->m_ui.removeButton->setIcon(QIcon(resourcePath + QLatin1String("/minus.png")));
+
+ connect(d->m_ui.componentWidget, &QOptionsWidget::optionSelectionChanged,
+ [this](const QStringList &options) {
+ Q_D(QHelpFilterSettingsWidget);
+ d->componentsChanged(options);
+ });
+ connect(d->m_ui.versionWidget, &QOptionsWidget::optionSelectionChanged,
+ [this](const QStringList &options) {
+ Q_D(QHelpFilterSettingsWidget);
+ d->versionsChanged(options);
+ });
+ connect(d->m_ui.filterWidget, &QListWidget::currentItemChanged,
+ this, [this](QListWidgetItem *) {
+ Q_D(QHelpFilterSettingsWidget);
+ d->updateCurrentFilter();
+ });
+ connect(d->m_ui.filterWidget, &QListWidget::itemDoubleClicked,
+ [this](QListWidgetItem *) {
+ Q_D(QHelpFilterSettingsWidget);
+ d->renameFilterClicked();
+ });
+
+ // TODO: repeat these actions on context menu
+ connect(d->m_ui.addButton, &QAbstractButton::clicked,
+ [this]() {
+ Q_D(QHelpFilterSettingsWidget);
+ d->addFilterClicked();
+ });
+ connect(d->m_ui.renameButton, &QAbstractButton::clicked,
+ [this]() {
+ Q_D(QHelpFilterSettingsWidget);
+ d->renameFilterClicked();
+ });
+ connect(d->m_ui.removeButton, &QAbstractButton::clicked,
+ [this]() {
+ Q_D(QHelpFilterSettingsWidget);
+ d->removeFilterClicked();
+ });
+
+ d->m_ui.componentWidget->setNoOptionText(tr("No Component"));
+ d->m_ui.componentWidget->setInvalidOptionText(tr("Invalid Component"));
+ d->m_ui.versionWidget->setNoOptionText(tr("No Version"));
+ d->m_ui.versionWidget->setInvalidOptionText(tr("Invalid Version"));
+}
+
+/*!
+ Destroys the filter settings widget.
+*/
+QHelpFilterSettingsWidget::~QHelpFilterSettingsWidget() = default;
+
+/*!
+ Sets the list of all available components to \a components.
+ \sa QHelpFilterEngine::availableComponents()
+*/
+void QHelpFilterSettingsWidget::setAvailableComponents(const QStringList &components)
+{
+ Q_D(QHelpFilterSettingsWidget);
+ d->m_components = components;
+ d->updateCurrentFilter();
+}
+
+/*!
+ Sets the list of all available version numbers to \a versions.
+ \sa QHelpFilterEngine::availableVersions()
+*/
+void QHelpFilterSettingsWidget::setAvailableVersions(const QList<QVersionNumber> &versions)
+{
+ Q_D(QHelpFilterSettingsWidget);
+ d->m_versions = versions;
+ d->updateCurrentFilter();
+}
+
+/*!
+ Reads the filter settings stored inside \a filterEngine and sets up
+ this filter settings widget accordingly.
+*/
+void QHelpFilterSettingsWidget::readSettings(const QHelpFilterEngine *filterEngine)
+{
+ Q_D(QHelpFilterSettingsWidget);
+ const QHelpFilterSettings settings = QHelpFilterSettings::readSettings(filterEngine);
+ d->setFilterSettings(settings);
+}
+
+/*!
+ Writes the filter settings, currently presented in this filter settings
+ widget, to the \a filterEngine. The old settings stored in the filter
+ engine will be overwritten.
+*/
+bool QHelpFilterSettingsWidget::applySettings(QHelpFilterEngine *filterEngine) const
+{
+ Q_D(const QHelpFilterSettingsWidget);
+ return QHelpFilterSettings::applySettings(filterEngine, d->filterSettings());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/help/qhelpfiltersettingswidget.h b/src/assistant/help/qhelpfiltersettingswidget.h
new file mode 100644
index 000000000..c3c77305f
--- /dev/null
+++ b/src/assistant/help/qhelpfiltersettingswidget.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPFILTERSETTINGSWIDGET_H
+#define QHELPFILTERSETTINGSWIDGET_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVersionNumber;
+
+class QHelpFilterEngine;
+class QHelpFilterSettingsWidgetPrivate;
+
+class QHELP_EXPORT QHelpFilterSettingsWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QHelpFilterSettingsWidget(QWidget *parent = nullptr);
+
+ ~QHelpFilterSettingsWidget();
+
+ void setAvailableComponents(const QStringList &components);
+ void setAvailableVersions(const QList<QVersionNumber> &versions);
+
+ // TODO: filterEngine may be moved to c'tor or to setFilterEngine() setter
+ void readSettings(const QHelpFilterEngine *filterEngine);
+ bool applySettings(QHelpFilterEngine *filterEngine) const;
+
+private:
+ QScopedPointer<class QHelpFilterSettingsWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QHelpFilterSettingsWidget)
+ Q_DISABLE_COPY_MOVE(QHelpFilterSettingsWidget)
+};
+
+QT_END_NAMESPACE
+
+#endif // QHELPFILTERSETTINGSWIDGET_H
diff --git a/src/assistant/help/qhelpfiltersettingswidget.ui b/src/assistant/help/qhelpfiltersettingswidget.ui
new file mode 100644
index 000000000..7e16e3f7b
--- /dev/null
+++ b/src/assistant/help/qhelpfiltersettingswidget.ui
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QHelpFilterSettingsWidget</class>
+ <widget class="QWidget" name="QHelpFilterSettingsWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>347</width>
+ <height>127</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="filterLabel">
+ <property name="text">
+ <string>Filter</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="componentsLabel">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="text">
+ <string>Components</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLabel" name="versionsLabel">
+ <property name="text">
+ <string>Versions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QListWidget" name="filterWidget"/>
+ </item>
+ <item row="1" column="3" rowspan="2">
+ <widget class="QOptionsWidget" name="componentWidget" native="true"/>
+ </item>
+ <item row="1" column="4" rowspan="2">
+ <widget class="QOptionsWidget" name="versionWidget" native="true"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QToolButton" name="addButton">
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QToolButton" name="renameButton">
+ <property name="text">
+ <string>Rename...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QToolButton" name="removeButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QOptionsWidget</class>
+ <extends>QWidget</extends>
+ <header>qoptionswidget_p.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/help/qhelpindexwidget.cpp b/src/assistant/help/qhelpindexwidget.cpp
index 73de1489f..ddc21e426 100644
--- a/src/assistant/help/qhelpindexwidget.cpp
+++ b/src/assistant/help/qhelpindexwidget.cpp
@@ -45,6 +45,7 @@
#include <QtCore/QThread>
#include <QtCore/QMutex>
+#include <QtHelp/QHelpLink>
#include <QtWidgets/QListView>
#include <QtWidgets/QHeaderView>
@@ -223,13 +224,28 @@ bool QHelpIndexModel::isCreatingIndex() const
}
/*!
+ \since 5.15
+
+ Returns the associated help engine that manages this model.
+*/
+QHelpEngineCore *QHelpIndexModel::helpEngine() const
+{
+ return d->helpEngine->q;
+}
+
+#if QT_DEPRECATED_SINCE(5, 15)
+/*!
\obsolete
- Use QHelpEngineCore::linksForKeyword() instead.
+ Use QHelpEngineCore::documentsForKeyword() instead.
*/
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QMap<QString, QUrl> QHelpIndexModel::linksForKeyword(const QString &keyword) const
{
return d->helpEngine->q->linksForKeyword(keyword);
}
+QT_WARNING_POP
+#endif
/*!
Filters the indices and returns the model index of the best
@@ -307,20 +323,50 @@ QModelIndex QHelpIndexModel::filter(const QString &filter, const QString &wildca
\fn void QHelpIndexWidget::linkActivated(const QUrl &link,
const QString &keyword)
+ \obsolete
+
+ Use documentActivated() instead.
+
This signal is emitted when an item is activated and its
associated \a link should be shown. To know where the link
- belongs to, the \a keyword is given as a second paremeter.
+ belongs to, the \a keyword is given as a second parameter.
*/
/*!
\fn void QHelpIndexWidget::linksActivated(const QMap<QString, QUrl> &links,
const QString &keyword)
+ \obsolete
+
+ Use documentsActivated() instead.
+
This signal is emitted when the item representing the \a keyword
is activated and the item has more than one link associated.
The \a links consist of the document titles and their URLs.
*/
+/*!
+ \fn void QHelpIndexWidget::documentActivated(const QHelpLink &document,
+ const QString &keyword)
+
+ \since 5.15
+
+ This signal is emitted when an item is activated and its
+ associated \a document should be shown. To know where the link
+ belongs to, the \a keyword is given as a second parameter.
+*/
+
+/*!
+ \fn void QHelpIndexWidget::documentsActivated(const QList<QHelpLink> &documents,
+ const QString &keyword)
+
+ \since 5.15
+
+ This signal is emitted when the item representing the \a keyword
+ is activated and the item has more than one document associated.
+ The \a documents consist of the document titles and their URLs.
+*/
+
QHelpIndexWidget::QHelpIndexWidget()
: QListView(nullptr)
{
@@ -342,11 +388,23 @@ void QHelpIndexWidget::showLink(const QModelIndex &index)
const QVariant &v = indexModel->data(index, Qt::DisplayRole);
const QString name = v.isValid() ? v.toString() : QString();
- const QMap<QString, QUrl> &links = indexModel->linksForKeyword(name);
- if (links.count() > 1)
+ const QList<QHelpLink> &docs = indexModel->helpEngine()->documentsForKeyword(name);
+ if (docs.count() > 1) {
+ emit documentsActivated(docs, name);
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+ QMap<QString, QUrl> links;
+ for (const auto &doc : docs)
+ static_cast<QMultiMap<QString, QUrl> &>(links).insert(doc.title, doc.url);
emit linksActivated(links, name);
- else if (!links.isEmpty())
- emit linkActivated(links.first(), name);
+ QT_WARNING_POP
+ } else if (!docs.isEmpty()) {
+ emit documentActivated(docs.first(), name);
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+ emit linkActivated(docs.first().url, name);
+ QT_WARNING_POP
+ }
}
/*!
diff --git a/src/assistant/help/qhelpindexwidget.h b/src/assistant/help/qhelpindexwidget.h
index 58dda5e39..896b0871f 100644
--- a/src/assistant/help/qhelpindexwidget.h
+++ b/src/assistant/help/qhelpindexwidget.h
@@ -50,7 +50,9 @@ QT_BEGIN_NAMESPACE
class QHelpEnginePrivate;
+class QHelpEngineCore;
class QHelpIndexModelPrivate;
+struct QHelpLink;
class QHELP_EXPORT QHelpIndexModel : public QStringListModel
{
@@ -61,8 +63,12 @@ public:
QModelIndex filter(const QString &filter,
const QString &wildcard = QString());
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use QHelpEngineCore::documentsForKeyword() instead")
QMap<QString, QUrl> linksForKeyword(const QString &keyword) const;
+#endif
bool isCreatingIndex() const;
+ QHelpEngineCore *helpEngine() const;
Q_SIGNALS:
void indexCreationStarted();
@@ -84,9 +90,17 @@ class QHELP_EXPORT QHelpIndexWidget : public QListView
Q_OBJECT
Q_SIGNALS:
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use documentActivated() instead")
void linkActivated(const QUrl &link, const QString &keyword);
+ QT_DEPRECATED_X("Use documentsActivated() instead")
void linksActivated(const QMap<QString, QUrl> &links,
const QString &keyword);
+#endif
+ void documentActivated(const QHelpLink &document,
+ const QString &keyword);
+ void documentsActivated(const QList<QHelpLink> &documents,
+ const QString &keyword);
public Q_SLOTS:
void filterIndices(const QString &filter,
diff --git a/src/assistant/help/qhelplink.cpp b/src/assistant/help/qhelplink.cpp
new file mode 100644
index 000000000..75cb16ab8
--- /dev/null
+++ b/src/assistant/help/qhelplink.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelplink.h"
+
+/*!
+ \class QHelpLink
+ \since 5.15
+ \inmodule QtHelp
+ \brief The QHelpLink struct provides the data associated with a help link.
+
+ The QHelpLink object is a data object that describes a link to a documentation file.
+ The description of the help link contains the document title and URL of the document.
+ \sa QHelpEngineCore
+*/
+
+/*!
+ \variable QHelpLink::url
+ \brief The target url of the link.
+*/
+/*!
+ \variable QHelpLink::title
+ \brief The title of the link.
+*/
diff --git a/src/assistant/help/qhelplink.h b/src/assistant/help/qhelplink.h
new file mode 100644
index 000000000..92b5ec6d0
--- /dev/null
+++ b/src/assistant/help/qhelplink.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPLINK_H
+#define QHELPLINK_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+struct QHELP_EXPORT QHelpLink final
+{
+ QUrl url;
+ QString title;
+};
+
+QT_END_NAMESPACE
+
+#endif // QHELPLINK_H
diff --git a/src/assistant/help/qhelpsearchindexwriter_default.cpp b/src/assistant/help/qhelpsearchindexwriter_default.cpp
index 806d0182a..692410fcc 100644
--- a/src/assistant/help/qhelpsearchindexwriter_default.cpp
+++ b/src/assistant/help/qhelpsearchindexwriter_default.cpp
@@ -465,7 +465,7 @@ void QHelpSearchIndexWriter::run()
const QMap<QString, QByteArray> txtFiles
= reader.filesData(attributes, QLatin1String("txt"));
- QMap<QString, QByteArray> files = htmlFiles;
+ QMultiMap<QString, QByteArray> files = htmlFiles;
files.unite(htmFiles);
files.unite(txtFiles);
diff --git a/src/assistant/help/qhelpsearchquerywidget.cpp b/src/assistant/help/qhelpsearchquerywidget.cpp
index 61902656d..183e317aa 100644
--- a/src/assistant/help/qhelpsearchquerywidget.cpp
+++ b/src/assistant/help/qhelpsearchquerywidget.cpp
@@ -302,7 +302,7 @@ void QHelpSearchQueryWidget::collapseExtendedSearch()
QList<QHelpSearchQuery> QHelpSearchQueryWidget::query() const
{
return QList<QHelpSearchQuery>() << QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
- searchInput().split(QChar::Space, QString::SkipEmptyParts));
+ searchInput().split(QChar::Space, Qt::SkipEmptyParts));
}
/*!
diff --git a/src/assistant/assistant/optionswidget.cpp b/src/assistant/help/qoptionswidget.cpp
index bc089c5bf..21fdfe07a 100644
--- a/src/assistant/assistant/optionswidget.cpp
+++ b/src/assistant/help/qoptionswidget.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Assistant of the Qt Toolkit.
@@ -26,20 +26,17 @@
**
****************************************************************************/
-#include "optionswidget.h"
+#include "qoptionswidget_p.h"
#include <QtWidgets/QComboBox>
#include <QtWidgets/QItemDelegate>
#include <QtWidgets/QListWidget>
#include <QtWidgets/QVBoxLayout>
-#include <algorithm>
-
QT_BEGIN_NAMESPACE
class ListWidgetDelegate : public QItemDelegate
{
-// Q_OBJECT not needed
public:
ListWidgetDelegate(QWidget *w) : QItemDelegate(w), m_widget(w) {}
@@ -87,9 +84,7 @@ static QStringList subtract(const QStringList &minuend, const QStringList &subtr
return result;
}
-/////////////////
-
-OptionsWidget::OptionsWidget(QWidget *parent)
+QOptionsWidget::QOptionsWidget(QWidget *parent)
: QWidget(parent)
, m_noOptionText(tr("No Option"))
, m_invalidOptionText(tr("Invalid Option"))
@@ -100,16 +95,16 @@ OptionsWidget::OptionsWidget(QWidget *parent)
layout->addWidget(m_listWidget);
layout->setContentsMargins(QMargins());
- connect(m_listWidget, &QListWidget::itemChanged, this, &OptionsWidget::itemChanged);
+ connect(m_listWidget, &QListWidget::itemChanged, this, &QOptionsWidget::itemChanged);
}
-void OptionsWidget::clear()
+void QOptionsWidget::clear()
{
setOptions(QStringList(), QStringList());
}
-void OptionsWidget::setOptions(const QStringList &validOptions,
- const QStringList &selectedOptions)
+void QOptionsWidget::setOptions(const QStringList &validOptions,
+ const QStringList &selectedOptions)
{
m_listWidget->clear();
m_optionToItem.clear();
@@ -145,17 +140,17 @@ void OptionsWidget::setOptions(const QStringList &validOptions,
}
}
-QStringList OptionsWidget::validOptions() const
+QStringList QOptionsWidget::validOptions() const
{
return m_validOptions;
}
-QStringList OptionsWidget::selectedOptions() const
+QStringList QOptionsWidget::selectedOptions() const
{
return m_selectedOptions;
}
-void OptionsWidget::setNoOptionText(const QString &text)
+void QOptionsWidget::setNoOptionText(const QString &text)
{
if (m_noOptionText == text)
return;
@@ -171,7 +166,7 @@ void OptionsWidget::setNoOptionText(const QString &text)
}
}
-void OptionsWidget::setInvalidOptionText(const QString &text)
+void QOptionsWidget::setInvalidOptionText(const QString &text)
{
if (m_invalidOptionText == text)
return;
@@ -183,7 +178,7 @@ void OptionsWidget::setInvalidOptionText(const QString &text)
m_optionToItem.value(option)->setText(optionText(option, false));
}
-QString OptionsWidget::optionText(const QString &optionName, bool valid) const
+QString QOptionsWidget::optionText(const QString &optionName, bool valid) const
{
QString text = optionName;
if (optionName.isEmpty())
@@ -193,7 +188,7 @@ QString OptionsWidget::optionText(const QString &optionName, bool valid) const
return text;
}
-QListWidgetItem *OptionsWidget::appendItem(const QString &optionName, bool valid, bool selected)
+QListWidgetItem *QOptionsWidget::appendItem(const QString &optionName, bool valid, bool selected)
{
QListWidgetItem *optionItem = new QListWidgetItem(optionText(optionName, valid), m_listWidget);
optionItem->setCheckState(selected ? Qt::Checked : Qt::Unchecked);
@@ -203,14 +198,14 @@ QListWidgetItem *OptionsWidget::appendItem(const QString &optionName, bool valid
return optionItem;
}
-void OptionsWidget::appendSeparator()
+void QOptionsWidget::appendSeparator()
{
QListWidgetItem *separatorItem = new QListWidgetItem(m_listWidget);
ListWidgetDelegate::setSeparator(separatorItem);
m_listWidget->insertItem(m_listWidget->count(), separatorItem);
}
-void OptionsWidget::itemChanged(QListWidgetItem *item)
+void QOptionsWidget::itemChanged(QListWidgetItem *item)
{
const auto it = m_itemToOption.constFind(item);
if (it == m_itemToOption.constEnd())
diff --git a/src/assistant/assistant/optionswidget.h b/src/assistant/help/qoptionswidget_p.h
index 52c876bad..a6700c1d7 100644
--- a/src/assistant/assistant/optionswidget.h
+++ b/src/assistant/help/qoptionswidget_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Assistant of the Qt Toolkit.
@@ -26,8 +26,19 @@
**
****************************************************************************/
-#ifndef OPTIONSWIDGET_H
-#define OPTIONSWIDGET_H
+#ifndef QOPTIONSWIDGET_H
+#define QOPTIONSWIDGET_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
#include <QtWidgets/QWidget>
#include <QtCore/QMap>
@@ -37,11 +48,11 @@ QT_BEGIN_NAMESPACE
class QListWidget;
class QListWidgetItem;
-class OptionsWidget : public QWidget
+class QOptionsWidget : public QWidget
{
Q_OBJECT
public:
- OptionsWidget(QWidget *parent = nullptr);
+ QOptionsWidget(QWidget *parent = nullptr);
void clear();
void setOptions(const QStringList &validOptions,
diff --git a/src/assistant/shared/collectionconfiguration.cpp b/src/assistant/shared/collectionconfiguration.cpp
index a1b63c9bd..562cbfaab 100644
--- a/src/assistant/shared/collectionconfiguration.cpp
+++ b/src/assistant/shared/collectionconfiguration.cpp
@@ -239,7 +239,7 @@ void CollectionConfiguration::setDefaultHomePage(QHelpEngineCore &helpEngine,
const QStringList CollectionConfiguration::lastShownPages(const QHelpEngineCore &helpEngine)
{
return helpEngine.customValue(LastShownPagesKey).toString().
- split(ListSeparator, QString::SkipEmptyParts);
+ split(ListSeparator, Qt::SkipEmptyParts);
}
void CollectionConfiguration::setLastShownPages(QHelpEngineCore &helpEngine,
@@ -252,7 +252,7 @@ void CollectionConfiguration::setLastShownPages(QHelpEngineCore &helpEngine,
const QStringList CollectionConfiguration::lastZoomFactors(const QHelpEngineCore &helpEngine)
{
return helpEngine.customValue(LastZoomFactorsKey).toString().
- split(ListSeparator, QString::SkipEmptyParts);
+ split(ListSeparator, Qt::SkipEmptyParts);
}
void CollectionConfiguration::setLastZoomFactors(QHelpEngineCore &helpEngine,
diff --git a/src/designer/data/generate_header.xsl b/src/designer/data/generate_header.xsl
index 334d3a73c..b1a2d1bb6 100644
--- a/src/designer/data/generate_header.xsl
+++ b/src/designer/data/generate_header.xsl
@@ -310,7 +310,7 @@
<xsl:text>class QDESIGNER_UILIB_EXPORT </xsl:text>
<xsl:value-of select="$name"/>
- <xsl:text> {&endl; Q_DISABLE_COPY(</xsl:text>
+ <xsl:text> {&endl; Q_DISABLE_COPY_MOVE(</xsl:text>
<xsl:value-of select="$name"/>
<xsl:text>)&endl;</xsl:text>
<xsl:text>public:&endl;</xsl:text>
diff --git a/src/designer/data/generate_impl.xsl b/src/designer/data/generate_impl.xsl
index da7a043b2..2002c71a1 100644
--- a/src/designer/data/generate_impl.xsl
+++ b/src/designer/data/generate_impl.xsl
@@ -194,7 +194,7 @@
<xsl:if test="$node/xs:attribute">
<xsl:text> const QXmlStreamAttributes &amp;attributes = reader.attributes();&endl;</xsl:text>
<xsl:text> for (const QXmlStreamAttribute &amp;attribute : attributes) {&endl;</xsl:text>
- <xsl:text> const QStringRef name = attribute.name();&endl;</xsl:text>
+ <xsl:text> const auto name = attribute.name();&endl;</xsl:text>
<xsl:for-each select="$node/xs:attribute">
<xsl:variable name="camel-case-name">
@@ -347,7 +347,7 @@
<xsl:text> while (!reader.hasError()) {&endl;</xsl:text>
<xsl:text> switch (reader.readNext()) {&endl;</xsl:text>
<xsl:text> case QXmlStreamReader::StartElement : {&endl;</xsl:text>
- <xsl:text> const QStringRef tag = reader.name();&endl;</xsl:text>
+ <xsl:text> const auto tag = reader.name();&endl;</xsl:text>
<xsl:for-each select="$node//xs:sequence | $node//xs:choice | $node//xs:all">
<xsl:call-template name="read-impl-load-child-element">
diff --git a/src/designer/designer.pro b/src/designer/designer.pro
index be734fb11..46c488f97 100644
--- a/src/designer/designer.pro
+++ b/src/designer/designer.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(designer))
+
TEMPLATE = subdirs
SUBDIRS = src
diff --git a/src/designer/src/components/buddyeditor/buddyeditor.cpp b/src/designer/src/components/buddyeditor/buddyeditor.cpp
index 7593326db..8fb9184e1 100644
--- a/src/designer/src/components/buddyeditor/buddyeditor.cpp
+++ b/src/designer/src/components/buddyeditor/buddyeditor.cpp
@@ -41,6 +41,7 @@
#include <metadatabase_p.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qvector.h>
#include <QtWidgets/qlabel.h>
#include <QtWidgets/qmenu.h>
#include <QtWidgets/qaction.h>
@@ -83,8 +84,6 @@ static QString buddy(QLabel *label, QDesignerFormEditorInterface *core)
return sheet->property(prop_idx).toString();
}
-using LabelList = QList<QLabel *>;
-
namespace qdesigner_internal {
/*******************************************************************************
@@ -143,8 +142,8 @@ void BuddyEditor::updateBackground()
ConnectionEdit::updateBackground();
m_updating = true;
- QList<Connection *> newList;
- const LabelList label_list = background()->findChildren<QLabel*>();
+ QVector<Connection *> newList;
+ const auto label_list = background()->findChildren<QLabel*>();
for (QLabel *label : label_list) {
const QString buddy_name = buddy(label, m_formWindow->core());
if (buddy_name.isEmpty())
@@ -165,7 +164,7 @@ void BuddyEditor::updateBackground()
newList.append(con);
}
- QList<Connection *> toRemove;
+ QVector<Connection *> toRemove;
const int c = connectionCount();
for (int i = 0; i < c; i++) {
@@ -212,7 +211,7 @@ void BuddyEditor::setBackground(QWidget *background)
clear();
ConnectionEdit::setBackground(background);
- const LabelList label_list = background->findChildren<QLabel*>();
+ const auto label_list = background->findChildren<QLabel*>();
for (QLabel *label : label_list) {
const QString buddy_name = buddy(label, m_formWindow->core());
if (buddy_name.isEmpty())
@@ -328,8 +327,8 @@ void BuddyEditor::deleteSelected()
void BuddyEditor::autoBuddy()
{
// Any labels?
- LabelList labelList = background()->findChildren<QLabel*>();
- if (labelList.empty())
+ auto labelList = background()->findChildren<QLabel*>();
+ if (labelList.isEmpty())
return;
// Find already used buddies
QWidgetList usedBuddies;
@@ -338,7 +337,7 @@ void BuddyEditor::autoBuddy()
usedBuddies.push_back(c->widget(EndPoint::Target));
// Find potential new buddies, keep lists in sync
QWidgetList buddies;
- for (LabelList::iterator it = labelList.begin(); it != labelList.end(); ) {
+ for (auto it = labelList.begin(); it != labelList.end(); ) {
QLabel *label = *it;
QWidget *newBuddy = nullptr;
if (m_formWindow->isManaged(label)) {
@@ -355,7 +354,7 @@ void BuddyEditor::autoBuddy()
}
}
// Add the list in one go.
- if (labelList.empty())
+ if (labelList.isEmpty())
return;
const int count = labelList.size();
Q_ASSERT(count == buddies.size());
diff --git a/src/designer/src/components/formeditor/deviceprofiledialog.cpp b/src/designer/src/components/formeditor/deviceprofiledialog.cpp
index 40a9e6ab6..ef1693c39 100644
--- a/src/designer/src/components/formeditor/deviceprofiledialog.cpp
+++ b/src/designer/src/components/formeditor/deviceprofiledialog.cpp
@@ -73,7 +73,7 @@ DeviceProfileDialog::DeviceProfileDialog(QDesignerDialogGuiInterface *dlgGui, QW
setModal(true);
m_ui->setupUi(this);
- const QList<int> standardFontSizes = QFontDatabase::standardSizes();
+ const auto standardFontSizes = QFontDatabase::standardSizes();
populateNumericCombo(standardFontSizes.constBegin(), standardFontSizes.constEnd(), m_ui->m_systemFontSizeCombo);
// 288pt observed on macOS.
diff --git a/src/designer/src/components/formeditor/dpi_chooser.cpp b/src/designer/src/components/formeditor/dpi_chooser.cpp
index 5e2f9f605..a254bf12a 100644
--- a/src/designer/src/components/formeditor/dpi_chooser.cpp
+++ b/src/designer/src/components/formeditor/dpi_chooser.cpp
@@ -94,7 +94,7 @@ DPI_Chooser::DPI_Chooser(QWidget *parent) :
setFocusProxy(m_predefinedCombo);
m_predefinedCombo->setEditable(false);
m_predefinedCombo->setCurrentIndex(0);
- connect(m_predefinedCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(m_predefinedCombo, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &DPI_Chooser::syncSpinBoxes);
// top row with predefined settings
QVBoxLayout *vBoxLayout = new QVBoxLayout;
diff --git a/src/designer/src/components/formeditor/embeddedoptionspage.cpp b/src/designer/src/components/formeditor/embeddedoptionspage.cpp
index 96a6c7c4a..062fc6e4f 100644
--- a/src/designer/src/components/formeditor/embeddedoptionspage.cpp
+++ b/src/designer/src/components/formeditor/embeddedoptionspage.cpp
@@ -52,6 +52,7 @@
#include <QtWidgets/qgroupbox.h>
#include <QtCore/qset.h>
+#include <QtCore/qvector.h>
#include <algorithm>
@@ -59,7 +60,7 @@ QT_BEGIN_NAMESPACE
namespace qdesigner_internal {
-using DeviceProfileList = QList<DeviceProfile>;
+using DeviceProfileList = QVector<DeviceProfile>;
enum { profileComboIndexOffset = 1 };
@@ -144,7 +145,7 @@ void EmbeddedOptionsControlPrivate::init(EmbeddedOptionsControl *q)
m_profileCombo->setEditable(false);
hLayout->addWidget(m_profileCombo);
m_profileCombo->addItem(EmbeddedOptionsControl::tr("None"));
- EmbeddedOptionsControl::connect(m_profileCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ EmbeddedOptionsControl::connect(m_profileCombo, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
m_q, &EmbeddedOptionsControl::slotProfileIndexChanged);
m_addButton->setIcon(createIconSet(QString::fromUtf8("plus.png")));
@@ -265,7 +266,7 @@ void EmbeddedOptionsControlPrivate::sortAndPopulateProfileCombo()
// Clear items until only "None" is left
for (int i = m_profileCombo->count() - 1; i > 0; i--)
m_profileCombo->removeItem(i);
- if (!m_sortedProfiles.empty()) {
+ if (!m_sortedProfiles.isEmpty()) {
std::sort(m_sortedProfiles.begin(), m_sortedProfiles.end(), deviceProfileLessThan);
m_profileCombo->addItems(existingProfileNames());
}
diff --git a/src/designer/src/components/formeditor/formeditor.cpp b/src/designer/src/components/formeditor/formeditor.cpp
index 335241e5f..05e7fc4ee 100644
--- a/src/designer/src/components/formeditor/formeditor.cpp
+++ b/src/designer/src/components/formeditor/formeditor.cpp
@@ -44,6 +44,7 @@
#include "spacer_propertysheet.h"
#include "line_propertysheet.h"
#include "layout_propertysheet.h"
+#include "qdesigner_dockwidget_p.h"
#include "qdesigner_stackedbox_p.h"
#include "qdesigner_toolbox_p.h"
#include "qdesigner_tabwidget_p.h"
@@ -111,6 +112,7 @@ FormEditor::FormEditor(QObject *parent)
QMenuActionProviderFactory::registerExtension(mgr, actionProviderExtensionId);
QDesignerDefaultPropertySheetFactory::registerExtension(mgr);
+ QDockWidgetPropertySheetFactory::registerExtension(mgr);
QLayoutWidgetPropertySheetFactory::registerExtension(mgr);
SpacerPropertySheetFactory::registerExtension(mgr);
LinePropertySheetFactory::registerExtension(mgr);
diff --git a/src/designer/src/components/formeditor/formwindow.cpp b/src/designer/src/components/formeditor/formwindow.cpp
index 464d7f618..84e065bcb 100644
--- a/src/designer/src/components/formeditor/formwindow.cpp
+++ b/src/designer/src/components/formeditor/formwindow.cpp
@@ -75,6 +75,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/qbuffer.h>
#include <QtCore/qtimer.h>
+#include <QtCore/qvector.h>
#include <QtCore/qxmlstream.h>
#include <QtWidgets/qmenu.h>
#include <QtWidgets/qaction.h>
@@ -162,7 +163,7 @@ public:
private:
- using SelectionPool = QList<WidgetSelection *>;
+ using SelectionPool = QVector<WidgetSelection *>;
SelectionPool m_selectionPool;
typedef QHash<QWidget *, WidgetSelection *> SelectionHash;
@@ -178,7 +179,7 @@ FormWindow::Selection::~Selection()
void FormWindow::Selection::clear()
{
- if (!m_usedSelections.empty()) {
+ if (!m_usedSelections.isEmpty()) {
for (auto it = m_usedSelections.begin(), mend = m_usedSelections.end(); it != mend; ++it)
it.value()->setWidget(nullptr);
m_usedSelections.clear();
@@ -684,6 +685,7 @@ bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e)
const bool blocked = blockSelectionChanged(true);
QWidgetList sel = selectedWidgets();
+ const QWidgetList originalSelection = sel;
simplifySelection(&sel);
QSet<QWidget*> widget_set;
@@ -733,9 +735,14 @@ bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e)
}
}
+ // In case when we have reduced the selection (by calling simplifySelection()
+ // beforehand) we still need to hide selection handles for children widgets
+ for (auto *widget : originalSelection)
+ m_selection->hide(widget);
+
blockSelectionChanged(blocked);
- if (!sel.empty()) // reshow selection?
+ if (!sel.isEmpty()) // reshow selection?
if (QDesignerMimeData::execDrag(item_list, core()->topLevel()) == Qt::IgnoreAction && dropType == QDesignerDnDItemInterface::MoveDrop)
for (QWidget *widget : qAsConst(sel))
m_selection->show(widget);
@@ -940,7 +947,7 @@ bool FormWindow::isMainContainer(const QWidget *w) const
void FormWindow::updateChildSelections(QWidget *w)
{
const QWidgetList l = w->findChildren<QWidget*>();
- if (!l.empty()) {
+ if (!l.isEmpty()) {
const QWidgetList::const_iterator lcend = l.constEnd();
for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it) {
QWidget *w = *it;
@@ -1150,19 +1157,19 @@ bool FormWindow::unify(QObject *w, QString &s, bool changeIt)
const QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
const QWidgetList widgetChildren = main->findChildren<QWidget*>();
- if (!widgetChildren.empty())
+ if (!widgetChildren.isEmpty())
insertNames(metaDataBase, widgetChildren.constBegin(), widgetChildren.constEnd(), w, existingNames);
- const QList<QLayout *> layoutChildren = main->findChildren<QLayout*>();
- if (!layoutChildren.empty())
+ const auto layoutChildren = main->findChildren<QLayout*>();
+ if (!layoutChildren.isEmpty())
insertNames(metaDataBase, layoutChildren.constBegin(), layoutChildren.constEnd(), w, existingNames);
- const QList<QAction *> actionChildren = main->findChildren<QAction*>();
- if (!actionChildren.empty())
+ const auto actionChildren = main->findChildren<QAction*>();
+ if (!actionChildren.isEmpty())
insertNames(metaDataBase, actionChildren.constBegin(), actionChildren.constEnd(), w, existingNames);
- const QList<QButtonGroup *> buttonGroupChildren = main->findChildren<QButtonGroup*>();
- if (!buttonGroupChildren.empty())
+ const auto buttonGroupChildren = main->findChildren<QButtonGroup*>();
+ if (!buttonGroupChildren.isEmpty())
insertNames(metaDataBase, buttonGroupChildren.constBegin(), buttonGroupChildren.constEnd(), w, existingNames);
const StringSet::const_iterator enEnd = existingNames.constEnd();
@@ -1695,7 +1702,7 @@ QWidget *FormWindow::containerForPaste() const
// Try to find a close parent, for example a non-laid-out
// QFrame/QGroupBox when a widget within it is selected.
QWidgetList selection = selectedWidgets();
- if (selection.empty())
+ if (selection.isEmpty())
break;
simplifySelection(&selection);
@@ -2252,7 +2259,7 @@ QAction *FormWindow::createSelectAncestorSubMenu(QWidget *w)
for (QWidget *p = w->parentWidget(); p && p != mc; p = p->parentWidget())
if (isManaged(p) && !isWidgetSelected(p))
parents.push_back(p);
- if (parents.empty())
+ if (parents.isEmpty())
return nullptr;
// Create a submenu listing the managed, unselected parents
QMenu *menu = new QMenu;
diff --git a/src/designer/src/components/formeditor/formwindow_widgetstack.cpp b/src/designer/src/components/formeditor/formwindow_widgetstack.cpp
index 18126c145..4c93c7674 100644
--- a/src/designer/src/components/formeditor/formwindow_widgetstack.cpp
+++ b/src/designer/src/components/formeditor/formwindow_widgetstack.cpp
@@ -165,7 +165,7 @@ void FormWindowWidgetStack::addTool(QDesignerFormWindowToolInterface *tool)
m_layout->addWidget(w);
} else {
// The form editor might not have a tool initially, use dummy. Assert on anything else
- Q_ASSERT(m_tools.empty());
+ Q_ASSERT(m_tools.isEmpty());
m_layout->addWidget(m_formContainer);
}
diff --git a/src/designer/src/components/formeditor/formwindowmanager.cpp b/src/designer/src/components/formeditor/formwindowmanager.cpp
index d1edb231c..692b20c54 100644
--- a/src/designer/src/components/formeditor/formwindowmanager.cpp
+++ b/src/designer/src/components/formeditor/formwindowmanager.cpp
@@ -71,7 +71,6 @@
#endif
#include <QtWidgets/qmdiarea.h>
#include <QtWidgets/qmdisubwindow.h>
-#include <QtWidgets/qdesktopwidget.h>
#include <QtWidgets/qmessagebox.h>
#include <QtCore/qdebug.h>
@@ -567,7 +566,7 @@ static inline QWidget *findLayoutContainer(const FormWindow *fw)
{
QWidgetList l(fw->selectedWidgets());
fw->simplifySelection(&l);
- return l.empty() ? fw->mainContainer() : l.front();
+ return l.isEmpty() ? fw->mainContainer() : l.constFirst();
}
void FormWindowManager::createLayout()
@@ -617,7 +616,7 @@ void FormWindowManager::slotActionSimplifyLayoutActivated()
if (selectedWidgets.size() != 1)
return;
SimplifyLayoutCommand *cmd = new SimplifyLayoutCommand(m_activeFormWindow);
- if (cmd->init(selectedWidgets.front())) {
+ if (cmd->init(selectedWidgets.constFirst())) {
m_activeFormWindow->commandHistory()->push(cmd);
} else {
delete cmd;
@@ -754,7 +753,7 @@ QSet<QWidget *> FormWindowManager::getUnsortedLayoutsToBeBroken(bool firstOnly)
for (QWidget *selectedWidget : qAsConst(selection)) {
// find all layouts
const QWidgetList &list = layoutsToBeBroken(selectedWidget);
- if (!list.empty()) {
+ if (!list.isEmpty()) {
for (QWidget *widget : list)
layouts.insert(widget);
if (firstOnly)
diff --git a/src/designer/src/components/formeditor/formwindowsettings.cpp b/src/designer/src/components/formeditor/formwindowsettings.cpp
index 4ccd7210b..3e24b7623 100644
--- a/src/designer/src/components/formeditor/formwindowsettings.cpp
+++ b/src/designer/src/components/formeditor/formwindowsettings.cpp
@@ -108,12 +108,13 @@ void FormWindowData::fromFormWindow(FormWindowBase* fw)
defaultMargin = defaultSpacing = INT_MIN;
fw->layoutDefault(&defaultMargin, &defaultSpacing);
- QStyle *style = fw->formContainer()->style();
+ auto container = fw->formContainer();
+ QStyle *style = container->style();
layoutDefaultEnabled = defaultMargin != INT_MIN || defaultSpacing != INT_MIN;
if (defaultMargin == INT_MIN)
- defaultMargin = style->pixelMetric(QStyle::PM_DefaultChildMargin, nullptr);
+ defaultMargin = style->pixelMetric(QStyle::PM_LayoutLeftMargin, nullptr, container);
if (defaultSpacing == INT_MIN)
- defaultSpacing = style->pixelMetric(QStyle::PM_DefaultLayoutSpacing, nullptr);
+ defaultSpacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, nullptr);
marginFunction.clear();
@@ -244,7 +245,7 @@ void FormWindowSettings::setData(const FormWindowData &data)
m_ui->authorLineEdit->setText(data.author);
- if (data.includeHints.empty()) {
+ if (data.includeHints.isEmpty()) {
m_ui->includeHintsTextEdit->clear();
} else {
m_ui->includeHintsTextEdit->setText(data.includeHints.join(QLatin1Char('\n')));
diff --git a/src/designer/src/components/formeditor/layout_propertysheet.cpp b/src/designer/src/components/formeditor/layout_propertysheet.cpp
index e0e456d32..0bb3ecb2f 100644
--- a/src/designer/src/components/formeditor/layout_propertysheet.cpp
+++ b/src/designer/src/components/formeditor/layout_propertysheet.cpp
@@ -103,7 +103,7 @@ static bool isIntegerList(const QString &s)
static LayoutPropertyType layoutPropertyType(const QString &name)
{
static QHash<QString, LayoutPropertyType> namePropertyMap;
- if (namePropertyMap.empty()) {
+ if (namePropertyMap.isEmpty()) {
namePropertyMap.insert(QLatin1String(leftMargin), LayoutPropertyLeftMargin);
namePropertyMap.insert(QLatin1String(topMargin), LayoutPropertyTopMargin);
namePropertyMap.insert(QLatin1String(rightMargin), LayoutPropertyRightMargin);
diff --git a/src/designer/src/components/formeditor/previewactiongroup.cpp b/src/designer/src/components/formeditor/previewactiongroup.cpp
index 89c3a0ae7..a85fb22c0 100644
--- a/src/designer/src/components/formeditor/previewactiongroup.cpp
+++ b/src/designer/src/components/formeditor/previewactiongroup.cpp
@@ -91,14 +91,11 @@ PreviewActionGroup::PreviewActionGroup(QDesignerFormEditorInterface *core, QObje
void PreviewActionGroup::updateDeviceProfiles()
{
- using DeviceProfileList = QList<DeviceProfile>;
- using ActionList = QList<QAction *>;
-
const QDesignerSharedSettings settings(m_core);
- const DeviceProfileList profiles = settings.deviceProfiles();
- const ActionList al = actions();
+ const auto profiles = settings.deviceProfiles();
+ const auto al = actions();
// Separator?
- const bool hasProfiles = !profiles.empty();
+ const bool hasProfiles = !profiles.isEmpty();
al.at(MaxDeviceActions)->setVisible(hasProfiles);
int index = 0;
if (hasProfiles) {
diff --git a/src/designer/src/components/formeditor/qdesigner_resource.cpp b/src/designer/src/components/formeditor/qdesigner_resource.cpp
index dd1144d7c..ff4a42744 100644
--- a/src/designer/src/components/formeditor/qdesigner_resource.cpp
+++ b/src/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -516,14 +516,14 @@ void QDesignerResource::saveDom(DomUI *ui, QWidget *widget)
ui->setAttributeConnectslotsbyname(false);
const QVariantMap designerFormData = m_formWindow->formData();
- if (!designerFormData.empty()) {
+ if (!designerFormData.isEmpty()) {
DomPropertyList domPropertyList;
const QVariantMap::const_iterator cend = designerFormData.constEnd();
for (QVariantMap::const_iterator it = designerFormData.constBegin(); it != cend; ++it) {
if (DomProperty *prop = variantToDomProperty(this, widget->metaObject(), it.key(), it.value()))
domPropertyList += prop;
}
- if (!domPropertyList.empty()) {
+ if (!domPropertyList.isEmpty()) {
DomDesignerData* domDesignerFormData = new DomDesignerData;
domDesignerFormData->setElementProperty(domPropertyList);
ui->setElementDesignerdata(domDesignerFormData);
@@ -590,7 +590,7 @@ void QDesignerResource::saveDom(DomUI *ui, QWidget *widget)
const MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(m_formWindow->mainContainer());
const QStringList fakeSlots = item->fakeSlots();
const QStringList fakeSignals =item->fakeSignals();
- if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ if (!fakeSlots.isEmpty() || !fakeSignals.isEmpty()) {
DomSlots *domSlots = new DomSlots();
domSlots->setElementSlot(fakeSlots);
domSlots->setElementSignal(fakeSignals);
@@ -708,7 +708,7 @@ QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget)
// Register all button groups the form builder adds as children of the main container for them to be found
// in the signal slot editor
const QObjectList mchildren = mainWidget->children();
- if (!mchildren.empty()) {
+ if (!mchildren.isEmpty()) {
QDesignerMetaDataBaseInterface *mdb = core()->metaDataBase();
const QObjectList::const_iterator cend = mchildren.constEnd();
for (QObjectList::const_iterator it = mchildren.constBegin(); it != cend; ++it)
@@ -740,7 +740,7 @@ QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget)
// Initialize the mainwindow geometry. Has it been explicitly specified?
bool hasExplicitGeometry = false;
const auto &properties = ui->elementWidget()->elementProperty();
- if (!properties.empty()) {
+ if (!properties.isEmpty()) {
const QString geometry = QStringLiteral("geometry");
for (const DomProperty *p : properties) {
if (p->attributeName() == geometry) {
@@ -941,7 +941,7 @@ static bool readDomEnumerationValue(const DomProperty *p,
void QDesignerResource::applyProperties(QObject *o, const QList<DomProperty*> &properties)
{
- if (properties.empty())
+ if (properties.isEmpty())
return;
QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), o);
@@ -1692,7 +1692,7 @@ DomUI *QDesignerResource::copy(const FormBuilderClipboard &selection)
ui_widget->setAttributeName(QLatin1String(clipboardObjectName));
bool hasItems = false;
// Widgets
- if (!selection.m_widgets.empty()) {
+ if (!selection.m_widgets.isEmpty()) {
QVector<DomWidget *> ui_widget_list;
const int size = selection.m_widgets.size();
for (int i=0; i< size; ++i) {
@@ -1703,19 +1703,19 @@ DomUI *QDesignerResource::copy(const FormBuilderClipboard &selection)
if (ui_child)
ui_widget_list.append(ui_child);
}
- if (!ui_widget_list.empty()) {
+ if (!ui_widget_list.isEmpty()) {
ui_widget->setElementWidget(ui_widget_list);
hasItems = true;
}
}
// actions
- if (!selection.m_actions.empty()) {
+ if (!selection.m_actions.isEmpty()) {
QVector<DomAction *> domActions;
for (QAction* action : qAsConst(selection.m_actions)) {
if (DomAction *domAction = createDom(action))
domActions += domAction;
}
- if (!domActions.empty()) {
+ if (!domActions.isEmpty()) {
ui_widget-> setElementAction(domActions);
hasItems = true;
}
@@ -1750,7 +1750,7 @@ FormBuilderClipboard QDesignerResource::paste(DomUI *ui, QWidget *widgetParent,
const DomWidget *topLevel = ui->elementWidget();
initialize(ui);
const auto &domWidgets = topLevel->elementWidget();
- if (!domWidgets.empty()) {
+ if (!domWidgets.isEmpty()) {
const QPoint offset = m_formWindow->grid();
for (DomWidget* domWidget : domWidgets) {
if (QWidget *w = create(domWidget, widgetParent)) {
@@ -1857,7 +1857,7 @@ DomCustomWidgets *QDesignerResource::saveCustomWidgets()
WidgetDataBaseItem *internalItem = static_cast<WidgetDataBaseItem *>(item);
const QStringList fakeSlots = internalItem->fakeSlots();
const QStringList fakeSignals = internalItem->fakeSignals();
- if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ if (!fakeSlots.isEmpty() || !fakeSignals.isEmpty()) {
DomSlots *domSlots = new DomSlots();
domSlots->setElementSlot(fakeSlots);
domSlots->setElementSignal(fakeSignals);
@@ -2212,7 +2212,7 @@ QActionGroup *QDesignerResource::createActionGroup(QObject *parent, const QStrin
void QDesignerResource::applyAttributesToPropertySheet(const DomWidget *ui_widget, QWidget *widget)
{
const DomPropertyList attributes = ui_widget->elementAttribute();
- if (attributes.empty())
+ if (attributes.isEmpty())
return;
QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_formWindow->core()->extensionManager(), widget);
const DomPropertyList::const_iterator acend = attributes.constEnd();
diff --git a/src/designer/src/components/formeditor/qmdiarea_container.cpp b/src/designer/src/components/formeditor/qmdiarea_container.cpp
index e33c99367..03fe667a3 100644
--- a/src/designer/src/components/formeditor/qmdiarea_container.cpp
+++ b/src/designer/src/components/formeditor/qmdiarea_container.cpp
@@ -117,7 +117,7 @@ void QMdiAreaContainer::insertWidget(int, QWidget *widget)
void QMdiAreaContainer::remove(int index)
{
- QList<QMdiSubWindow *> subWins = m_mdiArea->subWindowList(QMdiArea::CreationOrder);
+ auto subWins = m_mdiArea->subWindowList(QMdiArea::CreationOrder);
if (index >= 0 && index < subWins.size()) {
QMdiSubWindow *f = subWins.at(index);
m_mdiArea->removeSubWindow(f->widget());
@@ -144,7 +144,7 @@ QMdiAreaPropertySheet::MdiAreaProperty QMdiAreaPropertySheet::mdiAreaProperty(co
{
using MdiAreaPropertyHash = QHash<QString, MdiAreaProperty>;
static MdiAreaPropertyHash mdiAreaPropertyHash;
- if (mdiAreaPropertyHash.empty()) {
+ if (mdiAreaPropertyHash.isEmpty()) {
mdiAreaPropertyHash.insert(QLatin1String(subWindowNameC), MdiAreaSubWindowName);
mdiAreaPropertyHash.insert(QLatin1String(subWindowTitleC), MdiAreaSubWindowTitle);
}
diff --git a/src/designer/src/components/formeditor/qwizard_container.cpp b/src/designer/src/components/formeditor/qwizard_container.cpp
index dbc7084eb..9acb4988c 100644
--- a/src/designer/src/components/formeditor/qwizard_container.cpp
+++ b/src/designer/src/components/formeditor/qwizard_container.cpp
@@ -33,11 +33,11 @@
#include <QtWidgets/qwizard.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
-using IdList = QList<int>;
-using WizardPageList = QList<QWizardPage *>;
+using WizardPageList = QVector<QWizardPage *>;
namespace qdesigner_internal {
@@ -56,7 +56,7 @@ QWidget *QWizardContainer::widget(int index) const
{
QWidget *rc = nullptr;
if (index >= 0) {
- const IdList idList = m_wizard->pageIds();
+ const auto idList = m_wizard->pageIds();
if (index < idList.size())
rc = m_wizard->page(idList.at(index));
}
@@ -65,15 +65,12 @@ QWidget *QWizardContainer::widget(int index) const
int QWizardContainer::currentIndex() const
{
- const IdList idList = m_wizard->pageIds();
- const int currentId = m_wizard->currentId();
- const int rc = idList.empty() ? -1 : idList.indexOf(currentId);
- return rc;
+ return m_wizard->pageIds().indexOf(m_wizard->currentId());
}
void QWizardContainer::setCurrentIndex(int index)
{
- if (index < 0 || m_wizard->pageIds().empty())
+ if (index < 0 || m_wizard->pageIds().isEmpty())
return;
int currentIdx = currentIndex();
@@ -120,7 +117,7 @@ void QWizardContainer::insertWidget(int index, QWidget *widget)
return;
}
- const IdList idList = m_wizard->pageIds();
+ const auto idList = m_wizard->pageIds();
const int pageCount = idList.size();
if (index >= pageCount) {
addWidget(widget);
@@ -142,9 +139,8 @@ void QWizardContainer::insertWidget(int index, QWidget *widget)
m_wizard->removePage(idList.at(i));
}
int newId = idBefore + delta;
- const WizardPageList::const_iterator wcend = pageList.constEnd();
- for (WizardPageList::const_iterator it = pageList.constBegin(); it != wcend; ++it) {
- m_wizard->setPage(newId, *it);
+ for (QWizardPage *page : qAsConst(pageList)) {
+ m_wizard->setPage(newId, page);
newId += delta;
}
} else {
@@ -160,7 +156,7 @@ void QWizardContainer::remove(int index)
if (index < 0)
return;
- const IdList idList = m_wizard->pageIds();
+ const auto idList = m_wizard->pageIds();
if (index >= idList.size())
return;
diff --git a/src/designer/src/components/formeditor/templateoptionspage.cpp b/src/designer/src/components/formeditor/templateoptionspage.cpp
index b1c0dc2d4..4e638c913 100644
--- a/src/designer/src/components/formeditor/templateoptionspage.cpp
+++ b/src/designer/src/components/formeditor/templateoptionspage.cpp
@@ -79,7 +79,7 @@ void TemplateOptionsWidget::setTemplatePaths(const QStringList &l)
{
// add paths and select 0
m_ui->m_templatePathListWidget->clear();
- if (l.empty()) {
+ if (l.isEmpty()) {
// disable button
templatePathSelectionChanged();
} else {
@@ -96,9 +96,9 @@ void TemplateOptionsWidget::addTemplatePath()
if (templatePath.isEmpty())
return;
- const QList<QListWidgetItem *> existing
+ const auto existing
= m_ui->m_templatePathListWidget->findItems(templatePath, Qt::MatchExactly);
- if (!existing.empty())
+ if (!existing.isEmpty())
return;
QListWidgetItem *newItem = new QListWidgetItem(templatePath);
@@ -108,17 +108,16 @@ void TemplateOptionsWidget::addTemplatePath()
void TemplateOptionsWidget::removeTemplatePath()
{
- const QList<QListWidgetItem *> selectedPaths
- = m_ui->m_templatePathListWidget->selectedItems();
- if (selectedPaths.empty())
+ const auto selectedPaths = m_ui->m_templatePathListWidget->selectedItems();
+ if (selectedPaths.isEmpty())
return;
- delete selectedPaths.front();
+ delete selectedPaths.constFirst();
}
void TemplateOptionsWidget::templatePathSelectionChanged()
{
- const QList<QListWidgetItem *> selectedPaths = m_ui->m_templatePathListWidget->selectedItems();
- m_ui->m_removeTemplatePathButton->setEnabled(!selectedPaths.empty());
+ const auto selectedPaths = m_ui->m_templatePathListWidget->selectedItems();
+ m_ui->m_removeTemplatePathButton->setEnabled(!selectedPaths.isEmpty());
}
QString TemplateOptionsWidget::chooseTemplatePath(QDesignerFormEditorInterface *core, QWidget *parent)
diff --git a/src/designer/src/components/formeditor/tool_widgeteditor.cpp b/src/designer/src/components/formeditor/tool_widgeteditor.cpp
index d3ecf8087..bdfdc2675 100644
--- a/src/designer/src/components/formeditor/tool_widgeteditor.cpp
+++ b/src/designer/src/components/formeditor/tool_widgeteditor.cpp
@@ -222,7 +222,7 @@ void WidgetEditorTool::detectDockDrag(const QDesignerMimeData *mimeData)
if (!mw)
return;
- const QList<QDesignerDnDItemInterface*> item_list = mimeData->items();
+ const auto item_list = mimeData->items();
for (QDesignerDnDItemInterface *item : item_list) {
if (item->decoration() && item->decoration()->property("_q_dockDrag").toBool())
diff --git a/src/designer/src/components/objectinspector/objectinspector.cpp b/src/designer/src/components/objectinspector/objectinspector.cpp
index 4267fea22..248041811 100644
--- a/src/designer/src/components/objectinspector/objectinspector.cpp
+++ b/src/designer/src/components/objectinspector/objectinspector.cpp
@@ -424,7 +424,7 @@ bool ObjectInspector::ObjectInspectorPrivate::selectObject(QObject *o)
using ModelIndexSet = QSet<QModelIndex>;
const QModelIndexList objectIndexes = indexesOf(o);
- if (objectIndexes.empty())
+ if (objectIndexes.isEmpty())
return false;
QItemSelectionModel *selectionModel = m_treeView->selectionModel();
@@ -432,8 +432,10 @@ bool ObjectInspector::ObjectInspectorPrivate::selectObject(QObject *o)
const ModelIndexSet currentSelectedItems(currentSelectedItemList.cbegin(), currentSelectedItemList.cend());
// Change in selection?
- if (!currentSelectedItems.empty() && currentSelectedItems == ModelIndexSet(objectIndexes.cbegin(), objectIndexes.cend()))
+ if (!currentSelectedItems.isEmpty()
+ && currentSelectedItems == ModelIndexSet(objectIndexes.cbegin(), objectIndexes.cend())) {
return true;
+ }
// do select and update
selectIndexRange(objectIndexes, MakeCurrent);
@@ -442,7 +444,7 @@ bool ObjectInspector::ObjectInspectorPrivate::selectObject(QObject *o)
void ObjectInspector::ObjectInspectorPrivate::selectIndexRange(const QModelIndexList &indexes, unsigned flags)
{
- if (indexes.empty())
+ if (indexes.isEmpty())
return;
QItemSelectionModel::SelectionFlags selectFlags = QItemSelectionModel::Select|QItemSelectionModel::Rows;
@@ -459,7 +461,7 @@ void ObjectInspector::ObjectInspectorPrivate::selectIndexRange(const QModelIndex
selectFlags &= ~(QItemSelectionModel::Clear|QItemSelectionModel::Current);
}
if (flags & MakeCurrent)
- m_treeView->scrollTo(indexes.front(), QAbstractItemView::EnsureVisible);
+ m_treeView->scrollTo(indexes.constFirst(), QAbstractItemView::EnsureVisible);
}
void ObjectInspector::ObjectInspectorPrivate::clear()
@@ -528,10 +530,10 @@ void ObjectInspector::ObjectInspectorPrivate::setFormWindowBlocked(QDesignerForm
bool applySelection = !mainContainerIsCurrent(m_formWindow);
if (!applySelection) {
const QModelIndexList currentIndexes = m_treeView->selectionModel()->selectedRows(0);
- if (currentIndexes.empty()) {
+ if (currentIndexes.isEmpty()) {
applySelection = true;
} else {
- applySelection = selectionType(m_formWindow, objectAt(currentIndexes.front())) == ManagedWidgetSelection;
+ applySelection = selectionType(m_formWindow, objectAt(currentIndexes.constFirst())) == ManagedWidgetSelection;
}
}
if (applySelection)
@@ -590,7 +592,7 @@ void ObjectInspector::ObjectInspectorPrivate::slotSelectionChanged(const QItemSe
// some index lists are multicolumn ranges
QObjectVector ObjectInspector::ObjectInspectorPrivate::indexesToObjects(const QModelIndexList &indexes) const
{
- if (indexes.empty())
+ if (indexes.isEmpty())
return QObjectVector();
QObjectVector rc;
rc.reserve(indexes.size());
@@ -638,11 +640,11 @@ void ObjectInspector::ObjectInspectorPrivate::synchronizeSelection(const QItemSe
const QModelIndexList currentSelectedIndexes = m_treeView->selectionModel()->selectedRows(0);
int deselectedManagedWidgetCount = 0;
- if (!deselected.empty())
+ if (!deselected.isEmpty())
deselectedManagedWidgetCount = selectInCursor(m_formWindow, deselected, false);
- if (newlySelected.empty()) { // Nothing selected
- if (currentSelectedIndexes.empty()) // Do not allow a null-selection, reset to main container
+ if (newlySelected.isEmpty()) { // Nothing selected
+ if (currentSelectedIndexes.isEmpty()) // Do not allow a null-selection, reset to main container
m_formWindow->clearSelection(!m_withinClearSelection);
return;
}
@@ -660,7 +662,7 @@ void ObjectInspector::ObjectInspectorPrivate::synchronizeSelection(const QItemSe
}
// And now for the unmanaged selection
m_formWindow->clearSelection(false);
- QObject *unmanagedObject = newlySelected.front();
+ QObject *unmanagedObject = newlySelected.constFirst();
m_core->propertyEditor()->setObject(unmanagedObject);
m_core->propertyEditor()->setEnabled(true);
// open container page if it is a single widget
@@ -670,7 +672,7 @@ void ObjectInspector::ObjectInspectorPrivate::synchronizeSelection(const QItemSe
}
// Open container page if it is a single widget
if (newlySelected.size() == 1) {
- QObject *object = newlySelected.back();
+ QObject *object = newlySelected.constFirst();
if (object->isWidgetType())
showContainersCurrentPage(static_cast<QWidget*>(object));
}
@@ -693,7 +695,7 @@ void ObjectInspector::ObjectInspectorPrivate::getSelection(Selection &s) const
return;
const QModelIndexList currentSelectedIndexes = m_treeView->selectionModel()->selectedRows(0);
- if (currentSelectedIndexes.empty())
+ if (currentSelectedIndexes.isEmpty())
return;
// sort objects
diff --git a/src/designer/src/components/objectinspector/objectinspectormodel.cpp b/src/designer/src/components/objectinspector/objectinspectormodel.cpp
index 6baf4bcdc..f6e7c78f2 100644
--- a/src/designer/src/components/objectinspector/objectinspectormodel.cpp
+++ b/src/designer/src/components/objectinspector/objectinspectormodel.cpp
@@ -260,8 +260,6 @@ namespace qdesigner_internal {
setItemsDisplayData(row, icons, ClassNameChanged|ObjectNameChanged|ClassIconChanged|TypeChanged|LayoutTypeChanged);
}
- using ObjectModel = QList<ObjectData>;
-
// Recursive routine that creates the model by traversing the form window object tree.
void createModelRecursion(const QDesignerFormWindowInterface *fwi,
QObject *parent,
@@ -269,9 +267,7 @@ namespace qdesigner_internal {
ObjectModel &model,
const ModelRecursionContext &ctx)
{
- using ButtonGroupList = QList<QButtonGroup *>;
- using ActionList = QList<QAction *>;
-
+ using ButtonGroupList = QVector<QButtonGroup *>;
// 1) Create entry
const ObjectData entry(parent, object, ctx);
model.push_back(entry);
@@ -289,46 +285,41 @@ namespace qdesigner_internal {
}
}
- QObjectList children = object->children();
- if (!children.empty()) {
+ if (!object->children().isEmpty()) {
ButtonGroupList buttonGroups;
+ QObjectList children = object->children();
std::sort(children.begin(), children.end(), sortEntry);
- const QObjectList::const_iterator cend = children.constEnd();
- for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it) {
+ for (QObject *childObject : qAsConst(children)) {
// Managed child widgets unless we had a container extension
- if ((*it)->isWidgetType()) {
+ if (childObject->isWidgetType()) {
if (!containerExtension) {
- QWidget *widget = qobject_cast<QWidget*>(*it);
+ QWidget *widget = qobject_cast<QWidget*>(childObject);
if (fwi->isManaged(widget))
createModelRecursion(fwi, object, widget, model, ctx);
}
} else {
- if (ctx.mdb->item(*it)) {
- if (QButtonGroup *bg = qobject_cast<QButtonGroup*>(*it))
+ if (ctx.mdb->item(childObject)) {
+ if (auto bg = qobject_cast<QButtonGroup*>(childObject))
buttonGroups.push_back(bg);
} // Has MetaDataBase entry
}
}
// Add button groups
- if (!buttonGroups.empty()) {
- const ButtonGroupList::const_iterator bgcend = buttonGroups.constEnd();
- for (ButtonGroupList::const_iterator bgit = buttonGroups.constBegin(); bgit != bgcend; ++bgit)
- createModelRecursion(fwi, object, *bgit, model, ctx);
+ if (!buttonGroups.isEmpty()) {
+ for (QButtonGroup *group : qAsConst(buttonGroups))
+ createModelRecursion(fwi, object, group, model, ctx);
}
} // has children
if (object->isWidgetType()) {
// Add actions
- const ActionList actions = static_cast<QWidget*>(object)->actions();
- if (!actions.empty()) {
- const ActionList::const_iterator cend = actions.constEnd();
- for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it)
- if (ctx.mdb->item(*it)) {
- QAction *action = *it;
- QObject *obj = action;
- if (action->menu())
- obj = action->menu();
- createModelRecursion(fwi, object, obj, model, ctx);
- }
+ const auto actions = static_cast<QWidget*>(object)->actions();
+ for (QAction *action : actions) {
+ if (ctx.mdb->item(action)) {
+ QObject *childObject = action;
+ if (auto menu = action->menu())
+ childObject = menu;
+ createModelRecursion(fwi, object, childObject, model, ctx);
+ }
}
}
}
@@ -415,7 +406,7 @@ namespace qdesigner_internal {
void ObjectInspectorModel::rebuild(const ObjectModel &newModel)
{
clearItems();
- if (newModel.empty())
+ if (newModel.isEmpty())
return;
const ObjectModel::const_iterator mcend = newModel.constEnd();
@@ -424,7 +415,7 @@ namespace qdesigner_internal {
StandardItemList rootRow = createModelRow(it->object());
it->setItems(rootRow, m_icons);
appendRow(rootRow);
- m_objectIndexMultiMap.insert(it->object(), indexFromItem(rootRow.front()));
+ m_objectIndexMultiMap.insert(it->object(), indexFromItem(rootRow.constFirst()));
for (++it; it != mcend; ++it) {
// Add to parent item, found via map
const QModelIndex parentIndex = m_objectIndexMultiMap.value(it->parent(), QModelIndex());
@@ -433,7 +424,7 @@ namespace qdesigner_internal {
StandardItemList row = createModelRow(it->object());
it->setItems(row, m_icons);
parentItem->appendRow(row);
- m_objectIndexMultiMap.insert(it->object(), indexFromItem(row.front()));
+ m_objectIndexMultiMap.insert(it->object(), indexFromItem(row.constFirst()));
}
}
diff --git a/src/designer/src/components/objectinspector/objectinspectormodel_p.h b/src/designer/src/components/objectinspector/objectinspectormodel_p.h
index f138253a5..14bcf78cb 100644
--- a/src/designer/src/components/objectinspector/objectinspectormodel_p.h
+++ b/src/designer/src/components/objectinspector/objectinspectormodel_p.h
@@ -48,6 +48,7 @@
#include <QtCore/qlist.h>
#include <QtCore/qmap.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -114,7 +115,7 @@ namespace qdesigner_internal {
inline bool operator==(const ObjectData &e1, const ObjectData &e2) { return e1.equals(e2); }
inline bool operator!=(const ObjectData &e1, const ObjectData &e2) { return !e1.equals(e2); }
- using ObjectModel = QList<ObjectData>;
+ using ObjectModel = QVector<ObjectData>;
// QStandardItemModel for ObjectInspector. Uses ObjectData/ObjectModel
// internally for its updates.
diff --git a/src/designer/src/components/propertyeditor/designerpropertymanager.cpp b/src/designer/src/components/propertyeditor/designerpropertymanager.cpp
index 2f1a65940..27d265696 100644
--- a/src/designer/src/components/propertyeditor/designerpropertymanager.cpp
+++ b/src/designer/src/components/propertyeditor/designerpropertymanager.cpp
@@ -1012,7 +1012,7 @@ void DesignerPropertyManager::slotValueChanged(QtProperty *property, const QVari
}
if (QtProperty *flagProperty = m_flagToProperty.value(property, 0)) {
- const QList<QtProperty *> subFlags = m_propertyToFlags.value(flagProperty);
+ const auto subFlags = m_propertyToFlags.value(flagProperty);
const int subFlagCount = subFlags.count();
// flag changed
const bool subValue = variantProperty(property)->value().toBool();
@@ -1025,7 +1025,7 @@ void DesignerPropertyManager::slotValueChanged(QtProperty *property, const QVari
m_changingSubValue = true;
FlagData data = m_flagValues.value(flagProperty);
- const QList<uint> values = data.values;
+ const auto values = data.values;
// Compute new value, without including (additional) supermasks
if (values.at(subIndex) == 0) {
for (int i = 0; i < subFlagCount; ++i) {
@@ -1123,7 +1123,7 @@ void DesignerPropertyManager::slotPropertyDestroyed(QtProperty *property)
{
if (QtProperty *flagProperty = m_flagToProperty.value(property, 0)) {
PropertyToPropertyListMap::iterator it = m_propertyToFlags.find(flagProperty);
- QList<QtProperty *> &propertyList = it.value();
+ auto &propertyList = it.value();
propertyList.replace(propertyList.indexOf(property), 0);
m_flagToProperty.remove(property);
} else if (QtProperty *alignProperty = m_alignHToProperty.value(property, 0)) {
@@ -1516,15 +1516,13 @@ QString DesignerPropertyManager::valueText(const QtProperty *property) const
const uint v = data.val;
const QChar bar = QLatin1Char('|');
QString valueStr;
- const QList<QPair<QString, uint> > flags = data.flags;
- const QList<QPair<QString, uint> >::const_iterator fcend = flags.constEnd();
- for (QList<QPair<QString, uint> >::const_iterator it = flags.constBegin(); it != fcend; ++it) {
- const uint val = it->second;
+ for (const DesignerIntPair &p : data.flags) {
+ const uint val = p.second;
const bool checked = (val == 0) ? (v == 0) : ((val & v) == val);
if (checked) {
if (!valueStr.isEmpty())
valueStr += bar;
- valueStr += it->first;
+ valueStr += p.first;
}
}
return valueStr;
@@ -1754,8 +1752,8 @@ void DesignerPropertyManager::setValue(QtProperty *property, const QVariant &val
// set Value
- const QList<uint> values = data.values;
- const QList<QtProperty *> subFlags = m_propertyToFlags.value(property);
+ const auto values = data.values;
+ const auto subFlags = m_propertyToFlags.value(property);
const int subFlagCount = subFlags.count();
for (int i = 0; i < subFlagCount; ++i) {
QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
@@ -2272,7 +2270,7 @@ void DesignerEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *
template <class EditorContainer, class Editor, class SetterParameter, class Value>
static inline void applyToEditors(const EditorContainer &list, void (Editor::*setter)(SetterParameter), const Value &value)
{
- if (list.empty()) {
+ if (list.isEmpty()) {
return;
}
for (auto it = list.constBegin(), end = list.constEnd(); it != end; ++it) {
@@ -2317,7 +2315,7 @@ void DesignerEditorFactory::slotPropertyChanged(QtProperty *property)
defaultPixmap = qvariant_cast<QIcon>(manager->attributeValue(property, QLatin1String(defaultResourceAttributeC))).pixmap(16, 16);
else if (m_fwb)
defaultPixmap = m_fwb->iconCache()->icon(qvariant_cast<PropertySheetIconValue>(manager->value(property))).pixmap(16, 16);
- const QList<PixmapEditor *> editors = m_iconPropertyToEditors.value(property);
+ const auto editors = m_iconPropertyToEditors.value(property);
for (PixmapEditor *editor : editors)
editor->setDefaultPixmap(defaultPixmap);
}
@@ -2659,7 +2657,7 @@ void DesignerEditorFactory::slotStringTextChanged(const QString &value)
PropertySheetStringValue strVal = qvariant_cast<PropertySheetStringValue>(val);
strVal.setValue(value);
// Disable translation if no translation subproperties exist.
- if (varProp->subProperties().empty())
+ if (varProp->subProperties().isEmpty())
strVal.setTranslatable(false);
val = QVariant::fromValue(strVal);
} else {
@@ -2725,7 +2723,7 @@ void DesignerEditorFactory::slotStringListChanged(const QStringList &value)
PropertySheetStringListValue listValue = qvariant_cast<PropertySheetStringListValue>(val);
listValue.setValue(value);
// Disable translation if no translation subproperties exist.
- if (varProp->subProperties().empty())
+ if (varProp->subProperties().isEmpty())
listValue.setTranslatable(false);
val = QVariant::fromValue(listValue);
} else {
@@ -2746,7 +2744,7 @@ ResetDecorator::ResetDecorator(const QDesignerFormEditorInterface *core, QObject
ResetDecorator::~ResetDecorator()
{
- const QList<ResetWidget *> editors = m_resetWidgetToProperty.keys();
+ const auto editors = m_resetWidgetToProperty.keys();
qDeleteAll(editors);
}
@@ -2819,7 +2817,7 @@ QWidget *ResetDecorator::editor(QWidget *subEditor, bool resettable, QtAbstractP
void ResetDecorator::slotPropertyChanged(QtProperty *property)
{
- QMap<QtProperty *, QList<ResetWidget *> >::ConstIterator prIt = m_createdResetWidgets.constFind(property);
+ const auto prIt = m_createdResetWidgets.constFind(property);
if (prIt == m_createdResetWidgets.constEnd())
return;
diff --git a/src/designer/src/components/propertyeditor/fontpropertymanager.cpp b/src/designer/src/components/propertyeditor/fontpropertymanager.cpp
index a29867011..b34b288a5 100644
--- a/src/designer/src/components/propertyeditor/fontpropertymanager.cpp
+++ b/src/designer/src/components/propertyeditor/fontpropertymanager.cpp
@@ -86,7 +86,7 @@ namespace qdesigner_internal {
// Map the font family names to display names retrieved from the XML configuration
static QStringList designerFamilyNames(QStringList families, const FontPropertyManager::NameMap &nm)
{
- if (nm.empty())
+ if (nm.isEmpty())
return families;
const auto ncend = nm.constEnd();
@@ -117,9 +117,9 @@ namespace qdesigner_internal {
m_propertyToAntialiasing[property] = antialiasing;
m_antialiasingToProperty[antialiasing] = property;
// Fiddle family names
- if (!m_familyMappings.empty()) {
+ if (!m_familyMappings.isEmpty()) {
const PropertyToSubPropertiesMap::iterator it = m_propertyToFontSubProperties.find(m_createdFontProperty);
- QtVariantProperty *familyProperty = vm->variantProperty(it.value().front());
+ QtVariantProperty *familyProperty = vm->variantProperty(it.value().constFirst());
const QString enumNamesAttribute = QStringLiteral("enumNames");
QStringList plainFamilyNames = familyProperty->attributeValue(enumNamesAttribute).toStringList();
// Did someone load fonts or something?
diff --git a/src/designer/src/components/propertyeditor/paletteeditor.cpp b/src/designer/src/components/propertyeditor/paletteeditor.cpp
index 4bb1bf450..64ed49a61 100644
--- a/src/designer/src/components/propertyeditor/paletteeditor.cpp
+++ b/src/designer/src/components/propertyeditor/paletteeditor.cpp
@@ -31,13 +31,29 @@
#include <iconloader_p.h>
#include <qtcolorbutton.h>
+#include <private/formbuilderextra_p.h>
+#include <private/ui4_p.h>
+
#include <QtDesigner/abstractformeditor.h>
#include <QtDesigner/abstractformwindowmanager.h>
+#include <QtCore/qfile.h>
#include <QtCore/qmetaobject.h>
+#include <QtCore/qsavefile.h>
+#include <QtCore/qxmlstream.h>
+#include <QtGui/qguiapplication.h>
#include <QtGui/qpainter.h>
+#include <QtGui/qscreen.h>
+#if QT_CONFIG(clipboard)
+# include <QtGui/qclipboard.h>
+#endif
+#include <QtWidgets/qaction.h>
+#include <QtWidgets/qfiledialog.h>
+#include <QtWidgets/qmessagebox.h>
+#include <QtWidgets/qpushbutton.h>
#include <QtWidgets/qtoolbutton.h>
#include <QtWidgets/qlabel.h>
+#include <QtWidgets/qmenu.h>
#include <QtWidgets/qheaderview.h>
QT_BEGIN_NAMESPACE
@@ -48,14 +64,15 @@ enum { BrushRole = 33 };
PaletteEditor::PaletteEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
QDialog(parent),
- m_currentColorGroup(QPalette::Active),
m_paletteModel(new PaletteModel(this)),
- m_modelUpdated(false),
- m_paletteUpdated(false),
- m_compute(true),
m_core(core)
{
ui.setupUi(this);
+ auto saveButton = ui.buttonBox->addButton(tr("Save..."), QDialogButtonBox::ActionRole);
+ connect(saveButton, &QPushButton::clicked, this, &PaletteEditor::save);
+ auto loadButton = ui.buttonBox->addButton(tr("Load..."), QDialogButtonBox::ActionRole);
+ connect(loadButton, &QPushButton::clicked, this, &PaletteEditor::load);
+
ui.paletteView->setModel(m_paletteModel);
updatePreviewPalette();
updateStyledButton();
@@ -71,6 +88,14 @@ PaletteEditor::PaletteEditor(QDesignerFormEditorInterface *core, QWidget *parent
ui.paletteView->setRootIsDecorated(false);
ui.paletteView->setColumnHidden(2, true);
ui.paletteView->setColumnHidden(3, true);
+ ui.paletteView->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui.paletteView, &QWidget::customContextMenuRequested,
+ this, &PaletteEditor::viewContextMenuRequested);
+
+ const auto itemRect = ui.paletteView->visualRect(m_paletteModel->index(0, 0));
+ const int minHeight = qMin(itemRect.height() * QPalette::NColorRoles,
+ (screen()->geometry().height() * 2) / 3);
+ ui.paletteView->setMinimumSize({itemRect.width() * 4, minHeight});
}
PaletteEditor::~PaletteEditor() = default;
@@ -221,6 +246,145 @@ QPalette PaletteEditor::getPalette(QDesignerFormEditorInterface *core, QWidget*
return result == QDialog::Accepted ? dlg.palette() : init;
}
+void PaletteEditor::viewContextMenuRequested(const QPoint &pos)
+{
+ const auto index = ui.paletteView->indexAt(pos);
+ if (!index.isValid())
+ return;
+ auto brush = m_paletteModel->brushAt(index);
+ const auto color = brush.color();
+ if (!m_contextMenu) {
+ m_contextMenu = new QMenu(this);
+ m_lighterAction = m_contextMenu->addAction(tr("Lighter"));
+ m_darkerAction = m_contextMenu->addAction(tr("Darker"));
+ m_copyColorAction = m_contextMenu->addAction(QString());
+ }
+ const auto rgb = color.rgb() & 0xffffffu;
+ const bool isBlack = rgb == 0u;
+ m_lighterAction->setEnabled(rgb != 0xffffffu);
+ m_darkerAction->setDisabled(isBlack);
+ m_copyColorAction->setText(tr("Copy color %1").arg(color.name()));
+ auto action = m_contextMenu->exec(ui.paletteView->viewport()->mapToGlobal(pos));
+ if (!action)
+ return;
+ if (action == m_copyColorAction) {
+#if QT_CONFIG(clipboard)
+ QGuiApplication::clipboard()->setText(color.name());
+#endif
+ return;
+ }
+ // Fall through to darker/lighter. Note: black cannot be made lighter due
+ // to QTBUG-9343.
+ enum : int { factor = 120 };
+ const QColor newColor = action == m_darkerAction
+ ? color.darker(factor)
+ : (isBlack ? QColor(0x404040u) : color.lighter(factor));
+ brush.setColor(newColor);
+ m_paletteModel->setData(index, QVariant(brush), BrushRole);
+}
+
+static inline QString paletteSuffix() { return QStringLiteral("xml"); }
+
+static inline QString paletteFilter()
+{
+ return PaletteEditor::tr("QPalette UI file (*.xml)");
+}
+
+static bool savePalette(const QString &fileName, const QPalette &pal, QString *errorMessage)
+{
+ QSaveFile file;
+ file.setFileName(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ *errorMessage = PaletteEditor::tr("Cannot open %1 for writing: %2")
+ .arg(QDir::toNativeSeparators(fileName), file.errorString());
+ return false;
+ }
+ {
+ QScopedPointer<DomPalette> domPalette(QFormBuilderExtra::savePalette(pal));
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ domPalette->write(writer);
+ writer.writeEndDocument();
+ }
+ const bool result = file.commit();
+ if (!result) {
+ *errorMessage = PaletteEditor::tr("Cannot write %1: %2")
+ .arg(QDir::toNativeSeparators(fileName), file.errorString());
+ }
+ return result;
+}
+
+static QString msgCannotReadPalette(const QString &fileName, const QXmlStreamReader &reader,
+ const QString &why)
+{
+ return PaletteEditor::tr("Cannot read palette from %1:%2:%3")
+ .arg(QDir::toNativeSeparators(fileName)).arg(reader.lineNumber()).arg(why);
+}
+
+static inline QString msgCannotReadPalette(const QString &fileName, const QXmlStreamReader &reader)
+{
+ return msgCannotReadPalette(fileName, reader, reader.errorString());
+}
+
+static bool loadPalette(const QString &fileName, QPalette *pal, QString *errorMessage)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ *errorMessage = PaletteEditor::tr("Cannot open %1 for reading: %2")
+ .arg(QDir::toNativeSeparators(fileName), file.errorString());
+ return false;
+ }
+ QXmlStreamReader reader(&file);
+ if (!reader.readNextStartElement()) {
+ *errorMessage = msgCannotReadPalette(fileName, reader);
+ return false;
+ }
+ if (reader.name() != QLatin1String("palette")) {
+ const auto why = PaletteEditor::tr("Invalid element \"%1\", expected \"palette\".")
+ .arg(reader.name().toString());
+ *errorMessage = msgCannotReadPalette(fileName, reader, why);
+ return false;
+ }
+ QScopedPointer<DomPalette> domPalette(new DomPalette);
+ domPalette->read(reader);
+ if (reader.hasError()) {
+ *errorMessage = msgCannotReadPalette(fileName, reader);
+ return false;
+ }
+ *pal = QFormBuilderExtra::loadPalette(domPalette.data());
+ return true;
+}
+
+void PaletteEditor::save()
+{
+ QFileDialog dialog(this, tr("Save Palette"), QString(), paletteFilter());
+ dialog.setAcceptMode(QFileDialog::AcceptSave);
+ dialog.setDefaultSuffix(paletteSuffix());
+ while (dialog.exec() == QDialog::Accepted) {
+ QString errorMessage;
+ if (savePalette(dialog.selectedFiles().constFirst(), palette(), &errorMessage))
+ break;
+ QMessageBox::warning(this, tr("Error Writing Palette"), errorMessage);
+ }
+}
+
+void PaletteEditor::load()
+{
+ QFileDialog dialog(this, tr("Load Palette"), QString(), paletteFilter());
+ dialog.setAcceptMode(QFileDialog::AcceptOpen);
+ while (dialog.exec() == QDialog::Accepted) {
+ QPalette pal;
+ QString errorMessage;
+ if (loadPalette(dialog.selectedFiles().constFirst(), &pal, &errorMessage)) {
+ setPalette(pal);
+ break;
+ }
+ QMessageBox::warning(this, tr("Error Reading Palette"), errorMessage);
+ }
+}
+
//////////////////////
PaletteModel::PaletteModel(QObject *parent) :
@@ -230,14 +394,17 @@ PaletteModel::PaletteModel(QObject *parent) :
const int index = meta->indexOfProperty("colorRole");
const QMetaProperty p = meta->property(index);
const QMetaEnum e = p.enumerator();
+ m_roleEntries.reserve(QPalette::NColorRoles);
for (int r = QPalette::WindowText; r < QPalette::NColorRoles; r++) {
- m_roleNames[static_cast<QPalette::ColorRole>(r)] = QLatin1String(e.key(r));
+ const auto role = static_cast<QPalette::ColorRole>(r);
+ if (role != QPalette::NoRole)
+ m_roleEntries.append({QLatin1String(e.key(r)), role});
}
}
int PaletteModel::rowCount(const QModelIndex &) const
{
- return m_roleNames.count();
+ return m_roleEntries.size();
}
int PaletteModel::columnCount(const QModelIndex &) const
@@ -245,29 +412,35 @@ int PaletteModel::columnCount(const QModelIndex &) const
return 4;
}
+QBrush PaletteModel::brushAt(const QModelIndex &index) const
+{
+ return m_palette.brush(columnToGroup(index.column()), roleAt(index.row()));
+}
+
QVariant PaletteModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
- if (index.row() < 0 || index.row() >= QPalette::NColorRoles)
+ if (index.row() < 0 || index.row() >= m_roleEntries.size())
return QVariant();
if (index.column() < 0 || index.column() >= 4)
return QVariant();
if (index.column() == 0) {
if (role == Qt::DisplayRole)
- return m_roleNames[static_cast<QPalette::ColorRole>(index.row())];
+ return m_roleEntries.at(index.row()).name;
if (role == Qt::EditRole) {
const uint mask = m_palette.resolve();
- if (mask & (1 << index.row()))
+ if (mask & (1 << int(roleAt(index.row()))))
return true;
return false;
}
return QVariant();
}
+ if (role == Qt::ToolTipRole)
+ return brushAt(index).color().name();
if (role == BrushRole)
- return m_palette.brush(columnToGroup(index.column()),
- static_cast<QPalette::ColorRole>(index.row()));
+ return brushAt(index);
return QVariant();
}
@@ -276,17 +449,19 @@ bool PaletteModel::setData(const QModelIndex &index, const QVariant &value, int
if (!index.isValid())
return false;
+ const int row = index.row();
+ const auto colorRole = roleAt(row);
+
if (index.column() != 0 && role == BrushRole) {
const QBrush br = qvariant_cast<QBrush>(value);
- const QPalette::ColorRole r = static_cast<QPalette::ColorRole>(index.row());
const QPalette::ColorGroup g = columnToGroup(index.column());
- m_palette.setBrush(g, r, br);
+ m_palette.setBrush(g, colorRole, br);
- QModelIndex idxBegin = PaletteModel::index(r, 0);
- QModelIndex idxEnd = PaletteModel::index(r, 3);
+ QModelIndex idxBegin = PaletteModel::index(row, 0);
+ QModelIndex idxEnd = PaletteModel::index(row, 3);
if (m_compute) {
- m_palette.setBrush(QPalette::Inactive, r, br);
- switch (r) {
+ m_palette.setBrush(QPalette::Inactive, colorRole, br);
+ switch (colorRole) {
case QPalette::WindowText:
case QPalette::Text:
case QPalette::ButtonText:
@@ -298,18 +473,18 @@ bool PaletteModel::setData(const QModelIndex &index, const QVariant &value, int
m_palette.setBrush(QPalette::Disabled, QPalette::Text, br);
m_palette.setBrush(QPalette::Disabled, QPalette::ButtonText, br);
idxBegin = PaletteModel::index(0, 0);
- idxEnd = PaletteModel::index(m_roleNames.count() - 1, 3);
+ idxEnd = PaletteModel::index(m_roleEntries.size() - 1, 3);
break;
case QPalette::Window:
m_palette.setBrush(QPalette::Disabled, QPalette::Base, br);
m_palette.setBrush(QPalette::Disabled, QPalette::Window, br);
- idxBegin = PaletteModel::index(QPalette::Base, 0);
+ idxBegin = PaletteModel::index(rowOf(QPalette::Base), 0);
break;
case QPalette::Highlight:
//m_palette.setBrush(QPalette::Disabled, QPalette::Highlight, c.dark(120));
break;
default:
- m_palette.setBrush(QPalette::Disabled, r, br);
+ m_palette.setBrush(QPalette::Disabled, colorRole, br);
break;
}
}
@@ -320,22 +495,21 @@ bool PaletteModel::setData(const QModelIndex &index, const QVariant &value, int
if (index.column() == 0 && role == Qt::EditRole) {
uint mask = m_palette.resolve();
const bool isMask = qvariant_cast<bool>(value);
- const int r = index.row();
if (isMask)
- mask |= (1 << r);
+ mask |= (1 << int(colorRole));
else {
- m_palette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(r),
- m_parentPalette.brush(QPalette::Active, static_cast<QPalette::ColorRole>(r)));
- m_palette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r),
- m_parentPalette.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r)));
- m_palette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r),
- m_parentPalette.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r)));
-
- mask &= ~(1 << index.row());
+ m_palette.setBrush(QPalette::Active, colorRole,
+ m_parentPalette.brush(QPalette::Active, colorRole));
+ m_palette.setBrush(QPalette::Inactive, colorRole,
+ m_parentPalette.brush(QPalette::Inactive, colorRole));
+ m_palette.setBrush(QPalette::Disabled, colorRole,
+ m_parentPalette.brush(QPalette::Disabled, colorRole));
+
+ mask &= ~(1 << int(colorRole));
}
m_palette.resolve(mask);
emit paletteChanged(m_palette);
- const QModelIndex idxEnd = PaletteModel::index(r, 3);
+ const QModelIndex idxEnd = PaletteModel::index(row, 3);
emit dataChanged(index, idxEnd);
return true;
}
@@ -375,7 +549,7 @@ void PaletteModel::setPalette(const QPalette &palette, const QPalette &parentPal
m_parentPalette = parentPalette;
m_palette = palette;
const QModelIndex idxBegin = index(0, 0);
- const QModelIndex idxEnd = index(m_roleNames.count() - 1, 3);
+ const QModelIndex idxEnd = index(m_roleEntries.size() - 1, 3);
emit dataChanged(idxBegin, idxEnd);
}
@@ -397,6 +571,15 @@ int PaletteModel::groupToColumn(QPalette::ColorGroup group) const
return 3;
}
+int PaletteModel::rowOf(QPalette::ColorRole role) const
+{
+ for (int row = 0, size = m_roleEntries.size(); row < size; ++row) {
+ if (m_roleEntries.at(row).role == role)
+ return row;
+ }
+ return -1;
+}
+
//////////////////////////
BrushEditor::BrushEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
diff --git a/src/designer/src/components/propertyeditor/paletteeditor.h b/src/designer/src/components/propertyeditor/paletteeditor.h
index 6124340dc..b4d649163 100644
--- a/src/designer/src/components/propertyeditor/paletteeditor.h
+++ b/src/designer/src/components/propertyeditor/paletteeditor.h
@@ -34,7 +34,9 @@
QT_BEGIN_NAMESPACE
+class QAction;
class QListView;
+class QMenu;
class QLabel;
class QtColorButton;
class QDesignerFormEditorInterface;
@@ -65,6 +67,9 @@ private slots:
void on_detailsRadio_clicked();
void paletteChanged(const QPalette &palette);
+ void viewContextMenuRequested(const QPoint &pos);
+ void save();
+ void load();
protected:
@@ -81,12 +86,16 @@ private:
Ui::PaletteEditor ui;
QPalette m_editPalette;
QPalette m_parentPalette;
- QPalette::ColorGroup m_currentColorGroup;
class PaletteModel *m_paletteModel;
- bool m_modelUpdated;
- bool m_paletteUpdated;
- bool m_compute;
QDesignerFormEditorInterface *m_core;
+ QAction *m_lighterAction = nullptr;
+ QAction *m_darkerAction = nullptr;
+ QAction *m_copyColorAction = nullptr;
+ QMenu *m_contextMenu = nullptr;
+ QPalette::ColorGroup m_currentColorGroup = QPalette::Active;
+ bool m_modelUpdated = false;
+ bool m_paletteUpdated = false;
+ bool m_compute = true;
};
@@ -108,18 +117,27 @@ public:
QPalette getPalette() const;
void setPalette(const QPalette &palette, const QPalette &parentPalette);
+ QBrush brushAt(const QModelIndex &index) const;
+
QPalette::ColorRole colorRole() const { return QPalette::NoRole; }
void setCompute(bool on) { m_compute = on; }
signals:
void paletteChanged(const QPalette &palette);
private:
+ struct RoleEntry
+ {
+ QString name;
+ QPalette::ColorRole role;
+ };
QPalette::ColorGroup columnToGroup(int index) const;
int groupToColumn(QPalette::ColorGroup group) const;
+ QPalette::ColorRole roleAt(int row) const { return m_roleEntries.at(row).role; }
+ int rowOf(QPalette::ColorRole role) const;
QPalette m_palette;
QPalette m_parentPalette;
- QMap<QPalette::ColorRole, QString> m_roleNames;
+ QVector<RoleEntry> m_roleEntries;
bool m_compute = true;
};
diff --git a/src/designer/src/components/propertyeditor/paletteeditor.ui b/src/designer/src/components/propertyeditor/paletteeditor.ui
index aa5965d79..2bb8cfedc 100644
--- a/src/designer/src/components/propertyeditor/paletteeditor.ui
+++ b/src/designer/src/components/propertyeditor/paletteeditor.ui
@@ -1,4 +1,5 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<comment>*********************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
@@ -27,175 +28,183 @@
**
*********************************************************************</comment>
<class>qdesigner_internal::PaletteEditor</class>
- <widget class="QDialog" name="qdesigner_internal::PaletteEditor" >
- <property name="geometry" >
+ <widget class="QDialog" name="qdesigner_internal::PaletteEditor">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>365</width>
- <height>409</height>
+ <width>918</width>
+ <height>599</height>
</rect>
</property>
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>7</hsizetype>
- <vsizetype>7</vsizetype>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>Edit Palette</string>
</property>
- <layout class="QVBoxLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QGroupBox" name="advancedBox" >
- <property name="minimumSize" >
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize" >
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="title" >
- <string>Tune Palette</string>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="0" column="1" >
- <widget class="QtColorButton" name="buildButton" >
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>7</hsizetype>
- <vsizetype>13</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QGroupBox" name="advancedBox">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Tune Palette</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="leftMargin">
+ <number>9</number>
</property>
- <property name="text" >
- <string/>
+ <property name="topMargin">
+ <number>9</number>
</property>
- </widget>
- </item>
- <item row="1" column="0" colspan="4" >
- <widget class="QTreeView" name="paletteView" >
- <property name="minimumSize" >
- <size>
- <width>0</width>
- <height>200</height>
- </size>
+ <property name="rightMargin">
+ <number>9</number>
</property>
- </widget>
- </item>
- <item row="0" column="3" >
- <widget class="QRadioButton" name="detailsRadio" >
- <property name="text" >
- <string>Show Details</string>
+ <property name="bottomMargin">
+ <number>9</number>
</property>
- </widget>
- </item>
- <item row="0" column="2" >
- <widget class="QRadioButton" name="computeRadio" >
- <property name="text" >
- <string>Compute Details</string>
+ <property name="spacing">
+ <number>6</number>
</property>
- <property name="checked" >
- <bool>true</bool>
+ <item row="0" column="1">
+ <widget class="QtColorButton" name="buildButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="4">
+ <widget class="QTreeView" name="paletteView">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>200</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QRadioButton" name="detailsRadio">
+ <property name="text">
+ <string>Show Details</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QRadioButton" name="computeRadio">
+ <property name="text">
+ <string>Compute Details</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Quick</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="GroupBox126">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Preview</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="leftMargin">
+ <number>8</number>
</property>
- </widget>
- </item>
- <item row="0" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Quick</string>
+ <property name="topMargin">
+ <number>8</number>
</property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="GroupBox126" >
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>5</hsizetype>
- <vsizetype>7</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title" >
- <string>Preview</string>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>8</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="0" column="2" >
- <widget class="QRadioButton" name="disabledRadio" >
- <property name="text" >
- <string>Disabled</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QRadioButton" name="inactiveRadio" >
- <property name="text" >
- <string>Inactive</string>
+ <property name="rightMargin">
+ <number>8</number>
</property>
- </widget>
- </item>
- <item row="0" column="0" >
- <widget class="QRadioButton" name="activeRadio" >
- <property name="text" >
- <string>Active</string>
+ <property name="bottomMargin">
+ <number>8</number>
</property>
- <property name="checked" >
- <bool>true</bool>
+ <property name="spacing">
+ <number>6</number>
</property>
- </widget>
- </item>
- <item row="1" column="0" colspan="3" >
- <widget class="qdesigner_internal::PreviewFrame" native="1" name="previewFrame" >
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>7</hsizetype>
- <vsizetype>7</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
+ <item row="0" column="2">
+ <widget class="QRadioButton" name="disabledRadio">
+ <property name="text">
+ <string>Disabled</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="inactiveRadio">
+ <property name="text">
+ <string>Inactive</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="activeRadio">
+ <property name="text">
+ <string>Active</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="qdesigner_internal::PreviewFrame" name="previewFrame" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="standardButtons" >
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
@@ -221,11 +230,11 @@
<receiver>qdesigner_internal::PaletteEditor</receiver>
<slot>accept()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>180</x>
<y>331</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>134</x>
<y>341</y>
</hint>
@@ -237,11 +246,11 @@
<receiver>qdesigner_internal::PaletteEditor</receiver>
<slot>reject()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>287</x>
<y>329</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>302</x>
<y>342</y>
</hint>
diff --git a/src/designer/src/components/propertyeditor/previewframe.cpp b/src/designer/src/components/propertyeditor/previewframe.cpp
index a97e46877..c093663e2 100644
--- a/src/designer/src/components/propertyeditor/previewframe.cpp
+++ b/src/designer/src/components/propertyeditor/previewframe.cpp
@@ -78,7 +78,7 @@ PreviewFrame::PreviewFrame(QWidget *parent) :
void PreviewFrame::setPreviewPalette(const QPalette &pal)
{
- ensureMdiSubWindow()->widget()->setPalette(pal);
+ ensureMdiSubWindow()->setPalette(pal);
}
void PreviewFrame::setSubWindowActive(bool active)
diff --git a/src/designer/src/components/propertyeditor/previewwidget.cpp b/src/designer/src/components/propertyeditor/previewwidget.cpp
index cc5a3af31..d041ec9be 100644
--- a/src/designer/src/components/propertyeditor/previewwidget.cpp
+++ b/src/designer/src/components/propertyeditor/previewwidget.cpp
@@ -28,6 +28,11 @@
#include "previewwidget.h"
+#include <QtWidgets/qaction.h>
+#include <QtWidgets/qmenu.h>
+
+#include <QtCore/qabstractitemmodel.h>
+
QT_BEGIN_NAMESPACE
using namespace qdesigner_internal;
@@ -36,6 +41,16 @@ PreviewWidget::PreviewWidget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
+ ui.treeWidget->expandAll();
+ auto model = ui.treeWidget->model();
+ ui.treeWidget->setCurrentIndex(model->index(0, 0, model->index(0, 0)));
+ auto toolButtonMenu = new QMenu(ui.menuToolButton);
+ toolButtonMenu->addAction(tr("Option 1"));
+ toolButtonMenu->addSeparator();
+ auto checkable = toolButtonMenu->addAction(tr("Checkable"));
+ checkable->setCheckable(true);
+ ui.menuToolButton->setMenu(toolButtonMenu);
+ ui.menuToolButton->setPopupMode(QToolButton::InstantPopup);
}
PreviewWidget::~PreviewWidget() = default;
diff --git a/src/designer/src/components/propertyeditor/previewwidget.ui b/src/designer/src/components/propertyeditor/previewwidget.ui
index fc81c8b85..077ff24b4 100644
--- a/src/designer/src/components/propertyeditor/previewwidget.ui
+++ b/src/designer/src/components/propertyeditor/previewwidget.ui
@@ -1,4 +1,5 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<comment>*********************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
@@ -27,191 +28,296 @@
**
*********************************************************************</comment>
<class>qdesigner_internal::PreviewWidget</class>
- <widget class="QWidget" name="qdesigner_internal::PreviewWidget" >
- <property name="geometry" >
+ <widget class="QWidget" name="qdesigner_internal::PreviewWidget">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>471</width>
- <height>251</height>
+ <width>608</width>
+ <height>367</height>
</rect>
</property>
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>1</hsizetype>
- <vsizetype>1</vsizetype>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string extracomment="Palette Editor Preview Widget">Preview Window</string>
</property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item rowspan="3" row="0" column="1" >
- <layout class="QVBoxLayout" >
- <property name="margin" >
- <number>0</number>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="buttonGroup">
+ <property name="title">
+ <string extracomment="Palette Editor Preview Widget">Buttons</string>
</property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <widget class="QLineEdit" name="LineEdit1" >
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">LineEdit</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="ComboBox1" >
- <item>
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">ComboBox</string>
- </property>
- </item>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <property name="margin" >
- <number>0</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <widget class="QSpinBox" name="SpinBox1" />
- </item>
- <item>
- <widget class="QPushButton" name="PushButton1" >
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">PushButton</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QScrollBar" name="ScrollBar1" >
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSlider" name="Slider1" >
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListWidget" name="listWidget" >
- <property name="maximumSize" >
- <size>
- <width>32767</width>
- <height>50</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="3" column="0" colspan="2" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="2" column="0" >
- <widget class="QProgressBar" name="ProgressBar1" >
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
+ <property name="checkable">
+ <bool>true</bool>
</property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QRadioButton" name="RadioButton1">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">RadioButton1</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="RadioButton2">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">RadioButton2</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="RadioButton3">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">RadioButton3</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="CheckBox1">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">CheckBox1</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="CheckBox2">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Tristate CheckBox</string>
+ </property>
+ <property name="tristate">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="PushButton1">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">PushButton</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="toggleButton">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">ToggleButton</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="toolButton">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">ToolButton</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="menuToolButton">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Menu</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QGroupBox" name="ButtonGroup2" >
- <property name="title" >
- <string extracomment="Palette Editor Preview Widget">ButtonGroup2</string>
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="itemGroupBox">
+ <property name="title">
+ <string extracomment="Palette Editor Preview Widget">Item Views</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
</property>
- <layout class="QVBoxLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
<item>
- <widget class="QCheckBox" name="CheckBox1" >
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">CheckBox1</string>
- </property>
- <property name="checked" >
+ <widget class="QTreeWidget" name="treeWidget">
+ <property name="alternatingRowColors">
<bool>true</bool>
</property>
+ <column>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Column 1</string>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Top Level 1</string>
+ </property>
+ <item>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Nested Item 1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Nested Item 2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Nested Item 3</string>
+ </property>
+ </item>
+ </item>
</widget>
</item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="simpleGroupBox">
+ <property name="title">
+ <string extracomment="Palette Editor Preview Widget">Simple Input Widgets</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLineEdit" name="LineEdit1">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">LineEdit</string>
+ </property>
+ <property name="clearButtonEnabled">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ComboBox1">
+ <item>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">ComboBox</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Item1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">Item2</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
<item>
- <widget class="QCheckBox" name="CheckBox2" >
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">CheckBox2</string>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QSpinBox" name="SpinBox1"/>
+ </item>
+ <item>
+ <widget class="QScrollBar" name="ScrollBar1">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="Slider1">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</widget>
</item>
- <item row="0" column="0" >
- <widget class="QGroupBox" name="ButtonGroup1" >
- <property name="title" >
- <string extracomment="Palette Editor Preview Widget">ButtonGroup</string>
+ <item row="1" column="1">
+ <widget class="QGroupBox" name="displayGroupBox">
+ <property name="title">
+ <string extracomment="Palette Editor Preview Widget">Display Widgets</string>
</property>
- <layout class="QVBoxLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
- <widget class="QRadioButton" name="RadioButton1" >
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">RadioButton1</string>
+ <widget class="QProgressBar" name="ProgressBar1">
+ <property name="value">
+ <number>50</number>
</property>
- <property name="checked" >
- <bool>true</bool>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="RadioButton2" >
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">RadioButton2</string>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">QLabel</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="RadioButton3" >
- <property name="text" >
- <string extracomment="Palette Editor Preview Widget">RadioButton3</string>
+ <widget class="QLabel" name="label_2">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="text">
+ <string extracomment="Palette Editor Preview Widget">QLabel with frame</string>
</property>
</widget>
</item>
diff --git a/src/designer/src/components/propertyeditor/propertyeditor.cpp b/src/designer/src/components/propertyeditor/propertyeditor.cpp
index af590a7d5..392f1c3f5 100644
--- a/src/designer/src/components/propertyeditor/propertyeditor.cpp
+++ b/src/designer/src/components/propertyeditor/propertyeditor.cpp
@@ -363,7 +363,7 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare
break;
}
// Restore expansionState from QVariant map
- if (!expansionState.empty()) {
+ if (!expansionState.isEmpty()) {
const QVariantMap::const_iterator cend = expansionState.constEnd();
for (QVariantMap::const_iterator it = expansionState.constBegin(); it != cend; ++it)
m_expansionState.insert(it.key(), it.value().toBool());
@@ -386,7 +386,7 @@ void PropertyEditor::saveSettings() const
settings->setValue(QLatin1String(SortedKeyC), QVariant(m_sorting));
// Save last expansionState as QVariant map
QVariantMap expansionState;
- if (!m_expansionState.empty()) {
+ if (!m_expansionState.isEmpty()) {
const QMap<QString, bool>::const_iterator cend = m_expansionState.constEnd();
for (QMap<QString, bool>::const_iterator it = m_expansionState.constBegin(); it != cend; ++it)
expansionState.insert(it.key(), QVariant(it.value()));
@@ -436,7 +436,7 @@ void PropertyEditor::storePropertiesExpansionState(const QList<QtBrowserItem *>
{
const QChar bar = QLatin1Char('|');
for (QtBrowserItem *propertyItem : items) {
- if (!propertyItem->children().empty()) {
+ if (!propertyItem->children().isEmpty()) {
QtProperty *property = propertyItem->property();
const QString propertyName = property->propertyName();
const QMap<QtProperty *, QString>::const_iterator itGroup = m_propertyToGroup.constFind(property);
@@ -452,14 +452,14 @@ void PropertyEditor::storePropertiesExpansionState(const QList<QtBrowserItem *>
void PropertyEditor::storeExpansionState()
{
- const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ const auto items = m_currentBrowser->topLevelItems();
if (m_sorting) {
storePropertiesExpansionState(items);
} else {
for (QtBrowserItem *item : items) {
const QString groupName = item->property()->propertyName();
- QList<QtBrowserItem *> propertyItems = item->children();
- if (!propertyItems.empty())
+ auto propertyItems = item->children();
+ if (!propertyItems.isEmpty())
m_expansionState[groupName] = isExpanded(item);
// properties stuff here
@@ -470,7 +470,7 @@ void PropertyEditor::storeExpansionState()
void PropertyEditor::collapseAll()
{
- const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ const auto items = m_currentBrowser->topLevelItems();
for (QtBrowserItem *group : items)
setExpanded(group, false);
}
@@ -498,7 +498,7 @@ void PropertyEditor::applyPropertiesExpansionState(const QList<QtBrowserItem *>
void PropertyEditor::applyExpansionState()
{
- const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ const auto items = m_currentBrowser->topLevelItems();
if (m_sorting) {
applyPropertiesExpansionState(items);
} else {
@@ -533,7 +533,7 @@ int PropertyEditor::applyPropertiesFilter(const QList<QtBrowserItem *> &items)
void PropertyEditor::applyFilter()
{
- const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ const auto items = m_currentBrowser->topLevelItems();
if (m_sorting) {
applyPropertiesFilter(items);
} else {
@@ -664,7 +664,7 @@ void PropertyEditor::slotSorting(bool sort)
void PropertyEditor::updateColors()
{
if (m_treeBrowser && m_currentBrowser == m_treeBrowser) {
- const QList<QtBrowserItem *> items = m_treeBrowser->topLevelItems();
+ const auto items = m_treeBrowser->topLevelItems();
for (QtBrowserItem *item : items)
m_treeBrowser->setBackgroundColor(item, propertyColor(item->property()));
}
@@ -814,7 +814,7 @@ void PropertyEditor::updateBrowserValue(QtVariantProperty *property, const QVari
}
// Rich text string property with comment: Store/Update the font the rich text editor dialog starts out with
- if (type == QVariant::String && !property->subProperties().empty()) {
+ if (type == QVariant::String && !property->subProperties().isEmpty()) {
const int fontIndex = m_propertySheet->indexOf(m_strings.m_fontProperty);
if (fontIndex != -1)
property->setAttribute(m_strings.m_fontAttribute, m_propertySheet->property(fontIndex));
@@ -1092,9 +1092,9 @@ void PropertyEditor::setObject(QObject *object)
if (lastGroup != groupProperty) {
lastGroup = groupProperty;
lastProperty = nullptr; // Append at end
- const QList<QtProperty*> subProperties = lastGroup->subProperties();
- if (!subProperties.empty())
- lastProperty = subProperties.back();
+ const auto subProperties = lastGroup->subProperties();
+ if (!subProperties.isEmpty())
+ lastProperty = subProperties.constLast();
lastGroup = groupProperty;
}
if (!m_groups.contains(groupProperty))
@@ -1108,7 +1108,7 @@ void PropertyEditor::setObject(QObject *object)
property->setModified(m_propertySheet->isChanged(i));
if (propertyName == QStringLiteral("geometry") && type == QVariant::Rect) {
- const QList<QtProperty *> &subProperties = property->subProperties();
+ const auto &subProperties = property->subProperties();
for (QtProperty *subProperty : subProperties) {
const QString subPropertyName = subProperty->propertyName();
if (subPropertyName == QStringLiteral("X") || subPropertyName == QStringLiteral("Y"))
@@ -1123,7 +1123,7 @@ void PropertyEditor::setObject(QObject *object)
QMap<QString, QtVariantProperty *> groups = m_nameToGroup;
for (auto itGroup = groups.cbegin(), end = groups.cend(); itGroup != end; ++itGroup) {
QtVariantProperty *groupProperty = itGroup.value();
- if (groupProperty->subProperties().empty()) {
+ if (groupProperty->subProperties().isEmpty()) {
if (groupProperty == m_dynamicGroup)
m_dynamicGroup = nullptr;
delete groupProperty;
@@ -1157,7 +1157,7 @@ QtBrowserItem *PropertyEditor::nonFakePropertyBrowserItem(QtBrowserItem *item) c
{
// Top-level properties are QObject/QWidget groups, etc. Find first item property below
// which should be nonfake
- const QList<QtBrowserItem *> topLevelItems = m_currentBrowser->topLevelItems();
+ const auto topLevelItems = m_currentBrowser->topLevelItems();
do {
if (topLevelItems.contains(item->parent()))
return item;
@@ -1245,9 +1245,9 @@ void PropertyEditor::editProperty(const QString &name)
// find the browser item belonging to the property, make it current and edit it
QtBrowserItem *browserItem = nullptr;
if (QtVariantProperty *property = m_nameToProperty.value(name, 0)) {
- const QList<QtBrowserItem *> items = m_currentBrowser->items(property);
+ const auto items = m_currentBrowser->items(property);
if (items.size() == 1)
- browserItem = items.front();
+ browserItem = items.constFirst();
}
if (browserItem == nullptr)
return;
diff --git a/src/designer/src/components/signalsloteditor/connectdialog.cpp b/src/designer/src/components/signalsloteditor/connectdialog.cpp
index 571ddba12..dcb6f1ded 100644
--- a/src/designer/src/components/signalsloteditor/connectdialog.cpp
+++ b/src/designer/src/components/signalsloteditor/connectdialog.cpp
@@ -42,10 +42,6 @@
QT_BEGIN_NAMESPACE
-namespace {
- using ListWidgetItems = QList<QListWidgetItem *>;
-}
-
static QString realClassName(QDesignerFormEditorInterface *core, QWidget *widget)
{
QString class_name = QLatin1String(widget->metaObject()->className());
@@ -138,22 +134,22 @@ void ConnectDialog::populateLists()
void ConnectDialog::setSignalSlot(const QString &signal, const QString &slot)
{
- ListWidgetItems sigItems = m_ui.signalList->findItems(signal, Qt::MatchExactly);
+ auto sigItems = m_ui.signalList->findItems(signal, Qt::MatchExactly);
- if (sigItems.empty()) {
+ if (sigItems.isEmpty()) {
m_ui.showAllCheckBox->setChecked(true);
sigItems = m_ui.signalList->findItems(signal, Qt::MatchExactly);
}
- if (!sigItems.empty()) {
- selectSignal(sigItems.front());
- ListWidgetItems slotItems = m_ui.slotList->findItems(slot, Qt::MatchExactly);
- if (slotItems.empty()) {
+ if (!sigItems.isEmpty()) {
+ selectSignal(sigItems.constFirst());
+ auto slotItems = m_ui.slotList->findItems(slot, Qt::MatchExactly);
+ if (slotItems.isEmpty()) {
m_ui.showAllCheckBox->setChecked(true);
slotItems = m_ui.slotList->findItems(slot, Qt::MatchExactly);
}
- if (!slotItems.empty())
- selectSlot(slotItems.front());
+ if (!slotItems.isEmpty())
+ selectSlot(slotItems.constFirst());
}
}
@@ -194,7 +190,7 @@ void ConnectDialog::selectSlot(QListWidgetItem *item)
QString ConnectDialog::signal() const
{
- const ListWidgetItems item_list = m_ui.signalList->selectedItems();
+ const auto item_list = m_ui.signalList->selectedItems();
if (item_list.size() != 1)
return QString();
return item_list.at(0)->text();
@@ -202,7 +198,7 @@ QString ConnectDialog::signal() const
QString ConnectDialog::slot() const
{
- const ListWidgetItems item_list = m_ui.slotList->selectedItems();
+ const auto item_list = m_ui.slotList->selectedItems();
if (item_list.size() != 1)
return QString();
return item_list.at(0)->text();
diff --git a/src/designer/src/components/signalsloteditor/signalslot_utils.cpp b/src/designer/src/components/signalsloteditor/signalslot_utils.cpp
index f913b5bdf..c7a960ef3 100644
--- a/src/designer/src/components/signalsloteditor/signalslot_utils.cpp
+++ b/src/designer/src/components/signalsloteditor/signalslot_utils.cpp
@@ -93,7 +93,7 @@ static void memberList(QDesignerFormEditorInterface *core,
const QString className = wdbItem->name();
const QStringList wdbFakeMethods = member_type == qdesigner_internal::SlotMember ? wdbItem->fakeSlots() : wdbItem->fakeSignals();
- if (!wdbFakeMethods.empty())
+ if (!wdbFakeMethods.isEmpty())
for (const QString &fakeMethod : wdbFakeMethods)
if (predicate(fakeMethod)) {
*it = ClassNameSignaturePair(className, fakeMethod);
@@ -106,7 +106,7 @@ static void memberList(QDesignerFormEditorInterface *core,
if (const qdesigner_internal::MetaDataBaseItem *mdbItem = metaDataBase->metaDataBaseItem(object)) {
const QStringList mdbFakeMethods = member_type == qdesigner_internal::SlotMember ? mdbItem->fakeSlots() : mdbItem->fakeSignals();
- if (!mdbFakeMethods.empty())
+ if (!mdbFakeMethods.isEmpty())
for (const QString &fakeMethod : mdbFakeMethods)
if (predicate(fakeMethod)) {
*it = ClassNameSignaturePair(className, fakeMethod);
@@ -266,7 +266,7 @@ namespace qdesigner_internal {
{
QMap<QString, QString> rc;
memberList(core, object, type, true, EqualsPredicate(signature), SignatureIterator(&rc));
- return !rc.empty();
+ return !rc.isEmpty();
}
// ### deprecated
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp b/src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
index c2f53a46e..0868c9fe2 100644
--- a/src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
+++ b/src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
@@ -79,9 +79,6 @@ static void addWidgetToObjectList(const QWidget *w, QStringList &r)
static QStringList objectNameList(QDesignerFormWindowInterface *form)
{
- using ActionList = QList<QAction *>;
- using ButtonGroupList = QList<QButtonGroup *>;
-
QStringList result;
QWidget *mainContainer = form->mainContainer();
@@ -104,30 +101,24 @@ static QStringList objectNameList(QDesignerFormWindowInterface *form)
const QDesignerMetaDataBaseInterface *mdb = form->core()->metaDataBase();
// Add managed actions and actions with managed menus
- const ActionList actions = mainContainer->findChildren<QAction*>();
- if (!actions.empty()) {
- const ActionList::const_iterator cend = actions.constEnd();
- for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it) {
- QAction *a = *it;
- if (!a->isSeparator()) {
- if (QMenu *menu = a->menu()) {
- if (mdb->item(menu))
- result.push_back(menu->objectName());
- } else {
- if (mdb->item(a))
- result.push_back(a->objectName());
- }
+ const auto actions = mainContainer->findChildren<QAction*>();
+ for (QAction *a : actions) {
+ if (!a->isSeparator()) {
+ if (QMenu *menu = a->menu()) {
+ if (mdb->item(menu))
+ result.push_back(menu->objectName());
+ } else {
+ if (mdb->item(a))
+ result.push_back(a->objectName());
}
}
}
// Add managed buttons groups
- const ButtonGroupList buttonGroups = mainContainer->findChildren<QButtonGroup *>();
- if (!buttonGroups.empty()) {
- const ButtonGroupList::const_iterator cend = buttonGroups.constEnd();
- for (ButtonGroupList::const_iterator it = buttonGroups.constBegin(); it != cend; ++it)
- if (mdb->item(*it))
- result.append((*it)->objectName());
+ const auto buttonGroups = mainContainer->findChildren<QButtonGroup *>();
+ for (QButtonGroup * b : buttonGroups) {
+ if (mdb->item(b))
+ result.append(b->objectName());
}
result.sort();
diff --git a/src/designer/src/components/taskmenu/button_taskmenu.cpp b/src/designer/src/components/taskmenu/button_taskmenu.cpp
index 5791c6991..80e9d45c3 100644
--- a/src/designer/src/components/taskmenu/button_taskmenu.cpp
+++ b/src/designer/src/components/taskmenu/button_taskmenu.cpp
@@ -211,7 +211,7 @@ CreateButtonGroupCommand::CreateButtonGroupCommand(QDesignerFormWindowInterface
bool CreateButtonGroupCommand::init(const ButtonList &bl)
{
- if (bl.empty())
+ if (bl.isEmpty())
return false;
QDesignerFormWindowInterface *fw = formWindow();
QButtonGroup *buttonGroup = new QButtonGroup(fw->mainContainer());
@@ -286,9 +286,9 @@ RemoveButtonsFromGroupCommand::RemoveButtonsFromGroupCommand(QDesignerFormWindow
bool RemoveButtonsFromGroupCommand::init(const ButtonList &bl)
{
- if (bl.empty())
+ if (bl.isEmpty())
return false;
- QButtonGroup *group = bl.front()->group();
+ QButtonGroup *group = bl.constFirst()->group();
if (!group)
return false;
if (bl.size() >= group->buttons().size())
@@ -560,7 +560,7 @@ static ButtonList buttonList(const QDesignerFormWindowCursorInterface *cursor)
static QUndoCommand *createRemoveButtonsCommand(QDesignerFormWindowInterface *fw, const ButtonList &bl)
{
- QButtonGroup *bg = bl.front()->group();
+ QButtonGroup *bg = bl.constFirst()->group();
// Complete group or 1-member group?
if (bl.size() >= bg->buttons().size() - 1) {
BreakButtonGroupCommand *breakCmd = new BreakButtonGroupCommand(fw);
@@ -588,7 +588,7 @@ void ButtonTaskMenu::createGroup()
const ButtonList bl = buttonList(fw->cursor());
// Do we need to remove the buttons from an existing group?
QUndoCommand *removeCmd = nullptr;
- if (bl.front()->group()) {
+ if (bl.constFirst()->group()) {
removeCmd = createRemoveButtonsCommand(fw, bl);
if (!removeCmd)
return;
@@ -651,7 +651,7 @@ void ButtonTaskMenu::addToGroup(QAction *a)
const ButtonList bl = buttonList(fw->cursor());
// Do we need to remove the buttons from an existing group?
QUndoCommand *removeCmd = nullptr;
- if (bl.front()->group()) {
+ if (bl.constFirst()->group()) {
removeCmd = createRemoveButtonsCommand(fw, bl);
if (!removeCmd)
return;
diff --git a/src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp b/src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
index 1df9e4bbb..b4cd1cb2b 100644
--- a/src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
+++ b/src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
@@ -150,7 +150,7 @@ QList<QAction*> ContainerWidgetTaskMenu::taskActions() const
const QDesignerContainerExtension *ce = containerExtension();
const int index = ce->currentIndex();
- QList<QAction*> actions = QDesignerTaskMenu::taskActions();
+ auto actions = QDesignerTaskMenu::taskActions();
actions += m_taskActions;
// Update the page submenu, deletion and promotion. Updated on demand due to promotion state.
m_pageMenu->clear();
@@ -224,7 +224,7 @@ WizardContainerWidgetTaskMenu::WizardContainerWidgetTaskMenu(QWizard *w, QObject
{
connect(m_nextAction, &QAction::triggered, w, &QWizard::next);
connect(m_previousAction, &QAction::triggered, w, &QWizard::back);
- QList<QAction*> &l = containerActions();
+ auto &l = containerActions();
l.push_front(createSeparator());
l.push_front(m_nextAction);
l.push_front(m_previousAction);
@@ -260,7 +260,7 @@ void MdiContainerWidgetTaskMenu::initializeActions()
m_tileAction = new QAction(tr("Tile"), this);
m_cascadeAction = new QAction(tr("Cascade"), this);
- QList<QAction*> &l = containerActions();
+ auto &l = containerActions();
l.push_front(createSeparator());
l.push_front(m_tileAction);
l.push_front(m_cascadeAction);
@@ -271,7 +271,7 @@ void MdiContainerWidgetTaskMenu::initializeActions()
QList<QAction*> MdiContainerWidgetTaskMenu::taskActions() const
{
- const QList<QAction*> rc = ContainerWidgetTaskMenu::taskActions();
+ const auto rc = ContainerWidgetTaskMenu::taskActions();
// Enable
const int count = pageCount();
m_nextAction->setEnabled(count > 1);
diff --git a/src/designer/src/components/taskmenu/layouttaskmenu.cpp b/src/designer/src/components/taskmenu/layouttaskmenu.cpp
index 94c2095c4..b69051212 100644
--- a/src/designer/src/components/taskmenu/layouttaskmenu.cpp
+++ b/src/designer/src/components/taskmenu/layouttaskmenu.cpp
@@ -73,7 +73,7 @@ QAction *SpacerTaskMenu::preferredEditAction() const
QList<QAction*> SpacerTaskMenu::taskActions() const
{
- return QList<QAction*>();
+ return {};
}
QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/toolbar_taskmenu.cpp b/src/designer/src/components/taskmenu/toolbar_taskmenu.cpp
index 158917e24..42f3b271a 100644
--- a/src/designer/src/components/taskmenu/toolbar_taskmenu.cpp
+++ b/src/designer/src/components/taskmenu/toolbar_taskmenu.cpp
@@ -58,7 +58,7 @@ namespace qdesigner_internal {
{
if (ToolBarEventFilter *ef = ToolBarEventFilter::eventFilterOf(m_toolBar))
return ef->contextMenuActions();
- return QList<QAction*>();
+ return {};
}
// ------------ StatusBarTaskMenu
diff --git a/src/designer/src/components/widgetbox/widgetbox_dnditem.cpp b/src/designer/src/components/widgetbox/widgetbox_dnditem.cpp
index 30fbc2337..c44fa4169 100644
--- a/src/designer/src/components/widgetbox/widgetbox_dnditem.cpp
+++ b/src/designer/src/components/widgetbox/widgetbox_dnditem.cpp
@@ -174,7 +174,7 @@ static QWidget *decorationFromDomWidget(DomUI *dom_ui, QDesignerFormEditorInterf
QWidget *fakeTopLevel = builder.createUI(dom_ui, nullptr);
fakeTopLevel->setParent(nullptr, Qt::ToolTip); // Container
// Actual widget
- const DomWidget *domW = dom_ui->elementWidget()->elementWidget().front();
+ const DomWidget *domW = dom_ui->elementWidget()->elementWidget().constFirst();
QWidget *w = fakeTopLevel->findChildren<QWidget*>().constFirst();
Q_ASSERT(w);
// hack begin;
diff --git a/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp b/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
index 5b00ea68f..9863da25b 100644
--- a/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
+++ b/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
@@ -129,7 +129,7 @@ public:
bool removeCustomWidgets();
private:
- using WidgetBoxCategoryEntrys = QList<WidgetBoxCategoryEntry>;
+ using WidgetBoxCategoryEntrys = QVector<WidgetBoxCategoryEntry>;
QDesignerFormEditorInterface *m_core;
WidgetBoxCategoryEntrys m_items;
diff --git a/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp b/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
index dd17b3a4e..054d622a0 100644
--- a/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
+++ b/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
@@ -160,7 +160,7 @@ void WidgetBoxTreeWidget::restoreExpandedState()
const auto &closedCategoryList = settings->value(groupKey + QLatin1String(widgetBoxExpandedKeyC), QStringList()).toStringList();
const StringSet closedCategories(closedCategoryList.cbegin(), closedCategoryList.cend());
expandAll();
- if (closedCategories.empty())
+ if (closedCategories.isEmpty())
return;
if (const int numCategories = categoryCount()) {
@@ -366,7 +366,7 @@ bool WidgetBoxTreeWidget::readCategories(const QString &fileName, const QString
while (!reader.atEnd()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement: {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (tag == QLatin1String(widgetBoxRootElementC)) {
//<widgetbox version="4.5">
continue;
@@ -411,7 +411,7 @@ bool WidgetBoxTreeWidget::readCategories(const QString &fileName, const QString
break;
}
case QXmlStreamReader::EndElement: {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (tag == QLatin1String(widgetBoxRootElementC)) {
continue;
}
@@ -472,7 +472,7 @@ bool WidgetBoxTreeWidget::readWidget(Widget *w, const QString &xml, QXmlStreamRe
case QXmlStreamReader::StartElement:
if (nesting++ == 0) {
// First element must be <ui> or (legacy) <widget>
- const QStringRef name = r.name();
+ const auto name = r.name();
if (name == QLatin1String(uiElementC)) {
startTagPosition = currentPosition;
} else {
@@ -593,9 +593,8 @@ static int findCategory(const QString &name, const WidgetBoxTreeWidget::Category
static inline bool isValidIcon(const QIcon &icon)
{
if (!icon.isNull()) {
- const QList<QSize> availableSizes = icon.availableSizes();
- if (!availableSizes.empty())
- return !availableSizes.front().isEmpty();
+ const auto availableSizes = icon.availableSizes();
+ return !availableSizes.isEmpty() && !availableSizes.constFirst().isEmpty();
}
return false;
}
@@ -606,7 +605,7 @@ WidgetBoxTreeWidget::CategoryList WidgetBoxTreeWidget::loadCustomCategoryList()
const QDesignerPluginManager *pm = m_core->pluginManager();
const QDesignerPluginManager::CustomWidgetList customWidgets = pm->registeredCustomWidgets();
- if (customWidgets.empty())
+ if (customWidgets.isEmpty())
return result;
static const QString customCatName = tr("Custom Widgets");
diff --git a/src/designer/src/designer/appfontdialog.cpp b/src/designer/src/designer/appfontdialog.cpp
index b1a3942df..12dd80bed 100644
--- a/src/designer/src/designer/appfontdialog.cpp
+++ b/src/designer/src/designer/appfontdialog.cpp
@@ -82,7 +82,7 @@ public:
// Store loaded fonts as pair of file name and Id
using FileNameFontIdPair = QPair<QString,int>;
- using FileNameFontIdPairs = QList<FileNameFontIdPair>;
+ using FileNameFontIdPairs = QVector<FileNameFontIdPair>;
const FileNameFontIdPairs &fonts() const;
private:
@@ -122,7 +122,7 @@ void AppFontManager::restore(const QDesignerSettingsInterface *s, const QString
if (debugAppFontWidget)
qDebug() << "AppFontManager::restoring" << fontFiles.size() << "fonts from " << prefix;
- if (!fontFiles.empty()) {
+ if (!fontFiles.isEmpty()) {
QString errorMessage;
const QStringList::const_iterator cend = fontFiles.constEnd();
for (QStringList::const_iterator it = fontFiles.constBegin(); it != cend; ++it)
@@ -311,7 +311,7 @@ void AppFontWidget::addFiles()
const QStringList files =
QFileDialog::getOpenFileNames(this, tr("Add Font Files"), QString(),
tr("Font files (*.ttf)"));
- if (files.empty())
+ if (files.isEmpty())
return;
QString errorMessage;
@@ -331,7 +331,7 @@ void AppFontWidget::addFiles()
static void removeFonts(const QModelIndexList &selectedIndexes, AppFontModel *model, QWidget *dialogParent)
{
- if (selectedIndexes.empty())
+ if (selectedIndexes.isEmpty())
return;
// Reverse sort top level rows and remove
@@ -382,7 +382,7 @@ void AppFontWidget::slotRemoveAll()
void AppFontWidget::selectionChanged(const QItemSelection &selected, const QItemSelection & /*deselected*/)
{
- m_removeButton->setEnabled(!selected.indexes().empty());
+ m_removeButton->setEnabled(!selected.indexes().isEmpty());
}
void AppFontWidget::save(QDesignerSettingsInterface *s, const QString &prefix)
diff --git a/src/designer/src/designer/assistantclient.cpp b/src/designer/src/designer/assistantclient.cpp
index bf8026c3c..fb8bb5dde 100644
--- a/src/designer/src/designer/assistantclient.cpp
+++ b/src/designer/src/designer/assistantclient.cpp
@@ -85,7 +85,7 @@ bool AssistantClient::sendCommand(const QString &cmd, QString *errorMessage)
return false;
}
QTextStream str(m_process);
- str << cmd << QLatin1Char('\n') << endl;
+ str << cmd << QLatin1Char('\n') << Qt::endl;
return true;
}
diff --git a/src/designer/src/designer/doc/src/designer-manual.qdoc b/src/designer/src/designer/doc/src/designer-manual.qdoc
index 99f45ecdd..5c6fd208a 100644
--- a/src/designer/src/designer/doc/src/designer-manual.qdoc
+++ b/src/designer/src/designer/doc/src/designer-manual.qdoc
@@ -90,7 +90,6 @@
/*!
\page designer-to-know.html
- \contentspage {Qt Designer Manual}{Contents}
\title Getting to Know Qt Designer
@@ -258,7 +257,6 @@
/*!
\page designer-quick-start.html
- \contentspage {Qt Designer Manual}{Contents}
\title A Quick Start to Qt Designer
@@ -398,7 +396,6 @@
/*!
\page designer-editing-mode.html
\previouspage Getting to Know Qt Designer
- \contentspage {Qt Designer Manual}{Contents}
\nextpage Using Layouts in Qt Designer
\title Qt Designer's Editing Modes
@@ -447,7 +444,6 @@
/*!
\page designer-widget-mode.html
\previouspage Qt Designer's Editing Modes
- \contentspage {Qt Designer Manual}{Contents}
\nextpage Qt Designer's Signals and Slots Editing Mode
\title Qt Designer's Widget Editing Mode
@@ -687,7 +683,6 @@
/*!
\page designer-layouts.html
\previouspage Qt Designer's Widget Editing Mode
- \contentspage
\nextpage Qt Designer's Signals and Slots Editing Mode
\title Using Layouts in Qt Designer
@@ -890,7 +885,6 @@
/*!
\page designer-preview.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Using Layouts in Qt Designer
\nextpage Qt Designer's Buddy Editing Mode
\title Saving, Previewing and Printing Forms in Qt Designer
@@ -971,7 +965,6 @@
/*!
\page designer-connection-mode.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Using Layouts in Qt Designer
\nextpage Qt Designer's Buddy Editing Mode
@@ -1105,7 +1098,6 @@
/*!
\page designer-buddy-mode.html
- \contentspage{Qt Designer Manual}{Contents}
\previouspage Qt Designer's Signals and Slots Editing Mode
\nextpage Qt Designer's Tab Order Editing Mode
@@ -1159,7 +1151,6 @@
/*!
\page designer-tab-order.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Qt Designer's Buddy Editing Mode
\nextpage Using Containers in Qt Designer
@@ -1208,7 +1199,6 @@
/*!
\page designer-using-containers.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Qt Designer's Tab Order Editing Mode
\nextpage Creating Main Windows in Qt Designer
@@ -1346,7 +1336,6 @@
/*!
\page designer-creating-mainwindows.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Using Containers in Qt Designer
\nextpage Editing Resources with Qt Designer
@@ -1601,7 +1590,6 @@
/*!
\page designer-resources.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Creating Main Windows in Qt Designer
\nextpage Using Stylesheets with Qt Designer
@@ -1706,7 +1694,6 @@ pixmap property in the property editor.
/*!
\page designer-stylesheet.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Editing Resources with Qt Designer
\nextpage Using a Designer UI File in Your Application
@@ -1734,7 +1721,6 @@ pixmap property in the property editor.
/*!
\page designer-using-a-ui-file.html
\previouspage Using Stylesheets with Qt Designer
- \contentspage {Qt Designer Manual}{Contents}
\nextpage Using Custom Widgets with Qt Designer
\title Using a Designer UI File in Your Application
@@ -2128,7 +2114,6 @@ pixmap property in the property editor.
/*!
\page designer-customizing-forms.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Using Stylesheets with Qt Designer
\nextpage Using Custom Widgets with Qt Designer
@@ -2185,7 +2170,6 @@ pixmap property in the property editor.
/*!
\page designer-using-custom-widgets.html
- \contentspage {Qt Designer Manual}{Contents}
\previouspage Customizing Qt Designer Forms
\nextpage Creating Custom Widgets for Qt Designer
@@ -2281,7 +2265,6 @@ pixmap property in the property editor.
/*!
\page designer-creating-custom-widgets.html
\previouspage Using Custom Widgets with Qt Designer
- \contentspage {Qt Designer Manual}{Contents}
\nextpage Creating Custom Widget Extensions
\title Creating Custom Widgets for Qt Designer
@@ -2642,7 +2625,6 @@ pixmap property in the property editor.
\page designer-creating-custom-widgets-extensions.html
\previouspage Creating Custom Widgets for Qt Designer
\nextpage Qt Designer's UI File Format
- \contentspage {Qt Designer Manual}{Contents}
\title Creating Custom Widget Extensions
@@ -2812,7 +2794,6 @@ pixmap property in the property editor.
/*!
\page designer-ui-file-format.html
\previouspage Creating Custom Widget Extensions
- \contentspage {Qt Designer Manual}{Contents}
\title Qt Designer's UI File Format
diff --git a/src/designer/src/designer/mainwindow.cpp b/src/designer/src/designer/mainwindow.cpp
index 3a1ae3ce9..dba96fd86 100644
--- a/src/designer/src/designer/mainwindow.cpp
+++ b/src/designer/src/designer/mainwindow.cpp
@@ -150,12 +150,11 @@ QStringList DockedMdiArea::uiFiles(const QMimeData *d) const
QStringList rc;
if (!d->hasFormat(QLatin1String(uriListMimeFormatC)))
return rc;
- const QList<QUrl> urls = d->urls();
- if (urls.empty())
+ const auto urls = d->urls();
+ if (urls.isEmpty())
return rc;
- const QList<QUrl>::const_iterator cend = urls.constEnd();
- for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
- const QString fileName = it->toLocalFile();
+ for (const auto &url : urls) {
+ const QString fileName = url.toLocalFile();
if (!fileName.isEmpty() && fileName.endsWith(m_extension))
rc.push_back(fileName);
}
@@ -169,7 +168,7 @@ bool DockedMdiArea::event(QEvent *event)
switch (event->type()) {
case QEvent::DragEnter: {
QDragEnterEvent *e = static_cast<QDragEnterEvent*>(event);
- if (!uiFiles(e->mimeData()).empty()) {
+ if (!uiFiles(e->mimeData()).isEmpty()) {
e->acceptProposedAction();
return true;
}
@@ -338,7 +337,7 @@ QMdiSubWindow *DockedMainWindow::createMdiSubWindow(QWidget *fw, Qt::WindowFlags
// designer menu actions
if (designerCloseActionShortCut == QKeySequence(QKeySequence::Close)) {
const ActionList systemMenuActions = rc->systemMenu()->actions();
- if (!systemMenuActions.empty()) {
+ if (!systemMenuActions.isEmpty()) {
const ActionList::const_iterator cend = systemMenuActions.constEnd();
for (ActionList::const_iterator it = systemMenuActions.constBegin(); it != cend; ++it) {
if ( (*it)->shortcut() == designerCloseActionShortCut) {
diff --git a/src/designer/src/designer/newform.cpp b/src/designer/src/designer/newform.cpp
index 797e60149..35199927a 100644
--- a/src/designer/src/designer/newform.cpp
+++ b/src/designer/src/designer/newform.cpp
@@ -103,13 +103,10 @@ QDialogButtonBox *NewForm::createButtonBox()
QDesignerActions *da = m_workbench->actionManager();
QMenu *recentFilesMenu = new QMenu(tr("&Recent Forms"), m_recentButton);
// Pop the "Recent Files" stuff in here.
- const QList<QAction *> recentActions = da->recentFilesActions()->actions();
- if (!recentActions.empty()) {
- const QList<QAction *>::const_iterator acend = recentActions.constEnd();
- for (QList<QAction *>::const_iterator it = recentActions.constBegin(); it != acend; ++it) {
- recentFilesMenu->addAction(*it);
- connect(*it, &QAction::triggered, this, &NewForm::recentFileChosen);
- }
+ const auto recentActions = da->recentFilesActions()->actions();
+ for (auto action : recentActions) {
+ recentFilesMenu->addAction(action);
+ connect(action, &QAction::triggered, this, &NewForm::recentFileChosen);
}
m_recentButton->setMenu(recentFilesMenu);
connect(buttonBox, &QDialogButtonBox::clicked, this, &NewForm::slotButtonBoxClicked);
diff --git a/src/designer/src/designer/qdesigner.cpp b/src/designer/src/designer/qdesigner.cpp
index ff244ec29..4344b1c07 100644
--- a/src/designer/src/designer/qdesigner.cpp
+++ b/src/designer/src/designer/qdesigner.cpp
@@ -252,7 +252,7 @@ QDesigner::ParseArgumentsResult QDesigner::parseCommandLineArguments()
m_suppressNewFormShow = m_workbench->readInBackup();
- if (!options.files.empty()) {
+ if (!options.files.isEmpty()) {
const QStringList::const_iterator cend = options.files.constEnd();
for (QStringList::const_iterator it = options.files.constBegin(); it != cend; ++it) {
// Ensure absolute paths for recent file list to be unique
diff --git a/src/designer/src/designer/qdesigner_actions.cpp b/src/designer/src/designer/qdesigner_actions.cpp
index 71a02f759..ea296fc27 100644
--- a/src/designer/src/designer/qdesigner_actions.cpp
+++ b/src/designer/src/designer/qdesigner_actions.cpp
@@ -907,7 +907,7 @@ void QDesignerActions::updateRecentFileActions()
QStringList files = m_settings.recentFilesList();
const int originalSize = files.size();
int numRecentFiles = qMin(files.size(), int(MaxRecentFiles));
- const QList<QAction *> recentFilesActs = m_recentFilesActions->actions();
+ const auto recentFilesActs = m_recentFilesActions->actions();
for (int i = 0; i < numRecentFiles; ++i) {
const QFileInfo fi(files[i]);
diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.cpp b/src/designer/src/designer/qdesigner_appearanceoptions.cpp
index 66eb49c9f..fbcfacc6e 100644
--- a/src/designer/src/designer/qdesigner_appearanceoptions.cpp
+++ b/src/designer/src/designer/qdesigner_appearanceoptions.cpp
@@ -65,7 +65,7 @@ QDesignerAppearanceOptionsWidget::QDesignerAppearanceOptionsWidget(QWidget *pare
m_ui->m_uiModeCombo->addItem(tr("Docked Window"), QVariant(DockedMode));
m_ui->m_uiModeCombo->addItem(tr("Multiple Top-Level Windows"), QVariant(TopLevelMode));
- connect(m_ui->m_uiModeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(m_ui->m_uiModeCombo, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &QDesignerAppearanceOptionsWidget::slotUiModeComboChanged);
m_ui->m_fontPanel->setCheckable(true);
diff --git a/src/designer/src/designer/qdesigner_formwindow.cpp b/src/designer/src/designer/qdesigner_formwindow.cpp
index 77223e416..19c79e52d 100644
--- a/src/designer/src/designer/qdesigner_formwindow.cpp
+++ b/src/designer/src/designer/qdesigner_formwindow.cpp
@@ -173,7 +173,7 @@ int QDesignerFormWindow::getNumberOfUntitledWindows() const
if (maxUntitled == 0)
++maxUntitled;
if (match.lastCapturedIndex() >= 2) {
- const QStringRef numberCapture = match.capturedRef(2);
+ const auto numberCapture = match.capturedRef(2);
if (!numberCapture.isEmpty())
maxUntitled = qMax(numberCapture.toInt(), maxUntitled);
}
diff --git a/src/designer/src/designer/qdesigner_settings.cpp b/src/designer/src/designer/qdesigner_settings.cpp
index 8ac61c52a..e8ac4be54 100644
--- a/src/designer/src/designer/qdesigner_settings.cpp
+++ b/src/designer/src/designer/qdesigner_settings.cpp
@@ -40,7 +40,6 @@
#include <QtCore/qvariant.h>
#include <QtCore/qdir.h>
-#include <QtWidgets/qdesktopwidget.h>
#include <QtWidgets/qstyle.h>
#include <QtWidgets/qlistview.h>
diff --git a/src/designer/src/designer/qdesigner_workbench.cpp b/src/designer/src/designer/qdesigner_workbench.cpp
index f2a8b5d1c..d18d2a179 100644
--- a/src/designer/src/designer/qdesigner_workbench.cpp
+++ b/src/designer/src/designer/qdesigner_workbench.cpp
@@ -58,7 +58,6 @@
#include <QtWidgets/qactiongroup.h>
#include <QtGui/qevent.h>
#include <QtGui/qscreen.h>
-#include <QtWidgets/qdesktopwidget.h>
#include <QtWidgets/qdockwidget.h>
#include <QtWidgets/qmenu.h>
#include <QtWidgets/qmenubar.h>
@@ -236,7 +235,7 @@ QDesignerWorkbench::QDesignerWorkbench() :
{ // Add application specific options pages
QDesignerAppearanceOptionsPage *appearanceOptions = new QDesignerAppearanceOptionsPage(m_core);
connect(appearanceOptions, &QDesignerAppearanceOptionsPage::settingsChanged, this, &QDesignerWorkbench::notifyUISettingsChanged);
- QList<QDesignerOptionsPageInterface*> optionsPages = m_core->optionsPages();
+ auto optionsPages = m_core->optionsPages();
optionsPages.push_front(appearanceOptions);
m_core->setOptionsPages(optionsPages);
}
@@ -330,7 +329,7 @@ Qt::WindowFlags QDesignerWorkbench::magicalWindowFlags(const QWidget *widgetForF
return Qt::Window;
default:
Q_ASSERT(0);
- return nullptr;
+ return {};
}
}
@@ -569,9 +568,9 @@ QRect QDesignerWorkbench::desktopGeometry() const
case NeutralMode:
break;
}
- const int screenNumber = widget ? QApplication::desktop()->screenNumber(widget) : 0;
- auto screen = QGuiApplication::screens().value(screenNumber, QGuiApplication::primaryScreen());
- return screen->availableGeometry();
+ const auto screen = widget ? widget->screen() : QGuiApplication::primaryScreen();
+ return screen ? screen->availableGeometry()
+ : QGuiApplication::primaryScreen()->availableGeometry();
}
QRect QDesignerWorkbench::availableGeometry() const
@@ -579,9 +578,8 @@ QRect QDesignerWorkbench::availableGeometry() const
if (m_mode == DockedMode)
return m_dockedMainWindow->mdiArea()->geometry();
- const int screenNumber = QApplication::desktop()->screenNumber(widgetBoxToolWindow());
- auto screen = QGuiApplication::screens().value(screenNumber, QGuiApplication::primaryScreen());
- return screen->availableGeometry();
+ const auto screen = widgetBoxToolWindow()->screen();
+ return screen ? screen->availableGeometry() : QGuiApplication::primaryScreen()->availableGeometry() ;
}
int QDesignerWorkbench::marginHint() const
@@ -608,7 +606,7 @@ void QDesignerWorkbench::removeFormWindow(QDesignerFormWindow *formWindow)
m_windowMenu->removeAction(action);
}
- if (m_formWindows.empty()) {
+ if (m_formWindows.isEmpty()) {
m_actionManager->setWindowListSeparatorVisible(false);
// Show up new form dialog unless closing
if (loadOk && m_state == StateUp
@@ -689,7 +687,7 @@ QDesignerFormWindow *QDesignerWorkbench::findFormWindow(QWidget *widget) const
bool QDesignerWorkbench::handleClose()
{
m_state = StateClosing;
- QList<QDesignerFormWindow *> dirtyForms;
+ QVector<QDesignerFormWindow *> dirtyForms;
for (QDesignerFormWindow *w : qAsConst(m_formWindows)) {
if (w->editor()->isDirty())
dirtyForms << w;
@@ -1079,7 +1077,7 @@ void QDesignerWorkbench::restoreUISettings()
ToolWindowFontSettings fontSettings = QDesignerSettings(m_core).toolWindowFont();
const QFont &font = fontSettings.m_useFont ? fontSettings.m_font : qApp->font();
- if (font == m_toolWindows.front()->font())
+ if (font == m_toolWindows.constFirst()->font())
return;
for (QDesignerToolWindow *tw : qAsConst(m_toolWindows))
diff --git a/src/designer/src/lib/sdk/abstractdialoggui_p.h b/src/designer/src/lib/sdk/abstractdialoggui_p.h
index b9c1814fd..0d1734e12 100644
--- a/src/designer/src/lib/sdk/abstractdialoggui_p.h
+++ b/src/designer/src/lib/sdk/abstractdialoggui_p.h
@@ -78,11 +78,11 @@ public:
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) = 0;
virtual QString getExistingDirectory(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly)= 0;
- virtual QString getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr)= 0;
- virtual QString getOpenImageFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr);
- virtual QStringList getOpenFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr)= 0;
- virtual QStringList getOpenImageFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr);
- virtual QString getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr)= 0;
+ virtual QString getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {})= 0;
+ virtual QString getOpenImageFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {});
+ virtual QStringList getOpenFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {})= 0;
+ virtual QStringList getOpenImageFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {});
+ virtual QString getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {})= 0;
};
QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/actioneditor.cpp b/src/designer/src/lib/shared/actioneditor.cpp
index 86cbb4959..2aeea2a74 100644
--- a/src/designer/src/lib/shared/actioneditor.cpp
+++ b/src/designer/src/lib/shared/actioneditor.cpp
@@ -325,7 +325,7 @@ void ActionEditor::setFormWindow(QDesignerFormWindowInterface *formWindow)
void ActionEditor::slotSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/)
{
- const bool hasSelection = !selected.indexes().empty();
+ const bool hasSelection = !selected.indexes().isEmpty();
#if QT_CONFIG(clipboard)
m_actionCopy->setEnabled(hasSelection);
m_actionCut->setEnabled(hasSelection);
@@ -349,7 +349,7 @@ void ActionEditor::slotCurrentItemChanged(QAction *action)
QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector());
- if (action->associatedWidgets().empty()) {
+ if (action->associatedWidgets().isEmpty()) {
// Special case: action not in object tree. Deselect all and set in property editor
fw->clearSelection(false);
if (oi)
@@ -528,7 +528,7 @@ static inline QString textPropertyValue(const QDesignerPropertySheetExtension *s
return ps.value();
}
-void ActionEditor::editAction(QAction *action)
+void ActionEditor::editAction(QAction *action, int column)
{
if (!action)
return;
@@ -546,6 +546,24 @@ void ActionEditor::editAction(QAction *action)
oldActionData.checkable = action->isCheckable();
dlg.setActionData(oldActionData);
+ switch (column) {
+ case qdesigner_internal::ActionModel::NameColumn:
+ dlg.focusName();
+ break;
+ case qdesigner_internal::ActionModel::TextColumn:
+ dlg.focusText();
+ break;
+ case qdesigner_internal::ActionModel::ShortCutColumn:
+ dlg.focusShortcut();
+ break;
+ case qdesigner_internal::ActionModel::CheckedColumn:
+ dlg.focusCheckable();
+ break;
+ case qdesigner_internal::ActionModel::ToolTipColumn:
+ dlg.focusTooltip();
+ break;
+ }
+
if (!dlg.exec())
return;
@@ -602,8 +620,9 @@ void ActionEditor::deleteActions(QDesignerFormWindowInterface *fw, const ActionL
{
// We need a macro even in the case of single action because the commands might cause the
// scheduling of other commands (signal slots connections)
- const QString description = actions.size() == 1 ?
- tr("Remove action '%1'").arg(actions.front()->objectName()) : tr("Remove actions");
+ const QString description = actions.size() == 1
+ ? tr("Remove action '%1'").arg(actions.constFirst()->objectName())
+ : tr("Remove actions");
fw->beginCommand(description);
for (QAction *action : actions) {
RemoveActionCommand *cmd = new RemoveActionCommand(fw);
@@ -644,7 +663,7 @@ void ActionEditor::slotDelete()
return;
const ActionView::ActionList selection = m_actionView->selectedActions();
- if (selection.empty())
+ if (selection.isEmpty())
return;
deleteActions(fw, selection);
@@ -784,7 +803,7 @@ void ActionEditor::slotCopy()
return;
const ActionView::ActionList selection = m_actionView->selectedActions();
- if (selection.empty())
+ if (selection.isEmpty())
return;
copyActions(fw, selection);
@@ -797,7 +816,7 @@ void ActionEditor::slotCut()
return;
const ActionView::ActionList selection = m_actionView->selectedActions();
- if (selection.empty())
+ if (selection.isEmpty())
return;
copyActions(fw, selection);
@@ -826,7 +845,7 @@ void ActionEditor::slotContextMenuRequested(QContextMenuEvent *e, QAction *item)
// Associated Widgets
if (QAction *action = m_actionView->currentAction()) {
const QWidgetList associatedWidgets = ActionModel::associatedWidgets(action);
- if (!associatedWidgets.empty()) {
+ if (!associatedWidgets.isEmpty()) {
QMenu *associatedWidgetsSubMenu = menu.addMenu(tr("Used In"));
for (QWidget *w : associatedWidgets) {
associatedWidgetsSubMenu->addAction(w->objectName(),
diff --git a/src/designer/src/lib/shared/actioneditor_p.h b/src/designer/src/lib/shared/actioneditor_p.h
index 321dbfb32..2f78887ba 100644
--- a/src/designer/src/lib/shared/actioneditor_p.h
+++ b/src/designer/src/lib/shared/actioneditor_p.h
@@ -100,7 +100,7 @@ public slots:
private slots:
void slotCurrentItemChanged(QAction *item);
void slotSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
- void editAction(QAction *item);
+ void editAction(QAction *item, int column = -1);
void editCurrentAction();
void navigateToSlotCurrentAction();
void slotActionChanged();
@@ -117,7 +117,7 @@ private slots:
#endif
signals:
- void itemActivated(QAction *item);
+ void itemActivated(QAction *item, int column);
// Context menu for item or global menu if item == 0.
void contextMenuRequested(QMenu *menu, QAction *item);
diff --git a/src/designer/src/lib/shared/actionprovider_p.h b/src/designer/src/lib/shared/actionprovider_p.h
index 085162a8e..63d902951 100644
--- a/src/designer/src/lib/shared/actionprovider_p.h
+++ b/src/designer/src/lib/shared/actionprovider_p.h
@@ -66,7 +66,7 @@ public:
template <class Widget>
int actionIndexAt(const Widget *w, const QPoint &pos, Qt::Orientation orientation)
{
- const QList<QAction*> actions = w->actions();
+ const auto actions = w->actions();
const int actionCount = actions.count();
if (actionCount == 0)
return -1;
diff --git a/src/designer/src/lib/shared/actionrepository.cpp b/src/designer/src/lib/shared/actionrepository.cpp
index 2d91a5f00..6162d02e2 100644
--- a/src/designer/src/lib/shared/actionrepository.cpp
+++ b/src/designer/src/lib/shared/actionrepository.cpp
@@ -107,7 +107,7 @@ void ActionModel::update(int row)
for (int i = 0; i < NumColumns; i++)
list += item(row, i);
- setItems(m_core, actionOfItem(list.front()), m_emptyIcon, list);
+ setItems(m_core, actionOfItem(list.constFirst()), m_emptyIcon, list);
}
void ActionModel::remove(int row)
@@ -132,7 +132,7 @@ QModelIndex ActionModel::addAction(QAction *action)
}
setItems(m_core, action, m_emptyIcon, items);
appendRow(items);
- return indexFromItem(items.front());
+ return indexFromItem(items.constFirst());
}
// Find the associated menus and toolbars, ignore toolbuttons
@@ -190,7 +190,7 @@ void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action,
item->setWhatsThis(firstTooltip);
// Used
const QWidgetList associatedDesignerWidgets = associatedWidgets(action);
- const bool used = !associatedDesignerWidgets.empty();
+ const bool used = !associatedDesignerWidgets.isEmpty();
item = sl[UsedColumn];
item->setCheckState(used ? Qt::Checked : Qt::Unchecked);
if (used) {
@@ -308,14 +308,14 @@ static void handleImageDropEvent(const QAbstractItemView *iv, QDropEvent *event,
void startActionDrag(QWidget *dragParent, ActionModel *model, const QModelIndexList &indexes, Qt::DropActions supportedActions)
{
- if (indexes.empty())
+ if (indexes.isEmpty())
return;
QDrag *drag = new QDrag(dragParent);
QMimeData *data = model->mimeData(indexes);
drag->setMimeData(data);
if (ActionRepositoryMimeData *actionMimeData = qobject_cast<ActionRepositoryMimeData *>(data))
- drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(actionMimeData->actionList().front()));
+ drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(actionMimeData->actionList().constFirst()));
drag->exec(supportedActions);
}
@@ -392,7 +392,7 @@ void ActionTreeView::currentChanged(const QModelIndex &current, const QModelInde
void ActionTreeView::slotActivated(const QModelIndex &index)
{
- emit actionActivated(m_model->actionAt(index));
+ emit actionActivated(m_model->actionAt(index), index.column());
}
void ActionTreeView::startDrag(Qt::DropActions supportedActions)
@@ -499,7 +499,8 @@ ActionView::ActionView(QWidget *parent) :
// make it possible for vs integration to reimplement edit action dialog
// [which it shouldn't do actually]
- connect(m_actionListView, &ActionListView::actionActivated, this, &ActionView::activated);
+ connect(m_actionListView, &ActionListView::actionActivated,
+ this, [this](QAction *a) { this->activated(a, -1); });
connect(m_actionTreeView, &ActionTreeView::actionActivated, this, &ActionView::activated);
connect(m_actionListView, &ActionListView::currentActionChanged,
diff --git a/src/designer/src/lib/shared/actionrepository_p.h b/src/designer/src/lib/shared/actionrepository_p.h
index a68b3371f..333093a09 100644
--- a/src/designer/src/lib/shared/actionrepository_p.h
+++ b/src/designer/src/lib/shared/actionrepository_p.h
@@ -124,7 +124,7 @@ public slots:
signals:
void actionContextMenuRequested(QContextMenuEvent *event, QAction *);
void currentActionChanged(QAction *action);
- void actionActivated(QAction *action);
+ void actionActivated(QAction *action, int column);
protected slots:
void currentChanged(const QModelIndex &current, const QModelIndex &previous) override;
@@ -215,7 +215,7 @@ public slots:
signals:
void contextMenuRequested(QContextMenuEvent *event, QAction *);
void currentChanged(QAction *action);
- void activated(QAction *action);
+ void activated(QAction *action, int column);
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
void resourceImageDropped(const QString &data, QAction *action);
diff --git a/src/designer/src/lib/shared/connectionedit.cpp b/src/designer/src/lib/shared/connectionedit.cpp
index a55465440..5e43607d4 100644
--- a/src/designer/src/lib/shared/connectionedit.cpp
+++ b/src/designer/src/lib/shared/connectionedit.cpp
@@ -35,7 +35,7 @@
#include <QtGui/qevent.h>
#include <QtGui/qfontmetrics.h>
#include <QtGui/qpixmap.h>
-#include <QtGui/qmatrix.h>
+#include <QtGui/qtransform.h>
#include <QtWidgets/qapplication.h>
#include <QtWidgets/qmenu.h>
#include <QtWidgets/qaction.h>
@@ -881,7 +881,7 @@ void Connection::updatePixmap(EndPoint::Type type)
const LineDir dir = labelDir(type);
if (dir == DownDir)
- *pm = pm->transformed(QMatrix(0.0, -1.0, 1.0, 0.0, 0.0, 0.0));
+ *pm = pm->transformed(QTransform(0.0, -1.0, 1.0, 0.0, 0.0, 0.0));
}
void Connection::checkWidgets()
@@ -1371,7 +1371,7 @@ static ConnectionEdit::ConnectionSet findConnectionsOf(const ConnectionEdit::Con
void ConnectionEdit::widgetRemoved(QWidget *widget)
{
// Remove all connections of that widget and its children.
- if (m_con_list.empty())
+ if (m_con_list.isEmpty())
return;
QWidgetList child_list = widget->findChildren<QWidget*>();
@@ -1379,8 +1379,10 @@ void ConnectionEdit::widgetRemoved(QWidget *widget)
const ConnectionSet remove_set = findConnectionsOf(m_con_list, child_list.constBegin(), child_list.constEnd());
- if (!remove_set.isEmpty())
- m_undo_stack->push(new DeleteConnectionsCommand(this, remove_set.keys()));
+ if (!remove_set.isEmpty()) {
+ auto cmd = new DeleteConnectionsCommand(this, ConnectionList(remove_set.cbegin(), remove_set.cend()));
+ m_undo_stack->push(cmd);
+ }
updateBackground();
}
@@ -1388,14 +1390,16 @@ void ConnectionEdit::widgetRemoved(QWidget *widget)
void ConnectionEdit::objectRemoved(QObject *o)
{
// Remove all connections of that object and its children (in case of action groups).
- if (m_con_list.empty())
+ if (m_con_list.isEmpty())
return;
QObjectList child_list = o->children();
child_list.prepend(o);
const ConnectionSet remove_set = findConnectionsOf(m_con_list, child_list.constBegin(), child_list.constEnd());
- if (!remove_set.isEmpty())
- m_undo_stack->push(new DeleteConnectionsCommand(this, remove_set.keys()));
+ if (!remove_set.isEmpty()) {
+ auto cmd = new DeleteConnectionsCommand(this, ConnectionList(remove_set.cbegin(), remove_set.cend()));
+ m_undo_stack->push(cmd);
+ }
updateBackground();
}
@@ -1500,7 +1504,8 @@ void ConnectionEdit::deleteSelected()
{
if (m_sel_con_set.isEmpty())
return;
- m_undo_stack->push(new DeleteConnectionsCommand(this, m_sel_con_set.keys()));
+ auto cmd = new DeleteConnectionsCommand(this, ConnectionList(m_sel_con_set.cbegin(), m_sel_con_set.cend()));
+ m_undo_stack->push(cmd);
}
void ConnectionEdit::addConnection(Connection *con)
diff --git a/src/designer/src/lib/shared/connectionedit_p.h b/src/designer/src/lib/shared/connectionedit_p.h
index 6fd623457..51ad450f8 100644
--- a/src/designer/src/lib/shared/connectionedit_p.h
+++ b/src/designer/src/lib/shared/connectionedit_p.h
@@ -45,6 +45,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
#include <QtCore/qpointer.h>
#include <QtWidgets/qwidget.h>
@@ -67,7 +68,7 @@ class ConnectionEdit;
class QDESIGNER_SHARED_EXPORT CETypes
{
public:
- using ConnectionList = QList<Connection *>;
+ using ConnectionList = QVector<Connection *>;
using ConnectionSet = QHash<Connection*, Connection*> ;
using WidgetSet = QHash<QWidget*, QWidget*>;
@@ -132,7 +133,7 @@ public:
private:
QPoint m_source_pos, m_target_pos;
QObject *m_source, *m_target;
- QList<QPoint> m_knee_list;
+ QVector<QPoint> m_knee_list;
QPolygonF m_arrow_head;
ConnectionEdit *m_edit;
QString m_source_label, m_target_label;
diff --git a/src/designer/src/lib/shared/dialoggui.cpp b/src/designer/src/lib/shared/dialoggui.cpp
index 8c537ab34..613a42143 100644
--- a/src/designer/src/lib/shared/dialoggui.cpp
+++ b/src/designer/src/lib/shared/dialoggui.cpp
@@ -211,13 +211,13 @@ QString DialogGui::getOpenImageFileName(QWidget *parent, const QString &caption,
return QString();
const QStringList selectedFiles = fileDialog.selectedFiles();
- if (selectedFiles.empty())
+ if (selectedFiles.isEmpty())
return QString();
if (selectedFilter)
*selectedFilter = fileDialog.selectedNameFilter();
- return selectedFiles.front();
+ return selectedFiles.constFirst();
#else
return getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
#endif
@@ -232,7 +232,7 @@ QStringList DialogGui::getOpenImageFileNames(QWidget *parent, const QString &cap
return QStringList();
const QStringList selectedFiles = fileDialog.selectedFiles();
- if (!selectedFiles.empty() && selectedFilter)
+ if (!selectedFiles.isEmpty() && selectedFilter)
*selectedFilter = fileDialog.selectedNameFilter();
return selectedFiles;
diff --git a/src/designer/src/lib/shared/dialoggui_p.h b/src/designer/src/lib/shared/dialoggui_p.h
index 0dde0b34e..4b5f2829f 100644
--- a/src/designer/src/lib/shared/dialoggui_p.h
+++ b/src/designer/src/lib/shared/dialoggui_p.h
@@ -73,12 +73,12 @@ public:
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) override;
QString getExistingDirectory(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly) override;
- QString getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr) override;
- QStringList getOpenFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr) override;
- QString getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr) override;
+ QString getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {}) override;
+ QStringList getOpenFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {}) override;
+ QString getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {}) override;
- QString getOpenImageFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr) override;
- QStringList getOpenImageFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = nullptr) override;
+ QString getOpenImageFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {}) override;
+ QStringList getOpenImageFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = {}) override;
private:
QFileIconProvider *ensureIconProvider();
diff --git a/src/designer/src/lib/shared/formlayoutmenu.cpp b/src/designer/src/lib/shared/formlayoutmenu.cpp
index 8d4bab6c7..58631b5db 100644
--- a/src/designer/src/lib/shared/formlayoutmenu.cpp
+++ b/src/designer/src/lib/shared/formlayoutmenu.cpp
@@ -154,7 +154,7 @@ FormLayoutRowDialog::FormLayoutRowDialog(QDesignerFormEditorInterface *core,
m_ui.fieldClassComboBox->addItems(fieldWidgetClasses(core));
m_ui.fieldClassComboBox->setCurrentIndex(0);
connect(m_ui.fieldClassComboBox,
- QOverload<int>::of(&QComboBox::currentIndexChanged),
+ QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &FormLayoutRowDialog::fieldClassChanged);
updateOkButton();
@@ -476,7 +476,7 @@ void FormLayoutMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, Acti
{
switch (LayoutInfo::managedLayoutType(fw->core(), w)) {
case LayoutInfo::Form:
- if (!actions.empty() && !actions.back()->isSeparator())
+ if (!actions.isEmpty() && !actions.constLast()->isSeparator())
actions.push_back(m_separator1);
actions.push_back(m_populateFormAction);
actions.push_back(m_separator2);
diff --git a/src/designer/src/lib/shared/formwindowbase.cpp b/src/designer/src/lib/shared/formwindowbase.cpp
index 8c35ea700..6814cd04f 100644
--- a/src/designer/src/lib/shared/formwindowbase.cpp
+++ b/src/designer/src/lib/shared/formwindowbase.cpp
@@ -446,7 +446,7 @@ void FormWindowBase::deleteWidgetList(const QWidgetList &widget_list)
// the signal slot editor are connected to widgetRemoved() and add their
// own commands (for example, to delete w's connections)
const QString description = widget_list.size() == 1 ?
- tr("Delete '%1'").arg(widget_list.front()->objectName()) : tr("Delete");
+ tr("Delete '%1'").arg(widget_list.constFirst()->objectName()) : tr("Delete");
commandHistory()->beginMacro(description);
for (QWidget *w : qAsConst(widget_list)) {
@@ -467,16 +467,16 @@ QMenu *FormWindowBase::createExtensionTaskMenu(QDesignerFormWindowInterface *fw,
if (const QDesignerTaskMenuExtension *extTaskMenu = qt_extension<QDesignerTaskMenuExtension*>(em, o))
actions += extTaskMenu->taskActions();
if (const QDesignerTaskMenuExtension *intTaskMenu = qobject_cast<QDesignerTaskMenuExtension *>(em->extension(o, QStringLiteral("QDesignerInternalTaskMenuExtension")))) {
- if (!actions.empty()) {
+ if (!actions.isEmpty()) {
QAction *a = new QAction(fw);
a->setSeparator(true);
actions.push_back(a);
}
actions += intTaskMenu->taskActions();
}
- if (actions.empty())
+ if (actions.isEmpty())
return nullptr;
- if (trailingSeparator && !actions.back()->isSeparator()) {
+ if (trailingSeparator && !actions.constLast()->isSeparator()) {
QAction *a = new QAction(fw);
a->setSeparator(true);
actions.push_back(a);
diff --git a/src/designer/src/lib/shared/iconselector.cpp b/src/designer/src/lib/shared/iconselector.cpp
index d9d50e782..ccfdc5c18 100644
--- a/src/designer/src/lib/shared/iconselector.cpp
+++ b/src/designer/src/lib/shared/iconselector.cpp
@@ -55,6 +55,7 @@
#include <QtWidgets/qlabel.h>
#include <QtGui/qvalidator.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -189,7 +190,7 @@ public:
void slotResetAllActivated();
void slotUpdate();
- QList<QPair<QPair<QIcon::Mode, QIcon::State>, QString> > m_stateToName; // could be static map
+ QVector<QPair<QPair<QIcon::Mode, QIcon::State>, QString> > m_stateToName; // could be static map
QMap<QPair<QIcon::Mode, QIcon::State>, int> m_stateToIndex;
QMap<int, QPair<QIcon::Mode, QIcon::State> > m_indexToState;
@@ -329,7 +330,7 @@ bool IconSelector::checkPixmap(const QString &fileName, CheckMode cm, QString *e
static QString imageFilter()
{
QString filter = QApplication::translate("IconSelector", "All Pixmaps (");
- const QList<QByteArray> supportedImageFormats = QImageReader::supportedImageFormats();
+ const auto supportedImageFormats = QImageReader::supportedImageFormats();
const QString jpeg = QStringLiteral("JPEG");
const int count = supportedImageFormats.count();
for (int i = 0; i< count; ++i) {
@@ -590,8 +591,7 @@ void IconThemeEditor::updatePreview(const QString &t)
{
// Update preview label with icon.
if (t.isEmpty() || !QIcon::hasThemeIcon(t)) { // Empty
- const QPixmap *currentPixmap = d->m_themeLabel->pixmap();
- if (currentPixmap == nullptr || currentPixmap->cacheKey() != d->m_emptyPixmap.cacheKey())
+ if (d->m_themeLabel->pixmap(Qt::ReturnByValue).cacheKey() != d->m_emptyPixmap.cacheKey())
d->m_themeLabel->setPixmap(d->m_emptyPixmap);
} else {
const QIcon icon = QIcon::fromTheme(t);
diff --git a/src/designer/src/lib/shared/layout.cpp b/src/designer/src/lib/shared/layout.cpp
index 436d5223b..d5414dbf1 100644
--- a/src/designer/src/lib/shared/layout.cpp
+++ b/src/designer/src/lib/shared/layout.cpp
@@ -392,7 +392,7 @@ void Layout::breakLayout()
for (auto it = rects.cbegin(), end = rects.cend(); it != end; ++it) {
QWidget *w = it.key();
if (needReparent) {
- w->setParent(m_layoutBase->parentWidget(), nullptr);
+ w->setParent(m_layoutBase->parentWidget(), {});
w->move(m_layoutBasePos + it.value().topLeft());
w->show();
}
@@ -456,7 +456,7 @@ QLayout *Layout::createLayout(int type)
void Layout::reparentToLayoutBase(QWidget *w)
{
if (w->parent() != m_layoutBase) {
- w->setParent(m_layoutBase, nullptr);
+ w->setParent(m_layoutBase, {});
w->move(QPoint(0,0));
}
}
@@ -1104,7 +1104,7 @@ void GridLayout<GridLikeLayout, LayoutType, GridMode>::doLayout()
if (needReparent)
reparentToLayoutBase(w);
- Qt::Alignment alignment = Qt::Alignment(nullptr);
+ Qt::Alignment alignment;
if (const Spacer *spacer = qobject_cast<const Spacer*>(w))
alignment = spacer->alignment();
@@ -1143,7 +1143,7 @@ inline QRect expandGeometry(const QRect &rect)
template <class GridLikeLayout, int LayoutType, int GridMode>
QWidgetList GridLayout<GridLikeLayout, LayoutType, GridMode>::buildGrid(const QWidgetList &widgetList)
{
- if (widgetList.empty())
+ if (widgetList.isEmpty())
return QWidgetList();
// Pixel to cell conversion:
diff --git a/src/designer/src/lib/shared/layoutinfo.cpp b/src/designer/src/lib/shared/layoutinfo.cpp
index 30cfabfda..73651a36c 100644
--- a/src/designer/src/lib/shared/layoutinfo.cpp
+++ b/src/designer/src/lib/shared/layoutinfo.cpp
@@ -65,7 +65,7 @@ LayoutInfo::Type LayoutInfo::layoutType(const QDesignerFormEditorInterface *core
static const QHash<QString, LayoutInfo::Type> &layoutNameTypeMap()
{
static QHash<QString, LayoutInfo::Type> nameTypeMap;
- if (nameTypeMap.empty()) {
+ if (nameTypeMap.isEmpty()) {
nameTypeMap.insert(QStringLiteral("QVBoxLayout"), LayoutInfo::VBox);
nameTypeMap.insert(QStringLiteral("QHBoxLayout"), LayoutInfo::HBox);
nameTypeMap.insert(QStringLiteral("QGridLayout"), LayoutInfo::Grid);
@@ -177,12 +177,10 @@ LayoutInfo::Type LayoutInfo::laidoutWidgetType(const QDesignerFormEditorInterfac
}
// 3) Some child layout (see below comment about Q3GroupBox)
- const QList<QLayout*> childLayouts = parentLayout->findChildren<QLayout*>();
- if (childLayouts.empty())
+ const auto childLayouts = parentLayout->findChildren<QLayout*>();
+ if (childLayouts.isEmpty())
return NoLayout;
- const QList<QLayout*>::const_iterator lcend = childLayouts.constEnd();
- for (QList<QLayout*>::const_iterator it = childLayouts.constBegin(); it != lcend; ++it) {
- QLayout *layout = *it;
+ for (QLayout *layout : childLayouts) {
if (layout->indexOf(widget) != -1) {
if (isManaged)
*isManaged = core->metaDataBase()->item(layout);
diff --git a/src/designer/src/lib/shared/morphmenu.cpp b/src/designer/src/lib/shared/morphmenu.cpp
index ee09dfafd..f92d9600b 100644
--- a/src/designer/src/lib/shared/morphmenu.cpp
+++ b/src/designer/src/lib/shared/morphmenu.cpp
@@ -226,14 +226,10 @@ static QString suggestObjectName(const QString &oldClassName, const QString &new
// Find the label whose buddy the widget is.
QLabel *buddyLabelOf(QDesignerFormWindowInterface *fw, QWidget *w)
{
- using LabelList = QList<QLabel *>;
- const LabelList labelList = fw->findChildren<QLabel*>();
- if (labelList.empty())
- return nullptr;
- const LabelList::const_iterator cend = labelList.constEnd();
- for (LabelList::const_iterator it = labelList.constBegin(); it != cend; ++it )
- if ( (*it)->buddy() == w)
- return *it;
+ const auto labelList = fw->findChildren<QLabel*>();
+ for (QLabel *label : labelList)
+ if (label->buddy() == w)
+ return label;
return nullptr;
}
@@ -586,7 +582,7 @@ bool MorphMenu::populateMenu(QWidget *w, QDesignerFormWindowInterface *fw)
return false;
const QStringList c = MorphWidgetCommand::candidateClasses(fw, w);
- if (c.empty())
+ if (c.isEmpty())
return false;
// Pull up
diff --git a/src/designer/src/lib/shared/newactiondialog.cpp b/src/designer/src/lib/shared/newactiondialog.cpp
index 676d4a80a..d5380bfcb 100644
--- a/src/designer/src/lib/shared/newactiondialog.cpp
+++ b/src/designer/src/lib/shared/newactiondialog.cpp
@@ -78,7 +78,7 @@ NewActionDialog::NewActionDialog(ActionEditor *parent) :
this, &NewActionDialog::slotResetKeySequence);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- m_ui->editActionText->setFocus();
+ focusText();
updateButtons();
QDesignerFormWindowInterface *form = parent->formWindow();
@@ -96,6 +96,31 @@ NewActionDialog::~NewActionDialog()
delete m_ui;
}
+void NewActionDialog::focusName()
+{
+ m_ui->editObjectName->setFocus();
+}
+
+void NewActionDialog::focusText()
+{
+ m_ui->editActionText->setFocus();
+}
+
+void NewActionDialog::focusTooltip()
+{
+ m_ui->tooltipEditor->setFocus();
+}
+
+void NewActionDialog::focusShortcut()
+{
+ m_ui->keySequenceEdit->setFocus();
+}
+
+void NewActionDialog::focusCheckable()
+{
+ m_ui->checkableCheckBox->setFocus();
+}
+
QString NewActionDialog::actionText() const
{
return m_ui->editActionText->text();
diff --git a/src/designer/src/lib/shared/newactiondialog_p.h b/src/designer/src/lib/shared/newactiondialog_p.h
index 8eddcbe72..f6e3b1dd7 100644
--- a/src/designer/src/lib/shared/newactiondialog_p.h
+++ b/src/designer/src/lib/shared/newactiondialog_p.h
@@ -89,6 +89,13 @@ public:
QString actionText() const;
QString actionName() const;
+public slots:
+ void focusName();
+ void focusText();
+ void focusTooltip();
+ void focusShortcut();
+ void focusCheckable();
+
private slots:
void on_editActionText_textEdited(const QString &text);
void on_editObjectName_textEdited(const QString &text);
diff --git a/src/designer/src/lib/shared/newformwidget.cpp b/src/designer/src/lib/shared/newformwidget.cpp
index b3853ae21..67e08c475 100644
--- a/src/designer/src/lib/shared/newformwidget.cpp
+++ b/src/designer/src/lib/shared/newformwidget.cpp
@@ -129,8 +129,6 @@ NewFormWidget::NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parent
m_currentItem(nullptr),
m_acceptedItem(nullptr)
{
- using DeviceProfileList = QList<qdesigner_internal::DeviceProfile>;
-
m_ui->setupUi(this);
m_ui->treeWidget->setItemDelegate(new qdesigner_internal::SheetDelegate(m_ui->treeWidget, this));
m_ui->treeWidget->header()->hide();
@@ -181,14 +179,13 @@ NewFormWidget::NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parent
m_deviceProfiles = settings.deviceProfiles();
m_ui->profileComboBox->addItem(tr("None"));
connect(m_ui->profileComboBox,
- QOverload<int>::of(&QComboBox::currentIndexChanged),
+ QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &NewFormWidget::slotDeviceProfileIndexChanged);
- if (m_deviceProfiles.empty()) {
+ if (m_deviceProfiles.isEmpty()) {
m_ui->profileComboBox->setEnabled(false);
} else {
- const DeviceProfileList::const_iterator dcend = m_deviceProfiles.constEnd();
- for (DeviceProfileList::const_iterator it = m_deviceProfiles.constBegin(); it != dcend; ++it)
- m_ui->profileComboBox->addItem(it->name());
+ for (const auto &deviceProfile : qAsConst(m_deviceProfiles))
+ m_ui->profileComboBox->addItem(deviceProfile.name());
const int ci = settings.currentDeviceProfileIndex();
if (ci >= 0)
m_ui->profileComboBox->setCurrentIndex(ci + profileComboIndexOffset);
@@ -446,7 +443,7 @@ void NewFormWidget::loadFrom(const QString &path, bool resourceFile, const QStri
void NewFormWidget::loadFrom(const QString &title, const QStringList &nameList,
const QString &selectedItem, QTreeWidgetItem *&selectedItemFound)
{
- if (nameList.empty())
+ if (nameList.isEmpty())
return;
QTreeWidgetItem *root = new QTreeWidgetItem(m_ui->treeWidget);
root->setFlags(root->flags() & ~Qt::ItemIsSelectable);
diff --git a/src/designer/src/lib/shared/newformwidget_p.h b/src/designer/src/lib/shared/newformwidget_p.h
index f6daae122..b428d5bc6 100644
--- a/src/designer/src/lib/shared/newformwidget_p.h
+++ b/src/designer/src/lib/shared/newformwidget_p.h
@@ -51,6 +51,7 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qpair.h>
#include <QtCore/qmap.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -69,7 +70,7 @@ class QDESIGNER_SHARED_EXPORT NewFormWidget : public QDesignerNewFormWidgetInter
Q_DISABLE_COPY_MOVE(NewFormWidget)
public:
- using DeviceProfileList = QList<qdesigner_internal::DeviceProfile>;
+ using DeviceProfileList = QVector<qdesigner_internal::DeviceProfile>;
explicit NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parentWidget);
~NewFormWidget() override;
diff --git a/src/designer/src/lib/shared/plugindialog.cpp b/src/designer/src/lib/shared/plugindialog.cpp
index 8f73099e7..86f90f963 100644
--- a/src/designer/src/lib/shared/plugindialog.cpp
+++ b/src/designer/src/lib/shared/plugindialog.cpp
@@ -101,7 +101,7 @@ void PluginDialog::populateTreeWidget()
if (QObject *plugin = loader.instance()) {
if (const QDesignerCustomWidgetCollectionInterface *c = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(plugin)) {
- const QList<QDesignerCustomWidgetInterface *> &collCustomWidgets = c->customWidgets();
+ const auto &collCustomWidgets = c->customWidgets();
for (const QDesignerCustomWidgetInterface *p : collCustomWidgets)
setItem(pluginItem, p->name(), p->toolTip(), p->whatsThis(), p->icon());
} else {
diff --git a/src/designer/src/lib/shared/pluginmanager.cpp b/src/designer/src/lib/shared/pluginmanager.cpp
index ddc8cd611..88b581862 100644
--- a/src/designer/src/lib/shared/pluginmanager.cpp
+++ b/src/designer/src/lib/shared/pluginmanager.cpp
@@ -544,7 +544,7 @@ void QDesignerPluginManagerPrivate::addCustomWidgets(const QObject *o,
return;
}
if (const QDesignerCustomWidgetCollectionInterface *coll = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(o)) {
- const QList<QDesignerCustomWidgetInterface *> &collCustomWidgets = coll->customWidgets();
+ const auto &collCustomWidgets = coll->customWidgets();
for (QDesignerCustomWidgetInterface *c : collCustomWidgets)
addCustomWidget(c, pluginPath, designerLanguage);
}
@@ -589,7 +589,7 @@ QStringList QDesignerPluginManager::findPlugins(const QString &path)
return QStringList();
const QFileInfoList infoList = dir.entryInfoList(QDir::Files);
- if (infoList.empty())
+ if (infoList.isEmpty())
return QStringList();
// Load symbolic links but make sure all file names are unique as not
@@ -738,7 +738,7 @@ void QDesignerPluginManager::ensureInitialized()
m_d->clearCustomWidgets();
// Add the static custom widgets
const QObjectList staticPluginObjects = QPluginLoader::staticInstances();
- if (!staticPluginObjects.empty()) {
+ if (!staticPluginObjects.isEmpty()) {
const QString staticPluginPath = QCoreApplication::applicationFilePath();
for (QObject *o : staticPluginObjects)
m_d->addCustomWidgets(o, staticPluginPath, designerLanguage);
diff --git a/src/designer/src/lib/shared/previewconfigurationwidget.cpp b/src/designer/src/lib/shared/previewconfigurationwidget.cpp
index f9ddb4b5e..1f7649975 100644
--- a/src/designer/src/lib/shared/previewconfigurationwidget.cpp
+++ b/src/designer/src/lib/shared/previewconfigurationwidget.cpp
@@ -57,19 +57,19 @@ static const char *skinExtensionC = "skin";
// Pair of skin name, path
typedef QPair<QString, QString> SkinNamePath;
-using Skins = QList<SkinNamePath>;
+using Skins = QVector<SkinNamePath>;
enum { SkinComboNoneIndex = 0 };
// find default skins (resources)
static const Skins &defaultSkins() {
static Skins rc;
- if (rc.empty()) {
+ if (rc.isEmpty()) {
const QString skinPath = QLatin1String(skinResourcePathC);
QString pattern = QStringLiteral("*.");
pattern += QLatin1String(skinExtensionC);
const QDir dir(skinPath, pattern);
const QFileInfoList list = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::Name);
- if (list.empty())
+ if (list.isEmpty())
return rc;
const QFileInfoList::const_iterator lcend = list.constEnd();
for (QFileInfoList::const_iterator it = list.constBegin(); it != lcend; ++it)
@@ -144,9 +144,8 @@ PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::PreviewConfigurat
Skins skins = defaultSkins();
skins.push_front(SkinNamePath(PreviewConfigurationWidget::tr("None"), QString()));
- const Skins::const_iterator scend = skins.constEnd();
- for (Skins::const_iterator it = skins.constBegin(); it != scend; ++it)
- m_ui.m_skinCombo->addItem (it->first, QVariant(it->second));
+ for (const auto &skin : qAsConst(skins))
+ m_ui.m_skinCombo->addItem(skin.first, QVariant(skin.second));
m_browseSkinIndex = m_firstUserSkinIndex = skins.size();
m_ui.m_skinCombo->addItem(PreviewConfigurationWidget::tr("Browse..."), QString());
@@ -171,7 +170,7 @@ QStringList PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::userS
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::addUserSkins(const QStringList &files)
{
- if (files.empty())
+ if (files.isEmpty())
return;
const QStringList ::const_iterator fcend = files.constEnd();
for (QStringList::const_iterator it = files.constBegin(); it != fcend; ++it) {
@@ -281,7 +280,7 @@ int PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::browseSkin()
break;
// check: 1) name already there
- const QString directory = directories.front();
+ const QString directory = directories.constFirst();
const QString name = QFileInfo(directory).baseName();
const int existingIndex = m_ui.m_skinCombo->findText(name);
if (existingIndex != -1 && existingIndex != SkinComboNoneIndex && existingIndex != m_browseSkinIndex) {
@@ -318,7 +317,7 @@ PreviewConfigurationWidget::PreviewConfigurationWidget(QDesignerFormEditorInterf
this, &PreviewConfigurationWidget::slotEditAppStyleSheet);
connect(m_impl->skinRemoveButton(), &QAbstractButton::clicked,
this, &PreviewConfigurationWidget::slotDeleteSkinEntry);
- connect(m_impl->skinCombo(), QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(m_impl->skinCombo(), QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &PreviewConfigurationWidget::slotSkinChanged);
m_impl->retrieveSettings();
diff --git a/src/designer/src/lib/shared/previewmanager.cpp b/src/designer/src/lib/shared/previewmanager.cpp
index 4649901f9..68466d597 100644
--- a/src/designer/src/lib/shared/previewmanager.cpp
+++ b/src/designer/src/lib/shared/previewmanager.cpp
@@ -54,11 +54,12 @@
#include <QtWidgets/qaction.h>
#include <QtWidgets/qactiongroup.h>
#include <QtGui/qcursor.h>
-#include <QtGui/qmatrix.h>
+#include <QtGui/qtransform.h>
#include <QtCore/qmap.h>
#include <QtCore/qdebug.h>
#include <QtCore/qshareddata.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -168,7 +169,7 @@ protected:
virtual void fitWidget(const QSize &size);
// Calculate the complete transformation for the skin
// (base class implementation provides rotation).
- virtual QMatrix skinTransform() const;
+ virtual QTransform skinTransform() const;
private:
const QSize m_screenSize;
@@ -207,7 +208,7 @@ void PreviewDeviceSkin::setPreview(QWidget *formWidget)
void PreviewDeviceSkin::slotSkinKeyPressEvent(int code, const QString& text, bool autorep)
{
if (QWidget *focusWidget = QApplication::focusWidget()) {
- QKeyEvent e(QEvent::KeyPress, code, nullptr, text, autorep);
+ QKeyEvent e(QEvent::KeyPress, code, {}, text, autorep);
QApplication::sendEvent(focusWidget, &e);
}
}
@@ -215,7 +216,7 @@ void PreviewDeviceSkin::slotSkinKeyPressEvent(int code, const QString& text, boo
void PreviewDeviceSkin::slotSkinKeyReleaseEvent(int code, const QString& text, bool autorep)
{
if (QWidget *focusWidget = QApplication::focusWidget()) {
- QKeyEvent e(QEvent::KeyRelease, code, nullptr, text, autorep);
+ QKeyEvent e(QEvent::KeyRelease, code, {}, text, autorep);
QApplication::sendEvent(focusWidget, &e);
}
}
@@ -285,9 +286,9 @@ void PreviewDeviceSkin::fitWidget(const QSize &size)
view()->setFixedSize(size);
}
-QMatrix PreviewDeviceSkin::skinTransform() const
+QTransform PreviewDeviceSkin::skinTransform() const
{
- QMatrix newTransform;
+ QTransform newTransform;
switch (m_direction) {
case DirectionUp:
break;
@@ -341,7 +342,7 @@ signals:
protected:
void populateContextMenu(QMenu *m) override;
- QMatrix skinTransform() const override;
+ QTransform skinTransform() const override;
void fitWidget(const QSize &size) override;
private:
@@ -414,10 +415,10 @@ void ZoomablePreviewDeviceSkin::populateContextMenu(QMenu *menu)
menu->addSeparator();
}
-QMatrix ZoomablePreviewDeviceSkin::skinTransform() const
+QTransform ZoomablePreviewDeviceSkin::skinTransform() const
{
// Complete transformation consisting of base class rotation and zoom.
- QMatrix rc = PreviewDeviceSkin::skinTransform();
+ QTransform rc = PreviewDeviceSkin::skinTransform();
const int zp = zoomPercent();
if (zp != 100) {
const qreal factor = zoomFactor(zp);
@@ -555,7 +556,7 @@ public:
QPointer<QWidget> m_activePreview;
- using PreviewDataList = QList<PreviewData>;
+ using PreviewDataList = QVector<PreviewData>;
PreviewDataList m_previews;
@@ -772,11 +773,11 @@ QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw,
// If its the first one, position relative to form.
// 2nd, attempt to tile right (for comparing styles) or cascade
const QSize size = widget->size();
- const bool firstPreview = d->m_previews.empty();
+ const bool firstPreview = d->m_previews.isEmpty();
if (firstPreview) {
widget->move(fw->mapToGlobal(QPoint(Spacing, Spacing)));
} else {
- if (QWidget *lastPreview = d->m_previews.back().m_widget) {
+ if (QWidget *lastPreview = d->m_previews.constLast().m_widget) {
QDesktopWidget *desktop = qApp->desktop();
const QRect lastPreviewGeometry = lastPreview->frameGeometry();
const QRect availGeometry = desktop->availableGeometry(lastPreview);
@@ -798,7 +799,7 @@ QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw,
QWidget *PreviewManager::raise(const QDesignerFormWindowInterface *fw, const PreviewConfiguration &pc)
{
using PreviewDataList = PreviewManagerPrivate::PreviewDataList;
- if (d->m_previews.empty())
+ if (d->m_previews.isEmpty())
return nullptr;
// find matching window
@@ -816,7 +817,7 @@ QWidget *PreviewManager::raise(const QDesignerFormWindowInterface *fw, const Pre
void PreviewManager::closeAllPreviews()
{
- if (!d->m_previews.empty()) {
+ if (!d->m_previews.isEmpty()) {
d->m_updateBlocked = true;
d->m_activePreview = nullptr;
for (auto it = d->m_previews.constBegin(), cend = d->m_previews.constEnd(); it != cend ;++it) {
@@ -843,7 +844,7 @@ void PreviewManager::updatePreviewClosed(QWidget *w)
++it;
}
}
- if (d->m_previews.empty())
+ if (d->m_previews.isEmpty())
emit lastPreviewClosed();
}
diff --git a/src/designer/src/lib/shared/promotionmodel.cpp b/src/designer/src/lib/shared/promotionmodel.cpp
index c2dd25523..37136ced6 100644
--- a/src/designer/src/lib/shared/promotionmodel.cpp
+++ b/src/designer/src/lib/shared/promotionmodel.cpp
@@ -129,7 +129,7 @@ namespace qdesigner_internal {
// Set the item index as user data on the item.
const PromotedClasses promotedClasses = m_core->promotion()->promotedClasses();
- if (promotedClasses.empty())
+ if (promotedClasses.isEmpty())
return;
const QSet<QString> usedPromotedClasses = m_core->promotion()->referencedPromotedClassNames();
@@ -143,7 +143,7 @@ namespace qdesigner_internal {
if (baseClass != it->baseItem) {
baseClass = it->baseItem;
const StandardItemList baseRow = baseModelRow(it->baseItem);
- baseItem = baseRow.front();
+ baseItem = baseRow.constFirst();
appendRow(baseRow);
}
Q_ASSERT(baseItem);
@@ -187,7 +187,7 @@ namespace qdesigner_internal {
QModelIndex PromotionModel::indexOfClass(const QString &className) const {
const StandardItemList matches = findItems (className, Qt::MatchFixedString|Qt::MatchCaseSensitive|Qt::MatchRecursive);
- return matches.empty() ? QModelIndex() : indexFromItem (matches.front());
+ return matches.isEmpty() ? QModelIndex() : indexFromItem (matches.constFirst());
}
} // namespace qdesigner_internal
diff --git a/src/designer/src/lib/shared/promotiontaskmenu.cpp b/src/designer/src/lib/shared/promotiontaskmenu.cpp
index bb5631d32..33554707a 100644
--- a/src/designer/src/lib/shared/promotiontaskmenu.cpp
+++ b/src/designer/src/lib/shared/promotiontaskmenu.cpp
@@ -111,7 +111,7 @@ void PromotionTaskMenu::setDemoteLabel(const QString &demoteLabel)
PromotionTaskMenu::PromotionState PromotionTaskMenu::createPromotionActions(QDesignerFormWindowInterface *formWindow)
{
// clear out old
- if (!m_promotionActions.empty()) {
+ if (!m_promotionActions.isEmpty()) {
qDeleteAll(m_promotionActions);
m_promotionActions.clear();
}
@@ -122,7 +122,7 @@ PromotionTaskMenu::PromotionState PromotionTaskMenu::createPromotionActions(QDe
// Check for a homogenous selection
const PromotionSelectionList promotionSelection = promotionSelectionList(formWindow);
- if (promotionSelection.empty())
+ if (promotionSelection.isEmpty())
return NoHomogenousSelection;
QDesignerFormEditorInterface *core = formWindow->core();
@@ -137,7 +137,7 @@ PromotionTaskMenu::PromotionState PromotionTaskMenu::createPromotionActions(QDe
// figure out candidates
const QString baseClassName = WidgetFactory::classNameOf(core, m_widget);
const WidgetDataBaseItemList candidates = promotionCandidates(core->widgetDataBase(), baseClassName );
- if (candidates.empty()) {
+ if (candidates.isEmpty()) {
// Is this thing promotable at all?
return QDesignerPromotionDialog::baseClassNames(core->promotion()).contains(baseClassName) ? CanPromote : NotApplicable;
}
@@ -230,7 +230,7 @@ void PromotionTaskMenu::slotDemoteFromCustomWidget()
{
QDesignerFormWindowInterface *fw = formWindow();
const PromotionSelectionList promotedWidgets = promotionSelectionList(fw);
- Q_ASSERT(!promotedWidgets.empty() && isPromoted(fw->core(), promotedWidgets.front()));
+ Q_ASSERT(!promotedWidgets.isEmpty() && isPromoted(fw->core(), promotedWidgets.constFirst()));
// ### use the undo stack
DemoteFromCustomWidgetCommand *cmd = new DemoteFromCustomWidgetCommand(fw);
diff --git a/src/designer/src/lib/shared/promotiontaskmenu_p.h b/src/designer/src/lib/shared/promotiontaskmenu_p.h
index 830986968..641efa9b3 100644
--- a/src/designer/src/lib/shared/promotiontaskmenu_p.h
+++ b/src/designer/src/lib/shared/promotiontaskmenu_p.h
@@ -45,6 +45,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -111,7 +112,7 @@ private:
PromotionState createPromotionActions(QDesignerFormWindowInterface *formWindow);
QDesignerFormWindowInterface *formWindow() const;
- using PromotionSelectionList = QList<QPointer<QWidget> >;
+ using PromotionSelectionList = QVector<QPointer<QWidget> >;
PromotionSelectionList promotionSelectionList(QDesignerFormWindowInterface *formWindow) const;
Mode m_mode;
diff --git a/src/designer/src/lib/shared/qdesigner_command.cpp b/src/designer/src/lib/shared/qdesigner_command.cpp
index 7346b98f3..04cbfeff3 100644
--- a/src/designer/src/lib/shared/qdesigner_command.cpp
+++ b/src/designer/src/lib/shared/qdesigner_command.cpp
@@ -232,18 +232,15 @@ void InsertWidgetCommand::undo()
void InsertWidgetCommand::refreshBuddyLabels()
{
- using LabelList = QList<QLabel *>;
-
- const LabelList label_list = formWindow()->findChildren<QLabel*>();
- if (label_list.empty())
+ const auto label_list = formWindow()->findChildren<QLabel*>();
+ if (label_list.isEmpty())
return;
const QString buddyProperty = QStringLiteral("buddy");
const QByteArray objectNameU8 = m_widget->objectName().toUtf8();
// Re-set the buddy (The sheet locates the object by name and sets it)
- const LabelList::const_iterator cend = label_list.constEnd();
- for (LabelList::const_iterator it = label_list.constBegin(); it != cend; ++it ) {
- if (QDesignerPropertySheetExtension* sheet = propertySheet(*it)) {
+ for (QLabel *label : label_list) {
+ if (QDesignerPropertySheetExtension* sheet = propertySheet(label)) {
const int idx = sheet->indexOf(buddyProperty);
if (idx != -1) {
const QVariant value = sheet->property(idx);
@@ -350,7 +347,7 @@ void ManageWidgetCommandHelper::init(const QDesignerFormWindowInterface *fw, QWi
m_managedChildren.clear();
const QWidgetList children = m_widget->findChildren<QWidget *>();
- if (children.empty())
+ if (children.isEmpty())
return;
m_managedChildren.reserve(children.size());
@@ -370,7 +367,7 @@ void ManageWidgetCommandHelper::manage(QDesignerFormWindowInterface *fw)
{
// Manage the managed children after parent
fw->manageWidget(m_widget);
- if (!m_managedChildren.empty()) {
+ if (!m_managedChildren.isEmpty()) {
const WidgetVector::const_iterator lcend = m_managedChildren.constEnd();
for (WidgetVector::const_iterator it = m_managedChildren.constBegin(); it != lcend; ++it)
fw->manageWidget(*it);
@@ -380,7 +377,7 @@ void ManageWidgetCommandHelper::manage(QDesignerFormWindowInterface *fw)
void ManageWidgetCommandHelper::unmanage(QDesignerFormWindowInterface *fw)
{
// Unmanage the managed children first
- if (!m_managedChildren.empty()) {
+ if (!m_managedChildren.isEmpty()) {
const WidgetVector::const_iterator lcend = m_managedChildren.constEnd();
for (WidgetVector::const_iterator it = m_managedChildren.constBegin(); it != lcend; ++it)
fw->unmanageWidget(*it);
@@ -665,7 +662,7 @@ DemoteFromCustomWidgetCommand::DemoteFromCustomWidgetCommand
void DemoteFromCustomWidgetCommand::init(const WidgetList &promoted)
{
- m_promote_cmd.init(promoted, promotedCustomClassName(core(), promoted.front()));
+ m_promote_cmd.init(promoted, promotedCustomClassName(core(), promoted.constFirst()));
}
void DemoteFromCustomWidgetCommand::redo()
@@ -695,7 +692,7 @@ void CursorSelectionState::save(const QDesignerFormWindowInterface *formWindow)
void CursorSelectionState::restore(QDesignerFormWindowInterface *formWindow) const
{
- if (m_selection.empty()) {
+ if (m_selection.isEmpty()) {
formWindow->clearSelection(true);
} else {
// Select current as last
@@ -2656,7 +2653,7 @@ static RemoveActionCommand::ActionData findActionIn(QAction *action)
const QWidgetList &associatedWidgets = action->associatedWidgets();
for (QWidget *widget : associatedWidgets) {
if (qobject_cast<const QMenu *>(widget) || qobject_cast<const QToolBar *>(widget)) {
- const QList<QAction*> actionList = widget->actions();
+ const auto actionList = widget->actions();
const int size = actionList.size();
for (int i = 0; i < size; ++i) {
if (actionList.at(i) == action) {
@@ -2692,7 +2689,7 @@ void RemoveActionCommand::redo()
core()->actionEditor()->setFormWindow(fw);
core()->actionEditor()->unmanageAction(m_action);
- if (!m_actionData.empty())
+ if (!m_actionData.isEmpty())
core()->objectInspector()->setFormWindow(fw);
}
@@ -2702,7 +2699,7 @@ void RemoveActionCommand::undo()
core()->actionEditor()->manageAction(m_action);
for (const ActionDataItem &item : qAsConst(m_actionData))
item.widget->insertAction(item.before, m_action);
- if (!m_actionData.empty())
+ if (!m_actionData.isEmpty())
core()->objectInspector()->setFormWindow(formWindow());
}
diff --git a/src/designer/src/lib/shared/qdesigner_command2.cpp b/src/designer/src/lib/shared/qdesigner_command2.cpp
index e956e7d92..ac035f6ec 100644
--- a/src/designer/src/lib/shared/qdesigner_command2.cpp
+++ b/src/designer/src/lib/shared/qdesigner_command2.cpp
@@ -143,7 +143,7 @@ QString MorphLayoutCommand::formatDescription(QDesignerFormEditorInterface * /*
LayoutAlignmentCommand::LayoutAlignmentCommand(QDesignerFormWindowInterface *formWindow) :
QDesignerFormWindowCommand(QApplication::translate("Command", "Change layout alignment"), formWindow),
- m_newAlignment(nullptr), m_oldAlignment(nullptr), m_widget(nullptr)
+ m_widget(nullptr)
{
}
@@ -180,7 +180,7 @@ Qt::Alignment LayoutAlignmentCommand::alignmentOf(const QDesignerFormEditorInter
(type == LayoutInfo::HBox || type == LayoutInfo::VBox
|| type == LayoutInfo::Grid);
if (!enabled)
- return Qt::Alignment(nullptr);
+ return {};
// Get alignment
const int index = layout->indexOf(w);
Q_ASSERT(index >= 0);
diff --git a/src/designer/src/lib/shared/qdesigner_command_p.h b/src/designer/src/lib/shared/qdesigner_command_p.h
index 8053c8918..fc20745f7 100644
--- a/src/designer/src/lib/shared/qdesigner_command_p.h
+++ b/src/designer/src/lib/shared/qdesigner_command_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qpoint.h>
#include <QtCore/qrect.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -316,7 +317,7 @@ private:
class QDESIGNER_SHARED_EXPORT PromoteToCustomWidgetCommand : public QDesignerFormWindowCommand
{
public:
- using WidgetPointerList = QList<QPointer<QWidget> >;
+ using WidgetPointerList = QVector<QPointer<QWidget> >;
explicit PromoteToCustomWidgetCommand(QDesignerFormWindowInterface *formWindow);
@@ -354,7 +355,7 @@ public:
void restore(QDesignerFormWindowInterface *formWindow) const;
private:
- using WidgetPointerList = QList<QPointer<QWidget> >;
+ using WidgetPointerList = QVector<QPointer<QWidget> >;
WidgetPointerList m_selection;
QPointer<QWidget> m_current;
};
@@ -871,7 +872,7 @@ struct QDESIGNER_SHARED_EXPORT ListContents {
bool operator==(const ListContents &rhs) const { return m_items == rhs.m_items; }
bool operator!=(const ListContents &rhs) const { return m_items != rhs.m_items; }
- QList<ItemData> m_items;
+ QVector<ItemData> m_items;
};
// Data structure representing the contents of a QTableWidget with
@@ -933,7 +934,7 @@ struct QDESIGNER_SHARED_EXPORT TreeWidgetContents {
//bool m_firstColumnSpanned:1;
//bool m_hidden:1;
//bool m_expanded:1;
- QList<ItemContents> m_children;
+ QVector<ItemContents> m_children;
};
void clear();
@@ -945,7 +946,7 @@ struct QDESIGNER_SHARED_EXPORT TreeWidgetContents {
bool operator!=(const TreeWidgetContents &rhs) const { return !(*this == rhs); }
ListContents m_headerItem;
- QList<ItemContents> m_rootItems;
+ QVector<ItemContents> m_rootItems;
};
class QDESIGNER_SHARED_EXPORT ChangeTreeContentsCommand: public QDesignerFormWindowCommand
@@ -1016,7 +1017,7 @@ public:
QAction *before;
QWidget *widget;
};
- using ActionData = QList<ActionDataItem>;
+ using ActionData = QVector<ActionDataItem>;
private:
QAction *m_action;
diff --git a/src/designer/src/lib/shared/qdesigner_dnditem.cpp b/src/designer/src/lib/shared/qdesigner_dnditem.cpp
index db714d950..4a7864372 100644
--- a/src/designer/src/lib/shared/qdesigner_dnditem.cpp
+++ b/src/designer/src/lib/shared/qdesigner_dnditem.cpp
@@ -206,7 +206,7 @@ Qt::DropAction QDesignerMimeData::proposedDropAction() const
Qt::DropAction QDesignerMimeData::execDrag(const QDesignerDnDItems &items, QWidget * dragSource)
{
- if (items.empty())
+ if (items.isEmpty())
return Qt::IgnoreAction;
QDrag *drag = new QDrag(dragSource);
@@ -253,7 +253,7 @@ void QDesignerMimeData::removeMovedWidgetsFromSourceForm(const QDesignerDnDItems
if (FormWindowBase *fb = qobject_cast<FormWindowBase *>((*it)->source()))
formWidgetMap.insert(fb, w);
- const QList<FormWindowBase *> &formWindows = formWidgetMap.uniqueKeys();
+ const auto &formWindows = formWidgetMap.uniqueKeys();
for (FormWindowBase *fb : formWindows)
fb->deleteWidgetList(formWidgetMap.values(fb));
}
diff --git a/src/designer/src/lib/shared/qdesigner_dockwidget.cpp b/src/designer/src/lib/shared/qdesigner_dockwidget.cpp
index 278f9b829..d29fcaba2 100644
--- a/src/designer/src/lib/shared/qdesigner_dockwidget.cpp
+++ b/src/designer/src/lib/shared/qdesigner_dockwidget.cpp
@@ -35,11 +35,23 @@
#include <QtDesigner/qextensionmanager.h>
#include <QtDesigner/abstractformwindowcursor.h>
+#include <qdesigner_propertysheet_p.h>
+
#include <QtWidgets/qmainwindow.h>
#include <QtWidgets/qlayout.h>
QT_BEGIN_NAMESPACE
+bool QDockWidgetPropertySheet::isEnabled(int index) const
+{
+ const QString &name = propertyName(index);
+ if (name == QLatin1String("dockWidgetArea"))
+ return static_cast<const QDesignerDockWidget *>(object())->docked();
+ if (name == QLatin1String("docked"))
+ return static_cast<const QDesignerDockWidget *>(object())->inMainWindow();
+ return QDesignerPropertySheet::isEnabled(index);
+}
+
QDesignerDockWidget::QDesignerDockWidget(QWidget *parent)
: QDockWidget(parent)
{
diff --git a/src/designer/src/lib/shared/qdesigner_dockwidget_p.h b/src/designer/src/lib/shared/qdesigner_dockwidget_p.h
index 7db332495..a39ece90d 100644
--- a/src/designer/src/lib/shared/qdesigner_dockwidget_p.h
+++ b/src/designer/src/lib/shared/qdesigner_dockwidget_p.h
@@ -41,6 +41,9 @@
#define QDESIGNER_DOCKWIDGET_H
#include "shared_global_p.h"
+
+#include <qdesigner_propertysheet_p.h>
+
#include <QtWidgets/qdockwidget.h>
QT_BEGIN_NAMESPACE
@@ -50,8 +53,8 @@ class QDesignerFormWindowInterface;
class QDESIGNER_SHARED_EXPORT QDesignerDockWidget: public QDockWidget
{
Q_OBJECT
- Q_PROPERTY(Qt::DockWidgetArea dockWidgetArea READ dockWidgetArea WRITE setDockWidgetArea DESIGNABLE docked STORED false)
- Q_PROPERTY(bool docked READ docked WRITE setDocked DESIGNABLE inMainWindow STORED false)
+ Q_PROPERTY(Qt::DockWidgetArea dockWidgetArea READ dockWidgetArea WRITE setDockWidgetArea DESIGNABLE true STORED false)
+ Q_PROPERTY(bool docked READ docked WRITE setDocked DESIGNABLE true STORED false)
public:
QDesignerDockWidget(QWidget *parent = nullptr);
~QDesignerDockWidget() override;
@@ -69,6 +72,18 @@ private:
QMainWindow *findMainWindow() const;
};
+class QDESIGNER_SHARED_EXPORT QDockWidgetPropertySheet : public QDesignerPropertySheet
+{
+ Q_OBJECT
+public:
+ using QDesignerPropertySheet::QDesignerPropertySheet;
+
+ bool isEnabled(int index) const override;
+};
+
+using QDockWidgetPropertySheetFactory =
+ QDesignerPropertySheetFactory<QDockWidget, QDockWidgetPropertySheet>;
+
QT_END_NAMESPACE
#endif // QDESIGNER_DOCKWIDGET_H
diff --git a/src/designer/src/lib/shared/qdesigner_formbuilder.cpp b/src/designer/src/lib/shared/qdesigner_formbuilder.cpp
index 260316381..3b25125af 100644
--- a/src/designer/src/lib/shared/qdesigner_formbuilder.cpp
+++ b/src/designer/src/lib/shared/qdesigner_formbuilder.cpp
@@ -226,7 +226,7 @@ static bool readDomEnumerationValue(const DomProperty *p,
void QDesignerFormBuilder::applyProperties(QObject *o, const QList<DomProperty*> &properties)
{
- if (properties.empty())
+ if (properties.isEmpty())
return;
const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), o);
diff --git a/src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp b/src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
index 7c44ec4f7..190540db2 100644
--- a/src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
+++ b/src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
@@ -100,19 +100,17 @@ void QDesignerFormWindowCommand::updateBuddies(QDesignerFormWindowInterface *for
{
QExtensionManager* extensionManager = form->core()->extensionManager();
- using LabelList = QList<QLabel *>;
-
- const LabelList label_list = form->findChildren<QLabel*>();
- if (label_list.empty())
+ const auto label_list = form->findChildren<QLabel*>();
+ if (label_list.isEmpty())
return;
const QString buddyProperty = QStringLiteral("buddy");
const QByteArray oldNameU8 = old_name.toUtf8();
const QByteArray newNameU8 = new_name.toUtf8();
- const LabelList::const_iterator cend = label_list.constEnd();
- for (LabelList::const_iterator it = label_list.constBegin(); it != cend; ++it ) {
- if (QDesignerPropertySheetExtension* sheet = qt_extension<QDesignerPropertySheetExtension*>(extensionManager, *it)) {
+ for (QLabel *label : label_list) {
+ if (QDesignerPropertySheetExtension* sheet =
+ qt_extension<QDesignerPropertySheetExtension*>(extensionManager, label)) {
const int idx = sheet->indexOf(buddyProperty);
if (idx != -1) {
const QByteArray oldBuddy = sheet->property(idx).toByteArray();
diff --git a/src/designer/src/lib/shared/qdesigner_introspection.cpp b/src/designer/src/lib/shared/qdesigner_introspection.cpp
index 3001d6b76..344fed976 100644
--- a/src/designer/src/lib/shared/qdesigner_introspection.cpp
+++ b/src/designer/src/lib/shared/qdesigner_introspection.cpp
@@ -37,7 +37,7 @@ QT_BEGIN_NAMESPACE
// Qt Implementation
static QStringList byteArrayListToStringList(const QByteArrayList &l)
{
- if (l.empty())
+ if (l.isEmpty())
return QStringList();
QStringList rc;
for (const QByteArray &b : l)
diff --git a/src/designer/src/lib/shared/qdesigner_membersheet.cpp b/src/designer/src/lib/shared/qdesigner_membersheet.cpp
index 93371ac06..2e62aab7f 100644
--- a/src/designer/src/lib/shared/qdesigner_membersheet.cpp
+++ b/src/designer/src/lib/shared/qdesigner_membersheet.cpp
@@ -36,7 +36,7 @@ QT_BEGIN_NAMESPACE
static QList<QByteArray> stringListToByteArray(const QStringList &l)
{
- if (l.empty())
+ if (l.isEmpty())
return QList<QByteArray>();
QList<QByteArray> rc;
const QStringList::const_iterator cend = l.constEnd();
diff --git a/src/designer/src/lib/shared/qdesigner_menu.cpp b/src/designer/src/lib/shared/qdesigner_menu.cpp
index 88668ea45..a8cad50d3 100644
--- a/src/designer/src/lib/shared/qdesigner_menu.cpp
+++ b/src/designer/src/lib/shared/qdesigner_menu.cpp
@@ -568,7 +568,7 @@ void QDesignerMenu::paintEvent(QPaintEvent *event)
QAction *current = currentAction();
- const QList<QAction *> &actionList = actions();
+ const auto &actionList = actions();
for (QAction *a : actionList) {
const QRect g = actionGeometry(a);
@@ -708,7 +708,7 @@ QDesignerMenu::ActionDragCheck QDesignerMenu::checkAction(QAction *action) const
void QDesignerMenu::dragEnterEvent(QDragEnterEvent *event)
{
const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
- if (!d || d->actionList().empty()) {
+ if (!d || d->actionList().isEmpty()) {
event->ignore();
return;
}
@@ -740,7 +740,7 @@ void QDesignerMenu::dragMoveEvent(QDragMoveEvent *event)
}
const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
- if (!d || d->actionList().empty()) {
+ if (!d || d->actionList().isEmpty()) {
event->ignore();
return;
}
@@ -785,7 +785,7 @@ void QDesignerMenu::dropEvent(QDropEvent *event)
QDesignerFormWindowInterface *fw = formWindow();
const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
- if (!d || d->actionList().empty()) {
+ if (!d || d->actionList().isEmpty()) {
event->ignore();
return;
}
@@ -851,7 +851,7 @@ void QDesignerMenu::closeMenuChain()
w = w->parentWidget();
if (w) {
- const QList<QMenu *> &menus = w->findChildren<QMenu *>();
+ const auto &menus = w->findChildren<QMenu *>();
for (QMenu *subMenu : menus)
subMenu->hide();
}
@@ -1298,7 +1298,7 @@ QAction *QDesignerMenu::safeActionAt(int index) const
void QDesignerMenu::hideSubMenu()
{
m_lastSubMenuIndex = -1;
- const QList<QMenu *> &menus = findChildren<QMenu *>();
+ const auto &menus = findChildren<QMenu *>();
for (QMenu *subMenu : menus)
subMenu->hide();
}
diff --git a/src/designer/src/lib/shared/qdesigner_menubar.cpp b/src/designer/src/lib/shared/qdesigner_menubar.cpp
index e212eff82..287a2fc3c 100644
--- a/src/designer/src/lib/shared/qdesigner_menubar.cpp
+++ b/src/designer/src/lib/shared/qdesigner_menubar.cpp
@@ -604,7 +604,7 @@ QDesignerMenuBar::ActionDragCheck QDesignerMenuBar::checkAction(QAction *action)
void QDesignerMenuBar::dragEnterEvent(QDragEnterEvent *event)
{
const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
- if (!d || d->actionList().empty()) {
+ if (!d || d->actionList().isEmpty()) {
event->ignore();
return;
}
@@ -629,7 +629,7 @@ void QDesignerMenuBar::dragEnterEvent(QDragEnterEvent *event)
void QDesignerMenuBar::dragMoveEvent(QDragMoveEvent *event)
{
const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
- if (!d || d->actionList().empty()) {
+ if (!d || d->actionList().isEmpty()) {
event->ignore();
return;
}
diff --git a/src/designer/src/lib/shared/qdesigner_objectinspector.cpp b/src/designer/src/lib/shared/qdesigner_objectinspector.cpp
index e07504259..c672dca70 100644
--- a/src/designer/src/lib/shared/qdesigner_objectinspector.cpp
+++ b/src/designer/src/lib/shared/qdesigner_objectinspector.cpp
@@ -50,7 +50,7 @@ void Selection::clear()
bool Selection::empty() const
{
- return managed.empty() && unmanaged.empty() && objects.empty();
+ return managed.isEmpty() && unmanaged.isEmpty() && objects.isEmpty();
}
QObjectList Selection::selection() const
diff --git a/src/designer/src/lib/shared/qdesigner_promotion.cpp b/src/designer/src/lib/shared/qdesigner_promotion.cpp
index 2d8169960..08b2848fd 100644
--- a/src/designer/src/lib/shared/qdesigner_promotion.cpp
+++ b/src/designer/src/lib/shared/qdesigner_promotion.cpp
@@ -48,7 +48,7 @@ namespace {
// Return a set of on-promotable classes
const QSet<QString> &nonPromotableClasses() {
static QSet<QString> rc;
- if (rc.empty()) {
+ if (rc.isEmpty()) {
rc.insert(QStringLiteral("Line"));
rc.insert(QStringLiteral("QAction"));
rc.insert(QStringLiteral("Spacer"));
@@ -225,7 +225,7 @@ namespace qdesigner_internal {
// convert map into list.
PromotedClasses rc;
- if (baseClassPromotedMap.empty())
+ if (baseClassPromotedMap.isEmpty())
return rc;
const BaseClassPromotedMap::const_iterator bcend = baseClassPromotedMap.constEnd();
@@ -262,7 +262,7 @@ namespace qdesigner_internal {
// check the scratchpad of the widget box
if (QDesignerWidgetBoxInterface *widgetBox = m_core->widgetBox()) {
const QStringList scratchPadClasses = getScratchPadClasses(widgetBox);
- if (!scratchPadClasses.empty()) {
+ if (!scratchPadClasses.isEmpty()) {
// Check whether these are actually promoted
QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
QStringList::const_iterator cend = scratchPadClasses.constEnd();
diff --git a/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp b/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp
index 7058b0c81..1ec5cd9ae 100644
--- a/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp
+++ b/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp
@@ -290,7 +290,7 @@ namespace qdesigner_internal {
const QStringList &QDesignerPromotionDialog::baseClassNames(const QDesignerPromotionInterface *promotion) {
using WidgetDataBaseItemList = QList<QDesignerWidgetDataBaseItemInterface *>;
static QStringList rc;
- if (rc.empty()) {
+ if (rc.isEmpty()) {
// Convert the item list into a string list.
const WidgetDataBaseItemList dbItems = promotion->promotionBaseClasses();
const WidgetDataBaseItemList::const_iterator cend = dbItems.constEnd();
@@ -351,7 +351,7 @@ namespace qdesigner_internal {
QDesignerWidgetDataBaseItemInterface *QDesignerPromotionDialog::databaseItemAt(const QItemSelection &selected, unsigned &flags) const {
flags = 0;
const QModelIndexList indexes = selected.indexes();
- if (indexes.empty())
+ if (indexes.isEmpty())
return nullptr;
const PromotionModel::ModelData data = m_model->modelData(indexes.constFirst());
QDesignerWidgetDataBaseItemInterface *dbItem = data.promotedItem;
diff --git a/src/designer/src/lib/shared/qdesigner_propertycommand.cpp b/src/designer/src/lib/shared/qdesigner_propertycommand.cpp
index 8b564ab6f..8eec59868 100644
--- a/src/designer/src/lib/shared/qdesigner_propertycommand.cpp
+++ b/src/designer/src/lib/shared/qdesigner_propertycommand.cpp
@@ -646,7 +646,7 @@ PropertyHelper::PropertyHelper(QObject* object,
m_objectType = OT_Widget;
} else {
if (const QAction *action = qobject_cast<const QAction *>(m_object))
- m_objectType = action->associatedWidgets().empty() ? OT_FreeAction : OT_AssociatedAction;
+ m_objectType = action->associatedWidgets().isEmpty() ? OT_FreeAction : OT_AssociatedAction;
}
if(debugPropertyCommands)
@@ -881,7 +881,7 @@ QVariant PropertyHelper::findDefaultValue(QDesignerFormWindowInterface *fw) cons
return m_oldValue.first; // We simply don't know the value in this case
const QDesignerWidgetDataBaseItemInterface *item = fw->core()->widgetDataBase()->item(item_idx);
- const QList<QVariant> default_prop_values = item->defaultPropertyValues();
+ const auto default_prop_values = item->defaultPropertyValues();
if (m_index < default_prop_values.size())
return default_prop_values.at(m_index);
@@ -982,7 +982,7 @@ bool PropertyListCommand::add(QObject *object, const QString &propertyName)
const PropertyDescription description(propertyName, sheet, index);
- if (m_propertyHelperList.empty()) {
+ if (m_propertyHelperList.isEmpty()) {
// first entry
m_propertyDescription = description;
} else {
@@ -1018,7 +1018,7 @@ bool PropertyListCommand::initList(const QObjectList &list, const QString &aprop
add(o, apropertyName);
}
- return !propertyHelperList().empty();
+ return !propertyHelperList().isEmpty();
}
diff --git a/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp b/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp
index 3a26553fd..69f1cdf87 100644
--- a/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp
+++ b/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp
@@ -49,7 +49,7 @@ using PropertyNameTypeMap = QHash<QString, StringPropertyParameters>;
static const PropertyNameTypeMap &stringPropertyTypes()
{
static PropertyNameTypeMap propertyNameTypeMap;
- if (propertyNameTypeMap.empty()) {
+ if (propertyNameTypeMap.isEmpty()) {
const StringPropertyParameters richtext(ValidationRichText, true);
// Accessibility. Both are texts the narrator reads
propertyNameTypeMap.insert(QStringLiteral("accessibleDescription"), richtext);
diff --git a/src/designer/src/lib/shared/qdesigner_propertyeditor_p.h b/src/designer/src/lib/shared/qdesigner_propertyeditor_p.h
index dbb116f65..5995cd21e 100644
--- a/src/designer/src/lib/shared/qdesigner_propertyeditor_p.h
+++ b/src/designer/src/lib/shared/qdesigner_propertyeditor_p.h
@@ -56,7 +56,7 @@ class QDESIGNER_SHARED_EXPORT QDesignerPropertyEditor: public QDesignerPropertyE
{
Q_OBJECT
public:
- explicit QDesignerPropertyEditor(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr);
+ explicit QDesignerPropertyEditor(QWidget *parent = nullptr, Qt::WindowFlags flags = {});
// A pair <ValidationMode, bool isTranslatable>.
using StringPropertyParameters = QPair<TextPropertyValidationMode, bool>;
diff --git a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
index eafc0de4f..c142ee7b1 100644
--- a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
+++ b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
@@ -44,9 +44,12 @@
#include <QtWidgets/qlayout.h>
#include <QtWidgets/qdockwidget.h>
#include <QtWidgets/qdialog.h>
+#include <QtWidgets/qgroupbox.h>
#include <QtWidgets/qlabel.h>
#include <QtWidgets/qgroupbox.h>
#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qabstractbutton.h>
+#include <QtWidgets/qaction.h>
#include <QtWidgets/qapplication.h>
#include <QtWidgets/qtoolbar.h>
#include <QtWidgets/qmainwindow.h>
@@ -173,6 +176,7 @@ class QDesignerPropertySheetPrivate {
public:
using PropertyType = QDesignerPropertySheet::PropertyType;
using ObjectType = QDesignerPropertySheet::ObjectType;
+ using ObjectFlags = QDesignerPropertySheet::ObjectFlags;
explicit QDesignerPropertySheetPrivate(QDesignerPropertySheet *sheetPublic, QObject *object, QObject *sheetParent);
@@ -227,6 +231,7 @@ public:
QDesignerFormEditorInterface *m_core;
const QDesignerMetaObjectInterface *m_meta;
const ObjectType m_objectType;
+ const ObjectFlags m_objectFlags;
using InfoHash = QHash<int, Info>;
InfoHash m_info;
@@ -388,6 +393,7 @@ QDesignerPropertySheetPrivate::QDesignerPropertySheetPrivate(QDesignerPropertySh
m_core(formEditorForObject(sheetParent)),
m_meta(m_core->introspection()->metaObject(object)),
m_objectType(QDesignerPropertySheet::objectTypeFromObject(object)),
+ m_objectFlags(QDesignerPropertySheet::objectFlagsFromObject(object)),
m_canHaveLayoutAttributes(hasLayoutAttributes(m_core, object)),
m_object(object),
m_lastLayout(nullptr),
@@ -470,7 +476,7 @@ QString QDesignerPropertySheetPrivate::transformLayoutPropertyName(int index) co
{
using TypeNameMap = QMap<QDesignerPropertySheet::PropertyType, QString>;
static TypeNameMap typeNameMap;
- if (typeNameMap.empty()) {
+ if (typeNameMap.isEmpty()) {
typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutObjectName, QStringLiteral("objectName"));
typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutLeftMargin, QStringLiteral("leftMargin"));
typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutTopMargin, QStringLiteral("topMargin"));
@@ -515,11 +521,22 @@ QDesignerPropertySheet::ObjectType QDesignerPropertySheet::objectTypeFromObject(
return ObjectNone;
}
+QDesignerPropertySheet::ObjectFlags QDesignerPropertySheet::objectFlagsFromObject(const QObject *o)
+{
+ ObjectFlags result;
+ if ((o->isWidgetType() && (qobject_cast<const QAbstractButton *>(o)
+ || qobject_cast<const QGroupBox *>(o)))
+ || qobject_cast<const QAction *>(o)) {
+ result |= CheckableProperty;
+ }
+ return result;
+}
+
QDesignerPropertySheet::PropertyType QDesignerPropertySheet::propertyTypeFromName(const QString &name)
{
typedef QHash<QString, PropertyType> PropertyTypeHash;
static PropertyTypeHash propertyTypeHash;
- if (propertyTypeHash.empty()) {
+ if (propertyTypeHash.isEmpty()) {
propertyTypeHash.insert(QLatin1String(layoutObjectNameC), PropertyLayoutObjectName);
propertyTypeHash.insert(QLatin1String(layoutLeftMarginC), PropertyLayoutLeftMargin);
propertyTypeHash.insert(QLatin1String(layoutTopMarginC), PropertyLayoutTopMargin);
@@ -540,6 +557,7 @@ QDesignerPropertySheet::PropertyType QDesignerPropertySheet::propertyTypeFromNam
propertyTypeHash.insert(QLatin1String(layoutGridColumnMinimumWidthC), PropertyLayoutGridColumnMinimumWidth);
propertyTypeHash.insert(QStringLiteral("buddy"), PropertyBuddy);
propertyTypeHash.insert(QStringLiteral("geometry"), PropertyGeometry);
+ propertyTypeHash.insert(QStringLiteral("checked"), PropertyChecked);
propertyTypeHash.insert(QStringLiteral("checkable"), PropertyCheckable);
propertyTypeHash.insert(QStringLiteral("accessibleName"), PropertyAccessibility);
propertyTypeHash.insert(QStringLiteral("accessibleDescription"), PropertyAccessibility);
@@ -676,7 +694,7 @@ QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent)
using ByteArrayList = QList<QByteArray>;
const ByteArrayList names = object->dynamicPropertyNames();
- if (!names.empty()) {
+ if (!names.isEmpty()) {
const ByteArrayList::const_iterator cend = names.constEnd();
for (ByteArrayList::const_iterator it = names.constBegin(); it != cend; ++it) {
const char* cName = it->constData();
@@ -1567,8 +1585,16 @@ bool QDesignerPropertySheet::isEnabled(int index) const
// as this might be done via TaskMenu/Cursor::setProperty. Note that those
// properties are not visible.
const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
- return (p->accessFlags() & QDesignerMetaPropertyInterface::WriteAccess) &&
- designableState(p, d->m_object) != PropertyOfObjectNotDesignable;
+ if (!p->accessFlags().testFlag(QDesignerMetaPropertyInterface::WriteAccess))
+ return false;
+
+ if (designableState(p, d->m_object) == PropertyOfObjectNotDesignable)
+ return false;
+
+ const PropertyType type = propertyType(index);
+ if (type == PropertyChecked && d->m_objectFlags.testFlag(CheckableProperty))
+ return d->m_object->property("checkable").toBool();
+ return true;
}
bool QDesignerPropertySheet::isAttribute(int index) const
diff --git a/src/designer/src/lib/shared/qdesigner_propertysheet_p.h b/src/designer/src/lib/shared/qdesigner_propertysheet_p.h
index 4da33b525..49380e1ee 100644
--- a/src/designer/src/lib/shared/qdesigner_propertysheet_p.h
+++ b/src/designer/src/lib/shared/qdesigner_propertysheet_p.h
@@ -155,6 +155,7 @@ public:
PropertyBuddy,
PropertyAccessibility,
PropertyGeometry,
+ PropertyChecked,
PropertyCheckable,
PropertyWindowTitle,
PropertyWindowIcon,
@@ -168,8 +169,14 @@ public:
};
enum ObjectType { ObjectNone, ObjectLabel, ObjectLayout, ObjectLayoutWidget };
+ enum ObjectFlag
+ {
+ CheckableProperty = 0x1 // Has a "checked" property depending on "checkable"
+ };
+ Q_DECLARE_FLAGS(ObjectFlags, ObjectFlag)
static ObjectType objectTypeFromObject(const QObject *o);
+ static ObjectFlags objectFlagsFromObject(const QObject *o);
static PropertyType propertyTypeFromName(const QString &name);
protected:
@@ -248,6 +255,8 @@ void QDesignerPropertySheetFactory<Object, PropertySheet>::registerExtension(QEx
// Standard property sheet
typedef QDesignerPropertySheetFactory<QObject, QDesignerPropertySheet> QDesignerDefaultPropertySheetFactory;
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDesignerPropertySheet::ObjectFlags)
+
QT_END_NAMESPACE
#endif // QDESIGNER_PROPERTYSHEET_H
diff --git a/src/designer/src/lib/shared/qdesigner_tabwidget.cpp b/src/designer/src/lib/shared/qdesigner_tabwidget.cpp
index 2f003cf6c..42a72b403 100644
--- a/src/designer/src/lib/shared/qdesigner_tabwidget.cpp
+++ b/src/designer/src/lib/shared/qdesigner_tabwidget.cpp
@@ -118,9 +118,9 @@ QTabBar *QTabWidgetEventFilter::tabBar() const
{
// QTabWidget::tabBar() accessor is protected, grmbl...
if (!m_cachedTabBar) {
- const QList<QTabBar *> tabBars = m_tabWidget->findChildren<QTabBar *>();
+ const auto tabBars = m_tabWidget->findChildren<QTabBar *>();
Q_ASSERT(tabBars.size() == 1);
- m_cachedTabBar = tabBars.front();
+ m_cachedTabBar = tabBars.constFirst();
}
return m_cachedTabBar;
@@ -406,7 +406,7 @@ QTabWidgetPropertySheet::TabWidgetProperty QTabWidgetPropertySheet::tabWidgetPro
{
using TabWidgetPropertyHash = QHash<QString, TabWidgetProperty>;
static TabWidgetPropertyHash tabWidgetPropertyHash;
- if (tabWidgetPropertyHash.empty()) {
+ if (tabWidgetPropertyHash.isEmpty()) {
tabWidgetPropertyHash.insert(QLatin1String(currentTabTextKey), PropertyCurrentTabText);
tabWidgetPropertyHash.insert(QLatin1String(currentTabNameKey), PropertyCurrentTabName);
tabWidgetPropertyHash.insert(QLatin1String(currentTabIconKey), PropertyCurrentTabIcon);
diff --git a/src/designer/src/lib/shared/qdesigner_taskmenu.cpp b/src/designer/src/lib/shared/qdesigner_taskmenu.cpp
index f1783587f..3168eae73 100644
--- a/src/designer/src/lib/shared/qdesigner_taskmenu.cpp
+++ b/src/designer/src/lib/shared/qdesigner_taskmenu.cpp
@@ -250,7 +250,7 @@ bool LayoutAlignmentMenu::setAlignment(const QDesignerFormEditorInterface *core,
Qt::Alignment LayoutAlignmentMenu::alignment() const
{
- Qt::Alignment alignment = nullptr;
+ Qt::Alignment alignment;
if (const QAction *horizAction = m_horizGroup->checkedAction())
if (const int horizAlign = horizAction->data().toInt())
alignment |= static_cast<Qt::Alignment>(horizAlign);
diff --git a/src/designer/src/lib/shared/qdesigner_toolbar.cpp b/src/designer/src/lib/shared/qdesigner_toolbar.cpp
index 28c2ca285..08723c2ff 100644
--- a/src/designer/src/lib/shared/qdesigner_toolbar.cpp
+++ b/src/designer/src/lib/shared/qdesigner_toolbar.cpp
@@ -124,7 +124,7 @@ ActionList ToolBarEventFilter::contextMenuActions(const QPoint &globalPos)
{
ActionList rc;
const int index = actionIndexAt(m_toolBar, m_toolBar->mapFromGlobal(globalPos), m_toolBar->orientation());
- const ActionList actions = m_toolBar->actions();
+ const auto actions = m_toolBar->actions();
QAction *action = index != -1 ?actions.at(index) : 0;
QVariant itemData;
@@ -138,7 +138,7 @@ ActionList ToolBarEventFilter::contextMenuActions(const QPoint &globalPos)
}
// Append separator
- if (actions.empty() || !actions.back()->isSeparator()) {
+ if (actions.isEmpty() || !actions.constLast()->isSeparator()) {
QAction *newSeperatorAct = new QAction(tr("Append Separator"), nullptr);
itemData.setValue(static_cast<QAction*>(nullptr));
newSeperatorAct->setData(itemData);
@@ -448,7 +448,8 @@ QRect ToolBarEventFilter::freeArea(const QToolBar *tb)
{
QRect rc = QRect(QPoint(0, 0), tb->size());
const ActionList actionList = tb->actions();
- QRect exclusionRectangle = actionList.empty() ? handleArea(tb) : tb->actionGeometry(actionList.back());
+ QRect exclusionRectangle = actionList.isEmpty()
+ ? handleArea(tb) : tb->actionGeometry(actionList.constLast());
switch (tb->orientation()) {
case Qt::Horizontal:
switch (tb->layoutDirection()) {
diff --git a/src/designer/src/lib/shared/qdesigner_toolbox.cpp b/src/designer/src/lib/shared/qdesigner_toolbox.cpp
index f0c0dc726..3a7ed6307 100644
--- a/src/designer/src/lib/shared/qdesigner_toolbox.cpp
+++ b/src/designer/src/lib/shared/qdesigner_toolbox.cpp
@@ -256,7 +256,7 @@ QToolBoxWidgetPropertySheet::ToolBoxProperty QToolBoxWidgetPropertySheet::toolBo
{
using ToolBoxPropertyHash = QHash<QString, ToolBoxProperty>;
static ToolBoxPropertyHash toolBoxPropertyHash;
- if (toolBoxPropertyHash.empty()) {
+ if (toolBoxPropertyHash.isEmpty()) {
toolBoxPropertyHash.insert(QLatin1String(currentItemTextKey), PropertyCurrentItemText);
toolBoxPropertyHash.insert(QLatin1String(currentItemNameKey), PropertyCurrentItemName);
toolBoxPropertyHash.insert(QLatin1String(currentItemIconKey), PropertyCurrentItemIcon);
diff --git a/src/designer/src/lib/shared/qdesigner_utils.cpp b/src/designer/src/lib/shared/qdesigner_utils.cpp
index a7c4fdd72..a16266cae 100644
--- a/src/designer/src/lib/shared/qdesigner_utils.cpp
+++ b/src/designer/src/lib/shared/qdesigner_utils.cpp
@@ -198,7 +198,7 @@ namespace qdesigner_internal
QString DesignerMetaFlags::toString(int value, SerializationMode sm) const
{
const QStringList flagIds = flags(value);
- if (flagIds.empty())
+ if (flagIds.isEmpty())
return QString();
const QChar delimiter = QLatin1Char('|');
@@ -695,7 +695,7 @@ namespace qdesigner_internal
if (const QDesignerTaskMenuExtension *taskMenu = qt_extension<QDesignerTaskMenuExtension*>(core->extensionManager(), managedWidget)) {
action = taskMenu->preferredEditAction();
if (!action) {
- const QList<QAction *> actions = taskMenu->taskActions();
+ const auto actions = taskMenu->taskActions();
if (!actions.isEmpty())
action = actions.first();
}
@@ -705,7 +705,7 @@ namespace qdesigner_internal
core->extensionManager()->extension(managedWidget, QStringLiteral("QDesignerInternalTaskMenuExtension")))) {
action = taskMenu->preferredEditAction();
if (!action) {
- const QList<QAction *> actions = taskMenu->taskActions();
+ const auto actions = taskMenu->taskActions();
if (!actions.isEmpty())
action = actions.first();
}
diff --git a/src/designer/src/lib/shared/qdesigner_widgetbox.cpp b/src/designer/src/lib/shared/qdesigner_widgetbox.cpp
index 1ca79d777..e530bcfc1 100644
--- a/src/designer/src/lib/shared/qdesigner_widgetbox.cpp
+++ b/src/designer/src/lib/shared/qdesigner_widgetbox.cpp
@@ -190,7 +190,7 @@ DomUI *QDesignerWidgetBox::xmlToUi(const QString &name, const QString &xml, bool
while (!reader.atEnd()) {
if (reader.readNext() == QXmlStreamReader::StartElement) {
- const QStringRef name = reader.name();
+ const auto name = reader.name();
if (ui) {
reader.raiseError(tr("Unexpected element <%1>").arg(name.toString()));
continue;
diff --git a/src/designer/src/lib/shared/qdesigner_widgetbox_p.h b/src/designer/src/lib/shared/qdesigner_widgetbox_p.h
index efedb34b2..cad8e04da 100644
--- a/src/designer/src/lib/shared/qdesigner_widgetbox_p.h
+++ b/src/designer/src/lib/shared/qdesigner_widgetbox_p.h
@@ -57,7 +57,7 @@ class QDESIGNER_SHARED_EXPORT QDesignerWidgetBox : public QDesignerWidgetBoxInte
public:
enum LoadMode { LoadMerge, LoadReplace, LoadCustomWidgetsOnly };
- explicit QDesignerWidgetBox(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr);
+ explicit QDesignerWidgetBox(QWidget *parent = nullptr, Qt::WindowFlags flags = {});
LoadMode loadMode() const;
void setLoadMode(LoadMode lm);
diff --git a/src/designer/src/lib/shared/qdesigner_widgetitem.cpp b/src/designer/src/lib/shared/qdesigner_widgetitem.cpp
index 93dd2112e..e6e6cd00a 100644
--- a/src/designer/src/lib/shared/qdesigner_widgetitem.cpp
+++ b/src/designer/src/lib/shared/qdesigner_widgetitem.cpp
@@ -224,7 +224,7 @@ bool QDesignerWidgetItem::check(const QLayout *layout, QWidget *w, Qt::Orientati
// well. Avoid nested layouts (as the effective stretch cannot be easily
// computed and may mess things up).
if (ptrToOrientations)
- *ptrToOrientations = nullptr;
+ *ptrToOrientations = {};
const QObject *layoutParent = layout->parent();
if (!layoutParent || !layoutParent->isWidgetType() || !WidgetFactory::isFormEditorObject(layoutParent))
diff --git a/src/designer/src/lib/shared/qlayout_widget.cpp b/src/designer/src/lib/shared/qlayout_widget.cpp
index 852002838..5090aae17 100644
--- a/src/designer/src/lib/shared/qlayout_widget.cpp
+++ b/src/designer/src/lib/shared/qlayout_widget.cpp
@@ -217,7 +217,7 @@ static bool removeEmptyCellsOnGrid(GridLikeLayout *grid, const QRect &area)
}
}
// remove, starting from last
- if (!indexesToBeRemoved.empty()) {
+ if (!indexesToBeRemoved.isEmpty()) {
std::stable_sort(indexesToBeRemoved.begin(), indexesToBeRemoved.end());
for (int i = indexesToBeRemoved.size() - 1; i >= 0; i--)
delete grid->takeAt(indexesToBeRemoved[i]);
@@ -638,12 +638,11 @@ QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
GridLayoutState::CellStates GridLayoutState::cellStates(const QList<QRect> &rects, int numRows, int numColumns)
{
CellStates rc = CellStates(numRows * numColumns, CellState(Free, Free));
- const QList<QRect>::const_iterator rcend = rects.constEnd();
- for (QList<QRect>::const_iterator it = rects.constBegin(); it != rcend; ++it) {
- const int leftColumn = it->x();
- const int topRow = it->y();
- const int rightColumn = leftColumn + it->width() - 1;
- const int bottomRow = topRow + it->height() - 1;
+ for (const auto &rect : rects) {
+ const int leftColumn = rect.x();
+ const int topRow = rect.y();
+ const int rightColumn = leftColumn + rect.width() - 1;
+ const int bottomRow = topRow + rect.height() - 1;
for (int r = topRow; r <= bottomRow; r++)
for (int c = leftColumn; c <= rightColumn; c++) {
const int flatIndex = r * numColumns + c;
@@ -979,7 +978,7 @@ QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
void GridLayoutHelper::popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout)
{
- Q_ASSERT(!m_states.empty());
+ Q_ASSERT(!m_states.isEmpty());
const GridLayoutState state = m_states.pop();
state.applyToLayout(core, widgetWithManagedLayout);
}
@@ -1137,7 +1136,7 @@ QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
void FormLayoutHelper::popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout)
{
QFormLayout *formLayout = qobject_cast<QFormLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
- Q_ASSERT(!m_states.empty() && formLayout);
+ Q_ASSERT(!m_states.isEmpty() && formLayout);
const FormLayoutState storedState = m_states.pop();
const FormLayoutState currentState = state(formLayout);
@@ -1916,11 +1915,11 @@ void QLayoutWidget::paintEvent(QPaintEvent*)
columns[column + i - 2] = true;
while (rowSpan > 0) {
- excludedColumnsForRow[row + rowSpan - 1].unite(columns);
+ excludedColumnsForRow[row + rowSpan - 1].insert(columns);
rowSpan--;
}
while (columnSpan > 0) {
- excludedRowsForColumn[column + columnSpan - 1].unite(rows);
+ excludedRowsForColumn[column + columnSpan - 1].insert(rows);
columnSpan--;
}
}
diff --git a/src/designer/src/lib/shared/qsimpleresource.cpp b/src/designer/src/lib/shared/qsimpleresource.cpp
index 705d7b608..3d79379b2 100644
--- a/src/designer/src/lib/shared/qsimpleresource.cpp
+++ b/src/designer/src/lib/shared/qsimpleresource.cpp
@@ -224,7 +224,7 @@ void QSimpleResource::handleDomCustomWidgets(const QDesignerFormEditorInterface
// (derived first, max depth: promoted custom plugin = 2)
for (int iteration = 0; iteration < 2; iteration++) {
addCustomWidgetsToWidgetDatabase(core, custom_widget_list);
- if (custom_widget_list.empty())
+ if (custom_widget_list.isEmpty())
return;
}
// Oops, there are classes left whose base class could not be found.
@@ -250,7 +250,7 @@ FormBuilderClipboard::FormBuilderClipboard(QWidget *w)
bool FormBuilderClipboard::empty() const
{
- return m_widgets.empty() && m_actions.empty();
+ return m_widgets.isEmpty() && m_actions.isEmpty();
}
}
diff --git a/src/designer/src/lib/shared/qtresourceeditordialog.cpp b/src/designer/src/lib/shared/qtresourceeditordialog.cpp
index f2275d0b9..a1c15e708 100644
--- a/src/designer/src/lib/shared/qtresourceeditordialog.cpp
+++ b/src/designer/src/lib/shared/qtresourceeditordialog.cpp
@@ -399,10 +399,10 @@ void QtQrcManager::exportQrcFile(QtQrcFile *qrcFile, QtQrcFileData *qrcFileData)
QList<QtResourcePrefixData> resourceList;
- const QList<QtResourcePrefix *> resourcePrefixes = qrcFile->resourcePrefixList();
+ const auto resourcePrefixes = qrcFile->resourcePrefixList();
for (const QtResourcePrefix *prefix : resourcePrefixes) {
QList<QtResourceFileData> resourceFileList;
- const QList<QtResourceFile *> resourceFiles = prefix->resourceFiles();
+ const auto resourceFiles = prefix->resourceFiles();
for (QtResourceFile *file : resourceFiles) {
QtResourceFileData fileData;
fileData.path = file->path();
@@ -460,7 +460,7 @@ QtResourcePrefix *QtQrcManager::prevResourcePrefix(QtResourcePrefix *resourcePre
{
if (!resourcePrefix)
return nullptr;
- QList<QtResourcePrefix *> prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
+ const auto prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
const int idx = prefixes.indexOf(resourcePrefix);
if (idx <= 0)
return nullptr;
@@ -471,7 +471,7 @@ QtResourcePrefix *QtQrcManager::nextResourcePrefix(QtResourcePrefix *resourcePre
{
if (!resourcePrefix)
return nullptr;
- QList<QtResourcePrefix *> prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
+ const auto prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
const int idx = prefixes.indexOf(resourcePrefix);
if (idx < 0 || idx == prefixes.size() - 1)
return nullptr;
@@ -482,7 +482,7 @@ QtResourceFile *QtQrcManager::prevResourceFile(QtResourceFile *resourceFile) con
{
if (!resourceFile)
return nullptr;
- QList<QtResourceFile *> files = resourcePrefixOf(resourceFile)->resourceFiles();
+ const auto files = resourcePrefixOf(resourceFile)->resourceFiles();
const int idx = files.indexOf(resourceFile);
if (idx <= 0)
return nullptr;
@@ -493,7 +493,7 @@ QtResourceFile *QtQrcManager::nextResourceFile(QtResourceFile *resourceFile) con
{
if (!resourceFile)
return nullptr;
- QList<QtResourceFile *> files = resourcePrefixOf(resourceFile)->resourceFiles();
+ const auto files = resourcePrefixOf(resourceFile)->resourceFiles();
const int idx = files.indexOf(resourceFile);
if (idx < 0 || idx == files.size() - 1)
return nullptr;
@@ -502,7 +502,7 @@ QtResourceFile *QtQrcManager::nextResourceFile(QtResourceFile *resourceFile) con
void QtQrcManager::clear()
{
- const QList<QtQrcFile *> oldQrcFiles = qrcFiles();
+ const auto oldQrcFiles = qrcFiles();
for (QtQrcFile *qf : oldQrcFiles)
removeQrcFile(qf);
}
@@ -569,7 +569,7 @@ void QtQrcManager::removeQrcFile(QtQrcFile *qrcFile)
if (idx < 0)
return;
- const QList<QtResourcePrefix *> resourcePrefixes = qrcFile->resourcePrefixList();
+ const auto resourcePrefixes = qrcFile->resourcePrefixList();
for (QtResourcePrefix *rp : resourcePrefixes)
removeResourcePrefix(rp);
@@ -672,7 +672,7 @@ void QtQrcManager::removeResourcePrefix(QtResourcePrefix *resourcePrefix)
const int idx = qrcFile->m_resourcePrefixes.indexOf(resourcePrefix);
- const QList<QtResourceFile *> resourceFiles = resourcePrefix->resourceFiles();
+ const auto resourceFiles = resourcePrefix->resourceFiles();
for (QtResourceFile *rf : resourceFiles)
removeResourceFile(rf);
@@ -1013,7 +1013,7 @@ void QtResourceEditorDialogPrivate::slotResourcePrefixMoved(QtResourcePrefix *re
const QModelIndex index = m_treeModel->indexFromItem(prefixItem);
const bool expanded = m_ui.resourceTreeView->isExpanded(index);
m_ignoreCurrentChanged = true;
- const QList<QStandardItem *> items = m_treeModel->takeRow(index.row());
+ const auto items = m_treeModel->takeRow(index.row());
int row = m_treeModel->rowCount();
QtResourcePrefix *nextResourcePrefix = m_qrcManager->nextResourcePrefix(resourcePrefix);
@@ -1126,7 +1126,7 @@ void QtResourceEditorDialogPrivate::slotResourceFileMoved(QtResourceFile *resour
QStandardItem *parentItem = pathItem->parent();
m_ignoreCurrentChanged = true;
- const QList<QStandardItem *> items = parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
+ const auto items = parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
int row = parentItem->rowCount();
QtResourceFile *nextResourceFile = m_qrcManager->nextResourceFile(resourceFile);
@@ -1189,7 +1189,7 @@ void QtResourceEditorDialogPrivate::slotCurrentQrcFileChanged(QListWidgetItem *i
QMap<QtResourcePrefix *, QStandardItem *> currentPrefixList = m_resourcePrefixToPrefixItem;
for (auto it = currentPrefixList.cbegin(), end = currentPrefixList.cend(); it != end; ++it) {
QtResourcePrefix *resourcePrefix = it.key();
- const QList<QtResourceFile *> currentResourceFiles = resourcePrefix->resourceFiles();
+ const auto currentResourceFiles = resourcePrefix->resourceFiles();
for (QtResourceFile *rf : currentResourceFiles)
slotResourceFileRemoved(rf);
slotResourcePrefixRemoved(resourcePrefix);
@@ -1200,12 +1200,12 @@ void QtResourceEditorDialogPrivate::slotCurrentQrcFileChanged(QListWidgetItem *i
slotCurrentTreeViewItemChanged(QModelIndex());
QStandardItem *firstPrefix = nullptr; // select first prefix
if (m_currentQrcFile) {
- const QList<QtResourcePrefix *> newPrefixList = m_currentQrcFile->resourcePrefixList();
+ const auto newPrefixList = m_currentQrcFile->resourcePrefixList();
for (QtResourcePrefix *resourcePrefix : newPrefixList) {
if (QStandardItem *newPrefixItem = insertResourcePrefix(resourcePrefix))
if (!firstPrefix)
firstPrefix = newPrefixItem;
- const QList<QtResourceFile *> newResourceFiles = resourcePrefix->resourceFiles();
+ const auto newResourceFiles = resourcePrefix->resourceFiles();
for (QtResourceFile *rf : newResourceFiles)
slotResourceFileInserted(rf);
}
@@ -1542,7 +1542,7 @@ void QtResourceEditorDialogPrivate::slotAddFiles()
QtResourceFile *nextResourceFile = m_qrcManager->nextResourceFile(currentResourceFile);
if (!currentResourceFile) {
- QList<QtResourceFile *> resourceFiles = currentResourcePrefix->resourceFiles();
+ const auto resourceFiles = currentResourcePrefix->resourceFiles();
if (resourceFiles.count() > 0)
nextResourceFile = resourceFiles.first();
}
@@ -1660,7 +1660,7 @@ void QtResourceEditorDialogPrivate::slotClonePrefix()
QtResourcePrefix *newResourcePrefix = m_qrcManager->insertResourcePrefix(m_currentQrcFile, currentResourcePrefix->prefix(),
currentResourcePrefix->language(), m_qrcManager->nextResourcePrefix(currentResourcePrefix));
if (newResourcePrefix) {
- const QList<QtResourceFile *> files = currentResourcePrefix->resourceFiles();
+ const auto files = currentResourcePrefix->resourceFiles();
for (QtResourceFile *resourceFile : files) {
QString path = resourceFile->path();
QFileInfo fi(path);
@@ -2096,7 +2096,7 @@ void QtResourceEditorDialog::accept()
QStringList newQrcPaths;
QList<QtQrcFileData> currentState;
- const QList<QtQrcFile *> qrcFiles = d_ptr->m_qrcManager->qrcFiles();
+ const auto qrcFiles = d_ptr->m_qrcManager->qrcFiles();
for (QtQrcFile *qrcFile : qrcFiles) {
QtQrcFileData qrcFileData;
d_ptr->m_qrcManager->exportQrcFile(qrcFile, &qrcFileData);
diff --git a/src/designer/src/lib/shared/qtresourcemodel.cpp b/src/designer/src/lib/shared/qtresourcemodel.cpp
index 1586fcf44..fec22a015 100644
--- a/src/designer/src/lib/shared/qtresourcemodel.cpp
+++ b/src/designer/src/lib/shared/qtresourcemodel.cpp
@@ -169,7 +169,7 @@ const QByteArray *QtResourceModelPrivate::createResource(const QString &path, QS
*errorCount = library.failedResources().size();
*contents = resMap.keys();
- if (resMap.empty())
+ if (resMap.isEmpty())
break;
buffer.close();
@@ -279,9 +279,9 @@ void QtResourceModelPrivate::activate(QtResourceSet *resourceSet, const QStringL
m_pathToModified.insert(path, false);
m_pathToContents.insert(path, contents);
newResourceSetChanged = true;
- const QMap<QString, QList<QtResourceSet *> >::iterator itReload = m_pathToResourceSet.find(path);
+ const auto itReload = m_pathToResourceSet.find(path);
if (itReload != m_pathToResourceSet.end()) {
- const QList<QtResourceSet *> resources = itReload.value();
+ const auto resources = itReload.value();
for (QtResourceSet *res : resources) {
if (res != resourceSet) {
m_resourceSetToReload[res] = true;
@@ -292,10 +292,10 @@ void QtResourceModelPrivate::activate(QtResourceSet *resourceSet, const QStringL
}
}
- const QList<const QByteArray *> oldData = m_pathToData.values();
- const QList<const QByteArray *> newData = newPathToData.values();
+ const auto oldData = m_pathToData.values();
+ const auto newData = newPathToData.values();
- QList<const QByteArray *> toDelete;
+ QVector<const QByteArray *> toDelete;
for (const QByteArray *array : oldData) {
if (array && !newData.contains(array))
toDelete.append(array);
@@ -373,7 +373,7 @@ void QtResourceModelPrivate::removeOldPaths(QtResourceSet *resourceSet, const QS
// remove old
for (const QString &oldPath : oldPaths) {
if (!newPaths.contains(oldPath)) {
- const QMap<QString, QList<QtResourceSet *> >::iterator itRemove = m_pathToResourceSet.find(oldPath);
+ const auto itRemove = m_pathToResourceSet.find(oldPath);
if (itRemove != m_pathToResourceSet.end()) {
const int idx = itRemove.value().indexOf(resourceSet);
if (idx >= 0)
@@ -452,7 +452,7 @@ QtResourceModel::QtResourceModel(QObject *parent) :
QtResourceModel::~QtResourceModel()
{
blockSignals(true);
- const QList<QtResourceSet *> resourceList = resourceSets();
+ const auto resourceList = resourceSets();
for (QtResourceSet *rs : resourceList)
removeResourceSet(rs);
blockSignals(false);
@@ -478,11 +478,11 @@ void QtResourceModel::setModified(const QString &path)
return;
d_ptr->m_pathToModified[path] = true;
- QMap<QString, QList<QtResourceSet *> >::const_iterator it = d_ptr->m_pathToResourceSet.constFind(path);
+ const auto it = d_ptr->m_pathToResourceSet.constFind(path);
if (it == d_ptr->m_pathToResourceSet.constEnd())
return;
- const QList<QtResourceSet *> resourceList = it.value();
+ const auto resourceList = it.value();
for (QtResourceSet *rs : resourceList)
d_ptr->m_resourceSetToReload.insert(rs, true);
}
diff --git a/src/designer/src/lib/shared/rcc.cpp b/src/designer/src/lib/shared/rcc.cpp
index b98f17e07..050c6f418 100644
--- a/src/designer/src/lib/shared/rcc.cpp
+++ b/src/designer/src/lib/shared/rcc.cpp
@@ -589,7 +589,7 @@ bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file)
parent->m_children.insert(node, s);
parent = s;
} else {
- parent = parent->m_children[node];
+ parent = *parent->m_children.constFind(node);
}
}
@@ -602,7 +602,7 @@ bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file)
qPrintable(fileName), qPrintable(filename));
}
}
- parent->m_children.insertMulti(filename, s);
+ parent->m_children.insert(filename, s);
return true;
}
@@ -895,12 +895,11 @@ bool RCCResourceLibrary::writeDataStructure()
file->m_childOffset = offset;
//sort by hash value for binary lookup
- QList<RCCFileInfo*> m_children = file->m_children.values();
- std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
+ auto children = file->m_children.values();
+ std::sort(children.begin(), children.end(), qt_rcc_compare_hash);
//write out the actual data now
- for (int i = 0; i < m_children.size(); ++i) {
- RCCFileInfo *child = m_children.at(i);
+ for (RCCFileInfo *child : children) {
++offset;
if (child->m_flags & RCCFileInfo::Directory)
pending.push(child);
@@ -914,12 +913,11 @@ bool RCCResourceLibrary::writeDataStructure()
RCCFileInfo *file = pending.pop();
//sort by hash value for binary lookup
- QList<RCCFileInfo*> m_children = file->m_children.values();
- std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
+ auto children = file->m_children.values();
+ std::sort(children.begin(), children.end(), qt_rcc_compare_hash);
//write out the actual data now
- for (int i = 0; i < m_children.size(); ++i) {
- RCCFileInfo *child = m_children.at(i);
+ for (RCCFileInfo *child : children) {
child->writeDataInfo(*this);
if (child->m_flags & RCCFileInfo::Directory)
pending.push(child);
diff --git a/src/designer/src/lib/shared/richtexteditor.cpp b/src/designer/src/lib/shared/richtexteditor.cpp
index ca2a82b09..666bdd1cb 100644
--- a/src/designer/src/lib/shared/richtexteditor.cpp
+++ b/src/designer/src/lib/shared/richtexteditor.cpp
@@ -131,7 +131,7 @@ QString simplifyRichTextFilter(const QString &in, bool *isPlainTextPtr = nullptr
case QXmlStreamReader::StartElement:
elementCount++;
if (filterElement(reader.name())) {
- const QStringRef name = reader.name();
+ const auto name = reader.name();
QXmlStreamAttributes attributes = reader.attributes();
filterAttributes(name, &attributes, &paragraphAlignmentFound);
writer.writeStartElement(name.toString());
@@ -425,7 +425,7 @@ RichTextEditorToolBar::RichTextEditorToolBar(QDesignerFormEditorInterface *core,
{
// Font size combo box
m_font_size_input->setEditable(false);
- const QList<int> font_sizes = QFontDatabase::standardSizes();
+ const auto font_sizes = QFontDatabase::standardSizes();
for (int font_size : font_sizes)
m_font_size_input->addItem(QString::number(font_size));
diff --git a/src/designer/src/lib/shared/selectsignaldialog.cpp b/src/designer/src/lib/shared/selectsignaldialog.cpp
index 67b988a56..8c2678f1f 100644
--- a/src/designer/src/lib/shared/selectsignaldialog.cpp
+++ b/src/designer/src/lib/shared/selectsignaldialog.cpp
@@ -162,7 +162,7 @@ void SelectSignalDialog::populate(QDesignerFormEditorInterface *core, QObject *o
if (defaultSignal.isEmpty()) {
selectedIndex = m_model->index(0, 0, m_model->index(0, 0, QModelIndex())); // first method
} else {
- const QList<QStandardItem *> items = m_model->findItems(defaultSignal, Qt::MatchExactly | Qt::MatchRecursive, 0);
+ const auto items = m_model->findItems(defaultSignal, Qt::MatchExactly | Qt::MatchRecursive, 0);
if (!items.isEmpty())
selectedIndex = m_model->indexFromItem(items.constFirst());
}
diff --git a/src/designer/src/lib/shared/shared_settings.cpp b/src/designer/src/lib/shared/shared_settings.cpp
index b759555bd..2800e89c5 100644
--- a/src/designer/src/lib/shared/shared_settings.cpp
+++ b/src/designer/src/lib/shared/shared_settings.cpp
@@ -90,7 +90,7 @@ Grid QDesignerSharedSettings::defaultGrid() const
Grid grid;
const QVariantMap defaultGridMap
= m_settings->value(QLatin1String(defaultGridKey), QVariantMap()).toMap();
- if (!defaultGridMap.empty())
+ if (!defaultGridMap.isEmpty())
grid.fromVariantMap(defaultGridMap);
return grid;
}
@@ -103,7 +103,7 @@ void QDesignerSharedSettings::setDefaultGrid(const Grid &grid)
const QStringList &QDesignerSharedSettings::defaultFormTemplatePaths()
{
static QStringList rc;
- if (rc.empty()) {
+ if (rc.isEmpty()) {
// Ensure default form template paths
const QString templatePath = QStringLiteral("/templates");
// home
@@ -300,7 +300,7 @@ QDesignerSharedSettings::DeviceProfileList QDesignerSharedSettings::deviceProfil
{
DeviceProfileList rc;
const QStringList xmls = deviceProfileXml();
- if (xmls.empty())
+ if (xmls.isEmpty())
return rc;
// De-serialize
QString errorMessage;
diff --git a/src/designer/src/lib/shared/shared_settings_p.h b/src/designer/src/lib/shared/shared_settings_p.h
index 65dcf29bc..cd7b32779 100644
--- a/src/designer/src/lib/shared/shared_settings_p.h
+++ b/src/designer/src/lib/shared/shared_settings_p.h
@@ -45,7 +45,7 @@
#include "deviceprofile_p.h"
#include <QtCore/qglobal.h>
-#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -67,7 +67,7 @@ namespace qdesigner_internal {
class QDESIGNER_SHARED_EXPORT QDesignerSharedSettings {
public:
- using DeviceProfileList = QList<DeviceProfile>;
+ using DeviceProfileList = QVector<DeviceProfile>;
explicit QDesignerSharedSettings(QDesignerFormEditorInterface *core);
diff --git a/src/designer/src/lib/shared/signalslotdialog.cpp b/src/designer/src/lib/shared/signalslotdialog.cpp
index 5c0d9e1fe..9b7575177 100644
--- a/src/designer/src/lib/shared/signalslotdialog.cpp
+++ b/src/designer/src/lib/shared/signalslotdialog.cpp
@@ -270,7 +270,7 @@ void SignaturePanel::slotAdd()
newSlot += QString::number(i); // Always add number, Avoid setting 'slot' for first entry
newSlot += QLatin1Char('(');
// check for function name independent of parameters
- if (m_model->findItems(newSlot, Qt::MatchStartsWith, 0).empty()) {
+ if (m_model->findItems(newSlot, Qt::MatchStartsWith, 0).isEmpty()) {
newSlot += QLatin1Char(')');
QStandardItem * item = createEditableItem(newSlot);
m_model->appendRow(item);
@@ -290,13 +290,13 @@ int SignaturePanel::count(const QString &signature) const
void SignaturePanel::slotRemove()
{
const QModelIndexList selectedIndexes = m_listView->selectionModel()->selectedIndexes ();
- if (selectedIndexes.empty())
+ if (selectedIndexes.isEmpty())
return;
closeEditor();
// scroll to previous
- if (const int row = selectedIndexes.front().row())
- m_listView->setCurrentIndex (selectedIndexes.front().sibling(row - 1, 0));
+ if (const int row = selectedIndexes.constFirst().row())
+ m_listView->setCurrentIndex (selectedIndexes.constFirst().sibling(row - 1, 0));
for (int i = selectedIndexes.size() - 1; i >= 0; i--)
qDeleteAll(m_model->takeRow(selectedIndexes[i].row()));
@@ -304,7 +304,7 @@ void SignaturePanel::slotRemove()
void SignaturePanel::slotSelectionChanged(const QItemSelection &selected, const QItemSelection &)
{
- m_removeButton->setEnabled(!selected.indexes().empty());
+ m_removeButton->setEnabled(!selected.indexes().isEmpty());
}
void SignaturePanel::setData(const SignalSlotDialogData &d)
diff --git a/src/designer/src/lib/shared/textpropertyeditor.cpp b/src/designer/src/lib/shared/textpropertyeditor.cpp
index 88e8841b6..e78cb81b4 100644
--- a/src/designer/src/lib/shared/textpropertyeditor.cpp
+++ b/src/designer/src/lib/shared/textpropertyeditor.cpp
@@ -259,7 +259,7 @@ namespace qdesigner_internal {
break;
case ValidationURL: {
static QStringList urlCompletions;
- if (urlCompletions.empty()) {
+ if (urlCompletions.isEmpty()) {
urlCompletions.push_back(QStringLiteral("about:blank"));
urlCompletions.push_back(QStringLiteral("http://"));
urlCompletions.push_back(QStringLiteral("http://www."));
diff --git a/src/designer/src/lib/shared/widgetdatabase.cpp b/src/designer/src/lib/shared/widgetdatabase.cpp
index 5fecd4c98..6b63ac7b4 100644
--- a/src/designer/src/lib/shared/widgetdatabase.cpp
+++ b/src/designer/src/lib/shared/widgetdatabase.cpp
@@ -373,10 +373,8 @@ void WidgetDataBase::loadPlugins()
unsigned replacedPlugins = 0;
unsigned addedPlugins = 0;
unsigned removedPlugins = 0;
- if (!pluginList.empty()) {
- ItemList::const_iterator cend = pluginList.constEnd();
- for (ItemList::const_iterator it = pluginList.constBegin();it != cend; ++it ) {
- QDesignerWidgetDataBaseItemInterface* pluginItem = *it;
+ if (!pluginList.isEmpty()) {
+ for (QDesignerWidgetDataBaseItemInterface *pluginItem : qAsConst(pluginList)) {
const QString pluginName = pluginItem->name();
NameIndexMap::iterator existingIt = existingCustomClasses.find(pluginName);
if (existingIt == existingCustomClasses.end()) {
@@ -399,7 +397,7 @@ void WidgetDataBase::loadPlugins()
}
}
// 4) remove classes that have not been matched. The stored indexes become invalid while deleting.
- if (!existingCustomClasses.empty()) {
+ if (!existingCustomClasses.isEmpty()) {
NameIndexMap::const_iterator cend = existingCustomClasses.constEnd();
for (NameIndexMap::const_iterator it = existingCustomClasses.constBegin();it != cend; ++it ) {
const int index = indexOfClassName(it.key());
@@ -429,10 +427,10 @@ QList<QVariant> WidgetDataBase::defaultPropertyValues(const QString &name)
object = factory->createWidget(name, nullptr);
if (!object) {
qDebug() << "** WARNING Factory failed to create " << name;
- return QList<QVariant>();
+ return {};
}
// Get properties from sheet.
- QList<QVariant> result;
+ QVariantList result;
if (const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_core->extensionManager(), object)) {
const int propertyCount = sheet->count();
for (int i = 0; i < propertyCount; ++i) {
@@ -448,7 +446,7 @@ void WidgetDataBase::grabDefaultPropertyValues()
const int itemCount = count();
for (int i = 0; i < itemCount; ++i) {
QDesignerWidgetDataBaseItemInterface *dbItem = item(i);
- const QList<QVariant> default_prop_values = defaultPropertyValues(dbItem->name());
+ const auto default_prop_values = defaultPropertyValues(dbItem->name());
dbItem->setDefaultPropertyValues(default_prop_values);
}
}
@@ -503,7 +501,7 @@ static inline bool suitableForNewForm(const QString &className)
QStringList WidgetDataBase::formWidgetClasses(const QDesignerFormEditorInterface *core)
{
static QStringList rc;
- if (rc.empty()) {
+ if (rc.isEmpty()) {
const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
const int widgetCount = wdb->count();
for (int i = 0; i < widgetCount; i++) {
diff --git a/src/designer/src/lib/shared/widgetfactory.cpp b/src/designer/src/lib/shared/widgetfactory.cpp
index 14cd72124..c8db16f97 100644
--- a/src/designer/src/lib/shared/widgetfactory.cpp
+++ b/src/designer/src/lib/shared/widgetfactory.cpp
@@ -212,8 +212,7 @@ void WidgetFactory::loadPlugins()
{
m_customFactory.clear();
- const QList<QDesignerCustomWidgetInterface*> &lst =
- m_core->pluginManager()->registeredCustomWidgets();
+ const auto &lst = m_core->pluginManager()->registeredCustomWidgets();
for (QDesignerCustomWidgetInterface *c : lst)
m_customFactory.insert(c->name(), c);
}
diff --git a/src/designer/src/lib/shared/zoomwidget.cpp b/src/designer/src/lib/shared/zoomwidget.cpp
index fef509a39..9670958ce 100644
--- a/src/designer/src/lib/shared/zoomwidget.cpp
+++ b/src/designer/src/lib/shared/zoomwidget.cpp
@@ -43,9 +43,6 @@
QT_BEGIN_NAMESPACE
-using ActionList = QList<QAction *>;
-using GraphicsItemList = QList<QGraphicsItem *>;
-
enum { debugZoomWidget = 0 };
static const int menuZoomList[] = { 100, 25, 50, 75, 125, 150 , 175, 200 };
@@ -77,11 +74,10 @@ int ZoomMenu::zoomOf(const QAction *a)
void ZoomMenu::addActions(QMenu *m)
{
- const ActionList za = m_menuActions->actions();
- const ActionList::const_iterator cend = za.constEnd();
- for (ActionList::const_iterator it = za.constBegin(); it != cend; ++it) {
- m->addAction(*it);
- if (zoomOf(*it) == 100)
+ const auto za = m_menuActions->actions();
+ for (QAction *a : za) {
+ m->addAction(a);
+ if (zoomOf(a) == 100)
m->addSeparator();
}
}
@@ -93,13 +89,13 @@ int ZoomMenu::zoom() const
void ZoomMenu::setZoom(int percent)
{
- const ActionList za = m_menuActions->actions();
- const ActionList::const_iterator cend = za.constEnd();
- for (ActionList::const_iterator it = za.constBegin(); it != cend; ++it)
- if (zoomOf(*it) == percent) {
- (*it)->setChecked(true);
+ const auto za = m_menuActions->actions();
+ for (QAction *a : za) {
+ if (zoomOf(a) == percent) {
+ a->setChecked(true);
return;
}
+ }
}
void ZoomMenu::slotZoomMenu(QAction *a)
@@ -290,7 +286,7 @@ ZoomWidget::ZoomWidget(QWidget *parent) :
void ZoomWidget::setWidget(QWidget *w, Qt::WindowFlags wFlags)
{
if (debugZoomWidget)
- qDebug() << "ZoomWidget::setWidget" << w << bin << wFlags;
+ qDebug() << "ZoomWidget::setWidget" << w << Qt::bin << wFlags;
if (m_proxy) {
scene().removeItem(m_proxy);
@@ -520,7 +516,7 @@ void ZoomWidget::dump() const
{
qDebug() << "ZoomWidget::dump " << geometry() << " Viewport " << viewport()->geometry()
- << "Scroll: " << scrollPosition() << "Matrix: " << matrix() << " SceneRect: " << sceneRect();
+ << "Scroll: " << scrollPosition() << "Transform: " << transform() << " SceneRect: " << sceneRect();
if (m_proxy) {
qDebug() << "Proxy Pos: " << m_proxy->pos() << "Proxy " << m_proxy->size()
<< "\nProxy size hint"
diff --git a/src/designer/src/lib/uilib/abstractformbuilder.cpp b/src/designer/src/lib/uilib/abstractformbuilder.cpp
index b723b7a34..4d39cdb5d 100644
--- a/src/designer/src/lib/uilib/abstractformbuilder.cpp
+++ b/src/designer/src/lib/uilib/abstractformbuilder.cpp
@@ -219,7 +219,7 @@ QWidget *QAbstractFormBuilder::create(DomUI *ui, QWidget *parentWidget)
if (QWidget *widget = create(ui_widget, parentWidget)) {
// Reparent button groups that were actually created to main container for them to be found in the signal/slot part
const ButtonGroupHash &buttonGroups = d->buttonGroups();
- if (!buttonGroups.empty()) {
+ if (!buttonGroups.isEmpty()) {
const ButtonGroupHash::const_iterator cend = buttonGroups.constEnd();
for (ButtonGroupHash::const_iterator it = buttonGroups.constBegin(); it != cend; ++it)
if (it.value().second)
@@ -297,7 +297,7 @@ QWidget *QAbstractFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidge
}
const auto &addActions = ui_widget->elementAddAction();
- if (!addActions.empty()) {
+ if (!addActions.isEmpty()) {
const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
for (DomActionRef *ui_action_ref : addActions) {
const QString name = ui_action_ref->attributeName();
@@ -794,10 +794,10 @@ static inline QString alignmentValue(Qt::Alignment a)
static inline Qt::Alignment alignmentFromDom(const QString &in)
{
- Qt::Alignment rc = nullptr;
+ Qt::Alignment rc;
if (!in.isEmpty()) {
- const QVector<QStringRef> flags = in.splitRef(QLatin1Char('|'));
- for (const QStringRef &f : flags) {
+ const auto flags = in.splitRef(QLatin1Char('|'));
+ for (const auto &f : flags) {
if (f == QStringLiteral("Qt::AlignLeft")) {
rc |= Qt::AlignLeft;
} else if (f == QStringLiteral("Qt::AlignRight")) {
@@ -881,7 +881,7 @@ QLayoutItem *QAbstractFormBuilder::create(DomLayoutItem *ui_layoutItem, QLayout
const DomSpacer *ui_spacer = ui_layoutItem->elementSpacer();
const auto &spacerProperties = ui_spacer->elementProperty();
- if (!spacerProperties.empty()) {
+ if (!spacerProperties.isEmpty()) {
const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
for (DomProperty *p : spacerProperties) {
const QVariant v = toVariant(&QAbstractFormBuilderGadget::staticMetaObject, p); // ### remove me
@@ -959,27 +959,7 @@ QVariant QAbstractFormBuilder::toVariant(const QMetaObject *meta, DomProperty *p
void QAbstractFormBuilder::setupColorGroup(QPalette &palette, QPalette::ColorGroup colorGroup,
DomColorGroup *group)
{
- // old format
- const auto &colors = group->elementColor();
- for (int role = 0; role < colors.size(); ++role) {
- const DomColor *color = colors.at(role);
- const QColor c(color->elementRed(), color->elementGreen(), color->elementBlue());
- palette.setColor(colorGroup, QPalette::ColorRole(role), c);
- }
-
- // new format
- const QMetaEnum colorRole_enum = metaEnum<QAbstractFormBuilderGadget>("colorRole");
-
- const auto colorRoles = group->elementColorRole();
- for (const DomColorRole *colorRole : colorRoles) {
- if (colorRole->hasAttributeRole()) {
- const int r = colorRole_enum.keyToValue(colorRole->attributeRole().toLatin1());
- if (r != -1) {
- const QBrush br = setupBrush(colorRole->elementBrush());
- palette.setBrush(colorGroup, static_cast<QPalette::ColorRole>(r), br);
- }
- }
- }
+ QFormBuilderExtra::setupColorGroup(&palette, colorGroup, group);
}
/*!
@@ -987,26 +967,8 @@ void QAbstractFormBuilder::setupColorGroup(QPalette &palette, QPalette::ColorGro
*/
DomColorGroup *QAbstractFormBuilder::saveColorGroup(const QPalette &palette)
{
-
- const QMetaEnum colorRole_enum = metaEnum<QAbstractFormBuilderGadget>("colorRole");
-
- DomColorGroup *group = new DomColorGroup();
- QVector<DomColorRole *> colorRoles;
-
- const uint mask = palette.resolve();
- for (int role = QPalette::WindowText; role < QPalette::NColorRoles; ++role) {
- if (mask & (1 << role)) {
- const QBrush &br = palette.brush(QPalette::ColorRole(role));
-
- DomColorRole *colorRole = new DomColorRole();
- colorRole->setElementBrush(saveBrush(br));
- colorRole->setAttributeRole(QLatin1String(colorRole_enum.valueToKey(role)));
- colorRoles.append(colorRole);
- }
- }
-
- group->setElementColorRole(colorRoles);
- return group;
+ return QFormBuilderExtra::saveColorGroup(palette,
+ palette.currentColorGroup());
}
/*!
@@ -1014,143 +976,12 @@ DomColorGroup *QAbstractFormBuilder::saveColorGroup(const QPalette &palette)
*/
QBrush QAbstractFormBuilder::setupBrush(DomBrush *brush)
{
- QBrush br;
- if (!brush->hasAttributeBrushStyle())
- return br;
-
- const Qt::BrushStyle style = enumKeyOfObjectToValue<QAbstractFormBuilderGadget, Qt::BrushStyle>("brushStyle",
- brush->attributeBrushStyle().toLatin1().constData());
-
- if (style == Qt::LinearGradientPattern ||
- style == Qt::RadialGradientPattern ||
- style == Qt::ConicalGradientPattern) {
- const QMetaEnum gradientType_enum = metaEnum<QAbstractFormBuilderGadget>("gradientType");
- const QMetaEnum gradientSpread_enum = metaEnum<QAbstractFormBuilderGadget>("gradientSpread");
- const QMetaEnum gradientCoordinate_enum = metaEnum<QAbstractFormBuilderGadget>("gradientCoordinate");
-
- const DomGradient *gradient = brush->elementGradient();
- const QGradient::Type type = enumKeyToValue<QGradient::Type>(gradientType_enum, gradient->attributeType().toLatin1());
-
-
- QGradient *gr = nullptr;
-
- if (type == QGradient::LinearGradient) {
- gr = new QLinearGradient(QPointF(gradient->attributeStartX(), gradient->attributeStartY()),
- QPointF(gradient->attributeEndX(), gradient->attributeEndY()));
- } else if (type == QGradient::RadialGradient) {
- gr = new QRadialGradient(QPointF(gradient->attributeCentralX(), gradient->attributeCentralY()),
- gradient->attributeRadius(),
- QPointF(gradient->attributeFocalX(), gradient->attributeFocalY()));
- } else if (type == QGradient::ConicalGradient) {
- gr = new QConicalGradient(QPointF(gradient->attributeCentralX(), gradient->attributeCentralY()),
- gradient->attributeAngle());
- }
- if (!gr)
- return br;
-
- const QGradient::Spread spread = enumKeyToValue<QGradient::Spread>(gradientSpread_enum, gradient->attributeSpread().toLatin1());
- gr->setSpread(spread);
-
- const QGradient::CoordinateMode coord = enumKeyToValue<QGradient::CoordinateMode>(gradientCoordinate_enum, gradient->attributeCoordinateMode().toLatin1());
- gr->setCoordinateMode(coord);
-
- const auto &stops = gradient->elementGradientStop();
- for (const DomGradientStop *stop : stops) {
- const DomColor *color = stop->elementColor();
- gr->setColorAt(stop->attributePosition(), QColor::fromRgb(color->elementRed(),
- color->elementGreen(), color->elementBlue(), color->attributeAlpha()));
- }
- br = QBrush(*gr);
- delete gr;
- } else if (style == Qt::TexturePattern) {
- const DomProperty *texture = brush->elementTexture();
- if (texture && texture->kind() == DomProperty::Pixmap) {
- br.setTexture(domPropertyToPixmap(texture));
- }
- } else {
- const DomColor *color = brush->elementColor();
- br.setColor(QColor::fromRgb(color->elementRed(),
- color->elementGreen(), color->elementBlue(), color->attributeAlpha()));
- br.setStyle((Qt::BrushStyle)style);
- }
- return br;
+ return QFormBuilderExtra::setupBrush(brush);
}
-/*!
- \internal
-*/
DomBrush *QAbstractFormBuilder::saveBrush(const QBrush &br)
{
- const QMetaEnum brushStyle_enum = metaEnum<QAbstractFormBuilderGadget>("brushStyle");
-
- DomBrush *brush = new DomBrush();
- const Qt::BrushStyle style = br.style();
- brush->setAttributeBrushStyle(QLatin1String(brushStyle_enum.valueToKey(style)));
- if (style == Qt::LinearGradientPattern ||
- style == Qt::RadialGradientPattern ||
- style == Qt::ConicalGradientPattern) {
- const QMetaEnum gradientType_enum = metaEnum<QAbstractFormBuilderGadget>("gradientType");
- const QMetaEnum gradientSpread_enum = metaEnum<QAbstractFormBuilderGadget>("gradientSpread");
- const QMetaEnum gradientCoordinate_enum = metaEnum<QAbstractFormBuilderGadget>("gradientCoordinate");
-
- DomGradient *gradient = new DomGradient();
- const QGradient *gr = br.gradient();
- const QGradient::Type type = gr->type();
- gradient->setAttributeType(QLatin1String(gradientType_enum.valueToKey(type)));
- gradient->setAttributeSpread(QLatin1String(gradientSpread_enum.valueToKey(gr->spread())));
- gradient->setAttributeCoordinateMode(QLatin1String(gradientCoordinate_enum.valueToKey(gr->coordinateMode())));
- QVector<DomGradientStop *> stops;
- const QGradientStops st = gr->stops();
- for (const QGradientStop &pair : st) {
- DomGradientStop *stop = new DomGradientStop();
- stop->setAttributePosition(pair.first);
- DomColor *color = new DomColor();
- color->setElementRed(pair.second.red());
- color->setElementGreen(pair.second.green());
- color->setElementBlue(pair.second.blue());
- color->setAttributeAlpha(pair.second.alpha());
- stop->setElementColor(color);
- stops.append(stop);
- }
- gradient->setElementGradientStop(stops);
- if (type == QGradient::LinearGradient) {
- auto lgr = static_cast<const QLinearGradient *>(gr);
- gradient->setAttributeStartX(lgr->start().x());
- gradient->setAttributeStartY(lgr->start().y());
- gradient->setAttributeEndX(lgr->finalStop().x());
- gradient->setAttributeEndY(lgr->finalStop().y());
- } else if (type == QGradient::RadialGradient) {
- auto rgr = static_cast<const QRadialGradient *>(gr);
- gradient->setAttributeCentralX(rgr->center().x());
- gradient->setAttributeCentralY(rgr->center().y());
- gradient->setAttributeFocalX(rgr->focalPoint().x());
- gradient->setAttributeFocalY(rgr->focalPoint().y());
- gradient->setAttributeRadius(rgr->radius());
- } else if (type == QGradient::ConicalGradient) {
- auto cgr = static_cast<const QConicalGradient *>(gr);
- gradient->setAttributeCentralX(cgr->center().x());
- gradient->setAttributeCentralY(cgr->center().y());
- gradient->setAttributeAngle(cgr->angle());
- }
-
- brush->setElementGradient(gradient);
- } else if (style == Qt::TexturePattern) {
- const QPixmap pixmap = br.texture();
- if (!pixmap.isNull()) {
- DomProperty *p = new DomProperty;
- setPixmapProperty(*p, pixmapPaths(pixmap));
- brush->setElementTexture(p);
- }
- } else {
- const QColor &c = br.color();
- DomColor *color = new DomColor();
- color->setElementRed(c.red());
- color->setElementGreen(c.green());
- color->setElementBlue(c.blue());
- color->setAttributeAlpha(c.alpha());
- brush->setElementColor(color);
- }
- return brush;
+ return QFormBuilderExtra::saveBrush(br);
}
/*!
@@ -1341,7 +1172,7 @@ DomWidget *QAbstractFormBuilder::createDom(QWidget *widget, DomWidget *ui_parent
continue;
if (QMenu *menu = qobject_cast<QMenu *>(childWidget)) {
- const QList<QAction *> actions = menu->parentWidget()->actions();
+ const auto actions = menu->parentWidget()->actions();
const bool found =
std::any_of(actions.cbegin(), actions.cend(),
[menu] (const QAction *a) { return a->menu() == menu; });
@@ -1370,7 +1201,7 @@ DomWidget *QAbstractFormBuilder::createDom(QWidget *widget, DomWidget *ui_parent
// add-action
QVector<DomActionRef *> ui_action_refs;
- const QList<QAction *> &actions = widget->actions();
+ const auto &actions = widget->actions();
ui_action_refs.reserve(actions.size());
for (QAction *action : actions) {
if (DomActionRef *ui_action_ref = createActionRefDom(action)) {
@@ -1621,7 +1452,7 @@ QList<DomProperty*> QAbstractFormBuilder::computeProperties(QObject *obj)
for(int i=0; i < propertyCount; ++i)
properties.insert(meta->property(i).name(), true);
- const QList<QByteArray> propertyNames = properties.keys();
+ const auto propertyNames = properties.keys();
const int propertyNamesCount = propertyNames.size();
for(int i=0; i<propertyNamesCount ; ++i) {
@@ -1761,7 +1592,7 @@ DomButtonGroups *QAbstractFormBuilder::saveButtonGroups(const QWidget *mainConta
{
// Save fst order buttongroup children of maincontainer
const QObjectList &mchildren = mainContainer->children();
- if (mchildren.empty())
+ if (mchildren.isEmpty())
return nullptr;
QVector<DomButtonGroup *> domGroups;
for (QObject *o : mchildren) {
@@ -1769,7 +1600,7 @@ DomButtonGroups *QAbstractFormBuilder::saveButtonGroups(const QWidget *mainConta
if (DomButtonGroup* dg = createDom(bg))
domGroups.push_back(dg);
}
- if (domGroups.empty())
+ if (domGroups.isEmpty())
return nullptr;
DomButtonGroups *rc = new DomButtonGroups;
rc->setElementButtonGroup(domGroups);
@@ -2432,7 +2263,7 @@ void QAbstractFormBuilder::loadComboBoxExtraInfo(DomWidget *ui_widget, QComboBox
static QString buttonGroupName(const DomWidget *ui_widget)
{
const auto &attributes = ui_widget->elementAttribute();
- if (attributes.empty())
+ if (attributes.isEmpty())
return QString();
const QString buttonGroupProperty = QLatin1String(buttonGroupPropertyC);
for (const DomProperty *p : attributes) {
@@ -2653,7 +2484,7 @@ DomActionGroup *QAbstractFormBuilder::createDom(QActionGroup *actionGroup)
QVector<DomAction *> ui_actions;
- const QList<QAction *> &actions = actionGroup->actions();
+ const auto &actions = actionGroup->actions();
ui_actions.reserve(actions.size());
for (QAction *action : actions) {
if (DomAction *ui_action = createDom(action)) {
@@ -2696,6 +2527,8 @@ QMetaEnum QAbstractFormBuilder::toolBarAreaMetaEnum()
return metaEnum<QAbstractFormBuilderGadget>("toolBarArea");
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+
/*!
\internal
Return paths of an icon.
@@ -2720,6 +2553,8 @@ QAbstractFormBuilder::IconPaths QAbstractFormBuilder::pixmapPaths(const QPixmap
return IconPaths();
}
+#endif // < Qt 6
+
/*!
\internal
Set up a DOM property with icon.
@@ -2746,16 +2581,11 @@ void QAbstractFormBuilder::setIconProperty(DomProperty &p, const IconPaths &ip)
void QAbstractFormBuilder::setPixmapProperty(DomProperty &p, const IconPaths &ip) const
{
- DomResourcePixmap *pix = new DomResourcePixmap;
- if (!ip.second.isEmpty())
- pix->setAttributeResource(ip.second);
-
- pix->setText(ip.first);
-
- p.setAttributeName(QFormBuilderStrings::instance().pixmapAttribute);
- p.setElementPixmap(pix);
+ QFormBuilderExtra::setPixmapProperty(&p, ip);
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+
/*!
\internal
Convenience. Return DOM property for icon; 0 if icon.isNull().
@@ -2768,6 +2598,8 @@ DomProperty* QAbstractFormBuilder::iconToDomProperty(const QIcon &icon) const
return nullptr;
}
+#endif // < Qt 6
+
/*!
\internal
\since 4.4
@@ -2819,6 +2651,8 @@ const DomResourcePixmap *QAbstractFormBuilder::domPixmap(const DomProperty* p) {
return nullptr;
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+
/*!
\internal
Create icon from DOM.
@@ -2873,6 +2707,8 @@ QPixmap QAbstractFormBuilder::domPropertyToPixmap(const DomProperty* p)
return QPixmap();
}
+#endif // < Qt 6
+
/*!
\fn void QAbstractFormBuilder::createConnections ( DomConnections *, QWidget * )
\internal
diff --git a/src/designer/src/lib/uilib/abstractformbuilder.h b/src/designer/src/lib/uilib/abstractformbuilder.h
index 486359099..fa6449c30 100644
--- a/src/designer/src/lib/uilib/abstractformbuilder.h
+++ b/src/designer/src/lib/uilib/abstractformbuilder.h
@@ -243,17 +243,20 @@ protected:
// A Pair of icon path/qrc path.
using IconPaths = QPair<QString, QString>;
- IconPaths iconPaths(const QIcon &) const;
- IconPaths pixmapPaths(const QPixmap &) const;
void setIconProperty(DomProperty &, const IconPaths &) const;
void setPixmapProperty(DomProperty &, const IconPaths &) const;
- DomProperty* iconToDomProperty(const QIcon &) const;
static const DomResourcePixmap *domPixmap(const DomProperty* p);
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ IconPaths iconPaths(const QIcon &) const;
+ IconPaths pixmapPaths(const QPixmap &) const;
+ DomProperty* iconToDomProperty(const QIcon &) const;
QIcon domPropertyToIcon(const DomResourcePixmap *);
QIcon domPropertyToIcon(const DomProperty* p);
QPixmap domPropertyToPixmap(const DomResourcePixmap* p);
QPixmap domPropertyToPixmap(const DomProperty* p);
+#endif
private:
//
diff --git a/src/designer/src/lib/uilib/formbuilder.cpp b/src/designer/src/lib/uilib/formbuilder.cpp
index 31bfdfde4..4230e27f7 100644
--- a/src/designer/src/lib/uilib/formbuilder.cpp
+++ b/src/designer/src/lib/uilib/formbuilder.cpp
@@ -517,7 +517,7 @@ QList<QDesignerCustomWidgetInterface*> QFormBuilder::customWidgets() const
void QFormBuilder::applyProperties(QObject *o, const QList<DomProperty*> &properties)
{
- if (properties.empty())
+ if (properties.isEmpty())
return;
const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
diff --git a/src/designer/src/lib/uilib/formbuilderextra.cpp b/src/designer/src/lib/uilib/formbuilderextra.cpp
index 01d79c557..8dfb1b479 100644
--- a/src/designer/src/lib/uilib/formbuilderextra.cpp
+++ b/src/designer/src/lib/uilib/formbuilderextra.cpp
@@ -50,6 +50,7 @@
#include "formbuilderextra_p.h"
#include "abstractformbuilder.h"
+#include "properties_p.h"
#include "resourcebuilder_p.h"
#include "textbuilder_p.h"
#include "ui4_p.h"
@@ -206,7 +207,7 @@ bool QFormBuilderExtra::applyPropertyInternally(QObject *o, const QString &prope
void QFormBuilderExtra::applyInternalProperties() const
{
- if (m_buddies.empty())
+ if (m_buddies.isEmpty())
return;
const BuddyHash::const_iterator cend = m_buddies.constEnd();
@@ -222,7 +223,7 @@ bool QFormBuilderExtra::applyBuddy(const QString &buddyName, BuddyMode applyMode
}
const QWidgetList widgets = label->topLevelWidget()->findChildren<QWidget*>(buddyName);
- if (widgets.empty()) {
+ if (widgets.isEmpty()) {
label->setBuddy(nullptr);
return false;
}
@@ -385,8 +386,8 @@ inline bool parsePerCellProperty(Layout *l, int count, void (Layout::*setter)(in
clearPerCellValue(l, count, setter, defaultValue);
return true;
}
- const QVector<QStringRef> list = s.splitRef(QLatin1Char(','));
- if (list.empty()) {
+ const auto list = s.splitRef(QLatin1Char(','));
+ if (list.isEmpty()) {
clearPerCellValue(l, count, setter, defaultValue);
return true;
}
@@ -511,6 +512,234 @@ void QFormBuilderExtra::clearGridLayoutColumnMinimumWidth(QGridLayout *grid)
clearPerCellValue(grid, grid->columnCount(), &QGridLayout::setColumnMinimumWidth);
}
+void QFormBuilderExtra::setPixmapProperty(DomProperty *p, const QPair<QString, QString> &ip)
+{
+ DomResourcePixmap *pix = new DomResourcePixmap;
+ if (!ip.second.isEmpty())
+ pix->setAttributeResource(ip.second);
+
+ pix->setText(ip.first);
+
+ p->setAttributeName(QFormBuilderStrings::instance().pixmapAttribute);
+ p->setElementPixmap(pix);
+}
+
+void QFormBuilderExtra::setupColorGroup(QPalette *palette, QPalette::ColorGroup colorGroup,
+ const DomColorGroup *group)
+{
+ // old format
+ const auto &colors = group->elementColor();
+ for (int role = 0; role < colors.size(); ++role) {
+ const DomColor *color = colors.at(role);
+ const QColor c(color->elementRed(), color->elementGreen(), color->elementBlue());
+ palette->setColor(colorGroup, QPalette::ColorRole(role), c);
+ }
+
+ // new format
+ const QMetaEnum colorRole_enum = metaEnum<QAbstractFormBuilderGadget>("colorRole");
+
+ const auto colorRoles = group->elementColorRole();
+ for (const DomColorRole *colorRole : colorRoles) {
+ if (colorRole->hasAttributeRole()) {
+ const int r = colorRole_enum.keyToValue(colorRole->attributeRole().toLatin1());
+ if (r != -1) {
+ const QBrush br = setupBrush(colorRole->elementBrush());
+ palette->setBrush(colorGroup, static_cast<QPalette::ColorRole>(r), br);
+ }
+ }
+ }
+}
+
+DomColorGroup *QFormBuilderExtra::saveColorGroup(const QPalette &palette,
+ QPalette::ColorGroup colorGroup)
+{
+
+ const QMetaEnum colorRole_enum = metaEnum<QAbstractFormBuilderGadget>("colorRole");
+
+ DomColorGroup *group = new DomColorGroup();
+ QVector<DomColorRole *> colorRoles;
+
+ const uint mask = palette.resolve();
+ for (int role = QPalette::WindowText; role < QPalette::NColorRoles; ++role) {
+ if (mask & (1 << role)) {
+ const QBrush &br = palette.brush(colorGroup, QPalette::ColorRole(role));
+
+ DomColorRole *colorRole = new DomColorRole();
+ colorRole->setElementBrush(saveBrush(br));
+ colorRole->setAttributeRole(QLatin1String(colorRole_enum.valueToKey(role)));
+ colorRoles.append(colorRole);
+ }
+ }
+
+ group->setElementColorRole(colorRoles);
+ return group;
+}
+
+DomPalette *QFormBuilderExtra::savePalette(const QPalette &palette)
+{
+ DomPalette *dom = new DomPalette();
+ dom->setElementActive(QFormBuilderExtra::saveColorGroup(palette, QPalette::Active));
+ dom->setElementInactive(QFormBuilderExtra::saveColorGroup(palette, QPalette::Inactive));
+ dom->setElementDisabled(QFormBuilderExtra::saveColorGroup(palette, QPalette::Disabled));
+
+ return dom;
+}
+
+QPalette QFormBuilderExtra::loadPalette(const DomPalette *dom)
+{
+ QPalette palette;
+
+ if (dom->elementActive())
+ QFormBuilderExtra::setupColorGroup(&palette, QPalette::Active, dom->elementActive());
+
+ if (dom->elementInactive())
+ QFormBuilderExtra::setupColorGroup(&palette, QPalette::Inactive, dom->elementInactive());
+
+ if (dom->elementDisabled())
+ QFormBuilderExtra::setupColorGroup(&palette, QPalette::Disabled, dom->elementDisabled());
+
+ palette.setCurrentColorGroup(QPalette::Active);
+ return palette;
+}
+
+QBrush QFormBuilderExtra::setupBrush(const DomBrush *brush)
+{
+ QBrush br;
+ if (!brush->hasAttributeBrushStyle())
+ return br;
+
+ const Qt::BrushStyle style = enumKeyOfObjectToValue<QAbstractFormBuilderGadget, Qt::BrushStyle>("brushStyle",
+ brush->attributeBrushStyle().toLatin1().constData());
+
+ if (style == Qt::LinearGradientPattern ||
+ style == Qt::RadialGradientPattern ||
+ style == Qt::ConicalGradientPattern) {
+ const QMetaEnum gradientType_enum = metaEnum<QAbstractFormBuilderGadget>("gradientType");
+ const QMetaEnum gradientSpread_enum = metaEnum<QAbstractFormBuilderGadget>("gradientSpread");
+ const QMetaEnum gradientCoordinate_enum = metaEnum<QAbstractFormBuilderGadget>("gradientCoordinate");
+
+ const DomGradient *gradient = brush->elementGradient();
+ const QGradient::Type type = enumKeyToValue<QGradient::Type>(gradientType_enum, gradient->attributeType().toLatin1());
+
+
+ QGradient *gr = nullptr;
+
+ if (type == QGradient::LinearGradient) {
+ gr = new QLinearGradient(QPointF(gradient->attributeStartX(), gradient->attributeStartY()),
+ QPointF(gradient->attributeEndX(), gradient->attributeEndY()));
+ } else if (type == QGradient::RadialGradient) {
+ gr = new QRadialGradient(QPointF(gradient->attributeCentralX(), gradient->attributeCentralY()),
+ gradient->attributeRadius(),
+ QPointF(gradient->attributeFocalX(), gradient->attributeFocalY()));
+ } else if (type == QGradient::ConicalGradient) {
+ gr = new QConicalGradient(QPointF(gradient->attributeCentralX(), gradient->attributeCentralY()),
+ gradient->attributeAngle());
+ }
+ if (!gr)
+ return br;
+
+ const QGradient::Spread spread = enumKeyToValue<QGradient::Spread>(gradientSpread_enum, gradient->attributeSpread().toLatin1());
+ gr->setSpread(spread);
+
+ const QGradient::CoordinateMode coord = enumKeyToValue<QGradient::CoordinateMode>(gradientCoordinate_enum, gradient->attributeCoordinateMode().toLatin1());
+ gr->setCoordinateMode(coord);
+
+ const auto &stops = gradient->elementGradientStop();
+ for (const DomGradientStop *stop : stops) {
+ const DomColor *color = stop->elementColor();
+ gr->setColorAt(stop->attributePosition(), QColor::fromRgb(color->elementRed(),
+ color->elementGreen(), color->elementBlue(), color->attributeAlpha()));
+ }
+ br = QBrush(*gr);
+ delete gr;
+ } else if (style == Qt::TexturePattern) {
+ const DomProperty *texture = brush->elementTexture();
+ if (texture && texture->kind() == DomProperty::Pixmap) {
+ br.setTexture({});
+ }
+ } else {
+ const DomColor *color = brush->elementColor();
+ br.setColor(QColor::fromRgb(color->elementRed(),
+ color->elementGreen(), color->elementBlue(), color->attributeAlpha()));
+ br.setStyle((Qt::BrushStyle)style);
+ }
+ return br;
+}
+
+DomBrush *QFormBuilderExtra::saveBrush(const QBrush &br)
+{
+ const QMetaEnum brushStyle_enum = metaEnum<QAbstractFormBuilderGadget>("brushStyle");
+
+ DomBrush *brush = new DomBrush();
+ const Qt::BrushStyle style = br.style();
+ brush->setAttributeBrushStyle(QLatin1String(brushStyle_enum.valueToKey(style)));
+ if (style == Qt::LinearGradientPattern ||
+ style == Qt::RadialGradientPattern ||
+ style == Qt::ConicalGradientPattern) {
+ const QMetaEnum gradientType_enum = metaEnum<QAbstractFormBuilderGadget>("gradientType");
+ const QMetaEnum gradientSpread_enum = metaEnum<QAbstractFormBuilderGadget>("gradientSpread");
+ const QMetaEnum gradientCoordinate_enum = metaEnum<QAbstractFormBuilderGadget>("gradientCoordinate");
+
+ DomGradient *gradient = new DomGradient();
+ const QGradient *gr = br.gradient();
+ const QGradient::Type type = gr->type();
+ gradient->setAttributeType(QLatin1String(gradientType_enum.valueToKey(type)));
+ gradient->setAttributeSpread(QLatin1String(gradientSpread_enum.valueToKey(gr->spread())));
+ gradient->setAttributeCoordinateMode(QLatin1String(gradientCoordinate_enum.valueToKey(gr->coordinateMode())));
+ QVector<DomGradientStop *> stops;
+ const QGradientStops st = gr->stops();
+ for (const QGradientStop &pair : st) {
+ DomGradientStop *stop = new DomGradientStop();
+ stop->setAttributePosition(pair.first);
+ DomColor *color = new DomColor();
+ color->setElementRed(pair.second.red());
+ color->setElementGreen(pair.second.green());
+ color->setElementBlue(pair.second.blue());
+ color->setAttributeAlpha(pair.second.alpha());
+ stop->setElementColor(color);
+ stops.append(stop);
+ }
+ gradient->setElementGradientStop(stops);
+ if (type == QGradient::LinearGradient) {
+ auto lgr = static_cast<const QLinearGradient *>(gr);
+ gradient->setAttributeStartX(lgr->start().x());
+ gradient->setAttributeStartY(lgr->start().y());
+ gradient->setAttributeEndX(lgr->finalStop().x());
+ gradient->setAttributeEndY(lgr->finalStop().y());
+ } else if (type == QGradient::RadialGradient) {
+ auto rgr = static_cast<const QRadialGradient *>(gr);
+ gradient->setAttributeCentralX(rgr->center().x());
+ gradient->setAttributeCentralY(rgr->center().y());
+ gradient->setAttributeFocalX(rgr->focalPoint().x());
+ gradient->setAttributeFocalY(rgr->focalPoint().y());
+ gradient->setAttributeRadius(rgr->radius());
+ } else if (type == QGradient::ConicalGradient) {
+ auto cgr = static_cast<const QConicalGradient *>(gr);
+ gradient->setAttributeCentralX(cgr->center().x());
+ gradient->setAttributeCentralY(cgr->center().y());
+ gradient->setAttributeAngle(cgr->angle());
+ }
+
+ brush->setElementGradient(gradient);
+ } else if (style == Qt::TexturePattern) {
+ const QPixmap pixmap = br.texture();
+ if (!pixmap.isNull()) {
+ DomProperty *p = new DomProperty;
+ QFormBuilderExtra::setPixmapProperty(p, {});
+ brush->setElementTexture(p);
+ }
+ } else {
+ const QColor &c = br.color();
+ DomColor *color = new DomColor();
+ color->setElementRed(c.red());
+ color->setElementGreen(c.green());
+ color->setElementBlue(c.blue());
+ color->setAttributeAlpha(c.alpha());
+ brush->setElementColor(color);
+ }
+ return brush;
+}
+
// ------------ QFormBuilderStrings
QFormBuilderStrings::QFormBuilderStrings() :
@@ -575,7 +804,8 @@ QFormBuilderStrings::QFormBuilderStrings() :
whatsThisAttribute));
// Note: this skips the first item!
- QList<TextRoleNName>::const_iterator it = itemTextRoles.constBegin(), end = itemTextRoles.constEnd();
+ auto it = itemTextRoles.constBegin();
+ const auto end = itemTextRoles.constEnd();
while (++it != end)
treeItemTextRoleHash.insert(it->second, it->first);
}
diff --git a/src/designer/src/lib/uilib/formbuilderextra_p.h b/src/designer/src/lib/uilib/formbuilderextra_p.h
index 54fbfbe66..b0239f6b1 100644
--- a/src/designer/src/lib/uilib/formbuilderextra_p.h
+++ b/src/designer/src/lib/uilib/formbuilderextra_p.h
@@ -69,6 +69,7 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qmap.h>
#include <QtCore/qdir.h>
+#include <QtGui/qpalette.h>
QT_BEGIN_NAMESPACE
@@ -89,9 +90,13 @@ namespace QFormInternal
{
#endif
+class DomBrush;
class DomButtonGroups;
class DomButtonGroup;
+class DomColorGroup;
class DomCustomWidget;
+class DomPalette;
+class DomProperty;
class DomUI;
class QAbstractFormBuilder;
@@ -175,6 +180,16 @@ public:
static bool setGridLayoutColumnMinimumWidth(const QString &, QGridLayout *);
static void clearGridLayoutColumnMinimumWidth(QGridLayout *);
+ static void setPixmapProperty(DomProperty *p, const QPair<QString, QString> &ip);
+ static QPalette loadPalette(const DomPalette *dom);
+ static void setupColorGroup(QPalette *palette, QPalette::ColorGroup colorGroup,
+ const DomColorGroup *group);
+ static DomColorGroup *saveColorGroup(const QPalette &palette,
+ QPalette::ColorGroup colorGroup);
+ static DomPalette *savePalette(const QPalette &palette);
+ static QBrush setupBrush(const DomBrush *brush);
+ static DomBrush *saveBrush(const QBrush &br);
+
QStringList m_pluginPaths;
QMap<QString, QDesignerCustomWidgetInterface*> m_customWidgets;
diff --git a/src/designer/src/lib/uilib/ui4.cpp b/src/designer/src/lib/uilib/ui4.cpp
index 879426b0d..bc58c202b 100644
--- a/src/designer/src/lib/uilib/ui4.cpp
+++ b/src/designer/src/lib/uilib/ui4.cpp
@@ -81,7 +81,7 @@ void DomUI::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("version")) {
setAttributeVersion(attribute.value().toString());
continue;
@@ -116,7 +116,7 @@ void DomUI::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("author"), Qt::CaseInsensitive)) {
setElementAuthor(reader.readElementText());
continue;
@@ -603,7 +603,7 @@ void DomIncludes::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("include"), Qt::CaseInsensitive)) {
auto *v = new DomInclude();
v->read(reader);
@@ -643,7 +643,7 @@ void DomInclude::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("location")) {
setAttributeLocation(attribute.value().toString());
continue;
@@ -658,7 +658,7 @@ void DomInclude::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -700,7 +700,7 @@ void DomResources::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -711,7 +711,7 @@ void DomResources::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("include"), Qt::CaseInsensitive)) {
auto *v = new DomResource();
v->read(reader);
@@ -754,7 +754,7 @@ void DomResource::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("location")) {
setAttributeLocation(attribute.value().toString());
continue;
@@ -765,7 +765,7 @@ void DomResource::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -803,7 +803,7 @@ void DomActionGroup::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -814,7 +814,7 @@ void DomActionGroup::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("action"), Qt::CaseInsensitive)) {
auto *v = new DomAction();
v->read(reader);
@@ -908,7 +908,7 @@ void DomAction::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -923,7 +923,7 @@ void DomAction::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -984,7 +984,7 @@ void DomActionRef::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -995,7 +995,7 @@ void DomActionRef::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -1029,7 +1029,7 @@ void DomButtonGroup::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -1040,7 +1040,7 @@ void DomButtonGroup::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -1103,7 +1103,7 @@ void DomButtonGroups::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("buttongroup"), Qt::CaseInsensitive)) {
auto *v = new DomButtonGroup();
v->read(reader);
@@ -1148,7 +1148,7 @@ void DomCustomWidgets::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("customwidget"), Qt::CaseInsensitive)) {
auto *v = new DomCustomWidget();
v->read(reader);
@@ -1188,7 +1188,7 @@ void DomHeader::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("location")) {
setAttributeLocation(attribute.value().toString());
continue;
@@ -1199,7 +1199,7 @@ void DomHeader::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -1241,7 +1241,7 @@ void DomCustomWidget::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("class"), Qt::CaseInsensitive)) {
setElementClass(reader.readElementText());
continue;
@@ -1495,7 +1495,7 @@ void DomLayoutDefault::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("spacing")) {
setAttributeSpacing(attribute.value().toInt());
continue;
@@ -1510,7 +1510,7 @@ void DomLayoutDefault::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -1541,7 +1541,7 @@ void DomLayoutFunction::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("spacing")) {
setAttributeSpacing(attribute.value().toString());
continue;
@@ -1556,7 +1556,7 @@ void DomLayoutFunction::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -1591,7 +1591,7 @@ void DomTabStops::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("tabstop"), Qt::CaseInsensitive)) {
m_tabStop.append(reader.readElementText());
continue;
@@ -1637,7 +1637,7 @@ void DomLayout::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("class")) {
setAttributeClass(attribute.value().toString());
continue;
@@ -1672,7 +1672,7 @@ void DomLayout::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -1781,7 +1781,7 @@ void DomLayoutItem::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("row")) {
setAttributeRow(attribute.value().toInt());
continue;
@@ -1808,7 +1808,7 @@ void DomLayoutItem::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("widget"), Qt::CaseInsensitive)) {
auto *v = new DomWidget();
v->read(reader);
@@ -1932,7 +1932,7 @@ void DomRow::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -1977,7 +1977,7 @@ void DomColumn::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -2023,7 +2023,7 @@ void DomItem::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("row")) {
setAttributeRow(attribute.value().toInt());
continue;
@@ -2038,7 +2038,7 @@ void DomItem::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -2123,7 +2123,7 @@ void DomWidget::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("class")) {
setAttributeClass(attribute.value().toString());
continue;
@@ -2142,7 +2142,7 @@ void DomWidget::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("class"), Qt::CaseInsensitive)) {
m_class.append(reader.readElementText());
continue;
@@ -2366,7 +2366,7 @@ void DomSpacer::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -2377,7 +2377,7 @@ void DomSpacer::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -2420,7 +2420,7 @@ void DomColor::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("alpha")) {
setAttributeAlpha(attribute.value().toInt());
continue;
@@ -2431,7 +2431,7 @@ void DomColor::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("red"), Qt::CaseInsensitive)) {
setElementRed(reader.readElementText().toInt());
continue;
@@ -2516,7 +2516,7 @@ void DomGradientStop::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("position")) {
setAttributePosition(attribute.value().toDouble());
continue;
@@ -2527,7 +2527,7 @@ void DomGradientStop::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
auto *v = new DomColor();
v->read(reader);
@@ -2590,7 +2590,7 @@ void DomGradient::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("startx")) {
setAttributeStartX(attribute.value().toDouble());
continue;
@@ -2649,7 +2649,7 @@ void DomGradient::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("gradientstop"), Qt::CaseInsensitive)) {
auto *v = new DomGradientStop();
v->read(reader);
@@ -2746,7 +2746,7 @@ void DomBrush::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("brushstyle")) {
setAttributeBrushStyle(attribute.value().toString());
continue;
@@ -2757,7 +2757,7 @@ void DomBrush::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
auto *v = new DomColor();
v->read(reader);
@@ -2867,7 +2867,7 @@ void DomColorRole::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("role")) {
setAttributeRole(attribute.value().toString());
continue;
@@ -2878,7 +2878,7 @@ void DomColorRole::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("brush"), Qt::CaseInsensitive)) {
auto *v = new DomBrush();
v->read(reader);
@@ -2944,7 +2944,7 @@ void DomColorGroup::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("colorrole"), Qt::CaseInsensitive)) {
auto *v = new DomColorRole();
v->read(reader);
@@ -3005,7 +3005,7 @@ void DomPalette::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("active"), Qt::CaseInsensitive)) {
auto *v = new DomColorGroup();
v->read(reader);
@@ -3124,7 +3124,7 @@ void DomFont::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("family"), Qt::CaseInsensitive)) {
setElementFamily(reader.readElementText());
continue;
@@ -3330,7 +3330,7 @@ void DomPoint::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
setElementX(reader.readElementText().toInt());
continue;
@@ -3392,7 +3392,7 @@ void DomRect::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
setElementX(reader.readElementText().toInt());
continue;
@@ -3489,7 +3489,7 @@ void DomLocale::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("language")) {
setAttributeLanguage(attribute.value().toString());
continue;
@@ -3504,7 +3504,7 @@ void DomLocale::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -3535,7 +3535,7 @@ void DomSizePolicy::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("hsizetype")) {
setAttributeHSizeType(attribute.value().toString());
continue;
@@ -3550,7 +3550,7 @@ void DomSizePolicy::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("hsizetype"), Qt::CaseInsensitive)) {
setElementHSizeType(reader.readElementText().toInt());
continue;
@@ -3654,7 +3654,7 @@ void DomSize::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("width"), Qt::CaseInsensitive)) {
setElementWidth(reader.readElementText().toInt());
continue;
@@ -3716,7 +3716,7 @@ void DomDate::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("year"), Qt::CaseInsensitive)) {
setElementYear(reader.readElementText().toInt());
continue;
@@ -3796,7 +3796,7 @@ void DomTime::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("hour"), Qt::CaseInsensitive)) {
setElementHour(reader.readElementText().toInt());
continue;
@@ -3876,7 +3876,7 @@ void DomDateTime::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("hour"), Qt::CaseInsensitive)) {
setElementHour(reader.readElementText().toInt());
continue;
@@ -4012,7 +4012,7 @@ void DomStringList::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("notr")) {
setAttributeNotr(attribute.value().toString());
continue;
@@ -4035,7 +4035,7 @@ void DomStringList::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
m_string.append(reader.readElementText());
continue;
@@ -4085,7 +4085,7 @@ void DomResourcePixmap::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("resource")) {
setAttributeResource(attribute.value().toString());
continue;
@@ -4100,7 +4100,7 @@ void DomResourcePixmap::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -4148,7 +4148,7 @@ void DomResourceIcon::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("theme")) {
setAttributeTheme(attribute.value().toString());
continue;
@@ -4163,7 +4163,7 @@ void DomResourceIcon::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("normaloff"), Qt::CaseInsensitive)) {
auto *v = new DomResourcePixmap();
v->read(reader);
@@ -4449,7 +4449,7 @@ void DomString::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("notr")) {
setAttributeNotr(attribute.value().toString());
continue;
@@ -4472,7 +4472,7 @@ void DomString::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -4517,7 +4517,7 @@ void DomPointF::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
setElementX(reader.readElementText().toDouble());
continue;
@@ -4579,7 +4579,7 @@ void DomRectF::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
setElementX(reader.readElementText().toDouble());
continue;
@@ -4677,7 +4677,7 @@ void DomSizeF::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("width"), Qt::CaseInsensitive)) {
setElementWidth(reader.readElementText().toDouble());
continue;
@@ -4739,7 +4739,7 @@ void DomChar::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("unicode"), Qt::CaseInsensitive)) {
setElementUnicode(reader.readElementText().toInt());
continue;
@@ -4786,7 +4786,7 @@ void DomUrl::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
auto *v = new DomString();
v->read(reader);
@@ -4921,7 +4921,7 @@ void DomProperty::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -4936,7 +4936,7 @@ void DomProperty::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("bool"), Qt::CaseInsensitive)) {
setElementBool(reader.readElementText());
continue;
@@ -5681,7 +5681,7 @@ void DomConnections::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("connection"), Qt::CaseInsensitive)) {
auto *v = new DomConnection();
v->read(reader);
@@ -5725,7 +5725,7 @@ void DomConnection::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("sender"), Qt::CaseInsensitive)) {
setElementSender(reader.readElementText());
continue;
@@ -5858,7 +5858,7 @@ void DomConnectionHints::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("hint"), Qt::CaseInsensitive)) {
auto *v = new DomConnectionHint();
v->read(reader);
@@ -5898,7 +5898,7 @@ void DomConnectionHint::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("type")) {
setAttributeType(attribute.value().toString());
continue;
@@ -5909,7 +5909,7 @@ void DomConnectionHint::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
setElementX(reader.readElementText().toInt());
continue;
@@ -5978,7 +5978,7 @@ void DomDesignerData::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
auto *v = new DomProperty();
v->read(reader);
@@ -6023,7 +6023,7 @@ void DomSlots::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("signal"), Qt::CaseInsensitive)) {
m_signal.append(reader.readElementText());
continue;
@@ -6081,7 +6081,7 @@ void DomPropertySpecifications::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
if (!tag.compare(QLatin1String("tooltip"), Qt::CaseInsensitive)) {
auto *v = new DomPropertyToolTip();
v->read(reader);
@@ -6136,7 +6136,7 @@ void DomPropertyToolTip::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -6147,7 +6147,7 @@ void DomPropertyToolTip::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -6175,7 +6175,7 @@ void DomStringPropertySpecification::read(QXmlStreamReader &reader)
{
const QXmlStreamAttributes &attributes = reader.attributes();
for (const QXmlStreamAttribute &attribute : attributes) {
- const QStringRef name = attribute.name();
+ const auto name = attribute.name();
if (name == QLatin1String("name")) {
setAttributeName(attribute.value().toString());
continue;
@@ -6194,7 +6194,7 @@ void DomStringPropertySpecification::read(QXmlStreamReader &reader)
while (!reader.hasError()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement : {
- const QStringRef tag = reader.name();
+ const auto tag = reader.name();
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
diff --git a/src/designer/src/uitools/quiloader.cpp b/src/designer/src/uitools/quiloader.cpp
index e5f157fb1..d1d4c5a73 100644
--- a/src/designer/src/uitools/quiloader.cpp
+++ b/src/designer/src/uitools/quiloader.cpp
@@ -242,7 +242,7 @@ public:
bool eventFilter(QObject *o, QEvent *event) override
{
if (event->type() == QEvent::LanguageChange) {
- const QList<QByteArray> &dynamicPropertyNames = o->dynamicPropertyNames();
+ const auto &dynamicPropertyNames = o->dynamicPropertyNames();
for (const QByteArray &prop : dynamicPropertyNames) {
if (prop.startsWith(PROP_GENERIC_PREFIX)) {
const QByteArray propName = prop.mid(sizeof(PROP_GENERIC_PREFIX) - 1);
@@ -438,7 +438,7 @@ void FormBuilderPrivate::applyProperties(QObject *o, const QList<DomProperty*> &
if (!m_trwatch)
m_trwatch = new TranslationWatcher(o, m_class, m_idBased);
- if (properties.empty())
+ if (properties.isEmpty())
return;
// Unlike string item roles, string properties are not loaded via the textBuilder
diff --git a/src/distancefieldgenerator/distancefieldgenerator.pro b/src/distancefieldgenerator/distancefieldgenerator.pro
index c37ca6888..d73f4ddea 100644
--- a/src/distancefieldgenerator/distancefieldgenerator.pro
+++ b/src/distancefieldgenerator/distancefieldgenerator.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(distancefieldgenerator))
+
TARGET = qdistancefieldgenerator
QT += gui widgets gui-private core-private quick-private
diff --git a/src/distancefieldgenerator/distancefieldmodel.cpp b/src/distancefieldgenerator/distancefieldmodel.cpp
index aebd86140..e529e65ba 100644
--- a/src/distancefieldgenerator/distancefieldmodel.cpp
+++ b/src/distancefieldgenerator/distancefieldmodel.cpp
@@ -183,7 +183,7 @@ void DistanceFieldModel::addDistanceField(const QImage &distanceField,
if (ucs4 != 0) {
UnicodeRange range = unicodeRangeForUcs4(ucs4);
- m_glyphsPerUnicodeRange.insertMulti(range, glyphId);
+ m_glyphsPerUnicodeRange.insert(range, glyphId);
m_glyphsPerUcs4.insert(ucs4, glyphId);
}
diff --git a/src/distancefieldgenerator/distancefieldmodel.h b/src/distancefieldgenerator/distancefieldmodel.h
index b866e5e6a..5c71a20ab 100644
--- a/src/distancefieldgenerator/distancefieldmodel.h
+++ b/src/distancefieldgenerator/distancefieldmodel.h
@@ -31,6 +31,7 @@
#include <QAbstractListModel>
#include <QRawFont>
+#include <QtGui/qpainterpath.h>
#include <QtGui/private/qtextengine_p.h>
#include <QMultiHash>
#include <QScopedPointer>
diff --git a/src/kmap2qmap/kmap2qmap.pro b/src/kmap2qmap/kmap2qmap.pro
index d08ec6bb4..320c6a290 100644
--- a/src/kmap2qmap/kmap2qmap.pro
+++ b/src/kmap2qmap/kmap2qmap.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(kmap2qmap))
+
QT = core input_support-private
CONFIG += console
diff --git a/src/kmap2qmap/main.cpp b/src/kmap2qmap/main.cpp
index 0cff817c5..0f18166bd 100644
--- a/src/kmap2qmap/main.cpp
+++ b/src/kmap2qmap/main.cpp
@@ -496,27 +496,27 @@ bool KeymapParser::generateHeader(QFile *f)
{
QTextStream ts(f);
- ts << "#ifndef QEVDEVKEYBOARDHANDLER_DEFAULTMAP_H" << endl;
- ts << "#define QEVDEVKEYBOARDHANDLER_DEFAULTMAP_H" << endl << endl;
+ ts << "#ifndef QEVDEVKEYBOARDHANDLER_DEFAULTMAP_H" << Qt::endl;
+ ts << "#define QEVDEVKEYBOARDHANDLER_DEFAULTMAP_H" << Qt::endl << Qt::endl;
- ts << "const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {" << endl;
+ ts << "const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {" << Qt::endl;
for (int i = 0; i < m_keymap.size(); ++i) {
const QEvdevKeyboardMap::Mapping &m = m_keymap.at(i);
ts << QString::asprintf(" { %3d, 0x%04x, 0x%08x, 0x%02x, 0x%02x, 0x%04x },\n", m.keycode, m.unicode, m.qtcode, m.modifiers, m.flags, m.special);
}
- ts << "};" << endl << endl;
+ ts << "};" << Qt::endl << Qt::endl;
- ts << "const QEvdevKeyboardMap::Composing QEvdevKeyboardHandler::s_keycompose_default[] = {" << endl;
+ ts << "const QEvdevKeyboardMap::Composing QEvdevKeyboardHandler::s_keycompose_default[] = {" << Qt::endl;
for (int i = 0; i < m_keycompose.size(); ++i) {
const QEvdevKeyboardMap::Composing &c = m_keycompose.at(i);
ts << QString::asprintf(" { 0x%04x, 0x%04x, 0x%04x },\n", c.first, c.second, c.result);
}
- ts << "};" << endl << endl;
+ ts << "};" << Qt::endl << Qt::endl;
- ts << "#endif" << endl;
+ ts << "#endif" << Qt::endl;
return (ts.status() == QTextStream::Ok);
}
diff --git a/src/linguist/Qt5LinguistToolsConfig.cmake.in b/src/linguist/Qt5LinguistToolsConfig.cmake.in
index 4318b16fa..2e99bc762 100644
--- a/src/linguist/Qt5LinguistToolsConfig.cmake.in
+++ b/src/linguist/Qt5LinguistToolsConfig.cmake.in
@@ -89,4 +89,15 @@ endif()
set(Qt5_LRELEASE_EXECUTABLE Qt5::lrelease)
set(Qt5_LUPDATE_EXECUTABLE Qt5::lupdate)
+# Create versionless tool targets.
+foreach(__qt_tool lrelease lupdate lconvert)
+ if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::${__qt_tool}
+ AND TARGET Qt5::${__qt_tool})
+ add_executable(Qt::${__qt_tool} IMPORTED)
+ get_target_property(__qt_imported_location Qt5::${__qt_tool} IMPORTED_LOCATION)
+ set_target_properties(Qt::${__qt_tool}
+ PROPERTIES IMPORTED_LOCATION \"${__qt_imported_location}\")
+ endif()
+endforeach()
+
include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5LinguistToolsMacros.cmake\")
diff --git a/src/linguist/Qt5LinguistToolsMacros.cmake b/src/linguist/Qt5LinguistToolsMacros.cmake
index 23beeb397..ab271d56a 100644
--- a/src/linguist/Qt5LinguistToolsMacros.cmake
+++ b/src/linguist/Qt5LinguistToolsMacros.cmake
@@ -81,6 +81,17 @@ function(QT5_CREATE_TRANSLATION _qm_files)
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
endfunction()
+if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
+ function(qt_create_translation _qm_files)
+ if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
+ qt5_create_translation("${_qm_files}" ${ARGN})
+ elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
+ qt6_create_translation("${_qm_files}" ${ARGN})
+ endif()
+ set("${_qm_files}" "${${_qm_files}}" PARENT_SCOPE)
+ endfunction()
+endif()
+
function(QT5_ADD_TRANSLATION _qm_files)
set(options)
@@ -112,3 +123,14 @@ function(QT5_ADD_TRANSLATION _qm_files)
endforeach()
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
endfunction()
+
+if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
+ function(qt_add_translation _qm_files)
+ if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
+ qt5_add_translation("${_qm_files}" ${ARGN})
+ elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
+ qt6_add_translation("${_qm_files}" ${ARGN})
+ endif()
+ set("${_qm_files}" "${${_qm_files}}" PARENT_SCOPE)
+ endfunction()
+endif()
diff --git a/src/linguist/linguist.pro b/src/linguist/linguist.pro
index face6545f..7638c7710 100644
--- a/src/linguist/linguist.pro
+++ b/src/linguist/linguist.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(linguist))
+
TEMPLATE = subdirs
SUBDIRS = \
lconvert \
diff --git a/src/linguist/linguist/doc/src/linguist-manual.qdoc b/src/linguist/linguist/doc/src/linguist-manual.qdoc
index 3ff17926e..5407b03ee 100644
--- a/src/linguist/linguist/doc/src/linguist-manual.qdoc
+++ b/src/linguist/linguist/doc/src/linguist-manual.qdoc
@@ -77,7 +77,6 @@
\title Overview of the Translation Process
\ingroup internationalization
- \contentspage {Qt Linguist Manual}{Contents}
\previouspage Qt Linguist Manual
\nextpage Qt Linguist Manual: Release Manager
@@ -146,7 +145,6 @@
\title Qt Linguist Manual: Release Manager
\ingroup internationalization
- \contentspage {Qt Linguist Manual}{Contents}
\previouspage Overview of the Translation Process
\nextpage Qt Linguist Manual: Translators
@@ -321,7 +319,6 @@
\title Qt Linguist Manual: Translators
\ingroup internationalization
- \contentspage {Qt Linguist Manual}{Contents}
\previouspage Qt Linguist Manual: Release Manager
\nextpage Qt Linguist Manual: Developers
@@ -876,7 +873,6 @@
\title Qt Linguist Manual: Developers
\ingroup internationalization
- \contentspage {Qt Linguist Manual}{Contents}
\previouspage Qt Linguist Manual: Translators
\nextpage Qt Linguist Manual: TS File Format
@@ -1047,7 +1043,6 @@
\title Qt Linguist Manual: TS File Format
\ingroup internationalization
- \contentspage {Qt Linguist Manual}{Contents}
\previouspage Qt Linguist Manual: Developers
\nextpage Qt Linguist Manual: Text ID Based Translations
@@ -1065,7 +1060,6 @@
\title Qt Linguist Manual: Text ID Based Translations
\ingroup internationalization
- \contentspage {Qt Linguist Manual}{Contents}
\previouspage Qt Linguist Manual: TS File Format
\brief Text ID based internationalization provides support for large scale
diff --git a/src/linguist/linguist/linguist.pro b/src/linguist/linguist/linguist.pro
index af74df8ec..d083896c3 100644
--- a/src/linguist/linguist/linguist.pro
+++ b/src/linguist/linguist/linguist.pro
@@ -1,4 +1,4 @@
-QT += core-private gui-private widgets xml uitools-private printsupport
+QT += core-private gui-private widgets uitools-private printsupport
DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
diff --git a/src/linguist/linguist/main.cpp b/src/linguist/linguist/main.cpp
index e4eb514a5..8f8bdb134 100644
--- a/src/linguist/linguist/main.cpp
+++ b/src/linguist/linguist/main.cpp
@@ -35,7 +35,6 @@
#include <QtCore/QTranslator>
#include <QtWidgets/QApplication>
-#include <QtWidgets/QDesktopWidget>
#include <QtGui/QPixmap>
#ifdef Q_OS_MAC
diff --git a/src/linguist/linguist/mainwindow.cpp b/src/linguist/linguist/mainwindow.cpp
index fde084d56..26a3d03f2 100644
--- a/src/linguist/linguist/mainwindow.cpp
+++ b/src/linguist/linguist/mainwindow.cpp
@@ -299,7 +299,6 @@ MainWindow::MainWindow()
m_contextDock = new QDockWidget(this);
m_contextDock->setObjectName(QLatin1String("ContextDockWidget"));
m_contextDock->setAllowedAreas(Qt::AllDockWidgetAreas);
- m_contextDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
m_contextDock->setWindowTitle(tr("Context"));
m_contextDock->setAcceptDrops(true);
m_contextDock->installEventFilter(this);
@@ -329,7 +328,6 @@ MainWindow::MainWindow()
m_messagesDock = new QDockWidget(this);
m_messagesDock->setObjectName(QLatin1String("StringsDockWidget"));
m_messagesDock->setAllowedAreas(Qt::AllDockWidgetAreas);
- m_messagesDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
m_messagesDock->setWindowTitle(tr("Strings"));
m_messagesDock->setAcceptDrops(true);
m_messagesDock->installEventFilter(this);
@@ -366,7 +364,6 @@ MainWindow::MainWindow()
m_phrasesDock = new QDockWidget(this);
m_phrasesDock->setObjectName(QLatin1String("PhrasesDockwidget"));
m_phrasesDock->setAllowedAreas(Qt::AllDockWidgetAreas);
- m_phrasesDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
m_phrasesDock->setWindowTitle(tr("Phrases and guesses"));
m_phraseView = new PhraseView(m_dataModel, &m_phraseDict, this);
@@ -376,7 +373,6 @@ MainWindow::MainWindow()
m_sourceAndFormDock = new QDockWidget(this);
m_sourceAndFormDock->setObjectName(QLatin1String("SourceAndFormDock"));
m_sourceAndFormDock->setAllowedAreas(Qt::AllDockWidgetAreas);
- m_sourceAndFormDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
m_sourceAndFormDock->setWindowTitle(tr("Sources and Forms"));
m_sourceAndFormView = new QStackedWidget(this);
m_sourceAndFormDock->setWidget(m_sourceAndFormView);
@@ -391,7 +387,6 @@ MainWindow::MainWindow()
m_errorsDock = new QDockWidget(this);
m_errorsDock->setObjectName(QLatin1String("ErrorsDockWidget"));
m_errorsDock->setAllowedAreas(Qt::AllDockWidgetAreas);
- m_errorsDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
m_errorsDock->setWindowTitle(tr("Warnings"));
m_errorsView = new ErrorsView(m_dataModel, this);
m_errorsDock->setWidget(m_errorsView);
@@ -1347,7 +1342,7 @@ void MainWindow::manual()
<< (QT_VERSION >> 16) << ((QT_VERSION >> 8) & 0xFF)
<< (QT_VERSION & 0xFF)
<< QLatin1String("/qtlinguist/qtlinguist-index.html")
- << QLatin1Char('\n') << endl;
+ << QLatin1Char('\n') << Qt::endl;
}
void MainWindow::about()
diff --git a/src/linguist/linguist/messageeditorwidgets.cpp b/src/linguist/linguist/messageeditorwidgets.cpp
index 6c16b36fd..bb0eb5baf 100644
--- a/src/linguist/linguist/messageeditorwidgets.cpp
+++ b/src/linguist/linguist/messageeditorwidgets.cpp
@@ -372,7 +372,7 @@ void FormMultiWidget::slotSelectionChanged()
void FormMultiWidget::setTranslation(const QString &text, bool userAction)
{
- QStringList texts = text.split(QChar(Translator::BinaryVariantSeparator), QString::KeepEmptyParts);
+ QStringList texts = text.split(QChar(Translator::BinaryVariantSeparator), Qt::KeepEmptyParts);
while (m_editors.count() > texts.count()) {
delete m_minusButtons.takeLast();
diff --git a/src/linguist/linguist/messagemodel.h b/src/linguist/linguist/messagemodel.h
index 5c2d95ec2..32f868d51 100644
--- a/src/linguist/linguist/messagemodel.h
+++ b/src/linguist/linguist/messagemodel.h
@@ -37,8 +37,6 @@
#include <QtCore/QLocale>
#include <QtGui/QColor>
#include <QtGui/QBitmap>
-#include <QtXml/QXmlDefaultHandler>
-
QT_BEGIN_NAMESPACE
diff --git a/src/linguist/linguist/phrase.cpp b/src/linguist/linguist/phrase.cpp
index b7b9835f5..064e79f40 100644
--- a/src/linguist/linguist/phrase.cpp
+++ b/src/linguist/linguist/phrase.cpp
@@ -28,6 +28,7 @@
#include "phrase.h"
#include "translator.h"
+#include "xmlparser.h"
#include <QApplication>
#include <QFile>
@@ -36,9 +37,7 @@
#include <QRegExp>
#include <QTextCodec>
#include <QTextStream>
-#include <QXmlAttributes>
-#include <QXmlDefaultHandler>
-#include <QXmlParseException>
+#include <QXmlStreamReader>
QT_BEGIN_NAMESPACE
@@ -104,24 +103,26 @@ bool operator==(const Phrase &p, const Phrase &q)
p.definition() == q.definition() && p.phraseBook() == q.phraseBook();
}
-class QphHandler : public QXmlDefaultHandler
+class QphHandler : public XmlParser
{
public:
- QphHandler(PhraseBook *phraseBook)
- : pb(phraseBook), ferrorCount(0) { }
-
- virtual bool startElement(const QString &namespaceURI,
- const QString &localName, const QString &qName,
- const QXmlAttributes &atts);
- virtual bool endElement(const QString &namespaceURI,
- const QString &localName, const QString &qName);
- virtual bool characters(const QString &ch);
- virtual bool fatalError(const QXmlParseException &exception);
+ QphHandler(PhraseBook *phraseBook, QXmlStreamReader &reader)
+ : XmlParser(reader), pb(phraseBook), ferrorCount(0)
+ {
+ }
+ ~QphHandler() override = default;
QString language() const { return m_language; }
QString sourceLanguage() const { return m_sourceLanguage; }
private:
+ bool startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts) override;
+ bool endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName) override;
+ bool characters(const QStringRef &ch) override;
+ bool fatalError(qint64 line, qint64 column, const QString &message) override;
+
PhraseBook *pb;
QString source;
QString target;
@@ -133,14 +134,15 @@ private:
int ferrorCount;
};
-bool QphHandler::startElement(const QString & /* namespaceURI */,
- const QString & /* localName */,
- const QString &qName,
- const QXmlAttributes &atts)
+bool QphHandler::startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts)
{
+ Q_UNUSED(namespaceURI)
+ Q_UNUSED(localName)
+
if (qName == QLatin1String("QPH")) {
- m_language = atts.value(QLatin1String("language"));
- m_sourceLanguage = atts.value(QLatin1String("sourcelanguage"));
+ m_language = atts.value(QLatin1String("language")).toString();
+ m_sourceLanguage = atts.value(QLatin1String("sourcelanguage")).toString();
} else if (qName == QLatin1String("phrase")) {
source.truncate(0);
target.truncate(0);
@@ -150,10 +152,12 @@ bool QphHandler::startElement(const QString & /* namespaceURI */,
return true;
}
-bool QphHandler::endElement(const QString & /* namespaceURI */,
- const QString & /* localName */,
- const QString &qName)
+bool QphHandler::endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName)
{
+ Q_UNUSED(namespaceURI)
+ Q_UNUSED(localName)
+
if (qName == QLatin1String("source"))
source = accum;
else if (qName == QLatin1String("target"))
@@ -165,20 +169,20 @@ bool QphHandler::endElement(const QString & /* namespaceURI */,
return true;
}
-bool QphHandler::characters(const QString &ch)
+bool QphHandler::characters(const QStringRef &ch)
{
accum += ch;
return true;
}
-bool QphHandler::fatalError(const QXmlParseException &exception)
+bool QphHandler::fatalError(qint64 line, qint64 column, const QString &message)
{
if (ferrorCount++ == 0) {
QString msg = PhraseBook::tr("Parse error at line %1, column %2 (%3).")
- .arg(exception.lineNumber()).arg(exception.columnNumber())
- .arg(exception.message());
- QMessageBox::information(0,
- QObject::tr("Qt Linguist"), msg);
+ .arg(line)
+ .arg(column)
+ .arg(message);
+ QMessageBox::information(nullptr, QObject::tr("Qt Linguist"), msg);
}
return false;
}
@@ -223,20 +227,10 @@ bool PhraseBook::load(const QString &fileName, bool *langGuessed)
m_fileName = fileName;
- QXmlInputSource in(&f);
- QXmlSimpleReader reader;
- // don't click on these!
- reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), false);
- reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true);
- reader.setFeature(QLatin1String("http://trolltech.com/xml/features/report-whitespace"
- "-only-CharData"), false);
- QphHandler *hand = new QphHandler(this);
- reader.setContentHandler(hand);
- reader.setErrorHandler(hand);
-
- bool ok = reader.parse(in);
- reader.setContentHandler(0);
- reader.setErrorHandler(0);
+ QXmlStreamReader reader(&f);
+ QphHandler *hand = new QphHandler(this, reader);
+ reader.setNamespaceProcessing(false);
+ bool ok = hand->parse();
Translator::languageAndCountry(hand->language(), &m_language, &m_country);
*langGuessed = false;
diff --git a/src/linguist/linguist/phrasemodel.cpp b/src/linguist/linguist/phrasemodel.cpp
index afd880cc1..8a820e1ce 100644
--- a/src/linguist/linguist/phrasemodel.cpp
+++ b/src/linguist/linguist/phrasemodel.cpp
@@ -116,7 +116,7 @@ QVariant PhraseModel::headerData(int section, Qt::Orientation orientation, int r
Qt::ItemFlags PhraseModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
- return 0;
+ return {};
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
// Edit is allowed for source & translation if item is from phrasebook
if (plist.at(index.row())->phraseBook()
diff --git a/src/linguist/linguist/statistics.h b/src/linguist/linguist/statistics.h
index 632332ffd..6fcbdcf07 100644
--- a/src/linguist/linguist/statistics.h
+++ b/src/linguist/linguist/statistics.h
@@ -39,7 +39,7 @@ class Statistics : public QDialog, public Ui::Statistics
Q_OBJECT
public:
- Statistics(QWidget *parent = 0, Qt::WindowFlags fl = 0);
+ Statistics(QWidget *parent = 0, Qt::WindowFlags fl = {});
~Statistics() {}
public slots:
diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp
index 712b95550..104971e08 100644
--- a/src/linguist/lupdate/main.cpp
+++ b/src/linguist/lupdate/main.cpp
@@ -285,7 +285,7 @@ static void printUsage()
static bool handleTrFunctionAliases(const QString &arg)
{
- foreach (const QString &pair, arg.split(QLatin1Char(','), QString::SkipEmptyParts)) {
+ foreach (const QString &pair, arg.split(QLatin1Char(','), Qt::SkipEmptyParts)) {
const int equalSign = pair.indexOf(QLatin1Char('='));
if (equalSign < 0) {
printErr(LU::tr("tr-function mapping '%1' in -tr-function-alias is missing the '='.\n").arg(pair));
diff --git a/src/linguist/lupdate/qdeclarative.cpp b/src/linguist/lupdate/qdeclarative.cpp
index 7a453aa32..7d995ae86 100644
--- a/src/linguist/lupdate/qdeclarative.cpp
+++ b/src/linguist/lupdate/qdeclarative.cpp
@@ -39,6 +39,7 @@
#include <private/qqmljslexer_p.h>
#include <private/qqmljsastvisitor_p.h>
#include <private/qqmljsast_p.h>
+#include <private/qqmlapiversion_p.h>
#include <QCoreApplication>
#include <QFile>
@@ -52,6 +53,12 @@
QT_BEGIN_NAMESPACE
+#if Q_QML_PRIVATE_API_VERSION < 8
+namespace QQmlJS {
+ using SourceLocation = AST::SourceLocation;
+}
+#endif
+
using namespace QQmlJS;
static QString MagicComment(QLatin1String("TRANSLATOR"));
@@ -229,7 +236,7 @@ private:
void processComments(quint32 offset, bool flush = false);
- void processComment(const AST::SourceLocation &loc);
+ void processComment(const SourceLocation &loc);
void consumeComment();
bool createString(AST::ExpressionNode *ast, QString *out)
@@ -259,7 +266,7 @@ private:
TranslatorMessage::ExtraData extra;
QString sourcetext;
QString trcontext;
- QList<AST::SourceLocation> m_todo;
+ QList<SourceLocation> m_todo;
};
QString createErrorString(const QString &filename, const QString &code, Parser &parser)
@@ -274,7 +281,7 @@ QString createErrorString(const QString &filename, const QString &code, Parser &
if (m.isWarning())
continue;
-#if Q_QML_PRIVATE_API_VERSION < 5
+#if Q_QML_PRIVATE_API_VERSION >= 8
const int line = m.loc.startLine;
const int column = m.loc.startColumn;
#else
@@ -315,7 +322,7 @@ void FindTrCalls::postVisit(AST::Node *node)
void FindTrCalls::processComments(quint32 offset, bool flush)
{
for (; !m_todo.isEmpty(); m_todo.removeFirst()) {
- AST::SourceLocation loc = m_todo.first();
+ SourceLocation loc = m_todo.first();
if (! flush && (loc.begin() >= offset))
break;
@@ -332,7 +339,7 @@ void FindTrCalls::consumeComment()
sourcetext.clear();
}
-void FindTrCalls::processComment(const AST::SourceLocation &loc)
+void FindTrCalls::processComment(const SourceLocation &loc)
{
if (!loc.length)
return;
diff --git a/src/linguist/lupdate/ui.cpp b/src/linguist/lupdate/ui.cpp
index ce4ecc045..f91ffac5b 100644
--- a/src/linguist/lupdate/ui.cpp
+++ b/src/linguist/lupdate/ui.cpp
@@ -29,40 +29,41 @@
#include "lupdate.h"
#include <translator.h>
+#include <xmlparser.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QString>
-
-#include <QtXml/QXmlAttributes>
-#include <QtXml/QXmlDefaultHandler>
-#include <QtXml/QXmlLocator>
-#include <QtXml/QXmlParseException>
-
+#include <QtCore/QXmlStreamReader>
QT_BEGIN_NAMESPACE
-class UiReader : public QXmlDefaultHandler
+class UiReader : public XmlParser
{
public:
- UiReader(Translator &translator, ConversionData &cd)
- : m_translator(translator), m_cd(cd), m_lineNumber(-1), m_isTrString(false),
- m_insideStringList(false), m_idBasedTranslations(false)
- {}
-
- bool startElement(const QString &namespaceURI, const QString &localName,
- const QString &qName, const QXmlAttributes &atts);
- bool endElement(const QString &namespaceURI, const QString &localName,
- const QString &qName);
- bool characters(const QString &ch);
- bool fatalError(const QXmlParseException &exception);
-
- void setDocumentLocator(QXmlLocator *locator) { m_locator = locator; }
+ UiReader(Translator &translator, ConversionData &cd, QXmlStreamReader &reader)
+ : XmlParser(reader),
+ m_translator(translator),
+ m_cd(cd),
+ m_lineNumber(-1),
+ m_isTrString(false),
+ m_insideStringList(false),
+ m_idBasedTranslations(false)
+ {
+ }
+ ~UiReader() override = default;
private:
+ bool startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts) override;
+ bool endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName) override;
+ bool characters(const QStringRef &ch) override;
+ bool fatalError(qint64 line, qint64 column, const QString &message) override;
+
void flush();
- void readTranslationAttributes(const QXmlAttributes &atts);
+ void readTranslationAttributes(const QXmlStreamAttributes &atts);
Translator &m_translator;
ConversionData &m_cd;
@@ -71,7 +72,6 @@ private:
QString m_comment;
QString m_extracomment;
QString m_id;
- QXmlLocator *m_locator;
QString m_accum;
int m_lineNumber;
@@ -80,8 +80,8 @@ private:
bool m_idBasedTranslations;
};
-bool UiReader::startElement(const QString &namespaceURI,
- const QString &localName, const QString &qName, const QXmlAttributes &atts)
+bool UiReader::startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts)
{
Q_UNUSED(namespaceURI);
Q_UNUSED(localName);
@@ -95,16 +95,16 @@ bool UiReader::startElement(const QString &namespaceURI,
m_insideStringList = true;
readTranslationAttributes(atts);
} else if (qName == QLatin1String("ui")) { // UI "header"
- const int translationTypeIndex = atts.index(QStringLiteral("idbasedtr"));
- m_idBasedTranslations = translationTypeIndex >= 0
- && atts.value(translationTypeIndex) == QLatin1String("true");
+ const auto attr = QStringLiteral("idbasedtr");
+ m_idBasedTranslations =
+ atts.hasAttribute(attr) && atts.value(attr) == QLatin1String("true");
}
m_accum.clear();
return true;
}
-bool UiReader::endElement(const QString &namespaceURI,
- const QString &localName, const QString &qName)
+bool UiReader::endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName)
{
Q_UNUSED(namespaceURI);
Q_UNUSED(localName);
@@ -127,17 +127,18 @@ bool UiReader::endElement(const QString &namespaceURI,
return true;
}
-bool UiReader::characters(const QString &ch)
+bool UiReader::characters(const QStringRef &ch)
{
- m_accum += ch;
+ m_accum += ch.toString();
return true;
}
-bool UiReader::fatalError(const QXmlParseException &exception)
+bool UiReader::fatalError(qint64 line, qint64 column, const QString &message)
{
QString msg = LU::tr("XML error: Parse error at line %1, column %2 (%3).")
- .arg(exception.lineNumber()).arg(exception.columnNumber())
- .arg(exception.message());
+ .arg(line)
+ .arg(column)
+ .arg(message);
m_cd.appendError(msg);
return false;
}
@@ -160,17 +161,17 @@ void UiReader::flush()
}
}
-void UiReader::readTranslationAttributes(const QXmlAttributes &atts)
+void UiReader::readTranslationAttributes(const QXmlStreamAttributes &atts)
{
- const QString notr = atts.value(QStringLiteral("notr"));
+ const auto notr = atts.value(QStringLiteral("notr"));
if (notr.isEmpty() || notr != QStringLiteral("true")) {
m_isTrString = true;
- m_comment = atts.value(QStringLiteral("comment"));
- m_extracomment = atts.value(QStringLiteral("extracomment"));
+ m_comment = atts.value(QStringLiteral("comment")).toString();
+ m_extracomment = atts.value(QStringLiteral("extracomment")).toString();
if (m_idBasedTranslations)
- m_id = atts.value(QStringLiteral("id"));
+ m_id = atts.value(QStringLiteral("id")).toString();
if (!m_cd.m_noUiLines)
- m_lineNumber = m_locator->lineNumber();
+ m_lineNumber = static_cast<int>(reader.lineNumber());
} else {
m_isTrString = false;
}
@@ -184,20 +185,14 @@ bool loadUI(Translator &translator, const QString &filename, ConversionData &cd)
cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
return false;
}
- QXmlInputSource in(&file);
- QXmlSimpleReader reader;
- reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), false);
- reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true);
- reader.setFeature(QLatin1String(
- "http://trolltech.com/xml/features/report-whitespace-only-CharData"), false);
- UiReader handler(translator, cd);
- reader.setContentHandler(&handler);
- reader.setErrorHandler(&handler);
- bool result = reader.parse(in);
+
+ QXmlStreamReader reader(&file);
+ reader.setNamespaceProcessing(false);
+
+ UiReader uiReader(translator, cd, reader);
+ bool result = uiReader.parse();
if (!result)
cd.appendError(LU::tr("Parse error in UI file"));
- reader.setContentHandler(0);
- reader.setErrorHandler(0);
return result;
}
diff --git a/src/linguist/shared/formats.pri b/src/linguist/shared/formats.pri
index e5f388f2a..876fe50cc 100644
--- a/src/linguist/shared/formats.pri
+++ b/src/linguist/shared/formats.pri
@@ -1,17 +1,15 @@
-
-# infrastructure
-QT *= xml
-
INCLUDEPATH *= $$PWD
SOURCES += \
$$PWD/numerus.cpp \
$$PWD/translator.cpp \
- $$PWD/translatormessage.cpp
+ $$PWD/translatormessage.cpp \
+ $$PWD/xmlparser.cpp
HEADERS += \
$$PWD/translator.h \
- $$PWD/translatormessage.h
+ $$PWD/translatormessage.h \
+ $$PWD/xmlparser.h
# "real" formats readers and writers
SOURCES += \
diff --git a/src/linguist/shared/po.cpp b/src/linguist/shared/po.cpp
index 4e623e6a3..69062b772 100644
--- a/src/linguist/shared/po.cpp
+++ b/src/linguist/shared/po.cpp
@@ -548,7 +548,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
QString xrefs;
foreach (const QString &ref,
codec->toUnicode(item.references).split(
- QRegExp(QLatin1String("\\s")), QString::SkipEmptyParts)) {
+ QRegExp(QLatin1String("\\s")), Qt::SkipEmptyParts)) {
int pos = ref.indexOf(QLatin1Char(':'));
int lpos = ref.lastIndexOf(QLatin1Char(':'));
if (pos != -1 && pos == lpos) {
@@ -607,7 +607,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
case ',': {
QStringList flags =
QString::fromLatin1(line.mid(2)).split(
- QRegExp(QLatin1String("[, ]")), QString::SkipEmptyParts);
+ QRegExp(QLatin1String("[, ]")), Qt::SkipEmptyParts);
if (flags.removeOne(QLatin1String("fuzzy")))
item.isFuzzy = true;
flags.removeOne(QLatin1String("qt-format"));
@@ -750,7 +750,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &)
out << "msgid \"\"\n";
Translator::ExtraData headers = translator.extras();
QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split(
- QLatin1Char(','), QString::SkipEmptyParts);
+ QLatin1Char(','), Qt::SkipEmptyParts);
// Keep in sync with loadPO
addPoHeader(headers, hdrOrder, "MIME-Version", QLatin1String("1.0"));
addPoHeader(headers, hdrOrder, "Content-Type",
@@ -779,7 +779,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &)
out << poEscapedString(QString(), QString::fromLatin1("msgstr"), true, hdrStr);
foreach (const TranslatorMessage &msg, translator.messages()) {
- out << endl;
+ out << Qt::endl;
if (!msg.translatorComment().isEmpty())
out << poEscapedLines(QLatin1String("#"), true, msg.translatorComment());
diff --git a/src/linguist/shared/qm.cpp b/src/linguist/shared/qm.cpp
index 6963ad6cb..288607824 100644
--- a/src/linguist/shared/qm.cpp
+++ b/src/linguist/shared/qm.cpp
@@ -151,9 +151,9 @@ public:
uint o;
};
- enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96 };
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96, Language = 0xa7 };
- Releaser() {}
+ Releaser(const QString &language) : m_language(language) {}
bool save(QIODevice *iod);
@@ -179,6 +179,7 @@ private:
void writeMessage(const ByteTranslatorMessage & msg, QDataStream & stream,
TranslatorSaveMode strip, Prefix prefix) const;
+ QString m_language;
// for squeezed but non-file data, this is what needs to be deleted
QByteArray m_messageArray;
QByteArray m_offsetArray;
@@ -249,6 +250,12 @@ bool Releaser::save(QIODevice *iod)
QDataStream s(iod);
s.writeRawData((const char *)magic, MagicLength);
+ if (!m_language.isEmpty()) {
+ QByteArray lang = originalBytes(m_language);
+ quint32 las = quint32(lang.size());
+ s << quint8(Language) << las;
+ s.writeRawData(lang, las);
+ }
if (!m_dependencyArray.isEmpty()) {
quint32 das = quint32(m_dependencyArray.size());
s << quint8(Dependencies) << das;
@@ -465,7 +472,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
return false;
}
- enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96 };
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96, Language = 0xa7 };
// for squeezed but non-file data, this is what needs to be deleted
const uchar *messageArray = 0;
@@ -473,6 +480,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
uint offsetLength = 0;
bool ok = true;
+ bool utf8Fail = false;
const uchar *end = data + len;
data += MagicLength;
@@ -505,6 +513,10 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
dependencies.append(dep);
}
translator.setDependencies(dependencies);
+ } else if (tag == Language) {
+ QString language;
+ fromBytes((const char *)data, blockLen, &language, &utf8Fail);
+ translator.setLanguageCode(language);
}
data += blockLen;
@@ -524,7 +536,6 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
guessPlurals = (numerusForms.count() == 1);
QString context, sourcetext, comment;
- bool utf8Fail = false;
QStringList translations;
for (const uchar *start = offsetArray; start != offsetArray + (numItems << 3); start += 8) {
@@ -632,7 +643,7 @@ static bool containsStripped(const Translator &translator, const TranslatorMessa
bool saveQM(const Translator &translator, QIODevice &dev, ConversionData &cd)
{
- Releaser releaser;
+ Releaser releaser(translator.languageCode());
QLocale::Language l;
QLocale::Country c;
Translator::languageAndCountry(translator.languageCode(), &l, &c);
diff --git a/src/linguist/shared/qmakebuiltins.cpp b/src/linguist/shared/qmakebuiltins.cpp
index 92366b9f7..180c1fa7a 100644
--- a/src/linguist/shared/qmakebuiltins.cpp
+++ b/src/linguist/shared/qmakebuiltins.cpp
@@ -768,7 +768,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
const auto vars = values(map(args.at(0)));
for (const ProString &var : vars) {
// FIXME: this is inconsistent with the "there are no empty strings" dogma.
- const auto splits = var.toQStringRef().split(sep, QString::KeepEmptyParts);
+ const auto splits = var.toQStringRef().split(sep, Qt::KeepEmptyParts);
for (const auto &splt : splits)
ret << ProString(splt).setSource(var);
}
@@ -1538,7 +1538,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (args.count() == 1)
return returnBool(isActiveConfig(args.at(0).toQStringRef()));
const auto &mutuals = args.at(1).toQStringRef().split(QLatin1Char('|'),
- QString::SkipEmptyParts);
+ Qt::SkipEmptyParts);
const ProStringList &configs = values(statics.strCONFIG);
for (int i = configs.size() - 1; i >= 0; i--) {
@@ -1572,7 +1572,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
} else {
const auto mutuals = args.at(2).toQStringRef().split(QLatin1Char('|'),
- QString::SkipEmptyParts);
+ Qt::SkipEmptyParts);
for (int i = l.size() - 1; i >= 0; i--) {
const ProString &val = l[i];
for (int mut = 0; mut < mutuals.count(); mut++) {
diff --git a/src/linguist/shared/qmakeevaluator.cpp b/src/linguist/shared/qmakeevaluator.cpp
index 639114d20..9e3fbf3e0 100644
--- a/src/linguist/shared/qmakeevaluator.cpp
+++ b/src/linguist/shared/qmakeevaluator.cpp
@@ -883,7 +883,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable(
return ReturnTrue;
}
QChar sep = val.at(1);
- auto func = val.split(sep, QString::KeepEmptyParts);
+ auto func = val.split(sep, Qt::KeepEmptyParts);
if (func.count() < 3 || func.count() > 4) {
evalError(fL1S("The s/// function expects 3 or 4 arguments."));
return ReturnTrue;
@@ -1022,7 +1022,7 @@ static ProString msvcArchitecture(const QString &vcInstallDir, const QString &pa
QString vcBinDir = vcInstallDir;
if (vcBinDir.endsWith(QLatin1Char('\\')))
vcBinDir.chop(1);
- const auto dirs = pathVar.split(QLatin1Char(';'), QString::SkipEmptyParts);
+ const auto dirs = pathVar.split(QLatin1Char(';'), Qt::SkipEmptyParts);
for (const QString &dir : dirs) {
if (!dir.startsWith(vcBinDir, Qt::CaseInsensitive))
continue;
diff --git a/src/linguist/shared/qmakeglobals.cpp b/src/linguist/shared/qmakeglobals.cpp
index 6ba7abf28..0a58e9e29 100644
--- a/src/linguist/shared/qmakeglobals.cpp
+++ b/src/linguist/shared/qmakeglobals.cpp
@@ -261,7 +261,7 @@ QStringList QMakeGlobals::splitPathList(const QString &val) const
QStringList ret;
if (!val.isEmpty()) {
QString cwd(QDir::currentPath());
- const QStringList vals = val.split(dirlist_sep, QString::SkipEmptyParts);
+ const QStringList vals = val.split(dirlist_sep, Qt::SkipEmptyParts);
ret.reserve(vals.length());
for (const QString &it : vals)
ret << IoUtils::resolvePath(cwd, it);
diff --git a/src/linguist/shared/ts.cpp b/src/linguist/shared/ts.cpp
index 8d394766a..6a7cc64fc 100644
--- a/src/linguist/shared/ts.cpp
+++ b/src/linguist/shared/ts.cpp
@@ -486,7 +486,7 @@ static void writeExtras(QTextStream &t, const char *indent,
}
outs.sort();
foreach (const QString &out, outs)
- t << indent << out << endl;
+ t << indent << out << Qt::endl;
}
static void writeVariants(QTextStream &t, const char *indent, const QString &input)
diff --git a/src/linguist/shared/xliff.cpp b/src/linguist/shared/xliff.cpp
index c499e9ea5..bc47289b4 100644
--- a/src/linguist/shared/xliff.cpp
+++ b/src/linguist/shared/xliff.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "translator.h"
+#include "xmlparser.h"
#include <QtCore/QDebug>
#include <QtCore/QMap>
@@ -36,11 +37,6 @@
#include <QtCore/QTextCodec>
#include <QtCore/QTextStream>
-#include <QtXml/QXmlAttributes>
-#include <QtXml/QXmlDefaultHandler>
-#include <QtXml/QXmlParseException>
-
-
// The string value is historical and reflects the main purpose: Keeping
// obsolete entries separate from the magic file message (which both have
// no location information, but typically reside at opposite ends of the file).
@@ -368,22 +364,22 @@ static void writeMessage(QTextStream &ts, const TranslatorMessage &msg, const QR
}
}
-
-class XLIFFHandler : public QXmlDefaultHandler
+class XLIFFHandler : public XmlParser
{
public:
- XLIFFHandler(Translator &translator, ConversionData &cd);
+ XLIFFHandler(Translator &translator, ConversionData &cd, QXmlStreamReader &reader);
+ ~XLIFFHandler() override = default;
- bool startElement(const QString& namespaceURI, const QString &localName,
- const QString &qName, const QXmlAttributes &atts );
- bool endElement(const QString& namespaceURI, const QString &localName,
- const QString &qName );
- bool characters(const QString &ch);
- bool fatalError(const QXmlParseException &exception);
+private:
+ bool startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts) override;
+ bool endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName) override;
+ bool characters(const QStringRef &ch) override;
+ bool fatalError(qint64 line, qint64 column, const QString &message) override;
- bool endDocument();
+ bool endDocument() override;
-private:
enum XliffContext {
XC_xliff,
XC_group,
@@ -442,14 +438,16 @@ private:
QStack<int> m_contextStack;
};
-XLIFFHandler::XLIFFHandler(Translator &translator, ConversionData &cd)
- : m_translator(translator), m_cd(cd),
- m_translate(true),
- m_approved(true),
- m_lineNumber(-1),
- m_URITT(QLatin1String(TrollTsNamespaceURI)),
- m_URI(QLatin1String(XLIFF11namespaceURI)),
- m_URI12(QLatin1String(XLIFF12namespaceURI))
+XLIFFHandler::XLIFFHandler(Translator &translator, ConversionData &cd, QXmlStreamReader &reader)
+ : XmlParser(reader, true),
+ m_translator(translator),
+ m_cd(cd),
+ m_translate(true),
+ m_approved(true),
+ m_lineNumber(-1),
+ m_URITT(QLatin1String(TrollTsNamespaceURI)),
+ m_URI(QLatin1String(XLIFF11namespaceURI)),
+ m_URI12(QLatin1String(XLIFF12namespaceURI))
{}
@@ -485,33 +483,35 @@ bool XLIFFHandler::hasContext(XliffContext ctx) const
return false;
}
-bool XLIFFHandler::startElement(const QString& namespaceURI,
- const QString &localName, const QString &qName, const QXmlAttributes &atts )
+bool XLIFFHandler::startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts)
{
Q_UNUSED(qName);
if (namespaceURI == m_URITT)
goto bail;
- if (namespaceURI != m_URI && namespaceURI != m_URI12)
- return false;
+ if (namespaceURI != m_URI && namespaceURI != m_URI12) {
+ return fatalError(reader.lineNumber(), reader.columnNumber(),
+ QLatin1String("Unknown namespace in the XLIFF file"));
+ }
if (localName == QLatin1String("xliff")) {
// make sure that the stack is not empty during parsing
pushContext(XC_xliff);
} else if (localName == QLatin1String("file")) {
- m_fileName = atts.value(QLatin1String("original"));
- m_language = atts.value(QLatin1String("target-language"));
+ m_fileName = atts.value(QLatin1String("original")).toString();
+ m_language = atts.value(QLatin1String("target-language")).toString();
m_language.replace(QLatin1Char('-'), QLatin1Char('_'));
- m_sourceLanguage = atts.value(QLatin1String("source-language"));
+ m_sourceLanguage = atts.value(QLatin1String("source-language")).toString();
m_sourceLanguage.replace(QLatin1Char('-'), QLatin1Char('_'));
if (m_sourceLanguage == QLatin1String("en"))
m_sourceLanguage.clear();
} else if (localName == QLatin1String("group")) {
if (atts.value(QLatin1String("restype")) == QLatin1String(restypeContext)) {
- m_context = atts.value(QLatin1String("resname"));
+ m_context = atts.value(QLatin1String("resname")).toString();
pushContext(XC_restype_context);
} else {
if (atts.value(QLatin1String("restype")) == QLatin1String(restypePlurals)) {
pushContext(XC_restype_plurals);
- m_id = atts.value(QLatin1String("id"));
+ m_id = atts.value(QLatin1String("id")).toString();
if (atts.value(QLatin1String("translate")) == QLatin1String("no"))
m_translate = false;
} else {
@@ -523,7 +523,7 @@ bool XLIFFHandler::startElement(const QString& namespaceURI,
if (atts.value(QLatin1String("translate")) == QLatin1String("no"))
m_translate = false;
if (!hasContext(XC_restype_plurals)) {
- m_id = atts.value(QLatin1String("id"));
+ m_id = atts.value(QLatin1String("id")).toString();
if (m_id.startsWith(QLatin1String("_msg")))
m_id.clear();
}
@@ -539,19 +539,18 @@ bool XLIFFHandler::startElement(const QString& namespaceURI,
if (atts.value(QLatin1String("restype")) != QLatin1String(restypeDummy))
pushContext(XC_restype_translation);
} else if (localName == QLatin1String("context-group")) {
- QString purpose = atts.value(QLatin1String("purpose"));
- if (purpose == QLatin1String("location"))
+ if (atts.value(QLatin1String("purpose")) == QLatin1String("location"))
pushContext(XC_context_group);
else
pushContext(XC_context_group_any);
} else if (currentContext() == XC_context_group && localName == QLatin1String("context")) {
- QString ctxtype = atts.value(QLatin1String("context-type"));
+ const auto ctxtype = atts.value(QLatin1String("context-type"));
if (ctxtype == QLatin1String("linenumber"))
pushContext(XC_context_linenumber);
else if (ctxtype == QLatin1String("sourcefile"))
pushContext(XC_context_filename);
} else if (currentContext() == XC_context_group_any && localName == QLatin1String("context")) {
- QString ctxtype = atts.value(QLatin1String("context-type"));
+ const auto ctxtype = atts.value(QLatin1String("context-type"));
if (ctxtype == QLatin1String(contextMsgctxt))
pushContext(XC_context_comment);
else if (ctxtype == QLatin1String(contextOldMsgctxt))
@@ -563,7 +562,7 @@ bool XLIFFHandler::startElement(const QString& namespaceURI,
else
pushContext(XC_translator_comment);
} else if (localName == QLatin1String("ph")) {
- QString ctype = atts.value(QLatin1String("ctype"));
+ QString ctype = atts.value(QLatin1String("ctype")).toString();
if (ctype.startsWith(QLatin1String("x-ch-")))
m_ctype = ctype.mid(5);
pushContext(XC_ph);
@@ -574,19 +573,21 @@ bail:
return true;
}
-bool XLIFFHandler::endElement(const QString &namespaceURI, const QString& localName,
- const QString &qName)
+bool XLIFFHandler::endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName)
{
Q_UNUSED(qName);
if (namespaceURI == m_URITT) {
if (hasContext(XC_trans_unit) || hasContext(XC_restype_plurals))
- m_extra[localName] = accum;
+ m_extra[localName.toString()] = accum;
else
- m_translator.setExtra(localName, accum);
+ m_translator.setExtra(localName.toString(), accum);
return true;
}
- if (namespaceURI != m_URI && namespaceURI != m_URI12)
- return false;
+ if (namespaceURI != m_URI && namespaceURI != m_URI12) {
+ return fatalError(reader.lineNumber(), reader.columnNumber(),
+ QLatin1String("Unknown namespace in the XLIFF file"));
+ }
//qDebug() << "URI:" << namespaceURI << "QNAME:" << qName;
if (localName == QLatin1String("xliff")) {
popContext(XC_xliff);
@@ -640,15 +641,19 @@ bool XLIFFHandler::endElement(const QString &namespaceURI, const QString& localN
if (!m_hadAlt)
m_oldSources.append(QString());
if (!hasContext(XC_restype_plurals)) {
- if (!finalizeMessage(false))
- return false;
+ if (!finalizeMessage(false)) {
+ return fatalError(reader.lineNumber(), reader.columnNumber(),
+ QLatin1String("Element processing failed"));
+ }
}
} else if (localName == QLatin1String("alt-trans")) {
popContext(XC_alt_trans);
} else if (localName == QLatin1String("group")) {
if (popContext(XC_restype_plurals)) {
- if (!finalizeMessage(true))
- return false;
+ if (!finalizeMessage(true)) {
+ return fatalError(reader.lineNumber(), reader.columnNumber(),
+ QLatin1String("Element processing failed"));
+ }
} else if (popContext(XC_restype_context)) {
m_context.clear();
} else {
@@ -658,7 +663,7 @@ bool XLIFFHandler::endElement(const QString &namespaceURI, const QString& localN
return true;
}
-bool XLIFFHandler::characters(const QString &ch)
+bool XLIFFHandler::characters(const QStringRef &ch)
{
if (currentContext() == XC_ph) {
// handle the content of <ph> elements
@@ -670,7 +675,7 @@ bool XLIFFHandler::characters(const QString &ch)
accum.append(chr);
}
} else {
- QString t = ch;
+ QString t = ch.toString();
t.replace(QLatin1String("\r"), QLatin1String(""));
accum.append(t);
}
@@ -730,23 +735,20 @@ bool XLIFFHandler::finalizeMessage(bool isPlural)
return true;
}
-bool XLIFFHandler::fatalError(const QXmlParseException &exception)
+bool XLIFFHandler::fatalError(qint64 line, qint64 column, const QString &message)
{
QString msg = QString::asprintf("XML error: Parse error at line %d, column %d (%s).\n",
- exception.lineNumber(), exception.columnNumber(),
- exception.message().toLatin1().data());
+ static_cast<int>(line), static_cast<int>(column),
+ message.toLatin1().data());
m_cd.appendError(msg);
return false;
}
bool loadXLIFF(Translator &translator, QIODevice &dev, ConversionData &cd)
{
- QXmlInputSource in(&dev);
- QXmlSimpleReader reader;
- XLIFFHandler hand(translator, cd);
- reader.setContentHandler(&hand);
- reader.setErrorHandler(&hand);
- return reader.parse(in);
+ QXmlStreamReader reader(&dev);
+ XLIFFHandler hand(translator, cd, reader);
+ return hand.parse();
}
bool saveXLIFF(const Translator &translator, QIODevice &dev, ConversionData &cd)
diff --git a/src/linguist/shared/xmlparser.cpp b/src/linguist/shared/xmlparser.cpp
new file mode 100644
index 000000000..bcdca12bb
--- /dev/null
+++ b/src/linguist/shared/xmlparser.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xmlparser.h"
+
+QT_BEGIN_NAMESPACE
+
+bool XmlParser::parse()
+{
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.hasError()) {
+ fatalError(reader.lineNumber(), reader.columnNumber(), reader.errorString());
+ return false;
+ }
+
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ if (!startElement(reader.namespaceUri(), reader.name(), reader.qualifiedName(),
+ reader.attributes())) {
+ return false;
+ }
+ break;
+ case QXmlStreamReader::EndElement:
+ if (!endElement(reader.namespaceUri(), reader.name(), reader.qualifiedName())) {
+ return false;
+ }
+ break;
+ case QXmlStreamReader::Characters:
+ if (reportWhitespaceOnlyData
+ || (!reader.isWhitespace() && !reader.text().toString().trimmed().isEmpty())) {
+ if (!characters(reader.text()))
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (reader.isEndDocument() && !endDocument())
+ return false;
+
+ return true;
+}
+
+bool XmlParser::startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts)
+{
+ Q_UNUSED(namespaceURI)
+ Q_UNUSED(localName)
+ Q_UNUSED(qName)
+ Q_UNUSED(atts)
+ return true;
+}
+
+bool XmlParser::endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName)
+{
+ Q_UNUSED(namespaceURI)
+ Q_UNUSED(localName)
+ Q_UNUSED(qName)
+ return true;
+}
+
+bool XmlParser::characters(const QStringRef &text)
+{
+ Q_UNUSED(text)
+ return true;
+}
+
+bool XmlParser::fatalError(qint64 line, qint64 column, const QString &message)
+{
+ Q_UNUSED(line)
+ Q_UNUSED(column)
+ Q_UNUSED(message)
+ return true;
+}
+
+bool XmlParser::endDocument()
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/xmlparser.h b/src/linguist/shared/xmlparser.h
new file mode 100644
index 000000000..4028c7067
--- /dev/null
+++ b/src/linguist/shared/xmlparser.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XMLPARSER_H
+#define XMLPARSER_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qxmlstream.h>
+
+QT_BEGIN_NAMESPACE
+
+class XmlParser
+{
+public:
+ XmlParser(QXmlStreamReader &r, bool whitespaceOnlyData = false)
+ : reader(r), reportWhitespaceOnlyData(whitespaceOnlyData)
+ {
+ }
+ virtual ~XmlParser() = default;
+
+ bool parse();
+
+protected:
+ virtual bool startElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName, const QXmlStreamAttributes &atts);
+ virtual bool endElement(const QStringRef &namespaceURI, const QStringRef &localName,
+ const QStringRef &qName);
+ virtual bool characters(const QStringRef &text);
+ virtual bool endDocument();
+ virtual bool fatalError(qint64 line, qint64 column, const QString &message);
+
+ QXmlStreamReader &reader;
+ bool reportWhitespaceOnlyData;
+};
+
+QT_END_NAMESPACE
+
+#endif // XMLPARSER_H
diff --git a/src/macdeployqt/macdeployqt.pro b/src/macdeployqt/macdeployqt.pro
index a0d90b640..6d50da2d2 100644
--- a/src/macdeployqt/macdeployqt.pro
+++ b/src/macdeployqt/macdeployqt.pro
@@ -1,2 +1,6 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(macdeployqt))
+
TEMPLATE = subdirs
SUBDIRS = macdeployqt macchangeqt
diff --git a/src/macdeployqt/macdeployqt/main.cpp b/src/macdeployqt/macdeployqt/main.cpp
index 0599b739e..3c13a6693 100644
--- a/src/macdeployqt/macdeployqt/main.cpp
+++ b/src/macdeployqt/macdeployqt/main.cpp
@@ -52,6 +52,7 @@ int main(int argc, char **argv)
qDebug() << " -qmlimport=<path> : Add the given path to the QML module search locations";
qDebug() << " -always-overwrite : Copy files even if the target file exists";
qDebug() << " -codesign=<ident> : Run codesign with the given identity on all executables";
+ qDebug() << " -hardened-runtime : Enable Hardened Runtime when code signing";
qDebug() << " -appstore-compliant: Skip deployment of components that use private API";
qDebug() << " -libpath=<path> : Add the given path to the library search path";
qDebug() << " -fs=<filesystem> : Set the filesystem used for the .dmg disk image (defaults to HFS+)";
@@ -96,6 +97,7 @@ int main(int argc, char **argv)
QStringList qmlImportPaths;
extern bool runCodesign;
extern QString codesignIdentiy;
+ extern bool hardenedRuntime;
extern bool appstoreCompliant;
extern bool deployFramework;
@@ -164,6 +166,9 @@ int main(int argc, char **argv)
runCodesign = true;
codesignIdentiy = argument.mid(index+1);
}
+ } else if (argument.startsWith(QByteArray("-hardened-runtime"))) {
+ LogDebug() << "Argument found:" << argument;
+ hardenedRuntime = true;
} else if (argument == QByteArray("-appstore-compliant")) {
LogDebug() << "Argument found:" << argument;
appstoreCompliant = true;
diff --git a/src/macdeployqt/shared/shared.cpp b/src/macdeployqt/shared/shared.cpp
index 69d0ce8ca..cc3b2607b 100644
--- a/src/macdeployqt/shared/shared.cpp
+++ b/src/macdeployqt/shared/shared.cpp
@@ -53,6 +53,8 @@ bool alwaysOwerwriteEnabled = false;
bool runCodesign = false;
QStringList librarySearchPath;
QString codesignIdentiy;
+QString extraEntitlements;
+bool hardenedRuntime = false;
bool appstoreCompliant = false;
int logLevel = 1;
bool deployFramework = false;
@@ -183,7 +185,7 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
"current version (\\d+\\.\\d+\\.\\d+)\\)$"));
QString output = otool.readAllStandardOutput();
- QStringList outputLines = output.split("\n", QString::SkipEmptyParts);
+ QStringList outputLines = output.split("\n", Qt::SkipEmptyParts);
if (outputLines.size() < 2) {
LogError() << "Could not parse otool output:" << output;
return info;
@@ -472,6 +474,23 @@ QStringList findAppBundleFiles(const QString &appBundlePath, bool absolutePath =
return result;
}
+QString findEntitlementsFile(const QString& path)
+{
+ QDirIterator iter(path, QStringList() << QString::fromLatin1("*.entitlements"),
+ QDir::Files, QDirIterator::Subdirectories);
+
+ while (iter.hasNext()) {
+ iter.next();
+ if (iter.fileInfo().isSymLink())
+ continue;
+
+ //return the first entitlements file - only one is used for signing anyway
+ return iter.fileInfo().absoluteFilePath();
+ }
+
+ return QString();
+}
+
QList<FrameworkInfo> getQtFrameworks(const QList<DylibInfo> &dependencies, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
{
QList<FrameworkInfo> libraries;
@@ -1371,11 +1390,21 @@ void codesignFile(const QString &identity, const QString &filePath)
if (!runCodesign)
return;
- LogNormal() << "codesign" << filePath;
+ QString codeSignLogMessage = "codesign";
+ if (hardenedRuntime)
+ codeSignLogMessage += ", enable hardned runtime";
+ LogNormal() << codeSignLogMessage << filePath;
+
+ QStringList codeSignOptions = { "--preserve-metadata=identifier,entitlements", "--force", "-s",
+ identity, filePath };
+ if (hardenedRuntime)
+ codeSignOptions << "-o" << "runtime";
+
+ if (!extraEntitlements.isEmpty())
+ codeSignOptions << "--entitlements" << extraEntitlements;
QProcess codesign;
- codesign.start("codesign", QStringList() << "--preserve-metadata=identifier,entitlements"
- << "--force" << "-s" << identity << filePath);
+ codesign.start("codesign", codeSignOptions);
codesign.waitForFinished(-1);
QByteArray err = codesign.readAllStandardError();
@@ -1495,6 +1524,9 @@ QSet<QString> codesignBundle(const QString &identity,
}
}
+ // Look for an entitlements file in the bundle to include when signing
+ extraEntitlements = findEntitlementsFile(appBundleAbsolutePath + "/Contents/Resources/");
+
// All dependencies are signed, now sign this binary.
codesignFile(identity, binary);
signedBinaries.insert(binary);
diff --git a/src/makeqpf/makeqpf.pro b/src/makeqpf/makeqpf.pro
index 5a8abc882..25c7e5939 100644
--- a/src/makeqpf/makeqpf.pro
+++ b/src/makeqpf/makeqpf.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(makeqpf))
+
QT += widgets gui-private core-private
CONFIG += console
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/src/makeqpf/qpf2.cpp b/src/makeqpf/qpf2.cpp
index c56ec391a..aca3d72cc 100644
--- a/src/makeqpf/qpf2.cpp
+++ b/src/makeqpf/qpf2.cpp
@@ -629,7 +629,7 @@ void QPF::dump(const QByteArray &qpf)
const QFontEngineQPF2::Block *block = reinterpret_cast<const QFontEngineQPF2::Block *>(data);
quint32 tag = qFromBigEndian(block->tag);
quint32 blockSize = qFromBigEndian(block->dataSize);
- qDebug() << "Block: Tag =" << qFromBigEndian(block->tag) << "; Size =" << blockSize << "; Offset =" << hex << data - reinterpret_cast<const uchar *>(qpf.constData());
+ qDebug() << "Block: Tag =" << qFromBigEndian(block->tag) << "; Size =" << blockSize << "; Offset =" << Qt::hex << data - reinterpret_cast<const uchar *>(qpf.constData());
data += sizeof(QFontEngineQPF2::Block);
if (debugVerbosity) {
diff --git a/src/pixeltool/pixeltool.pro b/src/pixeltool/pixeltool.pro
index f3d1bf436..113211d41 100644
--- a/src/pixeltool/pixeltool.pro
+++ b/src/pixeltool/pixeltool.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(pixeltool))
+
QT += core-private gui-private widgets
mac {
diff --git a/src/pixeltool/qpixeltool.cpp b/src/pixeltool/qpixeltool.cpp
index b41f5e942..a52a828c2 100644
--- a/src/pixeltool/qpixeltool.cpp
+++ b/src/pixeltool/qpixeltool.cpp
@@ -535,7 +535,7 @@ void QPixelTool::grabScreen()
const QBrush darkBrush = palette().color(QPalette::Dark);
const QDesktopWidget *desktopWidget = QApplication::desktop();
- if (QScreen *screen = QGuiApplication::screens().value(desktopWidget->screenNumber(this), nullptr)) {
+ if (QScreen *screen = this->screen()) {
m_buffer = screen->grabWindow(desktopWidget->winId(), x, y, w, h);
} else {
m_buffer = QPixmap(w, h);
@@ -685,8 +685,8 @@ QTextStream &operator<<(QTextStream &str, const QScreen *screen)
{
const QRect geometry = screen->geometry();
str << '"' << screen->name() << "\" " << geometry.width()
- << 'x' << geometry.height() << forcesign << geometry.x() << geometry.y()
- << noforcesign << ", " << qRound(screen->logicalDotsPerInch()) << "DPI"
+ << 'x' << geometry.height() << Qt::forcesign << geometry.x() << geometry.y()
+ << Qt::noforcesign << ", " << qRound(screen->logicalDotsPerInch()) << "DPI"
<< ", Depth: " << screen->depth() << ", " << screen->refreshRate() << "Hz";
const qreal dpr = screen->devicePixelRatio();
if (!qFuzzyCompare(dpr, qreal(1)))
diff --git a/src/qdbus/qdbus.pro b/src/qdbus/qdbus.pro
index 860c1e11e..5bf16848a 100644
--- a/src/qdbus/qdbus.pro
+++ b/src/qdbus/qdbus.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(qdbus))
+
TEMPLATE = subdirs
QT_FOR_CONFIG += xml
qtConfig(dom): SUBDIRS = qdbus
diff --git a/src/qdbus/qdbusviewer/propertydialog.h b/src/qdbus/qdbusviewer/propertydialog.h
index a151de473..6621c60fd 100644
--- a/src/qdbus/qdbusviewer/propertydialog.h
+++ b/src/qdbus/qdbusviewer/propertydialog.h
@@ -38,7 +38,7 @@ class PropertyDialog: public QDialog
{
Q_OBJECT
public:
- explicit PropertyDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
+ explicit PropertyDialog(QWidget *parent = 0, Qt::WindowFlags f = {});
void addProperty(const QString &name, int type);
void setInfo(const QString &caption);
diff --git a/src/qdbus/qdbusviewer/qdbusmodel.cpp b/src/qdbus/qdbusviewer/qdbusmodel.cpp
index 79239b264..1e1e4f9fc 100644
--- a/src/qdbus/qdbusviewer/qdbusmodel.cpp
+++ b/src/qdbus/qdbusviewer/qdbusmodel.cpp
@@ -305,7 +305,7 @@ QString QDBusModel::dBusTypeSignature(const QModelIndex &index) const
QModelIndex QDBusModel::findObject(const QDBusObjectPath &objectPath)
{
- QStringList path = objectPath.path().split(QLatin1Char('/'), QString::SkipEmptyParts);
+ QStringList path = objectPath.path().split(QLatin1Char('/'), Qt::SkipEmptyParts);
QDBusItem *item = root;
int childIdx = -1;
diff --git a/src/qdoc/Qt5DocToolsConfig.cmake.in b/src/qdoc/Qt5DocToolsConfig.cmake.in
index daa336127..2a252bb31 100644
--- a/src/qdoc/Qt5DocToolsConfig.cmake.in
+++ b/src/qdoc/Qt5DocToolsConfig.cmake.in
@@ -54,3 +54,14 @@ if (NOT TARGET Qt5::qdoc)
IMPORTED_LOCATION ${imported_location}
)
endif()
+
+# Create versionless tool targets.
+foreach(__qt_tool qdoc)
+ if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::${__qt_tool}
+ AND TARGET Qt5::${__qt_tool})
+ add_executable(Qt::${__qt_tool} IMPORTED)
+ get_target_property(__qt_imported_location Qt5::${__qt_tool} IMPORTED_LOCATION)
+ set_target_properties(Qt::${__qt_tool}
+ PROPERTIES IMPORTED_LOCATION \"${__qt_imported_location}\")
+ endif()
+endforeach()
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp
index ee51e7bd4..db9c2ed07 100644
--- a/src/qdoc/clangcodeparser.cpp
+++ b/src/qdoc/clangcodeparser.cpp
@@ -45,7 +45,6 @@
#include "codechunk.h"
#include "config.h"
-#include "generator.h"
#include "loggingcategory.h"
#include "qdocdatabase.h"
#include "utilities.h"
@@ -110,6 +109,54 @@ static QString fromCXString(CXString &&string)
return ret;
}
+static QString templateDecl(CXCursor cursor);
+
+/*!
+ Returns a list of template parameters at \a cursor.
+*/
+static QStringList getTemplateParameters(CXCursor cursor)
+{
+ QStringList parameters;
+ visitChildrenLambda(cursor, [&parameters](CXCursor cur) {
+ QString name = fromCXString(clang_getCursorSpelling(cur));
+ QString type;
+
+ switch (clang_getCursorKind(cur)) {
+ case CXCursor_TemplateTypeParameter:
+ type = QStringLiteral("typename");
+ break;
+ case CXCursor_NonTypeTemplateParameter:
+ type = fromCXString(clang_getTypeSpelling(clang_getCursorType(cur)));
+ // Hack: Omit QtPrivate template parameters from public documentation
+ if (type.startsWith(QLatin1String("QtPrivate")))
+ return CXChildVisit_Continue;
+ break;
+ case CXCursor_TemplateTemplateParameter:
+ type = templateDecl(cur) + QLatin1String(" class");
+ break;
+ default:
+ return CXChildVisit_Continue;
+ }
+
+ if (!name.isEmpty())
+ name.prepend(QLatin1Char(' '));
+
+ parameters << type + name;
+ return CXChildVisit_Continue;
+ });
+
+ return parameters;
+}
+
+/*!
+ Gets the template declaration at specified \a cursor.
+ */
+static QString templateDecl(CXCursor cursor)
+{
+ QStringList params = getTemplateParameters(cursor);
+ return QLatin1String("template <") + params.join(QLatin1String(", ")) + QLatin1Char('>');
+}
+
/*!
convert a CXSourceLocation to a qdoc Location
*/
@@ -545,6 +592,8 @@ CXChildVisitResult ClangVisitor::visitFnSignature(CXCursor cursor, CXSourceLocat
bool &ignoreSignature)
{
switch (clang_getCursorKind(cursor)) {
+ case CXCursor_Namespace:
+ return CXChildVisit_Recurse;
case CXCursor_FunctionDecl:
case CXCursor_FunctionTemplate:
case CXCursor_CXXMethod:
@@ -573,6 +622,7 @@ CXChildVisitResult ClangVisitor::visitFnSignature(CXCursor cursor, CXSourceLocat
CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation loc)
{
auto kind = clang_getCursorKind(cursor);
+ QString templateString;
switch (kind) {
case CXCursor_TypeAliasDecl: {
QString spelling = getSpelling(clang_getCursorExtent(cursor));
@@ -595,8 +645,10 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
if (fromCXString(clang_getCursorSpelling(cursor)).isEmpty()) // anonymous struct or union
return CXChildVisit_Continue;
Q_FALLTHROUGH();
- case CXCursor_ClassDecl:
- case CXCursor_ClassTemplate: {
+ case CXCursor_ClassTemplate:
+ templateString = templateDecl(cursor);
+ Q_FALLTHROUGH();
+ case CXCursor_ClassDecl: {
if (!clang_isCursorDefinition(cursor))
return CXChildVisit_Continue;
@@ -622,10 +674,8 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
classe->setAccess(fromCX_CXXAccessSpecifier(clang_getCXXAccessSpecifier(cursor)));
classe->setLocation(fromCXSourceLocation(clang_getCursorLocation(cursor)));
- if (kind == CXCursor_ClassTemplate) {
- QString displayName = fromCXString(clang_getCursorSpelling(cursor));
- classe->setTemplateStuff(displayName.mid(className.size()));
- }
+ if (kind == CXCursor_ClassTemplate)
+ classe->setTemplateDecl(templateString);
QScopedValueRollback<Aggregate *> setParent(parent_, classe);
return visitChildren(cursor);
@@ -639,8 +689,9 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
auto baseNode = findNodeForCursor(qdb_, baseCursor);
auto classe = static_cast<ClassNode *>(parent_);
if (baseNode == nullptr || !baseNode->isClassNode()) {
- QString bcName = fromCXString(clang_getCursorSpelling(baseCursor));
- classe->addUnresolvedBaseClass(access, QStringList(bcName), bcName);
+ QString bcName = reconstructQualifiedPathForCursor(baseCursor);
+ classe->addUnresolvedBaseClass(
+ access, bcName.split(QLatin1String("::"), Qt::SkipEmptyParts), bcName);
return CXChildVisit_Continue;
}
auto baseClasse = static_cast<ClassNode *>(baseNode);
@@ -661,8 +712,10 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
QScopedValueRollback<Aggregate *> setParent(parent_, ns);
return visitChildren(cursor);
}
- case CXCursor_FunctionDecl:
case CXCursor_FunctionTemplate:
+ templateString = templateDecl(cursor);
+ Q_FALLTHROUGH();
+ case CXCursor_FunctionDecl:
case CXCursor_CXXMethod:
case CXCursor_Constructor:
case CXCursor_Destructor:
@@ -760,6 +813,7 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
if (clang_isFunctionTypeVariadic(funcType))
parameters.append(QStringLiteral("..."));
readParameterNamesAndAttributes(fn, cursor);
+ fn->setTemplateDecl(templateString);
return CXChildVisit_Continue;
}
#if CINDEX_VERSION >= 36
@@ -774,10 +828,10 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
}
#endif
case CXCursor_EnumDecl: {
- if (findNodeForCursor(qdb_, cursor)) // Was already parsed, propably in another tu
- return CXChildVisit_Continue;
+ EnumNode *en = static_cast<EnumNode *>(findNodeForCursor(qdb_, cursor));
+ if (en && en->items().count())
+ return CXChildVisit_Continue; // Was already parsed, probably in another TU
QString enumTypeName = fromCXString(clang_getCursorSpelling(cursor));
- EnumNode *en = nullptr;
if (enumTypeName.isEmpty()) {
enumTypeName = "anonymous";
if (parent_ && (parent_->isClassNode() || parent_->isNamespace())) {
@@ -787,10 +841,11 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
}
}
if (!en) {
- en = new EnumNode(parent_, enumTypeName);
+ en = new EnumNode(parent_, enumTypeName, clang_EnumDecl_isScoped(cursor));
en->setAccess(fromCX_CXXAccessSpecifier(clang_getCXXAccessSpecifier(cursor)));
en->setLocation(fromCXSourceLocation(clang_getCursorLocation(cursor)));
}
+
// Enum values
visitChildrenLambda(cursor, [&](CXCursor cur) {
if (clang_getCursorKind(cur) != CXCursor_EnumConstantDecl)
@@ -1045,8 +1100,9 @@ ClangCodeParser::~ClangCodeParser()
\a config. Call the initializeParser() in the base class.
Get the defines list from the qdocconf database.
*/
-void ClangCodeParser::initializeParser(const Config &config)
+void ClangCodeParser::initializeParser()
{
+ Config &config = Config::instance();
printParsingErrors_ = 1;
version_ = config.getString(CONFIG_VERSION);
const auto args = config.getStringList(CONFIG_INCLUDEPATHS);
@@ -1076,7 +1132,7 @@ void ClangCodeParser::initializeParser(const Config &config)
path.prepend(option);
includePaths_.append(path);
}
- CppCodeParser::initializeParser(config);
+ CppCodeParser::initializeParser();
pchFileDir_.reset(nullptr);
allHeaders_.clear();
pchName_.clear();
@@ -1176,6 +1232,7 @@ static const char *defaultArgs_[] = {
"-Wno-constant-logical-operand",
"-Wno-macro-redefined",
"-Wno-nullability-completeness",
+ "-fvisibility=default",
"-ferror-limit=0",
"-I" CLANG_RESOURCE_DIR
};
@@ -1231,8 +1288,7 @@ bool ClangCodeParser::getMoreArgs()
of reasonable places to look for include files and use
that list instead.
*/
- Location::logToStdErrAlways(
- "No include paths passed to qdoc; guessing reasonable include paths");
+ qCWarning(lcQdoc) << "No include paths passed to qdoc; guessing reasonable include paths";
guessedIncludePaths = true;
auto forest = qdb_->searchOrder();
@@ -1262,7 +1318,7 @@ void ClangCodeParser::buildPCH()
const QByteArray module = moduleHeader().toUtf8();
QByteArray header;
QByteArray privateHeaderDir;
- Location::logToStdErrAlways("Build & visit PCH for " + moduleHeader());
+ qCDebug(lcQdoc) << "Build and visit PCH for" << moduleHeader();
// A predicate for std::find_if() to locate a path to the module's header
// (e.g. QtGui/QtGui) to be used as pre-compiled header
struct FindPredicate
@@ -1353,8 +1409,7 @@ void ClangCodeParser::buildPCH()
tmpHeaderFile.close();
}
if (printParsingErrors_ == 0)
- Location::logToStdErrAlways(
- "clang not printing errors; include paths were guessed");
+ qCWarning(lcQdoc) << "clang not printing errors; include paths were guessed";
CXErrorCode err =
clang_parseTranslationUnit2(index_, tmpHeader.toLatin1().data(), args_.data(),
static_cast<int>(args_.size()), nullptr, 0,
@@ -1366,7 +1421,7 @@ void ClangCodeParser::buildPCH()
auto error = clang_saveTranslationUnit(tu, pchName_.constData(),
clang_defaultSaveOptions(tu));
if (error) {
- Location::logToStdErrAlways("Could not save PCH file for " + moduleHeader());
+ qCCritical(lcQdoc) << "Could not save PCH file for" << moduleHeader();
pchName_.clear();
} else {
// Visit the header now, as token from pre-compiled header won't be visited
@@ -1374,12 +1429,12 @@ void ClangCodeParser::buildPCH()
CXCursor cur = clang_getTranslationUnitCursor(tu);
ClangVisitor visitor(qdb_, allHeaders_);
visitor.visitChildren(cur);
- Location::logToStdErrAlways("PCH built & visited for " + moduleHeader());
+ qCDebug(lcQdoc) << "PCH built and visited for" << moduleHeader();
}
clang_disposeTranslationUnit(tu);
} else {
pchFileDir_->remove();
- Location::logToStdErrAlways("Could not create PCH file for " + moduleHeader());
+ qCCritical(lcQdoc) << "Could not create PCH file for " << moduleHeader();
}
args_.pop_back(); // remove the "-xc++";
}
@@ -1455,14 +1510,14 @@ void ClangCodeParser::parseSourceFile(const Location & /*location*/, const QStri
return;
}
- CXCursor cur = clang_getTranslationUnitCursor(tu);
+ CXCursor tuCur = clang_getTranslationUnitCursor(tu);
ClangVisitor visitor(qdb_, allHeaders_);
- visitor.visitChildren(cur);
+ visitor.visitChildren(tuCur);
CXToken *tokens;
unsigned int numTokens = 0;
const QSet<QString> &commands = topicCommands() + metaCommands();
- clang_tokenize(tu, clang_getCursorExtent(cur), &tokens, &numTokens);
+ clang_tokenize(tu, clang_getCursorExtent(tuCur), &tokens, &numTokens);
for (unsigned int i = 0; i < numTokens; ++i) {
if (clang_getTokenKind(tokens[i]) != CXToken_Comment)
@@ -1471,7 +1526,8 @@ void ClangCodeParser::parseSourceFile(const Location & /*location*/, const QStri
if (!comment.startsWith("/*!"))
continue;
- auto loc = fromCXSourceLocation(clang_getTokenLocation(tu, tokens[i]));
+ auto commentLoc = clang_getTokenLocation(tu, tokens[i]);
+ auto loc = fromCXSourceLocation(commentLoc);
auto end_loc = fromCXSourceLocation(clang_getRangeEnd(clang_getTokenExtent(tu, tokens[i])));
Doc::trimCStyleComment(loc, comment);
@@ -1488,7 +1544,6 @@ void ClangCodeParser::parseSourceFile(const Location & /*location*/, const QStri
topic = topics[0].topic;
if (topic.isEmpty()) {
- CXSourceLocation commentLoc = clang_getTokenLocation(tu, tokens[i]);
Node *n = nullptr;
if (i + 1 < numTokens) {
// Try to find the next declaration.
@@ -1520,6 +1575,17 @@ void ClangCodeParser::parseSourceFile(const Location & /*location*/, const QStri
}
}
} else {
+ // Store the namespace scope from lexical parents of the comment
+ namespaceScope_.clear();
+ CXCursor cur = clang_getCursor(tu, commentLoc);
+ while (true) {
+ CXCursorKind kind = clang_getCursorKind(cur);
+ if (clang_isTranslationUnit(kind) || clang_isInvalid(kind))
+ break;
+ if (kind == CXCursor_Namespace)
+ namespaceScope_ << fromCXString(clang_getCursorSpelling(cur));
+ cur = clang_getCursorLexicalParent(cur);
+ }
processTopicArgs(doc, topic, nodes, docs);
}
processMetaCommands(nodes, docs);
@@ -1528,6 +1594,7 @@ void ClangCodeParser::parseSourceFile(const Location & /*location*/, const QStri
clang_disposeTokens(tu, tokens, numTokens);
clang_disposeTranslationUnit(tu);
clang_disposeIndex(index_);
+ namespaceScope_.clear();
}
/*!
@@ -1606,9 +1673,14 @@ Node *ClangCodeParser::parseFnArg(const Location &location, const QString &fnArg
args.push_back(pchName_.constData());
}
CXTranslationUnit tu;
- QByteArray fn = fnArg.toUtf8();
+ QByteArray fn;
+ for (const auto &ns : qAsConst(namespaceScope_))
+ fn.prepend("namespace " + ns.toUtf8() + " {");
+ fn += fnArg.toUtf8();
if (!fn.endsWith(";"))
fn += "{ }";
+ fn.append(namespaceScope_.size(), '}');
+
const char *dummyFileName = "/fn_dummyfile.cpp";
CXUnsavedFile unsavedFile { dummyFileName, fn.constData(),
static_cast<unsigned long>(fn.size()) };
@@ -1639,7 +1711,8 @@ Node *ClangCodeParser::parseFnArg(const Location &location, const QString &fnArg
*/
if (fnNode == nullptr) {
unsigned diagnosticCount = clang_getNumDiagnostics(tu);
- if (diagnosticCount > 0 && (!Generator::preparing() || Generator::singleExec())) {
+ const auto &config = Config::instance();
+ if (diagnosticCount > 0 && (!config.preparing() || config.singleExec())) {
bool report = true;
QStringList signature = fnArg.split(QChar('('));
if (signature.size() > 1) {
diff --git a/src/qdoc/clangcodeparser.h b/src/qdoc/clangcodeparser.h
index b47c5f79c..9af292e67 100644
--- a/src/qdoc/clangcodeparser.h
+++ b/src/qdoc/clangcodeparser.h
@@ -53,7 +53,7 @@ class ClangCodeParser : public CppCodeParser
public:
~ClangCodeParser() override;
- void initializeParser(const Config &config) override;
+ void initializeParser() override;
void terminateParser() override;
QString language() override;
QStringList headerFileNameFilter() override;
@@ -78,6 +78,7 @@ private:
QVector<QByteArray> defines_;
std::vector<const char *> args_;
QVector<QByteArray> moreArgs_;
+ QStringList namespaceScope_;
};
QT_END_NAMESPACE
diff --git a/src/qdoc/codemarker.cpp b/src/qdoc/codemarker.cpp
index 000bf97f0..070218b6e 100644
--- a/src/qdoc/codemarker.cpp
+++ b/src/qdoc/codemarker.cpp
@@ -66,9 +66,7 @@ CodeMarker::~CodeMarker()
A code market performs no initialization by default. Marker-specific
initialization is performed in subclasses.
*/
-void CodeMarker::initializeMarker(const Config &) // config
-{
-}
+void CodeMarker::initializeMarker() {}
/*!
Terminating a code marker is trivial.
@@ -82,11 +80,11 @@ void CodeMarker::terminateMarker()
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)
+void CodeMarker::initialize()
{
- defaultLang = config.getString(CONFIG_LANGUAGE);
+ defaultLang = Config::instance().getString(CONFIG_LANGUAGE);
for (const auto &marker : qAsConst(markers))
- marker->initializeMarker(config);
+ marker->initializeMarker();
}
/*!
diff --git a/src/qdoc/codemarker.h b/src/qdoc/codemarker.h
index e17b82903..094908836 100644
--- a/src/qdoc/codemarker.h
+++ b/src/qdoc/codemarker.h
@@ -34,15 +34,13 @@
QT_BEGIN_NAMESPACE
-class Config;
-
class CodeMarker
{
public:
CodeMarker();
virtual ~CodeMarker();
- virtual void initializeMarker(const Config &config);
+ virtual void initializeMarker();
virtual void terminateMarker();
virtual bool recognizeCode(const QString & /*code*/) { return true; }
virtual bool recognizeExtension(const QString & /*extension*/) { return true; }
@@ -73,7 +71,7 @@ public:
virtual QString functionEndRegExp(const QString & /*funcName*/) { return QString(); }
virtual QStringList macRefsForNode(Node *node);
- static void initialize(const Config &config);
+ static void initialize();
static void terminate();
static CodeMarker *markerForCode(const QString &code);
static CodeMarker *markerForFileName(const QString &fileName);
diff --git a/src/qdoc/codeparser.cpp b/src/qdoc/codeparser.cpp
index 4f4589823..648a2de22 100644
--- a/src/qdoc/codeparser.cpp
+++ b/src/qdoc/codeparser.cpp
@@ -68,10 +68,10 @@ CodeParser::~CodeParser()
/*!
Initialize the code parser base class.
*/
-void CodeParser::initializeParser(const Config &config)
+void CodeParser::initializeParser()
{
- showInternal_ = config.getBool(CONFIG_SHOWINTERNAL);
- singleExec_ = config.getBool(CONFIG_SINGLEEXEC);
+ showInternal_ = Config::instance().getBool(CONFIG_SHOWINTERNAL);
+ singleExec_ = Config::instance().getBool(CONFIG_SINGLEEXEC);
}
/*!
@@ -96,10 +96,10 @@ void CodeParser::parseHeaderFile(const Location &location, const QString &filePa
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)
+void CodeParser::initialize()
{
for (const auto &parser : qAsConst(parsers))
- parser->initializeParser(config);
+ parser->initializeParser();
}
/*!
@@ -161,11 +161,11 @@ const QSet<QString> &CodeParser::commonMetaCommands()
<< COMMAND_INJSMODULE << COMMAND_INMODULE << COMMAND_INPUBLICGROUP
<< COMMAND_INQMLMODULE << COMMAND_INTERNAL << COMMAND_MAINCLASS
<< COMMAND_NOAUTOLIST << COMMAND_NONREENTRANT << COMMAND_OBSOLETE
- << COMMAND_PAGEKEYWORDS << COMMAND_PRELIMINARY << COMMAND_QMLABSTRACT
- << COMMAND_QMLDEFAULT << COMMAND_QMLINHERITS << COMMAND_QMLREADONLY
- << COMMAND_QTVARIABLE << COMMAND_REENTRANT << COMMAND_SINCE
- << COMMAND_STARTPAGE << COMMAND_SUBTITLE << COMMAND_THREADSAFE
- << COMMAND_TITLE << COMMAND_WRAPPER;
+ << COMMAND_PRELIMINARY << COMMAND_QMLABSTRACT << COMMAND_QMLDEFAULT
+ << COMMAND_QMLINHERITS << COMMAND_QMLREADONLY << COMMAND_QTVARIABLE
+ << COMMAND_REENTRANT << COMMAND_SINCE << COMMAND_STARTPAGE
+ << COMMAND_SUBTITLE << COMMAND_THREADSAFE << COMMAND_TITLE
+ << COMMAND_WRAPPER;
}
return commonMetaCommands_;
}
@@ -270,24 +270,27 @@ void CodeParser::checkModuleInclusion(Node *n)
{
if (n->physicalModuleName().isEmpty()) {
n->setPhysicalModuleName(Generator::defaultModuleName());
- QString word;
- switch (n->nodeType()) {
- case Node::Class:
- word = QLatin1String("Class");
- break;
- case Node::Struct:
- word = QLatin1String("Struct");
- break;
- case Node::Union:
- word = QLatin1String("Union");
- break;
- case Node::Namespace:
- word = QLatin1String("Namespace");
- break;
- default:
- return;
- }
+
if (n->isInAPI() && !n->name().isEmpty()) {
+ QString word;
+ switch (n->nodeType()) {
+ case Node::Class:
+ word = QLatin1String("Class");
+ break;
+ case Node::Struct:
+ word = QLatin1String("Struct");
+ break;
+ case Node::Union:
+ word = QLatin1String("Union");
+ break;
+ case Node::Namespace:
+ word = QLatin1String("Namespace");
+ break;
+ default:
+ return;
+ }
+
+ qdb_->addToModule(Generator::defaultModuleName(), n);
n->doc().location().warning(tr("%1 %2 has no \\inmodule command; "
"using project name by default: %3")
.arg(word)
diff --git a/src/qdoc/codeparser.h b/src/qdoc/codeparser.h
index 7e1e551e4..7ae34df1d 100644
--- a/src/qdoc/codeparser.h
+++ b/src/qdoc/codeparser.h
@@ -35,7 +35,6 @@
QT_BEGIN_NAMESPACE
-class Config;
class Location;
class QString;
class QDocDatabase;
@@ -48,7 +47,7 @@ public:
CodeParser();
virtual ~CodeParser();
- virtual void initializeParser(const Config &config);
+ virtual void initializeParser();
virtual void terminateParser();
virtual QString language() = 0;
virtual QStringList headerFileNameFilter();
@@ -66,7 +65,7 @@ public:
void setModuleHeader(const QString &t) { moduleHeader_ = t; }
void checkModuleInclusion(Node *n);
- static void initialize(const Config &config);
+ static void initialize();
static void terminate();
static CodeParser *parserForLanguage(const QString &language);
static CodeParser *parserForHeaderFile(const QString &filePath);
@@ -138,7 +137,6 @@ private:
#define COMMAND_OBSOLETE Doc::alias(QLatin1String("obsolete"))
#define COMMAND_OVERLOAD Doc::alias(QLatin1String("overload"))
#define COMMAND_PAGE Doc::alias(QLatin1String("page"))
-#define COMMAND_PAGEKEYWORDS Doc::alias(QLatin1String("pagekeywords"))
#define COMMAND_PERMISSIONS Doc::alias(QLatin1String("permissions"))
#define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary"))
#define COMMAND_PREVIOUSPAGE Doc::alias(QLatin1String("previouspage"))
diff --git a/src/qdoc/config.cpp b/src/qdoc/config.cpp
index 934958910..1387fb411 100644
--- a/src/qdoc/config.cpp
+++ b/src/qdoc/config.cpp
@@ -31,7 +31,7 @@
*/
#include "config.h"
-#include "generator.h"
+#include "loggingcategory.h"
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
@@ -56,6 +56,7 @@ QString ConfigStrings::CPPCLASSESTITLE = QStringLiteral("cppclassestitle");
QString ConfigStrings::DEFINES = QStringLiteral("defines");
QString ConfigStrings::DEPENDS = QStringLiteral("depends");
QString ConfigStrings::DESCRIPTION = QStringLiteral("description");
+QString ConfigStrings::DOCBOOKEXTENSIONS = QStringLiteral("usedocbookextensions");
QString ConfigStrings::EDITION = QStringLiteral("edition");
QString ConfigStrings::ENDHEADER = QStringLiteral("endheader");
QString ConfigStrings::EXAMPLEDIRS = QStringLiteral("exampledirs");
@@ -73,6 +74,7 @@ QString ConfigStrings::HEADERSTYLES = QStringLiteral("headerstyles");
QString ConfigStrings::HOMEPAGE = QStringLiteral("homepage");
QString ConfigStrings::HOMETITLE = QStringLiteral("hometitle");
QString ConfigStrings::IGNOREDIRECTIVES = QStringLiteral("ignoredirectives");
+QString ConfigStrings::IGNORESINCE = QStringLiteral("ignoresince");
QString ConfigStrings::IGNORETOKENS = QStringLiteral("ignoretokens");
QString ConfigStrings::IGNOREWORDS = QStringLiteral("ignorewords");
QString ConfigStrings::IMAGEDIRS = QStringLiteral("imagedirs");
@@ -82,6 +84,8 @@ QString ConfigStrings::INDEXES = QStringLiteral("indexes");
QString ConfigStrings::LANDINGPAGE = QStringLiteral("landingpage");
QString ConfigStrings::LANDINGTITLE = QStringLiteral("landingtitle");
QString ConfigStrings::LANGUAGE = QStringLiteral("language");
+QString ConfigStrings::LOCATIONINFO = QStringLiteral("locationinfo");
+QString ConfigStrings::LOGPROGRESS = QStringLiteral("logprogress");
QString ConfigStrings::MACRO = QStringLiteral("macro");
QString ConfigStrings::MANIFESTMETA = QStringLiteral("manifestmeta");
QString ConfigStrings::MODULEHEADER = QStringLiteral("moduleheader");
@@ -114,6 +118,7 @@ QString ConfigStrings::STYLESHEETS = QStringLiteral("stylesheets");
QString ConfigStrings::SYNTAXHIGHLIGHTING = QStringLiteral("syntaxhighlighting");
QString ConfigStrings::TABSIZE = QStringLiteral("tabsize");
QString ConfigStrings::TAGFILE = QStringLiteral("tagfile");
+QString ConfigStrings::TIMESTAMPS = QStringLiteral("timestamps");
QString ConfigStrings::TRANSLATORS = QStringLiteral("translators");
QString ConfigStrings::URL = QStringLiteral("url");
QString ConfigStrings::VERSION = QStringLiteral("version");
@@ -235,15 +240,14 @@ QStringList MetaStack::getExpanded(const Location &location)
}
const QString Config::dot = QLatin1String(".");
-bool Config::debug_ = false;
+bool Config::m_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_;
+QMap<QString, QString> Config::m_extractedDirs;
+QStack<QString> Config::m_workingDirs;
+QMap<QString, QStringList> Config::m_includeFilesMap;
/*!
\class Config
@@ -254,13 +258,13 @@ QMap<QString, QStringList> Config::includeFilesMap_;
*/
/*!
- The constructor sets the \a programName and initializes all
+ Initializes the Config with \a programName and sets all
internal state variables to either default values or to ones
defined in command line arguments \a args.
*/
-Config::Config(const QString &programName, const QStringList &args) : prog(programName)
+void Config::init(const QString &programName, const QStringList &args)
{
- ++numInstances;
+ m_prog = programName;
processCommandLineOptions(args);
reset();
}
@@ -275,9 +279,9 @@ Config::~Config()
*/
void Config::clear()
{
- loc = lastLocation_ = Location();
- configVars_.clear();
- includeFilesMap_.clear();
+ m_location = m_lastLocation = Location();
+ m_configVars.clear();
+ m_includeFilesMap.clear();
}
/*!
@@ -294,6 +298,7 @@ void Config::reset()
setStringList(CONFIG_LANGUAGE, QStringList("Cpp")); // i.e. C++
setStringList(CONFIG_OUTPUTFORMATS, QStringList("HTML"));
setStringList(CONFIG_TABSIZE, QStringList("8"));
+ setStringList(CONFIG_LOCATIONINFO, QStringList("true"));
// Publish options from the command line as config variables
const auto setListFlag = [this](const QString &key, bool test) {
@@ -324,21 +329,25 @@ void Config::reset()
void Config::load(const QString &fileName)
{
// Reset if a previous project was loaded
- if (configVars_.contains(CONFIG_PROJECT))
+ if (m_configVars.contains(CONFIG_PROJECT))
reset();
load(Location(), fileName);
- if (loc.isEmpty())
- loc = Location(fileName);
+ if (m_location.isEmpty())
+ m_location = Location(fileName);
else
- loc.setEtc(true);
- lastLocation_ = Location();
+ m_location.setEtc(true);
+ m_lastLocation = Location();
// Add defines and includepaths from command line to their
// respective configuration variables. Values set here are
// always added to what's defined in configuration file.
insertStringList(CONFIG_DEFINES, m_defines);
insertStringList(CONFIG_INCLUDEPATHS, m_includePaths);
+
+ // Prefetch values that are used internally
+ m_exampleFiles = getCanonicalPathList(CONFIG_EXAMPLES);
+ m_exampleDirs = getCanonicalPathList(CONFIG_EXAMPLEDIRS);
}
/*!
@@ -346,7 +355,7 @@ void Config::load(const QString &fileName)
*/
void Config::setStringList(const QString &var, const QStringList &values)
{
- configVars_.replace(var, ConfigVar(var, values, QDir::currentPath()));
+ m_configVars.replace(var, ConfigVar(var, values, QDir::currentPath()));
}
/*!
@@ -355,7 +364,7 @@ void Config::setStringList(const QString &var, const QStringList &values)
*/
void Config::insertStringList(const QString &var, const QStringList &values)
{
- configVars_.insert(var, ConfigVar(var, values, QDir::currentPath()));
+ m_configVars.insert(var, ConfigVar(var, values, QDir::currentPath()));
}
/*!
@@ -380,21 +389,22 @@ void Config::processCommandLineOptions(const QStringList &args)
for (const auto &format : outputFormats)
overrideOutputFormats.insert(format);
- debug_ = m_parser.isSet(m_parser.debugOption);
+ m_debug = m_parser.isSet(m_parser.debugOption);
- // TODO: Make Generator use Config instead of storing these separately
if (m_parser.isSet(m_parser.prepareOption))
- Generator::setQDocPass(Generator::Prepare);
+ m_qdocPass = Prepare;
if (m_parser.isSet(m_parser.generateOption))
- Generator::setQDocPass(Generator::Generate);
- if (m_parser.isSet(m_parser.singleExecOption))
- Generator::setSingleExec();
- if (m_parser.isSet(m_parser.writeQaPagesOption))
- Generator::setWriteQaPages();
+ m_qdocPass = Generate;
+ if (m_parser.isSet(m_parser.writeQaPagesOption)) {
+ qCWarning(lcQdoc,
+ "The QA pages option for QDoc is deprecated and will be removed in Qt 6.");
+ }
if (m_parser.isSet(m_parser.logProgressOption))
- Location::startLoggingProgress();
+ setStringList(CONFIG_LOGPROGRESS, QStringList("true"));
if (m_parser.isSet(m_parser.timestampsOption))
- Generator::setUseTimestamps();
+ setStringList(CONFIG_TIMESTAMPS, QStringList("true"));
+ if (m_parser.isSet(m_parser.useDocBookExtensions))
+ setStringList(CONFIG_DOCBOOKEXTENSIONS, QStringList("true"));
}
void Config::setIncludePaths()
@@ -422,7 +432,7 @@ void Config::setIndexDirs()
[](const QString &s) { return !QFile::exists(s); });
std::for_each(it, m_indexDirs.end(), [](const QString &s) {
- Location::logToStdErrAlways(tr("Cannot find index directory: %1").arg(s));
+ qCWarning(lcQdoc) << "Cannot find index directory: " << s;
});
m_indexDirs.erase(it, m_indexDirs.end());
}
@@ -467,7 +477,7 @@ QString Config::getOutputDir(const QString &format) const
t = getString(CONFIG_OUTPUTDIR);
else
t = overrideOutputDir;
- if (Generator::singleExec()) {
+ if (getBool(CONFIG_SINGLEEXEC)) {
QString project = getString(CONFIG_PROJECT);
t += QLatin1Char('/') + project.toLower();
}
@@ -512,21 +522,21 @@ QSet<QString> Config::getOutputFormats() const
*/
QString Config::getString(const QString &var, const QString &defaultString) const
{
- QList<ConfigVar> configVars = configVars_.values(var);
+ QList<ConfigVar> configVars = m_configVars.values(var);
if (!configVars.empty()) {
QString value("");
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_)
+ if (!cv.m_location.isEmpty())
+ const_cast<Config *>(this)->m_lastLocation = cv.m_location;
+ if (!cv.m_values.isEmpty()) {
+ if (!cv.m_plus)
value.clear();
- for (int j = 0; j < cv.values_.size(); ++j) {
+ for (int j = 0; j < cv.m_values.size(); ++j) {
if (!value.isEmpty() && !value.endsWith(QChar('\n')))
value.append(QChar(' '));
- value.append(cv.values_[j]);
+ value.append(cv.m_values[j]);
}
}
--i;
@@ -562,17 +572,17 @@ QSet<QString> Config::getStringSet(const QString &var) const
*/
QStringList Config::getStringList(const QString &var) const
{
- QList<ConfigVar> configVars = configVars_.values(var);
+ QList<ConfigVar> configVars = m_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_);
+ if (!configVars[i].m_location.isEmpty())
+ const_cast<Config *>(this)->m_lastLocation = configVars[i].m_location;
+ if (configVars[i].m_plus)
+ values.append(configVars[i].m_values);
else
- values = configVars[i].values_;
+ values = configVars[i].m_values;
--i;
}
}
@@ -597,17 +607,17 @@ QStringList Config::getStringList(const QString &var) const
QStringList Config::getCanonicalPathList(const QString &var, bool validate) const
{
QStringList t;
- QList<ConfigVar> configVars = configVars_.values(var);
+ QList<ConfigVar> configVars = m_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_)
+ if (!cv.m_location.isEmpty())
+ const_cast<Config *>(this)->m_lastLocation = cv.m_location;
+ if (!cv.m_plus)
t.clear();
- const QString d = cv.currentPath_;
- const QStringList &sl = cv.values_;
+ const QString d = cv.m_currentPath;
+ const QStringList &sl = cv.m_values;
if (!sl.isEmpty()) {
t.reserve(t.size() + sl.size());
for (int i = 0; i < sl.size(); ++i) {
@@ -616,7 +626,7 @@ QStringList Config::getCanonicalPathList(const QString &var, bool validate) cons
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));
+ m_lastLocation.warning(tr("Cannot find file or directory: %1").arg(path));
else {
QString canonicalPath = dir.canonicalPath();
if (!canonicalPath.isEmpty())
@@ -681,7 +691,7 @@ QSet<QString> Config::subVars(const QString &var) const
{
QSet<QString> result;
QString varDot = var + QLatin1Char('.');
- for (auto it = configVars_.constBegin(); it != configVars_.constEnd(); ++it) {
+ for (auto it = m_configVars.constBegin(); it != m_configVars.constEnd(); ++it) {
if (it.key().startsWith(varDot)) {
QString subVar = it.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
@@ -702,7 +712,7 @@ QSet<QString> Config::subVars(const QString &var) const
void Config::subVarsAndValues(const QString &var, ConfigVarMultimap &t) const
{
QString varDot = var + QLatin1Char('.');
- for (auto it = configVars_.constBegin(); it != configVars_.constEnd(); ++it) {
+ for (auto it = m_configVars.constBegin(); it != m_configVars.constEnd(); ++it) {
if (it.key().startsWith(varDot)) {
QString subVar = it.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
@@ -721,7 +731,7 @@ QString Config::getIncludeFilePath(const QString &fileName) const
QString ext = fileName.mid(fileName.lastIndexOf('.'));
ext.prepend('*');
- if (!includeFilesMap_.contains(ext)) {
+ if (!m_includeFilesMap.contains(ext)) {
QSet<QString> t;
QStringList result;
const auto sourceDirs = getCanonicalPathList(CONFIG_SOURCEDIRS);
@@ -731,9 +741,9 @@ QString Config::getIncludeFilePath(const QString &fileName) const
const auto exampleDirs = getCanonicalPathList(CONFIG_EXAMPLEDIRS);
for (const auto &dir : exampleDirs)
result += getFilesHere(dir, ext, location(), t, t);
- includeFilesMap_.insert(ext, result);
+ m_includeFilesMap.insert(ext, result);
}
- const QStringList &paths = (*includeFilesMap_.find(ext));
+ const QStringList &paths = (*m_includeFilesMap.find(ext));
for (const auto &path : paths) {
if (path.endsWith(fileName))
return path;
@@ -789,6 +799,32 @@ QStringList Config::getExampleImageFiles(const QSet<QString> &excludedDirs,
}
/*!
+ Returns the path to the project file for \a examplePath, or an empty string
+ if no project file was found.
+ */
+QString Config::getExampleProjectFile(const QString &examplePath)
+{
+ QFileInfo fileInfo(examplePath);
+ QStringList validNames;
+ validNames << fileInfo.fileName() + QLatin1String(".pro")
+ << fileInfo.fileName() + QLatin1String(".qmlproject")
+ << fileInfo.fileName() + QLatin1String(".pyproject")
+ << QLatin1String("CMakeLists.txt")
+ << QLatin1String("qbuild.pro"); // legacy
+
+ QString projectFile;
+
+ for (const auto &name : qAsConst(validNames)) {
+ projectFile = Config::findFile(Location(), m_exampleFiles, m_exampleDirs,
+ examplePath + QLatin1Char('/') + name);
+ if (!projectFile.isEmpty())
+ return projectFile;
+ }
+
+ return projectFile;
+}
+
+/*!
\a fileName is the path of the file to find.
\a files and \a dirs are the lists where we must find the
@@ -839,7 +875,7 @@ QString Config::findFile(const Location &location, const QStringList &files,
userFriendlyFilePath->append(*c);
if (isArchive) {
- QString extracted = extractedDirs[fileInfo.filePath()];
+ QString extracted = m_extractedDirs[fileInfo.filePath()];
++c;
fileInfo.setFile(QDir(extracted), *c);
} else {
@@ -987,9 +1023,10 @@ QStringList Config::loadMaster(const QString &fileName)
stream.setCodec("UTF-8");
#endif
QStringList qdocFiles;
+ QDir configDir(QFileInfo(fileName).canonicalPath());
QString line = stream.readLine();
while (!line.isNull()) {
- qdocFiles.append(line);
+ qdocFiles.append(QFileInfo(configDir, line).filePath());
line = stream.readLine();
}
fin.close();
@@ -1214,9 +1251,9 @@ void Config::load(Location location, const QString &fileName)
keyLoc.fatal(tr("Invalid key '%1'").arg(key));
ConfigVarMultimap::Iterator i;
- i = configVars_.insert(key,
+ i = m_configVars.insert(key,
ConfigVar(key, rhsValues, QDir::currentPath(), keyLoc));
- i.value().plus_ = plus;
+ i.value().m_plus = plus;
}
}
} else {
@@ -1224,8 +1261,8 @@ void Config::load(Location location, const QString &fileName)
}
}
popWorkingDir();
- if (!workingDirs_.isEmpty())
- QDir::setCurrent(workingDirs_.top());
+ if (!m_workingDirs.isEmpty())
+ QDir::setCurrent(m_workingDirs.top());
}
bool Config::isFileExcluded(const QString &fileName, const QSet<QString> &excludedFiles)
@@ -1279,7 +1316,7 @@ QStringList Config::getFilesHere(const QString &uncleanDir, const QString &nameF
*/
void Config::pushWorkingDir(const QString &dir)
{
- workingDirs_.push(dir);
+ m_workingDirs.push(dir);
}
/*!
@@ -1288,8 +1325,8 @@ void Config::pushWorkingDir(const QString &dir)
*/
QString Config::popWorkingDir()
{
- if (!workingDirs_.isEmpty())
- return workingDirs_.pop();
+ if (!m_workingDirs.isEmpty())
+ return m_workingDirs.pop();
qDebug() << "RETURNED EMPTY WORKING DIR";
return QString();
diff --git a/src/qdoc/config.h b/src/qdoc/config.h
index 451946ecd..f8823d521 100644
--- a/src/qdoc/config.h
+++ b/src/qdoc/config.h
@@ -44,28 +44,44 @@
QT_BEGIN_NAMESPACE
+template<typename T>
+class Singleton
+{
+public:
+ Singleton(const Singleton &) = delete;
+ Singleton &operator=(const Singleton &) = delete;
+ static T &instance()
+ {
+ static T instance;
+ return instance;
+ }
+
+protected:
+ Singleton() = default;
+};
+
/*
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_;
+ bool m_plus {};
+ QString m_name {};
+ QStringList m_values {};
+ QString m_currentPath {};
+ Location m_location {};
- ConfigVar() : plus_(false) {}
+ ConfigVar() : m_plus(false) {}
ConfigVar(const QString &name, const QStringList &values, const QString &dir)
- : plus_(true), name_(name), values_(values), currentPath_(dir)
+ : m_plus(true), m_name(name), m_values(values), m_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)
+ : m_plus(false), m_name(name), m_values(values), m_currentPath(dir), m_location(loc)
{
}
};
@@ -75,15 +91,17 @@ struct ConfigVar
*/
typedef QMultiMap<QString, ConfigVar> ConfigVarMultimap;
-class Config
+class Config : public Singleton<Config>
{
Q_DECLARE_TR_FUNCTIONS(QDoc::Config)
public:
- Config(const QString &programName, const QStringList &args);
~Config();
- bool getDebug() const { return debug_; }
+ enum QDocPass { Neither, Prepare, Generate };
+
+ void init(const QString &programName, const QStringList &args);
+ bool getDebug() const { return m_debug; }
void clear();
void reset();
@@ -93,9 +111,9 @@ public:
void showHelp(int exitCode = 0) { m_parser.showHelp(exitCode); }
QStringList qdocFiles() const { return m_parser.positionalArguments(); }
- const QString &programName() const { return prog; }
- const Location &location() const { return loc; }
- const Location &lastLocation() const { return lastLocation_; }
+ const QString &programName() const { return m_prog; }
+ const Location &location() const { return m_location; }
+ const Location &lastLocation() const { return m_lastLocation; }
bool getBool(const QString &var) const;
int getInt(const QString &var) const;
@@ -117,6 +135,7 @@ public:
const QSet<QString> &excludedFiles);
QStringList getExampleImageFiles(const QSet<QString> &excludedDirs,
const QSet<QString> &excludedFiles);
+ QString getExampleProjectFile(const QString &examplePath);
static QStringList loadMaster(const QString &fileName);
static bool isFileExcluded(const QString &fileName, const QSet<QString> &excludedFiles);
@@ -147,6 +166,7 @@ public:
static QSet<QString> overrideOutputFormats;
inline bool singleExec() const;
+ inline bool dualExec() const;
QStringList &defines() { return m_defines; }
QStringList &dependModules() { return m_dependModules; }
QStringList &includePaths() { return m_includePaths; }
@@ -156,33 +176,41 @@ public:
QString previousCurrentDir() const { return m_previousCurrentDir; }
void setPreviousCurrentDir(const QString &path) { m_previousCurrentDir = path; }
+ QDocPass qdocPass() const { return m_qdocPass; }
+ void setQDocPass(const QDocPass &pass) { m_qdocPass = pass; };
+ bool preparing() const { return (m_qdocPass == Prepare); }
+ bool generating() const { return (m_qdocPass == Generate); }
+
private:
void processCommandLineOptions(const QStringList &args);
void setIncludePaths();
void setIndexDirs();
- QStringList m_dependModules;
- QStringList m_defines;
- QStringList m_includePaths;
- QStringList m_indexDirs;
- QString m_currentDir;
- QString m_previousCurrentDir;
+ QStringList m_dependModules {};
+ QStringList m_defines {};
+ QStringList m_includePaths {};
+ QStringList m_indexDirs {};
+ QStringList m_exampleFiles {};
+ QStringList m_exampleDirs {};
+ QString m_currentDir {};
+ QString m_previousCurrentDir {};
- static bool debug_;
+ static bool m_debug;
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_;
- QDocCommandLineParser m_parser;
+ QString m_prog {};
+ Location m_location {};
+ Location m_lastLocation {};
+ ConfigVarMultimap m_configVars {};
+
+ static QMap<QString, QString> m_uncompressedFiles;
+ static QMap<QString, QString> m_extractedDirs;
+ static QStack<QString> m_workingDirs;
+ static QMap<QString, QStringList> m_includeFilesMap;
+ QDocCommandLineParser m_parser {};
+
+ QDocPass m_qdocPass { Neither };
};
struct ConfigStrings
@@ -199,6 +227,7 @@ struct ConfigStrings
static QString DEFINES;
static QString DEPENDS;
static QString DESCRIPTION;
+ static QString DOCBOOKEXTENSIONS;
static QString EDITION;
static QString ENDHEADER;
static QString EXAMPLEDIRS;
@@ -217,6 +246,7 @@ struct ConfigStrings
static QString HOMETITLE;
static QString IGNOREDIRECTIVES;
static QString IGNORETOKENS;
+ static QString IGNORESINCE;
static QString IGNOREWORDS;
static QString IMAGEDIRS;
static QString IMAGES;
@@ -225,6 +255,8 @@ struct ConfigStrings
static QString LANDINGPAGE;
static QString LANDINGTITLE;
static QString LANGUAGE;
+ static QString LOCATIONINFO;
+ static QString LOGPROGRESS;
static QString MACRO;
static QString MANIFESTMETA;
static QString MODULEHEADER;
@@ -256,6 +288,7 @@ struct ConfigStrings
static QString SYNTAXHIGHLIGHTING;
static QString TABSIZE;
static QString TAGFILE;
+ static QString TIMESTAMPS;
static QString TRANSLATORS;
static QString URL;
static QString VERSION;
@@ -281,6 +314,7 @@ struct ConfigStrings
#define CONFIG_DEFINES ConfigStrings::DEFINES
#define CONFIG_DEPENDS ConfigStrings::DEPENDS
#define CONFIG_DESCRIPTION ConfigStrings::DESCRIPTION
+#define CONFIG_DOCBOOKEXTENSIONS ConfigStrings::DOCBOOKEXTENSIONS
#define CONFIG_EDITION ConfigStrings::EDITION
#define CONFIG_ENDHEADER ConfigStrings::ENDHEADER
#define CONFIG_EXAMPLEDIRS ConfigStrings::EXAMPLEDIRS
@@ -298,6 +332,7 @@ struct ConfigStrings
#define CONFIG_HOMEPAGE ConfigStrings::HOMEPAGE
#define CONFIG_HOMETITLE ConfigStrings::HOMETITLE
#define CONFIG_IGNOREDIRECTIVES ConfigStrings::IGNOREDIRECTIVES
+#define CONFIG_IGNORESINCE ConfigStrings::IGNORESINCE
#define CONFIG_IGNORETOKENS ConfigStrings::IGNORETOKENS
#define CONFIG_IGNOREWORDS ConfigStrings::IGNOREWORDS
#define CONFIG_IMAGEDIRS ConfigStrings::IMAGEDIRS
@@ -307,6 +342,8 @@ struct ConfigStrings
#define CONFIG_LANDINGPAGE ConfigStrings::LANDINGPAGE
#define CONFIG_LANDINGTITLE ConfigStrings::LANDINGTITLE
#define CONFIG_LANGUAGE ConfigStrings::LANGUAGE
+#define CONFIG_LOCATIONINFO ConfigStrings::LOCATIONINFO
+#define CONFIG_LOGPROGRESS ConfigStrings::LOGPROGRESS
#define CONFIG_MACRO ConfigStrings::MACRO
#define CONFIG_MANIFESTMETA ConfigStrings::MANIFESTMETA
#define CONFIG_MODULEHEADER ConfigStrings::MODULEHEADER
@@ -338,6 +375,7 @@ struct ConfigStrings
#define CONFIG_SYNTAXHIGHLIGHTING ConfigStrings::SYNTAXHIGHLIGHTING
#define CONFIG_TABSIZE ConfigStrings::TABSIZE
#define CONFIG_TAGFILE ConfigStrings::TAGFILE
+#define CONFIG_TIMESTAMPS ConfigStrings::TIMESTAMPS
#define CONFIG_TRANSLATORS ConfigStrings::TRANSLATORS
#define CONFIG_URL ConfigStrings::URL
#define CONFIG_VERSION ConfigStrings::VERSION
@@ -355,6 +393,11 @@ inline bool Config::singleExec() const
return getBool(CONFIG_SINGLEEXEC);
}
+inline bool Config::dualExec() const
+{
+ return !getBool(CONFIG_SINGLEEXEC);
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp
index b23312d19..38dd8e79f 100644
--- a/src/qdoc/cppcodemarker.cpp
+++ b/src/qdoc/cppcodemarker.cpp
@@ -136,9 +136,13 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, const Node * /* relati
break;
case Node::Function:
func = (const FunctionNode *)node;
-
+ if (style == Section::Details) {
+ QString templateDecl = node->templateDecl();
+ if (!templateDecl.isEmpty())
+ synopsis = templateDecl + QLatin1Char(' ');
+ }
if (style != Section::AllMembers && !func->returnType().isEmpty())
- synopsis = typified(func->returnType(), true);
+ synopsis += typified(func->returnType(), true);
synopsis += name;
if (!func->isMacroWithoutParams()) {
synopsis += QLatin1Char('(');
@@ -217,7 +221,10 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, const Node * /* relati
break;
case Node::Enum:
enume = static_cast<const EnumNode *>(node);
- synopsis = "enum " + name;
+ synopsis = "enum ";
+ if (enume->isScoped())
+ synopsis += "class ";
+ synopsis += name;
if (style == Section::Summary) {
synopsis += " { ";
@@ -378,18 +385,18 @@ QString CppCodeMarker::markedUpEnumValue(const QString &enumValue, const Node *r
return enumValue;
const Node *node = relative->parent();
- QString fullName;
- while (node->parent()) {
- fullName.prepend(markedUpName(node));
+ QStringList parts;
+ while (!node->isHeader() && node->parent()) {
+ parts.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;
+ if (static_cast<const EnumNode *>(relative)->isScoped())
+ parts.append(relative->name());
+
+ parts.append(enumValue);
+ return parts.join(QLatin1String("<@op>::</@op>"));
}
QString CppCodeMarker::markedUpIncludes(const QStringList &includes)
diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp
index c60957793..ed12f64c2 100644
--- a/src/qdoc/cppcodeparser.cpp
+++ b/src/qdoc/cppcodeparser.cpp
@@ -33,8 +33,9 @@
#include "cppcodeparser.h"
#include "config.h"
-#include "qdocdatabase.h"
#include "generator.h"
+#include "loggingcategory.h"
+#include "qdocdatabase.h"
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
@@ -47,8 +48,6 @@ QT_BEGIN_NAMESPACE
/* qmake ignore Q_OBJECT */
-QStringList CppCodeParser::exampleFiles;
-QStringList CppCodeParser::exampleDirs;
QSet<QString> CppCodeParser::excludeDirs;
QSet<QString> CppCodeParser::excludeFiles;
@@ -90,9 +89,9 @@ CppCodeParser::CppCodeParser()
for identifying important nodes. And it initializes
some filters for identifying and excluding certain kinds of files.
*/
-void CppCodeParser::initializeParser(const Config &config)
+void CppCodeParser::initializeParser()
{
- CodeParser::initializeParser(config);
+ CodeParser::initializeParser();
/*
All these can appear in a C++ namespace. Don't add
@@ -118,8 +117,7 @@ void CppCodeParser::initializeParser(const Config &config)
nodeTypeTestFuncMap_.insert(COMMAND_PROPERTY, &Node::isProperty);
nodeTypeTestFuncMap_.insert(COMMAND_VARIABLE, &Node::isVariable);
- exampleFiles = config.getCanonicalPathList(CONFIG_EXAMPLES);
- exampleDirs = config.getCanonicalPathList(CONFIG_EXAMPLEDIRS);
+ Config &config = Config::instance();
QStringList exampleFilePatterns =
config.getStringList(CONFIG_EXAMPLES + Config::dot + CONFIG_FILEEXTENSIONS);
@@ -558,6 +556,7 @@ void CppCodeParser::processMetaCommand(const Doc &doc, const QString &command,
}
}
} else if (command == COMMAND_CONTENTSPAGE) {
+ qCWarning(lcQdoc, "(qdoc) The \\contentspage command is obsolete and should not be used.");
setLink(node, Node::ContentsLink, arg);
} else if (command == COMMAND_NEXTPAGE) {
setLink(node, Node::NextLink, arg);
@@ -619,8 +618,6 @@ void CppCodeParser::processMetaCommand(const Doc &doc, const QString &command,
node->setSince(arg);
} else if (command == COMMAND_WRAPPER) {
node->setWrapper();
- } else if (command == COMMAND_PAGEKEYWORDS) {
- node->addPageKeywords(arg);
} else if (command == COMMAND_THREADSAFE) {
node->setThreadSafeness(Node::ThreadSafe);
} else if (command == COMMAND_TITLE) {
@@ -770,58 +767,29 @@ FunctionNode *CppCodeParser::parseMacroArg(const Location &location, const QStri
return macro;
}
-void CppCodeParser::setExampleFileLists(PageNode *pn)
+void CppCodeParser::setExampleFileLists(ExampleNode *en)
{
- QString examplePath = pn->name();
- QString proFileName =
- examplePath + QLatin1Char('/') + examplePath.split(QLatin1Char('/')).last() + ".pro";
- QString fullPath =
- Config::findFile(pn->doc().location(), exampleFiles, exampleDirs, proFileName);
-
+ Config &config = Config::instance();
+ QString fullPath = config.getExampleProjectFile(en->name());
if (fullPath.isEmpty()) {
- QString tmp = proFileName;
- proFileName = examplePath + QLatin1Char('/') + "qbuild.pro";
- fullPath = Config::findFile(pn->doc().location(), exampleFiles, exampleDirs, proFileName);
- if (fullPath.isEmpty()) {
- proFileName = examplePath + QLatin1Char('/')
- + examplePath.split(QLatin1Char('/')).last() + ".qmlproject";
- fullPath =
- Config::findFile(pn->doc().location(), exampleFiles, exampleDirs, proFileName);
- if (fullPath.isEmpty()) {
- proFileName = examplePath + QLatin1Char('/')
- + examplePath.split(QLatin1Char('/')).last() + ".pyproject";
- fullPath = Config::findFile(pn->doc().location(), exampleFiles, exampleDirs,
- proFileName);
- if (fullPath.isEmpty()) {
- QString details = QLatin1String("Example directories: ")
- + exampleDirs.join(QLatin1Char(' '));
- if (!exampleFiles.isEmpty())
- details += QLatin1String(", example files: ")
- + exampleFiles.join(QLatin1Char(' '));
- pn->location().warning(
- tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName), details);
- pn->location().warning(tr(" EXAMPLE PATH DOES NOT EXIST: %1").arg(examplePath),
- details);
- return;
- }
- }
- }
+ QString details = QLatin1String("Example directories: ")
+ + config.getCanonicalPathList(CONFIG_EXAMPLEDIRS).join(QLatin1Char(' '));
+ en->location().warning(
+ tr("Cannot find project file for example '%1'").arg(en->name()), details);
+ return;
}
- int sizeOfBoringPartOfName = fullPath.size() - proFileName.size();
- if (fullPath.startsWith("./"))
- sizeOfBoringPartOfName = sizeOfBoringPartOfName - 2;
- fullPath.truncate(fullPath.lastIndexOf('/'));
+ QDir exampleDir(QFileInfo(fullPath).dir());
- QStringList exampleFiles = Config::getFilesHere(fullPath, exampleNameFilter, Location(),
+ QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), exampleNameFilter, Location(),
excludeDirs, excludeFiles);
// Search for all image files under the example project, excluding doc/images directory.
QSet<QString> excludeDocDirs(excludeDirs);
- excludeDocDirs.insert(QDir(fullPath).canonicalPath() + "/doc/images");
- QStringList imageFiles = Config::getFilesHere(fullPath, exampleImageFilter, Location(),
+ excludeDocDirs.insert(exampleDir.path() + QLatin1String("/doc/images"));
+ QStringList imageFiles = Config::getFilesHere(exampleDir.path(), exampleImageFilter, Location(),
excludeDocDirs, excludeFiles);
if (!exampleFiles.isEmpty()) {
- // move main.cpp and to the end, if it exists
+ // move main.cpp to the end, if it exists
QString mainCpp;
const auto isGeneratedOrMainCpp = [&mainCpp](const QString &fileName) {
@@ -841,16 +809,19 @@ void CppCodeParser::setExampleFileLists(PageNode *pn)
if (!mainCpp.isEmpty())
exampleFiles.append(mainCpp);
- // add any qmake Qt resource files and qmake project files
- exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro *.qmlproject qmldir");
+ // Add any resource and project files
+ exampleFiles += Config::getFilesHere(exampleDir.path(),
+ QLatin1String("*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"));
}
+ exampleDir.cdUp();
+ int pathLen = exampleDir.path().size() + 1;
for (auto &file : exampleFiles)
- file = file.mid(sizeOfBoringPartOfName);
+ file = file.mid(pathLen);
for (auto &file : imageFiles)
- file = file.mid(sizeOfBoringPartOfName);
- ExampleNode *en = static_cast<ExampleNode *>(pn);
- en->setFiles(exampleFiles);
+ file = file.mid(pathLen);
+
+ en->setFiles(exampleFiles, fullPath.mid(pathLen));
en->setImages(imageFiles);
}
diff --git a/src/qdoc/cppcodeparser.h b/src/qdoc/cppcodeparser.h
index 04e556dc6..df92b71c4 100644
--- a/src/qdoc/cppcodeparser.h
+++ b/src/qdoc/cppcodeparser.h
@@ -57,7 +57,7 @@ class CppCodeParser : public CodeParser
public:
CppCodeParser();
- void initializeParser(const Config &config) override;
+ void initializeParser() override;
void terminateParser() override;
QString language() override { return QStringLiteral("Cpp"); }
QStringList headerFileNameFilter() override;
@@ -86,7 +86,7 @@ protected:
bool hasTooManyTopics(const Doc &doc) const;
private:
- void setExampleFileLists(PageNode *pn);
+ void setExampleFileLists(ExampleNode *en);
protected:
typedef bool (Node::*NodeTypeTestFunc)() const;
@@ -94,8 +94,6 @@ protected:
QMap<QString, Node::NodeType> nodeTypeMap_;
private:
- static QStringList exampleFiles;
- static QStringList exampleDirs;
static QSet<QString> excludeDirs;
static QSet<QString> excludeFiles;
QString exampleNameFilter;
diff --git a/src/qdoc/doc.cpp b/src/qdoc/doc.cpp
index e20870319..5b52e9e1a 100644
--- a/src/qdoc/doc.cpp
+++ b/src/qdoc/doc.cpp
@@ -1325,6 +1325,12 @@ void DocParser::parse(const QString &source, DocPrivate *docPrivate,
case NOT_A_CMD:
if (metaCommandSet.contains(cmdStr)) {
priv->metacommandsUsed.insert(cmdStr);
+ // Force a linebreak after \obsolete or \deprecated
+ // to treat potential arguments as a new text paragraph.
+ if (pos < len &&
+ (cmdStr == QLatin1String("obsolete") ||
+ cmdStr == QLatin1String("deprecated")))
+ input_[pos] = '\n';
QString arg = getMetaCommandArgument(cmdStr);
priv->metaCommandMap[cmdStr].append(ArgLocPair(arg, location()));
if (possibleTopics.contains(cmdStr)) {
@@ -1375,7 +1381,7 @@ void DocParser::parse(const QString &source, DocPrivate *docPrivate,
// The QML and JS property group commands are no longer required
// for grouping QML and JS properties. They are allowed but ignored.
location().warning(tr("Unknown command '\\%1'").arg(cmdStr),
- detailsUnknownCommand(metaCommandSet,cmdStr));
+ detailsUnknownCommand(metaCommandSet, cmdStr));
}
enterPara();
append(Atom::UnknownCommand, cmdStr);
@@ -1567,7 +1573,7 @@ void DocParser::include(const QString &fileName, const QString &identifier)
location().fatal(tr("Too many nested '\\%1's").arg(cmdName(CMD_INCLUDE)));
QString userFriendlyFilePath;
- QString filePath = Doc::config()->getIncludeFilePath(fileName);
+ QString filePath = Config::instance().getIncludeFilePath(fileName);
if (filePath.isEmpty()) {
location().warning(tr("Cannot find qdoc include file '%1'").arg(fileName));
} else {
@@ -1814,7 +1820,7 @@ void DocParser::parseAlso()
if (input_[pos] == '{') {
target = getArgument();
skipSpacesOnLine();
- if (input_[pos] == '{') {
+ if (pos < len && input_[pos] == '{') {
str = getArgument();
// hack for C++ to support links like \l{QString::}{count()}
@@ -1841,7 +1847,7 @@ void DocParser::parseAlso()
if (pos < len && input_[pos] == ',') {
pos++;
skipSpacesOrOneEndl();
- } else if (input_[pos] != '\n') {
+ } else if (pos >= len || input_[pos] != '\n') {
location().warning(tr("Missing comma in '\\%1'").arg(cmdName(CMD_SA)));
}
}
@@ -2433,7 +2439,7 @@ QString DocParser::getCode(int cmd, CodeMarker *marker, const QString &argStr)
QString code = untabifyEtc(getUntilEnd(cmd));
if (!argStr.isEmpty()) {
- QStringList args = argStr.split(" ", QString::SkipEmptyParts);
+ QStringList args = argStr.split(" ", Qt::SkipEmptyParts);
int paramNo, j = 0;
while (j < code.size()) {
if (code[j] == '\\' && j < code.size() - 1 && (paramNo = code[j + 1].digitValue()) >= 1
@@ -3011,10 +3017,9 @@ const QStringMultiMap &Doc::metaTagMap() const
return priv && priv->extra ? priv->extra->metaMap_ : *null_QStringMultiMap();
}
-const Config *Doc::config_ = nullptr;
-
-void Doc::initialize(const Config &config)
+void Doc::initialize()
{
+ Config &config = Config::instance();
DocParser::tabSize = config.getInt(CONFIG_TABSIZE);
DocParser::exampleFiles = config.getCanonicalPathList(CONFIG_EXAMPLES);
DocParser::exampleDirs = config.getCanonicalPathList(CONFIG_EXAMPLEDIRS);
@@ -3024,7 +3029,6 @@ void Doc::initialize(const Config &config)
QmlTypeNode::qmlOnly = config.getBool(CONFIG_QMLONLY);
QStringMap reverseAliasMap;
- config_ = &config;
for (const auto &a : config.subVars(CONFIG_ALIAS)) {
QString alias = config.getString(CONFIG_ALIAS + Config::dot + a);
diff --git a/src/qdoc/doc.h b/src/qdoc/doc.h
index 758901f1d..c488983ca 100644
--- a/src/qdoc/doc.h
+++ b/src/qdoc/doc.h
@@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE
class Atom;
class CodeMarker;
-class Config;
class DocPrivate;
class Quoter;
class Text;
@@ -167,7 +166,7 @@ public:
const QVector<Atom *> &targets() const;
const QStringMultiMap &metaTagMap() const;
- static void initialize(const Config &config);
+ static void initialize();
static void terminate();
static QString alias(const QString &english);
static void trimCStyleComment(Location &location, QString &str);
@@ -176,12 +175,10 @@ public:
static CodeMarker *quoteFromFile(const Location &location, Quoter &quoter,
const QString &fileName);
static QString canonicalTitle(const QString &title);
- static const Config *config() { return config_; }
private:
void detach();
DocPrivate *priv;
- static const Config *config_;
};
Q_DECLARE_TYPEINFO(Doc, Q_MOVABLE_TYPE);
typedef QVector<Doc> DocList;
diff --git a/src/qdoc/doc/files/basicqt.qdoc.sample b/src/qdoc/doc/files/basicqt.qdoc.sample
index ce8df096f..1243387b2 100644
--- a/src/qdoc/doc/files/basicqt.qdoc.sample
+++ b/src/qdoc/doc/files/basicqt.qdoc.sample
@@ -1,6 +1,5 @@
/*!
\page basicqt.html
- \contentspage {Basic Qt} {Contents}
\nextpage Getting Started
\indexpage Index
@@ -24,7 +23,6 @@
/*!
\page gettingstarted.html
\previouspage Basic Qt
- \contentspage {Basic Qt} {Contents}
\nextpage Creating Dialogs
\indexpage Index
@@ -40,7 +38,6 @@
/ *!
\page creatingdialogs.html
\previouspage Getting Started
- \contentspage {Basic Qt} {Contents}
\indexpage Index
\startpage Basic Qt
diff --git a/src/qdoc/doc/qa-pages.qdoc b/src/qdoc/doc/qa-pages.qdoc
index 5602ba3e0..1e3ca19f4 100644
--- a/src/qdoc/doc/qa-pages.qdoc
+++ b/src/qdoc/doc/qa-pages.qdoc
@@ -27,8 +27,7 @@
/*!
\page 28-qdoc-qa-pages.html
- \previouspage Generating DITA XML Output
- \contentspage QDoc Manual
+ \previouspage The QDoc Configuration File
\nextpage QDoc Manual
\title QA Pages
diff --git a/src/qdoc/doc/qdoc-manual-DITA.qdoc b/src/qdoc/doc/qdoc-manual-DITA.qdoc
deleted file mode 100644
index 116082628..000000000
--- a/src/qdoc/doc/qdoc-manual-DITA.qdoc
+++ /dev/null
@@ -1,164 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \page 21-0-qdoc-creating-dita-maps.html
- \previouspage Miscellaneous
- \contentspage QDoc Manual
- \nextpage The QDoc Configuration File
-
- \title Creating DITA Maps
-
- You can create DITA map files using three new qdoc commands, the \l{ditamap-command}
- {ditamap} command, the \l{topicref-command} {topicref} command, and the \l{mapref-command}
- {mapref} command. How these DITA maps will be used automatically or manually by the
- documentation build process is still under consideration. This section will be updated
- as the decisions are made.
-
- \section1 What is a DITA Map?
-
- A complete description of DITA can be found at the
- \l{http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=dita}
- {OASIS Darwin Information Typing Architecture} site.
-
- An explanation of the DITA map is found at that site
- \l{http://docs.oasis-open.org/dita/v1.2/os/spec/langref/map.html}{here}.
-
- \target ditamap-command
- \section1 \\ditamap
-
- The \\ditamap command is for creating a DITA map using qdoc commands.
- The \\ditamap command is a kind of \\page command that produces a
- \e{.ditamap} instead of a \e{.html} or \e{.xml} file. The file that
- is created actually contains XML text, but the \e{.ditamap} suffix is
- used to identify the file as containing a DITA MAP.
-
- The argument is the name of the file to be created. In the following
- example, the file \e{creator.ditamap} is output:
- \code
- \ditamap creator.ditamap
- \endcode
-
- \target topicref-command
- \section1 \\topicref \\endtopicref
-
- The \\topicref \\endtopicref commands are for creating a topicref
- in the ditamap. The \\endtopicref command is required because
- \\topicref commands can be nested.
-
- \\topicref has two arguments. The first argument becomes the value
- of the \e navtitle attribute. Normally, you use the title of the
- topic being referenced. This title is often what will appear in a
- table of contents constructed from the ditamap.
-
- The second argument is the name of the page being referenced. The
- second argument is actually optional, for example if you are using
- a topicref as a container for other topicrefs and maprefs. It is
- also optional if you want qdoc to find the page name for you by
- looking up the title in its internal data structure. It is recommended
- that you provide the second parameter if you know the page name.
-
- \code
- \topicref {QML Module QtQuick 2} {qtquick-2.xml}
- \mapref {Creator Manual} {creator-manual.ditamap} \endmapref
- \topicref {QML Mouse Events} {qtquick2-mouseevents.xml} \endtopicref
- \topicref {Property Binding} {qtquick2-propertybinding.xml} \endtopicref
- \endtopicref
- \endcode
-
- \target mapref-command
- \section1 \\mapref
-
- The \\mapref command is for creating a mapref in the ditamap. A
- mapref refers to another ditamap, which you want to include in
- your ditamap. Like the \\topicref command, the \\mapref command
- has two arguments, but for the \\mapref command, both arguments
- are required. The arguments are essentially the same as described
- for \\topicref, but for \\mapref, the second command must be the
- name of another ditamap, i.e. it must have the \e{.ditamap}
- suffix. You must provide the file name. qdoc can't look up the
- file name for you.
-
- \code
- \mapref {Creator Manual} {creator-manual.ditamap} \endmapref
- \endcode
-
- \section1 An Example Ditamap Page
-
- The following example uses the three qdoc ditamap commands described above.
-
- \code
- \ditamap creator.ditamap
- \title The DITA Map for Creator
-
- \topicref {QML Module QtQuick 1}
- \topicref {QML Mouse Events} \endtopicref
- \topicref {Property Binding} \endtopicref
- \endtopicref
-
- \topicref {QML Module QtQuick 2} {qtquick-2.xml}
- \mapref {Creator Manual} {creator-manual.ditamap} \endmapref
- \topicref {QML Mouse Events} {qtquick2-mouseevents.xml} \endtopicref
- \topicref {Property Binding} {qtquick2-propertybinding.xml} \endtopicref
- \endtopicref
-
- \topicref {QML Module QtQuick.Particles 2} {qtquick-particles-2.xml}
- \topicref {Age} {qml-qtquick-particles2-age.xml} \endtopicref
- \endtopicref
- \endcode
-
- \section1 The Resulting Ditamap File
-
- This is the \e{.ditamap} file you get when you input the qdoc
- ditamap page shown above. Note that you can write ditamap files
- directly in XML just as easily as you can write them using the
- qdoc commands. The choice is yours.
-
- \code
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
- <map>
- <topicmeta>
- <shortdesc>The DITA Map for Creator</shortdesc>
- </topicmeta>
- <topicref navtitle="QML Module QtQuick 1" href="qtquick-1.xml">
- <topicref navtitle="QML Mouse Events" href="qtquick2-mouseevents.xml"/>
- <topicref navtitle="Property Binding" href="qtquick2-propertybinding.xml"/>
- </topicref>
- <topicref navtitle="QML Module QtQuick 2" href="qtquick-2.xml">
- <mapref navtitle="Creator Manual" href="creator-manual.ditamap"/>
- <topicref navtitle="QML Mouse Events" href="qtquick2-mouseevents.xml"/>
- <topicref navtitle="Property Binding" href="qtquick2-propertybinding.xml"/>
- </topicref>
- <topicref navtitle="QML Module QtQuick.Particles 2" href="qtquick-particles-2.xml">
- <topicref navtitle="Age" href="qml-qtquick-particles2-age.xml"/>
- </topicref>
- </map>
- \endcode
-
-*/
-
diff --git a/src/qdoc/doc/qdoc-manual-cmdindex.qdoc b/src/qdoc/doc/qdoc-manual-cmdindex.qdoc
index 672c2e409..77a3266fb 100644
--- a/src/qdoc/doc/qdoc-manual-cmdindex.qdoc
+++ b/src/qdoc/doc/qdoc-manual-cmdindex.qdoc
@@ -28,7 +28,6 @@
/*!
\page 27-qdoc-commands-alphabetical.html
\previouspage Introduction to QDoc
- \contentspage QDoc Manual
\nextpage Topic Commands
\title Command Index
@@ -49,7 +48,6 @@
\li \l {class-command} {\\class}
\li \l {code-command} {\\code}
\li \l {codeline-command} {\\codeline}
- \li \l {contentspage-command} {\\contentspage}
\li \l {default-command} {\\default}
\li \l {div-command} {\\div}
\li \l {dots-command} {\\dots}
diff --git a/src/qdoc/doc/qdoc-manual-contextcmds.qdoc b/src/qdoc/doc/qdoc-manual-contextcmds.qdoc
index d3cf23b76..3d69e76a6 100644
--- a/src/qdoc/doc/qdoc-manual-contextcmds.qdoc
+++ b/src/qdoc/doc/qdoc-manual-contextcmds.qdoc
@@ -28,7 +28,6 @@
/*!
\page 14-qdoc-commands-contextcommands.html
\previouspage Topic Commands
- \contentspage QDoc Manual
\nextpage Document Navigation
\title Context Commands
@@ -47,7 +46,6 @@
\list
\li \l {abstract-command} {\\abstract}
- \li \l {contentspage-command}{\\contentspage},
\li \l {ingroup-command}{\\ingroup},
\li \l {inherits-command}{\\inherits},
\li \l {inmodule-command}{\\inmodule},
@@ -74,7 +72,6 @@
/*!
\page 15-qdoc-commands-navigation.html
\previouspage Context Commands
- \contentspage QDoc Manual
\nextpage Status
\title Document Navigation
@@ -169,20 +166,11 @@
documentation. The generated link type tells browsers and search
engines which document is considered by the author to be the
starting point of the collection.
-
- \target contentspage-command
- \section2 \\contentspage
-
- The \\contentspage command links the current page to a table of
- contents page. The command follows the same syntax and argument
- convention as the \l {previouspage-command} {\\previouspage}
- command.
*/
/*!
\page 16-qdoc-commands-status.html
\previouspage Document Navigation
- \contentspage QDoc Manual
\nextpage Thread Support
\title Status
@@ -262,7 +250,7 @@
deprecated, and it should no longer be used in new code. There is
no guarantee for how long it will remain in the library.
- The command must stand on its own line.
+ The \\obsolete command takes no arguments.
When generating the reference documentation for a class, QDoc will
create and link to a separate page documenting its obsolete
@@ -441,7 +429,6 @@
/*!
\page 17-qdoc-commands-thread.html
\previouspage Status
- \contentspage QDoc Manual
\nextpage Relating Things
\title Thread Support
@@ -621,7 +608,6 @@
/*!
\page 18-qdoc-commands-relating.html
\previouspage Thread Support
- \contentspage QDoc Manual
\nextpage Grouping Things
\title Relating Things
@@ -808,7 +794,6 @@
/*!
\page 19-qdoc-commands-grouping.html
\previouspage Relating Things
- \contentspage QDoc Manual
\nextpage Naming Things
\title Grouping Things
@@ -890,7 +875,6 @@
/*!
\page 20-qdoc-commands-namingthings.html
\previouspage Grouping Things
- \contentspage QDoc Manual
\nextpage Markup Commands
\title Naming Things
diff --git a/src/qdoc/doc/qdoc-manual-intro.qdoc b/src/qdoc/doc/qdoc-manual-intro.qdoc
index 7ea3f1e36..a943863a6 100644
--- a/src/qdoc/doc/qdoc-manual-intro.qdoc
+++ b/src/qdoc/doc/qdoc-manual-intro.qdoc
@@ -27,7 +27,6 @@
/*!
\page 01-qdoc-manual.html
- \contentspage QDoc Manual
\previouspage QDoc Manual
\nextpage Command Index
diff --git a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
index fb178c7cc..6fc16c9e1 100644
--- a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
+++ b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
@@ -27,7 +27,6 @@
/*!
\page 03-qdoc-commands-markup.html
- \contentspage QDoc Manual
\previouspage Naming Things
\nextpage Text Markup
@@ -109,7 +108,6 @@
/*!
\page 04-qdoc-commands-textmarkup.html
- \contentspage QDoc Manual
\previouspage Markup Commands
\nextpage Document Structure
@@ -240,21 +238,6 @@
}
\endcode
- If qdoc is generating DITA XML, it will translate the commands to:
-
- \code
- <sectiondiv outputclass="float-right">
- <p>
- <fig>
- <image href="images/qml-column.png" placement="inline"/>
- </fig>
- </p>
- </sectiondiv>
- \endcode
-
- Your DITA XML publishing program must then recognize the \e
- {outputclass} attribute value.
-
\note Note that the \b {\\div} command can be nested.
Below you can find an example taken from the index.qdoc file used to
@@ -320,53 +303,6 @@
\enddiv
\enddiv
- When generating DITA XML, qdoc outputs the nested \e {div} commands as:
-
- \code
- <sectiondiv outputclass="indexbox guide">
- <sectiondiv outputclass="heading">
- <p>Qt Developer Guide</p>
- </sectiondiv>
- <sectiondiv outputclass="indexboxcont indexboxbar">
- <sectiondiv outputclass="section indexIcon"/>
- <sectiondiv outputclass="section">
- <p>Qt is a cross-platform application and UI
- framework. Using Qt, you can write
- web-enabled applications once and deploy
- them across desktop, mobile and embedded
- operating systems without rewriting the
- source code.
- </p>
- </sectiondiv>
- <sectiondiv outputclass="section sectionlist">
- <ul>
- <li>
- <xref href="gettingstarted.xml#id-606ee7a8-219b-47b7-8f94-91bc8c76e54c">Getting started</xref>
- </li>
- <li>
- <xref href="installation.xml#id-075c20e2-aa1e-4f88-a316-a46517e50443">Installation</xref>
- </li>
- <li>
- <xref href="how-to-learn-qt.xml#id-49f509b5-52f9-4cd9-9921-74217b9a5182">How to learn Qt</xref>
- </li>
- <li>
- <xref href="tutorials.xml#id-a737f955-a904-455f-b4aa-0dc69ed5a64f">Tutorials</xref>
- </li>
- <li>
- <xref href="all-examples.xml#id-98d95159-d65b-4706-b08f-13d80080448d">Examples</xref>
- </li>
- <li>
- <xref href="qt4-7-intro.xml#id-519ae0e3-4242-4c2a-b2be-e05d1e95f177">What's new in Qt 4.7</xref>
- </li>
- </ul>
- </sectiondiv>
- </sectiondiv>
- </sectiondiv>
- \endcode
-
- Your DITA XML publishing program must recognize the values of the
- \e {outputclass} attribute.
-
See also \l {span-command} {\\span}.
\target span-command
@@ -640,7 +576,6 @@
The \\uicontrol command is used to mark content as being used for UI
control elements. When using HTML, the output is rendered in bold.
- When using DITA XML the content is enclosed in a \c{uicontrol} tag.
\sa \\b
@@ -722,7 +657,6 @@
/*!
\page 05-qdoc-commands-documentstructure.html
\previouspage Text Markup
- \contentspage QDoc Manual
\nextpage Including Code Inline
\title Document Structure
@@ -921,7 +855,6 @@
/*!
\page 06-qdoc-commands-includecodeinline.html
\previouspage Document Structure
- \contentspage QDoc Manual
\nextpage Including External Code
\title Including Code Inline
@@ -1154,7 +1087,6 @@
/*!
\page 07-0-qdoc-commands-includingexternalcode.html
\previouspage Including Code Inline
- \contentspage QDoc Manual
\nextpage Creating Links
\title Including External Code
@@ -1785,7 +1717,6 @@
/*!
\page 08-qdoc-commands-creatinglinks.html
\previouspage Including External Code
- \contentspage QDoc Manual
\nextpage Including Images
\title Creating Links
@@ -2182,7 +2113,6 @@
/*!
\page 09-qdoc-commands-includingimages.html
\previouspage Creating Links
- \contentspage QDoc Manual
\nextpage Tables and Lists
\title Including Images
@@ -2379,7 +2309,6 @@
/*!
\page 10-qdoc-commands-tablesandlists.html
\previouspage Including Images
- \contentspage QDoc Manual
\nextpage Special Content
\title Tables and Lists
@@ -2837,13 +2766,6 @@
* /
\endcode
- \note This doesn't work in DITA XML, so don't use it because it
- produces a DITA XML file that doesn't validate. There probably is
- a way to do this in DITA, so if we figure it out, we will put it
- in. But this capability is not used anywhere other than right
- here, so it probably isn't important. For now, if you use this
- option, qdoc will ignore it and produce a list without it.
-
QDoc renders this as:
\list G
@@ -2927,7 +2849,6 @@
/*!
\page 11-qdoc-commands-specialcontent.html
\previouspage Tables and Lists
- \contentspage QDoc Manual
\nextpage Miscellaneous
\title Special Content
@@ -3362,8 +3283,7 @@
/*!
\page 12-0-qdoc-commands-miscellaneous.html
\previouspage Special Content
- \contentspage QDoc Manual
- \nextpage Creating DITA Maps
+ \nextpage The QDoc Configuration File
\title Miscellaneous
@@ -3799,8 +3719,7 @@
\target meta-command
\section1 \\meta
- The \\meta command is mainly used for including metadata in DITA
- XML files. It is also used for adding metadata to example documentation,
+ The \\meta command is used for adding metadata to example documentation,
and when generating HTML output for specifying the \e maintainer(s) of a
C++ class.
@@ -3826,46 +3745,7 @@
\endcode
When running QDoc to generate HTML, the example above will have no
- effect on the generated output, but if you run QDoc to generate
- DITA XML, the example will generate the following:
-
- \code
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE cxxClass PUBLIC "-//NOKIA//DTD DITA C++ API Class Reference Type v0.6.0//EN" "dtd/cxxClass.dtd">
- <!--qwidget.cpp-->
- <cxxClass id="id-9a14268e-6b09-4eee-b940-21a00a0961df">
- <apiName>QWidget</apiName>
- <shortdesc>the QWidget class is the base class of all user interface objects.</shortdesc>
- <prolog>
- <author>Qt Development Frameworks</author>
- <publisher>Qt Project</publisher>
- <copyright>
- <copyryear year="2020"/>
- <copyrholder>Qt Project</copyrholder>
- </copyright>
- <permissions view="all"/>
- <metadata>
- <audience type="designer"/>
- <audience type="programmer"/>
- <audience type="user"/>
- <category>Class reference</category>
- <prodinfo>
- <prodname>Qt Reference Documentation</prodname>
- <vrmlist>
- <vrm version="4" release="7" modification="3"/>
- </vrmlist>
- <component>QtGui</component>
- </prodinfo>
- <othermeta name="platform" content="MeeGo"/>
- <othermeta name="platform" content="macOS 10.6"/>
- <othermeta name="technology" content="User Interface"/>
- </metadata>
- </prolog>
- \endcode
-
- In the example output, several values have been set using default
- values obtained from the QDoc configuration file. See \l
- {Generating DITA XML Output} for details.
+ effect on the generated output.
\b {Example Metadata}
@@ -3984,8 +3864,7 @@
The \\raw command and the corresponding
\\endraw command delimit a block of raw mark-up language code.
- \note Avoid using this command if possible, because it generates
- DITA XML code that causes problems. If you are trying to generate
+ \note Avoid using this command if possible. If you are trying to generate
special table or list behavior, try to get the behavior you want
using the \l {span-command} {\\span} and \l {div-command} {\\div}
commands in your \l {table-command} {\\table} or \l {list-command}
diff --git a/src/qdoc/doc/qdoc-manual-qdocconf.qdoc b/src/qdoc/doc/qdoc-manual-qdocconf.qdoc
index 415702e98..d15fd5515 100644
--- a/src/qdoc/doc/qdoc-manual-qdocconf.qdoc
+++ b/src/qdoc/doc/qdoc-manual-qdocconf.qdoc
@@ -27,8 +27,7 @@
/*!
\page 21-0-qdoc-configuration.html
- \previouspage Creating DITA Maps
- \contentspage QDoc Manual
+ \previouspage Miscellaneous
\nextpage Generic Configuration Variables
\title The QDoc Configuration File
@@ -106,10 +105,12 @@
\li \l {HTML.postheader-variable} {HTML.postheader}
\li \l {HTML.style-variable} {HTML.style}
\li \l {ignorewords-variable} {ignorewords}
+ \li \l {ignoresince-variable} {ignoresince}
\li \l {imagedirs-variable} {imagedirs}
\li \l {images-variable} {images}
\li \l {images.fileextensions-variable} {images.fileextensions}
\li \l {language-variable} {language}
+ \li \l {locationinfo-variable} {locationinfo}
\li \l {macro-variable} {macro}
\li \l {manifestmeta-variable} {manifestmeta}
\li \l {navigation-variable} {navigation}
@@ -149,7 +150,6 @@
/*!
\page 22-qdoc-configuration-generalvariables.html
\previouspage The QDoc Configuration File
- \contentspage QDoc Manual
\nextpage Creating Help Project Files
\title Generic Configuration Variables
@@ -629,6 +629,37 @@
The \c ignorewords variable was introduced in QDoc 5.14.
+ \target ignoresince-variable
+ \section1 ignoresince
+
+ The \c ignoresince variable is used for setting a cutoff value for
+ versions passed to the \l {since-command}{\\since} command. All
+ \\since commands that define a version lower than the cutoff are
+ ignored and do not generate output.
+
+ The cutoff values are project-specific. The project name can be
+ defined as a subvariable. The default project name is \e Qt. For
+ example:
+
+ \badcode
+ ignoresince = 5.0
+ ignoresince.QDoc = 5.0
+ \endcode
+
+ These will ignore \\since commands where the major version is 4
+ or lower and the project is either \c QDoc or undefined.
+
+ \badcode
+ \since 3.2 # Ignored
+ \since 5.2 # Documented (as 'Qt 5.2')
+ \since QDoc 4.6 # Ignored
+ \since QtQuick 2.5 # Documented
+ \endcode
+
+ The \c ignoresince variable was introduced in QDoc 5.15.
+
+ See also \l {since-command}{\\since}.
+
\target imagedirs-variable
\section1 imagedirs
@@ -757,6 +788,28 @@
This identifies C++ as the language of the Qt source code.
+ \target locationinfo-variable
+ \section1 locationinfo
+
+ The \c locationinfo boolean variable determines whether detailed
+ location information about each entity is written to
+ \c {.index}-files and \c {.webxml}-files (when using the WebXML
+ output format).
+
+ Location information consists of the full path and line
+ number of either the declaration or documentation comment block
+ in the source code.
+
+ Setting this to \c false turns off location info:
+
+ \badcode
+ locationinfo = false
+ \endcode
+
+ The default value is \c true.
+
+ The \c locationinfo variable was introduced in QDoc 5.15.
+
\target macro-variable
\section1 macro
@@ -766,9 +819,7 @@
A macro variable can be restricted for use in one type of output
generation. By appending \c {.HTML} to the macro name, for
- example, the macro is only used when generating HTML output. By
- appending \c {.DITAXML} to the macro name, the macro is only used
- when generating DITA XML.
+ example, the macro is only used when generating HTML output.
\badcode
macro.gui = "\\b"
@@ -963,9 +1014,10 @@
The \c outputformats variable specifies the format(s) of
the generated documentation.
- Since Qt 5.11, QDoc supports the HTML and WebXML formats. If no
+ Since Qt 5.11, QDoc supports the HTML and WebXML formats; since
+ Qt 5.15, it can also generate the documentation in DocBook. If no
\c outputformats are specified, QDoc generates the documentation
- in HTML (the default format). Both output formats can be specified,
+ in HTML (the default format). All output formats can be specified,
with dedicated output directories and other settings. For example:
\badcode
@@ -1263,7 +1315,6 @@
/*!
\page 22-creating-help-project-files.html
\previouspage Generic Configuration Variables
- \contentspage QDoc Manual
\nextpage C++ Specific Configuration Variables
\title Creating Help Project Files
@@ -1397,7 +1448,6 @@
/*!
\page 23-qdoc-configuration-cppvariables.html
\previouspage Creating Help Project Files
- \contentspage QDoc Manual
\nextpage Format-specific Configuration Variables
\title C++ Specific Configuration Variables
@@ -1508,7 +1558,6 @@
/*!
\page 24-qdoc-configuration-htmlvariables.html
\previouspage C++ Specific Configuration Variables
- \contentspage QDoc Manual
\nextpage Supporting Derived Projects
\keyword HTML Specific Configuration Variables
@@ -1659,7 +1708,6 @@
/*!
\page 25-qdoc-configuration-derivedprojects.html
\previouspage Format-specific Configuration Variables
- \contentspage QDoc Manual
\nextpage Example Manifest Files
\title Supporting Derived Projects
@@ -1817,7 +1865,6 @@
/*!
\page 26-qdoc-configuration-example-manifest-files.html
\previouspage Supporting Derived Projects
- \contentspage QDoc Manual
\title Example Manifest Files
@@ -1895,71 +1942,11 @@
another tag is applied to all examples by using just \c {*} as the
match string.
*/
-/*!
- \page 21-3-qt-dita-xml-output.html
- \previouspage minimum.qdocconf
- \contentspage QDoc Manual
- \nextpage QA Pages
-
- \title Generating DITA XML Output
-
- QDoc can generate \l {http://dita.xml.org} {DITA XML output}.
-
- In your configuration file, set your \c {outputformats} variable
- to \c {DITAXML}, and send the output to an appropriate directory:
-
- \badcode
- outputdir = $QTDIR/doc/ditaxml
- outputformats = DITAXML
- \endcode
-
- And include these macros in your configuration file to prevent
- QDoc from doing some escaping that doesn't validate in XML:
-
- \badcode
- macro.aacute.DITAXML = "&aacute;"
- macro.Aring.DITAXML = "&Aring;"
- macro.aring.DITAXML = "&aring;"
- macro.Auml.DITAXML = "&Auml;"
- macro.br.DITAXML = " "
- macro.BR.DITAXML = " "
- macro.copyright.DITAXML = "&copy;"
- macro.eacute.DITAXML = "&eacute;"
- macro.hr.DITAXML = " "
- macro.iacute.DITAXML = "&iacute;"
- macro.oslash.DITAXML = "&oslash;"
- macro.ouml.DITAXML = "&ouml;"
- macro.raisedaster.DITAXML = "<sup>*</sup>"
- macro.rarrow.DITAXML = "&rarr;"
- macro.reg.DITAXML = "<sup>&reg;</sup>"
- macro.uuml.DITAXML = "&uuml;"
- macro.mdash.DITAXML = "&mdash;"
- macro.emptyspan.DITAXML = " "
- \endcode
-
- You can also set default values for some of the tags in the DITA
- \c {<prolog>} and \c {<metadata>} elements:
-
- \badcode
- dita.metadata.default.author = Qt Development Frameworks
- dita.metadata.default.permissions = all
- dita.metadata.default.publisher = Qt Project
- dita.metadata.default.copyryear = 2020
- dita.metadata.default.copyrholder = Qt Project
- dita.metadata.default.audience = programmer
- \endcode
-
- See the \l {meta-command}
- {\\meta} command for more details on DITA metadata.
-
-*/
-
/*!
\page 21-1-minimum-qdocconf.html
\previouspage qtgui.qdocconf
- \contentspage QDoc Manual
- \nextpage Generating DITA XML Output
+ \nextpage The QDoc Configuration File
\title minimum.qdocconf
@@ -1969,7 +1956,6 @@
/*!
\page 21-2-qtgui-qdocconf.html
\previouspage Supporting Derived Projects
- \contentspage QDoc Manual
\nextpage minimum.qdocconf
\title qtgui.qdocconf
diff --git a/src/qdoc/doc/qdoc-manual-topiccmds.qdoc b/src/qdoc/doc/qdoc-manual-topiccmds.qdoc
index cdd0c9aeb..e7405e442 100644
--- a/src/qdoc/doc/qdoc-manual-topiccmds.qdoc
+++ b/src/qdoc/doc/qdoc-manual-topiccmds.qdoc
@@ -28,7 +28,6 @@
/*!
\page 13-qdoc-commands-topics.html
\previouspage Command Index
- \contentspage QDoc Manual
\nextpage Context Commands
\title Topic Commands
diff --git a/src/qdoc/doc/qdoc-manual.qdoc b/src/qdoc/doc/qdoc-manual.qdoc
index 716f8c73f..a03fe91ff 100644
--- a/src/qdoc/doc/qdoc-manual.qdoc
+++ b/src/qdoc/doc/qdoc-manual.qdoc
@@ -57,7 +57,6 @@
\li \l {Special Content}
\li \l {Miscellaneous}
\endlist
- \li \l{Creating DITA Maps}
\li \l {The QDoc Configuration File}
\list
\li \l {Generic Configuration Variables}
@@ -68,7 +67,6 @@
\li \l {Example Manifest Files}
\li \l {qtgui.qdocconf}
\li \l {minimum.qdocconf}
- \li \l {Generating DITA XML Output}
\endlist
\li \l {QA Pages}
\endlist
diff --git a/src/qdoc/docbookgenerator.cpp b/src/qdoc/docbookgenerator.cpp
new file mode 100644
index 000000000..f6476c9ec
--- /dev/null
+++ b/src/qdoc/docbookgenerator.cpp
@@ -0,0 +1,4216 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Thibaut Cuvelier
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <cctype>
+#include <qlist.h>
+#include <qiterator.h>
+#include <qtextcodec.h>
+#include <quuid.h>
+#include <qurl.h>
+#include <qmap.h>
+#include <QtCore/qversionnumber.h>
+
+#include "codemarker.h"
+#include "config.h"
+#include "generator.h"
+#include "docbookgenerator.h"
+#include "node.h"
+#include "quoter.h"
+#include "qdocdatabase.h"
+#include "separator.h"
+
+QT_BEGIN_NAMESPACE
+
+static const char dbNamespace[] = "http://docbook.org/ns/docbook";
+static const char xlinkNamespace[] = "http://www.w3.org/1999/xlink";
+
+inline void DocBookGenerator::newLine()
+{
+ writer->writeCharacters("\n");
+}
+
+void DocBookGenerator::startSectionBegin()
+{
+ writer->writeStartElement(dbNamespace, "section");
+ newLine();
+ writer->writeStartElement(dbNamespace, "title");
+}
+
+void DocBookGenerator::startSectionBegin(const QString &id)
+{
+ writer->writeStartElement(dbNamespace, "section");
+ writer->writeAttribute("xml:id", id);
+ newLine();
+ writer->writeStartElement(dbNamespace, "title");
+}
+
+void DocBookGenerator::startSectionEnd()
+{
+ writer->writeEndElement(); // title
+ newLine();
+}
+
+void DocBookGenerator::startSection(const QString &id, const QString &title)
+{
+ startSectionBegin(id);
+ writer->writeCharacters(title);
+ startSectionEnd();
+}
+
+void DocBookGenerator::endSection()
+{
+ writer->writeEndElement(); // section
+ newLine();
+}
+
+void DocBookGenerator::writeAnchor(const QString &id)
+{
+ writer->writeEmptyElement(dbNamespace, "anchor");
+ writer->writeAttribute("xml:id", id);
+ newLine();
+}
+
+/*!
+ Initializes the DocBook output generator's data structures
+ from the configuration (Config).
+ */
+void DocBookGenerator::initializeGenerator()
+{
+ // Excerpts from HtmlGenerator::initializeGenerator.
+ Generator::initializeGenerator();
+ config = &Config::instance();
+
+ project = config->getString(CONFIG_PROJECT);
+
+ projectDescription = config->getString(CONFIG_DESCRIPTION);
+ if (projectDescription.isEmpty() && !project.isEmpty())
+ projectDescription = project + QLatin1String(" Reference Documentation");
+
+ naturalLanguage = config->getString(CONFIG_NATURALLANGUAGE);
+ if (naturalLanguage.isEmpty())
+ naturalLanguage = QLatin1String("en");
+
+ buildversion = config->getString(CONFIG_BUILDVERSION);
+}
+
+QString DocBookGenerator::format()
+{
+ return QStringLiteral("DocBook");
+}
+
+/*!
+ Returns "xml" for this subclass of Generator.
+ */
+QString DocBookGenerator::fileExtension() const
+{
+ return QStringLiteral("xml");
+}
+
+/*!
+ Generate the documentation for \a relative. i.e. \a relative
+ is the node that represents the entity where a qdoc comment
+ was found, and \a text represents the qdoc comment.
+ */
+bool DocBookGenerator::generateText(const Text &text, const Node *relative, CodeMarker *marker)
+{
+ Q_UNUSED(marker);
+ // From Generator::generateText.
+ if (!text.firstAtom())
+ return false;
+
+ int numAtoms = 0;
+ initializeTextOutput();
+ generateAtomList(text.firstAtom(), relative, true, numAtoms);
+ closeTextSections();
+ return true;
+}
+
+/*!
+ Generate the text for \a atom relatively to \a relative.
+ \a generate indicates if output to \a writer is expected.
+ The number of generated atoms is returned in the argument
+ \a numAtoms. The returned value is the first atom that was not
+ generated.
+ */
+const Atom *DocBookGenerator::generateAtomList(const Atom *atom, const Node *relative,
+ bool generate, int &numAtoms)
+{
+ Q_ASSERT(writer);
+ // From Generator::generateAtomList.
+ while (atom) {
+ switch (atom->type()) {
+ case Atom::FormatIf: {
+ int numAtoms0 = numAtoms;
+ atom = generateAtomList(atom->next(), relative, generate, numAtoms);
+ if (!atom)
+ return nullptr;
+
+ if (atom->type() == Atom::FormatElse) {
+ ++numAtoms;
+ atom = generateAtomList(atom->next(), relative, false, numAtoms);
+ if (!atom)
+ return nullptr;
+ }
+
+ if (atom->type() == Atom::FormatEndif) {
+ if (generate && numAtoms0 == numAtoms) {
+ relative->location().warning(
+ tr("Output format %1 not handled %2").arg(format()).arg(outFileName()));
+ Atom unhandledFormatAtom(Atom::UnhandledFormat, format());
+ generateAtomList(&unhandledFormatAtom, relative, generate, numAtoms);
+ }
+ atom = atom->next();
+ }
+ } break;
+ case Atom::FormatElse:
+ case Atom::FormatEndif:
+ return atom;
+ default:
+ int n = 1;
+ if (generate) {
+ n += generateAtom(atom, relative);
+ numAtoms += n;
+ }
+ while (n-- > 0)
+ atom = atom->next();
+ }
+ }
+ return nullptr;
+}
+
+/*!
+ Generate DocBook from an instance of Atom.
+ */
+int DocBookGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker)
+{
+ Q_ASSERT(writer);
+ Q_UNUSED(marker);
+ // From HtmlGenerator::generateAtom, without warning generation.
+ int idx = 0;
+ int skipAhead = 0;
+ static bool inPara = false;
+
+ switch (atom->type()) {
+ case Atom::AutoLink:
+ case Atom::NavAutoLink:
+ if (!inLink && !inContents_ && !inSectionHeading_) {
+ const Node *node = nullptr;
+ QString link = getAutoLink(atom, relative, &node);
+ if (!link.isEmpty() && node && node->status() == Node::Obsolete
+ && relative->parent() != node && !relative->isObsolete()) {
+ link.clear();
+ }
+ if (link.isEmpty()) {
+ writer->writeCharacters(atom->string());
+ } else {
+ beginLink(link, node, relative);
+ generateLink(atom);
+ endLink();
+ }
+ } else {
+ writer->writeCharacters(atom->string());
+ }
+ break;
+ case Atom::BaseName:
+ break;
+ case Atom::BriefLeft:
+ if (!hasBrief(relative)) {
+ skipAhead = skipAtoms(atom, Atom::BriefRight);
+ break;
+ }
+ writer->writeStartElement(dbNamespace, "para");
+ rewritePropertyBrief(atom, relative);
+ break;
+ case Atom::BriefRight:
+ if (hasBrief(relative)) {
+ writer->writeEndElement(); // para
+ newLine();
+ }
+ break;
+ case Atom::C:
+ // This may at one time have been used to mark up C++ code but it is
+ // now widely used to write teletype text. As a result, text marked
+ // with the \c command is not passed to a code marker.
+ writer->writeTextElement(dbNamespace, "code", plainCode(atom->string()));
+ break;
+ case Atom::CaptionLeft:
+ writer->writeStartElement(dbNamespace, "title");
+ break;
+ case Atom::CaptionRight:
+ endLink();
+ writer->writeEndElement(); // title
+ newLine();
+ break;
+ case Atom::Qml:
+ writer->writeStartElement(dbNamespace, "programlisting");
+ writer->writeAttribute("language", "qml");
+ writer->writeCharacters(atom->string());
+ writer->writeEndElement(); // programlisting
+ newLine();
+ break;
+ case Atom::JavaScript:
+ writer->writeStartElement(dbNamespace, "programlisting");
+ writer->writeAttribute("language", "js");
+ writer->writeCharacters(atom->string());
+ writer->writeEndElement(); // programlisting
+ newLine();
+ break;
+ case Atom::CodeNew:
+ writer->writeTextElement(dbNamespace, "para", "you can rewrite it as");
+ newLine();
+ writer->writeStartElement(dbNamespace, "programlisting");
+ writer->writeAttribute("language", "cpp");
+ writer->writeAttribute("role", "new");
+ writer->writeCharacters(atom->string());
+ writer->writeEndElement(); // programlisting
+ newLine();
+ break;
+ case Atom::Code:
+ writer->writeStartElement(dbNamespace, "programlisting");
+ writer->writeAttribute("language", "cpp");
+ writer->writeCharacters(atom->string());
+ writer->writeEndElement(); // programlisting
+ newLine();
+ break;
+ case Atom::CodeOld:
+ writer->writeTextElement(dbNamespace, "para", "For example, if you have code like");
+ newLine();
+ Q_FALLTHROUGH();
+ case Atom::CodeBad:
+ writer->writeStartElement(dbNamespace, "programlisting");
+ writer->writeAttribute("language", "cpp");
+ writer->writeAttribute("role", "bad");
+ writer->writeCharacters(atom->string());
+ writer->writeEndElement(); // programlisting
+ newLine();
+ break;
+ case Atom::DivLeft:
+ case Atom::DivRight:
+ break;
+ case Atom::FootnoteLeft:
+ writer->writeStartElement(dbNamespace, "footnote");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ break;
+ case Atom::FootnoteRight:
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // footnote
+ break;
+ case Atom::FormatElse:
+ case Atom::FormatEndif:
+ case Atom::FormatIf:
+ break;
+ case Atom::FormattingLeft:
+ if (atom->string() == ATOM_FORMATTING_BOLD) {
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ } else if (atom->string() == ATOM_FORMATTING_ITALIC) {
+ writer->writeStartElement(dbNamespace, "emphasis");
+ } else if (atom->string() == ATOM_FORMATTING_UNDERLINE) {
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "underline");
+ } else if (atom->string() == ATOM_FORMATTING_SUBSCRIPT) {
+ writer->writeStartElement(dbNamespace, "sub");
+ } else if (atom->string() == ATOM_FORMATTING_SUPERSCRIPT) {
+ writer->writeStartElement(dbNamespace, "sup");
+ } else if (atom->string() == ATOM_FORMATTING_TELETYPE
+ || atom->string() == ATOM_FORMATTING_PARAMETER) {
+ writer->writeStartElement(dbNamespace, "code");
+
+ if (atom->string() == ATOM_FORMATTING_PARAMETER)
+ writer->writeAttribute("role", "parameter");
+ }
+ break;
+ case Atom::FormattingRight:
+ if (atom->string() == ATOM_FORMATTING_BOLD || atom->string() == ATOM_FORMATTING_ITALIC
+ || atom->string() == ATOM_FORMATTING_UNDERLINE
+ || atom->string() == ATOM_FORMATTING_SUBSCRIPT
+ || atom->string() == ATOM_FORMATTING_SUPERSCRIPT
+ || atom->string() == ATOM_FORMATTING_TELETYPE
+ || atom->string() == ATOM_FORMATTING_PARAMETER) {
+ writer->writeEndElement();
+ }
+ if (atom->string() == ATOM_FORMATTING_LINK)
+ endLink();
+ break;
+ case Atom::AnnotatedList:
+ if (const CollectionNode *cn = qdb_->getCollectionNode(atom->string(), Node::Group))
+ generateList(cn, atom->string());
+ break;
+ case Atom::GeneratedList:
+ if (atom->string() == QLatin1String("annotatedclasses")
+ || atom->string() == QLatin1String("attributions")
+ || atom->string() == QLatin1String("namespaces")) {
+ const NodeMultiMap things = atom->string() == QLatin1String("annotatedclasses")
+ ? qdb_->getCppClasses()
+ : atom->string() == QLatin1String("attributions") ? qdb_->getAttributions()
+ : qdb_->getNamespaces();
+ generateAnnotatedList(relative, things, atom->string());
+ } else if (atom->string() == QLatin1String("annotatedexamples")
+ || atom->string() == QLatin1String("annotatedattributions")) {
+ const NodeMultiMap things = atom->string() == QLatin1String("annotatedexamples")
+ ? qdb_->getAttributions()
+ : qdb_->getExamples();
+ generateAnnotatedLists(relative, things, atom->string());
+ } else if (atom->string() == QLatin1String("classes")
+ || atom->string() == QLatin1String("qmlbasictypes")
+ || atom->string() == QLatin1String("qmltypes")) {
+ const NodeMultiMap things = atom->string() == QLatin1String("classes")
+ ? qdb_->getCppClasses()
+ : atom->string() == QLatin1String("qmlbasictypes") ? qdb_->getQmlBasicTypes()
+ : qdb_->getQmlTypes();
+ generateCompactList(Generic, relative, things, QString(), atom->string());
+ } else if (atom->string().contains("classes ")) {
+ QString rootName = atom->string().mid(atom->string().indexOf("classes") + 7).trimmed();
+ generateCompactList(Generic, relative, qdb_->getCppClasses(), rootName, atom->string());
+ } else if ((idx = atom->string().indexOf(QStringLiteral("bymodule"))) != -1) {
+ QString moduleName = atom->string().mid(idx + 8).trimmed();
+ Node::NodeType type = typeFromString(atom);
+ QDocDatabase *qdb = QDocDatabase::qdocDB();
+ if (const CollectionNode *cn = qdb->getCollectionNode(moduleName, type)) {
+ if (type == Node::Module) {
+ NodeMap m;
+ cn->getMemberClasses(m);
+ if (!m.isEmpty())
+ generateAnnotatedList(relative, m, atom->string());
+ } else {
+ generateAnnotatedList(relative, cn->members(), atom->string());
+ }
+ }
+ } else if (atom->string().startsWith("examplefiles")
+ || atom->string().startsWith("exampleimages")) {
+ if (relative->isExample())
+ qDebug() << "GENERATE FILE LIST CALLED" << relative->name() << atom->string();
+ } else if (atom->string() == QLatin1String("classhierarchy")) {
+ generateClassHierarchy(relative, qdb_->getCppClasses());
+ } else if (atom->string().startsWith("obsolete")) {
+ ListType type = atom->string().endsWith("members") ? Obsolete : Generic;
+ QString prefix = atom->string().contains("cpp") ? QStringLiteral("Q") : QString();
+ const NodeMultiMap &things = atom->string() == QLatin1String("obsoleteclasses")
+ ? qdb_->getObsoleteClasses()
+ : atom->string() == QLatin1String("obsoleteqmltypes")
+ ? qdb_->getObsoleteQmlTypes()
+ : atom->string() == QLatin1String("obsoletecppmembers")
+ ? qdb_->getClassesWithObsoleteMembers()
+ : qdb_->getQmlTypesWithObsoleteMembers();
+ generateCompactList(type, relative, things, prefix, atom->string());
+ } else if (atom->string() == QLatin1String("functionindex")) {
+ generateFunctionIndex(relative);
+ } else if (atom->string() == QLatin1String("legalese")) {
+ generateLegaleseList(relative);
+ } else if (atom->string() == QLatin1String("overviews")
+ || atom->string() == QLatin1String("cpp-modules")
+ || atom->string() == QLatin1String("qml-modules")
+ || atom->string() == QLatin1String("related")) {
+ generateList(relative, atom->string());
+ }
+ break;
+ case Atom::SinceList:
+ // Table of contents, should automatically be generated by the DocBook processor.
+ break;
+ case Atom::LineBreak:
+ case Atom::BR:
+ case Atom::HR:
+ // Not supported in DocBook.
+ break;
+ case Atom::Image: // mediaobject
+ case Atom::InlineImage: { // inlinemediaobject
+ QString tag = atom->type() == Atom::Image ? "mediaobject" : "inlinemediaobject";
+ writer->writeStartElement(dbNamespace, tag);
+ newLine();
+
+ QString fileName = imageFileName(relative, atom->string());
+ if (fileName.isEmpty()) {
+ writer->writeStartElement(dbNamespace, "textobject");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeTextElement(dbNamespace, "emphasis",
+ "[Missing image " + atom->string() + "]");
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // textobject
+ newLine();
+ } else {
+ if (atom->next() && !atom->next()->string().isEmpty())
+ writer->writeTextElement(dbNamespace, "alt", atom->next()->string());
+
+ writer->writeStartElement(dbNamespace, "imageobject");
+ newLine();
+ writer->writeEmptyElement(dbNamespace, "imagedata");
+ writer->writeAttribute("fileref", fileName);
+ newLine();
+ writer->writeEndElement(); // imageobject
+ newLine();
+
+ setImageFileName(relative, fileName);
+ }
+
+ writer->writeEndElement(); // [inline]mediaobject
+ if (atom->type() == Atom::Image)
+ newLine();
+ } break;
+ case Atom::ImageText:
+ break;
+ case Atom::ImportantLeft:
+ case Atom::NoteLeft: {
+ QString tag = atom->type() == Atom::ImportantLeft ? "important" : "note";
+ writer->writeStartElement(dbNamespace, tag);
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ } break;
+ case Atom::ImportantRight:
+ case Atom::NoteRight:
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // note/important
+ newLine();
+ break;
+ case Atom::LegaleseLeft:
+ case Atom::LegaleseRight:
+ break;
+ case Atom::Link:
+ case Atom::NavLink: {
+ const Node *node = nullptr;
+ QString link = getLink(atom, relative, &node);
+ beginLink(link, node, relative); // Ended at Atom::FormattingRight
+ skipAhead = 1;
+ } break;
+ case Atom::LinkNode: {
+ const Node *node = CodeMarker::nodeForString(atom->string());
+ beginLink(linkForNode(node, relative), node, relative);
+ skipAhead = 1;
+ } break;
+ case Atom::ListLeft:
+ if (inPara) {
+ writer->writeEndElement(); // para
+ newLine();
+ inPara = false;
+ }
+ if (atom->string() == ATOM_LIST_BULLET) {
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+ } else if (atom->string() == ATOM_LIST_TAG) {
+ writer->writeStartElement(dbNamespace, "variablelist");
+ newLine();
+ } else if (atom->string() == ATOM_LIST_VALUE) {
+ writer->writeStartElement(dbNamespace, "informaltable");
+ newLine();
+ writer->writeStartElement(dbNamespace, "thead");
+ newLine();
+ writer->writeStartElement(dbNamespace, "tr");
+ newLine();
+ writer->writeTextElement(dbNamespace, "th", "Constant");
+ newLine();
+
+ threeColumnEnumValueTable_ = isThreeColumnEnumValueTable(atom);
+ if (threeColumnEnumValueTable_ && relative->nodeType() == Node::Enum) {
+ // If not in \enum topic, skip the value column
+ writer->writeTextElement(dbNamespace, "th", "Value");
+ newLine();
+ }
+
+ writer->writeTextElement(dbNamespace, "th", "Description");
+ newLine();
+
+ writer->writeEndElement(); // tr
+ newLine();
+ writer->writeEndElement(); // thead
+ newLine();
+ } else {
+ writer->writeStartElement(dbNamespace, "orderedlist");
+
+ if (atom->next() != nullptr && atom->next()->string().toInt() > 1)
+ writer->writeAttribute("startingnumber", atom->next()->string());
+
+ if (atom->string() == ATOM_LIST_UPPERALPHA)
+ writer->writeAttribute("numeration", "upperalpha");
+ else if (atom->string() == ATOM_LIST_LOWERALPHA)
+ writer->writeAttribute("numeration", "loweralpha");
+ else if (atom->string() == ATOM_LIST_UPPERROMAN)
+ writer->writeAttribute("numeration", "upperroman");
+ else if (atom->string() == ATOM_LIST_LOWERROMAN)
+ writer->writeAttribute("numeration", "lowerroman");
+ else // (atom->string() == ATOM_LIST_NUMERIC)
+ writer->writeAttribute("numeration", "arabic");
+
+ newLine();
+ }
+ break;
+ case Atom::ListItemNumber:
+ break;
+ case Atom::ListTagLeft:
+ if (atom->string() == ATOM_LIST_TAG) {
+ writer->writeStartElement(dbNamespace, "varlistentry");
+ newLine();
+ writer->writeStartElement(dbNamespace, "item");
+ } else { // (atom->string() == ATOM_LIST_VALUE)
+ QPair<QString, int> pair = getAtomListValue(atom);
+ skipAhead = pair.second;
+
+ writer->writeStartElement(dbNamespace, "tr");
+ newLine();
+ writer->writeStartElement(dbNamespace, "td");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ generateEnumValue(pair.first, relative);
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // td
+ newLine();
+
+ if (relative->nodeType() == Node::Enum) {
+ const auto enume = static_cast<const EnumNode *>(relative);
+ QString itemValue = enume->itemValue(atom->next()->string());
+
+ writer->writeStartElement(dbNamespace, "td");
+ if (itemValue.isEmpty())
+ writer->writeCharacters("?");
+ else
+ writer->writeTextElement(dbNamespace, "code", itemValue);
+ writer->writeEndElement(); // td
+ newLine();
+ }
+ }
+ break;
+ case Atom::SinceTagRight:
+ case Atom::ListTagRight:
+ if (atom->string() == ATOM_LIST_TAG) {
+ writer->writeEndElement(); // item
+ newLine();
+ }
+ break;
+ case Atom::ListItemLeft:
+ inListItemLineOpen = false;
+ if (atom->string() == ATOM_LIST_TAG) {
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ } else if (atom->string() == ATOM_LIST_VALUE) {
+ if (threeColumnEnumValueTable_) {
+ if (matchAhead(atom, Atom::ListItemRight)) {
+ writer->writeEmptyElement(dbNamespace, "td");
+ newLine();
+ inListItemLineOpen = false;
+ } else {
+ writer->writeStartElement(dbNamespace, "td");
+ newLine();
+ inListItemLineOpen = true;
+ }
+ }
+ } else {
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ }
+ // Don't skip a paragraph, DocBook requires them within list items.
+ break;
+ case Atom::ListItemRight:
+ if (atom->string() == ATOM_LIST_TAG) {
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // listitem
+ newLine();
+ writer->writeEndElement(); // varlistentry
+ newLine();
+ } else if (atom->string() == ATOM_LIST_VALUE) {
+ if (inListItemLineOpen) {
+ writer->writeEndElement(); // td
+ newLine();
+ inListItemLineOpen = false;
+ }
+ writer->writeEndElement(); // tr
+ newLine();
+ } else {
+ writer->writeEndElement(); // listitem
+ newLine();
+ }
+ break;
+ case Atom::ListRight:
+ // Depending on atom->string(), closing a different item:
+ // - ATOM_LIST_BULLET: itemizedlist
+ // - ATOM_LIST_TAG: variablelist
+ // - ATOM_LIST_VALUE: informaltable
+ // - ATOM_LIST_NUMERIC: orderedlist
+ writer->writeEndElement();
+ newLine();
+ break;
+ case Atom::Nop:
+ break;
+ case Atom::ParaLeft:
+ writer->writeStartElement(dbNamespace, "para");
+ inPara = true;
+ break;
+ case Atom::ParaRight:
+ endLink();
+ if (inPara) {
+ writer->writeEndElement(); // para
+ newLine();
+ inPara = false;
+ }
+ break;
+ case Atom::QuotationLeft:
+ writer->writeStartElement(dbNamespace, "blockquote");
+ inPara = true;
+ break;
+ case Atom::QuotationRight:
+ writer->writeEndElement(); // blockquote
+ newLine();
+ break;
+ case Atom::RawString:
+ writer->writeCharacters(atom->string());
+ break;
+ case Atom::SectionLeft:
+ currentSectionLevel = atom->string().toInt() + hOffset(relative);
+ // Level 1 is dealt with at the header level (info tag).
+ if (currentSectionLevel > 1) {
+ // Unfortunately, SectionRight corresponds to the end of any section,
+ // i.e. going to a new section, even deeper.
+ while (!sectionLevels.empty() && sectionLevels.top() >= currentSectionLevel) {
+ sectionLevels.pop();
+ writer->writeEndElement(); // section
+ newLine();
+ }
+
+ sectionLevels.push(currentSectionLevel);
+
+ writer->writeStartElement(dbNamespace, "section");
+ writer->writeAttribute("xml:id",
+ Doc::canonicalTitle(Text::sectionHeading(atom).toString()));
+ newLine();
+ // Unlike startSectionBegin, don't start a title here.
+ }
+ break;
+ case Atom::SectionRight:
+ // All the logic about closing sections is done in the SectionLeft case
+ // and generateFooter() for the end of the page.
+ break;
+ case Atom::SectionHeadingLeft:
+ // Level 1 is dealt with at the header level (info tag).
+ if (currentSectionLevel > 1) {
+ writer->writeStartElement(dbNamespace, "title");
+ inSectionHeading_ = true;
+ }
+ break;
+ case Atom::SectionHeadingRight:
+ // Level 1 is dealt with at the header level (info tag).
+ if (currentSectionLevel > 1) {
+ writer->writeEndElement(); // title
+ newLine();
+ inSectionHeading_ = false;
+ }
+ break;
+ case Atom::SidebarLeft:
+ writer->writeStartElement(dbNamespace, "sidebar");
+ break;
+ case Atom::SidebarRight:
+ writer->writeEndElement(); // sidebar
+ newLine();
+ break;
+ case Atom::String:
+ if (inLink && !inContents_ && !inSectionHeading_)
+ generateLink(atom);
+ else
+ writer->writeCharacters(atom->string());
+ break;
+ case Atom::TableLeft: {
+ QPair<QString, QString> pair = getTableWidthAttr(atom);
+ QString attr = pair.second;
+ QString width = pair.first;
+
+ if (inPara) {
+ writer->writeEndElement(); // para or blockquote
+ newLine();
+ inPara = false;
+ }
+
+ writer->writeStartElement(dbNamespace, "informaltable");
+ writer->writeAttribute("style", attr);
+ if (!width.isEmpty())
+ writer->writeAttribute("width", width);
+ newLine();
+ numTableRows_ = 0;
+ } break;
+ case Atom::TableRight:
+ writer->writeEndElement(); // table
+ newLine();
+ break;
+ case Atom::TableHeaderLeft:
+ writer->writeStartElement(dbNamespace, "thead");
+ newLine();
+ writer->writeStartElement(dbNamespace, "tr");
+ newLine();
+ inTableHeader_ = true;
+ break;
+ case Atom::TableHeaderRight:
+ writer->writeEndElement(); // tr
+ newLine();
+ if (matchAhead(atom, Atom::TableHeaderLeft)) {
+ skipAhead = 1;
+ writer->writeStartElement(dbNamespace, "tr");
+ newLine();
+ } else {
+ writer->writeEndElement(); // thead
+ newLine();
+ inTableHeader_ = false;
+ }
+ break;
+ case Atom::TableRowLeft:
+ writer->writeStartElement(dbNamespace, "tr");
+ if (atom->string().isEmpty()) {
+ writer->writeAttribute("valign", "top");
+ } else {
+ // Basic parsing of attributes, should be enough. The input string (atom->string())
+ // looks like:
+ // arg1="val1" arg2="val2"
+ QStringList args = atom->string().split("\"", Qt::SkipEmptyParts);
+ // arg1=, val1, arg2=, val2,
+ // \-- 1st --/ \-- 2nd --/ \-- remainder
+ if (args.size() % 2) {
+ // Problem...
+ relative->doc().location().warning(
+ tr("Error when parsing attributes for the table: got \"%1\"")
+ .arg(atom->string()));
+ }
+ for (int i = 0; i + 1 < args.size(); i += 2)
+ writer->writeAttribute(args.at(i).chopped(1), args.at(i + 1));
+ }
+ newLine();
+ break;
+ case Atom::TableRowRight:
+ writer->writeEndElement(); // tr
+ newLine();
+ break;
+ case Atom::TableItemLeft:
+ writer->writeStartElement(dbNamespace, inTableHeader_ ? "th" : "td");
+
+ for (int i = 0; i < atom->count(); ++i) {
+ const QString &p = atom->string(i);
+ if (p.contains('=')) {
+ QStringList lp = p.split(QLatin1Char('='));
+ writer->writeAttribute(lp.at(0), lp.at(1));
+ } else {
+ QStringList spans = p.split(QLatin1Char(','));
+ if (spans.size() == 2) {
+ if (spans.at(0) != "1")
+ writer->writeAttribute("colspan", spans.at(0));
+ if (spans.at(1) != "1")
+ writer->writeAttribute("rowspan", spans.at(1));
+ }
+ }
+ }
+ newLine();
+ // No skipahead, as opposed to HTML: in DocBook, the text must be wrapped in paragraphs.
+ break;
+ case Atom::TableItemRight:
+ writer->writeEndElement(); // th if inTableHeader_, otherwise td
+ newLine();
+ break;
+ case Atom::TableOfContents:
+ break;
+ case Atom::Keyword:
+ break;
+ case Atom::Target:
+ writeAnchor(Doc::canonicalTitle(atom->string()));
+ break;
+ case Atom::UnhandledFormat:
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ writer->writeCharacters("&lt;Missing DocBook&gt;");
+ writer->writeEndElement(); // emphasis
+ break;
+ case Atom::UnknownCommand:
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ writer->writeCharacters("&lt;Unknown command&gt;");
+ writer->writeStartElement(dbNamespace, "code");
+ writer->writeCharacters(atom->string());
+ writer->writeEndElement(); // code
+ writer->writeEndElement(); // emphasis
+ break;
+ case Atom::QmlText:
+ case Atom::EndQmlText:
+ // don't do anything with these. They are just tags.
+ break;
+ case Atom::CodeQuoteArgument:
+ case Atom::CodeQuoteCommand:
+ case Atom::SnippetCommand:
+ case Atom::SnippetIdentifier:
+ case Atom::SnippetLocation:
+ // no output (ignore)
+ break;
+ default:
+ unknownAtom(atom);
+ }
+ return skipAhead;
+}
+
+void DocBookGenerator::generateClassHierarchy(const Node *relative, NodeMap &classMap)
+{
+ // From HtmlGenerator::generateClassHierarchy.
+ if (classMap.isEmpty())
+ return;
+
+ NodeMap topLevel;
+ NodeMap::Iterator c = classMap.begin();
+ while (c != classMap.end()) {
+ auto *classe = static_cast<ClassNode *>(*c);
+ if (classe->baseClasses().isEmpty())
+ topLevel.insert(classe->name(), classe);
+ ++c;
+ }
+
+ QStack<NodeMap> stack;
+ stack.push(topLevel);
+
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+ while (!stack.isEmpty()) {
+ if (stack.top().isEmpty()) {
+ stack.pop();
+ writer->writeEndElement(); // listitem
+ newLine();
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+ } else {
+ ClassNode *child = static_cast<ClassNode *>(*stack.top().begin());
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ generateFullName(child, relative);
+ writer->writeEndElement(); // para
+ newLine();
+ // Don't close the listitem now, as DocBook requires sublists to reside in items.
+ stack.top().erase(stack.top().begin());
+
+ NodeMap newTop;
+ for (const RelatedClass &d : child->derivedClasses()) {
+ if (d.node_ && !d.isPrivate() && !d.node_->isInternal() && d.node_->hasDoc())
+ newTop.insert(d.node_->name(), d.node_);
+ }
+ if (!newTop.isEmpty()) {
+ stack.push(newTop);
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+ }
+ }
+ }
+}
+
+void DocBookGenerator::generateLink(const Atom *atom)
+{
+ // From HtmlGenerator::generateLink.
+ QRegExp funcLeftParen("\\S(\\()");
+ if (funcLeftParen.indexIn(atom->string()) != -1) {
+ // hack for C++: move () outside of link
+ int k = funcLeftParen.pos(1);
+ writer->writeCharacters(atom->string().left(k));
+ writer->writeEndElement(); // link
+ inLink = false;
+ writer->writeCharacters(atom->string().mid(k));
+ } else {
+ writer->writeCharacters(atom->string());
+ }
+}
+
+/*!
+ This version of the function is called when the \a link is known
+ to be correct.
+ */
+void DocBookGenerator::beginLink(const QString &link, const Node *node, const Node *relative)
+{
+ // From HtmlGenerator::beginLink.
+ writer->writeStartElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "href", link);
+ if (node && !(relative && node->status() == relative->status())
+ && node->status() == Node::Obsolete)
+ writer->writeAttribute("role", "obsolete");
+ inLink = true;
+}
+
+void DocBookGenerator::endLink()
+{
+ // From HtmlGenerator::endLink.
+ if (inLink)
+ writer->writeEndElement(); // link
+ inLink = false;
+}
+
+void DocBookGenerator::generateList(const Node *relative, const QString &selector)
+{
+ // From HtmlGenerator::generateList, without warnings, changing prototype.
+ CNMap cnm;
+ Node::NodeType type = Node::NoType;
+ if (selector == QLatin1String("overviews"))
+ type = Node::Group;
+ else if (selector == QLatin1String("cpp-modules"))
+ type = Node::Module;
+ else if (selector == QLatin1String("qml-modules"))
+ type = Node::QmlModule;
+ else if (selector == QLatin1String("js-modules"))
+ type = Node::JsModule;
+
+ if (type != Node::NoType) {
+ NodeList nodeList;
+ qdb_->mergeCollections(type, cnm, relative);
+ const QList<CollectionNode *> collectionList = cnm.values();
+ nodeList.reserve(collectionList.size());
+ for (auto *collectionNode : collectionList)
+ nodeList.append(collectionNode);
+ generateAnnotatedList(relative, nodeList, selector);
+ } else {
+ /*
+ \generatelist {selector} is only allowed in a
+ comment where the topic is \group, \module,
+ \qmlmodule, or \jsmodule
+ */
+ Node *n = const_cast<Node *>(relative);
+ auto *cn = static_cast<CollectionNode *>(n);
+ qdb_->mergeCollections(cn);
+ generateAnnotatedList(cn, cn->members(), selector);
+ }
+}
+
+/*!
+ Output an annotated list of the nodes in \a nodeMap.
+ A two-column table is output.
+ */
+void DocBookGenerator::generateAnnotatedList(const Node *relative, const NodeMultiMap &nmm,
+ const QString &selector)
+{
+ // From HtmlGenerator::generateAnnotatedList
+ if (nmm.isEmpty())
+ return;
+ generateAnnotatedList(relative, nmm.values(), selector);
+}
+
+void DocBookGenerator::generateAnnotatedList(const Node *relative, const NodeList &nodeList,
+ const QString &selector)
+{
+ // From WebXMLGenerator::generateAnnotatedList.
+ writer->writeStartElement(dbNamespace, "variablelist");
+ writer->writeAttribute("role", selector);
+ newLine();
+
+ for (auto node : nodeList) {
+ writer->writeStartElement(dbNamespace, "varlistentry");
+ newLine();
+ writer->writeStartElement(dbNamespace, "term");
+ generateFullName(node, relative);
+ writer->writeEndElement(); // term
+ newLine();
+
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters(node->doc().briefText().toString());
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // listitem
+ newLine();
+ writer->writeEndElement(); // varlistentry
+ newLine();
+ }
+ writer->writeEndElement(); // variablelist
+ newLine();
+}
+
+/*!
+ Outputs a series of annotated lists from the nodes in \a nmm,
+ divided into sections based by the key names in the multimap.
+ */
+void DocBookGenerator::generateAnnotatedLists(const Node *relative, const NodeMultiMap &nmm,
+ const QString &selector)
+{
+ // From HtmlGenerator::generateAnnotatedLists.
+ for (const QString &name : nmm.uniqueKeys()) {
+ if (!name.isEmpty())
+ startSection(registerRef(name.toLower()), name);
+ generateAnnotatedList(relative, nmm.values(name), selector);
+ if (!name.isEmpty())
+ endSection();
+ }
+}
+
+/*!
+ This function finds the common prefix of the names of all
+ the classes in the class map \a nmm and then generates a
+ compact list of the class names alphabetized on the part
+ of the name not including the common prefix. You can tell
+ the function to use \a comonPrefix as the common prefix,
+ but normally you let it figure it out itself by looking at
+ the name of the first and last classes in the class map
+ \a nmm.
+ */
+void DocBookGenerator::generateCompactList(ListType listType, const Node *relative,
+ const NodeMultiMap &nmm, const QString &commonPrefix,
+ const QString &selector)
+{
+ // From HtmlGenerator::generateCompactList. No more "includeAlphabet", this should be handled by
+ // the DocBook toolchain afterwards.
+ // TODO: In DocBook, probably no need for this method: this is purely presentational, i.e. to be
+ // fully handled by the DocBook toolchain.
+ if (nmm.isEmpty())
+ return;
+
+ const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
+ int commonPrefixLen = commonPrefix.length();
+
+ /*
+ Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z,
+ underscore (_). QAccel will fall in paragraph 10 (A) and
+ QXtWidget in paragraph 33 (X). This is the only place where we
+ assume that NumParagraphs is 37. Each paragraph is a NodeMultiMap.
+ */
+ NodeMultiMap paragraph[NumParagraphs + 1];
+ QString paragraphName[NumParagraphs + 1];
+ QSet<char> usedParagraphNames;
+
+ NodeMultiMap::ConstIterator c = nmm.constBegin();
+ while (c != nmm.constEnd()) {
+ QStringList pieces = c.key().split("::");
+ QString key;
+ int idx = commonPrefixLen;
+ if (idx > 0 && !pieces.last().startsWith(commonPrefix, Qt::CaseInsensitive))
+ idx = 0;
+ key = pieces.last().mid(idx).toLower();
+
+ int paragraphNr = NumParagraphs - 1;
+
+ if (key[0].digitValue() != -1)
+ paragraphNr = key[0].digitValue();
+ else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z'))
+ paragraphNr = 10 + key[0].unicode() - 'a';
+
+ paragraphName[paragraphNr] = key[0].toUpper();
+ usedParagraphNames.insert(key[0].toLower().cell());
+ paragraph[paragraphNr].insert(c.key(), c.value());
+ ++c;
+ }
+
+ /*
+ Each paragraph j has a size: paragraph[j].count(). In the
+ discussion, we will assume paragraphs 0 to 5 will have sizes
+ 3, 1, 4, 1, 5, 9.
+
+ We now want to compute the paragraph offset. Paragraphs 0 to 6
+ start at offsets 0, 3, 4, 8, 9, 14, 23.
+ */
+ int paragraphOffset[NumParagraphs + 1]; // 37 + 1
+ paragraphOffset[0] = 0;
+ for (int i = 0; i < NumParagraphs; i++) // i = 0..36
+ paragraphOffset[i + 1] = paragraphOffset[i] + paragraph[i].count();
+
+ // No table of contents in DocBook.
+
+ // Actual output.
+ numTableRows_ = 0;
+
+ int curParNr = 0;
+ int curParOffset = 0;
+ QString previousName;
+ bool multipleOccurrences = false;
+
+ for (int i = 0; i < nmm.count(); i++) {
+ while ((curParNr < NumParagraphs) && (curParOffset == paragraph[curParNr].count())) {
+ ++curParNr;
+ curParOffset = 0;
+ }
+
+ /*
+ Starting a new paragraph means starting a new variablelist.
+ */
+ if (curParOffset == 0) {
+ if (i > 0) {
+ writer->writeEndElement(); // variablelist
+ newLine();
+ }
+
+ writer->writeStartElement(dbNamespace, "variablelist");
+ writer->writeAttribute("role", selector);
+ newLine();
+ writer->writeStartElement(dbNamespace, "varlistentry");
+ newLine();
+
+ writer->writeStartElement(dbNamespace, "term");
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ writer->writeCharacters(paragraphName[curParNr]);
+ writer->writeEndElement(); // emphasis
+ writer->writeEndElement(); // term
+ newLine();
+ }
+
+ /*
+ Output a listitem for the current offset in the current paragraph.
+ */
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ if ((curParNr < NumParagraphs) && !paragraphName[curParNr].isEmpty()) {
+ NodeMultiMap::Iterator it;
+ NodeMultiMap::Iterator next;
+ it = paragraph[curParNr].begin();
+ for (int j = 0; j < curParOffset; j++)
+ ++it;
+
+ if (listType == Generic) {
+ generateFullName(it.value(), relative);
+ writer->writeStartElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "href", fullDocumentLocation(*it));
+ writer->writeAttribute("type", targetType(it.value()));
+ } else if (listType == Obsolete) {
+ QString fn = fileName(it.value(), fileExtension());
+ QString link;
+ if (useOutputSubdirs())
+ link = QString("../" + it.value()->outputSubdirectory() + QLatin1Char('/'));
+ link += fn;
+
+ writer->writeStartElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "href", link);
+ writer->writeAttribute("type", targetType(it.value()));
+ }
+
+ QStringList pieces;
+ if (it.value()->isQmlType() || it.value()->isJsType()) {
+ QString name = it.value()->name();
+ next = it;
+ ++next;
+ if (name != previousName)
+ multipleOccurrences = false;
+ if ((next != paragraph[curParNr].end()) && (name == next.value()->name())) {
+ multipleOccurrences = true;
+ previousName = name;
+ }
+ if (multipleOccurrences)
+ name += ": " + it.value()->tree()->camelCaseModuleName();
+ pieces << name;
+ } else
+ pieces = it.value()->fullName(relative).split("::");
+
+ writer->writeCharacters(pieces.last());
+ writer->writeEndElement(); // link
+
+ if (pieces.size() > 1) {
+ writer->writeCharacters(" (");
+ generateFullName(it.value()->parent(), relative);
+ writer->writeCharacters(")");
+ }
+ }
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // listitem
+ newLine();
+ writer->writeEndElement(); // varlistentry
+ newLine();
+ curParOffset++;
+ }
+ if (nmm.count() > 0) {
+ writer->writeEndElement(); // variablelist
+ }
+}
+
+void DocBookGenerator::generateFunctionIndex(const Node *relative)
+{
+ // From HtmlGenerator::generateFunctionIndex.
+ writer->writeStartElement(dbNamespace, "simplelist");
+ writer->writeAttribute("role", "functionIndex");
+ newLine();
+ for (int i = 0; i < 26; i++) {
+ QChar ch('a' + i);
+ writer->writeStartElement(dbNamespace, "member");
+ writer->writeAttribute(xlinkNamespace, "href", QString("#") + ch);
+ writer->writeCharacters(ch.toUpper());
+ writer->writeEndElement(); // member
+ newLine();
+ }
+ writer->writeEndElement(); // simplelist
+ newLine();
+
+ char nextLetter = 'a';
+ char currentLetter;
+
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+
+ NodeMapMap &funcIndex = qdb_->getFunctionIndex();
+ QMap<QString, NodeMap>::ConstIterator f = funcIndex.constBegin();
+ while (f != funcIndex.constEnd()) {
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters(f.key() + ": ");
+
+ currentLetter = f.key()[0].unicode();
+ while (islower(currentLetter) && currentLetter >= nextLetter) {
+ writeAnchor(QString(nextLetter));
+ nextLetter++;
+ }
+
+ NodeMap::ConstIterator s = (*f).constBegin();
+ while (s != (*f).constEnd()) {
+ writer->writeCharacters(" ");
+ generateFullName((*s)->parent(), relative);
+ ++s;
+ }
+
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // listitem
+ newLine();
+ ++f;
+ }
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+}
+
+void DocBookGenerator::generateLegaleseList(const Node *relative)
+{
+ // From HtmlGenerator::generateLegaleseList.
+ TextToNodeMap &legaleseTexts = qdb_->getLegaleseTexts();
+ QMap<Text, const Node *>::ConstIterator it = legaleseTexts.constBegin();
+ while (it != legaleseTexts.constEnd()) {
+ Text text = it.key();
+ generateText(text, relative);
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+ do {
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ generateFullName(it.value(), relative);
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // listitem
+ newLine();
+ ++it;
+ } while (it != legaleseTexts.constEnd() && it.key() == text);
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+ }
+}
+
+void DocBookGenerator::generateBrief(const Node *node)
+{
+ // From HtmlGenerator::generateBrief. Also see generateHeader, which is specifically dealing
+ // with the DocBook header (and thus wraps the brief in an abstract).
+ Text brief = node->doc().briefText();
+
+ if (!brief.isEmpty()) {
+ if (!brief.lastAtom()->string().endsWith('.'))
+ brief << Atom(Atom::String, ".");
+
+ writer->writeStartElement(dbNamespace, "para");
+ generateText(brief, node);
+ writer->writeEndElement(); // para
+ newLine();
+ }
+}
+
+bool DocBookGenerator::generateSince(const Node *node)
+{
+ // From Generator::generateSince.
+ if (!node->since().isEmpty()) {
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("This " + typeString(node) + " was introduced");
+ if (node->nodeType() == Node::Enum)
+ writer->writeCharacters(" or modified");
+ writer->writeCharacters(" in " + formatSince(node) + ".");
+ writer->writeEndElement(); // para
+ newLine();
+
+ return true;
+ }
+
+ return false;
+}
+
+void DocBookGenerator::generateHeader(const QString &title, const QString &subTitle,
+ const Node *node)
+{
+ // From HtmlGenerator::generateHeader.
+ refMap.clear();
+
+ // Output the DocBook header.
+ writer->writeStartElement(dbNamespace, "info");
+ newLine();
+ writer->writeTextElement(dbNamespace, "title", title);
+ newLine();
+
+ if (!subTitle.isEmpty()) {
+ writer->writeTextElement(dbNamespace, "subtitle", subTitle);
+ newLine();
+ }
+
+ if (!project.isEmpty()) {
+ writer->writeTextElement(dbNamespace, "productname", project);
+ newLine();
+ }
+
+ if (!buildversion.isEmpty()) {
+ writer->writeTextElement(dbNamespace, "edition", buildversion);
+ newLine();
+ }
+
+ if (!projectDescription.isEmpty()) {
+ writer->writeTextElement(dbNamespace, "titleabbrev", projectDescription);
+ newLine();
+ }
+
+ // Deal with links.
+ // Adapted from HtmlGenerator::generateHeader (output part: no need to update a navigationLinks
+ // or useSeparator field, as this content is only output in the info tag, not in the main
+ // content).
+ if (node && !node->links().empty()) {
+ QPair<QString, QString> linkPair;
+ QPair<QString, QString> anchorPair;
+ const Node *linkNode;
+
+ if (node->links().contains(Node::PreviousLink)) {
+ linkPair = node->links()[Node::PreviousLink];
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode || linkNode == node)
+ anchorPair = linkPair;
+ else
+ anchorPair = anchorForNode(linkNode);
+
+ writer->writeStartElement(dbNamespace, "extendedlink");
+ writer->writeEmptyElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "to", anchorPair.first);
+ writer->writeAttribute(xlinkNamespace, "title", "prev");
+ if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
+ writer->writeAttribute(xlinkNamespace, "label", anchorPair.second);
+ else
+ writer->writeAttribute(xlinkNamespace, "label", linkPair.second);
+ writer->writeEndElement(); // extendedlink
+ }
+ if (node->links().contains(Node::NextLink)) {
+ linkPair = node->links()[Node::NextLink];
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode || linkNode == node)
+ anchorPair = linkPair;
+ else
+ anchorPair = anchorForNode(linkNode);
+
+ writer->writeStartElement(dbNamespace, "extendedlink");
+ writer->writeEmptyElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "to", anchorPair.first);
+ writer->writeAttribute(xlinkNamespace, "title", "prev");
+ if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
+ writer->writeAttribute(xlinkNamespace, "label", anchorPair.second);
+ else
+ writer->writeAttribute(xlinkNamespace, "label", linkPair.second);
+ writer->writeEndElement(); // extendedlink
+ }
+ if (node->links().contains(Node::StartLink)) {
+ linkPair = node->links()[Node::StartLink];
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode || linkNode == node)
+ anchorPair = linkPair;
+ else
+ anchorPair = anchorForNode(linkNode);
+
+ writer->writeStartElement(dbNamespace, "extendedlink");
+ writer->writeEmptyElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "to", anchorPair.first);
+ writer->writeAttribute(xlinkNamespace, "title", "start");
+ if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
+ writer->writeAttribute(xlinkNamespace, "label", anchorPair.second);
+ else
+ writer->writeAttribute(xlinkNamespace, "label", linkPair.second);
+ writer->writeEndElement(); // extendedlink
+ }
+ }
+
+ // Deal with the abstract (what qdoc calls brief).
+ if (node) {
+ // Adapted from HtmlGenerator::generateBrief, without extraction marks. The parameter
+ // addLink is always false. Factoring this function out is not as easy as in HtmlGenerator:
+ // abstracts only happen in the header (info tag), slightly different tags must be used at
+ // other places. Also includes code from HtmlGenerator::generateCppReferencePage to handle
+ // the name spaces.
+ writer->writeStartElement(dbNamespace, "abstract");
+ newLine();
+
+ bool generatedSomething = false;
+
+ Text brief;
+ const NamespaceNode *ns = node->isAggregate()
+ ? static_cast<const NamespaceNode *>(static_cast<const Aggregate *>(node))
+ : nullptr;
+ if (node->isAggregate() && ns && !ns->hasDoc() && ns->docNode()) {
+ NamespaceNode *NS = ns->docNode();
+ brief << "The " << ns->name()
+ << " namespace includes the following elements from module "
+ << ns->tree()->camelCaseModuleName() << ". The full namespace is "
+ << "documented in module " << NS->tree()->camelCaseModuleName()
+ << Atom(Atom::LinkNode, fullDocumentLocation(NS))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, " here.")
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ } else {
+ brief = node->doc().briefText();
+ }
+
+ if (!brief.isEmpty()) {
+ if (!brief.lastAtom()->string().endsWith('.'))
+ brief << Atom(Atom::String, ".");
+
+ writer->writeStartElement(dbNamespace, "para");
+ generateText(brief, node);
+ writer->writeEndElement(); // para
+ newLine();
+
+ generatedSomething = true;
+ }
+
+ // Generate other paragraphs that should go into the abstract.
+ generatedSomething |= generateStatus(node);
+ generatedSomething |= generateSince(node);
+ generatedSomething |= generateThreadSafeness(node);
+
+ // An abstract cannot be empty, hence use the project description.
+ if (!generatedSomething)
+ writer->writeTextElement(dbNamespace, "para", projectDescription + ".");
+
+ writer->writeEndElement(); // abstract
+ newLine();
+ }
+
+ // End of the DocBook header.
+ writer->writeEndElement(); // info
+ newLine();
+}
+
+void DocBookGenerator::closeTextSections()
+{
+ while (!sectionLevels.isEmpty()) {
+ sectionLevels.pop();
+ endSection();
+ }
+}
+
+void DocBookGenerator::generateFooter()
+{
+ closeTextSections();
+ writer->writeEndElement(); // article
+}
+
+void DocBookGenerator::generateSimpleLink(const QString &href, const QString &text)
+{
+ writer->writeStartElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "href", href);
+ writer->writeCharacters(text);
+ writer->writeEndElement(); // link
+}
+
+void DocBookGenerator::generateObsoleteMembers(const Sections &sections)
+{
+ // From HtmlGenerator::generateObsoleteMembersFile.
+ SectionPtrVector summary_spv; // Summaries are ignored in DocBook (table of contents).
+ SectionPtrVector details_spv;
+ if (!sections.hasObsoleteMembers(&summary_spv, &details_spv))
+ return;
+
+ Aggregate *aggregate = sections.aggregate();
+ QString link;
+ if (useOutputSubdirs() && !Generator::outputSubdir().isEmpty())
+ link = QString("../" + Generator::outputSubdir() + QLatin1Char('/'));
+ link += fileName(aggregate, fileExtension());
+ aggregate->setObsoleteLink(link);
+
+ startSection("obsolete", "Obsolete Members for " + aggregate->name());
+
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ writer->writeCharacters("The following members of class ");
+ generateSimpleLink(linkForNode(aggregate, nullptr), aggregate->name());
+ writer->writeCharacters(" are obsolete.");
+ writer->writeEndElement(); // emphasis bold
+ writer->writeCharacters(" They are provided to keep old source code working. "
+ "We strongly advise against using them in new code.");
+ writer->writeEndElement(); // para
+ newLine();
+
+ for (int i = 0; i < details_spv.size(); ++i) {
+ QString title = details_spv.at(i)->title();
+ QString ref = registerRef(title.toLower());
+ startSection(ref, title);
+
+ const NodeVector &members = details_spv.at(i)->obsoleteMembers();
+ NodeVector::ConstIterator m = members.constBegin();
+ while (m != members.constEnd()) {
+ if ((*m)->access() != Node::Private)
+ generateDetailedMember(*m, aggregate);
+ ++m;
+ }
+
+ endSection();
+ }
+
+ endSection();
+}
+
+/*!
+ Generates a separate file where obsolete members of the QML
+ type \a qcn are listed. The \a marker is used to generate
+ the section lists, which are then traversed and output here.
+
+ Note that this function currently only handles correctly the
+ case where \a status is \c {Section::Obsolete}.
+ */
+void DocBookGenerator::generateObsoleteQmlMembers(const Sections &sections)
+{
+ // From HtmlGenerator::generateObsoleteQmlMembersFile.
+ SectionPtrVector summary_spv; // Summaries are not useful in DocBook.
+ SectionPtrVector details_spv;
+ if (!sections.hasObsoleteMembers(&summary_spv, &details_spv))
+ return;
+
+ Aggregate *aggregate = sections.aggregate();
+ QString title = "Obsolete Members for " + aggregate->name();
+ QString fn = fileName(aggregate, fileExtension());
+ QString link;
+ if (useOutputSubdirs() && !Generator::outputSubdir().isEmpty())
+ link = QString("../" + Generator::outputSubdir() + QLatin1Char('/'));
+ link += fn;
+ aggregate->setObsoleteLink(link);
+
+ startSection("obsolete", "Obsolete Members for " + aggregate->name());
+
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ writer->writeCharacters("The following members of QML type ");
+ generateSimpleLink(linkForNode(aggregate, nullptr), aggregate->name());
+ writer->writeCharacters(" are obsolete.");
+ writer->writeEndElement(); // emphasis bold
+ writer->writeCharacters("They are provided to keep old source code working. "
+ "We strongly advise against using them in new code.");
+ writer->writeEndElement(); // para
+ newLine();
+
+ for (auto i : details_spv) {
+ QString ref = registerRef(i->title().toLower());
+ startSection(ref, i->title());
+
+ NodeVector::ConstIterator m = i->members().constBegin();
+ while (m != i->members().constEnd()) {
+ generateDetailedQmlMember(*m, aggregate);
+ ++m;
+ }
+
+ endSection();
+ }
+
+ endSection();
+}
+
+static QString nodeToSynopsisTag(const Node *node)
+{
+ // Order from Node::nodeTypeString.
+ if (node->isClass() || node->isQmlType() || node->isQmlBasicType())
+ return QStringLiteral("classsynopsis");
+ if (node->isNamespace())
+ return QStringLiteral("namespacesynopsis");
+ if (node->isPageNode()) {
+ node->doc().location().warning("Unexpected document node in nodeToSynopsisTag");
+ return QString();
+ }
+ if (node->isEnumType())
+ return QStringLiteral("enumsynopsis");
+ if (node->isTypedef())
+ return QStringLiteral("typedefsynopsis");
+ if (node->isFunction()) {
+ // Signals are also encoded as functions (including QML/JS ones).
+ const auto fn = static_cast<const FunctionNode *>(node);
+ if (fn->isCtor() || fn->isCCtor() || fn->isMCtor())
+ return QStringLiteral("constructorsynopsis");
+ if (fn->isDtor())
+ return QStringLiteral("destructorsynopsis");
+ return QStringLiteral("methodsynopsis");
+ }
+ if (node->isProperty() || node->isVariable() || node->isQmlProperty())
+ return QStringLiteral("fieldsynopsis");
+
+ node->doc().location().warning(QString("Unknown node tag %1").arg(node->nodeTypeString()));
+ return QStringLiteral("synopsis");
+}
+
+void DocBookGenerator::generateStartRequisite(const QString &description)
+{
+ writer->writeStartElement(dbNamespace, "varlistentry");
+ newLine();
+ writer->writeTextElement(dbNamespace, "term", description);
+ newLine();
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+}
+
+void DocBookGenerator::generateEndRequisite()
+{
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // listitem
+ newLine();
+ writer->writeEndElement(); // varlistentry
+ newLine();
+}
+
+void DocBookGenerator::generateRequisite(const QString &description, const QString &value)
+{
+ generateStartRequisite(description);
+ writer->writeCharacters(value);
+ generateEndRequisite();
+}
+
+void DocBookGenerator::generateSortedNames(const ClassNode *cn, const QVector<RelatedClass> &rc)
+{
+ // From Generator::appendSortedNames.
+ QMap<QString, ClassNode *> classMap;
+ QVector<RelatedClass>::ConstIterator r = rc.constBegin();
+ while (r != rc.constEnd()) {
+ ClassNode *rcn = (*r).node_;
+ if (rcn && rcn->access() == Node::Public && rcn->status() != Node::Internal
+ && !rcn->doc().isEmpty()) {
+ classMap[rcn->plainFullName(cn).toLower()] = rcn;
+ }
+ ++r;
+ }
+
+ QStringList classNames = classMap.keys();
+ classNames.sort();
+
+ int index = 0;
+ for (const QString &className : classNames) {
+ generateFullName(classMap.value(className), cn);
+ writer->writeCharacters(comma(index++, classNames.count()));
+ }
+}
+
+void DocBookGenerator::generateSortedQmlNames(const Node *base, const NodeList &subs)
+{
+ // From Generator::appendSortedQmlNames.
+ QMap<QString, Node *> classMap;
+ int index = 0;
+
+ for (auto sub : subs)
+ if (!base->isQtQuickNode() || !sub->isQtQuickNode()
+ || (base->logicalModuleName() == sub->logicalModuleName()))
+ classMap[sub->plainFullName(base).toLower()] = sub;
+
+ QStringList names = classMap.keys();
+ names.sort();
+
+ for (const QString &name : names) {
+ generateFullName(classMap.value(name), base);
+ writer->writeCharacters(comma(index++, names.count()));
+ }
+}
+
+/*!
+ Lists the required imports and includes.
+*/
+void DocBookGenerator::generateRequisites(const Aggregate *aggregate)
+{
+ // Adapted from HtmlGenerator::generateRequisites, but simplified: no need to store all the
+ // elements, they can be produced one by one.
+ writer->writeStartElement(dbNamespace, "variablelist");
+ newLine();
+
+ // Includes.
+ if (!aggregate->includeFiles().isEmpty()) {
+ for (const QString &include : aggregate->includeFiles())
+ generateRequisite("Header", include);
+ }
+
+ // Since and project.
+ if (!aggregate->since().isEmpty())
+ generateRequisite("Since", formatSince(aggregate));
+
+ if (aggregate->isClassNode() || aggregate->isNamespace()) {
+ // QT variable.
+ if (!aggregate->physicalModuleName().isEmpty()) {
+ const CollectionNode *cn =
+ qdb_->getCollectionNode(aggregate->physicalModuleName(), Node::Module);
+ if (cn && !cn->qtVariable().isEmpty()) {
+ generateRequisite("qmake", "QT += " + cn->qtVariable());
+ }
+ }
+ }
+
+ if (aggregate->nodeType() == Node::Class) {
+ // Instantiated by.
+ auto *classe = const_cast<ClassNode *>(static_cast<const ClassNode *>(aggregate));
+ if (classe->qmlElement() != nullptr && classe->status() != Node::Internal) {
+ generateStartRequisite("Inherited By");
+ generateSortedNames(classe, classe->derivedClasses());
+ generateEndRequisite();
+ generateRequisite("Instantiated By", fullDocumentLocation(classe->qmlElement()));
+ }
+
+ // Inherits.
+ QVector<RelatedClass>::ConstIterator r;
+ if (!classe->baseClasses().isEmpty()) {
+ generateStartRequisite("Inherits");
+
+ r = classe->baseClasses().constBegin();
+ int index = 0;
+ while (r != classe->baseClasses().constEnd()) {
+ if ((*r).node_) {
+ generateFullName((*r).node_, classe);
+
+ if ((*r).access_ == Node::Protected)
+ writer->writeCharacters(" (protected)");
+ else if ((*r).access_ == Node::Private)
+ writer->writeCharacters(" (private)");
+ writer->writeCharacters(comma(index++, classe->baseClasses().count()));
+ }
+ ++r;
+ }
+
+ generateEndRequisite();
+ }
+
+ // Inherited by.
+ if (!classe->derivedClasses().isEmpty()) {
+ generateStartRequisite("Inherited By");
+ generateSortedNames(classe, classe->derivedClasses());
+ generateEndRequisite();
+ }
+ }
+
+ writer->writeEndElement(); // variablelist
+ newLine();
+}
+
+/*!
+ Lists the required imports and includes.
+*/
+void DocBookGenerator::generateQmlRequisites(const QmlTypeNode *qcn)
+{
+ // From HtmlGenerator::generateQmlRequisites, but simplified: no need to store all the elements,
+ // they can be produced one by one.
+ if (!qcn)
+ return;
+
+ writer->writeStartElement(dbNamespace, "variablelist");
+ newLine();
+
+ // Module name and version (i.e. import).
+ QString logicalModuleVersion;
+ const CollectionNode *collection = qcn->logicalModule();
+
+ // skip import statement for \internal collections
+ if (!collection || !collection->isInternal() || showInternal_) {
+ logicalModuleVersion =
+ collection ? collection->logicalModuleVersion() : qcn->logicalModuleVersion();
+
+ generateRequisite("Import Statement",
+ "import " + qcn->logicalModuleName() + QLatin1Char(' ')
+ + logicalModuleVersion);
+ }
+
+ // Since and project.
+ if (!qcn->since().isEmpty())
+ generateRequisite("Since:", formatSince(qcn));
+
+ // Inherited by.
+ NodeList subs;
+ QmlTypeNode::subclasses(qcn, subs);
+ if (!subs.isEmpty()) {
+ generateStartRequisite("Inherited By:");
+ generateSortedQmlNames(qcn, subs);
+ generateEndRequisite();
+ }
+
+ // Inherits.
+ QmlTypeNode *base = qcn->qmlBaseNode();
+ while (base && base->isInternal()) {
+ base = base->qmlBaseNode();
+ }
+ if (base) {
+ const Node *otherNode = nullptr;
+ Atom a = Atom(Atom::LinkNode, CodeMarker::stringForNode(base));
+ QString link = getAutoLink(&a, qcn, &otherNode);
+
+ generateStartRequisite("Inherits:");
+ generateSimpleLink(link, base->name());
+ generateEndRequisite();
+ }
+
+ // Instantiates.
+ ClassNode *cn = (const_cast<QmlTypeNode *>(qcn))->classNode();
+ if (cn && (cn->status() != Node::Internal)) {
+ const Node *otherNode = nullptr;
+ Atom a = Atom(Atom::LinkNode, CodeMarker::stringForNode(qcn));
+ QString link = getAutoLink(&a, cn, &otherNode);
+
+ generateStartRequisite("Instantiates:");
+ generateSimpleLink(fullDocumentLocation(cn), cn->name());
+ generateEndRequisite();
+ }
+
+ writer->writeEndElement(); // variablelist
+ newLine();
+}
+
+bool DocBookGenerator::generateStatus(const Node *node)
+{
+ // From Generator::generateStatus.
+ switch (node->status()) {
+ case Node::Active:
+ // Do nothing.
+ return false;
+ case Node::Preliminary:
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ writer->writeCharacters("This " + typeString(node)
+ + " is under development and is subject to change.");
+ writer->writeEndElement(); // emphasis
+ writer->writeEndElement(); // para
+ newLine();
+ return true;
+ case Node::Deprecated:
+ writer->writeStartElement(dbNamespace, "para");
+ if (node->isAggregate()) {
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ }
+ writer->writeCharacters("This " + typeString(node) + " is deprecated.");
+ if (node->isAggregate())
+ writer->writeEndElement(); // emphasis
+ writer->writeEndElement(); // para
+ newLine();
+ return true;
+ case Node::Obsolete:
+ writer->writeStartElement(dbNamespace, "para");
+ if (node->isAggregate()) {
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ }
+ writer->writeCharacters("This " + typeString(node) + " is obsolete.");
+ if (node->isAggregate())
+ writer->writeEndElement(); // emphasis
+ writer->writeCharacters(" It is provided to keep old source code working. "
+ "We strongly advise against using it in new code.");
+ writer->writeEndElement(); // para
+ newLine();
+ return true;
+ case Node::Internal:
+ default:
+ return false;
+ }
+}
+
+/*!
+ Generate a list of function signatures. The function nodes
+ are in \a nodes.
+ */
+void DocBookGenerator::generateSignatureList(const NodeList &nodes)
+{
+ // From Generator::signatureList and Generator::appendSignature.
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+
+ NodeList::ConstIterator n = nodes.constBegin();
+ while (n != nodes.constEnd()) {
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+
+ generateSimpleLink(currentGenerator()->fullDocumentLocation(*n),
+ (*n)->signature(false, true));
+
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+ ++n;
+ }
+
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+}
+
+/*!
+ Generates text that explains how threadsafe and/or reentrant
+ \a node is.
+ */
+bool DocBookGenerator::generateThreadSafeness(const Node *node)
+{
+ // From Generator::generateThreadSafeness
+ Node::ThreadSafeness ts = node->threadSafeness();
+
+ const Node *reentrantNode;
+ Atom reentrantAtom = Atom(Atom::Link, "reentrant");
+ QString linkReentrant = getAutoLink(&reentrantAtom, node, &reentrantNode);
+ const Node *threadSafeNode;
+ Atom threadSafeAtom = Atom(Atom::Link, "thread-safe");
+ QString linkThreadSafe = getAutoLink(&threadSafeAtom, node, &threadSafeNode);
+
+ if (ts == Node::NonReentrant) {
+ writer->writeStartElement(dbNamespace, "warning");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("This " + typeString(node) + " is not ");
+ generateSimpleLink(linkReentrant, "reentrant");
+ writer->writeCharacters(".");
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // warning
+
+ return true;
+ }
+ if (ts == Node::Reentrant || ts == Node::ThreadSafe) {
+ writer->writeStartElement(dbNamespace, "note");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+
+ if (node->isAggregate()) {
+ writer->writeCharacters("All functions in this " + typeString(node) + " are ");
+ if (ts == Node::ThreadSafe)
+ generateSimpleLink(linkThreadSafe, "thread-safe");
+ else
+ generateSimpleLink(linkReentrant, "reentrant");
+
+ NodeList reentrant;
+ NodeList threadsafe;
+ NodeList nonreentrant;
+ bool exceptions = hasExceptions(node, reentrant, threadsafe, nonreentrant);
+ if (!exceptions || (ts == Node::Reentrant && !threadsafe.isEmpty())) {
+ writer->writeCharacters(".");
+ writer->writeEndElement(); // para
+ newLine();
+ } else {
+ writer->writeCharacters(" with the following exceptions:");
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+
+ if (ts == Node::Reentrant) {
+ if (!nonreentrant.isEmpty()) {
+ writer->writeCharacters("These functions are not ");
+ generateSimpleLink(linkReentrant, "reentrant");
+ writer->writeCharacters(":");
+ writer->writeEndElement(); // para
+ newLine();
+ generateSignatureList(nonreentrant);
+ }
+ if (!threadsafe.isEmpty()) {
+ writer->writeCharacters("These functions are also ");
+ generateSimpleLink(linkThreadSafe, "thread-safe");
+ writer->writeCharacters(":");
+ writer->writeEndElement(); // para
+ newLine();
+ generateSignatureList(threadsafe);
+ }
+ } else { // thread-safe
+ if (!reentrant.isEmpty()) {
+ writer->writeCharacters("These functions are only ");
+ generateSimpleLink(linkReentrant, "reentrant");
+ writer->writeCharacters(":");
+ writer->writeEndElement(); // para
+ newLine();
+ generateSignatureList(reentrant);
+ }
+ if (!nonreentrant.isEmpty()) {
+ writer->writeCharacters("These functions are not ");
+ generateSimpleLink(linkReentrant, "reentrant");
+ writer->writeCharacters(":");
+ writer->writeEndElement(); // para
+ newLine();
+ generateSignatureList(nonreentrant);
+ }
+ }
+ }
+ } else {
+ writer->writeCharacters("This " + typeString(node) + " is ");
+ if (ts == Node::ThreadSafe)
+ generateSimpleLink(linkThreadSafe, "thread-safe");
+ else
+ generateSimpleLink(linkReentrant, "reentrant");
+ writer->writeCharacters(".");
+ writer->writeEndElement(); // para
+ newLine();
+ }
+ writer->writeEndElement(); // note
+
+ return true;
+ }
+
+ return false;
+}
+
+/*!
+ Generate the body of the documentation from the qdoc comment
+ found with the entity represented by the \a node.
+ */
+void DocBookGenerator::generateBody(const Node *node)
+{
+ // From Generator::generateBody, without warnings.
+ const FunctionNode *fn = node->isFunction() ? static_cast<const FunctionNode *>(node) : nullptr;
+
+ if (!node->hasDoc() && !node->hasSharedDoc()) {
+ /*
+ Test for special function, like a destructor or copy constructor,
+ that has no documentation.
+ */
+ if (fn) {
+ QString t;
+ if (fn->isDtor()) {
+ t = "Destroys the instance of " + fn->parent()->name() + ".";
+ if (fn->isVirtual())
+ t += " The destructor is virtual.";
+ } else if (fn->isCtor()) {
+ t = "Default constructs an instance of " + fn->parent()->name() + ".";
+ } else if (fn->isCCtor()) {
+ t = "Copy constructor.";
+ } else if (fn->isMCtor()) {
+ t = "Move-copy constructor.";
+ } else if (fn->isCAssign()) {
+ t = "Copy-assignment constructor.";
+ } else if (fn->isMAssign()) {
+ t = "Move-assignment constructor.";
+ }
+
+ if (!t.isEmpty())
+ writer->writeTextElement(dbNamespace, "para", t);
+ }
+ } else if (!node->isSharingComment()) {
+ if (fn) {
+ if (!fn->overridesThis().isEmpty())
+ generateReimplementsClause(fn);
+ }
+
+ if (!generateText(node->doc().body(), node)) {
+ if (node->isMarkedReimp())
+ return;
+ }
+
+ if (fn) {
+ if (fn->isQmlSignal())
+ generateAddendum(node, QmlSignalHandler);
+ if (fn->isPrivateSignal())
+ generateAddendum(node, PrivateSignal);
+ if (fn->isInvokable())
+ generateAddendum(node, Invokable);
+ if (fn->hasAssociatedProperties())
+ generateAddendum(node, AssociatedProperties);
+ }
+
+ // Warning generation skipped with respect to Generator::generateBody.
+ }
+
+ generateRequiredLinks(node);
+}
+
+/*!
+ Generates either a link to the project folder for example \a node, or a list
+ of links files/images if 'url.examples config' variable is not defined.
+
+ Does nothing for non-example nodes.
+*/
+void DocBookGenerator::generateRequiredLinks(const Node *node)
+{
+ // From Generator::generateRequiredLinks.
+ if (!node->isExample())
+ return;
+
+ const auto en = static_cast<const ExampleNode *>(node);
+ QString exampleUrl = Config::instance().getString(CONFIG_URL + Config::dot + CONFIG_EXAMPLES);
+
+ if (exampleUrl.isEmpty()) {
+ if (!en->noAutoList()) {
+ generateFileList(en, false); // files
+ generateFileList(en, true); // images
+ }
+ } else {
+ generateLinkToExample(en, exampleUrl);
+ }
+}
+
+/*!
+ The path to the example replaces a placeholder '\1' character if
+ one is found in the \a baseUrl string. If no such placeholder is found,
+ the path is appended to \a baseUrl, after a '/' character if \a baseUrl did
+ not already end in one.
+*/
+void DocBookGenerator::generateLinkToExample(const ExampleNode *en, const QString &baseUrl)
+{
+ // From Generator::generateLinkToExample.
+ QString exampleUrl(baseUrl);
+ QString link;
+#ifndef QT_BOOTSTRAPPED
+ link = QUrl(exampleUrl).host();
+#endif
+ if (!link.isEmpty())
+ link.prepend(" @ ");
+ link.prepend("Example project");
+
+ const QLatin1Char separator('/');
+ const QLatin1Char placeholder('\1');
+ if (!exampleUrl.contains(placeholder)) {
+ if (!exampleUrl.endsWith(separator))
+ exampleUrl += separator;
+ exampleUrl += placeholder;
+ }
+
+ // Construct a path to the example; <install path>/<example name>
+ QStringList path = QStringList()
+ << Config::instance().getString(CONFIG_EXAMPLESINSTALLPATH) << en->name();
+ path.removeAll({});
+
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeStartElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "href",
+ exampleUrl.replace(placeholder, path.join(separator)));
+ writer->writeCharacters(link);
+ writer->writeEndElement(); // link
+ writer->writeEndElement(); // para
+ newLine();
+}
+
+/*!
+ This function is called when the documentation for an example is
+ being formatted. It outputs a list of files for the example, which
+ can be the example's source files or the list of images used by the
+ example. The images are copied into a subtree of
+ \c{...doc/html/images/used-in-examples/...}
+*/
+void DocBookGenerator::generateFileList(const ExampleNode *en, bool images)
+{
+ // From Generator::generateFileList
+ QString tag;
+ QStringList paths;
+ if (images) {
+ paths = en->images();
+ tag = "Images:";
+ } else { // files
+ paths = en->files();
+ tag = "Files:";
+ }
+ std::sort(paths.begin(), paths.end(), Generator::comparePaths);
+
+ if (paths.isEmpty())
+ return;
+
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters(tag);
+ writer->writeEndElement(); // para
+ newLine();
+
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+
+ for (const auto &file : qAsConst(paths)) {
+ if (images) {
+ if (!file.isEmpty())
+ addImageToCopy(en, file);
+ } else {
+ generateExampleFilePage(en, file);
+ }
+
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ generateSimpleLink(file, file);
+ writer->writeEndElement(); // para
+ writer->writeEndElement(); // listitem
+ newLine();
+ }
+
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+}
+
+/*!
+ Generate a file with the contents of a C++ or QML source file.
+ */
+void DocBookGenerator::generateExampleFilePage(const Node *node, const QString &file,
+ CodeMarker *marker)
+{
+ Q_UNUSED(marker);
+ // From HtmlGenerator::generateExampleFilePage.
+ if (!node->isExample())
+ return;
+
+ const auto en = static_cast<const ExampleNode *>(node);
+
+ // Store current (active) writer
+ QXmlStreamWriter *currentWriter = writer;
+ writer = startDocument(en, file);
+ generateHeader(en->fullTitle(), en->subtitle(), en);
+
+ Text text;
+ Quoter quoter;
+ Doc::quoteFromFile(en->doc().location(), quoter, file);
+ QString code = quoter.quoteTo(en->location(), QString(), QString());
+ CodeMarker *codeMarker = CodeMarker::markerForFileName(file);
+ text << Atom(codeMarker->atomType(), code);
+ Atom a(codeMarker->atomType(), code);
+ generateText(text, en);
+
+ endDocument();
+ // Restore writer
+ writer = currentWriter;
+}
+
+void DocBookGenerator::generateReimplementsClause(const FunctionNode *fn)
+{
+ // From Generator::generateReimplementsClause, without warning generation.
+ if (!fn->overridesThis().isEmpty()) {
+ if (fn->parent()->isClassNode()) {
+ auto cn = static_cast<ClassNode *>(fn->parent());
+ const FunctionNode *overrides = cn->findOverriddenFunction(fn);
+ if (overrides && !overrides->isPrivate() && !overrides->parent()->isPrivate()) {
+ if (overrides->hasDoc()) {
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("Reimplements: ");
+ QString fullName =
+ overrides->parent()->name() + "::" + overrides->signature(false, true);
+ generateFullName(overrides->parent(), fullName, overrides);
+ writer->writeCharacters(".");
+ return;
+ }
+ }
+ const PropertyNode *sameName = cn->findOverriddenProperty(fn);
+ if (sameName && sameName->hasDoc()) {
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("Reimplements an access function for property: ");
+ QString fullName = sameName->parent()->name() + "::" + sameName->name();
+ generateFullName(sameName->parent(), fullName, overrides);
+ writer->writeCharacters(".");
+ return;
+ }
+ }
+ }
+}
+
+void DocBookGenerator::generateAlsoList(const Node *node, CodeMarker *marker)
+{
+ Q_UNUSED(marker);
+ // From Generator::generateAlsoList.
+ QVector<Text> alsoList = node->doc().alsoList();
+ supplementAlsoList(node, alsoList);
+
+ if (!alsoList.isEmpty()) {
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeCharacters("See also ");
+ writer->writeEndElement(); // emphasis
+ newLine();
+
+ writer->writeStartElement(dbNamespace, "simplelist");
+ writer->writeAttribute("type", "vert");
+ writer->writeAttribute("role", "see-also");
+ for (const Text &text : alsoList) {
+ writer->writeStartElement(dbNamespace, "member");
+ generateText(text, node);
+ writer->writeEndElement(); // member
+ newLine();
+ }
+ writer->writeEndElement(); // simplelist
+ newLine();
+
+ writer->writeEndElement(); // para
+ }
+}
+
+/*!
+ Generate a list of maintainers in the output
+ */
+void DocBookGenerator::generateMaintainerList(const Aggregate *node, CodeMarker *marker)
+{
+ Q_UNUSED(marker);
+ // From Generator::generateMaintainerList.
+ QStringList sl = getMetadataElements(node, "maintainer");
+
+ if (!sl.isEmpty()) {
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeCharacters("Maintained by: ");
+ writer->writeEndElement(); // emphasis
+ newLine();
+
+ writer->writeStartElement(dbNamespace, "simplelist");
+ writer->writeAttribute("type", "vert");
+ writer->writeAttribute("role", "maintainer");
+ for (int i = 0; i < sl.size(); ++i) {
+ writer->writeStartElement(dbNamespace, "member");
+ writer->writeCharacters(sl.at(i));
+ writer->writeEndElement(); // member
+ newLine();
+ }
+ writer->writeEndElement(); // simplelist
+ newLine();
+
+ writer->writeEndElement(); // para
+ }
+}
+
+/*!
+ Open a new file to write XML contents, including the DocBook
+ opening tag.
+ */
+QXmlStreamWriter *DocBookGenerator::startGenericDocument(const Node *node, const QString &fileName)
+{
+ QFile *outFile = openSubPageFile(node, fileName);
+ writer = new QXmlStreamWriter(outFile);
+ writer->setAutoFormatting(false); // We need a precise handling of line feeds.
+
+ writer->writeStartDocument();
+ newLine();
+ writer->writeNamespace(dbNamespace, "db");
+ writer->writeNamespace(xlinkNamespace, "xlink");
+ writer->writeStartElement(dbNamespace, "article");
+ writer->writeAttribute("version", "5.2");
+ if (!naturalLanguage.isEmpty())
+ writer->writeAttribute("xml:lang", naturalLanguage);
+ newLine();
+
+ // Empty the section stack for the new document.
+ sectionLevels.resize(0);
+
+ return writer;
+}
+
+QXmlStreamWriter *DocBookGenerator::startDocument(const Node *node)
+{
+ QString fileName = Generator::fileName(node, fileExtension());
+ return startGenericDocument(node, fileName);
+}
+
+QXmlStreamWriter *DocBookGenerator::startDocument(const ExampleNode *en, const QString &file)
+{
+ QString fileName = linkForExampleFile(file, en);
+ return startGenericDocument(en, fileName);
+}
+
+void DocBookGenerator::endDocument()
+{
+ writer->writeEndElement(); // article
+ writer->writeEndDocument();
+ writer->device()->close();
+ delete writer;
+ writer = nullptr;
+}
+
+/*!
+ Generate a reference page for the C++ class, namespace, or
+ header file documented in \a node.
+ */
+void DocBookGenerator::generateCppReferencePage(Node *node)
+{
+ // Based on HtmlGenerator::generateCppReferencePage.
+ Q_ASSERT(node->isAggregate());
+ const auto aggregate = static_cast<const Aggregate *>(node);
+
+ QString title;
+ QString rawTitle;
+ QString fullTitle;
+ const NamespaceNode *ns = nullptr;
+ if (aggregate->isNamespace()) {
+ rawTitle = aggregate->plainName();
+ fullTitle = aggregate->plainFullName();
+ title = rawTitle + " Namespace";
+ ns = static_cast<const NamespaceNode *>(aggregate);
+ } else if (aggregate->isClass()) {
+ rawTitle = aggregate->plainName();
+ QString templateDecl = node->templateDecl();
+ if (!templateDecl.isEmpty())
+ fullTitle = QString("%1 %2 ").arg(templateDecl, aggregate->typeWord(false));
+ fullTitle += aggregate->plainFullName();
+ title = rawTitle + QLatin1Char(' ') + aggregate->typeWord(true);
+ }
+
+ QString subtitleText;
+ if (rawTitle != fullTitle)
+ subtitleText = fullTitle;
+
+ // Start producing the DocBook file.
+ writer = startDocument(node);
+
+ // Info container.
+ generateHeader(title, subtitleText, aggregate);
+
+ generateRequisites(aggregate);
+ generateStatus(aggregate);
+
+ // Element synopsis.
+ generateDocBookSynopsis(node);
+
+ // Actual content.
+ if (!aggregate->doc().isEmpty()) {
+ startSection(registerRef("details"), "Detailed Description");
+
+ generateBody(aggregate);
+ generateAlsoList(aggregate);
+ generateMaintainerList(aggregate);
+
+ endSection();
+ }
+
+ Sections sections(const_cast<Aggregate *>(aggregate));
+ SectionVector *sectionVector =
+ ns ? &sections.stdDetailsSections() : &sections.stdCppClassDetailsSections();
+ SectionVector::ConstIterator section = sectionVector->constBegin();
+ while (section != sectionVector->constEnd()) {
+ bool headerGenerated = false;
+ NodeVector::ConstIterator member = section->members().constBegin();
+ while (member != section->members().constEnd()) {
+ if ((*member)->access() == Node::Private) { // ### check necessary?
+ ++member;
+ continue;
+ }
+
+ if (!headerGenerated) {
+ // Equivalent to h2
+ startSection(registerRef(section->title().toLower()), section->title());
+ headerGenerated = true;
+ }
+
+ if ((*member)->nodeType() != Node::Class) {
+ // This function starts its own section.
+ generateDetailedMember(*member, aggregate);
+ } else {
+ startSectionBegin();
+ writer->writeCharacters("class ");
+ generateFullName(*member, aggregate);
+ startSectionEnd();
+ generateBrief(*member);
+ endSection();
+ }
+
+ ++member;
+ }
+
+ if (headerGenerated)
+ endSection();
+ ++section;
+ }
+
+ generateObsoleteMembers(sections);
+
+ endDocument();
+}
+
+void DocBookGenerator::generateSynopsisInfo(const QString &key, const QString &value)
+{
+ writer->writeStartElement(dbNamespace, "synopsisinfo");
+ writer->writeAttribute(dbNamespace, "role", key);
+ writer->writeCharacters(value);
+ writer->writeEndElement(); // synopsisinfo
+ newLine();
+}
+
+void DocBookGenerator::generateModifier(const QString &value)
+{
+ writer->writeTextElement(dbNamespace, "modifier", value);
+ newLine();
+}
+
+/*!
+ Generate the metadata for the given \a node in DocBook.
+ */
+void DocBookGenerator::generateDocBookSynopsis(const Node *node)
+{
+ if (!node)
+ return;
+
+ // From Generator::generateStatus, HtmlGenerator::generateRequisites,
+ // Generator::generateThreadSafeness, QDocIndexFiles::generateIndexSection.
+
+ // This function is the only place where DocBook extensions are used.
+ if (config->getBool(CONFIG_DOCBOOKEXTENSIONS))
+ return;
+
+ // Nothing to export in some cases.
+ if (node->isGroup() || node->isGroup() || node->isPropertyGroup() || node->isModule()
+ || node->isJsModule() || node->isQmlModule() || node->isPageNode())
+ return;
+
+ // Cast the node to several subtypes (null pointer if the node is not of the required type).
+ const Aggregate *aggregate =
+ node->isAggregate() ? static_cast<const Aggregate *>(node) : nullptr;
+ const ClassNode *classNode = node->isClass() ? static_cast<const ClassNode *>(node) : nullptr;
+ const FunctionNode *functionNode =
+ node->isFunction() ? static_cast<const FunctionNode *>(node) : nullptr;
+ const PropertyNode *propertyNode =
+ node->isProperty() ? static_cast<const PropertyNode *>(node) : nullptr;
+ const VariableNode *variableNode =
+ node->isVariable() ? static_cast<const VariableNode *>(node) : nullptr;
+ const EnumNode *enumNode = node->isEnumType() ? static_cast<const EnumNode *>(node) : nullptr;
+ const QmlPropertyNode *qpn =
+ node->isQmlProperty() ? static_cast<const QmlPropertyNode *>(node) : nullptr;
+ const QmlTypeNode *qcn = node->isQmlType() ? static_cast<const QmlTypeNode *>(node) : nullptr;
+ // Typedefs are ignored, as they correspond to enums.
+ // Groups and modules are ignored.
+ // Documents are ignored, they have no interesting metadata.
+
+ // Start the synopsis tag.
+ QString synopsisTag = nodeToSynopsisTag(node);
+ writer->writeStartElement(dbNamespace, synopsisTag);
+ newLine();
+
+ // Name and basic properties of each tag (like types and parameters).
+ if (node->isClass()) {
+ writer->writeStartElement(dbNamespace, "ooclass");
+ writer->writeTextElement(dbNamespace, "classname", node->plainName());
+ writer->writeEndElement(); // ooclass
+ newLine();
+ } else if (node->isNamespace()) {
+ writer->writeTextElement(dbNamespace, "namespacename", node->plainName());
+ newLine();
+ } else if (node->isQmlType()) {
+ writer->writeStartElement(dbNamespace, "ooclass");
+ writer->writeTextElement(dbNamespace, "classname", node->plainName());
+ writer->writeEndElement(); // ooclass
+ newLine();
+ if (!qcn->groupNames().isEmpty())
+ writer->writeAttribute("groups", qcn->groupNames().join(QLatin1Char(',')));
+ } else if (node->isProperty()) {
+ writer->writeTextElement(dbNamespace, "modifier", "(Qt property)");
+ newLine();
+ writer->writeTextElement(dbNamespace, "type", propertyNode->dataType());
+ newLine();
+ writer->writeTextElement(dbNamespace, "varname", node->plainName());
+ newLine();
+ } else if (node->isVariable()) {
+ if (variableNode->isStatic()) {
+ writer->writeTextElement(dbNamespace, "modifier", "static");
+ newLine();
+ }
+ writer->writeTextElement(dbNamespace, "type", variableNode->dataType());
+ newLine();
+ writer->writeTextElement(dbNamespace, "varname", node->plainName());
+ newLine();
+ } else if (node->isEnumType()) {
+ writer->writeTextElement(dbNamespace, "enumname", node->plainName());
+ newLine();
+ } else if (node->isQmlProperty()) {
+ QString name = node->name();
+ if (qpn->isAttached())
+ name.prepend(qpn->element() + QLatin1Char('.'));
+
+ writer->writeTextElement(dbNamespace, "type", qpn->dataType());
+ newLine();
+ writer->writeTextElement(dbNamespace, "varname", name);
+ newLine();
+
+ if (qpn->isAttached()) {
+ writer->writeTextElement(dbNamespace, "modifier", "attached");
+ newLine();
+ }
+ if ((const_cast<QmlPropertyNode *>(qpn))->isWritable()) {
+ writer->writeTextElement(dbNamespace, "modifier", "writable");
+ newLine();
+ }
+
+ if (qpn->isReadOnly()) {
+ generateModifier("[read-only]");
+ newLine();
+ }
+ if (qpn->isDefault()) {
+ generateModifier("[default]");
+ newLine();
+ }
+ } else if (node->isFunction()) {
+ if (functionNode->virtualness() != "non")
+ generateModifier("virtual");
+ if (functionNode->isConst())
+ generateModifier("const");
+ if (functionNode->isStatic())
+ generateModifier("static");
+
+ if (!functionNode->isMacro()) {
+ if (functionNode->returnType() == "void")
+ writer->writeEmptyElement(dbNamespace, "void");
+ else
+ writer->writeTextElement(dbNamespace, "type", functionNode->returnType());
+ newLine();
+ }
+ // Remove two characters from the plain name to only get the name
+ // of the method without parentheses.
+ writer->writeTextElement(dbNamespace, "methodname", node->plainName().chopped(2));
+ newLine();
+
+ if (functionNode->isOverload())
+ generateModifier("overload");
+ if (functionNode->isDefault())
+ generateModifier("default");
+ if (functionNode->isFinal())
+ generateModifier("final");
+ if (functionNode->isOverride())
+ generateModifier("override");
+
+ if (!functionNode->isMacro() && functionNode->parameters().isEmpty()) {
+ writer->writeEmptyElement(dbNamespace, "void");
+ newLine();
+ }
+
+ const Parameters &lp = functionNode->parameters();
+ for (int i = 0; i < lp.count(); ++i) {
+ const Parameter &parameter = lp.at(i);
+ writer->writeStartElement(dbNamespace, "methodparam");
+ newLine();
+ writer->writeTextElement(dbNamespace, "type", parameter.type());
+ newLine();
+ writer->writeTextElement(dbNamespace, "parameter", parameter.name());
+ newLine();
+ if (!parameter.defaultValue().isEmpty()) {
+ writer->writeTextElement(dbNamespace, "initializer", parameter.defaultValue());
+ newLine();
+ }
+ writer->writeEndElement(); // methodparam
+ newLine();
+ }
+
+ generateSynopsisInfo("meta", functionNode->metanessString());
+
+ if (functionNode->isOverload())
+ generateSynopsisInfo("overload-number",
+ QString::number(functionNode->overloadNumber()));
+
+ if (functionNode->isRef())
+ generateSynopsisInfo("refness", QString::number(1));
+ else if (functionNode->isRefRef())
+ generateSynopsisInfo("refness", QString::number(2));
+
+ if (functionNode->hasAssociatedProperties()) {
+ QStringList associatedProperties;
+ const NodeList &nodes = functionNode->associatedProperties();
+ for (const Node *n : nodes) {
+ const auto pn = static_cast<const PropertyNode *>(n);
+ associatedProperties << pn->name();
+ }
+ associatedProperties.sort();
+ generateSynopsisInfo("associated-property",
+ associatedProperties.join(QLatin1Char(',')));
+ }
+
+ QString signature = functionNode->signature(false, false);
+ // 'const' is already part of FunctionNode::signature()
+ if (functionNode->isFinal())
+ signature += " final";
+ if (functionNode->isOverride())
+ signature += " override";
+ if (functionNode->isPureVirtual())
+ signature += " = 0";
+ else if (functionNode->isDefault())
+ signature += " = default";
+ generateSynopsisInfo("signature", signature);
+ } else {
+ node->doc().location().warning(tr("Unexpected node type in generateDocBookSynopsis: %1")
+ .arg(node->nodeTypeString()));
+ newLine();
+ }
+
+ // Accessibility status.
+ if (!node->isPageNode() && !node->isCollectionNode()) {
+ switch (node->access()) {
+ case Node::Public:
+ generateSynopsisInfo("access", "public");
+ break;
+ case Node::Protected:
+ generateSynopsisInfo("access", "protected");
+ break;
+ case Node::Private:
+ generateSynopsisInfo("access", "private");
+ break;
+ default:
+ break;
+ }
+ if (node->isAbstract())
+ generateSynopsisInfo("abstract", "true");
+ }
+
+ // Status.
+ switch (node->status()) {
+ case Node::Active:
+ generateSynopsisInfo("status", "active");
+ break;
+ case Node::Preliminary:
+ generateSynopsisInfo("status", "preliminary");
+ break;
+ case Node::Deprecated:
+ generateSynopsisInfo("status", "deprecated");
+ break;
+ case Node::Obsolete:
+ generateSynopsisInfo("status", "obsolete");
+ break;
+ case Node::Internal:
+ generateSynopsisInfo("status", "internal");
+ break;
+ default:
+ generateSynopsisInfo("status", "main");
+ break;
+ }
+
+ // C++ classes and name spaces.
+ if (aggregate) {
+ // Includes.
+ if (!aggregate->includeFiles().isEmpty()) {
+ for (const QString &include : aggregate->includeFiles())
+ generateSynopsisInfo("headers", include);
+ }
+
+ // Since and project.
+ if (!aggregate->since().isEmpty())
+ generateSynopsisInfo("since", formatSince(aggregate));
+
+ if (aggregate->nodeType() == Node::Class || aggregate->nodeType() == Node::Namespace) {
+ // QT variable.
+ if (!aggregate->physicalModuleName().isEmpty()) {
+ const CollectionNode *cn =
+ qdb_->getCollectionNode(aggregate->physicalModuleName(), Node::Module);
+ if (cn && !cn->qtVariable().isEmpty())
+ generateSynopsisInfo("qmake", "QT += " + cn->qtVariable());
+ }
+ }
+
+ if (aggregate->nodeType() == Node::Class) {
+ // Instantiated by.
+ auto *classe = const_cast<ClassNode *>(static_cast<const ClassNode *>(aggregate));
+ if (classe->qmlElement() != nullptr && classe->status() != Node::Internal) {
+ const Node *otherNode = nullptr;
+ Atom a = Atom(Atom::LinkNode, CodeMarker::stringForNode(classe->qmlElement()));
+ QString link = getAutoLink(&a, aggregate, &otherNode);
+
+ writer->writeStartElement(dbNamespace, "synopsisinfo");
+ writer->writeAttribute(dbNamespace, "role", "instantiatedBy");
+ generateSimpleLink(link, classe->qmlElement()->name());
+ writer->writeEndElement(); // synopsisinfo
+ newLine();
+ }
+
+ // Inherits.
+ QVector<RelatedClass>::ConstIterator r;
+ if (!classe->baseClasses().isEmpty()) {
+ writer->writeStartElement(dbNamespace, "synopsisinfo");
+ writer->writeAttribute(dbNamespace, "role", "inherits");
+
+ r = classe->baseClasses().constBegin();
+ int index = 0;
+ while (r != classe->baseClasses().constEnd()) {
+ if ((*r).node_) {
+ generateFullName((*r).node_, classe);
+
+ if ((*r).access_ == Node::Protected) {
+ writer->writeCharacters(" (protected)");
+ } else if ((*r).access_ == Node::Private) {
+ writer->writeCharacters(" (private)");
+ }
+ writer->writeCharacters(comma(index++, classe->baseClasses().count()));
+ }
+ ++r;
+ }
+
+ writer->writeEndElement(); // synopsisinfo
+ newLine();
+ }
+
+ // Inherited by.
+ if (!classe->derivedClasses().isEmpty()) {
+ writer->writeStartElement(dbNamespace, "synopsisinfo");
+ writer->writeAttribute(dbNamespace, "role", "inheritedBy");
+ generateSortedNames(classe, classe->derivedClasses());
+ writer->writeEndElement(); // synopsisinfo
+ newLine();
+ }
+ }
+ }
+
+ // QML types.
+ if (qcn) {
+ // Module name and version (i.e. import).
+ QString logicalModuleVersion;
+ const CollectionNode *collection =
+ qdb_->getCollectionNode(qcn->logicalModuleName(), qcn->nodeType());
+ if (collection)
+ logicalModuleVersion = collection->logicalModuleVersion();
+ else
+ logicalModuleVersion = qcn->logicalModuleVersion();
+
+ generateSynopsisInfo("import",
+ "import " + qcn->logicalModuleName() + QLatin1Char(' ')
+ + logicalModuleVersion);
+
+ // Since and project.
+ if (!qcn->since().isEmpty())
+ generateSynopsisInfo("since", formatSince(qcn));
+
+ // Inherited by.
+ NodeList subs;
+ QmlTypeNode::subclasses(qcn, subs);
+ if (!subs.isEmpty()) {
+ writer->writeTextElement(dbNamespace, "synopsisinfo");
+ writer->writeAttribute(dbNamespace, "role", "inheritedBy");
+ generateSortedQmlNames(qcn, subs);
+ writer->writeEndElement(); // synopsisinfo
+ newLine();
+ }
+
+ // Inherits.
+ QmlTypeNode *base = qcn->qmlBaseNode();
+ while (base && base->isInternal())
+ base = base->qmlBaseNode();
+ if (base) {
+ const Node *otherNode = nullptr;
+ Atom a = Atom(Atom::LinkNode, CodeMarker::stringForNode(base));
+ QString link = getAutoLink(&a, base, &otherNode);
+
+ writer->writeTextElement(dbNamespace, "synopsisinfo");
+ writer->writeAttribute(dbNamespace, "role", "inherits");
+ generateSimpleLink(link, base->name());
+ writer->writeEndElement(); // synopsisinfo
+ newLine();
+ }
+
+ // Instantiates.
+ ClassNode *cn = (const_cast<QmlTypeNode *>(qcn))->classNode();
+ if (cn && (cn->status() != Node::Internal)) {
+ const Node *otherNode = nullptr;
+ Atom a = Atom(Atom::LinkNode, CodeMarker::stringForNode(qcn));
+ QString link = getAutoLink(&a, cn, &otherNode);
+
+ writer->writeTextElement(dbNamespace, "synopsisinfo");
+ writer->writeAttribute(dbNamespace, "role", "instantiates");
+ generateSimpleLink(link, cn->name());
+ writer->writeEndElement(); // synopsisinfo
+ newLine();
+ }
+ }
+
+ // Thread safeness.
+ switch (node->threadSafeness()) {
+ case Node::UnspecifiedSafeness:
+ generateSynopsisInfo("threadsafeness", "unspecified");
+ break;
+ case Node::NonReentrant:
+ generateSynopsisInfo("threadsafeness", "non-reentrant");
+ break;
+ case Node::Reentrant:
+ generateSynopsisInfo("threadsafeness", "reentrant");
+ break;
+ case Node::ThreadSafe:
+ generateSynopsisInfo("threadsafeness", "thread safe");
+ break;
+ default:
+ generateSynopsisInfo("threadsafeness", "unspecified");
+ break;
+ }
+
+ // Module.
+ if (!node->physicalModuleName().isEmpty())
+ generateSynopsisInfo("module", node->physicalModuleName());
+
+ // Group.
+ if (classNode && !classNode->groupNames().isEmpty()) {
+ generateSynopsisInfo("groups", classNode->groupNames().join(QLatin1Char(',')));
+ } else if (qcn && !qcn->groupNames().isEmpty()) {
+ generateSynopsisInfo("groups", qcn->groupNames().join(QLatin1Char(',')));
+ }
+
+ // Properties.
+ if (propertyNode) {
+ for (const Node *fnNode : propertyNode->getters()) {
+ if (fnNode) {
+ const auto funcNode = static_cast<const FunctionNode *>(fnNode);
+ generateSynopsisInfo("getter", funcNode->name());
+ }
+ }
+ for (const Node *fnNode : propertyNode->setters()) {
+ if (fnNode) {
+ const auto funcNode = static_cast<const FunctionNode *>(fnNode);
+ generateSynopsisInfo("setter", funcNode->name());
+ }
+ }
+ for (const Node *fnNode : propertyNode->resetters()) {
+ if (fnNode) {
+ const auto funcNode = static_cast<const FunctionNode *>(fnNode);
+ generateSynopsisInfo("resetter", funcNode->name());
+ }
+ }
+ for (const Node *fnNode : propertyNode->notifiers()) {
+ if (fnNode) {
+ const auto funcNode = static_cast<const FunctionNode *>(fnNode);
+ generateSynopsisInfo("notifier", funcNode->name());
+ }
+ }
+ }
+
+ // Enums and typedefs.
+ if (enumNode) {
+ for (const EnumItem &item : enumNode->items()) {
+ writer->writeStartElement(dbNamespace, "enumitem");
+ newLine();
+ writer->writeAttribute(dbNamespace, "enumidentifier", item.name());
+ newLine();
+ writer->writeAttribute(dbNamespace, "enumvalue", item.value());
+ newLine();
+ writer->writeEndElement(); // enumitem
+ newLine();
+ }
+ }
+
+ writer->writeEndElement(); // nodeToSynopsisTag (like classsynopsis)
+ newLine();
+
+ // The typedef associated to this enum.
+ if (enumNode && enumNode->flagsType()) {
+ writer->writeStartElement(dbNamespace, "typedefsynopsis");
+ newLine();
+
+ writer->writeTextElement(dbNamespace, "typedefname",
+ enumNode->flagsType()->fullDocumentName());
+
+ writer->writeEndElement(); // typedefsynopsis
+ newLine();
+ }
+}
+
+QString taggedNode(const Node *node)
+{
+ // From CodeMarker::taggedNode, but without the tag part (i.e. only the QML specific case
+ // remaining).
+ // TODO: find a better name for this.
+ if (node->nodeType() == Node::QmlType && node->name().startsWith(QLatin1String("QML:")))
+ return node->name().mid(4);
+ return node->name();
+}
+
+/*!
+ Parses a string with method/variable name and (return) type
+ to include type tags.
+ */
+void DocBookGenerator::typified(const QString &string, const Node *relative, bool trailingSpace,
+ bool generateType)
+{
+ // Adapted from CodeMarker::typified and HtmlGenerator::highlightedCode.
+ // Note: CppCodeMarker::markedUpIncludes is not needed for DocBook, as this part is natively
+ // generated as DocBook. Hence, there is no need to reimplement <@headerfile> from
+ // HtmlGenerator::highlightedCode.
+ 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 (generateType && isProbablyType) {
+ // Flush the current buffer.
+ writer->writeCharacters(result);
+ result.truncate(0);
+
+ // Add the link, logic from HtmlGenerator::highlightedCode.
+ const Node *n = qdb_->findTypeNode(pendingWord, relative, Node::DontCare);
+ QString href;
+ if (!(n && (n->isQmlBasicType() || n->isJsBasicType()))
+ || (relative
+ && (relative->genus() == n->genus() || Node::DontCare == n->genus()))) {
+ href = linkForNode(n, relative);
+ }
+
+ writer->writeStartElement(dbNamespace, "type");
+ if (href.isEmpty())
+ writer->writeCharacters(pendingWord);
+ else
+ generateSimpleLink(href, pendingWord);
+ writer->writeEndElement(); // type
+ } else {
+ result += pendingWord;
+ }
+ }
+ pendingWord.clear();
+
+ switch (ch.unicode()) {
+ case '\0':
+ break;
+ // This only breaks out of the switch, not the loop. This means that the loop
+ // deliberately overshoots by one character.
+ case '&':
+ result += QLatin1String("&amp;");
+ break;
+ case '<':
+ result += QLatin1String("&lt;");
+ break;
+ case '>':
+ result += QLatin1String("&gt;");
+ break;
+ case '\'':
+ result += QLatin1String("&apos;");
+ break;
+ case '"':
+ result += QLatin1String("&quot;");
+ break;
+ default:
+ result += ch;
+ }
+ }
+ }
+
+ if (trailingSpace && string.size()) {
+ if (!string.endsWith(QLatin1Char('*')) && !string.endsWith(QLatin1Char('&')))
+ result += QLatin1Char(' ');
+ }
+
+ writer->writeCharacters(result);
+}
+
+void DocBookGenerator::generateSynopsisName(const Node *node, const Node *relative,
+ bool generateNameLink)
+{
+ // Implements the rewriting of <@link> from HtmlGenerator::highlightedCode, only due to calls to
+ // CodeMarker::linkTag in CppCodeMarker::markedUpSynopsis.
+ QString name = taggedNode(node);
+
+ if (!generateNameLink) {
+ writer->writeCharacters(name);
+ return;
+ }
+
+ writer->writeStartElement(dbNamespace, "emphasis");
+ writer->writeAttribute("role", "bold");
+ generateSimpleLink(linkForNode(node, relative), name);
+ writer->writeEndElement(); // emphasis
+}
+
+void DocBookGenerator::generateParameter(const Parameter &parameter, const Node *relative,
+ bool generateExtra, bool generateType)
+{
+ const QString &pname = parameter.name();
+ const QString &ptype = parameter.type();
+ QString paramName;
+ if (!pname.isEmpty()) {
+ typified(ptype, relative, true, generateType);
+ paramName = pname;
+ } else {
+ paramName = ptype;
+ }
+ if (generateExtra || pname.isEmpty()) {
+ // Look for the _ character in the member name followed by a number (or n):
+ // this is intended to be rendered as a subscript.
+ QRegExp sub("([a-z]+)_([0-9]+|n)");
+
+ writer->writeStartElement(dbNamespace, "emphasis");
+ if (sub.indexIn(paramName) != -1) {
+ writer->writeCharacters(sub.cap(0));
+ writer->writeStartElement(dbNamespace, "sub");
+ writer->writeCharacters(sub.cap(1));
+ writer->writeEndElement(); // sub
+ } else {
+ writer->writeCharacters(paramName);
+ }
+ writer->writeEndElement(); // emphasis
+ }
+
+ const QString &pvalue = parameter.defaultValue();
+ if (generateExtra && !pvalue.isEmpty())
+ writer->writeCharacters(" = " + pvalue);
+}
+
+void DocBookGenerator::generateSynopsis(const Node *node, const Node *relative,
+ Section::Style style)
+{
+ // From HtmlGenerator::generateSynopsis (conditions written as booleans).
+ const bool generateExtra = style != Section::AllMembers;
+ const bool generateType = style != Section::Details;
+ const bool generateNameLink = style != Section::Details;
+
+ // From CppCodeMarker::markedUpSynopsis, reversed the generation of "extra" and "synopsis".
+ const int MaxEnumValues = 6;
+
+ // First generate the extra part if needed (condition from HtmlGenerator::generateSynopsis).
+ if (generateExtra) {
+ if (node->nodeType() == Node::Function) {
+ const auto func = static_cast<const FunctionNode *>(node);
+ if (style != Section::Summary && style != Section::Accessors) {
+ QStringList bracketed;
+ if (func->isStatic()) {
+ bracketed += "static";
+ } else if (!func->isNonvirtual()) {
+ if (func->isFinal())
+ bracketed += "final";
+ if (func->isOverride())
+ bracketed += "override";
+ if (func->isPureVirtual())
+ bracketed += "pure";
+ bracketed += "virtual";
+ }
+
+ if (func->access() == Node::Protected)
+ bracketed += "protected";
+ else if (func->access() == Node::Private)
+ bracketed += "private";
+
+ if (func->isSignal())
+ bracketed += "signal";
+ else if (func->isSlot())
+ bracketed += "slot";
+
+ if (!bracketed.isEmpty())
+ writer->writeCharacters(QLatin1Char('[') + bracketed.join(' ')
+ + QStringLiteral("] "));
+ }
+ }
+
+ if (style == Section::Summary) {
+ QString extra;
+ if (node->isPreliminary())
+ extra = "(preliminary) ";
+ else if (node->isDeprecated())
+ extra = "(deprecated) ";
+ else if (node->isObsolete())
+ extra = "(obsolete) ";
+
+ if (!extra.isEmpty())
+ writer->writeCharacters(extra);
+ }
+ }
+
+ // Then generate the synopsis.
+ if (style == Section::Details) {
+ if (!node->isRelatedNonmember() && !node->isProxyNode() && !node->parent()->name().isEmpty()
+ && !node->parent()->isHeader() && !node->isProperty() && !node->isQmlNode()
+ && !node->isJsNode()) {
+ writer->writeCharacters(taggedNode(node->parent()) + "::");
+ }
+ }
+
+ switch (node->nodeType()) {
+ case Node::Namespace:
+ writer->writeCharacters("namespace ");
+ generateSynopsisName(node, relative, generateNameLink);
+ break;
+ case Node::Class:
+ writer->writeCharacters("class ");
+ generateSynopsisName(node, relative, generateNameLink);
+ break;
+ case Node::Function: {
+ const auto func = (const FunctionNode *)node;
+
+ // First, the part coming before the name.
+ if (style == Section::Summary || style == Section::Accessors) {
+ if (!func->isNonvirtual())
+ writer->writeCharacters(QStringLiteral("virtual "));
+ }
+
+ // Name and parameters.
+ if (style != Section::AllMembers && !func->returnType().isEmpty())
+ typified(func->returnType(), relative, true, generateType);
+ generateSynopsisName(node, relative, generateNameLink);
+
+ if (!func->isMacroWithoutParams()) {
+ writer->writeCharacters(QStringLiteral("("));
+ if (!func->parameters().isEmpty()) {
+ const Parameters &parameters = func->parameters();
+ for (int i = 0; i < parameters.count(); i++) {
+ if (i > 0)
+ writer->writeCharacters(QStringLiteral(", "));
+ generateParameter(parameters.at(i), relative, generateExtra, generateType);
+ }
+ }
+ writer->writeCharacters(QStringLiteral(")"));
+ }
+ if (func->isConst())
+ writer->writeCharacters(QStringLiteral(" const"));
+
+ if (style == Section::Summary || style == Section::Accessors) {
+ // virtual is prepended, if needed.
+ QString synopsis;
+ if (func->isFinal())
+ synopsis += QStringLiteral(" final");
+ if (func->isOverride())
+ synopsis += QStringLiteral(" override");
+ if (func->isPureVirtual())
+ synopsis += QStringLiteral(" = 0");
+ if (func->isRef())
+ synopsis += QStringLiteral(" &");
+ else if (func->isRefRef())
+ synopsis += QStringLiteral(" &&");
+ writer->writeCharacters(synopsis);
+ } else if (style == Section::AllMembers) {
+ if (!func->returnType().isEmpty() && func->returnType() != "void") {
+ writer->writeCharacters(QStringLiteral(" : "));
+ typified(func->returnType(), relative, false, generateType);
+ }
+ } else {
+ QString synopsis;
+ if (func->isRef())
+ synopsis += QStringLiteral(" &");
+ else if (func->isRefRef())
+ synopsis += QStringLiteral(" &&");
+ writer->writeCharacters(synopsis);
+ }
+ } break;
+ case Node::Enum: {
+ const auto enume = static_cast<const EnumNode *>(node);
+ writer->writeCharacters(QStringLiteral("enum "));
+ generateSynopsisName(node, relative, generateNameLink);
+
+ QString synopsis;
+ if (style == Section::Summary) {
+ synopsis += " { ";
+
+ QStringList documentedItems = enume->doc().enumItemNames();
+ if (documentedItems.isEmpty()) {
+ const auto &enumItems = enume->items();
+ for (const auto &item : enumItems)
+ documentedItems << item.name();
+ }
+ const QStringList omitItems = enume->doc().omitEnumItemNames();
+ for (const auto &item : omitItems)
+ documentedItems.removeAll(item);
+
+ if (documentedItems.size() > MaxEnumValues) {
+ // Take the last element and keep it safe, then elide the surplus.
+ const QString last = documentedItems.last();
+ documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
+ documentedItems += "&#x2026;"; // Ellipsis: in HTML, &hellip;.
+ documentedItems += last;
+ }
+ synopsis += documentedItems.join(QLatin1String(", "));
+
+ if (!documentedItems.isEmpty())
+ synopsis += QLatin1Char(' ');
+ synopsis += QLatin1Char('}');
+ }
+ writer->writeCharacters(synopsis);
+ } break;
+ case Node::Typedef: {
+ const auto typedeff = static_cast<const TypedefNode *>(node);
+ if (typedeff->associatedEnum())
+ writer->writeCharacters("flags ");
+ else
+ writer->writeCharacters("typedef ");
+ generateSynopsisName(node, relative, generateNameLink);
+ } break;
+ case Node::Property: {
+ const auto property = static_cast<const PropertyNode *>(node);
+ generateSynopsisName(node, relative, generateNameLink);
+ writer->writeCharacters(" : ");
+ typified(property->qualifiedDataType(), relative, false, generateType);
+ } break;
+ case Node::Variable: {
+ const auto variable = static_cast<const VariableNode *>(node);
+ if (style == Section::AllMembers) {
+ generateSynopsisName(node, relative, generateNameLink);
+ writer->writeCharacters(" : ");
+ typified(variable->dataType(), relative, false, generateType);
+ } else {
+ typified(variable->leftType(), relative, false, generateType);
+ writer->writeCharacters(" ");
+ generateSynopsisName(node, relative, generateNameLink);
+ writer->writeCharacters(variable->rightType());
+ }
+ } break;
+ default:
+ generateSynopsisName(node, relative, generateNameLink);
+ }
+}
+
+void DocBookGenerator::generateEnumValue(const QString &enumValue, const Node *relative)
+{
+ // From CppCodeMarker::markedUpEnumValue, simplifications from Generator::plainCode (removing
+ // <@op>). With respect to CppCodeMarker::markedUpEnumValue, the order of generation of parents
+ // must be reversed so that they are processed in the order
+ if (!relative->isEnumType()) {
+ writer->writeCharacters(enumValue);
+ return;
+ }
+
+ QVector<const Node *> parents;
+ const Node *node = relative->parent();
+ while (node->parent()) {
+ parents.prepend(node);
+ if (node->parent() == relative || node->parent()->name().isEmpty())
+ break;
+ node = node->parent();
+ }
+
+ writer->writeStartElement(dbNamespace, "code");
+ for (auto parent : parents) {
+ generateSynopsisName(parent, relative, true);
+ writer->writeCharacters("::");
+ }
+ writer->writeCharacters(enumValue);
+ writer->writeEndElement(); // code
+}
+
+/*!
+ If the node is an overloaded signal, and a node with an
+ example on how to connect to it
+
+ Someone didn't finish writing this comment, and I don't know what this
+ function is supposed to do, so I have not tried to complete the comment
+ yet.
+ */
+void DocBookGenerator::generateOverloadedSignal(const Node *node)
+{
+ // From Generator::generateOverloadedSignal.
+ QString code = getOverloadedSignalCode(node);
+ if (code.isEmpty())
+ return;
+
+ writer->writeStartElement(dbNamespace, "note");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("Signal ");
+ writer->writeTextElement(dbNamespace, "emphasis", node->name());
+ writer->writeCharacters(" is overloaded in this class. To connect to this "
+ "signal by using the function pointer syntax, Qt "
+ "provides a convenient helper for obtaining the "
+ "function pointer as shown in this example:");
+ writer->writeTextElement(dbNamespace, "code", code);
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // note
+ newLine();
+}
+
+/*!
+ Generates an addendum note of type \a type for \a node. \a marker
+ is unused in this generator.
+*/
+void DocBookGenerator::generateAddendum(const Node *node, Addendum type, CodeMarker *marker)
+{
+ Q_UNUSED(marker);
+ Q_ASSERT(node && !node->name().isEmpty());
+ writer->writeStartElement(dbNamespace, "note");
+ newLine();
+ switch (type) {
+ case Invokable:
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters(
+ "This function can be invoked via the meta-object system and from QML. See ");
+ generateSimpleLink(node->url(), "Q_INVOKABLE");
+ writer->writeCharacters(".");
+ writer->writeEndElement(); // para
+ newLine();
+ break;
+ case PrivateSignal:
+ writer->writeTextElement(dbNamespace, "para",
+ "This is a private signal. It can be used in signal connections but "
+ "cannot be emitted by the user.");
+ break;
+ case QmlSignalHandler:
+ {
+ QString handler(node->name());
+ handler[0] = handler[0].toTitleCase();
+ handler.prepend(QLatin1String("on"));
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("The corresponding handler is ");
+ writer->writeTextElement(dbNamespace, "code", handler);
+ writer->writeCharacters(".");
+ writer->writeEndElement(); // para
+ newLine();
+ break;
+ }
+ case AssociatedProperties:
+ {
+ if (!node->isFunction())
+ return;
+ const FunctionNode *fn = static_cast<const FunctionNode *>(node);
+ NodeList nodes = fn->associatedProperties();
+ if (nodes.isEmpty())
+ return;
+ std::sort(nodes.begin(), nodes.end(), Node::nodeNameLessThan);
+ for (const auto node : qAsConst(nodes)) {
+ QString msg;
+ const auto pn = static_cast<const PropertyNode *>(node);
+ switch (pn->role(fn)) {
+ case PropertyNode::Getter:
+ msg = QStringLiteral("Getter function");
+ break;
+ case PropertyNode::Setter:
+ msg = QStringLiteral("Setter function");
+ break;
+ case PropertyNode::Resetter:
+ msg = QStringLiteral("Resetter function");
+ break;
+ case PropertyNode::Notifier:
+ msg = QStringLiteral("Notifier signal");
+ break;
+ default:
+ continue;
+ }
+ writer->writeCharacters(msg + " for property ");
+ generateSimpleLink(linkForNode(pn, nullptr), pn->name());
+ writer->writeCharacters(". ");
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ writer->writeEndElement(); // note
+ newLine();
+}
+
+void DocBookGenerator::generateDetailedMember(const Node *node, const PageNode *relative)
+{
+ // From HtmlGenerator::generateDetailedMember.
+ writer->writeStartElement(dbNamespace, "section");
+ if (node->isSharedCommentNode()) {
+ const auto scn = reinterpret_cast<const SharedCommentNode *>(node);
+ const QVector<Node *> &collective = scn->collective();
+
+ bool firstFunction = true;
+ for (const Node *n : collective) {
+ if (n->isFunction()) {
+ QString nodeRef = refForNode(n);
+
+ if (firstFunction) {
+ writer->writeAttribute("xml:id", refForNode(collective.at(0)));
+ newLine();
+ writer->writeStartElement(dbNamespace, "title");
+ generateSynopsis(n, relative, Section::Details);
+ writer->writeEndElement(); // title
+ newLine();
+
+ firstFunction = false;
+ } else {
+ writer->writeStartElement(dbNamespace, "bridgehead");
+ writer->writeAttribute("renderas", "sect2");
+ writer->writeAttribute("xml:id", nodeRef);
+ generateSynopsis(n, relative, Section::Details);
+ writer->writeEndElement(); // bridgehead
+ newLine();
+ }
+ }
+ }
+ } else {
+ const EnumNode *etn;
+ QString nodeRef = refForNode(node);
+ if (node->isEnumType() && (etn = static_cast<const EnumNode *>(node))->flagsType()) {
+ writer->writeAttribute("xml:id", nodeRef);
+ newLine();
+ writer->writeStartElement(dbNamespace, "title");
+ generateSynopsis(etn, relative, Section::Details);
+ writer->writeEndElement(); // title
+ newLine();
+ writer->writeStartElement(dbNamespace, "bridgehead");
+ generateSynopsis(etn->flagsType(), relative, Section::Details);
+ writer->writeEndElement(); // bridgehead
+ newLine();
+ } else {
+ writer->writeAttribute("xml:id", nodeRef);
+ newLine();
+ writer->writeStartElement(dbNamespace, "title");
+ generateSynopsis(node, relative, Section::Details);
+ writer->writeEndElement(); // title
+ newLine();
+ }
+ }
+
+ generateDocBookSynopsis(node);
+
+ generateStatus(node);
+ generateBody(node);
+ generateOverloadedSignal(node);
+ generateThreadSafeness(node);
+ generateSince(node);
+
+ if (node->isProperty()) {
+ const auto property = static_cast<const PropertyNode *>(node);
+ Section section(Section::Accessors, Section::Active);
+
+ section.appendMembers(property->getters().toVector());
+ section.appendMembers(property->setters().toVector());
+ section.appendMembers(property->resetters().toVector());
+
+ if (!section.members().isEmpty()) {
+ writer->writeStartElement(dbNamespace, "para");
+ newLine();
+ writer->writeTextElement(dbNamespace, "emphasis", "Access functions:");
+ writer->writeAttribute("role", "bold");
+ newLine();
+ writer->writeEndElement(); // para
+ newLine();
+ generateSectionList(section, node);
+ }
+
+ Section notifiers(Section::Accessors, Section::Active);
+ notifiers.appendMembers(property->notifiers().toVector());
+
+ if (!notifiers.members().isEmpty()) {
+ writer->writeStartElement(dbNamespace, "para");
+ newLine();
+ writer->writeTextElement(dbNamespace, "emphasis", "Notifier signal:");
+ writer->writeAttribute("role", "bold");
+ newLine();
+ writer->writeEndElement(); // para
+ newLine();
+ generateSectionList(notifiers, node);
+ }
+ } else if (node->isEnumType()) {
+ const auto en = static_cast<const EnumNode *>(node);
+
+ if (qflagsHref_.isEmpty()) {
+ Node *qflags = qdb_->findClassNode(QStringList("QFlags"));
+ if (qflags)
+ qflagsHref_ = linkForNode(qflags, nullptr);
+ }
+
+ if (en->flagsType()) {
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("The " + en->flagsType()->name() + " type is a typedef for ");
+ generateSimpleLink(qflagsHref_, "QFlags");
+ writer->writeCharacters("&lt;" + en->name() + "&gt;. ");
+ writer->writeCharacters("It stores an OR combination of " + en->name() + "values.");
+ writer->writeEndElement(); // para
+ newLine();
+ }
+ }
+ generateAlsoList(node);
+ endSection(); // section
+}
+
+void DocBookGenerator::generateSectionList(const Section &section, const Node *relative,
+ Section::Status status)
+{
+ // From HtmlGenerator::generateSectionList, just generating a list (not tables).
+ const NodeVector &members =
+ (status == Section::Obsolete ? section.obsoleteMembers() : section.members());
+ if (!members.isEmpty()) {
+ bool hasPrivateSignals = false;
+ bool isInvokable = false;
+
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+
+ int i = 0;
+ NodeVector::ConstIterator m = members.constBegin();
+ while (m != members.constEnd()) {
+ if ((*m)->access() == Node::Private) {
+ ++m;
+ continue;
+ }
+
+ writer->writeStartElement(dbNamespace, "listitem");
+ newLine();
+ writer->writeStartElement(dbNamespace, "para");
+
+ // prefix no more needed.
+ generateSynopsis(*m, relative, section.style());
+ if ((*m)->isFunction()) {
+ const auto fn = static_cast<const FunctionNode *>(*m);
+ if (fn->isPrivateSignal())
+ hasPrivateSignals = true;
+ else if (fn->isInvokable())
+ isInvokable = true;
+ }
+
+ writer->writeEndElement(); // para
+ newLine();
+ writer->writeEndElement(); // listitem
+ newLine();
+
+ i++;
+ ++m;
+ }
+
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+
+ if (hasPrivateSignals)
+ generateAddendum(relative, Generator::PrivateSignal);
+ if (isInvokable)
+ generateAddendum(relative, Generator::Invokable);
+ }
+
+ if (status != Section::Obsolete && section.style() == Section::Summary
+ && !section.inheritedMembers().isEmpty()) {
+ writer->writeStartElement(dbNamespace, "itemizedlist");
+ newLine();
+
+ generateSectionInheritedList(section, relative);
+
+ writer->writeEndElement(); // itemizedlist
+ newLine();
+ }
+}
+
+void DocBookGenerator::generateSectionInheritedList(const Section &section, const Node *relative)
+{
+ // From HtmlGenerator::generateSectionInheritedList.
+ QVector<QPair<Aggregate *, int>>::ConstIterator p = section.inheritedMembers().constBegin();
+ while (p != section.inheritedMembers().constEnd()) {
+ writer->writeStartElement(dbNamespace, "listitem");
+ writer->writeCharacters(QString((*p).second) + " ");
+ if ((*p).second == 1)
+ writer->writeCharacters(section.singular());
+ else
+ writer->writeCharacters(section.plural());
+ writer->writeCharacters(" inherited from ");
+ generateSimpleLink(fileName((*p).first) + '#'
+ + Generator::cleanRef(section.title().toLower()),
+ (*p).first->plainFullName(relative));
+ ++p;
+ }
+}
+
+/*!
+ Generate the DocBook page for an entity that doesn't map
+ to any underlying parsable C++, QML, or Javascript element.
+ */
+void DocBookGenerator::generatePageNode(PageNode *pn)
+{
+ Q_ASSERT(writer == nullptr);
+ // From HtmlGenerator::generatePageNode, remove anything related to TOCs.
+ writer = startDocument(pn);
+
+ generateHeader(pn->fullTitle(), pn->subtitle(), pn);
+ generateBody(pn);
+ generateAlsoList(pn);
+ generateFooter();
+
+ endDocument();
+}
+
+/*!
+ Extract sections of markup text and output them.
+ */
+bool DocBookGenerator::generateQmlText(const Text &text, const Node *relative, CodeMarker *marker,
+ const QString &qmlName)
+{
+ Q_UNUSED(marker);
+ Q_UNUSED(qmlName);
+ // From Generator::generateQmlText.
+ const Atom *atom = text.firstAtom();
+ bool result = false;
+
+ if (atom != nullptr) {
+ initializeTextOutput();
+ while (atom) {
+ if (atom->type() != Atom::QmlText)
+ atom = atom->next();
+ else {
+ atom = atom->next();
+ while (atom && (atom->type() != Atom::EndQmlText)) {
+ int n = 1 + generateAtom(atom, relative);
+ while (n-- > 0)
+ atom = atom->next();
+ }
+ }
+ }
+ result = true;
+ }
+ return result;
+}
+
+/*!
+ Generate the DocBook page for a QML type. \qcn is the QML type.
+ */
+void DocBookGenerator::generateQmlTypePage(QmlTypeNode *qcn)
+{
+ // From HtmlGenerator::generateQmlTypePage.
+ // Start producing the DocBook file.
+ Q_ASSERT(writer == nullptr);
+ writer = startDocument(qcn);
+
+ Generator::setQmlTypeContext(qcn);
+ QString title = qcn->fullTitle();
+ if (qcn->isJsType())
+ title += " JavaScript Type";
+ else
+ title += " QML Type";
+
+ generateHeader(title, qcn->subtitle(), qcn);
+ generateQmlRequisites(qcn);
+
+ startSection(registerRef("details"), "Detailed Description");
+ generateBody(qcn);
+
+ ClassNode *cn = qcn->classNode();
+ if (cn)
+ generateQmlText(cn->doc().body(), cn);
+ generateAlsoList(qcn);
+
+ endSection();
+
+ Sections sections(qcn);
+ for (const auto &section : sections.stdQmlTypeDetailsSections()) {
+ if (!section.isEmpty()) {
+ startSection(registerRef(section.title().toLower()), section.title());
+
+ for (const auto &member : section.members())
+ generateDetailedQmlMember(member, qcn);
+
+ endSection();
+ }
+ }
+
+ generateObsoleteQmlMembers(sections);
+
+ generateFooter();
+ Generator::setQmlTypeContext(nullptr);
+
+ endDocument();
+}
+
+/*!
+ Generate the DocBook page for the QML basic type represented
+ by the QML basic type node \a qbtn.
+ */
+void DocBookGenerator::generateQmlBasicTypePage(QmlBasicTypeNode *qbtn)
+{
+ // From HtmlGenerator::generateQmlBasicTypePage.
+ // Start producing the DocBook file.
+ Q_ASSERT(writer == nullptr);
+ writer = startDocument(qbtn);
+
+ QString htmlTitle = qbtn->fullTitle();
+ if (qbtn->isJsType())
+ htmlTitle += " JavaScript Basic Type";
+ else
+ htmlTitle += " QML Basic Type";
+
+ Sections sections(qbtn);
+ generateHeader(htmlTitle, qbtn->subtitle(), qbtn);
+
+ startSection(registerRef("details"), "Detailed Description");
+
+ generateBody(qbtn);
+ generateAlsoList(qbtn);
+
+ endSection();
+
+ SectionVector::ConstIterator s = sections.stdQmlTypeDetailsSections().constBegin();
+ while (s != sections.stdQmlTypeDetailsSections().constEnd()) {
+ if (!s->isEmpty()) {
+ startSection(registerRef(s->title().toLower()), s->title());
+
+ NodeVector::ConstIterator m = s->members().constBegin();
+ while (m != s->members().constEnd()) {
+ generateDetailedQmlMember(*m, qbtn);
+ ++m;
+ }
+
+ endSection();
+ }
+ ++s;
+ }
+ generateFooter();
+
+ endDocument();
+}
+
+/*!
+ Outputs the DocBook detailed documentation for a section
+ on a QML element reference page.
+ */
+void DocBookGenerator::generateDetailedQmlMember(Node *node, const Aggregate *relative)
+{
+ // From HtmlGenerator::generateDetailedQmlMember, with elements from
+ // CppCodeMarker::markedUpQmlItem and HtmlGenerator::generateQmlItem.
+ std::function<QString(QmlPropertyNode *)> getQmlPropertyTitle = [&](QmlPropertyNode *n) {
+ if (!n->isReadOnlySet() && n->declarativeCppNode())
+ n->markReadOnly(!n->isWritable());
+
+ QString title;
+ if (!n->isWritable())
+ title += "[read-only] ";
+ if (n->isDefault())
+ title += "[default] ";
+
+ // Finalise generation of name, as per CppCodeMarker::markedUpQmlItem.
+ if (n->isAttached())
+ title += n->element() + QLatin1Char('.');
+ title += n->name() + " : " + n->dataType();
+
+ return title;
+ };
+
+ std::function<void(Node *)> generateQmlMethodTitle = [&](Node *node) {
+ generateSynopsis(node, relative, Section::Details);
+ };
+
+ bool generateEndSection = true;
+
+ if (node->isPropertyGroup()) {
+ const auto scn = static_cast<const SharedCommentNode *>(node);
+
+ QString heading;
+ if (!scn->name().isEmpty())
+ heading = scn->name() + " group";
+ else
+ heading = node->name();
+ startSection(refForNode(scn), heading);
+ // This last call creates a title for this section. In other words,
+ // titles are forbidden for the rest of the section.
+
+ const QVector<Node *> sharedNodes = scn->collective();
+ for (const auto &node : sharedNodes) {
+ if (node->isQmlProperty() || node->isJsProperty()) {
+ auto *qpn = static_cast<QmlPropertyNode *>(node);
+
+ writer->writeStartElement(dbNamespace, "bridgehead");
+ writer->writeAttribute("renderas", "sect2");
+ writer->writeAttribute("xml:id", refForNode(qpn));
+ writer->writeCharacters(getQmlPropertyTitle(qpn));
+ writer->writeEndElement(); // bridgehead
+ newLine();
+
+ generateDocBookSynopsis(qpn);
+ }
+ }
+ } else if (node->isQmlProperty() || node->isJsProperty()) {
+ auto qpn = static_cast<QmlPropertyNode *>(node);
+ startSection(refForNode(qpn), getQmlPropertyTitle(qpn));
+ generateDocBookSynopsis(qpn);
+ } else if (node->isSharedCommentNode()) {
+ const auto scn = reinterpret_cast<const SharedCommentNode *>(node);
+ const QVector<Node *> &sharedNodes = scn->collective();
+
+ // In the section, generate a title for the first node, then bridgeheads for
+ // the next ones.
+ int i = 0;
+ for (const auto m : sharedNodes) {
+ // Ignore this element if there is nothing to generate.
+ if (!node->isFunction(Node::QML) && !node->isFunction(Node::JS)
+ && !node->isQmlProperty() && !node->isJsProperty()) {
+ continue;
+ }
+
+ // Complete the section tag.
+ if (i == 0) {
+ writer->writeStartElement(dbNamespace, "section");
+ writer->writeAttribute("xml:id", refForNode(m));
+ newLine();
+ }
+
+ // Write the tag containing the title.
+ writer->writeStartElement(dbNamespace, (i == 0) ? "title" : "bridgehead");
+ if (i > 0)
+ writer->writeAttribute("renderas", "sect2");
+
+ // Write the title.
+ QString title;
+ if (node->isFunction(Node::QML) || node->isFunction(Node::JS))
+ generateQmlMethodTitle(node);
+ else if (node->isQmlProperty() || node->isJsProperty())
+ writer->writeCharacters(getQmlPropertyTitle(static_cast<QmlPropertyNode *>(node)));
+
+ // Complete the title and the synopsis.
+ generateDocBookSynopsis(m);
+ ++i;
+ }
+
+ if (i == 0)
+ generateEndSection = false;
+ } else { // assume the node is a method/signal handler
+ startSectionBegin(refForNode(node));
+ generateQmlMethodTitle(node);
+ startSectionEnd();
+ }
+
+ generateStatus(node);
+ generateBody(node);
+ generateThreadSafeness(node);
+ generateSince(node);
+ generateAlsoList(node);
+
+ if (generateEndSection)
+ endSection();
+}
+
+/*!
+ Recursive writing of DocBook files from the root \a node.
+ */
+void DocBookGenerator::generateDocumentation(Node *node)
+{
+ // Mainly from Generator::generateDocumentation, with parts from
+ // Generator::generateDocumentation and WebXMLGenerator::generateDocumentation.
+ // Don't generate nodes that are already processed, or if they're not
+ // supposed to generate output, ie. external, index or images nodes.
+ if (!node->url().isNull())
+ return;
+ if (node->isIndexNode())
+ return;
+ if (node->isInternal() && !showInternal_)
+ return;
+ if (node->isExternalPage())
+ return;
+
+ if (node->parent()) {
+ if (node->isCollectionNode()) {
+ /*
+ A collection node collects: groups, C++ modules,
+ QML modules or JavaScript modules. Testing for a
+ CollectionNode must be done before testing for a
+ TextPageNode because a CollectionNode is a PageNode
+ at this point.
+
+ Don't output an HTML page for the collection
+ node unless the \group, \module, \qmlmodule or
+ \jsmodule command was actually seen by qdoc in
+ the qdoc comment for the node.
+
+ A key prerequisite in this case is the call to
+ mergeCollections(cn). We must determine whether
+ this group, module, QML module, or JavaScript
+ module has members in other modules. We know at
+ this point that cn's members list contains only
+ members in the current module. Therefore, before
+ outputting the page for cn, we must search for
+ members of cn in the other modules and add them
+ to the members list.
+ */
+ auto cn = static_cast<CollectionNode *>(node);
+ if (cn->wasSeen()) {
+ qdb_->mergeCollections(cn);
+ generateCollectionNode(cn);
+ } else if (cn->isGenericCollection()) {
+ // Currently used only for the module's related orphans page
+ // but can be generalized for other kinds of collections if
+ // other use cases pop up.
+ generateGenericCollectionPage(cn);
+ }
+ } else if (node->isTextPageNode()) { // Pages.
+ generatePageNode(static_cast<PageNode *>(node));
+ } else if (node->isAggregate()) { // Aggregates.
+ if ((node->isClassNode() || node->isHeader() || node->isNamespace())
+ && node->docMustBeGenerated()) {
+ generateCppReferencePage(static_cast<Aggregate *>(node));
+ } else if (node->isQmlType() || node->isJsType()) {
+ generateQmlTypePage(static_cast<QmlTypeNode *>(node));
+ } else if (node->isQmlBasicType() || node->isJsBasicType()) {
+ generateQmlBasicTypePage(static_cast<QmlBasicTypeNode *>(node));
+ } else if (node->isProxyNode()) {
+ generateProxyPage(static_cast<Aggregate *>(node));
+ }
+ }
+ }
+
+ if (node->isAggregate()) {
+ auto *aggregate = static_cast<Aggregate *>(node);
+ for (auto c : aggregate->childNodes()) {
+ if (node->isPageNode() && !node->isPrivate())
+ generateDocumentation(c);
+ }
+ }
+}
+
+void DocBookGenerator::generateProxyPage(Aggregate *aggregate)
+{
+ // Adapted from HtmlGenerator::generateProxyPage.
+ Q_ASSERT(aggregate->isProxyNode());
+
+ // Start producing the DocBook file.
+ Q_ASSERT(writer == nullptr);
+ writer = startDocument(aggregate);
+
+ // Info container.
+ generateHeader(aggregate->plainFullName(), "", aggregate);
+
+ // No element synopsis.
+
+ // Actual content.
+ if (!aggregate->doc().isEmpty()) {
+ startSection(registerRef("details"), "Detailed Description");
+
+ generateBody(aggregate);
+ generateAlsoList(aggregate);
+ generateMaintainerList(aggregate);
+
+ endSection();
+ }
+
+ Sections sections(aggregate);
+ SectionVector *detailsSections = &sections.stdDetailsSections();
+
+ for (const auto &section : qAsConst(*detailsSections)) {
+ if (section.isEmpty())
+ continue;
+
+ startSection(section.title().toLower(), section.title());
+
+ const QVector<Node *> &members = section.members();
+ for (const auto &member : members) {
+ if (!member->isPrivate()) { // ### check necessary?
+ if (!member->isClassNode()) {
+ generateDetailedMember(member, aggregate);
+ } else {
+ startSectionBegin();
+ generateFullName(member, aggregate);
+ startSectionEnd();
+ generateBrief(member);
+ endSection();
+ }
+ }
+ }
+
+ endSection();
+ }
+
+ generateFooter();
+
+ endDocument();
+}
+
+/*!
+ Generate the HTML page for a group, module, or QML module.
+ */
+void DocBookGenerator::generateCollectionNode(CollectionNode *cn)
+{
+ // Adapted from HtmlGenerator::generateCollectionNode.
+ // Start producing the DocBook file.
+ Q_ASSERT(writer == nullptr);
+ writer = startDocument(cn);
+
+ // Info container.
+ generateHeader(cn->fullTitle(), cn->subtitle(), cn);
+
+ // Element synopsis.
+ generateDocBookSynopsis(cn);
+
+ // Actual content.
+ if (cn->isModule()) {
+ // Generate brief text and status for modules.
+ generateBrief(cn);
+ generateStatus(cn);
+ generateSince(cn);
+
+ if (!cn->noAutoList()) {
+ NodeMultiMap nmm;
+ cn->getMemberNamespaces(nmm);
+ if (!nmm.isEmpty()) {
+ startSection(registerRef("namespaces"), "Namespaces");
+ generateAnnotatedList(cn, nmm, "namespaces");
+ endSection();
+ }
+ nmm.clear();
+ cn->getMemberClasses(nmm);
+ if (!nmm.isEmpty()) {
+ startSection(registerRef("classes"), "Classes");
+ generateAnnotatedList(cn, nmm, "classes");
+ endSection();
+ }
+ }
+ }
+
+ Text brief = cn->doc().briefText();
+ bool generatedTitle = false;
+ if (cn->isModule() && !brief.isEmpty()) {
+ startSection(registerRef("details"), "Detailed Description");
+ generatedTitle = true;
+ } else {
+ writeAnchor(registerRef("details"));
+ }
+
+ generateBody(cn);
+ generateAlsoList(cn);
+
+ if (!cn->noAutoList() && (cn->isGroup() || cn->isQmlModule() || cn->isJsModule()))
+ generateAnnotatedList(cn, cn->members(), "members");
+
+ if (generatedTitle)
+ endSection();
+
+ generateFooter();
+
+ endDocument();
+}
+
+/*!
+ Generate the HTML page for a generic collection. This is usually
+ a collection of C++ elements that are related to an element in
+ a different module.
+ */
+void DocBookGenerator::generateGenericCollectionPage(CollectionNode *cn)
+{
+ // Adapted from HtmlGenerator::generateGenericCollectionPage.
+ // TODO: factor out this code to generate a file name.
+ QString name = cn->name().toLower();
+ name.replace(QChar(' '), QString("-"));
+ QString filename = cn->tree()->physicalModuleName() + "-" + name + "." + fileExtension();
+
+ // Start producing the DocBook file.
+ Q_ASSERT(writer == nullptr);
+ writer = startGenericDocument(cn, filename);
+
+ // Info container.
+ generateHeader(cn->fullTitle(), cn->subtitle(), cn);
+
+ // Element synopsis.
+ generateDocBookSynopsis(cn);
+
+ // Actual content.
+ writer->writeStartElement(dbNamespace, "para");
+ writer->writeCharacters("Each function or type documented here is related to a class or "
+ "namespace that is documented in a different module. The reference "
+ "page for that class or namespace will link to the function or type "
+ "on this page.");
+ writer->writeEndElement(); // para
+
+ const CollectionNode *cnc = cn;
+ const QList<Node *> members = cn->members();
+ for (const auto &member : members)
+ generateDetailedMember(member, cnc);
+
+ generateFooter();
+
+ endDocument();
+}
+
+void DocBookGenerator::generateFullName(const Node *node, const Node *relative)
+{
+ // From Generator::appendFullName.
+ writer->writeStartElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "href", fullDocumentLocation(node));
+ writer->writeAttribute(xlinkNamespace, "role", targetType(node));
+ writer->writeCharacters(node->fullName(relative));
+ writer->writeEndElement(); // link
+}
+
+void DocBookGenerator::generateFullName(const Node *apparentNode, const QString &fullName,
+ const Node *actualNode)
+{
+ // From Generator::appendFullName.
+ if (actualNode == nullptr)
+ actualNode = apparentNode;
+ writer->writeStartElement(dbNamespace, "link");
+ writer->writeAttribute(xlinkNamespace, "href", fullDocumentLocation(actualNode));
+ writer->writeAttribute("type", targetType(actualNode));
+ writer->writeCharacters(fullName);
+ writer->writeEndElement(); // link
+}
+
+QT_END_NAMESPACE
diff --git a/src/qdoc/docbookgenerator.h b/src/qdoc/docbookgenerator.h
new file mode 100644
index 000000000..5eea595f7
--- /dev/null
+++ b/src/qdoc/docbookgenerator.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Thibaut Cuvelier
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ docbookgenerator.h
+*/
+
+#ifndef DOCBOOKGENERATOR_H
+#define DOCBOOKGENERATOR_H
+
+#include "codemarker.h"
+#include "config.h"
+#include "xmlgenerator.h"
+
+#include <QtCore/qhash.h>
+#include <QtCore/qregexp.h>
+#include <QtCore/qxmlstream.h>
+
+QT_BEGIN_NAMESPACE
+
+class DocBookGenerator : public XmlGenerator
+{
+public:
+ explicit DocBookGenerator() = default;
+
+ void initializeGenerator() override;
+ QString format() override;
+
+protected:
+ QString fileExtension() const override;
+ void generateDocumentation(Node *node) override;
+ using Generator::generateCppReferencePage;
+ void generateCppReferencePage(Node *node);
+ using Generator::generatePageNode;
+ void generatePageNode(PageNode *pn);
+ using Generator::generateQmlTypePage;
+ void generateQmlTypePage(QmlTypeNode *qcn);
+ using Generator::generateQmlBasicTypePage;
+ void generateQmlBasicTypePage(QmlBasicTypeNode *qbtn);
+ using Generator::generateCollectionNode;
+ void generateCollectionNode(CollectionNode *cn);
+ using Generator::generateGenericCollectionPage;
+ void generateGenericCollectionPage(CollectionNode *cn);
+ using Generator::generateProxyPage;
+ void generateProxyPage(Aggregate *aggregate);
+
+ void generateList(const Node *relative, const QString &selector);
+ void generateHeader(const QString &title, const QString &subtitle, const Node *node);
+ void closeTextSections();
+ void generateFooter();
+ void generateDocBookSynopsis(const Node *node);
+ void generateRequisites(const Aggregate *inner);
+ void generateQmlRequisites(const QmlTypeNode *qcn);
+ void generateSortedNames(const ClassNode *cn, const QVector<RelatedClass> &rc);
+ void generateSortedQmlNames(const Node *base, const NodeList &subs);
+ bool generateStatus(const Node *node);
+ bool generateThreadSafeness(const Node *node);
+ bool generateSince(const Node *node);
+ void generateAddendum(const Node *node, Generator::Addendum type, CodeMarker *marker = nullptr) override;
+ using Generator::generateBody;
+ void generateBody(const Node *node);
+
+ bool generateText(const Text &text, const Node *relative,
+ CodeMarker *marker = nullptr) override;
+ const Atom *generateAtomList(const Atom *atom, const Node *relative, bool generate,
+ int &numAtoms);
+ int generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker = nullptr) override;
+
+private:
+ QXmlStreamWriter *startDocument(const Node *node);
+ QXmlStreamWriter *startDocument(const ExampleNode *en, const QString &file);
+ QXmlStreamWriter *startGenericDocument(const Node *node, const QString &fileName);
+ void endDocument();
+
+ void generateAnnotatedList(const Node *relative, const NodeList &nodeList,
+ const QString &selector);
+ void generateAnnotatedList(const Node *relative, const NodeMultiMap &nmm,
+ const QString &selector);
+ void generateAnnotatedLists(const Node *relative, const NodeMultiMap &nmm,
+ const QString &selector);
+ void generateCompactList(ListType listType, const Node *relative, const NodeMultiMap &nmm,
+ const QString &commonPrefix, const QString &selector);
+ using Generator::generateFileList;
+ void generateFileList(const ExampleNode *en, bool images);
+ void generateObsoleteMembers(const Sections &sections);
+ void generateObsoleteQmlMembers(const Sections &sections);
+ void generateSectionList(const Section &section, const Node *relative,
+ Section::Status status = Section::Active);
+ void generateSectionInheritedList(const Section &section, const Node *relative);
+ void generateSynopsisName(const Node *node, const Node *relative, bool generateNameLink);
+ void generateParameter(const Parameter &parameter, const Node *relative, bool generateExtra,
+ bool generateType);
+ void generateSynopsis(const Node *node, const Node *relative, Section::Style style);
+ void generateEnumValue(const QString &enumValue, const Node *relative);
+ void generateDetailedMember(const Node *node, const PageNode *relative);
+ void generateDetailedQmlMember(Node *node, const Aggregate *relative);
+
+ void generateFullName(const Node *node, const Node *relative);
+ void generateFullName(const Node *apparentNode, const QString &fullName,
+ const Node *actualNode);
+ void generateBrief(const Node *node);
+ void generateAlsoList(const Node *node, CodeMarker *marker = nullptr) override;
+ void generateSignatureList(const NodeList &nodes);
+ void generateMaintainerList(const Aggregate *node, CodeMarker *marker = nullptr) override;
+ void generateReimplementsClause(const FunctionNode *fn);
+ void generateClassHierarchy(const Node *relative, NodeMap &classMap);
+ void generateFunctionIndex(const Node *relative);
+ void generateLegaleseList(const Node *relative);
+ void generateExampleFilePage(const Node *en, const QString &file,
+ CodeMarker *marker = nullptr) override;
+ void generateOverloadedSignal(const Node *node);
+ bool generateQmlText(const Text &text, const Node *relative, CodeMarker *marker = nullptr,
+ const QString &qmlName = QString()) override;
+ void generateRequiredLinks(const Node *node);
+ void generateLinkToExample(const ExampleNode *en, const QString &baseUrl);
+
+ void typified(const QString &string, const Node *relative, bool trailingSpace = false,
+ bool generateType = true);
+ void generateLink(const Atom *atom);
+ void beginLink(const QString &link, const Node *node, const Node *relative);
+ void endLink();
+ inline void newLine();
+ void startSectionBegin();
+ void startSectionBegin(const QString &id);
+ void startSectionEnd();
+ void startSection(const QString &id, const QString &title);
+ void endSection();
+ void writeAnchor(const QString &id);
+ void generateSimpleLink(const QString &href, const QString &text);
+ void generateStartRequisite(const QString &description);
+ void generateEndRequisite();
+ void generateRequisite(const QString &description, const QString &value);
+ void generateSynopsisInfo(const QString &key, const QString &value);
+ void generateModifier(const QString &value);
+
+ bool inListItemLineOpen {};
+ bool inLink {};
+ int currentSectionLevel {};
+ QStack<int> sectionLevels {};
+ QString qflagsHref_;
+
+ QString project;
+ QString projectDescription;
+ QString naturalLanguage;
+ QString buildversion;
+ QXmlStreamWriter *writer = nullptr;
+
+ Config *config = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp
index 46d3ad453..bdeeec2be 100644
--- a/src/qdoc/generator.cpp
+++ b/src/qdoc/generator.cpp
@@ -75,11 +75,8 @@ QStringList Generator::styleFiles;
bool Generator::noLinkErrors_ = false;
bool Generator::autolinkErrors_ = false;
bool Generator::redirectDocumentationToDevNull_ = false;
-Generator::QDocPass Generator::qdocPass_ = Generator::Neither;
bool Generator::qdocSingleExec_ = false;
-bool Generator::qdocWriteQaPages_ = false;
bool Generator::useOutputSubdirs_ = true;
-bool Generator::useTimestamps_ = false;
QmlTypeNode *Generator::qmlTypeContext_ = nullptr;
static QRegExp tag("</?@[^>]*>");
@@ -393,9 +390,10 @@ QString Generator::fileBase(const Node *node) const
to the file name. The suffix, if one exists, is appended to the
module name.
*/
- if (!node->logicalModuleName().isEmpty()) {
+ if (!node->logicalModuleName().isEmpty()
+ && (!node->logicalModule()->isInternal() || showInternal_))
base.prepend(node->logicalModuleName() + outputSuffix(node) + QLatin1Char('-'));
- }
+
base.prepend(outputPrefix(node));
} else if (node->isProxyNode()) {
base = node->name();
@@ -761,55 +759,55 @@ const Atom *Generator::generateAtomList(const Atom *atom, const Node *relative,
*/
void Generator::generateBody(const Node *node, CodeMarker *marker)
{
+ const FunctionNode *fn = node->isFunction() ? static_cast<const FunctionNode *>(node) : nullptr;
if (!node->hasDoc() && !node->hasSharedDoc()) {
/*
Test for special function, like a destructor or copy constructor,
that has no documentation.
*/
- if (node->isFunction()) {
- const FunctionNode *func = static_cast<const FunctionNode *>(node);
- if (func->isDtor()) {
+ if (fn) {
+ if (fn->isDtor()) {
Text text;
text << "Destroys the instance of ";
- text << func->parent()->name() << ".";
- if (func->isVirtual())
+ text << fn->parent()->name() << ".";
+ if (fn->isVirtual())
text << " The destructor is virtual.";
out() << "<p>";
generateText(text, node, marker);
out() << "</p>";
- } else if (func->isCtor()) {
+ } else if (fn->isCtor()) {
Text text;
text << "Default constructs an instance of ";
- text << func->parent()->name() << ".";
+ text << fn->parent()->name() << ".";
out() << "<p>";
generateText(text, node, marker);
out() << "</p>";
- } else if (func->isCCtor()) {
+ } else if (fn->isCCtor()) {
Text text;
text << "Copy constructor.";
out() << "<p>";
generateText(text, node, marker);
out() << "</p>";
- } else if (func->isMCtor()) {
+ } else if (fn->isMCtor()) {
Text text;
text << "Move-copy constructor.";
out() << "<p>";
generateText(text, node, marker);
out() << "</p>";
- } else if (func->isCAssign()) {
+ } else if (fn->isCAssign()) {
Text text;
text << "Copy-assignment operator.";
out() << "<p>";
generateText(text, node, marker);
out() << "</p>";
- } else if (func->isMAssign()) {
+ } else if (fn->isMAssign()) {
Text text;
text << "Move-assignment operator.";
out() << "<p>";
generateText(text, node, marker);
out() << "</p>";
} else if (!node->isWrapper() && !node->isMarkedReimp()) {
- if (!func->isIgnored()) // undocumented functions added by Q_OBJECT
+ if (!fn->isIgnored()) // undocumented functions added by Q_OBJECT
node->location().warning(
tr("No documentation for '%1'").arg(node->plainSignature()));
}
@@ -820,8 +818,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
tr("No documentation for '%1'").arg(node->plainSignature()));
}
} else if (!node->isSharingComment()) {
- if (node->isFunction()) {
- const FunctionNode *fn = static_cast<const FunctionNode *>(node);
+ if (fn) {
if (!fn->overridesThis().isEmpty())
generateReimplementsClause(fn, marker);
}
@@ -831,6 +828,18 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
return;
}
+ if (fn) {
+ if (fn->isQmlSignal())
+ generateAddendum(node, QmlSignalHandler, marker);
+ if (fn->isPrivateSignal())
+ generateAddendum(node, PrivateSignal, marker);
+ if (fn->isInvokable())
+ generateAddendum(node, Invokable, marker);
+ if (fn->hasAssociatedProperties())
+ generateAddendum(node, AssociatedProperties, marker);
+ }
+
+ // Generate warnings
if (node->isEnumType()) {
const EnumNode *enume = static_cast<const EnumNode *>(node);
@@ -862,8 +871,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
}
- } else if (node->isFunction()) {
- const FunctionNode *fn = static_cast<const FunctionNode *>(node);
+ } else if (fn) {
const QSet<QString> declaredNames = fn->parameters().getNames();
const QSet<QString> documentedNames = fn->doc().parameterNames();
if (declaredNames != documentedNames) {
@@ -920,7 +928,7 @@ void Generator::generateRequiredLinks(const Node *node, CodeMarker *marker)
return;
const ExampleNode *en = static_cast<const ExampleNode *>(node);
- QString exampleUrl = config()->getString(CONFIG_URL + Config::dot + CONFIG_EXAMPLES);
+ QString exampleUrl = Config::instance().getString(CONFIG_URL + Config::dot + CONFIG_EXAMPLES);
if (exampleUrl.isEmpty()) {
if (!en->noAutoList()) {
@@ -962,7 +970,7 @@ void Generator::generateLinkToExample(const ExampleNode *en, CodeMarker *marker,
// Construct a path to the example; <install path>/<example name>
QString pathRoot = en->doc().metaTagMap().value(QLatin1String("installpath"));
if (pathRoot.isEmpty())
- pathRoot = config()->getString(CONFIG_EXAMPLESINSTALLPATH);
+ pathRoot = Config::instance().getString(CONFIG_EXAMPLESINSTALLPATH);
QStringList path = QStringList() << pathRoot << en->name();
path.removeAll({});
@@ -1261,8 +1269,12 @@ void Generator::generateReimplementsClause(const FunctionNode *fn, CodeMarker *m
appendFullName(text, overrides->parent(), fullName, overrides);
text << "." << Atom::ParaRight;
generateText(text, fn, marker);
- return;
+ } else {
+ fn->doc().location().warning(
+ tr("Illegal \\reimp; no documented virtual function for %1")
+ .arg(overrides->plainSignature()));
}
+ return;
}
const PropertyNode *sameName = cn->findOverriddenProperty(fn);
if (sameName && sameName->hasDoc()) {
@@ -1272,10 +1284,6 @@ void Generator::generateReimplementsClause(const FunctionNode *fn, CodeMarker *m
appendFullName(text, sameName->parent(), fullName, sameName);
text << "." << Atom::ParaRight;
generateText(text, fn, marker);
- } else {
- fn->doc().location().warning(
- tr("Illegal \\reimp; no documented virtual function for %1")
- .arg(fn->plainSignature()));
}
}
}
@@ -1346,33 +1354,76 @@ void Generator::generateStatus(const Node *node, CodeMarker *marker)
}
/*!
- Generates a bold line that explains that this is a private signal,
- only made public to let users pass it to connect().
- */
-void Generator::generatePrivateSignalNote(const Node *node, CodeMarker *marker)
+ Generates an addendum note of type \a type for \a node, using \a marker
+ as the code marker.
+*/
+void Generator::generateAddendum(const Node *node, Addendum type, CodeMarker *marker)
{
+ Q_ASSERT(node && !node->name().isEmpty());
Text text;
text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
- << "Note: " << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
- << "This is a private signal. It can be used in signal connections but cannot be emitted "
- "by the user."
- << Atom::ParaRight;
- generateText(text, node, marker);
-}
+ << "Note: " << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD);
+
+ switch (type) {
+ case Invokable:
+ text << "This function can be invoked via the meta-object system and from QML. See "
+ << Atom(Atom::Link, "Q_INVOKABLE")
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) << "Q_INVOKABLE"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << ".";
+ break;
+ case PrivateSignal:
+ text << "This is a private signal. It can be used in signal connections "
+ "but cannot be emitted by the user.";
+ break;
+ case QmlSignalHandler:
+ {
+ QString handler(node->name());
+ handler[0] = handler[0].toTitleCase();
+ handler.prepend(QLatin1String("on"));
+ text << "The corresponding handler is "
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_TELETYPE) << handler
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_TELETYPE) << ".";
+ break;
+ }
+ case AssociatedProperties:
+ {
+ if (!node->isFunction())
+ return;
+ const FunctionNode *fn = static_cast<const FunctionNode *>(node);
+ NodeList nodes = fn->associatedProperties();
+ if (nodes.isEmpty())
+ return;
+ std::sort(nodes.begin(), nodes.end(), Node::nodeNameLessThan);
+ for (const auto *n : qAsConst(nodes)) {
+ QString msg;
+ const PropertyNode *pn = static_cast<const PropertyNode *>(n);
+ switch (pn->role(fn)) {
+ case PropertyNode::Getter:
+ msg = QStringLiteral("Getter function");
+ break;
+ case PropertyNode::Setter:
+ msg = QStringLiteral("Setter function");
+ break;
+ case PropertyNode::Resetter:
+ msg = QStringLiteral("Resetter function");
+ break;
+ case PropertyNode::Notifier:
+ msg = QStringLiteral("Notifier signal");
+ break;
+ default:
+ continue;
+ }
+ text << msg << " for property " << Atom(Atom::Link, pn->name())
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) << pn->name()
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << ". ";
+ }
+ break;
+ }
+ default:
+ return;
+ }
-/*!
- Generates a bold line that says:
- "This function can be invoked via the meta-object system and from QML. See Q_INVOKABLE."
- */
-void Generator::generateInvokableNote(const Node *node, CodeMarker *marker)
-{
- Text text;
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
- << "Note: " << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
- << "This function can be invoked via the meta-object system and from QML. See "
- << Atom(Atom::Link, "Q_INVOKABLE") << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << "Q_INVOKABLE" << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << "."
- << Atom::ParaRight;
+ text << Atom::ParaRight;
generateText(text, node, marker);
}
@@ -1562,11 +1613,7 @@ QString Generator::getOverloadedSignalCode(const Node *node)
}
/*!
- If the node is an overloaded signal, and a node with an example on how to connect to it
-
- Someone didn't finish writing this comment, and I don't know what this
- function is supposed to do, so I have not tried to complete the comment
- yet.
+ If the node is an overloaded signal, add a node with an example on how to connect to it
*/
void Generator::generateOverloadedSignal(const Node *node, CodeMarker *marker)
{
@@ -1690,8 +1737,9 @@ QString Generator::indent(int level, const QString &markedCode)
return t;
}
-void Generator::initialize(const Config &config)
+void Generator::initialize()
{
+ Config &config = Config::instance();
outputFormats = config.getOutputFormats();
redirectDocumentationToDevNull_ = config.getBool(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL);
@@ -1711,7 +1759,7 @@ void Generator::initialize(const Config &config)
for (auto &g : generators) {
if (outputFormats.contains(g->format())) {
currentGenerator_ = g;
- g->initializeGenerator(config);
+ g->initializeGenerator();
}
}
@@ -1770,9 +1818,9 @@ void Generator::initialize(const Config &config)
Creates template-specific subdirs (e.g. /styles and /scripts for HTML)
and copies the files to them.
*/
-void Generator::copyTemplateFiles(const Config &config, const QString &configVar,
- const QString &subDir)
+void Generator::copyTemplateFiles(const QString &configVar, const QString &subDir)
{
+ Config &config = Config::instance();
QStringList files = config.getCanonicalPathList(configVar, true);
if (!files.isEmpty()) {
QDir dirInfo;
@@ -1790,12 +1838,13 @@ void Generator::copyTemplateFiles(const Config &config, const QString &configVar
}
/*!
- Reads format-specific variables from \a config, sets output
+ Reads format-specific variables from config, sets output
(sub)directories, creates them on the filesystem and copies the
template-specific files.
*/
-void Generator::initializeFormat(const Config &config)
+void Generator::initializeFormat()
{
+ Config &config = Config::instance();
outFileNames_.clear();
useOutputSubdirs_ = true;
if (config.getBool(format() + Config::dot + "nosubdirs"))
@@ -1814,7 +1863,7 @@ void Generator::initializeFormat(const Config &config)
QDir dirInfo;
if (dirInfo.exists(outDir_)) {
- if (!generating() && Generator::useOutputSubdirs()) {
+ if (!config.generating() && Generator::useOutputSubdirs()) {
if (!Config::removeDirContents(outDir_))
config.lastLocation().error(tr("Cannot empty output directory '%1'").arg(outDir_));
}
@@ -1823,16 +1872,16 @@ void Generator::initializeFormat(const Config &config)
}
// Output directory exists, which is enough for prepare phase.
- if (preparing())
+ if (config.preparing())
return;
if (!dirInfo.exists(outDir_ + "/images") && !dirInfo.mkdir(outDir_ + "/images"))
config.lastLocation().fatal(
tr("Cannot create images directory '%1'").arg(outDir_ + "/images"));
- copyTemplateFiles(config, format() + Config::dot + CONFIG_STYLESHEETS, "style");
- copyTemplateFiles(config, format() + Config::dot + CONFIG_SCRIPTS, "scripts");
- copyTemplateFiles(config, format() + Config::dot + CONFIG_EXTRAIMAGES, "images");
+ copyTemplateFiles(format() + Config::dot + CONFIG_STYLESHEETS, "style");
+ copyTemplateFiles(format() + Config::dot + CONFIG_SCRIPTS, "scripts");
+ copyTemplateFiles(format() + Config::dot + CONFIG_EXTRAIMAGES, "images");
// Use a format-specific .quotinginformation if defined, otherwise a global value
if (config.subVars(format()).contains(CONFIG_QUOTINGINFORMATION))
@@ -1856,11 +1905,10 @@ void Generator::augmentImageDirs(QSet<QString> &moreImageDirs)
/*!
Sets the generator's pointer to the Config instance.
*/
-void Generator::initializeGenerator(const Config &config)
+void Generator::initializeGenerator()
{
- config_ = &config;
- showInternal_ = config.getBool(CONFIG_SHOWINTERNAL);
- singleExec_ = config.getBool(CONFIG_SINGLEEXEC);
+ showInternal_ = Config::instance().getBool(CONFIG_SHOWINTERNAL);
+ singleExec_ = Config::instance().getBool(CONFIG_SINGLEEXEC);
}
bool Generator::matchAhead(const Atom *atom, Atom::AtomType expectedAtomType)
@@ -2138,8 +2186,8 @@ QString Generator::typeString(const Node *node)
case Node::Union:
return "union";
case Node::QmlType:
- return "type";
case Node::QmlBasicType:
+ case Node::JsBasicType:
return "type";
case Node::Page:
return "documentation";
@@ -2171,6 +2219,10 @@ QString Generator::typeString(const Node *node)
case Node::JsModule:
case Node::QmlModule:
return "module";
+ case Node::SharedComment: {
+ const auto &collective = static_cast<const SharedCommentNode *>(node)->collective();
+ return collective.first()->nodeTypeString();
+ }
default:
return "documentation";
}
diff --git a/src/qdoc/generator.h b/src/qdoc/generator.h
index 6723884f1..f12aff933 100644
--- a/src/qdoc/generator.h
+++ b/src/qdoc/generator.h
@@ -42,7 +42,6 @@ QT_BEGIN_NAMESPACE
typedef QMultiMap<QString, Node *> NodeMultiMap;
typedef QMap<Node *, NodeMultiMap> ParentMaps;
-class Config;
class CodeMarker;
class Location;
class Node;
@@ -53,8 +52,8 @@ class Generator
Q_DECLARE_TR_FUNCTIONS(QDoc::Generator)
public:
- enum QDocPass { Neither, Prepare, Generate };
enum ListType { Generic, Obsolete };
+ enum Addendum { Invokable, PrivateSignal, QmlSignalHandler, AssociatedProperties };
Generator();
virtual ~Generator();
@@ -62,18 +61,18 @@ public:
virtual bool canHandleFormat(const QString &format) { return format == this->format(); }
virtual QString format() = 0;
virtual void generateDocs();
- virtual void initializeGenerator(const Config &config);
- virtual void initializeFormat(const Config &config);
+ virtual void initializeGenerator();
+ virtual void initializeFormat();
virtual void terminateGenerator();
+ virtual QString typeString(const Node *node);
QString fullDocumentLocation(const Node *node, bool useSubdir = false);
- const Config *config() { return config_; }
QString linkForExampleFile(const QString &path, const Node *parent,
const QString &fileExt = QString());
static QString exampleFileTitle(const ExampleNode *relative, const QString &fileName);
static Generator *currentGenerator() { return currentGenerator_; }
static Generator *generatorForFormat(const QString &format);
- static void initialize(const Config &config);
+ static void initialize();
static const QString &outputDir() { return outDir_; }
static const QString &outputSubdir() { return outSubdir_; }
static void terminate();
@@ -82,15 +81,6 @@ public:
static void augmentImageDirs(QSet<QString> &moreImageDirs);
static bool noLinkErrors() { return noLinkErrors_; }
static bool autolinkErrors() { return autolinkErrors_; }
- static void setQDocPass(QDocPass t) { qdocPass_ = t; }
- static void setUseTimestamps() { useTimestamps_ = true; }
- static bool preparing() { return (qdocPass_ == Prepare); }
- static bool generating() { return (qdocPass_ == Generate); }
- static bool singleExec() { return qdocSingleExec_; }
- static bool dualExec() { return !qdocSingleExec_; }
- static bool writeQaPages() { return qdocWriteQaPages_; }
- static void setSingleExec() { qdocSingleExec_ = true; }
- static void setWriteQaPages() { qdocWriteQaPages_ = true; }
static QString defaultModuleName() { return project_; }
static void resetUseOutputSubdirs() { useOutputSubdirs_ = false; }
static bool useOutputSubdirs() { return useOutputSubdirs_; }
@@ -98,7 +88,6 @@ public:
static QmlTypeNode *qmlTypeContext() { return qmlTypeContext_; }
static QString cleanRef(const QString &ref);
static QString plainCode(const QString &markedCode);
- static bool useTimestamps() { return useTimestamps_; }
protected:
static QFile *openSubPageFile(const Node *node, const QString &fileName);
@@ -131,7 +120,6 @@ protected:
virtual bool generateText(const Text &text, const Node *relative, CodeMarker *marker);
virtual QString imageFileName(const Node *relative, const QString &fileBase);
virtual int skipAtoms(const Atom *atom, Atom::AtomType type) const;
- virtual QString typeString(const Node *node);
static bool matchAhead(const Atom *atom, Atom::AtomType expectedAtomType);
static QString outputPrefix(const Node *node);
@@ -153,8 +141,7 @@ protected:
static QString formatSince(const Node *node);
void generateSince(const Node *node, CodeMarker *marker);
void generateStatus(const Node *node, CodeMarker *marker);
- void generatePrivateSignalNote(const Node *node, CodeMarker *marker);
- void generateInvokableNote(const Node *node, CodeMarker *marker);
+ virtual void generateAddendum(const Node *node, Addendum type, CodeMarker *marker);
void generateThreadSafeness(const Node *node, CodeMarker *marker);
QString getMetadataElement(const Aggregate *inner, const QString &t);
QStringList getMetadataElements(const Aggregate *inner, const QString &t);
@@ -193,6 +180,8 @@ protected:
void signatureList(const NodeList &nodes, const Node *relative, CodeMarker *marker);
void addImageToCopy(const ExampleNode *en, const QString &file);
+ static bool compareNodes(const Node *a, const Node *b) { return (a->name() < b->name()); }
+ static bool comparePaths(const QString &a, const QString &b) { return (a < b); }
private:
static Generator *currentGenerator_;
@@ -218,21 +207,14 @@ private:
static bool noLinkErrors_;
static bool autolinkErrors_;
static bool redirectDocumentationToDevNull_;
- static QDocPass qdocPass_;
static bool qdocSingleExec_;
- static bool qdocWriteQaPages_;
static bool useOutputSubdirs_;
- static bool useTimestamps_;
static QmlTypeNode *qmlTypeContext_;
void generateReimplementsClause(const FunctionNode *fn, CodeMarker *marker);
- static bool compareNodes(Node *a, Node *b) { return (a->name() < b->name()); }
- static bool comparePaths(QString a, QString b) { return (a < b); }
- static void copyTemplateFiles(const Config &config, const QString &configVar,
- const QString &subDir);
+ static void copyTemplateFiles(const QString &configVar, const QString &subDir);
protected:
- const Config *config_;
QDocDatabase *qdb_;
bool inLink_;
bool inContents_;
diff --git a/src/qdoc/helpprojectwriter.cpp b/src/qdoc/helpprojectwriter.cpp
index 6f231f232..a372ea762 100644
--- a/src/qdoc/helpprojectwriter.cpp
+++ b/src/qdoc/helpprojectwriter.cpp
@@ -41,13 +41,12 @@
QT_BEGIN_NAMESPACE
-HelpProjectWriter::HelpProjectWriter(const Config &config, const QString &defaultFileName,
- Generator *g)
+HelpProjectWriter::HelpProjectWriter(const QString &defaultFileName, Generator *g)
{
- reset(config, defaultFileName, g);
+ reset(defaultFileName, g);
}
-void HelpProjectWriter::reset(const Config &config, const QString &defaultFileName, Generator *g)
+void HelpProjectWriter::reset(const QString &defaultFileName, Generator *g)
{
projects.clear();
gen_ = g;
@@ -60,6 +59,7 @@ void HelpProjectWriter::reset(const Config &config, const QString &defaultFileNa
// The output directory should already have been checked by the calling
// generator.
+ Config &config = Config::instance();
outputDir = config.getOutputDir();
const QStringList names = config.getStringList(CONFIG_QHP + Config::dot + "projects");
@@ -92,7 +92,6 @@ void HelpProjectWriter::reset(const Config &config, const QString &defaultFileNa
+ Config::dot + "filterAttributes");
project.customFilters[name] = QSet<QString>(filters.cbegin(), filters.cend());
}
- // customFilters = config.defs.
const auto excludedPrefixes = config.getStringSet(prefix + "excluded");
for (auto name : excludedPrefixes)
@@ -103,6 +102,8 @@ void HelpProjectWriter::reset(const Config &config, const QString &defaultFileNa
SubProject subproject;
QString subprefix = prefix + "subprojects" + Config::dot + name + Config::dot;
subproject.title = config.getString(subprefix + "title");
+ if (subproject.title.isEmpty())
+ continue;
subproject.indexTitle = config.getString(subprefix + "indexTitle");
subproject.sortPages = config.getBool(subprefix + "sortPages");
subproject.type = config.getString(subprefix + "type");
@@ -129,8 +130,8 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["union"] = Node::Union;
typeHash["header"] = Node::HeaderFile;
typeHash["headerfile"] = Node::HeaderFile;
- typeHash["doc"] = Node::Page; // to be removed from qdocconf files
- typeHash["fake"] = Node::Page; // to be removed from qdocconf files
+ typeHash["doc"] = Node::Page; // Unused (supported but ignored as a prefix)
+ typeHash["fake"] = Node::Page; // Unused (supported but ignored as a prefix)
typeHash["page"] = Node::Page;
typeHash["enum"] = Node::Enum;
typeHash["example"] = Node::Example;
@@ -149,41 +150,26 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["qmltype"] = Node::QmlType;
typeHash["qmlbasictype"] = Node::QmlBasicType;
- QHash<QString, Node::NodeType> pageTypeHash;
- pageTypeHash["example"] = Node::Example;
- pageTypeHash["headerfile"] = Node::HeaderFile;
- pageTypeHash["header"] = Node::HeaderFile;
- pageTypeHash["page"] = Node::Page;
- pageTypeHash["externalpage"] = Node::ExternalPage;
-
- NodeTypeSet fullSubset;
- for (auto it = pageTypeHash.constBegin(); it != pageTypeHash.constEnd(); ++it)
- fullSubset.insert(it.value());
-
for (const QString &selector : selectors) {
QStringList pieces = selector.split(QLatin1Char(':'));
- if (pieces.size() == 1) {
- QString lower = selector.toLower();
- if (typeHash.contains(lower))
- subproject.selectors[typeHash[lower]] = fullSubset;
- } else if (pieces.size() >= 2) {
- QString pageTypeStr = pieces[0].toLower();
- pieces = pieces[1].split(QLatin1Char(','));
- if (typeHash.contains(pageTypeStr)) {
- NodeTypeSet nodeTypeSet;
- for (int i = 0; i < pieces.size(); ++i) {
- QString piece = pieces[i].toLower();
- if (typeHash[pageTypeStr] == Node::Group
- || typeHash[pageTypeStr] == Node::Module
- || typeHash[pageTypeStr] == Node::QmlModule
- || typeHash[pageTypeStr] == Node::JsModule) {
- subproject.groups << piece;
- continue;
- }
- if (pageTypeHash.contains(piece))
- nodeTypeSet.insert(pageTypeHash[piece]);
+ // Remove doc: or fake: prefix
+ if (pieces.size() > 1 && typeHash.value(pieces[0].toLower()) == Node::Page)
+ pieces.takeFirst();
+
+ QString typeName = pieces.takeFirst().toLower();
+ if (!typeHash.contains(typeName))
+ continue;
+
+ subproject.selectors << typeHash.value(typeName);
+ if (!pieces.isEmpty()) {
+ pieces = pieces[0].split(QLatin1Char(','));
+ for (const auto &piece : qAsConst(pieces)) {
+ if (typeHash[typeName] == Node::Group
+ || typeHash[typeName] == Node::Module
+ || typeHash[typeName] == Node::QmlModule
+ || typeHash[typeName] == Node::JsModule) {
+ subproject.groups << piece.toLower();
}
- subproject.selectors[typeHash[pageTypeStr]] = nodeTypeSet;
}
}
}
@@ -268,7 +254,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter &
project.subprojects[i].nodes[objName] = node;
} else if (subproject.selectors.contains(node->nodeType())) {
// Add all group members for '[group|module|qmlmodule]:name' selector
- if (node->isGroup() || node->isModule() || node->isQmlModule()) {
+ if (node->isCollectionNode()) {
if (project.subprojects[i].groups.contains(node->name().toLower())) {
const CollectionNode *cn = static_cast<const CollectionNode *>(node);
const auto members = cn->members();
@@ -277,20 +263,15 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter &
m->isTextPageNode() ? m->fullTitle() : m->fullDocumentName();
project.subprojects[i].nodes[memberName] = m;
}
+ continue;
+ } else if (!project.subprojects[i].groups.isEmpty()) {
+ continue; // Node does not represent specified group(s)
}
+ } else if (node->isTextPageNode()) {
+ if (node->isExternalPage() || node->fullTitle().isEmpty())
+ continue;
}
- // Accept only the node types in the selectors hash.
- else if (!node->isTextPageNode())
- project.subprojects[i].nodes[objName] = node;
- else {
- // Accept only doc nodes with subtypes contained in the selector's
- // mask.
- if (subproject.selectors[node->nodeType()].contains(node->nodeType())
- && !node->isExternalPage() && !node->fullTitle().isEmpty()) {
-
- project.subprojects[i].nodes[objName] = node;
- }
- }
+ project.subprojects[i].nodes[objName] = node;
}
}
@@ -537,6 +518,9 @@ void HelpProjectWriter::writeSection(QXmlStreamWriter &writer, const QString &pa
*/
void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &writer, const Node *node)
{
+ if (node->isQmlBasicType() || node->isJsBasicType())
+ return;
+
QString href = gen_->fullDocumentLocation(node, false);
href = href.left(href.size() - 5);
if (href.isEmpty())
@@ -570,58 +554,41 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
case Node::Class:
case Node::Struct:
case Node::Union:
+ case Node::QmlType:
+ case Node::JsType:
+ case Node::QmlBasicType:
+ case Node::JsBasicType: {
+ QString typeStr = gen_->typeString(node);
+ if (!typeStr.isEmpty())
+ typeStr[0] = typeStr[0].toTitleCase();
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
if (node->parent() && !node->parent()->name().isEmpty())
writer.writeAttribute(
- "title", tr("%1::%2 Class Reference").arg(node->parent()->name()).arg(objName));
+ "title", tr("%1::%2 %3 Reference").arg(node->parent()->name()).arg(objName).arg(typeStr));
else
- writer.writeAttribute("title", tr("%1 Class Reference").arg(objName));
+ writer.writeAttribute("title", tr("%1 %2 Reference").arg(objName).arg(typeStr));
addMembers(project, writer, node);
writer.writeEndElement(); // section
- break;
+ } break;
case Node::Namespace:
writeSection(writer, href, objName);
break;
+ case Node::Example:
case Node::HeaderFile:
- writer.writeStartElement("section");
- writer.writeAttribute("ref", href);
- writer.writeAttribute("title", node->fullTitle());
- addMembers(project, writer, node);
- writer.writeEndElement(); // section
- break;
-
- case Node::JsType:
- case Node::QmlType:
- writer.writeStartElement("section");
- writer.writeAttribute("ref", href);
- writer.writeAttribute("title", tr("%1 Type Reference").arg(node->fullTitle()));
- addMembers(project, writer, node);
- writer.writeEndElement(); // section
- break;
-
- case Node::Page: {
- // Page nodes (such as manual pages) contain subtypes, titles and other
- // attributes.
- const PageNode *pn = static_cast<const PageNode *>(node);
-
- writer.writeStartElement("section");
- writer.writeAttribute("ref", href);
- writer.writeAttribute("title", pn->fullTitle());
-
- writer.writeEndElement(); // section
- } break;
+ case Node::Page:
case Node::Group:
case Node::Module:
case Node::JsModule:
case Node::QmlModule: {
- const CollectionNode *cn = static_cast<const CollectionNode *>(node);
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
- writer.writeAttribute("title", cn->fullTitle());
+ writer.writeAttribute("title", node->fullTitle());
+ if (node->nodeType() == Node::HeaderFile)
+ addMembers(project, writer, node);
writer.writeEndElement(); // section
} break;
default:;
diff --git a/src/qdoc/helpprojectwriter.h b/src/qdoc/helpprojectwriter.h
index be5439dfb..31b8f009d 100644
--- a/src/qdoc/helpprojectwriter.h
+++ b/src/qdoc/helpprojectwriter.h
@@ -29,7 +29,6 @@
#ifndef HELPPROJECTWRITER_H
#define HELPPROJECTWRITER_H
-#include "config.h"
#include "node.h"
#include <QtCore/qstring.h>
@@ -45,11 +44,9 @@ using NodeTypeSet = QSet<unsigned char>;
struct SubProject
{
- using NodeTypeToSet = QHash<unsigned char, NodeTypeSet>;
-
QString title;
QString indexTitle;
- NodeTypeToSet selectors;
+ NodeTypeSet selectors;
bool sortPages;
QString type;
QHash<QString, const Node *> nodes;
@@ -83,8 +80,8 @@ class HelpProjectWriter
Q_DECLARE_TR_FUNCTIONS(QDoc::HelpProjectWriter)
public:
- HelpProjectWriter(const Config &config, const QString &defaultFileName, Generator *g);
- void reset(const Config &config, const QString &defaultFileName, Generator *g);
+ HelpProjectWriter(const QString &defaultFileName, Generator *g);
+ void reset(const QString &defaultFileName, Generator *g);
void addExtraFile(const QString &file);
void addExtraFiles(const QSet<QString> &files);
void generate();
diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp
index fdfb4a65b..104d97bc2 100644
--- a/src/qdoc/htmlgenerator.cpp
+++ b/src/qdoc/htmlgenerator.cpp
@@ -32,6 +32,7 @@
#include "htmlgenerator.h"
+#include "config.h"
#include "codemarker.h"
#include "codeparser.h"
#include "helpprojectwriter.h"
@@ -105,9 +106,9 @@ HtmlGenerator::~HtmlGenerator()
/*!
Initializes the HTML output generator's data structures
- from the configuration class \a config.
+ from the configuration (Config) singleton.
*/
-void HtmlGenerator::initializeGenerator(const Config &config)
+void HtmlGenerator::initializeGenerator()
{
static const struct
{
@@ -126,8 +127,9 @@ void HtmlGenerator::initializeGenerator(const Config &config)
{ ATOM_FORMATTING_UNDERLINE, "<u>", "</u>" },
{ nullptr, nullptr, nullptr } };
- Generator::initializeGenerator(config);
- obsoleteLinks = config.getBool(CONFIG_OBSOLETELINKS);
+ Generator::initializeGenerator();
+ config = &Config::instance();
+ obsoleteLinks = config->getBool(CONFIG_OBSOLETELINKS);
setImageFileExtensions(QStringList() << "png"
<< "jpg"
<< "jpeg"
@@ -145,49 +147,50 @@ void HtmlGenerator::initializeGenerator(const Config &config)
i++;
}
- style = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_STYLE);
- endHeader = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_ENDHEADER);
- postHeader = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTHEADER);
+ style = config->getString(HtmlGenerator::format() + Config::dot + CONFIG_STYLE);
+ endHeader = config->getString(HtmlGenerator::format() + Config::dot + CONFIG_ENDHEADER);
+ postHeader =
+ config->getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTHEADER);
postPostHeader =
- config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTPOSTHEADER);
- prologue = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_PROLOGUE);
+ config->getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTPOSTHEADER);
+ prologue = config->getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_PROLOGUE);
- footer = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_FOOTER);
- address = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_ADDRESS);
+ footer = config->getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_FOOTER);
+ address = config->getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_ADDRESS);
pleaseGenerateMacRef =
- config.getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_GENERATEMACREFS);
+ config->getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_GENERATEMACREFS);
noNavigationBar =
- config.getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_NONAVIGATIONBAR);
- navigationSeparator = config.getString(HtmlGenerator::format() + Config::dot
- + HTMLGENERATOR_NAVIGATIONSEPARATOR);
- tocDepth = config.getInt(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_TOCDEPTH);
+ config->getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_NONAVIGATIONBAR);
+ navigationSeparator = config->getString(HtmlGenerator::format() + Config::dot
+ + HTMLGENERATOR_NAVIGATIONSEPARATOR);
+ tocDepth = config->getInt(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_TOCDEPTH);
- project = config.getString(CONFIG_PROJECT);
+ project = config->getString(CONFIG_PROJECT);
- projectDescription = config.getString(CONFIG_DESCRIPTION);
+ projectDescription = config->getString(CONFIG_DESCRIPTION);
if (projectDescription.isEmpty() && !project.isEmpty())
projectDescription = project + QLatin1String(" Reference Documentation");
- projectUrl = config.getString(CONFIG_URL);
- tagFile_ = config.getString(CONFIG_TAGFILE);
+ projectUrl = config->getString(CONFIG_URL);
+ tagFile_ = config->getString(CONFIG_TAGFILE);
#ifndef QT_NO_TEXTCODEC
- outputEncoding = config.getString(CONFIG_OUTPUTENCODING);
+ outputEncoding = config->getString(CONFIG_OUTPUTENCODING);
if (outputEncoding.isEmpty())
outputEncoding = QLatin1String("UTF-8");
outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit());
#endif
- naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE);
+ naturalLanguage = config->getString(CONFIG_NATURALLANGUAGE);
if (naturalLanguage.isEmpty())
naturalLanguage = QLatin1String("en");
- const QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
+ const QSet<QString> editionNames = config->subVars(CONFIG_EDITION);
for (const auto &editionName : editionNames) {
- QStringList editionModules = config.getStringList(CONFIG_EDITION + Config::dot + editionName
- + Config::dot + "modules");
- QStringList editionGroups = config.getStringList(CONFIG_EDITION + Config::dot + editionName
- + Config::dot + "groups");
+ QStringList editionModules = config->getStringList(CONFIG_EDITION + Config::dot
+ + editionName + Config::dot + "modules");
+ QStringList editionGroups = config->getStringList(CONFIG_EDITION + Config::dot + editionName
+ + Config::dot + "groups");
if (!editionModules.isEmpty())
editionModuleMap[editionName] = editionModules;
@@ -195,52 +198,54 @@ void HtmlGenerator::initializeGenerator(const Config &config)
editionGroupMap[editionName] = editionGroups;
}
- codeIndent = config.getInt(CONFIG_CODEINDENT); // QTBUG-27798
- codePrefix = config.getString(CONFIG_CODEPREFIX);
- codeSuffix = config.getString(CONFIG_CODESUFFIX);
+ codeIndent = config->getInt(CONFIG_CODEINDENT); // QTBUG-27798
+ codePrefix = config->getString(CONFIG_CODEPREFIX);
+ codeSuffix = config->getString(CONFIG_CODESUFFIX);
/*
The help file write should be allocated once and only once
per qdoc execution.
*/
if (helpProjectWriter)
- helpProjectWriter->reset(config, project.toLower() + ".qhp", this);
+ helpProjectWriter->reset(project.toLower() + ".qhp", this);
else
- helpProjectWriter = new HelpProjectWriter(config, project.toLower() + ".qhp", this);
+ helpProjectWriter = new HelpProjectWriter(project.toLower() + ".qhp", this);
// Documentation template handling
- headerScripts = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSCRIPTS);
- headerStyles = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSTYLES);
+ headerScripts = config->getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSCRIPTS);
+ headerStyles = config->getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSTYLES);
QString prefix = CONFIG_QHP + Config::dot + project + Config::dot;
manifestDir =
- QLatin1String("qthelp://") + config.getString(prefix + QLatin1String("namespace"));
- manifestDir += QLatin1Char('/') + config.getString(prefix + QLatin1String("virtualFolder"))
+ QLatin1String("qthelp://") + config->getString(prefix + QLatin1String("namespace"));
+ manifestDir += QLatin1Char('/') + config->getString(prefix + QLatin1String("virtualFolder"))
+ QLatin1Char('/');
- readManifestMetaContent(config);
- examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH);
+ readManifestMetaContent();
+ examplesPath = config->getString(CONFIG_EXAMPLESINSTALLPATH);
+ if (!examplesPath.isEmpty())
+ examplesPath += QLatin1Char('/');
// Retrieve the config for the navigation bar
- homepage = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_HOMEPAGE);
+ homepage = config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_HOMEPAGE);
- hometitle = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_HOMETITLE, homepage);
+ hometitle = config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_HOMETITLE, homepage);
- landingpage = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_LANDINGPAGE);
+ landingpage = config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_LANDINGPAGE);
landingtitle =
- config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_LANDINGTITLE, landingpage);
+ config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_LANDINGTITLE, landingpage);
- cppclassespage = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_CPPCLASSESPAGE);
+ cppclassespage = config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_CPPCLASSESPAGE);
- cppclassestitle = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_CPPCLASSESTITLE,
- QLatin1String("C++ Classes"));
+ cppclassestitle = config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_CPPCLASSESTITLE,
+ QLatin1String("C++ Classes"));
- qmltypespage = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_QMLTYPESPAGE);
+ qmltypespage = config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_QMLTYPESPAGE);
- qmltypestitle = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_QMLTYPESTITLE,
- QLatin1String("QML Types"));
+ qmltypestitle = config->getString(CONFIG_NAVIGATION + Config::dot + CONFIG_QMLTYPESTITLE,
+ QLatin1String("QML Types"));
- buildversion = config.getString(CONFIG_BUILDVERSION);
+ buildversion = config->getString(CONFIG_BUILDVERSION);
}
/*!
@@ -280,19 +285,19 @@ void HtmlGenerator::generateDocs()
Node *qflags = qdb_->findClassNode(QStringList("QFlags"));
if (qflags)
qflagsHref_ = linkForNode(qflags, nullptr);
- if (!preparing())
+ if (!config->preparing())
Generator::generateDocs();
- if (Generator::generating() && Generator::writeQaPages())
+ if (config->generating() && config->getBool(CONFIG_WRITEQAPAGES))
generateQAPage();
- if (!generating()) {
+ if (!config->generating()) {
QString fileBase =
project.toLower().simplified().replace(QLatin1Char(' '), QLatin1Char('-'));
qdb_->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", projectUrl,
projectDescription, this);
}
- if (!preparing()) {
+ if (!config->preparing()) {
helpProjectWriter->generate();
generateManifestFiles();
/*
@@ -497,7 +502,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
if (link.isEmpty()) {
out() << protectEnc(atom->string());
} else {
- if (Generator::writeQaPages() && node && (atom->type() != Atom::NavAutoLink)) {
+ if (config->getBool(CONFIG_WRITEQAPAGES)
+ && node && (atom->type() != Atom::NavAutoLink)) {
QString text = atom->string();
QString target = qdb_->getNewLinkTarget(relative, node, outFileName(), text);
out() << "<a id=\"" << Doc::canonicalTitle(target)
@@ -823,7 +829,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
out() << formattingRightMap()[ATOM_FORMATTING_BOLD];
break;
case Atom::NoteRight:
- out() << "</p>";
+ out() << "</p>\n";
break;
case Atom::LegaleseLeft:
out() << "<div class=\"LegaleseLeft\">";
@@ -841,13 +847,13 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
QString link = getLink(atom, relative, &node);
if (link.isEmpty() && (node != relative) && !noLinkErrors()) {
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
- if (Generator::writeQaPages() && (atom->type() != Atom::NavAutoLink)) {
+ if (config->getBool(CONFIG_WRITEQAPAGES) && (atom->type() != Atom::NavAutoLink)) {
QString text = atom->next()->next()->string();
QString target = qdb_->getNewLinkTarget(relative, node, outFileName(), text, true);
out() << "<a id=\"" << Doc::canonicalTitle(target) << "\" class=\"qa-mark\"></a>";
}
} else {
- if (Generator::writeQaPages() && node && (atom->type() != Atom::NavLink)) {
+ if (config->getBool(CONFIG_WRITEQAPAGES) && node && (atom->type() != Atom::NavLink)) {
QString text = atom->next()->next()->string();
QString target = qdb_->getNewLinkTarget(relative, node, outFileName(), text);
out() << "<a id=\"" << Doc::canonicalTitle(target) << "\" class=\"qa-mark\"></a>";
@@ -1167,6 +1173,7 @@ void HtmlGenerator::generateCppReferencePage(Aggregate *aggregate, CodeMarker *m
Sections sections(aggregate);
QString word = aggregate->typeWord(true);
+ QString templateDecl = aggregate->templateDecl();
if (aggregate->isNamespace()) {
rawTitle = aggregate->plainName();
fullTitle = aggregate->plainFullName();
@@ -1177,11 +1184,7 @@ void HtmlGenerator::generateCppReferencePage(Aggregate *aggregate, CodeMarker *m
} else if (aggregate->isClassNode()) {
rawTitle = aggregate->plainName();
fullTitle = aggregate->plainFullName();
- if (aggregate->isStruct())
- word = QLatin1String("Struct");
- else if (aggregate->isUnion())
- word = QLatin1String("Union");
- title = rawTitle + " " + word;
+ title = rawTitle + QLatin1Char(' ') + word;
summarySections = &sections.stdCppClassSummarySections();
detailsSections = &sections.stdCppClassDetailsSections();
} else if (aggregate->isHeader()) {
@@ -1191,14 +1194,22 @@ void HtmlGenerator::generateCppReferencePage(Aggregate *aggregate, CodeMarker *m
}
Text subtitleText;
- if (rawTitle != fullTitle) {
- if (aggregate->parent()->isClassNode()) {
- QString word2 = aggregate->parent()->typeWord(false);
- subtitleText << word << " " << rawTitle << " is declared in " << word2 << " "
- << Atom(Atom::AutoLink, aggregate->parent()->plainName()) << "."
- << Atom(Atom::LineBreak);
+ if (rawTitle != fullTitle || !templateDecl.isEmpty()) {
+ if (aggregate->isClassNode()) {
+ if (!templateDecl.isEmpty())
+ subtitleText << templateDecl + QLatin1Char(' ');
+ subtitleText << aggregate->typeWord(false) + QLatin1Char(' ');
+ const QStringList ancestors = fullTitle.split(QLatin1String("::"));
+ for (const auto &a : ancestors) {
+ if (a == rawTitle) {
+ subtitleText << a;
+ break;
+ } else {
+ subtitleText << Atom(Atom::AutoLink, a) << "::";
+ }
+ }
} else {
- subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")" << Atom(Atom::LineBreak);
+ subtitleText << fullTitle;
}
}
@@ -1639,23 +1650,24 @@ void HtmlGenerator::generateCollectionNode(CollectionNode *cn, CodeMarker *marke
generateStatus(cn, marker);
generateSince(cn, marker);
- NodeMultiMap nmm;
- cn->getMemberNamespaces(nmm);
- if (!nmm.isEmpty()) {
- ref = registerRef("namespaces");
- out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n';
- out() << "<h2 id=\"" << ref << "\">Namespaces</h2>\n";
- generateAnnotatedList(cn, marker, nmm);
- }
- nmm.clear();
- cn->getMemberClasses(nmm);
- if (!nmm.isEmpty()) {
- ref = registerRef("classes");
- out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n';
- out() << "<h2 id=\"" << ref << "\">Classes</h2>\n";
- generateAnnotatedList(cn, marker, nmm);
+ if (!cn->noAutoList()) {
+ NodeMultiMap nmm;
+ cn->getMemberNamespaces(nmm);
+ if (!nmm.isEmpty()) {
+ ref = registerRef("namespaces");
+ out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n';
+ out() << "<h2 id=\"" << ref << "\">Namespaces</h2>\n";
+ generateAnnotatedList(cn, marker, nmm);
+ }
+ nmm.clear();
+ cn->getMemberClasses(nmm);
+ if (!nmm.isEmpty()) {
+ ref = registerRef("classes");
+ out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n';
+ out() << "<h2 id=\"" << ref << "\">Classes</h2>\n";
+ generateAnnotatedList(cn, marker, nmm);
+ }
}
- nmm.clear();
}
Text brief = cn->doc().briefText();
@@ -2124,24 +2136,25 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker)
// add the module name and version to the map
QString logicalModuleVersion;
- const CollectionNode *collection =
- qdb_->getCollectionNode(qcn->logicalModuleName(), qcn->nodeType());
- if (collection != nullptr)
- logicalModuleVersion = collection->logicalModuleVersion();
- else
- logicalModuleVersion = qcn->logicalModuleVersion();
+ const CollectionNode *collection = qcn->logicalModule();
- if (logicalModuleVersion.isEmpty() || qcn->logicalModuleName().isEmpty())
- qcn->doc().location().warning(tr("Could not resolve QML import "
- "statement for type '%1'")
- .arg(qcn->name()),
- tr("Maybe you forgot to use the "
- "'\\%1' command?")
- .arg(COMMAND_INQMLMODULE));
+ // skip import statement of \internal collections
+ if (!collection || !collection->isInternal() || showInternal_) {
+ logicalModuleVersion =
+ collection ? collection->logicalModuleVersion() : qcn->logicalModuleVersion();
- text.clear();
- text << "import " + qcn->logicalModuleName() + QLatin1Char(' ') + logicalModuleVersion;
- requisites.insert(importText, text);
+ if (logicalModuleVersion.isEmpty() || qcn->logicalModuleName().isEmpty())
+ qcn->doc().location().warning(tr("Could not resolve QML import "
+ "statement for type '%1'")
+ .arg(qcn->name()),
+ tr("Maybe you forgot to use the "
+ "'\\%1' command?")
+ .arg(COMMAND_INQMLMODULE));
+
+ text.clear();
+ text << "import " + qcn->logicalModuleName() + QLatin1Char(' ') + logicalModuleVersion;
+ requisites.insert(importText, text);
+ }
// add the since and project into the map
if (!qcn->since().isEmpty()) {
@@ -2269,13 +2282,15 @@ void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker
out() << "<ul>\n";
if (node->isModule()) {
- if (node->hasNamespaces()) {
- out() << "<li class=\"level" << sectionNumber << "\"><a href=\"#"
- << registerRef("namespaces") << "\">Namespaces</a></li>\n";
- }
- if (node->hasClasses()) {
- out() << "<li class=\"level" << sectionNumber << "\"><a href=\"#"
- << registerRef("classes") << "\">Classes</a></li>\n";
+ if (!static_cast<const CollectionNode *>(node)->noAutoList()) {
+ if (node->hasNamespaces()) {
+ out() << "<li class=\"level" << sectionNumber << "\"><a href=\"#"
+ << registerRef("namespaces") << "\">Namespaces</a></li>\n";
+ }
+ if (node->hasClasses()) {
+ out() << "<li class=\"level" << sectionNumber << "\"><a href=\"#"
+ << registerRef("classes") << "\">Classes</a></li>\n";
+ }
}
out() << "<li class=\"level" << sectionNumber << "\"><a href=\"#" << registerRef("details")
<< "\">Detailed Description</a></li>\n";
@@ -2906,8 +2921,7 @@ void HtmlGenerator::generateQmlItem(const Node *node, const Node *relative, Code
// Look for the _ character in the member name followed by a number (or n):
// this is intended to be rendered as a subscript.
- marked.replace(QRegExp("<@param>([a-z]+)_([0-9]+|n)</@param>"),
- "<i>\\1<sub>\\2</sub></i>");
+ marked.replace(QRegExp("<@param>([a-z]+)_([0-9]+|n)</@param>"), "<i>\\1<sub>\\2</sub></i>");
// Replace some markup by HTML tags. Do both the opening and the closing tag
// in one go (instead of <@param> and </@param> separately, for instance).
@@ -3103,10 +3117,12 @@ void HtmlGenerator::generateSectionList(const Section &section, const Node *rela
if (twoColumn)
out() << "</td></tr>\n</table></div>\n";
}
- if (hasPrivateSignals && alignNames)
- generatePrivateSignalNote(relative, marker);
- if (isInvokable && alignNames)
- generateInvokableNote(relative, marker);
+ if (alignNames) {
+ if (hasPrivateSignals)
+ generateAddendum(relative, Generator::PrivateSignal, marker);
+ if (isInvokable)
+ generateAddendum(relative, Generator::Invokable, marker);
+ }
}
if (status != Section::Obsolete && section.style() == Section::Summary
@@ -3491,13 +3507,6 @@ void HtmlGenerator::generateDetailedMember(const Node *node, const PageNode *rel
out() << "<p><b>Notifier signal:</b></p>\n";
generateSectionList(notifiers, node, marker);
}
- } else if (node->isFunction()) {
- const FunctionNode *fn = static_cast<const FunctionNode *>(node);
- if (fn->isPrivateSignal())
- generatePrivateSignalNote(node, marker);
- if (fn->isInvokable())
- generateInvokableNote(node, marker);
- generateAssociatedPropertyNotes(const_cast<FunctionNode *>(fn));
} else if (node->isEnumType()) {
const EnumNode *etn = static_cast<const EnumNode *>(node);
if (etn->flagsType()) {
@@ -3910,33 +3919,9 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString
writer.writeAttribute("name", en->title());
QString docUrl = manifestDir + fileBase(en) + ".html";
writer.writeAttribute("docUrl", docUrl);
- QStringList proFiles;
const auto exampleFiles = en->files();
- for (const QString &file : exampleFiles) {
- if (file.endsWith(".pro") || file.endsWith(".qmlproject")
- || file.endsWith(".pyproject"))
- proFiles << file;
- }
- if (!proFiles.isEmpty()) {
- if (proFiles.size() == 1) {
- writer.writeAttribute("projectPath", installPath + proFiles[0]);
- } else {
- QString exampleName = en->name().split('/').last();
- bool proWithExampleNameFound = false;
- for (int j = 0; j < proFiles.size(); j++) {
- if (proFiles[j].endsWith(QStringLiteral("%1/%1.pro").arg(exampleName))
- || proFiles[j].endsWith(QStringLiteral("%1/%1.qmlproject").arg(exampleName))
- || proFiles[j].endsWith(
- QStringLiteral("%1/%1.pyproject").arg(exampleName))) {
- writer.writeAttribute("projectPath", installPath + proFiles[j]);
- proWithExampleNameFound = true;
- break;
- }
- }
- if (!proWithExampleNameFound)
- writer.writeAttribute("projectPath", installPath + proFiles[0]);
- }
- }
+ if (!en->projectFile().isEmpty())
+ writer.writeAttribute("projectPath", installPath + en->projectFile());
if (!en->imageFileName().isEmpty()) {
writer.writeAttribute("imageUrl", manifestDir + en->imageFileName());
usedAttributes << "imageUrl";
@@ -4093,8 +4078,9 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString
The manifest metacontent map is cleared immediately after
the manifest files have been generated.
*/
-void HtmlGenerator::readManifestMetaContent(const Config &config)
+void HtmlGenerator::readManifestMetaContent()
{
+ Config &config = Config::instance();
const QStringList names =
config.getStringList(CONFIG_MANIFESTMETA + Config::dot + QStringLiteral("filters"));
@@ -4199,40 +4185,4 @@ QXmlStreamWriter &HtmlGenerator::xmlWriter()
return *xmlWriterStack.top();
}
-/*!
- Generates bold Note lines that explain how function \a fn
- is associated with each of its associated properties.
- */
-void HtmlGenerator::generateAssociatedPropertyNotes(FunctionNode *fn)
-{
- if (fn->hasAssociatedProperties()) {
- out() << "<p><b>Note:</b> ";
- NodeList &nodes = fn->associatedProperties();
- std::sort(nodes.begin(), nodes.end(), Node::nodeNameLessThan);
- for (const auto *node : qAsConst(nodes)) {
- QString msg;
- const PropertyNode *pn = static_cast<const PropertyNode *>(node);
- switch (pn->role(fn)) {
- case PropertyNode::Getter:
- msg = QStringLiteral("Getter function ");
- break;
- case PropertyNode::Setter:
- msg = QStringLiteral("Setter function ");
- break;
- case PropertyNode::Resetter:
- msg = QStringLiteral("Resetter function ");
- break;
- case PropertyNode::Notifier:
- msg = QStringLiteral("Notifier signal ");
- break;
- default:
- break;
- }
- QString link = linkForNode(pn, nullptr);
- out() << msg << "for property <a href=\"" << link << "\">" << pn->name() << "</a>. ";
- }
- out() << "</p>";
- }
-}
-
QT_END_NAMESPACE
diff --git a/src/qdoc/htmlgenerator.h b/src/qdoc/htmlgenerator.h
index 1e3c46ef3..c1a47ba33 100644
--- a/src/qdoc/htmlgenerator.h
+++ b/src/qdoc/htmlgenerator.h
@@ -34,7 +34,6 @@
#define HTMLGENERATOR_H
#include "codemarker.h"
-#include "config.h"
#include "xmlgenerator.h"
#include <QtCore/qhash.h>
@@ -43,6 +42,7 @@
QT_BEGIN_NAMESPACE
+class Config;
class HelpProjectWriter;
class HtmlGenerator : public XmlGenerator
@@ -54,7 +54,7 @@ public:
HtmlGenerator();
~HtmlGenerator() override;
- void initializeGenerator(const Config &config) override;
+ void initializeGenerator() override;
void terminateGenerator() override;
QString format() override;
void generateDocs() override;
@@ -79,9 +79,8 @@ protected:
QString fileExtension() const override;
void generateManifestFile(const QString &manifest, const QString &element);
- void readManifestMetaContent(const Config &config);
+ void readManifestMetaContent();
void generateKeywordAnchors(const Node *node);
- void generateAssociatedPropertyNotes(FunctionNode *fn);
private:
enum SubTitleSize { SmallSubTitle, LargeSubTitle };
@@ -201,6 +200,8 @@ private:
QString qflagsHref_;
int tocDepth;
+ Config *config;
+
public:
static bool debugging_on;
static QString divNavTop;
diff --git a/src/qdoc/jscodemarker.cpp b/src/qdoc/jscodemarker.cpp
index d9ac99d6d..b3c675d5b 100644
--- a/src/qdoc/jscodemarker.cpp
+++ b/src/qdoc/jscodemarker.cpp
@@ -63,7 +63,7 @@ bool JsCodeMarker::recognizeCode(const QString &code)
QQmlJS::Parser parser(&engine);
QString newCode = code;
- QVector<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode);
+ QVector<QQmlJS::SourceLocation> pragmas = extractPragmas(newCode);
lexer.setCode(newCode, 1);
return parser.parseProgram();
@@ -112,7 +112,7 @@ QString JsCodeMarker::addMarkUp(const QString &code, const Node * /* relative */
QQmlJS::Lexer lexer(&engine);
QString newCode = code;
- QVector<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode);
+ QVector<QQmlJS::SourceLocation> pragmas = extractPragmas(newCode);
lexer.setCode(newCode, 1);
QQmlJS::Parser parser(&engine);
diff --git a/src/qdoc/location.cpp b/src/qdoc/location.cpp
index dc378b1d1..a63b1780e 100644
--- a/src/qdoc/location.cpp
+++ b/src/qdoc/location.cpp
@@ -48,7 +48,6 @@ int Location::warningLimit = -1;
QString Location::programName;
QString Location::project;
QRegExp *Location::spuriousRegExp = nullptr;
-bool Location::logProgress_ = false;
/*!
\class Location
@@ -256,7 +255,8 @@ QString Location::canonicalRelativePath(const QString &path)
*/
void Location::warning(const QString &message, const QString &details) const
{
- if (!Generator::preparing() || Generator::singleExec())
+ const auto &config = Config::instance();
+ if (!config.preparing() || config.singleExec())
emitMessage(Warning, message, details);
}
@@ -267,7 +267,8 @@ void Location::warning(const QString &message, const QString &details) const
*/
void Location::error(const QString &message, const QString &details) const
{
- if (!Generator::preparing() || Generator::singleExec())
+ const auto &config = Config::instance();
+ if (!config.preparing() || config.singleExec())
emitMessage(Error, message, details);
}
@@ -313,13 +314,14 @@ void Location::report(const QString &message, const QString &details) const
}
/*!
- Gets several parameters from the \a config, including
+ Gets several parameters from the config, including
tab size, program name, and a regular expression that
appears to be used for matching certain error messages
so that emitMessage() can avoid printing them.
*/
-void Location::initialize(const Config &config)
+void Location::initialize()
{
+ Config &config = Config::instance();
tabSize = config.getInt(CONFIG_TABSIZE);
programName = config.programName();
project = config.getString(CONFIG_PROJECT);
@@ -357,34 +359,6 @@ void Location::information(const QString &message)
}
/*!
- Prints \a message to \c stderr followed by a \c{'\n'},
- but only if the -log-progress option is set.
- */
-void Location::logToStdErr(const QString &message)
-{
- if (logProgress_) {
- fprintf(stderr, "LOG: %s\n", message.toLatin1().data());
- fflush(stderr);
- }
-}
-
-/*!
- Always prints the current time and \a message to \c stderr
- followed by a \c{'\n'}.
- */
-void Location::logToStdErrAlways(const QString &message)
-{
- if (Generator::useTimestamps()) {
- QTime t = QTime::currentTime();
- fprintf(stderr, "%s LOG: %s\n", t.toString().toLatin1().constData(),
- message.toLatin1().data());
- } else {
- fprintf(stderr, "LOG: %s\n", message.toLatin1().constData());
- }
- fflush(stderr);
-}
-
-/*!
Report a program bug, including the \a hint.
*/
void Location::internalError(const QString &hint)
diff --git a/src/qdoc/location.h b/src/qdoc/location.h
index fb35038a8..68ab28845 100644
--- a/src/qdoc/location.h
+++ b/src/qdoc/location.h
@@ -38,7 +38,6 @@
QT_BEGIN_NAMESPACE
-class Config;
class QRegExp;
class Location
@@ -80,14 +79,11 @@ public:
void fatal(const QString &message, const QString &details = QString()) const;
void report(const QString &message, const QString &details = QString()) const;
- static void initialize(const Config &config);
+ static void initialize();
+
static void terminate();
static void information(const QString &message);
static void internalError(const QString &hint);
- static void logToStdErr(const QString &message);
- static void logToStdErrAlways(const QString &message);
- static void startLoggingProgress() { logProgress_ = true; }
- static void stopLoggingProgress() { logProgress_ = false; }
static QString canonicalRelativePath(const QString &path);
static int exitCode();
@@ -119,7 +115,6 @@ private:
static QString programName;
static QString project;
static QRegExp *spuriousRegExp;
- static bool logProgress_;
};
Q_DECLARE_TYPEINFO(Location::StackEntry, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(Location, Q_COMPLEX_TYPE); // stkTop = &stkBottom
diff --git a/src/qdoc/main.cpp b/src/qdoc/main.cpp
index 72259d4e3..29ba75d7a 100644
--- a/src/qdoc/main.cpp
+++ b/src/qdoc/main.cpp
@@ -34,6 +34,7 @@
#include "cppcodeparser.h"
#include "doc.h"
#include "htmlgenerator.h"
+#include "docbookgenerator.h"
#include "jscodemarker.h"
#include "location.h"
#include "loggingcategory.h"
@@ -87,8 +88,9 @@ static ClangCodeParser *clangParser_ = nullptr;
a list of output formats; each format may have a different
output subdirectory where index files are located.
*/
-static void loadIndexFiles(Config &config, const QSet<QString> &formats)
+static void loadIndexFiles(const QSet<QString> &formats)
{
+ Config &config = Config::instance();
QDocDatabase *qdb = QDocDatabase::qdocDB();
QStringList indexFiles;
const QStringList configIndexes = config.getStringList(CONFIG_INDEXES);
@@ -158,9 +160,9 @@ static void loadIndexFiles(Config &config, const QSet<QString> &formats)
// Remove self-dependencies and possible duplicates
config.dependModules().removeAll(config.getString(CONFIG_PROJECT).toLower());
config.dependModules().removeDuplicates();
- Location::logToStdErrAlways(QString("qdocconf file has depends = *;"
- " loading all %1 index files found")
- .arg(config.dependModules().count()));
+ qCCritical(lcQdoc) << "qdocconf file has depends = *; loading all "
+ << config.dependModules().count()
+ << " index files found";
}
for (const auto &module : config.dependModules()) {
QVector<QFileInfo> foundIndices;
@@ -235,13 +237,13 @@ void logStartEndMessage(const QLatin1String &startStop, const Config &config)
const QString runName = " qdoc for "
+ config.getString(CONFIG_PROJECT)
+ QLatin1String(" in ")
- + QLatin1String(Generator::singleExec() ? "single" : "dual")
- + QLatin1String(" process mode, (")
- + QLatin1String(Generator::preparing() ? "prepare" : "generate")
- + QLatin1String(" phase)");
+ + QLatin1String(config.singleExec() ? "single" : "dual")
+ + QLatin1String(" process mode: ")
+ + QLatin1String(config.preparing() ? "prepare" : "generate")
+ + QLatin1String(" phase.");
const QString msg = startStop + runName;
- Location::logToStdErrAlways(msg);
+ qCInfo(lcQdoc) << msg.toUtf8().data();
}
/*!
@@ -249,8 +251,9 @@ void logStartEndMessage(const QLatin1String &startStop, const Config &config)
of QDoc. The \a config instance represents the configuration data for QDoc.
All other classes are initialized with the same config.
*/
-static void processQdocconfFile(const QString &fileName, Config &config)
+static void processQdocconfFile(const QString &fileName)
{
+ Config &config = Config::instance();
config.setPreviousCurrentDir(QDir::currentPath());
/*
@@ -262,12 +265,11 @@ static void processQdocconfFile(const QString &fileName, Config &config)
in the file being processed, mainly for error reporting
purposes.
*/
- Location::initialize(config);
+ Location::initialize();
config.load(fileName);
QString project = config.getString(CONFIG_PROJECT);
if (project.isEmpty()) {
- Location::logToStdErrAlways(
- QLatin1String("qdoc can't run; no project set in qdocconf file"));
+ qCCritical(lcQdoc) << QLatin1String("qdoc can't run; no project set in qdocconf file");
exit(1);
}
Location::terminate();
@@ -290,12 +292,12 @@ static void processQdocconfFile(const QString &fileName, Config &config)
are either cleared after they have been used, or they
are cleared in the terminate() functions below.
*/
- Location::initialize(config);
- Tokenizer::initialize(config);
- CodeMarker::initialize(config);
- CodeParser::initialize(config);
- Generator::initialize(config);
- Doc::initialize(config);
+ Location::initialize();
+ Tokenizer::initialize();
+ CodeMarker::initialize();
+ CodeParser::initialize();
+ Generator::initialize();
+ Doc::initialize();
#ifndef QT_NO_TRANSLATION
/*
@@ -356,14 +358,14 @@ static void processQdocconfFile(const QString &fileName, Config &config)
Location outputFormatsLocation = config.lastLocation();
qdb->clearSearchOrder();
- if (!Generator::singleExec()) {
- if (!Generator::preparing()) {
+ if (!config.singleExec()) {
+ if (!config.preparing()) {
qCDebug(lcQdoc, " loading index files");
- loadIndexFiles(config, outputFormats);
+ loadIndexFiles(outputFormats);
qCDebug(lcQdoc, " done loading index files");
}
qdb->newPrimaryTree(project);
- } else if (Generator::preparing())
+ } else if (config.preparing())
qdb->newPrimaryTree(project);
else
qdb->setPrimaryTree(project);
@@ -407,7 +409,7 @@ static void processQdocconfFile(const QString &fileName, Config &config)
}
Generator::augmentImageDirs(exampleImageDirs);
- if (Generator::dualExec() || Generator::preparing()) {
+ if (config.dualExec() || config.preparing()) {
QStringList headerList;
QStringList sourceList;
@@ -476,7 +478,7 @@ static void processQdocconfFile(const QString &fileName, Config &config)
add it to the big tree.
*/
parsed = 0;
- Location::logToStdErrAlways("Parse source files for " + project);
+ qCInfo(lcQdoc) << "Parse source files for" << project;
for (const auto &key : sources.keys()) {
auto *codeParser = CodeParser::parserForSourceFile(key);
if (codeParser) {
@@ -485,7 +487,7 @@ static void processQdocconfFile(const QString &fileName, Config &config)
codeParser->parseSourceFile(config.location(), key);
}
}
- Location::logToStdErrAlways("Source files parsed for " + project);
+ qCInfo(lcQdoc) << "Source files parsed for" << project;
}
/*
Now the primary tree has been built from all the header and
@@ -508,7 +510,7 @@ static void processQdocconfFile(const QString &fileName, Config &config)
if (generator == nullptr)
outputFormatsLocation.fatal(
QCoreApplication::translate("QDoc", "Unknown output format '%1'").arg(format));
- generator->initializeFormat(config);
+ generator->initializeFormat();
generator->generateDocs();
}
qdb->clearLinkCounts();
@@ -570,8 +572,10 @@ int main(int argc, char **argv)
HtmlGenerator htmlGenerator;
WebXMLGenerator webXMLGenerator;
+ DocBookGenerator docBookGenerator;
- Config config(QCoreApplication::translate("QDoc", "qdoc"), app.arguments());
+ Config::instance().init(QCoreApplication::translate("QDoc", "qdoc"), app.arguments());
+ Config &config = Config::instance();
// Get the list of files to act on:
QStringList qdocFiles = config.qdocFiles();
@@ -581,24 +585,24 @@ int main(int argc, char **argv)
if (config.singleExec())
qdocFiles = Config::loadMaster(qdocFiles.at(0));
- if (Generator::singleExec()) {
+ if (config.singleExec()) {
// single qdoc process for prepare and generate phases
- Generator::setQDocPass(Generator::Prepare);
+ config.setQDocPass(Config::Prepare);
for (const auto &file : qAsConst(qdocFiles)) {
config.dependModules().clear();
- processQdocconfFile(file, config);
+ processQdocconfFile(file);
}
- Generator::setQDocPass(Generator::Generate);
+ config.setQDocPass(Config::Generate);
QDocDatabase::qdocDB()->processForest();
for (const auto &file : qAsConst(qdocFiles)) {
config.dependModules().clear();
- processQdocconfFile(file, config);
+ processQdocconfFile(file);
}
} else {
// separate qdoc processes for prepare and generate phases
for (const auto &file : qAsConst(qdocFiles)) {
config.dependModules().clear();
- processQdocconfFile(file, config);
+ processQdocconfFile(file);
}
}
diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp
index 3e43c5644..634cce3ec 100644
--- a/src/qdoc/node.cpp
+++ b/src/qdoc/node.cpp
@@ -29,6 +29,7 @@
#include "node.h"
#include "codemarker.h"
+#include "config.h"
#include "cppcodeparser.h"
#include "generator.h"
#include "puredocparser.h"
@@ -38,6 +39,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/quuid.h>
+#include <QtCore/qversionnumber.h>
#include <algorithm>
@@ -598,25 +600,24 @@ QString Node::plainName() const
/*!
Constructs and returns the node's fully qualified name by
recursively ascending the parent links and prepending each
- parent name + "::". Breaks out when the parent pointer is
- \a relative. Almost all calls to this function pass 0 for
- \a relative.
+ parent name + "::". Breaks out when reaching a HeaderNode,
+ or when the parent pointer is \a relative. Typically, calls
+ to this function pass \c nullptr for \a relative.
*/
QString Node::plainFullName(const Node *relative) const
{
if (name_.isEmpty())
return QLatin1String("global");
- QString fullName;
+ QStringList parts;
const Node *node = this;
- while (node) {
- fullName.prepend(node->plainName());
+ while (node && !node->isHeader()) {
+ parts.prepend(node->plainName());
if (node->parent() == relative || node->parent()->name().isEmpty())
break;
- fullName.prepend(QLatin1String("::"));
node = node->parent();
}
- return fullName;
+ return parts.join(QLatin1String("::"));
}
/*!
@@ -1048,12 +1049,24 @@ void Node::setLink(LinkType linkType, const QString &link, const QString &desc)
/*!
Sets the information about the project and version a node was introduced
- in. The string is simplified, removing excess whitespace before being
- stored.
+ in, unless the version is lower than the 'ignoresince.<project>'
+ configuration variable.
*/
void Node::setSince(const QString &since)
{
- since_ = since.simplified();
+ QStringList parts = since.split(QLatin1Char(' '));
+ QString project;
+ if (parts.size() > 1)
+ project = Config::dot + parts.first();
+
+ QVersionNumber cutoff =
+ QVersionNumber::fromString(Config::instance().getString(CONFIG_IGNORESINCE + project))
+ .normalized();
+
+ if (!cutoff.isNull() && QVersionNumber::fromString(parts.last()).normalized() < cutoff)
+ return;
+
+ since_ = parts.join(QLatin1Char(' '));
}
/*!
@@ -1473,11 +1486,13 @@ QString Node::physicalModuleName() const
\sa PageType
*/
-/*! \fn QString Node::signature(bool values, bool noReturnType) const
+/*! \fn QString Node::signature(bool values, bool noReturnType, bool templateParams) const
If this node is a FunctionNode, this function returns the function's
- signature, including default values if \a values is \c true, and
- including the function's return type if \a noReturnType is \c false.
+ signature, including default values if \a values is \c true,
+ function's return type if \a noReturnType is \c false, and
+ prefixed with 'template <parameter_list>' for function templates
+ if templateParams is \true.
If this node is not a FunctionNode, this function returns plainName().
*/
@@ -1807,12 +1822,6 @@ QString Node::physicalModuleName() const
Returns the node's reconstituted brief data member.
*/
-/*! \fn void Node::addPageKeywords(const QString &t)
- If this is a PageNode, the function appends the string \a t
- to the page keywords data member. Otherwise the function does
- nothing.
- */
-
/*! \fn bool Node::isSharingComment() const
This function returns \c true if the node is sharing a comment
with other nodes. For example, multiple functions can be documented
@@ -2368,7 +2377,7 @@ void Aggregate::adoptFunction(FunctionNode *fn)
*/
void Aggregate::addChildByTitle(Node *child, const QString &title)
{
- nonfunctionMap_.insertMulti(title, child);
+ nonfunctionMap_.insert(title, child);
}
/*!
@@ -2400,7 +2409,7 @@ void Aggregate::addChild(Node *child)
if (child->isFunction()) {
addFunction(static_cast<FunctionNode *>(child));
} else if (!child->name().isEmpty()) {
- nonfunctionMap_.insertMulti(child->name(), child);
+ nonfunctionMap_.insert(child->name(), child);
if (child->isEnumType())
enumChildren_.append(child);
}
@@ -2425,7 +2434,7 @@ void Aggregate::adoptChild(Node *child)
if (child->isFunction()) {
adoptFunction(static_cast<FunctionNode *>(child));
} else if (!child->name().isEmpty()) {
- nonfunctionMap_.insertMulti(child->name(), child);
+ nonfunctionMap_.insert(child->name(), child);
if (child->isEnumType())
enumChildren_.append(child);
}
@@ -2686,7 +2695,7 @@ void Aggregate::findAllObsoleteThings()
void Aggregate::findAllClasses()
{
for (auto *node : qAsConst(children_)) {
- if (!node->isPrivate() && !node->isInternal()
+ if (!node->isPrivate() && !node->isInternal() && !node->isDontDocument()
&& node->tree()->camelCaseModuleName() != QString("QDoc")) {
if (node->isClassNode()) {
QDocDatabase::cppClasses().insert(node->qualifyCppName().toLower(), node);
@@ -2718,7 +2727,7 @@ void Aggregate::findAllAttributions(NodeMultiMap &attributions)
for (auto *node : qAsConst(children_)) {
if (!node->isPrivate()) {
if (node->pageType() == Node::AttributionPage)
- attributions.insertMulti(node->tree()->indexTitle(), node);
+ attributions.insert(node->tree()->indexTitle(), node);
else if (node->isAggregate())
static_cast<Aggregate *>(node)->findAllAttributions(attributions);
}
@@ -2931,7 +2940,9 @@ void ClassNode::removePrivateAndInternalBases()
ClassNode *bc = bases_.at(i).node_;
if (bc == nullptr)
bc = QDocDatabase::qdocDB()->findClassNode(bases_.at(i).path_);
- if (bc != nullptr && (bc->isPrivate() || bc->isInternal() || found.contains(bc))) {
+ if (bc != nullptr
+ && (bc->isPrivate() || bc->isInternal() || bc->isDontDocument()
+ || found.contains(bc))) {
RelatedClass rc = bases_.at(i);
bases_.removeAt(i);
ignoredBases_.append(rc);
@@ -2945,7 +2956,7 @@ void ClassNode::removePrivateAndInternalBases()
i = 0;
while (i < derived_.size()) {
ClassNode *dc = derived_.at(i).node_;
- if (dc != nullptr && (dc->isPrivate() || dc->isInternal())) {
+ if (dc != nullptr && (dc->isPrivate() || dc->isInternal() || dc->isDontDocument())) {
derived_.removeAt(i);
const QVector<RelatedClass> &dd = dc->derivedClasses();
for (int j = dd.size() - 1; j >= 0; --j)
@@ -3644,14 +3655,6 @@ bool PageNode::setTitle(const QString &title)
Appends \a t to the list of group names.
*/
-/*! \fn const QStringList &PageNode::pageKeywords() const
- Returns a const reference to the list of keywords for this page.
- */
-
-/*! \fn void PageNode::addPageKeywords(const QString &t)
- Appends \a t to the keywords list.
- */
-
/*! \fn void PageNode::setOutputFileName(const QString &f)
Sets this PageNode's output file name to \a f.
*/
@@ -4229,27 +4232,35 @@ bool FunctionNode::isObsolete() const
/*!
Reconstructs and returns the function's signature. If \a values
- is true, the default values of the parameters are included, if
- present.
+ is \c true, the default values of the parameters are included.
+ The return type is included unless \a noReturnType is \c true.
+ Function templates are prefixed with \c {template <parameter_list>}
+ if \a templateParams is \c true.
*/
-QString FunctionNode::signature(bool values, bool noReturnType) const
+QString FunctionNode::signature(bool values, bool noReturnType, bool templateParams) const
{
- QString result;
- if (!noReturnType && !returnType().isEmpty())
- result = returnType() + QLatin1Char(' ');
- result += name();
+ QStringList elements;
+
+ if (templateParams)
+ elements << templateDecl();
+ if (!noReturnType)
+ elements << returnType_;
+ elements.removeAll({});
+
if (!isMacroWithoutParams()) {
- result += QLatin1Char('(') + parameters_.signature(values) + QLatin1Char(')');
- if (isMacro())
- return result;
+ elements << name() + QLatin1Char('(') + parameters_.signature(values) + QLatin1Char(')');
+ if (!isMacro()) {
+ if (isConst())
+ elements << QStringLiteral("const");
+ if (isRef())
+ elements << QStringLiteral("&");
+ else if (isRefRef())
+ elements << QStringLiteral("&&");
+ }
+ } else {
+ elements << name();
}
- if (isConst())
- result += " const";
- if (isRef())
- result += " &";
- else if (isRefRef())
- result += " &&";
- return result;
+ return elements.join(QLatin1Char(' '));
}
/*!
diff --git a/src/qdoc/node.h b/src/qdoc/node.h
index 345a20033..b7293f408 100644
--- a/src/qdoc/node.h
+++ b/src/qdoc/node.h
@@ -232,7 +232,7 @@ public:
QString plainFullName(const Node *relative = nullptr) const;
QString plainSignature() const;
QString fullName(const Node *relative = nullptr) const;
- virtual QString signature(bool, bool) const { return plainName(); }
+ virtual QString signature(bool, bool, bool = false) const { return plainName(); }
const QString &fileNameBase() const { return fileNameBase_; }
bool hasFileNameBase() const { return !fileNameBase_.isEmpty(); }
@@ -251,7 +251,7 @@ public:
void setSince(const QString &since);
void setPhysicalModuleName(const QString &name) { physicalModuleName_ = name; }
void setUrl(const QString &url) { url_ = url; }
- void setTemplateStuff(const QString &t) { templateStuff_ = t; }
+ void setTemplateDecl(const QString &t) { templateDecl_ = t; }
void setReconstitutedBrief(const QString &t) { reconstitutedBrief_ = t; }
void setParent(Aggregate *n) { parent_ = n; }
void setIndexNodeFlag(bool isIndexNode = true) { indexNodeFlag_ = isIndexNode; }
@@ -319,10 +319,9 @@ public:
ThreadSafeness threadSafeness() const;
ThreadSafeness inheritedThreadSafeness() const;
QString since() const { return since_; }
- QString templateStuff() const { return templateStuff_; }
+ const QString &templateDecl() const { return templateDecl_; }
const QString &reconstitutedBrief() const { return reconstitutedBrief_; }
QString nodeSubtypeString() const;
- virtual void addPageKeywords(const QString &) {}
bool isSharingComment() const { return (sharedCommentNode_ != nullptr); }
bool hasSharedDoc() const;
@@ -387,7 +386,7 @@ private:
QString physicalModuleName_;
QString url_;
QString since_;
- QString templateStuff_;
+ QString templateDecl_;
QString reconstitutedBrief_;
// mutable QString uuid_;
QString outSubDir_;
@@ -434,8 +433,6 @@ public:
const QStringList &groupNames() const { return groupNames_; }
void appendGroupName(const QString &t) override { groupNames_.append(t); }
- const QStringList &pageKeywords() const { return pageKeywds_; }
- void addPageKeywords(const QString &t) override { pageKeywds_ << t; }
void setOutputFileName(const QString &f) override { outputFileName_ = f; }
QString outputFileName() const override { return outputFileName_; }
@@ -448,7 +445,6 @@ protected:
QString subtitle_;
QString outputFileName_;
QStringList groupNames_;
- QStringList pageKeywds_;
};
class ExternalPageNode : public PageNode
@@ -532,7 +528,7 @@ protected:
private:
QStringList includeFiles_;
NodeList enumChildren_;
- NodeMap nonfunctionMap_;
+ NodeMultiMap nonfunctionMap_;
NodeList nonfunctionList_;
protected:
@@ -709,13 +705,19 @@ public:
void setImageFileName(const QString &ifn) override { imageFileName_ = ifn; }
const QStringList &files() const { return files_; }
const QStringList &images() const { return images_; }
- void setFiles(const QStringList files) { files_ = files; }
+ const QString &projectFile() const { return projectFile_; }
+ void setFiles(const QStringList files, const QString &projectFile)
+ {
+ files_ = files;
+ projectFile_ = projectFile;
+ }
void setImages(const QStringList images) { images_ = images; }
void appendFile(QString &file) { files_.append(file); }
void appendImage(QString &image) { images_.append(image); }
private:
QString imageFileName_;
+ QString projectFile_;
QStringList files_;
QStringList images_;
};
@@ -864,13 +866,15 @@ private:
class EnumNode : public Node
{
public:
- EnumNode(Aggregate *parent, const QString &name) : Node(Enum, parent, name), flagsType_(nullptr)
+ EnumNode(Aggregate *parent, const QString &name, bool isScoped = false)
+ : Node(Enum, parent, name), flagsType_(nullptr), isScoped_(isScoped)
{
}
void addItem(const EnumItem &item);
void setFlagsType(TypedefNode *typedeff);
bool hasItem(const QString &name) const { return names_.contains(name); }
+ bool isScoped() const { return isScoped_; }
const QVector<EnumItem> &items() const { return items_; }
Access itemAccess(const QString &name) const;
@@ -882,6 +886,7 @@ private:
QVector<EnumItem> items_;
QSet<QString> names_;
const TypedefNode *flagsType_;
+ bool isScoped_;
};
class TypedefNode : public Node
@@ -952,10 +957,7 @@ public:
n->setSharedCommentNode(this);
setGenus(n->genus());
}
- void sort()
- {
- std::sort(collective_.begin(), collective_.end(), Node::nodeNameLessThan);
- }
+ void sort() { std::sort(collective_.begin(), collective_.end(), Node::nodeNameLessThan); }
const QVector<Node *> &collective() const { return collective_; }
void setOverloadFlags();
void setRelatedNonmember(bool b) override;
@@ -1058,10 +1060,10 @@ public:
const Parameters &parameters() const { return parameters_; }
bool isPrivateSignal() const { return parameters_.isPrivateSignal(); }
void setParameters(const QString &signature) { parameters_.set(signature); }
- QString signature(bool values, bool noReturnType) const override;
+ QString signature(bool values, bool noReturnType, bool templateParams = false) const override;
const QString &overridesThis() const { return overridesThis_; }
- NodeList &associatedProperties() { return associatedProperties_; }
+ const NodeList &associatedProperties() const { return associatedProperties_; }
const QStringList &parentPath() const { return parentPath_; }
bool hasAssociatedProperties() const { return !associatedProperties_.isEmpty(); }
bool hasOneAssociatedProperty() const { return (associatedProperties_.size() == 1); }
diff --git a/src/qdoc/qdoc.pro b/src/qdoc/qdoc.pro
index c38c50b16..11a11b70f 100644
--- a/src/qdoc/qdoc.pro
+++ b/src/qdoc/qdoc.pro
@@ -39,6 +39,7 @@ HEADERS += atom.h \
cppcodemarker.h \
cppcodeparser.h \
doc.h \
+ docbookgenerator.h \
editdistance.h \
generator.h \
helpprojectwriter.h \
@@ -72,6 +73,7 @@ SOURCES += atom.cpp \
cppcodemarker.cpp \
cppcodeparser.cpp \
doc.cpp \
+ docbookgenerator.cpp \
editdistance.cpp \
generator.cpp \
helpprojectwriter.cpp \
diff --git a/src/qdoc/qdoccommandlineparser.cpp b/src/qdoc/qdoccommandlineparser.cpp
index 3bd01fae5..02e8977ff 100644
--- a/src/qdoc/qdoccommandlineparser.cpp
+++ b/src/qdoc/qdoccommandlineparser.cpp
@@ -62,7 +62,8 @@ QDocCommandLineParser::QDocCommandLineParser()
"path"),
frameworkOption("F", "Add macOS framework to the include path for header files.",
"framework"),
- timestampsOption(QStringList() << QStringLiteral("timestamps"))
+ timestampsOption(QStringList() << QStringLiteral("timestamps")),
+ useDocBookExtensions(QStringList() << QStringLiteral("docbook-extensions"))
{
setApplicationDescription(QCoreApplication::translate("qdoc", "Qt documentation generator"));
addHelpOption();
@@ -165,6 +166,10 @@ QDocCommandLineParser::QDocCommandLineParser()
timestampsOption.setDescription(
QCoreApplication::translate("qdoc", "Timestamp each qdoc log line."));
addOption(timestampsOption);
+
+ useDocBookExtensions.setDescription(QCoreApplication::translate(
+ "qdoc", "Use the DocBook Library extensions for metadata."));
+ addOption(useDocBookExtensions);
}
/*!
diff --git a/src/qdoc/qdoccommandlineparser.h b/src/qdoc/qdoccommandlineparser.h
index d88cb6ffc..2ab50c0bc 100644
--- a/src/qdoc/qdoccommandlineparser.h
+++ b/src/qdoc/qdoccommandlineparser.h
@@ -46,7 +46,7 @@ struct QDocCommandLineParser : public QCommandLineParser
QCommandLineOption prepareOption, generateOption, logProgressOption;
QCommandLineOption singleExecOption, writeQaPagesOption;
QCommandLineOption includePathOption, includePathSystemOption, frameworkOption;
- QCommandLineOption timestampsOption;
+ QCommandLineOption timestampsOption, useDocBookExtensions;
};
QT_END_NAMESPACE
diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp
index f32c4b7dc..966fb8aaa 100644
--- a/src/qdoc/qdocdatabase.cpp
+++ b/src/qdoc/qdocdatabase.cpp
@@ -1024,7 +1024,7 @@ void QDocDatabase::findAllLegaleseTexts(Aggregate *node)
for (auto it = node->constBegin(); it != node->constEnd(); ++it) {
if (!(*it)->isPrivate()) {
if (!(*it)->doc().legaleseText().isEmpty())
- legaleseTexts_.insertMulti((*it)->doc().legaleseText(), *it);
+ legaleseTexts_.insert((*it)->doc().legaleseText(), *it);
if ((*it)->isAggregate())
findAllLegaleseTexts(static_cast<Aggregate *>(*it));
}
@@ -1102,33 +1102,34 @@ const NodeMap &QDocDatabase::getSinceMap(const QString &key)
*/
void QDocDatabase::resolveStuff()
{
- if (Generator::dualExec() || Generator::preparing()) {
+ const auto &config = Config::instance();
+ if (config.dualExec() || config.preparing()) {
+ // order matters
primaryTree()->resolveBaseClasses(primaryTreeRoot());
primaryTree()->resolvePropertyOverriddenFromPtrs(primaryTreeRoot());
primaryTreeRoot()->normalizeOverloads();
+ primaryTree()->markDontDocumentNodes();
primaryTree()->removePrivateAndInternalBases(primaryTreeRoot());
primaryTree()->resolveProperties();
- primaryTree()->markDontDocumentNodes();
primaryTreeRoot()->markUndocumentedChildrenInternal();
primaryTreeRoot()->resolveQmlInheritance();
primaryTree()->resolveTargets(primaryTreeRoot());
primaryTree()->resolveCppToQmlLinks();
primaryTree()->resolveUsingClauses();
}
- if (Generator::singleExec() && Generator::generating()) {
+ if (config.singleExec() && config.generating()) {
primaryTree()->resolveBaseClasses(primaryTreeRoot());
primaryTree()->resolvePropertyOverriddenFromPtrs(primaryTreeRoot());
primaryTreeRoot()->resolveQmlInheritance();
- // primaryTree()->resolveTargets(primaryTreeRoot());
primaryTree()->resolveCppToQmlLinks();
primaryTree()->resolveUsingClauses();
}
- if (Generator::generating()) {
+ if (config.generating()) {
resolveNamespaces();
resolveProxies();
resolveBaseClasses();
}
- if (Generator::dualExec())
+ if (config.dualExec())
QDocIndexFiles::destroyQDocIndexFiles();
}
diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h
index dd5d886e6..353a5c7c8 100644
--- a/src/qdoc/qdocdatabase.h
+++ b/src/qdoc/qdocdatabase.h
@@ -39,7 +39,7 @@
QT_BEGIN_NAMESPACE
-typedef QMap<Text, const Node *> TextToNodeMap;
+typedef QMultiMap<Text, const Node *> TextToNodeMap;
class Atom;
class Generator;
diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp
index 1b247fe24..12136dd4a 100644
--- a/src/qdoc/qdocindexfiles.cpp
+++ b/src/qdoc/qdocindexfiles.cpp
@@ -32,6 +32,7 @@
#include "config.h"
#include "generator.h"
#include "location.h"
+#include "loggingcategory.h"
#include "qdocdatabase.h"
#include "qdoctagfiles.h"
@@ -69,6 +70,7 @@ QDocIndexFiles *QDocIndexFiles::qdocIndexFiles_ = nullptr;
QDocIndexFiles::QDocIndexFiles() : gen_(nullptr)
{
qdb_ = QDocDatabase::qdocDB();
+ storeLocationInfo_ = Config::instance().getBool(CONFIG_LOCATIONINFO);
}
/*!
@@ -108,8 +110,7 @@ void QDocIndexFiles::destroyQDocIndexFiles()
void QDocIndexFiles::readIndexes(const QStringList &indexFiles)
{
for (const QString &file : indexFiles) {
- QString msg = "Loading index file: " + file;
- Location::logToStdErr(msg);
+ qCInfo(lcQdoc) << "Loading index file: " << file;
readIndexFile(file);
}
}
@@ -420,7 +421,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader &reader, Node *current,
node = pn;
} else if (elementName == QLatin1String("enum")) {
- EnumNode *enumNode = new EnumNode(parent, name);
+ EnumNode *enumNode = new EnumNode(parent, name, attributes.hasAttribute("scoped"));
if (!indexUrl.isEmpty())
location = Location(indexUrl + QLatin1Char('/') + parent->name().toLower() + ".html");
@@ -586,6 +587,8 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader &reader, Node *current,
node->setStatus(Node::Active);
else if (status == QLatin1String("internal"))
node->setStatus(Node::Internal);
+ else if (status == QLatin1String("ignored"))
+ node->setStatus(Node::DontDocument);
else
node->setStatus(Node::Active);
@@ -736,6 +739,8 @@ static const QString getStatusString(Node::Status t)
return QLatin1String("active");
case Node::Internal:
return QLatin1String("internal");
+ case Node::DontDocument:
+ return QLatin1String("ignored");
default:
break;
}
@@ -930,7 +935,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node,
const Location &declLocation = node->declLocation();
if (!declLocation.fileName().isEmpty())
writer.writeAttribute("location", declLocation.fileName());
- if (!declLocation.filePath().isEmpty()) {
+ if (storeLocationInfo_ && !declLocation.filePath().isEmpty()) {
writer.writeAttribute("filepath", declLocation.filePath());
writer.writeAttribute("lineno", QString("%1").arg(declLocation.lineNo()));
}
@@ -1174,6 +1179,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node,
} break;
case Node::Enum: {
const EnumNode *enumNode = static_cast<const EnumNode *>(node);
+ if (enumNode->isScoped())
+ writer.writeAttribute("scoped", "true");
if (enumNode->flagsType())
writer.writeAttribute("typedef", enumNode->flagsType()->fullDocumentName());
const auto &items = enumNode->items();
@@ -1321,7 +1328,7 @@ void QDocIndexFiles::generateFunctionSection(QXmlStreamWriter &writer, FunctionN
const Location &declLocation = fn->declLocation();
if (!declLocation.fileName().isEmpty())
writer.writeAttribute("location", declLocation.fileName());
- if (!declLocation.filePath().isEmpty()) {
+ if (storeLocationInfo_ && !declLocation.filePath().isEmpty()) {
writer.writeAttribute("filepath", declLocation.filePath());
writer.writeAttribute("lineno", QString("%1").arg(declLocation.lineNo()));
}
@@ -1357,7 +1364,7 @@ void QDocIndexFiles::generateFunctionSection(QXmlStreamWriter &writer, FunctionN
writer.writeAttribute("refness", QString::number(2));
if (fn->hasAssociatedProperties()) {
QStringList associatedProperties;
- for (const auto *node : qAsConst(fn->associatedProperties())) {
+ for (const auto *node : fn->associatedProperties()) {
associatedProperties << node->name();
}
associatedProperties.sort();
@@ -1503,11 +1510,10 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter &writer, Node *node,
}
/*!
- Writes aqdoc module index in XML to a file named \afilerName.
- \a url becaomes the \c url attribute of the <INDEX> element.
- \a title becomes the \c title attribute of the <INDEX> element.
- \a g is used to get the Config object that contains the variables
- from the module's .qdocconf file.
+ Writes a qdoc module index in XML to a file named \a fileName.
+ \a url is the \c url attribute of the <INDEX> element.
+ \a title is the \c title attribute of the <INDEX> element.
+ \a g is a pointer to the current Generator in use, stored for later use.
*/
void QDocIndexFiles::generateIndex(const QString &fileName, const QString &url,
const QString &title, Generator *g)
@@ -1516,8 +1522,7 @@ void QDocIndexFiles::generateIndex(const QString &fileName, const QString &url,
if (!file.open(QFile::WriteOnly | QFile::Text))
return;
- QString msg = "Writing index file: " + fileName;
- Location::logToStdErr(msg);
+ qCInfo(lcQdoc) << "Writing index file:" << fileName;
gen_ = g;
QXmlStreamWriter writer(&file);
@@ -1529,7 +1534,7 @@ void QDocIndexFiles::generateIndex(const QString &fileName, const QString &url,
writer.writeAttribute("url", url);
writer.writeAttribute("title", title);
writer.writeAttribute("version", qdb_->version());
- writer.writeAttribute("project", g->config()->getString(CONFIG_PROJECT));
+ writer.writeAttribute("project", Config::instance().getString(CONFIG_PROJECT));
root_ = qdb_->primaryTreeRoot();
if (!root_->tree()->indexTitle().isEmpty())
diff --git a/src/qdoc/qdocindexfiles.h b/src/qdoc/qdocindexfiles.h
index 96e73a9ed..b37c132a4 100644
--- a/src/qdoc/qdocindexfiles.h
+++ b/src/qdoc/qdocindexfiles.h
@@ -85,6 +85,7 @@ private:
Generator *gen_;
QString project_;
QVector<QPair<ClassNode *, QString>> basesList_;
+ bool storeLocationInfo_;
};
QT_END_NAMESPACE
diff --git a/src/qdoc/qdoctagfiles.cpp b/src/qdoc/qdoctagfiles.cpp
index cf593aa4c..0d9b0aee0 100644
--- a/src/qdoc/qdoctagfiles.cpp
+++ b/src/qdoc/qdoctagfiles.cpp
@@ -181,7 +181,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter &writer, const Aggreg
switch (node->nodeType()) {
case Node::Enum:
nodeName = "member";
- kind = "enum";
+ kind = "enumeration";
break;
case Node::Typedef:
nodeName = "member";
@@ -260,7 +260,8 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter &writer, const Aggreg
writer.writeTextElement("type", "virtual " + functionNode->returnType());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
+ const QStringList pieces =
+ gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
QString signature = functionNode->signature(false, false);
@@ -281,7 +282,8 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter &writer, const Aggreg
const PropertyNode *propertyNode = static_cast<const PropertyNode *>(node);
writer.writeAttribute("type", propertyNode->dataType());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
+ const QStringList pieces =
+ gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
writer.writeTextElement("arglist", QString());
@@ -291,15 +293,17 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter &writer, const Aggreg
case Node::Enum: {
const EnumNode *enumNode = static_cast<const EnumNode *>(node);
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
+ const QStringList pieces =
+ gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
+ writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
- writer.writeTextElement("arglist", QString());
writer.writeEndElement(); // member
- for (int i = 0; i < enumNode->items().size(); ++i) {
- EnumItem item = enumNode->items().value(i);
+ for (const auto &item : enumNode->items()) {
writer.writeStartElement("member");
- writer.writeAttribute("name", item.name());
+ writer.writeAttribute("kind", "enumvalue");
+ writer.writeTextElement("name", item.name());
+ writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
writer.writeTextElement("arglist", QString());
writer.writeEndElement(); // member
@@ -312,7 +316,8 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter &writer, const Aggreg
else
writer.writeAttribute("type", QString());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
+ const QStringList pieces =
+ gen_->fullDocumentLocation(node, false).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
writer.writeTextElement("arglist", QString());
diff --git a/src/qdoc/qmlcodemarker.cpp b/src/qdoc/qmlcodemarker.cpp
index 4ecfb6475..08c9b11ed 100644
--- a/src/qdoc/qmlcodemarker.cpp
+++ b/src/qdoc/qmlcodemarker.cpp
@@ -164,7 +164,7 @@ QString QmlCodeMarker::addMarkUp(const QString &code, const Node * /* relative *
QQmlJS::Lexer lexer(&engine);
QString newCode = code;
- QVector<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode);
+ QVector<QQmlJS::SourceLocation> pragmas = extractPragmas(newCode);
lexer.setCode(newCode, 1);
QQmlJS::Parser parser(&engine);
@@ -217,11 +217,11 @@ static void replaceWithSpace(QString &str, int idx, int n)
Searches for ".pragma <value>" or ".import <stuff>" declarations
in \a script. Currently supported pragmas are: library
*/
-QVector<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script)
+QVector<QQmlJS::SourceLocation> QmlCodeMarker::extractPragmas(QString &script)
{
const QString pragma(QLatin1String("pragma"));
const QString library(QLatin1String("library"));
- QVector<QQmlJS::AST::SourceLocation> removed;
+ QVector<QQmlJS::SourceLocation> removed;
QQmlJS::Lexer l(nullptr);
l.setCode(script, 0);
@@ -246,7 +246,7 @@ QVector<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &scri
token = l.lex();
}
replaceWithSpace(script, startOffset, endOffset - startOffset);
- removed.append(QQmlJS::AST::SourceLocation(startOffset, endOffset - startOffset, startLine,
+ removed.append(QQmlJS::SourceLocation(startOffset, endOffset - startOffset, startLine,
startColumn));
}
return removed;
diff --git a/src/qdoc/qmlcodemarker.h b/src/qdoc/qmlcodemarker.h
index c3435e840..67b1a9be7 100644
--- a/src/qdoc/qmlcodemarker.h
+++ b/src/qdoc/qmlcodemarker.h
@@ -41,6 +41,15 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_DECLARATIVE
+# include <private/qqmlapiversion_p.h>
+# if Q_QML_PRIVATE_API_VERSION < 8
+namespace QQmlJS {
+ using SourceLocation = AST::SourceLocation;
+}
+# endif
+#endif
+
class QmlCodeMarker : public CppCodeMarker
{
Q_DECLARE_TR_FUNCTIONS(QDoc::QmlCodeMarker)
@@ -64,7 +73,7 @@ public:
/* Copied from src/declarative/qml/qdeclarativescriptparser.cpp */
#ifndef QT_NO_DECLARATIVE
- QVector<QQmlJS::AST::SourceLocation> extractPragmas(QString &script);
+ QVector<QQmlJS::SourceLocation> extractPragmas(QString &script);
#endif
private:
diff --git a/src/qdoc/qmlcodeparser.cpp b/src/qdoc/qmlcodeparser.cpp
index 06ce5e1a5..a0a6bc5f0 100644
--- a/src/qdoc/qmlcodeparser.cpp
+++ b/src/qdoc/qmlcodeparser.cpp
@@ -33,7 +33,6 @@
#include "qmlcodeparser.h"
#include "node.h"
-#include "config.h"
#include "qmlvisitor.h"
#ifndef QT_NO_DECLARATIVE
@@ -60,14 +59,12 @@ QmlCodeParser::QmlCodeParser()
QmlCodeParser::~QmlCodeParser() {}
/*!
- Initializes the code parser base class. The \a config argument
- is passed to the initialization functions in the base class.
-
+ Initializes the code parser base class.
Also creates a lexer and parser from QQmlJS.
*/
-void QmlCodeParser::initializeParser(const Config &config)
+void QmlCodeParser::initializeParser()
{
- CodeParser::initializeParser(config);
+ CodeParser::initializeParser();
#ifndef QT_NO_DECLARATIVE
lexer = new QQmlJS::Lexer(&engine);
@@ -144,7 +141,7 @@ void QmlCodeParser::parseSourceFile(const Location &location, const QString &fil
const auto &messages = parser->diagnosticMessages();
for (const auto &msg : messages) {
qDebug().nospace() << qPrintable(filePath) << ':'
-# if Q_QML_PRIVATE_API_VERSION < 5
+# if Q_QML_PRIVATE_API_VERSION >= 8
<< msg.loc.startLine << ": QML syntax error at col "
<< msg.loc.startColumn
# else
diff --git a/src/qdoc/qmlcodeparser.h b/src/qdoc/qmlcodeparser.h
index f639f2115..ca34dc111 100644
--- a/src/qdoc/qmlcodeparser.h
+++ b/src/qdoc/qmlcodeparser.h
@@ -45,7 +45,6 @@
QT_BEGIN_NAMESPACE
-class Config;
class Node;
class QString;
@@ -57,7 +56,7 @@ public:
QmlCodeParser();
~QmlCodeParser() override;
- void initializeParser(const Config &config) override;
+ void initializeParser() override;
void terminateParser() override;
QString language() override;
QStringList sourceFileNameFilter() override;
diff --git a/src/qdoc/qmlmarkupvisitor.cpp b/src/qdoc/qmlmarkupvisitor.cpp
index 434fe76bc..78f48753a 100644
--- a/src/qdoc/qmlmarkupvisitor.cpp
+++ b/src/qdoc/qmlmarkupvisitor.cpp
@@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DECLARATIVE
QmlMarkupVisitor::QmlMarkupVisitor(const QString &source,
- const QVector<QQmlJS::AST::SourceLocation> &pragmas,
+ const QVector<QQmlJS::SourceLocation> &pragmas,
QQmlJS::Engine *engine)
{
this->source = source;
@@ -53,7 +53,7 @@ QmlMarkupVisitor::QmlMarkupVisitor(const QString &source,
// Merge the lists of locations of pragmas and comments in the source code.
int i = 0;
int j = 0;
- const QList<QQmlJS::AST::SourceLocation> comments = engine->comments();
+ const QList<QQmlJS::SourceLocation> comments = engine->comments();
while (i < comments.size() && j < pragmas.length()) {
if (comments[i].offset < pragmas[j].offset) {
extraTypes.append(Comment);
@@ -186,7 +186,7 @@ void QmlMarkupVisitor::addExtra(quint32 start, quint32 finish)
cursor = finish;
}
-void QmlMarkupVisitor::addMarkedUpToken(QQmlJS::AST::SourceLocation &location,
+void QmlMarkupVisitor::addMarkedUpToken(QQmlJS::SourceLocation &location,
const QString &tagName,
const QHash<QString, QString> &attributes)
{
@@ -205,13 +205,13 @@ void QmlMarkupVisitor::addMarkedUpToken(QQmlJS::AST::SourceLocation &location,
cursor += location.length;
}
-QString QmlMarkupVisitor::sourceText(QQmlJS::AST::SourceLocation &location)
+QString QmlMarkupVisitor::sourceText(QQmlJS::SourceLocation &location)
{
return source.mid(location.offset, location.length);
}
-void QmlMarkupVisitor::addVerbatim(QQmlJS::AST::SourceLocation first,
- QQmlJS::AST::SourceLocation last)
+void QmlMarkupVisitor::addVerbatim(QQmlJS::SourceLocation first,
+ QQmlJS::SourceLocation last)
{
if (!first.isValid())
return;
@@ -243,7 +243,9 @@ bool QmlMarkupVisitor::visit(QQmlJS::AST::UiImport *uiimport)
void QmlMarkupVisitor::endVisit(QQmlJS::AST::UiImport *uiimport)
{
- addVerbatim(uiimport->versionToken);
+ if (uiimport->version)
+ addVerbatim(uiimport->version->firstSourceLocation(),
+ uiimport->version->lastSourceLocation());
addVerbatim(uiimport->asToken);
addMarkedUpToken(uiimport->importIdToken, QLatin1String("headerfile"));
addVerbatim(uiimport->semicolonToken);
diff --git a/src/qdoc/qmlmarkupvisitor.h b/src/qdoc/qmlmarkupvisitor.h
index c9a012ae8..53d6b4ed9 100644
--- a/src/qdoc/qmlmarkupvisitor.h
+++ b/src/qdoc/qmlmarkupvisitor.h
@@ -42,12 +42,20 @@
QT_BEGIN_NAMESPACE
#ifndef QT_NO_DECLARATIVE
+# include <private/qqmlapiversion_p.h>
+# if Q_QML_PRIVATE_API_VERSION < 8
+namespace QQmlJS {
+ using SourceLocation = AST::SourceLocation;
+}
+# endif
+
+
class QmlMarkupVisitor : public QQmlJS::AST::Visitor
{
public:
enum ExtraType { Comment, Pragma };
- QmlMarkupVisitor(const QString &code, const QVector<QQmlJS::AST::SourceLocation> &pragmas,
+ QmlMarkupVisitor(const QString &code, const QVector<QQmlJS::SourceLocation> &pragmas,
QQmlJS::Engine *engine);
virtual ~QmlMarkupVisitor();
@@ -144,16 +152,16 @@ protected:
private:
typedef QHash<QString, QString> StringHash;
void addExtra(quint32 start, quint32 finish);
- void addMarkedUpToken(QQmlJS::AST::SourceLocation &location, const QString &text,
+ void addMarkedUpToken(QQmlJS::SourceLocation &location, const QString &text,
const StringHash &attributes = StringHash());
- void addVerbatim(QQmlJS::AST::SourceLocation first,
- QQmlJS::AST::SourceLocation last = QQmlJS::AST::SourceLocation());
- QString sourceText(QQmlJS::AST::SourceLocation &location);
+ void addVerbatim(QQmlJS::SourceLocation first,
+ QQmlJS::SourceLocation last = QQmlJS::SourceLocation());
+ QString sourceText(QQmlJS::SourceLocation &location);
void throwRecursionDepthError() final;
QQmlJS::Engine *engine;
QVector<ExtraType> extraTypes;
- QVector<QQmlJS::AST::SourceLocation> extraLocations;
+ QVector<QQmlJS::SourceLocation> extraLocations;
QString source;
QString output;
quint32 cursor;
diff --git a/src/qdoc/qmlvisitor.cpp b/src/qdoc/qmlvisitor.cpp
index d2d32b393..aac45dd43 100644
--- a/src/qdoc/qmlvisitor.cpp
+++ b/src/qdoc/qmlvisitor.cpp
@@ -76,11 +76,11 @@ QmlDocVisitor::~QmlDocVisitor()
/*!
Returns the location of the nearest comment above the \a offset.
*/
-QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) const
+QQmlJS::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) const
{
const auto comments = engine->comments();
for (auto it = comments.rbegin(); it != comments.rend(); ++it) {
- QQmlJS::AST::SourceLocation loc = *it;
+ QQmlJS::SourceLocation loc = *it;
if (loc.begin() <= lastEndOffset) {
// Return if we reach the end of the preceding structure.
@@ -99,7 +99,7 @@ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) cons
}
}
- return QQmlJS::AST::SourceLocation();
+ return QQmlJS::SourceLocation();
}
class QmlSignatureParser
@@ -134,9 +134,9 @@ private:
If a qdoc comment is found for \a location, true is returned.
If a comment is not found there, false is returned.
*/
-bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Node *node)
+bool QmlDocVisitor::applyDocumentation(QQmlJS::SourceLocation location, Node *node)
{
- QQmlJS::AST::SourceLocation loc = precedingComment(location.begin());
+ QQmlJS::SourceLocation loc = precedingComment(location.begin());
if (loc.isValid()) {
QString source = document.mid(loc.offset, loc.length);
@@ -419,7 +419,7 @@ bool QmlDocVisitor::splitQmlPropertyArg(const Doc &doc, const QString &arg, QmlP
/*!
Applies the metacommands found in the comment.
*/
-void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation, Node *node, Doc &doc)
+void QmlDocVisitor::applyMetacommands(QQmlJS::SourceLocation, Node *node, Doc &doc)
{
QDocDatabase *qdb = QDocDatabase::qdocDB();
QSet<QString> metacommands = doc.metaCommandsUsed();
@@ -453,8 +453,6 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation, Node *node, D
node->setStatus(Node::Internal);
} else if (command == COMMAND_OBSOLETE) {
node->setStatus(Node::Obsolete);
- } else if (command == COMMAND_PAGEKEYWORDS) {
- // Not done yet. Do we need this?
} else if (command == COMMAND_PRELIMINARY) {
node->setStatus(Node::Preliminary);
} else if (command == COMMAND_SINCE) {
@@ -540,10 +538,14 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiImport *import)
QString name = document.mid(import->fileNameToken.offset, import->fileNameToken.length);
if (name[0] == '\"')
name = name.mid(1, name.length() - 2);
- QString version = document.mid(import->versionToken.offset, import->versionToken.length);
+ QString version;
+ if (import->version) {
+ const auto start = import->version->firstSourceLocation().begin();
+ const auto end = import->version->lastSourceLocation().end();
+ version = document.mid(start, end - start);
+ }
QString importId = document.mid(import->importIdToken.offset, import->importIdToken.length);
QString importUri = getFullyQualifiedId(import->importUri);
- QString reconstructed = importUri + QLatin1Char(' ') + version;
importList.append(ImportRec(name, version, importId, importUri));
return true;
diff --git a/src/qdoc/qmlvisitor.h b/src/qdoc/qmlvisitor.h
index 6c10c5258..c0fe51251 100644
--- a/src/qdoc/qmlvisitor.h
+++ b/src/qdoc/qmlvisitor.h
@@ -40,6 +40,15 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_DECLARATIVE
+# include <private/qqmlapiversion_p.h>
+# if Q_QML_PRIVATE_API_VERSION < 8
+namespace QQmlJS {
+ using SourceLocation = AST::SourceLocation;
+}
+# endif
+#endif
+
struct QmlPropArgs
{
QString type_;
@@ -96,9 +105,9 @@ public:
private:
QString getFullyQualifiedId(QQmlJS::AST::UiQualifiedId *id);
- QQmlJS::AST::SourceLocation precedingComment(quint32 offset) const;
- bool applyDocumentation(QQmlJS::AST::SourceLocation location, Node *node);
- void applyMetacommands(QQmlJS::AST::SourceLocation location, Node *node, Doc &doc);
+ QQmlJS::SourceLocation precedingComment(quint32 offset) const;
+ bool applyDocumentation(QQmlJS::SourceLocation location, Node *node);
+ void applyMetacommands(QQmlJS::SourceLocation location, Node *node, Doc &doc);
bool splitQmlPropertyArg(const Doc &doc, const QString &arg, QmlPropArgs &qpa);
QQmlJS::Engine *engine;
diff --git a/src/qdoc/sections.cpp b/src/qdoc/sections.cpp
index 6cad782de..c9012e21c 100644
--- a/src/qdoc/sections.cpp
+++ b/src/qdoc/sections.cpp
@@ -205,13 +205,13 @@ void Section::insert(Node *node)
if (!irrelevant) {
QString key = sortName(node);
if (node->isObsolete()) {
- obsoleteMemberMap_.insertMulti(key, node);
+ obsoleteMemberMap_.insert(key, node);
} else {
if (!inherited)
- memberMap_.insertMulti(key, node);
+ memberMap_.insert(key, node);
else if (style_ == AllMembers) {
if (!memberMap_.contains(key))
- memberMap_.insertMulti(key, node);
+ memberMap_.insert(key, node);
}
if (inherited && (node->parent()->isClassNode() || node->parent()->isNamespace())) {
if (inheritedMembers_.isEmpty()
diff --git a/src/qdoc/sections.h b/src/qdoc/sections.h
index 90596b394..c8d17b141 100644
--- a/src/qdoc/sections.h
+++ b/src/qdoc/sections.h
@@ -77,7 +77,7 @@ public:
}
void insert(Node *node);
- void insert(const QString &key, Node *node) { memberMap_.insertMulti(key, node); }
+ void insert(const QString &key, Node *node) { memberMap_.insert(key, node); }
bool insertReimplementedMember(Node *node);
ClassMap *newClassMap(const Aggregate *aggregate);
diff --git a/src/qdoc/tokenizer.cpp b/src/qdoc/tokenizer.cpp
index d15b6d318..7a59bc598 100644
--- a/src/qdoc/tokenizer.cpp
+++ b/src/qdoc/tokenizer.cpp
@@ -502,8 +502,9 @@ int Tokenizer::getToken()
return Tok_Eoi;
}
-void Tokenizer::initialize(const Config &config)
+void Tokenizer::initialize()
{
+ Config &config = Config::instance();
QString versionSym = config.getString(CONFIG_VERSIONSYM);
QString sourceEncoding = config.getString(CONFIG_SOURCEENCODING);
diff --git a/src/qdoc/tokenizer.h b/src/qdoc/tokenizer.h
index 4f35090fe..64f188f07 100644
--- a/src/qdoc/tokenizer.h
+++ b/src/qdoc/tokenizer.h
@@ -169,7 +169,7 @@ public:
int bracketDepth() const { return yyBracketDepth; }
Location &tokenLocation() { return yyTokLoc; }
- static void initialize(const Config &config);
+ static void initialize();
static void terminate();
static bool isTrue(const QString &condition);
diff --git a/src/qdoc/tree.cpp b/src/qdoc/tree.cpp
index 718b16fc5..f6477b6b1 100644
--- a/src/qdoc/tree.cpp
+++ b/src/qdoc/tree.cpp
@@ -63,9 +63,8 @@ QT_BEGIN_NAMESPACE
qdoc database that is constructing the tree. This might not
be necessary, and it might be removed later.
- \a camelCaseModuleName is the project name for this tree,
- which was obtained from the qdocconf file via the Config
- singleton.
+ \a camelCaseModuleName is the project name for this tree
+ as it appears in the qdocconf file.
*/
Tree::Tree(const QString &camelCaseModuleName, QDocDatabase *qdb)
: treeHasBeenAnalyzed_(false),
@@ -79,9 +78,9 @@ Tree::Tree(const QString &camelCaseModuleName, QDocDatabase *qdb)
{
root_.setPhysicalModuleName(physicalModuleName_);
root_.setTree(this);
- if (Generator::writeQaPages()) {
+ const auto &config = Config::instance();
+ if (config.getBool(CONFIG_WRITEQAPAGES))
targetListMap_ = new TargetListMap;
- }
}
/*!
@@ -105,7 +104,8 @@ Tree::~Tree()
}
nodesByTargetRef_.clear();
nodesByTargetTitle_.clear();
- if (Generator::writeQaPages() && targetListMap_) {
+ const auto &config = Config::instance();
+ if (config.getBool(CONFIG_WRITEQAPAGES) && targetListMap_) {
for (auto target = targetListMap_->begin(); target != targetListMap_->end(); ++target) {
TargetList *tlist = target.value();
if (tlist) {
diff --git a/src/qdoc/webxmlgenerator.cpp b/src/qdoc/webxmlgenerator.cpp
index c7312d418..4d8906f6a 100644
--- a/src/qdoc/webxmlgenerator.cpp
+++ b/src/qdoc/webxmlgenerator.cpp
@@ -28,6 +28,7 @@
#include "webxmlgenerator.h"
+#include "config.h"
#include "helpprojectwriter.h"
#include "node.h"
#include "qdocdatabase.h"
@@ -41,9 +42,9 @@ QT_BEGIN_NAMESPACE
static CodeMarker *marker_ = nullptr;
-void WebXMLGenerator::initializeGenerator(const Config &config)
+void WebXMLGenerator::initializeGenerator()
{
- HtmlGenerator::initializeGenerator(config);
+ HtmlGenerator::initializeGenerator();
}
void WebXMLGenerator::terminateGenerator()
@@ -135,11 +136,14 @@ void WebXMLGenerator::generateExampleFilePage(const Node *en, const QString &fil
writer.writeAttribute("fulltitle", title);
writer.writeAttribute("subtitle", file);
writer.writeStartElement("description");
- QString userFriendlyFilePath; // unused
- writer.writeAttribute("path",
- Doc::resolveFile(en->doc().location(), file, &userFriendlyFilePath));
- writer.writeAttribute("line", "0");
- writer.writeAttribute("column", "0");
+
+ if (Config::instance().getBool(CONFIG_LOCATIONINFO)) {
+ QString userFriendlyFilePath; // unused
+ writer.writeAttribute("path",
+ Doc::resolveFile(en->doc().location(), file, &userFriendlyFilePath));
+ writer.writeAttribute("line", "0");
+ writer.writeAttribute("column", "0");
+ }
Quoter quoter;
Doc::quoteFromFile(en->doc().location(), quoter, file);
@@ -171,9 +175,11 @@ void WebXMLGenerator::append(QXmlStreamWriter &writer, Node *node)
Q_ASSERT(marker_);
writer.writeStartElement("description");
- writer.writeAttribute("path", node->doc().location().filePath());
- writer.writeAttribute("line", QString::number(node->doc().location().lineNo()));
- writer.writeAttribute("column", QString::number(node->doc().location().columnNo()));
+ if (Config::instance().getBool(CONFIG_LOCATIONINFO)) {
+ writer.writeAttribute("path", node->doc().location().filePath());
+ writer.writeAttribute("line", QString::number(node->doc().location().lineNo()));
+ writer.writeAttribute("column", QString::number(node->doc().location().columnNo()));
+ }
if (node->isTextPageNode())
generateRelations(writer, node);
diff --git a/src/qdoc/webxmlgenerator.h b/src/qdoc/webxmlgenerator.h
index 71fd9df24..f8b3fa80e 100644
--- a/src/qdoc/webxmlgenerator.h
+++ b/src/qdoc/webxmlgenerator.h
@@ -30,7 +30,6 @@
#define WEBXMLGENERATOR_H
#include "codemarker.h"
-#include "config.h"
#include "htmlgenerator.h"
#include "qdocindexfiles.h"
@@ -44,7 +43,7 @@ class WebXMLGenerator : public HtmlGenerator, public IndexSectionWriter
public:
explicit WebXMLGenerator() {}
- void initializeGenerator(const Config &config) override;
+ void initializeGenerator() override;
void terminateGenerator() override;
QString format() override;
// from IndexSectionWriter
diff --git a/src/qev/qev.cpp b/src/qev/qev.cpp
index b7de5dc73..01bfbd9e9 100644
--- a/src/qev/qev.cpp
+++ b/src/qev/qev.cpp
@@ -43,7 +43,7 @@ public:
bool event(QEvent *e) {
if (e->type() == QEvent::ContextMenu)
return false;
- QDebug(qout) << e << endl;
+ QDebug(qout) << e << Qt::endl;
return QWidget::event(e);
}
};
diff --git a/src/qev/qev.pro b/src/qev/qev.pro
index f00826ad1..02801a399 100644
--- a/src/qev/qev.pro
+++ b/src/qev/qev.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(qev))
+
QT += widgets
SOURCES += qev.cpp
diff --git a/src/qtattributionsscanner/Qt5AttributionsScannerTools.cmake.in b/src/qtattributionsscanner/Qt5AttributionsScannerTools.cmake.in
index 9e9381c24..e99540bfa 100644
--- a/src/qtattributionsscanner/Qt5AttributionsScannerTools.cmake.in
+++ b/src/qtattributionsscanner/Qt5AttributionsScannerTools.cmake.in
@@ -54,3 +54,14 @@ if (NOT TARGET Qt5::qtattributionsscanner)
IMPORTED_LOCATION ${imported_location}
)
endif()
+
+# Create versionless tool targets.
+foreach(__qt_tool qtattributionsscanner)
+ if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::${__qt_tool}
+ AND TARGET Qt5::${__qt_tool})
+ add_executable(Qt::${__qt_tool} IMPORTED)
+ get_target_property(__qt_imported_location Qt5::${__qt_tool} IMPORTED_LOCATION)
+ set_target_properties(Qt::${__qt_tool}
+ PROPERTIES IMPORTED_LOCATION \"${__qt_imported_location}\")
+ endif()
+endforeach()
diff --git a/src/qtattributionsscanner/qdocgenerator.cpp b/src/qtattributionsscanner/qdocgenerator.cpp
index 86e84724b..dfa460f3d 100644
--- a/src/qtattributionsscanner/qdocgenerator.cpp
+++ b/src/qtattributionsscanner/qdocgenerator.cpp
@@ -70,7 +70,6 @@ static void generate(QTextStream &out, const Package &package, const QDir &baseD
LogLevel logLevel)
{
out << "/*!\n\n";
- out << "\\contentspage attributions.html\n";
for (const QString &part: package.qtParts)
out << "\\ingroup attributions-" << part << "\n";
diff --git a/src/qtattributionsscanner/qtattributionsscanner.pro b/src/qtattributionsscanner/qtattributionsscanner.pro
index 839af9b08..a6f34ee6f 100644
--- a/src/qtattributionsscanner/qtattributionsscanner.pro
+++ b/src/qtattributionsscanner/qtattributionsscanner.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(qtattributionsscanner))
+
option(host_build)
CONFIG += console
diff --git a/src/qtattributionsscanner/scanner.cpp b/src/qtattributionsscanner/scanner.cpp
index dc7b88fbf..0b4330cf0 100644
--- a/src/qtattributionsscanner/scanner.cpp
+++ b/src/qtattributionsscanner/scanner.cpp
@@ -103,7 +103,7 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L
} else if (key == QLatin1String("Path")) {
p.path = QDir(directory).absoluteFilePath(value);
} else if (key == QLatin1String("Files")) {
- p.files = value.split(QRegExp(QStringLiteral("\\s")), QString::SkipEmptyParts);
+ p.files = value.split(QRegExp(QStringLiteral("\\s")), Qt::SkipEmptyParts);
} else if (key == QLatin1String("Id")) {
p.id = value;
} else if (key == QLatin1String("Homepage")) {
diff --git a/src/qtdiag/main.cpp b/src/qtdiag/main.cpp
index de56d7201..5851d3450 100644
--- a/src/qtdiag/main.cpp
+++ b/src/qtdiag/main.cpp
@@ -50,11 +50,13 @@ int main(int argc, char **argv)
const QCommandLineOption glExtensionOption(QStringLiteral("gl-extensions"), QStringLiteral("List GL extensions"));
const QCommandLineOption fontOption(QStringLiteral("fonts"), QStringLiteral("Output list of fonts"));
const QCommandLineOption noVkOption(QStringLiteral("no-vulkan"), QStringLiteral("Do not output Vulkan information"));
+ const QCommandLineOption noRhiOption(QStringLiteral("no-rhi"), QStringLiteral("Do not output RHI information"));
commandLineParser.setApplicationDescription(QStringLiteral("Prints diagnostic output about the Qt library."));
commandLineParser.addOption(noGlOption);
commandLineParser.addOption(glExtensionOption);
commandLineParser.addOption(fontOption);
commandLineParser.addOption(noVkOption);
+ commandLineParser.addOption(noRhiOption);
commandLineParser.addHelpOption();
commandLineParser.process(app);
unsigned flags = commandLineParser.isSet(noGlOption) ? 0u : unsigned(QtDiagGl);
@@ -64,6 +66,8 @@ int main(int argc, char **argv)
flags |= QtDiagFonts;
if (!commandLineParser.isSet(noVkOption))
flags |= QtDiagVk;
+ if (!commandLineParser.isSet(noRhiOption))
+ flags |= QtDiagRhi;
std::wcout << qtDiag(flags).toStdWString();
std::wcout.flush();
diff --git a/src/qtdiag/qtdiag.cpp b/src/qtdiag/qtdiag.cpp
index 9b082e37e..100b1acf8 100644
--- a/src/qtdiag/qtdiag.cpp
+++ b/src/qtdiag/qtdiag.cpp
@@ -74,6 +74,21 @@
#include <qpa/qplatformnativeinterface.h>
#include <private/qhighdpiscaling_p.h>
+#include <QtGui/private/qrhi_p.h>
+#include <QtGui/QOffscreenSurface>
+#if QT_CONFIG(opengl)
+# include <QtGui/private/qrhigles2_p.h>
+#endif
+#if QT_CONFIG(vulkan)
+# include <QtGui/private/qrhivulkan_p.h>
+#endif
+#ifdef Q_OS_WIN
+#include <QtGui/private/qrhid3d11_p.h>
+#endif
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
+# include <QtGui/private/qrhimetal_p.h>
+#endif
+
#ifdef QT_WIDGETS_LIB
# include <QtWidgets/QStyleFactory>
#endif
@@ -102,7 +117,7 @@ QTextStream &operator<<(QTextStream &str, const QDpi &d)
QTextStream &operator<<(QTextStream &str, const QRect &r)
{
- str << r.size() << forcesign << r.x() << r.y() << noforcesign;
+ str << r.size() << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
return str;
}
@@ -247,9 +262,9 @@ void dumpVkInfo(QTextStream &str)
window.setVulkanInstance(&inst);
for (const VkPhysicalDeviceProperties &props : window.availablePhysicalDevices()) {
str << " API version " << vulkanVersion(props.apiVersion).toString()
- << hex << ", vendor 0x" << props.vendorID
+ << Qt::hex << ", vendor 0x" << props.vendorID
<< ", device 0x" << props.deviceID << ", " << props.deviceName
- << dec << ", type " << props.deviceType
+ << Qt::dec << ", type " << props.deviceType
<< ", driver version " << vulkanVersion(props.driverVersion).toString();
}
} else {
@@ -258,6 +273,142 @@ void dumpVkInfo(QTextStream &str)
}
#endif // vulkan
+void dumpRhiBackendInfo(QTextStream &str, const char *name, QRhi::Implementation impl, QRhiInitParams *initParams)
+{
+ struct RhiFeature {
+ const char *name;
+ QRhi::Feature val;
+ };
+ const RhiFeature features[] = {
+ { "MultisampleTexture", QRhi::MultisampleTexture },
+ { "MultisampleRenderBuffer", QRhi::MultisampleRenderBuffer },
+ { "DebugMarkers", QRhi::DebugMarkers },
+ { "Timestamps", QRhi::Timestamps },
+ { "Instancing", QRhi::Instancing },
+ { "CustomInstanceStepRate", QRhi::CustomInstanceStepRate },
+ { "PrimitiveRestart", QRhi::PrimitiveRestart },
+ { "NonDynamicUniformBuffers", QRhi::NonDynamicUniformBuffers },
+ { "NonFourAlignedEffectiveIndexBufferOffset", QRhi::NonFourAlignedEffectiveIndexBufferOffset },
+ { "NPOTTextureRepeat", QRhi::NPOTTextureRepeat },
+ { "RedOrAlpha8IsRed", QRhi::RedOrAlpha8IsRed },
+ { "ElementIndexUint", QRhi::ElementIndexUint },
+ { "Compute", QRhi::Compute },
+ { "WideLines", QRhi::WideLines },
+ { "VertexShaderPointSize", QRhi::VertexShaderPointSize },
+ { "BaseVertex", QRhi::BaseVertex },
+ { "BaseInstance", QRhi::BaseInstance },
+ { "TriangleFanTopology", QRhi::TriangleFanTopology },
+ { "ReadBackNonUniformBuffer", QRhi::ReadBackNonUniformBuffer },
+ { "ReadBackNonBaseMipLevel", QRhi::ReadBackNonBaseMipLevel },
+ { nullptr, QRhi::Feature(0) }
+ };
+ struct RhiTextureFormat {
+ const char *name;
+ QRhiTexture::Format val;
+ };
+ const RhiTextureFormat textureFormats[] = {
+ { "RGBA8", QRhiTexture::RGBA8 },
+ { "BGRA8", QRhiTexture::BGRA8 },
+ { "R8", QRhiTexture::R8 },
+ { "R16", QRhiTexture::R16 },
+ { "RED_OR_ALPHA8", QRhiTexture::RED_OR_ALPHA8 },
+ { "RGBA16F", QRhiTexture::RGBA16F },
+ { "RGBA32F", QRhiTexture::RGBA32F },
+ { "R16F", QRhiTexture::R16F },
+ { "R32F", QRhiTexture::R32F },
+ { "D16", QRhiTexture::D16 },
+ { "D32F", QRhiTexture::D32F },
+ { "BC1", QRhiTexture::BC1 },
+ { "BC2", QRhiTexture::BC2 },
+ { "BC3", QRhiTexture::BC3 },
+ { "BC4", QRhiTexture::BC4 },
+ { "BC5", QRhiTexture::BC5 },
+ { "BC6H", QRhiTexture::BC6H },
+ { "BC7", QRhiTexture::BC7 },
+ { "ETC2_RGB8", QRhiTexture::ETC2_RGB8 },
+ { "ETC2_RGB8A1", QRhiTexture::ETC2_RGB8A1 },
+ { "ETC2_RGBA8", QRhiTexture::ETC2_RGBA8 },
+ { "ASTC_4x4", QRhiTexture::ASTC_4x4 },
+ { "ASTC_5x4", QRhiTexture::ASTC_5x4 },
+ { "ASTC_5x5", QRhiTexture::ASTC_5x5 },
+ { "ASTC_6x5", QRhiTexture::ASTC_6x5 },
+ { "ASTC_6x6", QRhiTexture::ASTC_6x6 },
+ { "ASTC_8x5", QRhiTexture::ASTC_8x5 },
+ { "ASTC_8x6", QRhiTexture::ASTC_8x6 },
+ { "ASTC_8x8", QRhiTexture::ASTC_8x8 },
+ { "ASTC_10x5", QRhiTexture::ASTC_10x5 },
+ { "ASTC_10x6", QRhiTexture::ASTC_10x6 },
+ { "ASTC_10x8", QRhiTexture::ASTC_10x8 },
+ { "ASTC_10x10", QRhiTexture::ASTC_10x10 },
+ { "ASTC_12x10", QRhiTexture::ASTC_12x10 },
+ { "ASTC_12x12", QRhiTexture::ASTC_12x12 },
+ { nullptr, QRhiTexture::UnknownFormat }
+ };
+
+ QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr));
+ if (rhi) {
+ str << name << ":\n";
+ str << " Min Texture Size: " << rhi->resourceLimit(QRhi::TextureSizeMin) << "\n";
+ str << " Max Texture Size: " << rhi->resourceLimit(QRhi::TextureSizeMax) << "\n";
+ str << " Max Color Attachments: " << rhi->resourceLimit(QRhi::MaxColorAttachments) << "\n";
+ str << " Frames in Flight: " << rhi->resourceLimit(QRhi::FramesInFlight) << "\n";
+ str << " Uniform Buffer Alignment: " << rhi->ubufAlignment() << "\n";
+ QByteArrayList supportedSampleCounts;
+ for (int s : rhi->supportedSampleCounts())
+ supportedSampleCounts << QByteArray::number(s);
+ str << " Supported MSAA sample counts: " << supportedSampleCounts.join(',') << "\n";
+ str << " Features:\n";
+ for (int i = 0; features[i].name; i++) {
+ str << " " << (rhi->isFeatureSupported(features[i].val) ? "v" : "-") << " " << features[i].name << "\n";
+ }
+ str << " Texture formats:";
+ for (int i = 0; textureFormats[i].name; i++) {
+ if (rhi->isTextureFormatSupported(textureFormats[i].val))
+ str << " " << textureFormats[i].name;
+ }
+ str << "\n";
+ }
+}
+
+void dumpRhiInfo(QTextStream &str)
+{
+ str << "Qt Rendering Hardware Interface supported backends:\n";
+
+#if QT_CONFIG(opengl)
+ {
+ QRhiGles2InitParams params;
+ params.fallbackSurface = QRhiGles2InitParams::newFallbackSurface();
+ dumpRhiBackendInfo(str, "OpenGL (with default QSurfaceFormat)", QRhi::OpenGLES2, &params);
+ delete params.fallbackSurface;
+ }
+#endif
+
+#if QT_CONFIG(vulkan)
+ {
+ QVulkanInstance vulkanInstance;
+ vulkanInstance.create();
+ QRhiVulkanInitParams params;
+ params.inst = &vulkanInstance;
+ dumpRhiBackendInfo(str, "Vulkan", QRhi::Vulkan, &params);
+ vulkanInstance.destroy();
+ }
+#endif
+
+#ifdef Q_OS_WIN
+ {
+ QRhiD3D11InitParams params;
+ dumpRhiBackendInfo(str, "Direct3D 11", QRhi::D3D11, &params);
+ }
+#endif
+
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
+ {
+ QRhiMetalInitParams params;
+ dumpRhiBackendInfo(str, "Metal", QRhi::Metal, &params);
+ }
+#endif
+}
+
#define DUMP_CAPABILITY(str, integration, capability) \
if (platformIntegration->hasCapability(QPlatformIntegration::capability)) \
str << ' ' << #capability;
@@ -480,7 +631,7 @@ QString qtDiag(unsigned flags)
# ifndef QT_NO_SSL
if (QSslSocket::supportsSsl()) {
str << "Using \"" << QSslSocket::sslLibraryVersionString() << "\", version: 0x"
- << hex << QSslSocket::sslLibraryVersionNumber() << dec;
+ << Qt::hex << QSslSocket::sslLibraryVersionNumber() << Qt::dec;
} else {
str << "\nSSL is not supported.";
}
@@ -528,7 +679,7 @@ QString qtDiag(unsigned flags)
if (passwordMaskCharacter.unicode() >= 32 && passwordMaskCharacter.unicode() < 128)
str << '\'' << passwordMaskCharacter << '\'';
else
- str << "U+" << qSetFieldWidth(4) << qSetPadChar('0') << uppercasedigits << hex << passwordMaskCharacter.unicode() << dec << qSetFieldWidth(0);
+ str << "U+" << qSetFieldWidth(4) << qSetPadChar('0') << Qt::uppercasedigits << Qt::hex << passwordMaskCharacter.unicode() << Qt::dec << qSetFieldWidth(0);
str << '\n'
<< " fontSmoothingGamma: " << styleHints->fontSmoothingGamma() << '\n'
<< " useRtlExtensions: " << styleHints->useRtlExtensions() << '\n'
@@ -664,7 +815,7 @@ QString qtDiag(unsigned flags)
#ifndef QT_NO_OPENGL
if (flags & QtDiagGl) {
dumpGlInfo(str, flags & QtDiagGlExtensions);
- str << "\n\n";
+ str << "\n";
}
#else
Q_UNUSED(flags);
@@ -688,8 +839,15 @@ QString qtDiag(unsigned flags)
if (!description.isEmpty())
str << "\nGPU #" << (i + 1) << ":\n" << description << '\n';
}
+ str << "\n";
}
}
+
+ if (flags & QtDiagRhi) {
+ dumpRhiInfo(str);
+ str << "\n";
+ }
+
return result;
}
diff --git a/src/qtdiag/qtdiag.h b/src/qtdiag/qtdiag.h
index 359840647..1317d5a9b 100644
--- a/src/qtdiag/qtdiag.h
+++ b/src/qtdiag/qtdiag.h
@@ -37,7 +37,8 @@ enum QtDiagFlags {
QtDiagGl = 0x1,
QtDiagGlExtensions = 0x2,
QtDiagFonts = 0x4,
- QtDiagVk = 0x8
+ QtDiagVk = 0x8,
+ QtDiagRhi = 0x10
};
QString qtDiag(unsigned flags = 0);
diff --git a/src/qtdiag/qtdiag.pro b/src/qtdiag/qtdiag.pro
index b9b3c6e56..311982f9f 100644
--- a/src/qtdiag/qtdiag.pro
+++ b/src/qtdiag/qtdiag.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(qtdiag))
+
CONFIG += console
QT += core-private gui-private
diff --git a/src/qtpaths/qtpaths.cpp b/src/qtpaths/qtpaths.cpp
index 3166d6a65..340a2ac43 100644
--- a/src/qtpaths/qtpaths.cpp
+++ b/src/qtpaths/qtpaths.cpp
@@ -111,8 +111,8 @@ static const struct StringEnum {
static QStringList types()
{
QStringList typelist;
- for (unsigned int i = 0; i < sizeof(lookupTableData)/sizeof(lookupTableData[0]); i++)
- typelist << QString::fromLatin1(lookupTableData[i].stringvalue);
+ for (const StringEnum &se : lookupTableData)
+ typelist << QString::fromLatin1(se.stringvalue);
std::sort(typelist.begin(), typelist.end());
return typelist;
}
@@ -123,9 +123,9 @@ static QStringList types()
*/
static QStandardPaths::StandardLocation parseLocationOrError(const QString &locationString)
{
- for (unsigned int i = 0; i < sizeof(lookupTableData)/sizeof(lookupTableData[0]); i++)
- if (locationString == QLatin1String(lookupTableData[i].stringvalue))
- return lookupTableData[i].enumvalue;
+ for (const StringEnum &se : lookupTableData)
+ if (locationString == QLatin1String(se.stringvalue))
+ return se.enumvalue;
QString message = QCoreApplication::translate("qtpaths", "Unknown location: %1");
error(message.arg(locationString));
diff --git a/src/qtpaths/qtpaths.pro b/src/qtpaths/qtpaths.pro
index f494c8148..690843f38 100644
--- a/src/qtpaths/qtpaths.pro
+++ b/src/qtpaths/qtpaths.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(qtpaths))
+
SOURCES = qtpaths.cpp
QT = core
win32:CONFIG += console
diff --git a/src/qtplugininfo/qtplugininfo.pro b/src/qtplugininfo/qtplugininfo.pro
index 98feeb986..98b9a34e8 100644
--- a/src/qtplugininfo/qtplugininfo.pro
+++ b/src/qtplugininfo/qtplugininfo.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(qtplugininfo))
+
SOURCES = qtplugininfo.cpp
QT = core
CONFIG += console
diff --git a/src/shared/deviceskin/deviceskin.cpp b/src/shared/deviceskin/deviceskin.cpp
index b8649b9b3..b44f06103 100644
--- a/src/shared/deviceskin/deviceskin.cpp
+++ b/src/shared/deviceskin/deviceskin.cpp
@@ -69,7 +69,7 @@ namespace {
}
static void parseRect(const QString &value, QRect *rect) {
- const QVector<QStringRef> l = value.splitRef(QLatin1Char(' '));
+ const auto l = value.splitRef(QLatin1Char(' '));
rect->setRect(l[0].toInt(), l[1].toInt(), l[2].toInt(), l[3].toInt());
}
@@ -474,7 +474,7 @@ DeviceSkin::~DeviceSkin( )
delete cursorw;
}
-void DeviceSkin::setTransform( const QMatrix& wm )
+void DeviceSkin::setTransform(const QTransform &wm)
{
transform = QImage::trueMatrix(wm,m_parameters.skinImageUp.width(),m_parameters.skinImageUp.height());
calcRegions();
@@ -488,7 +488,7 @@ void DeviceSkin::setTransform( const QMatrix& wm )
void DeviceSkin::setZoom( double z )
{
- setTransform(QMatrix().scale(z,z));
+ setTransform(QTransform().scale(z,z));
}
void DeviceSkin::updateSecondaryScreen()
@@ -535,7 +535,7 @@ void DeviceSkin::paintEvent( QPaintEvent *)
} else {
p.drawPixmap(0, 0, skinImageClosed);
}
- QList<int> toDraw;
+ QVector<int> toDraw;
if ( buttonPressed == true ) {
toDraw += buttonIndex;
}
diff --git a/src/shared/deviceskin/deviceskin.h b/src/shared/deviceskin/deviceskin.h
index 348119d96..fcdb88093 100644
--- a/src/shared/deviceskin/deviceskin.h
+++ b/src/shared/deviceskin/deviceskin.h
@@ -113,7 +113,7 @@ public:
void setSecondaryView( QWidget *v );
void setZoom( double );
- void setTransform( const QMatrix& );
+ void setTransform(const QTransform &);
bool hasCursor() const;
@@ -155,7 +155,7 @@ private:
QPoint clickPos;
bool buttonPressed;
int buttonIndex;
- QMatrix transform;
+ QTransform transform;
qvfb_internal::CursorWindow *cursorw;
bool joydown;
diff --git a/src/shared/fontpanel/fontpanel.cpp b/src/shared/fontpanel/fontpanel.cpp
index 6121421fc..325dad205 100644
--- a/src/shared/fontpanel/fontpanel.cpp
+++ b/src/shared/fontpanel/fontpanel.cpp
@@ -64,11 +64,11 @@ FontPanel::FontPanel(QWidget *parentWidget) :
// writing systems
m_writingSystemComboBox->setEditable(false);
- QList<QFontDatabase::WritingSystem> writingSystems = m_fontDatabase.writingSystems();
+ auto writingSystems = m_fontDatabase.writingSystems();
writingSystems.push_front(QFontDatabase::Any);
for (QFontDatabase::WritingSystem ws : qAsConst(writingSystems))
m_writingSystemComboBox->addItem(QFontDatabase::writingSystemName(ws), QVariant(ws));
- connect(m_writingSystemComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(m_writingSystemComboBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &FontPanel::slotWritingSystemChanged);
formLayout->addRow(tr("&Writing system"), m_writingSystemComboBox);
@@ -77,12 +77,12 @@ FontPanel::FontPanel(QWidget *parentWidget) :
formLayout->addRow(tr("&Family"), m_familyComboBox);
m_styleComboBox->setEditable(false);
- connect(m_styleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(m_styleComboBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &FontPanel::slotStyleChanged);
formLayout->addRow(tr("&Style"), m_styleComboBox);
m_pointSizeComboBox->setEditable(false);
- connect(m_pointSizeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ connect(m_pointSizeComboBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
this, &FontPanel::slotPointSizeChanged);
formLayout->addRow(tr("&Point size"), m_pointSizeComboBox);
@@ -119,10 +119,10 @@ void FontPanel::setSelectedFont(const QFont &f)
if (m_familyComboBox->currentIndex() < 0) {
// family not in writing system - find the corresponding one?
QList<QFontDatabase::WritingSystem> familyWritingSystems = m_fontDatabase.writingSystems(f.family());
- if (familyWritingSystems.empty())
+ if (familyWritingSystems.isEmpty())
return;
- setWritingSystem(familyWritingSystems.front());
+ setWritingSystem(familyWritingSystems.constFirst());
m_familyComboBox->setCurrentFont(f);
}
@@ -213,7 +213,7 @@ void FontPanel::updateFamily(const QString &family)
const QString &oldStyleString = styleString();
const QStringList &styles = m_fontDatabase.styles(family);
- const bool hasStyles = !styles.empty();
+ const bool hasStyles = !styles.isEmpty();
m_styleComboBox->setCurrentIndex(-1);
m_styleComboBox->clear();
@@ -269,11 +269,11 @@ void FontPanel::updatePointSizes(const QString &family, const QString &styleStri
{
const int oldPointSize = pointSize();
- QList<int> pointSizes = m_fontDatabase.pointSizes(family, styleString);
- if (pointSizes.empty())
+ auto pointSizes = m_fontDatabase.pointSizes(family, styleString);
+ if (pointSizes.isEmpty())
pointSizes = QFontDatabase::standardSizes();
- const bool hasSizes = !pointSizes.empty();
+ const bool hasSizes = !pointSizes.isEmpty();
m_pointSizeComboBox->clear();
m_pointSizeComboBox->setEnabled(hasSizes);
m_pointSizeComboBox->setCurrentIndex(-1);
diff --git a/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
index 57303f009..9fb44469a 100644
--- a/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
+++ b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
@@ -402,7 +402,7 @@ void QtGradientStopsControllerPrivate::slotChangeColor(const QColor &color)
if (!stop)
return;
m_model->changeStop(stop, color);
- const QList<QtGradientStop *> stops = m_model->selectedStops();
+ const auto stops = m_model->selectedStops();
for (QtGradientStop *s : stops) {
if (s != stop)
m_model->changeStop(s, color);
@@ -415,7 +415,7 @@ void QtGradientStopsControllerPrivate::slotChangeHue(const QColor &color)
if (!stop)
return;
m_model->changeStop(stop, color);
- const QList<QtGradientStop *> stops = m_model->selectedStops();
+ const auto stops = m_model->selectedStops();
for (QtGradientStop *s : stops) {
if (s != stop) {
QColor c = s->color();
@@ -444,7 +444,7 @@ void QtGradientStopsControllerPrivate::slotChangeSaturation(const QColor &color)
if (!stop)
return;
m_model->changeStop(stop, color);
- const QList<QtGradientStop *> stops = m_model->selectedStops();
+ const auto stops = m_model->selectedStops();
for (QtGradientStop *s : stops) {
if (s != stop) {
QColor c = s->color();
@@ -477,7 +477,7 @@ void QtGradientStopsControllerPrivate::slotChangeValue(const QColor &color)
if (!stop)
return;
m_model->changeStop(stop, color);
- const QList<QtGradientStop *> stops = m_model->selectedStops();
+ const auto stops = m_model->selectedStops();
for (QtGradientStop *s : stops) {
if (s != stop) {
QColor c = s->color();
@@ -510,7 +510,7 @@ void QtGradientStopsControllerPrivate::slotChangeAlpha(const QColor &color)
if (!stop)
return;
m_model->changeStop(stop, color);
- const QList<QtGradientStop *> stops = m_model->selectedStops();
+ const auto stops = m_model->selectedStops();
for (QtGradientStop *s : stops) {
if (s != stop) {
QColor c = s->color();
@@ -676,7 +676,7 @@ void QtGradientStopsController::setGradientStops(const QGradientStops &stops)
QGradientStops QtGradientStopsController::gradientStops() const
{
QGradientStops stops;
- const QList<QtGradientStop *> stopsList = d_ptr->m_model->stops().values();
+ const auto stopsList = d_ptr->m_model->stops().values();
for (const QtGradientStop *stop : stopsList)
stops << QPair<qreal, QColor>(stop->position(), stop->color());
return stops;
diff --git a/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
index d35c1f025..0afbf49bb 100644
--- a/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
+++ b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
@@ -375,7 +375,7 @@ void QtGradientStopsModel::moveStops(double newPosition)
PositionStopMap stopList;
- const QList<QtGradientStop *> selected = selectedStops();
+ const auto selected = selectedStops();
for (QtGradientStop *stop : selected)
stopList[stop->position()] = stop;
stopList[current->position()] = current;
@@ -406,14 +406,14 @@ void QtGradientStopsModel::moveStops(double newPosition)
void QtGradientStopsModel::clear()
{
- const QList<QtGradientStop *> stopsList = stops().values();
+ const auto stopsList = stops().values();
for (QtGradientStop *stop : stopsList)
removeStop(stop);
}
void QtGradientStopsModel::clearSelection()
{
- const QList<QtGradientStop *> stopsList = selectedStops();
+ const auto stopsList = selectedStops();
for (QtGradientStop *stop : stopsList)
selectStop(stop, false);
}
@@ -452,7 +452,7 @@ void QtGradientStopsModel::selectAll()
void QtGradientStopsModel::deleteStops()
{
- const QList<QtGradientStop *> selected = selectedStops();
+ const auto selected = selectedStops();
for (QtGradientStop *stop : selected)
removeStop(stop);
QtGradientStop *current = currentStop();
diff --git a/src/shared/qtgradienteditor/qtgradientstopswidget.cpp b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
index 3bfd30627..49569869e 100644
--- a/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
+++ b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
@@ -170,7 +170,7 @@ void QtGradientStopsWidgetPrivate::setupMove(QtGradientStop *stop, int x)
int viewportX = qRound(toViewport(stop->position()));
m_moveOffset = x - viewportX;
- const QList<QtGradientStop *> stops = m_stops;
+ const auto stops = m_stops;
m_stops.clear();
for (QtGradientStop *s : stops) {
if (m_model->isSelected(s) || s == stop) {
@@ -450,7 +450,7 @@ void QtGradientStopsWidget::setGradientStopsModel(QtGradientStopsModel *model)
for (auto it = stopsMap.cbegin(), end = stopsMap.cend(); it != end; ++it)
d_ptr->slotStopAdded(it.value());
- const QList<QtGradientStop *> selected = d_ptr->m_model->selectedStops();
+ const auto selected = d_ptr->m_model->selectedStops();
for (QtGradientStop *stop : selected)
d_ptr->slotStopSelected(stop, true);
@@ -652,8 +652,8 @@ void QtGradientStopsWidget::mouseMoveEvent(QMouseEvent *e)
p2 = QPoint(xv2, qRound(d_ptr->m_handleSize / 2));
}
- QList<QtGradientStop *> beginList = d_ptr->stopsAt(p1);
- QList<QtGradientStop *> endList = d_ptr->stopsAt(p2);
+ const auto beginList = d_ptr->stopsAt(p1);
+ const auto endList = d_ptr->stopsAt(p2);
double x1 = d_ptr->fromViewport(xv1);
double x2 = d_ptr->fromViewport(xv2);
diff --git a/src/shared/qtgradienteditor/qtgradientwidget.cpp b/src/shared/qtgradienteditor/qtgradientwidget.cpp
index 9db1b82e6..ebd5ba159 100644
--- a/src/shared/qtgradienteditor/qtgradientwidget.cpp
+++ b/src/shared/qtgradienteditor/qtgradientwidget.cpp
@@ -203,7 +203,7 @@ void QtGradientWidgetPrivate::setupDrag(QtGradientStop *stop, int x)
int viewportX = qRound(toViewport(stop->position()));
m_dragOffset = x - viewportX;
- const QList<QtGradientStop *> stops = m_stops;
+ const auto stops = m_stops;
m_stops.clear();
for (QtGradientStop *s : stops) {
if (m_model->isSelected(s) || s == stop) {
diff --git a/src/shared/qtpropertybrowser/qteditorfactory.cpp b/src/shared/qtpropertybrowser/qteditorfactory.cpp
index 664667c65..c83d20cfd 100644
--- a/src/shared/qtpropertybrowser/qteditorfactory.cpp
+++ b/src/shared/qtpropertybrowser/qteditorfactory.cpp
@@ -124,7 +124,7 @@ void EditorFactoryPrivate<Editor>::slotEditorDestroyed(QObject *object)
const typename PropertyToEditorListMap::iterator pit = m_createdEditors.find(property);
if (pit != m_createdEditors.end()) {
pit.value().removeAll(editor);
- if (pit.value().empty())
+ if (pit.value().isEmpty())
m_createdEditors.erase(pit);
}
m_editorToProperty.erase(itEditor);
@@ -1543,7 +1543,7 @@ bool QtCharEdit::eventFilter(QObject *o, QEvent *e)
if (o == m_lineEdit && e->type() == QEvent::ContextMenu) {
QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
QMenu *menu = m_lineEdit->createStandardContextMenu();
- const QList<QAction *> actions = menu->actions();
+ const auto actions = menu->actions();
for (QAction *action : actions) {
action->setShortcut(QKeySequence());
QString actionString = action->text();
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtpropertybrowser.cpp
index 0e892a2ee..601fb854a 100644
--- a/src/shared/qtpropertybrowser/qtpropertybrowser.cpp
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.cpp
@@ -452,7 +452,7 @@ void QtProperty::insertSubProperty(QtProperty *property,
return;
// traverse all children of item. if this item is a child of item then cannot add.
- QList<QtProperty *> pendingList = property->subProperties();
+ auto pendingList = property->subProperties();
QMap<QtProperty *, bool> visited;
while (!pendingList.isEmpty()) {
QtProperty *i = pendingList.first();
@@ -499,7 +499,7 @@ void QtProperty::removeSubProperty(QtProperty *property)
d_ptr->m_manager->d_ptr->propertyRemoved(property, this);
- QList<QtProperty *> pendingList = subProperties();
+ auto pendingList = subProperties();
int pos = 0;
while (pos < pendingList.count()) {
if (pendingList.at(pos) == property) {
@@ -1279,7 +1279,7 @@ void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property,
m_managerToProperties[manager].append(property);
m_propertyToParents[property].append(parentProperty);
- const QList<QtProperty *> subList = property->subProperties();
+ const auto subList = property->subProperties();
for (QtProperty *subProperty : subList)
insertSubTree(subProperty, property);
}
@@ -1316,7 +1316,7 @@ void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property,
m_managerToProperties.remove(manager);
}
- const QList<QtProperty *> subList = property->subProperties();
+ const auto subList = property->subProperties();
for (QtProperty *subProperty : subList)
removeSubTree(subProperty, property);
}
@@ -1325,8 +1325,7 @@ void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property
{
QMap<QtBrowserItem *, QtBrowserItem *> parentToAfter;
if (afterProperty) {
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.constFind(afterProperty);
+ const auto it = m_propertyToIndexes.constFind(afterProperty);
if (it == m_propertyToIndexes.constEnd())
return;
@@ -1336,8 +1335,7 @@ void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property
parentToAfter[idx->parent()] = idx;
}
} else if (parentProperty) {
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.find(parentProperty);
+ const auto it = m_propertyToIndexes.find(parentProperty);
if (it == m_propertyToIndexes.constEnd())
return;
@@ -1366,7 +1364,7 @@ QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *
q_ptr->itemInserted(newIndex, afterIndex);
- const QList<QtProperty *> subItems = property->subProperties();
+ const auto subItems = property->subProperties();
QtBrowserItem *afterChild = 0;
for (QtProperty *child : subItems)
afterChild = createBrowserIndex(child, newIndex, afterChild);
@@ -1376,8 +1374,7 @@ QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *
void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty)
{
QList<QtBrowserItem *> toRemove;
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.constFind(property);
+ const auto it = m_propertyToIndexes.constFind(property);
if (it == m_propertyToIndexes.constEnd())
return;
@@ -1393,7 +1390,7 @@ void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property
void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index)
{
- QList<QtBrowserItem *> children = index->children();
+ const auto children = index->children();
for (int i = children.count(); i > 0; i--) {
removeBrowserIndex(children.at(i - 1));
}
@@ -1418,7 +1415,7 @@ void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index)
void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index)
{
- const QList<QtBrowserItem *> children = index->children();
+ const auto children = index->children();
for (QtBrowserItem *item : children)
clearIndex(item);
delete index;
@@ -1456,12 +1453,11 @@ void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *prope
if (!m_propertyToParents.contains(property))
return;
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.find(property);
+ const auto it = m_propertyToIndexes.constFind(property);
if (it == m_propertyToIndexes.constEnd())
return;
- const QList<QtBrowserItem *> indexes = it.value();
+ const auto indexes = it.value();
for (QtBrowserItem *idx : indexes)
q_ptr->itemChanged(idx);
//q_ptr->propertyChanged(property);
@@ -1662,7 +1658,7 @@ QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent)
*/
QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser()
{
- const QList<QtBrowserItem *> indexes = topLevelItems();
+ const auto indexes = topLevelItems();
for (QtBrowserItem *item : indexes)
d_ptr->clearIndex(item);
}
@@ -1727,7 +1723,7 @@ QList<QtBrowserItem *> QtAbstractPropertyBrowser::topLevelItems() const
*/
void QtAbstractPropertyBrowser::clear()
{
- const QList<QtProperty *> subList = properties();
+ const auto subList = properties();
for (auto rit = subList.crbegin(), rend = subList.crend(); rit != rend; ++rit)
removeProperty(*rit);
}
@@ -1775,7 +1771,7 @@ QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
return 0;
// if item is already inserted in this item then cannot add.
- QList<QtProperty *> pendingList = properties();
+ auto pendingList = properties();
int pos = 0;
int newPos = 0;
while (pos < pendingList.count()) {
@@ -1813,7 +1809,7 @@ void QtAbstractPropertyBrowser::removeProperty(QtProperty *property)
if (!property)
return;
- QList<QtProperty *> pendingList = properties();
+ auto pendingList = properties();
int pos = 0;
while (pos < pendingList.count()) {
if (pendingList.at(pos) == property) {
diff --git a/src/shared/qtpropertybrowser/qtpropertymanager.cpp b/src/shared/qtpropertybrowser/qtpropertymanager.cpp
index 40a459c59..c1aeb624c 100644
--- a/src/shared/qtpropertybrowser/qtpropertymanager.cpp
+++ b/src/shared/qtpropertybrowser/qtpropertymanager.cpp
@@ -428,7 +428,7 @@ void QtMetaEnumProvider::initLocale()
if (!nameToLanguage.contains(QLocale::languageToString(system.language())))
nameToLanguage.insert(QLocale::languageToString(system.language()), system.language());
- const QList<QLocale::Language> languages = nameToLanguage.values();
+ const auto languages = nameToLanguage.values();
for (QLocale::Language language : languages) {
QList<QLocale::Country> countries;
countries = QLocale::countriesForLanguage(language);
@@ -5660,7 +5660,7 @@ void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange()
m_familyNames = fontDatabase()->families();
// Adapt all existing properties
- if (!m_propertyToFamily.empty()) {
+ if (!m_propertyToFamily.isEmpty()) {
PropertyPropertyMap::const_iterator cend = m_propertyToFamily.constEnd();
for (PropertyPropertyMap::const_iterator it = m_propertyToFamily.constBegin(); it != cend; ++it) {
QtProperty *familyProp = it.value();
@@ -5875,7 +5875,7 @@ void QtFontPropertyManager::initializeProperty(QtProperty *property)
QtProperty *familyProp = d_ptr->m_enumPropertyManager->addProperty();
familyProp->setPropertyName(tr("Family"));
- if (d_ptr->m_familyNames.empty())
+ if (d_ptr->m_familyNames.isEmpty())
d_ptr->m_familyNames = fontDatabase()->families();
d_ptr->m_enumPropertyManager->setEnumNames(familyProp, d_ptr->m_familyNames);
int idx = d_ptr->m_familyNames.indexOf(val.family());
diff --git a/src/shared/qtpropertybrowser/qtvariantproperty.cpp b/src/shared/qtpropertybrowser/qtvariantproperty.cpp
index e776f85fb..1ddc64fbc 100644
--- a/src/shared/qtpropertybrowser/qtvariantproperty.cpp
+++ b/src/shared/qtpropertybrowser/qtvariantproperty.cpp
@@ -1784,7 +1784,7 @@ void QtVariantPropertyManager::initializeProperty(QtProperty *property)
}
propertyToWrappedProperty()->insert(varProp, internProp);
if (internProp) {
- const QList<QtProperty *> children = internProp->subProperties();
+ const auto children = internProp->subProperties();
QtVariantProperty *lastProperty = 0;
for (QtProperty *child : children) {
QtVariantProperty *prop = d_ptr->createSubProperty(varProp, lastProperty, child);
@@ -1993,87 +1993,87 @@ QtVariantEditorFactory::~QtVariantEditorFactory()
*/
void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager)
{
- const QList<QtIntPropertyManager *> intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
+ const auto intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
for (QtIntPropertyManager *manager : intPropertyManagers)
d_ptr->m_spinBoxFactory->addPropertyManager(manager);
- const QList<QtDoublePropertyManager *> doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
+ const auto doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
for (QtDoublePropertyManager *manager : doublePropertyManagers)
d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager);
- const QList<QtBoolPropertyManager *> boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
+ const auto boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
for (QtBoolPropertyManager *manager : boolPropertyManagers)
d_ptr->m_checkBoxFactory->addPropertyManager(manager);
- const QList<QtStringPropertyManager *> stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
+ const auto stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
for (QtStringPropertyManager *manager : stringPropertyManagers)
d_ptr->m_lineEditFactory->addPropertyManager(manager);
- const QList<QtDatePropertyManager *> datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
+ const auto datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
for (QtDatePropertyManager *manager : datePropertyManagers)
d_ptr->m_dateEditFactory->addPropertyManager(manager);
- const QList<QtTimePropertyManager *> timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
+ const auto timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
for (QtTimePropertyManager *manager : timePropertyManagers)
d_ptr->m_timeEditFactory->addPropertyManager(manager);
- const QList<QtDateTimePropertyManager *> dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
+ const auto dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
for (QtDateTimePropertyManager *manager : dateTimePropertyManagers)
d_ptr->m_dateTimeEditFactory->addPropertyManager(manager);
- const QList<QtKeySequencePropertyManager *> keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
+ const auto keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
for (QtKeySequencePropertyManager *manager : keySequencePropertyManagers)
d_ptr->m_keySequenceEditorFactory->addPropertyManager(manager);
- const QList<QtCharPropertyManager *> charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
+ const auto charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
for (QtCharPropertyManager *manager : charPropertyManagers)
d_ptr->m_charEditorFactory->addPropertyManager(manager);
- const QList<QtLocalePropertyManager *> localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
+ const auto localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
for (QtLocalePropertyManager *manager : localePropertyManagers)
d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager());
- const QList<QtPointPropertyManager *> pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
+ const auto pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
for (QtPointPropertyManager *manager : pointPropertyManagers)
d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
- const QList<QtPointFPropertyManager *> pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
+ const auto pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
for (QtPointFPropertyManager *manager : pointFPropertyManagers)
d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager->subDoublePropertyManager());
- const QList<QtSizePropertyManager *> sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
+ const auto sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
for (QtSizePropertyManager *manager : sizePropertyManagers)
d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
- const QList<QtSizeFPropertyManager *> sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
+ const auto sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
for (QtSizeFPropertyManager *manager : sizeFPropertyManagers)
d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager->subDoublePropertyManager());
- const QList<QtRectPropertyManager *> rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
+ const auto rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
for (QtRectPropertyManager *manager : rectPropertyManagers)
d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
- const QList<QtRectFPropertyManager *> rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
+ const auto rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
for (QtRectFPropertyManager *manager : rectFPropertyManagers)
d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager->subDoublePropertyManager());
- const QList<QtColorPropertyManager *> colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
+ const auto colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
for (QtColorPropertyManager *manager : colorPropertyManagers) {
d_ptr->m_colorEditorFactory->addPropertyManager(manager);
d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
}
- const QList<QtEnumPropertyManager *> enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
+ const auto enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
for (QtEnumPropertyManager *manager : enumPropertyManagers)
d_ptr->m_comboBoxFactory->addPropertyManager(manager);
- const QList<QtSizePolicyPropertyManager *> sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
+ const auto sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
for (QtSizePolicyPropertyManager *manager : sizePolicyPropertyManagers) {
d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager());
}
- const QList<QtFontPropertyManager *> fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
+ const auto fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
for (QtFontPropertyManager *manager : fontPropertyManagers) {
d_ptr->m_fontEditorFactory->addPropertyManager(manager);
d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
@@ -2081,11 +2081,11 @@ void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *ma
d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager());
}
- const QList<QtCursorPropertyManager *> cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
+ const auto cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
for (QtCursorPropertyManager *manager : cursorPropertyManagers)
d_ptr->m_cursorEditorFactory->addPropertyManager(manager);
- const QList<QtFlagPropertyManager *> flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
+ const auto flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
for (QtFlagPropertyManager *manager : flagPropertyManagers)
d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager());
}
@@ -2112,87 +2112,87 @@ QWidget *QtVariantEditorFactory::createEditor(QtVariantPropertyManager *manager,
*/
void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager)
{
- const QList<QtIntPropertyManager *> intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
+ const auto intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
for (QtIntPropertyManager *manager : intPropertyManagers)
d_ptr->m_spinBoxFactory->removePropertyManager(manager);
- const QList<QtDoublePropertyManager *> doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
+ const auto doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
for (QtDoublePropertyManager *manager : doublePropertyManagers)
d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager);
- const QList<QtBoolPropertyManager *> boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
+ const auto boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
for (QtBoolPropertyManager *manager : boolPropertyManagers)
d_ptr->m_checkBoxFactory->removePropertyManager(manager);
- const QList<QtStringPropertyManager *> stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
+ const auto stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
for (QtStringPropertyManager *manager : stringPropertyManagers)
d_ptr->m_lineEditFactory->removePropertyManager(manager);
- const QList<QtDatePropertyManager *> datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
+ const auto datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
for (QtDatePropertyManager *manager : datePropertyManagers)
d_ptr->m_dateEditFactory->removePropertyManager(manager);
- const QList<QtTimePropertyManager *> timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
+ const auto timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
for (QtTimePropertyManager *manager : timePropertyManagers)
d_ptr->m_timeEditFactory->removePropertyManager(manager);
- const QList<QtDateTimePropertyManager *> dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
+ const auto dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
for (QtDateTimePropertyManager *manager : dateTimePropertyManagers)
d_ptr->m_dateTimeEditFactory->removePropertyManager(manager);
- const QList<QtKeySequencePropertyManager *> keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
+ const auto keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
for (QtKeySequencePropertyManager *manager : keySequencePropertyManagers)
d_ptr->m_keySequenceEditorFactory->removePropertyManager(manager);
- const QList<QtCharPropertyManager *> charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
+ const auto charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
for (QtCharPropertyManager *manager : charPropertyManagers)
d_ptr->m_charEditorFactory->removePropertyManager(manager);
- const QList<QtLocalePropertyManager *> localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
+ const auto localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
for (QtLocalePropertyManager *manager : localePropertyManagers)
d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager());
- const QList<QtPointPropertyManager *> pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
+ const auto pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
for (QtPointPropertyManager *manager : pointPropertyManagers)
d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
- const QList<QtPointFPropertyManager *> pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
+ const auto pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
for (QtPointFPropertyManager *manager : pointFPropertyManagers)
d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager->subDoublePropertyManager());
- const QList<QtSizePropertyManager *> sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
+ const auto sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
for (QtSizePropertyManager *manager : sizePropertyManagers)
d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
- const QList<QtSizeFPropertyManager *> sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
+ const auto sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
for (QtSizeFPropertyManager *manager : sizeFPropertyManagers)
d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager->subDoublePropertyManager());
- const QList<QtRectPropertyManager *> rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
+ const auto rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
for (QtRectPropertyManager *manager : rectPropertyManagers)
d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
- const QList<QtRectFPropertyManager *> rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
+ const auto rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
for (QtRectFPropertyManager *manager : rectFPropertyManagers)
d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager->subDoublePropertyManager());
- const QList<QtColorPropertyManager *> colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
+ const auto colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
for (QtColorPropertyManager *manager : colorPropertyManagers) {
d_ptr->m_colorEditorFactory->removePropertyManager(manager);
d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
}
- const QList<QtEnumPropertyManager *> enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
+ const auto enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
for (QtEnumPropertyManager *manager : enumPropertyManagers)
d_ptr->m_comboBoxFactory->removePropertyManager(manager);
- const QList<QtSizePolicyPropertyManager *> sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
+ const auto sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
for (QtSizePolicyPropertyManager *manager : sizePolicyPropertyManagers) {
d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager());
}
- const QList<QtFontPropertyManager *> fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
+ const auto fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
for (QtFontPropertyManager *manager : fontPropertyManagers) {
d_ptr->m_fontEditorFactory->removePropertyManager(manager);
d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
@@ -2200,11 +2200,11 @@ void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager
d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager());
}
- const QList<QtCursorPropertyManager *> cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
+ const auto cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
for (QtCursorPropertyManager *manager : cursorPropertyManagers)
d_ptr->m_cursorEditorFactory->removePropertyManager(manager);
- const QList<QtFlagPropertyManager *> flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
+ const auto flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
for (QtFlagPropertyManager *manager : flagPropertyManagers)
d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager());
}
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.cpp b/src/shared/qttoolbardialog/qttoolbardialog.cpp
index bce8e4345..58f317fd3 100644
--- a/src/shared/qttoolbardialog/qttoolbardialog.cpp
+++ b/src/shared/qttoolbardialog/qttoolbardialog.cpp
@@ -173,14 +173,14 @@ QToolBar *QtFullToolBarManagerPrivate::toolBarWidgetAction(QAction *action) cons
void QtFullToolBarManagerPrivate::removeWidgetActions(const QMap<QToolBar *, QList<QAction *> >
&actions)
{
- QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = actions.constBegin();
+ auto itToolBar = actions.constBegin();
while (itToolBar != actions.constEnd()) {
QToolBar *toolBar = itToolBar.key();
- QList<QAction *> newActions = toolBars.value(toolBar);
- QList<QAction *> newActionsWithSeparators = toolBarsWithSeparators.value(toolBar);
+ auto newActions = toolBars.value(toolBar);
+ auto newActionsWithSeparators = toolBarsWithSeparators.value(toolBar);
QList<QAction *> removedActions;
- const QList<QAction *> actionList = itToolBar.value();
+ const auto actionList = itToolBar.value();
for (QAction *action : actionList) {
if (newActions.contains(action) && toolBarWidgetAction(action) == toolBar) {
newActions.removeAll(action);
@@ -206,8 +206,7 @@ void QtFullToolBarManagerPrivate::saveState(QDataStream &stream) const
{
stream << (uchar) ToolBarMarker;
stream << defaultToolBars.size();
- QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar =
- defaultToolBars.constBegin();
+ auto itToolBar = defaultToolBars.constBegin();
while (itToolBar != defaultToolBars.constEnd()) {
QToolBar *tb = itToolBar.key();
if (tb->objectName().isEmpty()) {
@@ -219,7 +218,7 @@ void QtFullToolBarManagerPrivate::saveState(QDataStream &stream) const
stream << tb->objectName();
}
- const QList<QAction *> actions = toolBars.value(tb);
+ const auto actions = toolBars.value(tb);
stream << actions.size();
for (QAction *action : actions) {
if (action) {
@@ -250,7 +249,7 @@ void QtFullToolBarManagerPrivate::saveState(QDataStream &stream) const
stream << toolBars[tb].size();
- const QList<QAction *> actions = toolBars.value(tb);
+ const auto actions = toolBars.value(tb);
for (QAction *action : actions) {
if (action) {
if (action->objectName().isEmpty()) {
@@ -310,7 +309,7 @@ bool QtFullToolBarManagerPrivate::restoreState(QDataStream &stream) const
if (ctmarker != CustomToolBarMarker)
return false;
- QList<QToolBar *> oldCustomToolBars = customToolBars;
+ auto oldCustomToolBars = customToolBars;
stream >> toolBars;
for (int i = 0; i < toolBars; i++) {
@@ -353,8 +352,7 @@ bool QtFullToolBarManagerPrivate::restoreState(QDataStream &stream) const
QToolBar *QtFullToolBarManagerPrivate::findDefaultToolBar(const QString &objectName) const
{
- QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar =
- defaultToolBars.constBegin();
+ auto itToolBar = defaultToolBars.constBegin();
while (itToolBar != defaultToolBars.constEnd()) {
QToolBar *tb = itToolBar.key();
if (tb->objectName() == objectName)
@@ -406,7 +404,7 @@ QAction *QtFullToolBarManagerPrivate::findAction(const QString &actionName) cons
QToolBar *QtFullToolBarManagerPrivate::toolBarByName(const QString &toolBarName) const
{
- QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = toolBars.constBegin();
+ auto itToolBar = toolBars.constBegin();
while (itToolBar != toolBars.constEnd()) {
QToolBar *toolBar = itToolBar.key();
if (toolBar->objectName() == toolBarName)
@@ -456,11 +454,10 @@ QStringList QtFullToolBarManager::categories() const
QList<QAction *> QtFullToolBarManager::categoryActions(const QString &category) const
{
- QMap<QString, QList<QAction *> >::ConstIterator it =
- d_ptr->categoryToActions.find(category);
+ const auto it = d_ptr->categoryToActions.constFind(category);
if (it != d_ptr->categoryToActions.constEnd())
return it.value();
- return QList<QAction *>();
+ return {};
}
QString QtFullToolBarManager::actionCategory(QAction *action) const
@@ -494,7 +491,7 @@ void QtFullToolBarManager::removeAction(QAction *action)
if (!d_ptr->allActions.contains(action))
return;
- const QList<QToolBar *> toolBars = d_ptr->actionToToolBars[action];
+ const auto toolBars = d_ptr->actionToToolBars[action];
for (QToolBar *toolBar : toolBars) {
d_ptr->toolBars[toolBar].removeAll(action);
d_ptr->toolBarsWithSeparators[toolBar].removeAll(action);
@@ -502,8 +499,7 @@ void QtFullToolBarManager::removeAction(QAction *action)
toolBar->removeAction(action);
}
- QMap<QToolBar *, QList<QAction *> >::ConstIterator itDefault =
- d_ptr->defaultToolBars.constBegin();
+ auto itDefault = d_ptr->defaultToolBars.constBegin();
while (itDefault != d_ptr->defaultToolBars.constEnd()) {
if (itDefault.value().contains(action))
d_ptr->defaultToolBars[itDefault.key()].removeAll(action);
@@ -546,7 +542,7 @@ void QtFullToolBarManager::addDefaultToolBar(QToolBar *toolBar, const QString &c
QList<QAction *> newActionsWithSeparators;
QList<QAction *> newActions;
- const QList<QAction *> actions = toolBar->actions();
+ const auto actions = toolBar->actions();
for (QAction *action : actions) {
addAction(action, category);
if (d_ptr->widgetActions.contains(action))
@@ -569,7 +565,7 @@ void QtFullToolBarManager::removeDefaultToolBar(QToolBar *toolBar)
if (!d_ptr->defaultToolBars.contains(toolBar))
return;
- const QList<QAction *> defaultActions = d_ptr->defaultToolBars[toolBar];
+ const auto defaultActions = d_ptr->defaultToolBars[toolBar];
setToolBar(toolBar, QList<QAction *>());
for (QAction *action : defaultActions)
removeAction(action);
@@ -638,7 +634,7 @@ QList<QAction *> QtFullToolBarManager::actions(QToolBar *toolBar) const
void QtFullToolBarManager::setToolBars(const QMap<QToolBar *, QList<QAction *> > &actions)
{
- QMap<QToolBar *, QList<QAction *> >::ConstIterator it = actions.constBegin();
+ auto it = actions.constBegin();
while (it != actions.constEnd()) {
setToolBar(it.key(), it.value());
++it;
@@ -669,7 +665,7 @@ void QtFullToolBarManager::setToolBar(QToolBar *toolBar, const QList<QAction *>
d_ptr->removeWidgetActions(toRemove);
- const QList<QAction *> oldActions = d_ptr->toolBarsWithSeparators.value(toolBar);
+ const auto oldActions = d_ptr->toolBarsWithSeparators.value(toolBar);
for (QAction *action : oldActions) {
/*
When addDefaultToolBar() separator actions could be checked if they are
@@ -715,7 +711,7 @@ void QtFullToolBarManager::resetToolBar(QToolBar *toolBar)
void QtFullToolBarManager::resetAllToolBars()
{
setToolBars(defaultToolBars());
- const QList<QToolBar *> oldCustomToolBars = d_ptr->customToolBars;
+ const auto oldCustomToolBars = d_ptr->customToolBars;
for (QToolBar *tb : oldCustomToolBars)
deleteToolBar(tb);
}
@@ -1097,7 +1093,7 @@ void QtToolBarDialogPrivate::fillNew()
for (const QString &category : categories) {
QTreeWidgetItem *categoryItem = new QTreeWidgetItem(ui.actionTree);
categoryItem->setText(0, category);
- const QList<QAction *> actions = toolBarManager->categoryActions(category);
+ const auto actions = toolBarManager->categoryActions(category);
for (QAction *action : actions) {
item = new QTreeWidgetItem(categoryItem);
item->setText(0, action->text());
@@ -1115,8 +1111,8 @@ void QtToolBarDialogPrivate::fillNew()
}
//ui.actionTree->sortItems(0, Qt::AscendingOrder);
- QMap<QToolBar *, QList<QAction *> > toolBars = toolBarManager->toolBarsActions();
- QMap<QToolBar *, QList<QAction *> >::ConstIterator it = toolBars.constBegin();
+ const auto toolBars = toolBarManager->toolBarsActions();
+ auto it = toolBars.constBegin();
while (it != toolBars.constEnd()) {
QToolBar *toolBar = it.key();
ToolBarItem *tbItem = createItem(toolBar);
@@ -1125,7 +1121,7 @@ void QtToolBarDialogPrivate::fillNew()
ui.toolBarList);
toolBarToItem.insert(tbItem, item);
itemToToolBar.insert(item, tbItem);
- const QList<QAction *> actions = it.value();
+ const auto actions = it.value();
for (QAction *action : actions) {
if (toolBarManager->isWidgetAction(action)) {
widgetActionToToolBar.insert(action, tbItem);
@@ -1257,8 +1253,8 @@ void QtToolBarDialogPrivate::removeClicked()
void QtToolBarDialogPrivate::defaultClicked()
{
- QMap<QToolBar *, QList<QAction *> > defaultToolBars = toolBarManager->defaultToolBars();
- QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = defaultToolBars.constBegin();
+ const auto defaultToolBars = toolBarManager->defaultToolBars();
+ auto itToolBar = defaultToolBars.constBegin();
while (itToolBar != defaultToolBars.constEnd()) {
QToolBar *toolBar = itToolBar.key();
ToolBarItem *toolBarItem = toolBarItems.value(toolBar);
@@ -1289,7 +1285,7 @@ void QtToolBarDialogPrivate::defaultClicked()
}
currentToolBarChanged(toolBarToItem.value(currentToolBar));
- const QList<ToolBarItem *> toolBars = currentState.keys();
+ const auto toolBars = currentState.keys();
for (ToolBarItem *tb : toolBars)
removeToolBar(tb);
}
@@ -1302,8 +1298,8 @@ void QtToolBarDialogPrivate::okClicked()
void QtToolBarDialogPrivate::applyClicked()
{
- QMap<ToolBarItem *, QList<QAction *> > toolBars = currentState;
- QMap<ToolBarItem *, QList<QAction *> >::ConstIterator itToolBar = toolBars.constBegin();
+ const auto toolBars = currentState;
+ auto itToolBar = toolBars.constBegin();
while (itToolBar != toolBars.constEnd()) {
ToolBarItem *item = itToolBar.key();
QToolBar *toolBar = item->toolBar();
@@ -1329,7 +1325,7 @@ void QtToolBarDialogPrivate::applyClicked()
for (ToolBarItem *item : toCreate) {
QString toolBarName = item->toolBarName();
createdItems.remove(item);
- QList<QAction *> actions = currentState.value(item);
+ const auto actions = currentState.value(item);
QToolBar *toolBar = toolBarManager->createToolBar(toolBarName);
item->setToolBar(toolBar);
toolBarManager->setToolBar(toolBar, actions);
@@ -1347,7 +1343,7 @@ void QtToolBarDialogPrivate::upClicked()
ui.currentToolBarList->takeItem(row);
int newRow = row - 1;
ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
- QList<QAction *> actions = currentState.value(currentToolBar);
+ auto actions = currentState.value(currentToolBar);
QAction *action = actions.at(row);
actions.removeAt(row);
actions.insert(newRow, action);
@@ -1367,7 +1363,7 @@ void QtToolBarDialogPrivate::downClicked()
ui.currentToolBarList->takeItem(row);
int newRow = row + 1;
ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
- QList<QAction *> actions = currentState.value(currentToolBar);
+ auto actions = currentState.value(currentToolBar);
QAction *action = actions.at(row);
actions.removeAt(row);
actions.insert(newRow, action);
@@ -1388,7 +1384,7 @@ void QtToolBarDialogPrivate::leftClicked()
ToolBarItem *item = widgetActionToToolBar.value(action);
if (item == currentToolBar) { // have to be
toolBarToWidgetActions[item].remove(action);
- if (toolBarToWidgetActions[item].empty())
+ if (toolBarToWidgetActions[item].isEmpty())
toolBarToWidgetActions.remove(item);
}
widgetActionToToolBar.insert(action, 0);
@@ -1437,7 +1433,7 @@ void QtToolBarDialogPrivate::rightClicked()
if (toolBar) {
currentState[toolBar].removeAll(action);
toolBarToWidgetActions[toolBar].remove(action);
- if (toolBarToWidgetActions[toolBar].empty())
+ if (toolBarToWidgetActions[toolBar].isEmpty())
toolBarToWidgetActions.remove(toolBar);
}
widgetActionToToolBar.insert(action, currentToolBar);
@@ -1500,7 +1496,7 @@ void QtToolBarDialogPrivate::currentToolBarChanged(QListWidgetItem *current)
if (!currentToolBar) {
return;
}
- const QList<QAction *> actions = currentState.value(currentToolBar);
+ const auto actions = currentState.value(currentToolBar);
QListWidgetItem *first = 0;
for (QAction *action : actions) {
QString actionName = separatorText;
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.h b/src/shared/qttoolbardialog/qttoolbardialog.h
index 72d34bafb..1599d9da5 100644
--- a/src/shared/qttoolbardialog/qttoolbardialog.h
+++ b/src/shared/qttoolbardialog/qttoolbardialog.h
@@ -98,7 +98,7 @@ class QtToolBarDialog : public QDialog
Q_OBJECT
public:
- explicit QtToolBarDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ explicit QtToolBarDialog(QWidget *parent = 0, Qt::WindowFlags flags = {});
~QtToolBarDialog();
void setToolBarManager(QtToolBarManager *toolBarManager);
diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp
index ae27f36ba..4e480bb54 100644
--- a/src/windeployqt/main.cpp
+++ b/src/windeployqt/main.cpp
@@ -283,6 +283,7 @@ struct Options {
bool deployPdb = false;
bool dryRun = false;
bool patchQt = true;
+ bool ignoreLibraryErrors = false;
inline bool isWinRt() const { return platform.testFlag(WinRt); }
};
@@ -372,6 +373,10 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
QStringLiteral("Do not patch the Qt5Core library."));
parser->addOption(noPatchQtOption);
+ QCommandLineOption ignoreErrorOption(QStringLiteral("ignore-library-errors"),
+ QStringLiteral("Ignore errors when libraries cannot be found."));
+ parser->addOption(ignoreErrorOption);
+
QCommandLineOption noPluginsOption(QStringLiteral("no-plugins"),
QStringLiteral("Skip plugin deployment."));
parser->addOption(noPluginsOption);
@@ -553,6 +558,7 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
}
options->patchQt = !parser->isSet(noPatchQtOption);
+ options->ignoreLibraryErrors = parser->isSet(ignoreErrorOption);
for (int i = 0; i < qtModulesCount; ++i) {
if (parser->isSet(*enabledModuleOptions.at(i)))
@@ -1202,9 +1208,15 @@ static inline QString qtlibInfixFromCoreLibName(const QString &path, bool isDebu
static bool updateLibrary(const QString &sourceFileName, const QString &targetDirectory,
const Options &options, QString *errorMessage)
{
-
- if (!updateFile(sourceFileName, targetDirectory, options.updateFileFlags, options.json, errorMessage))
+ if (!updateFile(sourceFileName, targetDirectory, options.updateFileFlags, options.json, errorMessage)) {
+ if (options.ignoreLibraryErrors) {
+ std::wcerr << "Warning: Could not update " << sourceFileName << " :" << *errorMessage << '\n';
+ errorMessage->clear();
+ return true;
+ }
return false;
+ }
+
if (options.deployPdb) {
const QFileInfo pdb(pdbFileName(sourceFileName));
if (pdb.isFile())
diff --git a/src/windeployqt/windeployqt.pro b/src/windeployqt/windeployqt.pro
index cd09c238f..bfb219337 100644
--- a/src/windeployqt/windeployqt.pro
+++ b/src/windeployqt/windeployqt.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(windeployqt))
+
option(host_build)
QT = core-private
DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII QT_NO_FOREACH
diff --git a/src/winrtrunner/winrtrunner.pro b/src/winrtrunner/winrtrunner.pro
index 15ab391ce..a797bd023 100644
--- a/src/winrtrunner/winrtrunner.pro
+++ b/src/winrtrunner/winrtrunner.pro
@@ -1,3 +1,7 @@
+include($$OUT_PWD/../../qttools-config.pri)
+QT_FOR_CONFIG += tools-private
+requires(qtConfig(winrtrunner))
+
option(host_build)
CONFIG += force_bootstrap
diff --git a/tests/auto/qdoc/config/config.pro b/tests/auto/qdoc/config/config.pro
new file mode 100644
index 000000000..b6cb9a32d
--- /dev/null
+++ b/tests/auto/qdoc/config/config.pro
@@ -0,0 +1,16 @@
+CONFIG += testcase
+QT = core testlib
+TARGET = tst_config
+INCLUDEPATH += $$PWD/../../../../src/qdoc
+
+HEADERS += \
+ $$PWD/../../../../src/qdoc/config.h \
+ $$PWD/../../../../src/qdoc/location.h \
+ $$PWD/../../../../src/qdoc/qdoccommandlineparser.h \
+ $$PWD/../../../../src/qdoc/loggingcategory.h
+
+SOURCES += \
+ tst_config.cpp \
+ $$PWD/../../../../src/qdoc/config.cpp \
+ $$PWD/../../../../src/qdoc/location.cpp \
+ $$PWD/../../../../src/qdoc/qdoccommandlineparser.cpp
diff --git a/tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf b/tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf
new file mode 100644
index 000000000..a1459f977
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf
@@ -0,0 +1,2 @@
+project = ExampleTest
+exampledirs = ../exampletest/examples
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro b/tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/tst_config.cpp b/tests/auto/qdoc/config/tst_config.cpp
new file mode 100644
index 000000000..44a1ba953
--- /dev/null
+++ b/tests/auto/qdoc/config/tst_config.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "config.h"
+
+#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qstringlist.h>
+#include <QtTest/QtTest>
+
+QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQdoc, "qt.test")
+QT_END_NAMESPACE
+
+class tst_Config : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void classMembersInitializeToFalseOrEmpty();
+ void includePathsFromCommandLine();
+ void getExampleProjectFile();
+};
+
+void tst_Config::classMembersInitializeToFalseOrEmpty()
+{
+ QStringList commandLineArgs = { QStringLiteral("./qdoc") };
+
+ Config::instance().init("QDoc Test", commandLineArgs);
+ auto &config = Config::instance();
+ QCOMPARE(config.singleExec(), false);
+
+ QVERIFY(config.defines().isEmpty());
+ QVERIFY(config.includePaths().isEmpty());
+ QVERIFY(config.dependModules().isEmpty());
+ QVERIFY(config.indexDirs().isEmpty());
+ QVERIFY(config.currentDir().isEmpty());
+ QVERIFY(config.previousCurrentDir().isEmpty());
+}
+
+void tst_Config::includePathsFromCommandLine()
+{
+ const auto mockIncludePath1 = QString("-I" + QDir().absoluteFilePath("/qt5/qtdoc/doc/."));
+ const auto mockIncludePath2 = QString("-I" + QDir().absoluteFilePath("/qt5/qtbase/mkspecs/linux-g++"));
+ const QStringList commandLineArgs = {
+ QStringLiteral("./qdoc"),
+ mockIncludePath1,
+ mockIncludePath2
+ };
+
+ Config::instance().init("QDoc Test", commandLineArgs);
+ auto &config = Config::instance();
+
+ const QStringList expected = { mockIncludePath1, mockIncludePath2 };
+ const QStringList actual = config.includePaths();
+
+ QCOMPARE(actual, expected);
+}
+
+void::tst_Config::getExampleProjectFile()
+{
+ QStringList commandLineArgs = { QStringLiteral("./qdoc") };
+ Config::instance().init("QDoc Test", commandLineArgs);
+ auto &config = Config::instance();
+
+ const auto docConfig = QFINDTESTDATA("/testdata/configs/exampletest.qdocconf");
+ config.load(docConfig);
+
+ auto rootDir = QFileInfo(docConfig).dir();
+ QVERIFY(rootDir.cd("../exampletest/examples/test"));
+
+ QVERIFY(config.getExampleProjectFile("invalid").isEmpty());
+ QVERIFY(config.getExampleProjectFile("test/empty").isEmpty());
+
+ QCOMPARE(config.getExampleProjectFile("test/example1"),
+ rootDir.absoluteFilePath("example1/example1.pro"));
+ QCOMPARE(config.getExampleProjectFile("test/example2"),
+ rootDir.absoluteFilePath("example2/example2.qmlproject"));
+ QCOMPARE(config.getExampleProjectFile("test/example3"),
+ rootDir.absoluteFilePath("example3/example3.pyproject"));
+ QCOMPARE(config.getExampleProjectFile("test/example4"),
+ rootDir.absoluteFilePath("example4/CMakeLists.txt"));
+}
+
+
+QTEST_APPLESS_MAIN(tst_Config)
+
+#include "tst_config.moc"
diff --git a/tests/auto/qdoc/generatedoutput/TestCPP b/tests/auto/qdoc/generatedoutput/TestCPP
deleted file mode 100644
index 50cce69ff..000000000
--- a/tests/auto/qdoc/generatedoutput/TestCPP
+++ /dev/null
@@ -1 +0,0 @@
-#include "testcpp.h"
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/TestModule.h b/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/TestModule.h
deleted file mode 100644
index 686cbe948..000000000
--- a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/TestModule.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "testmodule/aaa.h"
-#include "testmodule/bbb.h"
-#include "testmodule/ccc.h"
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/webxml_testmodule.qdocconf b/tests/auto/qdoc/generatedoutput/bug80259/webxml_testmodule.qdocconf
deleted file mode 100644
index 642fe5c2d..000000000
--- a/tests/auto/qdoc/generatedoutput/bug80259/webxml_testmodule.qdocconf
+++ /dev/null
@@ -1,2 +0,0 @@
-include(testmodule.qdocconf)
-include(../webxml.qdocconf)
diff --git a/tests/auto/qdoc/generatedoutput/examples-qhp.qdocconf b/tests/auto/qdoc/generatedoutput/examples-qhp.qdocconf
deleted file mode 100644
index b4598476e..000000000
--- a/tests/auto/qdoc/generatedoutput/examples-qhp.qdocconf
+++ /dev/null
@@ -1,20 +0,0 @@
-# QML test includes a documented example
-include(testqml.qdocconf)
-
-examplesinstallpath = test
-
-# Configure .qhp generation
-qhp.projects = Test
-
-qhp.Test.file = test.qhp
-qhp.Test.namespace = org.qt-project.test.001
-qhp.Test.virtualFolder = test
-qhp.Test.indexTitle = UI Components
-qhp.Test.indexRoot =
-
-# Add some meta-data to the example
-manifestmeta.filters = test
-
-manifestmeta.test.names = *
-manifestmeta.test.attributes = isTest:true
-manifestmeta.test.tags = test
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html
new file mode 100644
index 000000000..21870bb3f
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testtype.cpp -->
+ <title>List of All Members for TestType | CrossModule</title>
+</head>
+<body>
+<li>TestType</li>
+<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">List of All Members for TestType</h1>
+<p>This is the complete list of members for <a href="testtype.html">TestType</a>, including inherited members.</p>
+<ul>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#inlineFunction">inlineFunction</a></b></span>()</li>
+<li class="fn"><span class="name"><b><a href="testtype.html#nothing">nothing</a></b></span>()</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#overload">overload</a></b></span>()</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#overload-1">overload</a></b></span>(bool )</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#someFunction">someFunction</a></b></span>(int ) : int</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#someFunctionDefaultArg">someFunctionDefaultArg</a></b></span>(int , bool )</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-testderived.html#virtualFun">virtualFun</a></b></span>()</li>
+</ul>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html
new file mode 100644
index 000000000..dcf2114b7
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testtype.cpp -->
+ <title>TestType Class | CrossModule</title>
+</head>
+<body>
+<li>TestType</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#public-functions">Public Functions</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+<li class="level2"><a href="#linking">Linking</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">TestType Class</h1>
+<!-- $$$TestType-brief -->
+<p>A class inheriting another class that lives in an external doc module. <a href="#details">More...</a></p>
+<!-- @@@TestType -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;TestType&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Inherits:</td><td class="memItemRight bottomAlign"> <a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></td></tr></table></div><ul>
+<li><a href="testtype-members.html">List of all members, including inherited members</a></li>
+</ul>
+<a name="public-functions"></a>
+<h2 id="public-functions">Public Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testtype.html#nothing">nothing</a></b>()</td></tr>
+</table></div>
+<a name="details"></a>
+<!-- $$$TestType-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+<a name="linking"></a>
+<h3 id="linking">Linking</h3>
+<p>These links go to the parent class:</p>
+<ul>
+<li><a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></li>
+<li><a href="testqdoc-test.html">Test</a> class <a href="testqdoc.html#usage">Usage</a>.</li>
+<li><a href="testqdoc.html#QDOCTEST_MACRO">QDOCTEST_MACRO</a></li>
+</ul>
+</div>
+<p><b>See also </b><a href="testqdoc-test.html#someFunction">someFunction</a>().</p>
+<!-- @@@TestType -->
+<div class="func">
+<h2>Member Function Documentation</h2>
+<!-- $$$nothing[overload1]$$$nothing -->
+<h3 class="fn" id="nothing"><a name="nothing"></a><span class="type">void</span> TestType::<span class="name">nothing</span>()</h3>
+<p>Nothing to see here.</p>
+<!-- @@@nothing -->
+</div>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoc-test-qmlmodule.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoc-test-qmlmodule.xml
new file mode 100644
index 000000000..1629830f9
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoc-test-qmlmodule.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title></db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>QML Types for the Test module.</db:para>
+</db:abstract>
+</db:info>
+<db:anchor xml:id="details"/>
+<db:variablelist role="members">
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-qdoc-test-doctest.xml" xlink:role="">DocTest</db:link></db:term>
+<db:listitem>
+<db:para>Represents a doc test case.</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-qdoc-test-abstractparent.xml" xlink:role="">AbstractParent</db:link></db:term>
+<db:listitem>
+<db:para>Abstract base QML type.</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-qdoc-test-child.xml" xlink:role="">Child</db:link></db:term>
+<db:listitem>
+<db:para>A Child inheriting its parent.</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-int.xml" xlink:role="">int</db:link></db:term>
+<db:listitem>
+<db:para>An integer basic type.</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-qdoc-test-type.xml" xlink:role="">Type</db:link></db:term>
+<db:listitem>
+<db:para>A QML type documented in a .cpp file.</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput-linking.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput-linking.xml
new file mode 100644
index 000000000..90fbb79cc
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput-linking.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>Testing QDoc's link command</db:title>
+<db:productname>OutputFromQDocFiles</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>This is a page for testing QDoc's link command.</db:para>
+</db:abstract>
+</db:info>
+<db:anchor xml:id="link-test-target"/>
+<db:section xml:id="link-targets">
+<db:title>Link targets</db:title>
+<db:para>Valid parameters for the link command (<db:code>\l</db:code>) are page and section titles, targets defined with \target or \keyword commands, and API reference keywords (types, methods, namespaces, and so on).</db:para>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput.xml
new file mode 100644
index 000000000..610197cc7
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qdoctests-qdocfileoutput.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>Testing QDoc output from .qdoc files</db:title>
+<db:productname>OutputFromQDocFiles</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>This is a simple page for testing purposes only.</db:para>
+</db:abstract>
+</db:info>
+<db:para>QDoc generates documentation for software projects. It does this by extracting <db:emphasis>QDoc comments</db:emphasis> from project source files. QDoc comments are signified by a C-style-like comment tag followed by an exclamation point, like this: <db:code>/*!</db:code> <db:code>This text is contained within QDoc comment tags.</db:code> <db:code>*/</db:code>.</db:para>
+<db:section xml:id="supported-file-types">
+<db:title>Supported file types</db:title>
+<db:para>QDoc parses <db:code>.cpp</db:code> and <db:code>.qdoc</db:code> files. It does extract comments from header (<db:code>.h</db:code>) files.</db:para>
+</db:section>
+<db:section xml:id="further-information">
+<db:title>Further information</db:title>
+<db:para>This test document is written with the purpose of testing the output QDoc generates when parsing <db:code>.qdoc</db:code> files. It is fairly simple and makes use of a limited subset of QDoc's command. Those commands are:</db:para>
+<db:itemizedlist>
+<db:listitem>
+<db:para><db:code>\page</db:code></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\title</db:code></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\brief</db:code></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\e</db:code> (for emphasizing &quot;QDoc comments&quot;)</db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\c</db:code> (for multiple monospace-formatted entries)</db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\section1</db:code></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\list</db:code></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\li</db:code></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:code>\endlist</db:code></db:para>
+</db:listitem>
+</db:itemizedlist>
+</db:section>
+<db:section xml:id="linking">
+<db:title>Linking</db:title>
+<db:para>There are multiple ways to create hyperlinks to other topics:</db:para>
+<db:itemizedlist>
+<db:listitem>
+<db:para><db:link xlink:href="qdoctests-qdocfileoutput-linking.xml">Linking to a page title</db:link></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:link xlink:href="qdoctests-qdocfileoutput-linking.xml#link-targets">Linking to a section title</db:link></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:link xlink:href="qdoctests-qdocfileoutput-linking.xml#link-test-target">Linking using a \target string</db:link></db:para>
+</db:listitem>
+<db:listitem>
+<db:para><db:link xlink:href="qdoctests-qdocfileoutput-linking.xml">Linking using a \keyword string</db:link></db:para>
+</db:listitem>
+</db:itemizedlist>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-int.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-int.xml
new file mode 100644
index 000000000..00ef9ec39
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-int.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>int QML Basic Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>An integer basic type.</db:para>
+</db:abstract>
+</db:info>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+<db:section xml:id="method-documentation">
+<db:title>Method Documentation</db:title>
+<db:section xml:id="abs-method">
+<db:title>int abs()</db:title>
+<db:para>Returns the absolute value of this integer.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-abstractparent.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-abstractparent.xml
new file mode 100644
index 000000000..111ea3ad9
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-abstractparent.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>AbstractParent QML Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>Abstract base QML type.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Import Statement</db:term>
+<db:listitem>
+<db:para>import QDoc.Test 1.1</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>Inherited By:</db:term>
+<db:listitem>
+<db:para><db:link xlink:href="qml-qdoc-test-child.xml" xlink:role="">Child</db:link></db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+<db:section xml:id="property-documentation">
+<db:title>Property Documentation</db:title>
+<db:section xml:id="children-prop">
+<db:title>[default] children : list&lt;Child&gt;</db:title>
+<db:fieldsynopsis>
+<db:type>list&lt;Child&gt;</db:type>
+<db:varname>children</db:varname>
+<db:modifier>writable</db:modifier>
+<db:modifier>[default]</db:modifier>
+
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>Children of the type.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="method-documentation">
+<db:title>Method Documentation</db:title>
+<db:section xml:id="rear-method">
+<db:title>void rear(<db:emphasis>child</db:emphasis>)</db:title>
+<db:para>Do some abstract parenting on <db:code role="parameter">child</db:code>.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-child.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-child.xml
new file mode 100644
index 000000000..ef832021e
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-child.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>Child QML Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>A Child inheriting its parent.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Import Statement</db:term>
+<db:listitem>
+<db:para>import QDoc.Test 1.1</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>Inherits:</db:term>
+<db:listitem>
+<db:para><db:link xlink:href="">AbstractParent</db:link></db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+<db:section xml:id="property-documentation">
+<db:title>Property Documentation</db:title>
+<db:section xml:id="children-prop">
+<db:title>[default] children : list&lt;Child&gt;</db:title>
+<db:fieldsynopsis>
+<db:type>list&lt;Child&gt;</db:type>
+<db:varname>children</db:varname>
+<db:modifier>writable</db:modifier>
+<db:modifier>[default]</db:modifier>
+
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>Children of the type.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="method-documentation">
+<db:title>Method Documentation</db:title>
+<db:section xml:id="rear-method">
+<db:title>void rear(<db:emphasis>child</db:emphasis>)</db:title>
+<db:para>Do some abstract parenting on <db:code role="parameter">child</db:code>.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-doctest.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-doctest.xml
new file mode 100644
index 000000000..b3904a048
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-doctest.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>DocTest QML Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>Represents a doc test case.</db:para>
+<db:para>This type was introduced in QDoc.Test 0.9.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Import Statement</db:term>
+<db:listitem>
+<db:para>import QDoc.Test 1.1</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>Since:</db:term>
+<db:listitem>
+<db:para>QDoc.Test 0.9</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+<db:section xml:id="introduction">
+<db:title>Introduction</db:title>
+<db:para>A documentation test case, itself documented inline in <db:link xlink:href="qml-qdoc-test-doctest.xml">DocTest</db:link>.qml.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="property-documentation">
+<db:title>Property Documentation</db:title>
+<db:section xml:id="active-prop">
+<db:title>active : bool</db:title>
+<db:fieldsynopsis>
+<db:type>bool</db:type>
+<db:varname>active</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>Whether the test is active.</db:para>
+<db:para><db:emphasis>See also </db:emphasis>
+<db:simplelist type="vert" role="see-also"><db:member><db:link xlink:href="qml-qdoc-test-doctest.xml#name-prop">name</db:link></db:member>
+</db:simplelist>
+</db:para></db:section>
+<db:section xml:id="name-prop">
+<db:title>name : string</db:title>
+<db:fieldsynopsis>
+<db:type>string</db:type>
+<db:varname>name</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>Name of the test.</db:para>
+<db:programlisting language="qml">&lt;@type&gt;DocTest&lt;/@type&gt; {
+ &lt;@name&gt;name&lt;/@name&gt;: &lt;@string&gt;&amp;quot;test&amp;quot;&lt;/@string&gt;
+ &lt;@comment&gt;// ...&lt;/@comment&gt;
+}
+</db:programlisting>
+</db:section>
+</db:section>
+<db:section xml:id="method-documentation">
+<db:title>Method Documentation</db:title>
+<db:section xml:id="fail-method">
+<db:title>fail(<db:emphasis>message</db:emphasis> = &quot;oops&quot;)</db:title>
+<db:para>Fails the current test case, with the optional <db:code role="parameter">message</db:code>.</db:para>
+<db:para>This method was introduced in QDoc.Test 1.0.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-type.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-type.xml
new file mode 100644
index 000000000..59ed97a01
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-type.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>Type QML Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>A QML type documented in a .cpp file.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Import Statement</db:term>
+<db:listitem>
+<db:para>import QDoc.Test 1.1</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>Instantiates:</db:term>
+<db:listitem>
+<db:para><db:link xlink:href="testqdoc-test.xml">Test</db:link></db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+<db:section xml:id="property-documentation">
+<db:title>Property Documentation</db:title>
+<db:para>A group of properties sharing a documentation comment.</db:para>
+<db:section xml:id="group-prop">
+<db:title>group group</db:title>
+<db:bridgehead renderas="sect2" xml:id="group.first-prop">group.first : int</db:bridgehead>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>group.first</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:bridgehead renderas="sect2" xml:id="group.second-prop">group.second : int</db:bridgehead>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>group.second</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:bridgehead renderas="sect2" xml:id="group.third-prop">group.third : int</db:bridgehead>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>group.third</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>A property group.</db:para>
+</db:section>
+<db:section xml:id="id-prop">
+<db:title>[read-only] id : int</db:title>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>id</db:varname>
+<db:modifier>[read-only]</db:modifier>
+
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>A read-only property.</db:para>
+</db:section>
+<db:section xml:id="name-prop">
+<db:title>name : string</db:title>
+<db:fieldsynopsis>
+<db:type>string</db:type>
+<db:varname>name</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>Name of the Test.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="attached-property-documentation">
+<db:title>Attached Property Documentation</db:title>
+<db:section xml:id="type-attached-prop">
+<db:title>Type.type : enumeration</db:title>
+<db:fieldsynopsis>
+<db:type>enumeration</db:type>
+<db:varname>Type.type</db:varname>
+<db:modifier>attached</db:modifier>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">Test</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:informaltable>
+<db:thead>
+<db:tr>
+<db:th>Constant</db:th>
+<db:th>Description</db:th>
+</db:tr>
+</db:thead>
+<db:tr>
+<db:td>
+<db:para>Type.NoType</db:para>
+</db:td>
+<db:td>
+<db:para>Nothing</db:para>
+</db:td>
+</db:tr>
+<db:tr>
+<db:td>
+<db:para>Type.SomeType</db:para>
+</db:td>
+<db:td>
+<db:para>Something</db:para>
+</db:td>
+</db:tr>
+</db:informaltable>
+</db:section>
+</db:section>
+<db:section xml:id="signal-documentation">
+<db:title>Signal Documentation</db:title>
+<db:section xml:id="completed-signal">
+<db:title>completed(<db:emphasis>status</db:emphasis>)</db:title>
+<db:para>This signal is emitted when the operation completed with <db:code role="parameter">status</db:code>.</db:para>
+<db:note>
+<db:para>The corresponding handler is <db:code>onCompleted</db:code>.</db:para>
+</db:note>
+</db:section>
+</db:section>
+<db:section xml:id="attached-signal-documentation">
+<db:title>Attached Signal Documentation</db:title>
+<db:section xml:id="configured-signal">
+<db:title>configured()</db:title>
+<db:para>This attached signal is emitted when the type was configured.</db:para>
+<db:note>
+<db:para>The corresponding handler is <db:code>onConfigured</db:code>.</db:para>
+</db:note>
+</db:section>
+</db:section>
+<db:section xml:id="method-documentation">
+<db:title>Method Documentation</db:title>
+<db:para>Enables or disables this type.</db:para>
+<db:section xml:id="copy-method">
+<db:title>Type copy(<db:emphasis>a</db:emphasis>)</db:title>
+<db:para>Returns another Type based on <db:code role="parameter">a</db:code>.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-progressbar.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-progressbar.xml
new file mode 100644
index 000000000..3f162e8a4
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-progressbar.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>ProgressBar QML Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>A component that shows the progress of an event.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Import Statement</db:term>
+<db:listitem>
+<db:para>import UIComponents 1.0</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+<db:para>A <db:link xlink:href="qml-uicomponents-progressbar.xml">ProgressBar</db:link> shows the linear progress of an event as its <db:link xlink:href="qml-uicomponents-progressbar.xml#value-prop">value</db:link>. The range is specified using the <db:link xlink:href="qml-uicomponents-progressbar.xml#minimum-prop">minimum</db:link> and the <db:link xlink:href="qml-uicomponents-progressbar.xml#maximum-prop">maximum</db:link> values.</db:para>
+<db:para>The <db:link xlink:href="qml-uicomponents-progressbar.xml">ProgressBar</db:link> component is part of the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module.</db:para>
+<db:para>This documentation is part of the <db:link xlink:href="test-componentset-example.xml">UIComponents</db:link> example.</db:para>
+</db:section>
+<db:section xml:id="property-documentation">
+<db:title>Property Documentation</db:title>
+<db:section xml:id="color-prop">
+<db:title>color : color</db:title>
+<db:fieldsynopsis>
+<db:type>color</db:type>
+<db:varname>color</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>The color of the <db:link xlink:href="qml-uicomponents-progressbar.xml">ProgressBar</db:link>'s gradient. Must bind to a color type.</db:para>
+<db:para><db:emphasis>See also </db:emphasis>
+<db:simplelist type="vert" role="see-also"><db:member><db:link xlink:href="qml-uicomponents-progressbar.xml#secondColor-prop">secondColor</db:link></db:member>
+</db:simplelist>
+</db:para></db:section>
+<db:section xml:id="maximum-prop">
+<db:title>maximum : int</db:title>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>maximum</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>The maximum value of the <db:link xlink:href="qml-uicomponents-progressbar.xml">ProgressBar</db:link> range. The <db:link xlink:href="qml-uicomponents-progressbar.xml#value-prop">value</db:link> must not be more than this value.</db:para>
+</db:section>
+<db:section xml:id="minimum-prop">
+<db:title>minimum : int</db:title>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>minimum</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>The minimum value of the <db:link xlink:href="qml-uicomponents-progressbar.xml">ProgressBar</db:link> range. The <db:link xlink:href="qml-uicomponents-progressbar.xml#value-prop">value</db:link> must not be less than this value.</db:para>
+</db:section>
+<db:section xml:id="secondColor-prop">
+<db:title>secondColor : color</db:title>
+<db:fieldsynopsis>
+<db:type>color</db:type>
+<db:varname>secondColor</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>The second color of the <db:link xlink:href="qml-uicomponents-progressbar.xml">ProgressBar</db:link>'s gradient. Must bind to a color type.</db:para>
+<db:para><db:emphasis>See also </db:emphasis>
+<db:simplelist type="vert" role="see-also"><db:member><db:link xlink:href="qml-uicomponents-progressbar.xml#color-prop">color</db:link></db:member>
+</db:simplelist>
+</db:para></db:section>
+<db:section xml:id="value-prop">
+<db:title>value : int</db:title>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>value</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>The value of the progress.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-switch.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-switch.xml
new file mode 100644
index 000000000..7b1e169ef
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-switch.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>Switch QML Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>A component that can be turned on or off.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Import Statement</db:term>
+<db:listitem>
+<db:para>import UIComponents 1.0</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+<db:para>A toggle switch has two states: an <db:code>on</db:code> and an <db:code>off</db:code> state. The <db:code>off</db:code> state is when the <db:link xlink:href="qml-uicomponents-switch.xml#on-prop">on</db:link> property is set to <db:code>false</db:code>.</db:para>
+<db:para>The ToggleSwitch component is part of the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module.</db:para>
+<db:para>This documentation is part of the <db:link xlink:href="test-componentset-example.xml">UIComponents</db:link> example.</db:para>
+</db:section>
+<db:section xml:id="property-documentation">
+<db:title>Property Documentation</db:title>
+<db:section xml:id="on-prop">
+<db:title>on : bool</db:title>
+<db:fieldsynopsis>
+<db:type>bool</db:type>
+<db:varname>on</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>Indicates the state of the switch. If <db:code>false</db:code>, then the switch is in the <db:code>off</db:code> state.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="method-documentation">
+<db:title>Method Documentation</db:title>
+<db:section xml:id="toggle-method">
+<db:title>toggle()</db:title>
+<db:para>A method to toggle the switch. If the switch is <db:code>on</db:code>, the toggling it will turn it <db:code>off</db:code>. Toggling a switch in the <db:code>off</db:code> position will turn it <db:code>on</db:code>.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-tabwidget.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-tabwidget.xml
new file mode 100644
index 000000000..0232dbe27
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-uicomponents-tabwidget.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>TabWidget QML Type</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>A widget that places its children as tabs.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Import Statement</db:term>
+<db:listitem>
+<db:para>import UIComponents 1.0</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+<db:para>A <db:link xlink:href="qml-uicomponents-tabwidget.xml">TabWidget</db:link> places its children as tabs in a view. Selecting a tab involves selecting the tab at the top.</db:para>
+<db:para>The <db:link xlink:href="qml-uicomponents-tabwidget.xml">TabWidget</db:link> component is part of the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module.</db:para>
+<db:para>This documentation is part of the <db:link xlink:href="test-componentset-example.xml">UIComponents</db:link> example.</db:para>
+<db:section xml:id="adding-tabs">
+<db:title>Adding Tabs</db:title>
+<db:para>To add a tab, declare the tab as a child of the <db:link xlink:href="qml-uicomponents-tabwidget.xml">TabWidget</db:link>.</db:para>
+<db:programlisting language="cpp">TabWidget {
+ id: tabwidget
+
+ Rectangle {
+ id: tab1
+ color: &lt;@string&gt;&amp;quot;red&amp;quot;&lt;/@string&gt;
+ &lt;@comment&gt;//... omitted&lt;/@comment&gt;
+ }
+ Rectangle {
+ id: tab2
+ color: &lt;@string&gt;&amp;quot;blue&amp;quot;&lt;/@string&gt;
+ &lt;@comment&gt;//... omitted&lt;/@comment&gt;
+ }
+
+}
+</db:programlisting>
+</db:section>
+</db:section>
+<db:section xml:id="property-documentation">
+<db:title>Property Documentation</db:title>
+<db:section xml:id="current-prop">
+<db:title>current : int</db:title>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>current</db:varname>
+<db:modifier>writable</db:modifier>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>The currently active tab in the <db:link xlink:href="qml-uicomponents-tabwidget.xml">TabWidget</db:link>.</db:para>
+</db:section>
+<db:section xml:id="sampleReadOnlyProperty-prop">
+<db:title>[read-only] sampleReadOnlyProperty : int</db:title>
+<db:fieldsynopsis>
+<db:type>int</db:type>
+<db:varname>sampleReadOnlyProperty</db:varname>
+<db:modifier>[read-only]</db:modifier>
+
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+</db:fieldsynopsis>
+<db:para>A sample <db:code>read-only</db:code> property. A contrived property to demonstrate QDoc's ability to detect read-only properties.</db:para>
+<db:para>The signature is:</db:para>
+<db:programlisting language="cpp">readonly property &lt;@type&gt;int&lt;/@type&gt; sampleReadOnlyProperty: &lt;@number&gt;0&lt;/@number&gt;
+</db:programlisting>
+<db:para>Note that the property must be initialized to a value.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/test-componentset-example.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/test-componentset-example.xml
new file mode 100644
index 000000000..48496733b
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/test-componentset-example.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>QML Documentation Example</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>Example for documenting QML types.</db:para>
+</db:abstract>
+</db:info>
+<db:para>This example demonstrates one of the ways to document QML types.</db:para>
+<db:para>In particular, there are sample types that are documented with QDoc commands comments. There are documentation comments for the QML types and their public interfaces. The types are grouped into a module, the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module.</db:para>
+<db:para>The uicomponents.qdoc file generates the overview page for the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module page.</db:para>
+<db:para>The generated documentation is available in the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module.</db:para>
+<db:section xml:id="qml-class">
+<db:title>QML Class</db:title>
+<db:para>The QML types use the \qmltype to document the type. In addition, they have the \inmodule command in order for QDoc to associate them to the <db:code>UIComponents</db:code> module.</db:para>
+<db:para>QDoc uses the \brief command to place a basic description when listing the types.</db:para>
+</db:section>
+<db:section xml:id="properties-signals-handlers-and-methods">
+<db:title>Properties, Signals, Handlers, and Methods</db:title>
+<db:para>The types have their properties, signals, handlers, and methods defined in their respective QML files. QDoc associates the properties and methods to the types, therefore, you only need to place the documentation above the property, method, or signal.</db:para>
+<db:para>To document the type of a <db:emphasis>property alias</db:emphasis>, you must use the \qmlproperty command to specify the data type.</db:para>
+<db:programlisting language="cpp">\qmlproperty &lt;@type&gt;int&lt;/@type&gt; anAliasedProperty
+An aliased property of type &lt;@type&gt;int&lt;/@type&gt;&lt;@op&gt;.&lt;/@op&gt;
+</db:programlisting>
+<db:section xml:id="internal-documentation">
+<db:title>Internal Documentation</db:title>
+<db:para>You may declare that a documentation is for internal use by placing the \internal command after the beginning QDoc comment <db:code>/*</db:code>. QDoc will prevent the internal documentation from appearing in the public API.</db:para>
+<db:para>If you wish to omit certain parts of the documentation, you may use the \omit and \endomit command.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="qml-types-with-c-implementation">
+<db:title>QML Types with C++ Implementation</db:title>
+<db:para>This example only demonstrates the documentation for types in QML files, but the regular QML commands may be placed inside C++ classes to define the public API of the QML type.</db:para>
+</db:section>
+<db:para>Files:</db:para>
+<db:itemizedlist><db:listitem>
+<db:para><db:link xlink:href="componentset/ProgressBar.qml">componentset/ProgressBar.qml</db:link></db:para></db:listitem>
+<db:listitem>
+<db:para><db:link xlink:href="componentset/Switch.qml">componentset/Switch.qml</db:link></db:para></db:listitem>
+<db:listitem>
+<db:para><db:link xlink:href="componentset/TabWidget.qml">componentset/TabWidget.qml</db:link></db:para></db:listitem>
+<db:listitem>
+<db:para><db:link xlink:href="componentset/componentset.pro">componentset/componentset.pro</db:link></db:para></db:listitem>
+</db:itemizedlist>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/testcpp-module.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testcpp-module.xml
new file mode 100644
index 000000000..604e577df
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testcpp-module.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>QDoc Test C++ Classes</db:title>
+<db:productname>TestCPP</db:productname>
+<db:titleabbrev>TestCPP Reference Documentation</db:titleabbrev>
+<db:abstract>
+<db:para>A test module page.</db:para>
+</db:abstract>
+</db:info>
+<db:para>A test module page.</db:para>
+<db:section xml:id="namespaces">
+<db:title>Namespaces</db:title>
+<db:variablelist role="namespaces">
+<db:varlistentry>
+<db:term><db:link xlink:href="testqdoc.xml" xlink:role="namespace">TestQDoc</db:link></db:term>
+<db:listitem>
+<db:para>A namespace.</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+</db:section>
+<db:section xml:id="classes">
+<db:title>Classes</db:title>
+<db:variablelist role="classes">
+<db:varlistentry>
+<db:term><db:link xlink:href="testqdoc-test.xml" xlink:role="class">TestQDoc::Test</db:link></db:term>
+<db:listitem>
+<db:para>A class in a namespace.</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term><db:link xlink:href="testqdoc-testderived.xml" xlink:role="class">TestQDoc::TestDerived</db:link></db:term>
+<db:listitem>
+<db:para>A derived class in a namespace.</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+</db:section>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-test.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-test.xml
new file mode 100644
index 000000000..ad6a4f30f
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-test.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>Test Class</db:title>
+<db:subtitle>TestQDoc::Test</db:subtitle>
+<db:productname>TestCPP</db:productname>
+<db:titleabbrev>TestCPP Reference Documentation</db:titleabbrev>
+<db:abstract>
+<db:para>A class in a namespace.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Header</db:term>
+<db:listitem>
+<db:para>Test</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>qmake</db:term>
+<db:listitem>
+<db:para>QT += testcpp</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>Inherited By</db:term>
+<db:listitem>
+<db:para><db:link xlink:href="testqdoc-testderived.xml" xlink:role="class">TestQDoc::TestDerived</db:link></db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+<db:section xml:id="member-function-documentation">
+<db:title>Member Function Documentation</db:title>
+<db:section xml:id="overload">
+<db:title>[protected] Test::void overload()</db:title>
+<db:bridgehead renderas="sect2" xml:id="overload-1">[protected] Test::void overload(bool <db:emphasis>b</db:emphasis>)</db:bridgehead>
+<db:synopsis>
+
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:synopsis>
+<db:para>Overloads that share a documentation comment, optionally taking a parameter <db:code role="parameter">b</db:code>.</db:para>
+<db:para>This function was introduced in Test 1.2.</db:para>
+</db:section>
+<db:section xml:id="inlineFunction">
+<db:title>Test::void inlineFunction()</db:title>
+<db:methodsynopsis>
+<db:void/>
+<db:methodname>inlineFunction</db:methodname>
+<db:void/>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">void inlineFunction()</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>An inline function, documented using the \fn QDoc command.</db:para>
+</db:section>
+<db:section xml:id="someFunction">
+<db:title>Test::int someFunction(int <db:emphasis>v</db:emphasis>)</db:title>
+<db:methodsynopsis>
+<db:type>int</db:type>
+<db:methodname>someFunction</db:methodname>
+<db:methodparam>
+<db:type>int</db:type>
+<db:parameter>v</db:parameter>
+</db:methodparam>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">int someFunction(int v)</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>Function that takes a parameter <db:code role="parameter">v</db:code>. Also returns the value of <db:code role="parameter">v</db:code>.</db:para>
+</db:section>
+<db:section xml:id="someFunctionDefaultArg">
+<db:title>Test::void someFunctionDefaultArg(int <db:emphasis>i</db:emphasis>, bool <db:emphasis>b</db:emphasis> = false)</db:title>
+<db:methodsynopsis>
+<db:void/>
+<db:methodname>someFunctionDefaultArg</db:methodname>
+<db:methodparam>
+<db:type>int</db:type>
+<db:parameter>i</db:parameter>
+</db:methodparam>
+<db:methodparam>
+<db:type>bool</db:type>
+<db:parameter>b</db:parameter>
+<db:initializer>false</db:initializer>
+</db:methodparam>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">void someFunctionDefaultArg(int i, bool b)</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>Function that takes a parameter <db:code role="parameter">i</db:code> and <db:code role="parameter">b</db:code>.</db:para>
+</db:section>
+<db:section xml:id="virtualFun">
+<db:title>[virtual] Test::void virtualFun()</db:title>
+<db:methodsynopsis>
+<db:modifier>virtual</db:modifier>
+<db:void/>
+<db:methodname>virtualFun</db:methodname>
+<db:void/>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">void virtualFun()</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>Function that must be reimplemented.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="macro-documentation">
+<db:title>Macro Documentation</db:title>
+<db:section xml:id="QDOCTEST_MACRO2">
+<db:title>QDOCTEST_MACRO2(<db:emphasis>x</db:emphasis>)</db:title>
+<db:methodsynopsis>
+<db:methodname>QDOCTEST_MACR</db:methodname>
+<db:methodparam>
+<db:type></db:type>
+<db:parameter>x</db:parameter>
+</db:methodparam>
+<db:synopsisinfo db:role="meta">macrowithparams</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">QDOCTEST_MACRO2( x)</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>A macro with argument <db:code role="parameter">x</db:code>.</db:para>
+<db:para>This function was introduced in Test 1.1.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="obsolete">
+<db:title>Obsolete Members for Test</db:title>
+<db:para><db:emphasis role="bold">The following members of class <db:link xlink:href="testqdoc-test.xml">Test</db:link> are obsolete.</db:emphasis> They are provided to keep old source code working. We strongly advise against using them in new code.</db:para>
+<db:section xml:id="member-function-documentation">
+<db:title>Member Function Documentation</db:title>
+<db:section xml:id="anotherObsoleteMember">
+<db:title>Test::void anotherObsoleteMember()</db:title>
+<db:methodsynopsis>
+<db:void/>
+<db:methodname>anotherObsoleteMember</db:methodname>
+<db:void/>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">void anotherObsoleteMember()</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">obsolete</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.</db:para>
+<db:para>Use <db:link xlink:href="testqdoc-test.xml#obsoleteMember">obsoleteMember</db:link>() instead.</db:para>
+</db:section>
+<db:section xml:id="deprecatedMember">
+<db:title>Test::void deprecatedMember()</db:title>
+<db:methodsynopsis>
+<db:void/>
+<db:methodname>deprecatedMember</db:methodname>
+<db:void/>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">void deprecatedMember()</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">obsolete</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.</db:para>
+<db:para>Use <db:link xlink:href="testqdoc-test.xml#someFunction">someFunction</db:link>() instead.</db:para>
+</db:section>
+<db:section xml:id="obsoleteMember">
+<db:title>Test::void obsoleteMember()</db:title>
+<db:methodsynopsis>
+<db:void/>
+<db:methodname>obsoleteMember</db:methodname>
+<db:void/>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">void obsoleteMember()</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">obsolete</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.</db:para>
+<db:para>Use <db:link xlink:href="testqdoc-test.xml#someFunction">someFunction</db:link>() instead.</db:para>
+</db:section>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-testderived.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-testderived.xml
new file mode 100644
index 000000000..9bb613cfc
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc-testderived.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>TestDerived Class</db:title>
+<db:subtitle>TestQDoc::TestDerived</db:subtitle>
+<db:productname>TestCPP</db:productname>
+<db:titleabbrev>TestCPP Reference Documentation</db:titleabbrev>
+<db:abstract>
+<db:para>A derived class in a namespace.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Header</db:term>
+<db:listitem>
+<db:para>TestDerived</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>qmake</db:term>
+<db:listitem>
+<db:para>QT += testcpp</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>Inherits</db:term>
+<db:listitem>
+<db:para><db:link xlink:href="testqdoc-test.xml" xlink:role="class">TestQDoc::Test</db:link></db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+<db:section xml:id="member-function-documentation">
+<db:title>Member Function Documentation</db:title>
+<db:section xml:id="virtualFun">
+<db:title>[override virtual] TestDerived::void virtualFun()</db:title>
+<db:methodsynopsis>
+<db:modifier>virtual</db:modifier>
+<db:void/>
+<db:methodname>virtualFun</db:methodname>
+<db:modifier>override</db:modifier>
+<db:void/>
+<db:synopsisinfo db:role="meta">plain</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">void virtualFun() override</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+<db:para>Reimplements: <db:link xlink:href="testqdoc-test.xml#virtualFun" type="function">Test::virtualFun()</db:link>.</db:para>
+</db:section>
+</db:section></db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc.xml
new file mode 100644
index 000000000..c5ba1fe65
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/testqdoc.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>TestQDoc Namespace</db:title>
+<db:productname>TestCPP</db:productname>
+<db:titleabbrev>TestCPP Reference Documentation</db:titleabbrev>
+<db:abstract>
+<db:para>A namespace.</db:para>
+</db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Header</db:term>
+<db:listitem>
+<db:para>TestCPP</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>qmake</db:term>
+<db:listitem>
+<db:para>QT += testcpp</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+<db:section xml:id="usage">
+<db:title>Usage</db:title>
+<db:para>This namespace is for testing QDoc output.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="classes">
+<db:title>Classes</db:title>
+<db:section>
+<db:title>class <db:link xlink:href="testqdoc-test.xml" xlink:role="class">Test</db:link></db:title>
+<db:para>A class in a namespace.</db:para>
+</db:section>
+<db:section>
+<db:title>class <db:link xlink:href="testqdoc-testderived.xml" xlink:role="class">TestDerived</db:link></db:title>
+<db:para>A derived class in a namespace.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="macro-documentation">
+<db:title>Macro Documentation</db:title>
+<db:section xml:id="QDOCTEST_MACRO">
+<db:title>QDOCTEST_MACRO</db:title>
+<db:methodsynopsis>
+<db:methodname>QDOCTEST_MAC</db:methodname>
+<db:synopsisinfo db:role="meta">macrowithoutparams</db:synopsisinfo>
+<db:synopsisinfo db:role="signature">QDOCTEST_MACRO</db:synopsisinfo>
+<db:synopsisinfo db:role="access">public</db:synopsisinfo>
+<db:synopsisinfo db:role="status">active</db:synopsisinfo>
+<db:synopsisinfo db:role="threadsafeness">unspecified</db:synopsisinfo>
+<db:synopsisinfo db:role="module">TestCPP</db:synopsisinfo>
+</db:methodsynopsis>
+</db:section>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/uicomponents-qmlmodule.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/uicomponents-qmlmodule.xml
new file mode 100644
index 000000000..f00b3d3f7
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/uicomponents-qmlmodule.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>UI Components</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>Basic set of UI components.</db:para>
+</db:abstract>
+</db:info>
+<db:anchor xml:id="details"/>
+<db:para>This is a listing of a list of UI components implemented by QML types. These files are available for general import and they are based on the Qt Quick Code Samples.</db:para>
+<db:para>This module is part of the <db:link xlink:href="test-componentset-example.xml">UIComponents</db:link> example.</db:para>
+<db:variablelist role="members">
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-uicomponents-progressbar.xml" xlink:role="">ProgressBar</db:link></db:term>
+<db:listitem>
+<db:para>A component that shows the progress of an event.</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-uicomponents-switch.xml" xlink:role="">Switch</db:link></db:term>
+<db:listitem>
+<db:para>A component that can be turned on or off.</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term><db:link xlink:href="qml-uicomponents-tabwidget.xml" xlink:role="">TabWidget</db:link></db:term>
+<db:listitem>
+<db:para>A widget that places its children as tabs.</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/dontdocument/classes.html b/tests/auto/qdoc/generatedoutput/expected_output/dontdocument/classes.html
new file mode 100644
index 000000000..f5bae610a
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/dontdocument/classes.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- test.qdoc -->
+ <title>Classes | TestCPP</title>
+</head>
+<body>
+<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">Classes</h1>
+<span class="subtitle"></span>
+<!-- $$$classes.html-description -->
+<div class="descr"> <a name="details"></a>
+<div class="table"><table class="annotated">
+<tr class="odd topAlign"><td class="tblName"><p><a href="seenclass.html">SeenClass</a></p></td><td class="tblDescr"><p>A public but undocumented class</p></td></tr>
+<tr class="even topAlign"><td class="tblName"><p><a href="testqdoc-test.html">TestQDoc::Test</a></p></td><td class="tblDescr"><p>A class in a namespace</p></td></tr>
+<tr class="odd topAlign"><td class="tblName"><p><a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></p></td><td class="tblDescr"><p>A derived class in a namespace</p></td></tr>
+</table></div>
+</div>
+<!-- @@@classes.html -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/dontdocument/seenclass.html b/tests/auto/qdoc/generatedoutput/expected_output/dontdocument/seenclass.html
new file mode 100644
index 000000000..119841e44
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/dontdocument/seenclass.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- dont.cpp -->
+ <title>SeenClass Class | TestCPP</title>
+</head>
+<body>
+<li>SeenClass</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">SeenClass Class</h1>
+<!-- $$$SeenClass-brief -->
+<p>A public but undocumented class. <a href="#details">More...</a></p>
+<!-- @@@SeenClass -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;SeenClass&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr></table></div><ul>
+</ul>
+<a name="details"></a>
+<!-- $$$SeenClass-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@SeenClass -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml b/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml
index 7f206d0e8..8aa9ce303 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<instructionals module="Test">
<examples>
+ <example name="CMake Example Project" docUrl="qthelp://org.qt-project.test.001/test/test-cmaketest-example.html" projectPath="test/cmaketest/CMakeLists.txt" isTest="true">
+ <description><![CDATA[No description available]]></description>
+ <tags>cmake,project,test</tags>
+ <fileToOpen mainFile="true">test/cmaketest/main.cpp</fileToOpen>
+ </example>
<example name="QML Documentation Example" docUrl="qthelp://org.qt-project.test.001/test/test-componentset-example.html" projectPath="tutorials/componentset/componentset.pro" isTest="true">
<description><![CDATA[Example for documenting QML types.]]></description>
<tags>documentation,qml,sample,test</tags>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/first.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/first.webxml
index 1001d0c53..b3dc9dffa 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/first.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/first.webxml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <class name="First" href="first.html" status="active" access="public" location="bbb.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/bbb.h" lineno="2" documented="true" module="TestModule">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/src/main.cpp" line="28" column="4">
+ <class name="First" href="first.html" status="active" access="public" location="bbb.h" documented="true" module="TestModule">
+ <description>
<para>This is a first class</para>
</description>
- <class name="Nested" fullname="First::Nested" href="first-nested.html" status="active" access="private" location="bbb.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/bbb.h" lineno="4" documented="true" module="TestModule">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/src/main.cpp" line="35" column="4">
+ <class name="Nested" fullname="First::Nested" href="first-nested.html" status="active" access="private" location="bbb.h" documented="true" module="TestModule">
+ <description>
<para>This is a nested class</para>
</description>
</class>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/index.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/index.webxml
index 4e51df8d0..c2235e69d 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/index.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/index.webxml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <page name="index.html" href="index.html" status="active" location="index.qdoc" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/src/qdoc/index.qdoc" lineno="1" documented="true" subtype="page" title="doc index" fulltitle="doc index" subtitle="" module="TestModule">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/src/qdoc/index.qdoc" line="1" column="5">
+ <page name="index.html" href="index.html" status="active" location="index.qdoc" documented="true" subtype="page" title="doc index" fulltitle="doc index" subtitle="" module="TestModule">
+ <description>
<generatedlist contents="classesbymodule TestModule"/>
</description>
</page>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput-linking.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput-linking.webxml
index 9e203d926..3983c2bbd 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput-linking.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput-linking.webxml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <page name="qdoctests-qdocfileoutput-linking.html" href="qdoctests-qdocfileoutput-linking.html" status="active" location="qdoctests-outputfromqdocfiles.qdoc" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc" lineno="71" documented="true" subtype="page" title="Testing QDoc's link command" fulltitle="Testing QDoc's link command" subtitle="" module="Test" brief="This is a page for testing QDoc's link command">
+ <page name="qdoctests-qdocfileoutput-linking.html" href="qdoctests-qdocfileoutput-linking.html" status="active" location="qdoctests-outputfromqdocfiles.qdoc" documented="true" subtype="page" title="Testing QDoc's link command" fulltitle="Testing QDoc's link command" subtitle="" module="OutputFromQDocFiles" brief="This is a page for testing QDoc's link command">
<target name="link-test-target"/>
<keyword name="qdoc-linking-test" title="QDoc Linking Test"/>
<contents name="link-targets" title="Link targets" level="1"/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc" line="71" column="4">
+ <description>
<brief>This is a page for testing QDoc's link command.</brief>
<target name="link-test-target"/>
<section id="link-targets">
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput.webxml
index c09bbe31c..4a56533a4 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/qdoctests-qdocfileoutput.webxml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <page name="qdoctests-qdocfileoutput.html" href="qdoctests-qdocfileoutput.html" status="active" location="qdoctests-outputfromqdocfiles.qdoc" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc" lineno="28" documented="true" subtype="page" title="Testing QDoc output from .qdoc files" fulltitle="Testing QDoc output from .qdoc files" subtitle="" module="Test" brief="This is a simple page for testing purposes only">
+ <page name="qdoctests-qdocfileoutput.html" href="qdoctests-qdocfileoutput.html" status="active" location="qdoctests-outputfromqdocfiles.qdoc" documented="true" subtype="page" title="Testing QDoc output from .qdoc files" fulltitle="Testing QDoc output from .qdoc files" subtitle="" module="OutputFromQDocFiles" brief="This is a simple page for testing purposes only">
<contents name="supported-file-types" title="Supported file types" level="1"/>
<contents name="further-information" title="Further information" level="1"/>
<contents name="linking" title="Linking" level="1"/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc" line="28" column="4">
+ <description>
<brief>This is a simple page for testing purposes only.</brief>
<para>QDoc generates documentation for software projects. It does this by extracting <italic>QDoc comments</italic> from project source files. QDoc comments are signified by a C-style-like comment tag followed by an exclamation point, like this: <teletype type="highlighted">/*!</teletype> <teletype type="highlighted">This text is contained within QDoc comment tags.</teletype> <teletype type="highlighted">*/</teletype>.</para>
<section id="supported-file-types">
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/second.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/second.webxml
index 0a4939841..9ecd3c2fe 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/second.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/second.webxml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <class name="Second" href="second.html" status="active" access="public" location="ccc.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/ccc.h" lineno="2" documented="true" module="TestModule">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/src/main.cpp" line="42" column="4">
+ <class name="Second" href="second.html" status="active" access="public" location="ccc.h" documented="true" module="TestModule">
+ <description>
<para>This is a second class</para>
</description>
</class>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/test-componentset-example.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/test-componentset-example.webxml
index 29ed944ba..515ef7bf1 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/test-componentset-example.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/test-componentset-example.webxml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <page name="componentset" href="test-componentset-example.html" status="active" location="examples.qdoc" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/qml/componentset/examples.qdoc" lineno="28" documented="true" subtype="example" title="QML Documentation Example" fulltitle="QML Documentation Example" subtitle="" module="Test" brief="Example for documenting QML types">
+ <page name="componentset" href="test-componentset-example.html" status="active" location="examples.qdoc" documented="true" subtype="example" title="QML Documentation Example" fulltitle="QML Documentation Example" subtitle="" module="Test" brief="Example for documenting QML types">
<contents name="qml-class" title="QML Class" level="1"/>
<contents name="properties-signals-handlers-and-methods" title="Properties, Signals, Handlers, and Methods" level="1"/>
<contents name="internal-documentation" title="Internal Documentation" level="2"/>
<contents name="qml-types-with-c-implementation" title="QML Types with C++ Implementation" level="1"/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/qml/componentset/examples.qdoc" line="28" column="4">
+ <description>
<brief>Example for documenting QML types.</brief>
<para>This example demonstrates one of the ways to document QML types.</para>
<para>In particular, there are sample types that are documented with QDoc commands comments. There are documentation comments for the QML types and their public interfaces. The types are grouped into a module, the <link raw="UI Components" href="uicomponents-qmlmodule.html" type="">UI Components</link> module.</para>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-test.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-test.webxml
index 5d88b6e7c..d2726cc57 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-test.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-test.webxml
@@ -1,58 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <class name="Test" fullname="TestQDoc::Test" href="testqdoc-test.html" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="34" documented="true" module="TestCPP" brief="A class in a namespace">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="49" column="4">
+ <class name="Test" fullname="TestQDoc::Test" href="testqdoc-test.html" status="active" access="public" location="testcpp.h" documented="true" module="TestCPP" brief="A class in a namespace">
+ <description>
<brief>A class in a namespace.</brief>
</description>
<function name="QDOCTEST_MACRO2" href="testqdoc-test.html#QDOCTEST_MACRO2" status="active" access="public" documented="true" related="true" since="Test 1.1" meta="macrowithparams" virtual="non" const="false" static="false" final="false" override="false" type="" brief="A macro with argument x" signature="QDOCTEST_MACRO2( x)">
<parameter type="" name="x" default=""/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="66" column="4">
+ <description>
<brief>A macro with argument <argument>x</argument>.</brief>
</description>
</function>
- <function name="anotherObsoleteMember" fullname="TestQDoc::Test::anotherObsoleteMember" href="testqdoc-test-obsolete.html#anotherObsoleteMember" status="obsolete" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="39" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void anotherObsoleteMember()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="93" column="4">
+ <function name="anotherObsoleteMember" fullname="TestQDoc::Test::anotherObsoleteMember" href="testqdoc-test-obsolete.html#anotherObsoleteMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void anotherObsoleteMember()">
+ <description>
<para>Use <link raw="obsoleteMember()" href="testqdoc-test-obsolete.html#obsoleteMember" type="function">obsoleteMember()</link> instead.</para>
</description>
</function>
- <function name="deprecatedMember" fullname="TestQDoc::Test::deprecatedMember" href="testqdoc-test-obsolete.html#deprecatedMember" status="obsolete" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="40" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void deprecatedMember()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="73" column="4">
+ <function name="deprecatedMember" fullname="TestQDoc::Test::deprecatedMember" href="testqdoc-test-obsolete.html#deprecatedMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void deprecatedMember()">
+ <description>
<para>Use <link raw="someFunction()" href="testqdoc-test.html#someFunction" type="function">someFunction()</link> instead.</para>
</description>
</function>
- <function name="inlineFunction" fullname="TestQDoc::Test::inlineFunction" href="testqdoc-test.html#inlineFunction" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="41" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" brief="An inline function, documented using the \fn QDoc command" signature="void inlineFunction()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="120" column="4">
+ <function name="inlineFunction" fullname="TestQDoc::Test::inlineFunction" href="testqdoc-test.html#inlineFunction" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" brief="An inline function, documented using the \fn QDoc command" signature="void inlineFunction()">
+ <description>
<brief>An inline function, documented using the \fn QDoc command.</brief>
</description>
</function>
- <function name="obsoleteMember" fullname="TestQDoc::Test::obsoleteMember" href="testqdoc-test-obsolete.html#obsoleteMember" status="obsolete" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="38" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void obsoleteMember()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="83" column="4">
+ <function name="obsoleteMember" fullname="TestQDoc::Test::obsoleteMember" href="testqdoc-test-obsolete.html#obsoleteMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void obsoleteMember()">
+ <description>
<para>Use <link raw="someFunction()" href="testqdoc-test.html#someFunction" type="function">someFunction()</link> instead.</para>
</description>
</function>
- <function name="overload" fullname="TestQDoc::Test::overload" href="testqdoc-test.html#overload" status="active" access="protected" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="45" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void overload()">
- <description path="" line="0" column="0"/>
+ <function name="overload" fullname="TestQDoc::Test::overload" href="testqdoc-test.html#overload" status="active" access="protected" location="testcpp.h" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void overload()">
+ <description/>
</function>
- <function name="overload" fullname="TestQDoc::Test::overload" href="testqdoc-test.html#overload-1" status="active" access="protected" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="46" meta="plain" virtual="non" const="false" static="false" final="false" override="false" overload="true" overload-number="1" type="void" signature="void overload(bool b)">
+ <function name="overload" fullname="TestQDoc::Test::overload" href="testqdoc-test.html#overload-1" status="active" access="protected" location="testcpp.h" meta="plain" virtual="non" const="false" static="false" final="false" override="false" overload="true" overload-number="1" type="void" signature="void overload(bool b)">
<parameter type="bool" name="b" default=""/>
- <description path="" line="0" column="0"/>
+ <description/>
</function>
- <function name="someFunction" fullname="TestQDoc::Test::someFunction" href="testqdoc-test.html#someFunction" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="36" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="int" signature="int someFunction(int v)">
+ <function name="someFunction" fullname="TestQDoc::Test::someFunction" href="testqdoc-test.html#someFunction" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="int" signature="int someFunction(int v)">
<parameter type="int" name="v" default=""/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="111" column="4">
+ <description>
<para>Function that takes a parameter <argument>v</argument>. Also returns the value of <argument>v</argument>.</para>
</description>
</function>
- <function name="someFunctionDefaultArg" fullname="TestQDoc::Test::someFunctionDefaultArg" href="testqdoc-test.html#someFunctionDefaultArg" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="37" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void someFunctionDefaultArg(int i, bool b)">
+ <function name="someFunctionDefaultArg" fullname="TestQDoc::Test::someFunctionDefaultArg" href="testqdoc-test.html#someFunctionDefaultArg" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void someFunctionDefaultArg(int i, bool b)">
<parameter type="int" name="i" default=""/>
<parameter type="bool" name="b" default="false"/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="103" column="4">
+ <description>
<para>Function that takes a parameter <argument>i</argument> and <argument>b</argument>.</para>
</description>
</function>
- <function name="virtualFun" fullname="TestQDoc::Test::virtualFun" href="testqdoc-test.html#virtualFun" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="42" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="false" type="void" signature="void virtualFun()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="126" column="4">
+ <function name="virtualFun" fullname="TestQDoc::Test::virtualFun" href="testqdoc-test.html#virtualFun" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="false" type="void" signature="void virtualFun()">
+ <description>
<para>Function that must be reimplemented.</para>
</description>
</function>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-testderived.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-testderived.webxml
index c0c8d852f..76a335658 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-testderived.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc-testderived.webxml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <class name="TestDerived" fullname="TestQDoc::TestDerived" href="testqdoc-testderived.html" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="49" documented="true" bases="TestQDoc::Test" module="TestCPP" brief="A derived class in a namespace">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="55" column="4">
+ <class name="TestDerived" fullname="TestQDoc::TestDerived" href="testqdoc-testderived.html" status="active" access="public" location="testcpp.h" documented="true" bases="TestQDoc::Test" module="TestCPP" brief="A derived class in a namespace">
+ <description>
<brief>A derived class in a namespace.</brief>
</description>
- <function name="virtualFun" fullname="TestQDoc::TestDerived::virtualFun" href="testqdoc-testderived.html#virtualFun" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="51" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="true" type="void" signature="void virtualFun() override">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="134" column="4"/>
+ <function name="virtualFun" fullname="TestQDoc::TestDerived::virtualFun" href="testqdoc-testderived.html#virtualFun" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="true" type="void" signature="void virtualFun() override">
+ <description/>
</function>
</class>
</document>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc.webxml
index 750f544b8..a8cbb951a 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/testqdoc.webxml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <namespace name="TestQDoc" href="testqdoc.html" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="32" documented="true" module="TestCPP" brief="A namespace">
+ <namespace name="TestQDoc" href="testqdoc.html" status="active" access="public" location="testcpp.h" documented="true" module="TestCPP" brief="A namespace">
<contents name="usage" title="Usage" level="1"/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="39" column="4">
+ <description>
<brief>A namespace.</brief>
<section id="usage">
<heading level="1">Usage</heading>
@@ -11,63 +11,63 @@
</section>
</description>
<function name="QDOCTEST_MACRO" href="testqdoc.html#QDOCTEST_MACRO" status="active" access="public" documented="true" related="true" meta="macrowithoutparams" virtual="non" const="false" static="false" final="false" override="false" type="" signature="QDOCTEST_MACRO">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="61" column="4"/>
+ <description />
</function>
- <class name="Test" fullname="TestQDoc::Test" href="testqdoc-test.html" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="34" documented="true" module="TestCPP" brief="A class in a namespace">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="49" column="4">
+ <class name="Test" fullname="TestQDoc::Test" href="testqdoc-test.html" status="active" access="public" location="testcpp.h" documented="true" module="TestCPP" brief="A class in a namespace">
+ <description>
<brief>A class in a namespace.</brief>
</description>
<function name="QDOCTEST_MACRO2" href="testqdoc-test.html#QDOCTEST_MACRO2" status="active" access="public" documented="true" related="true" since="Test 1.1" meta="macrowithparams" virtual="non" const="false" static="false" final="false" override="false" type="" brief="A macro with argument x" signature="QDOCTEST_MACRO2( x)">
<parameter type="" name="x" default=""/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="66" column="4">
+ <description>
<brief>A macro with argument <argument>x</argument>.</brief>
</description>
</function>
- <function name="anotherObsoleteMember" fullname="TestQDoc::Test::anotherObsoleteMember" href="testqdoc-test-obsolete.html#anotherObsoleteMember" status="obsolete" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="39" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void anotherObsoleteMember()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="93" column="4">
+ <function name="anotherObsoleteMember" fullname="TestQDoc::Test::anotherObsoleteMember" href="testqdoc-test-obsolete.html#anotherObsoleteMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void anotherObsoleteMember()">
+ <description>
<para>Use <link raw="obsoleteMember()" href="testqdoc-test-obsolete.html#obsoleteMember" type="function">obsoleteMember()</link> instead.</para>
</description>
</function>
- <function name="deprecatedMember" fullname="TestQDoc::Test::deprecatedMember" href="testqdoc-test-obsolete.html#deprecatedMember" status="obsolete" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="40" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void deprecatedMember()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="73" column="4">
+ <function name="deprecatedMember" fullname="TestQDoc::Test::deprecatedMember" href="testqdoc-test-obsolete.html#deprecatedMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void deprecatedMember()">
+ <description>
<para>Use <link raw="someFunction()" href="testqdoc-test.html#someFunction" type="function">someFunction()</link> instead.</para>
</description>
</function>
- <function name="inlineFunction" fullname="TestQDoc::Test::inlineFunction" href="testqdoc-test.html#inlineFunction" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="41" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" brief="An inline function, documented using the \fn QDoc command" signature="void inlineFunction()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="120" column="4">
+ <function name="inlineFunction" fullname="TestQDoc::Test::inlineFunction" href="testqdoc-test.html#inlineFunction" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" brief="An inline function, documented using the \fn QDoc command" signature="void inlineFunction()">
+ <description>
<brief>An inline function, documented using the \fn QDoc command.</brief>
</description>
</function>
- <function name="obsoleteMember" fullname="TestQDoc::Test::obsoleteMember" href="testqdoc-test-obsolete.html#obsoleteMember" status="obsolete" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="38" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void obsoleteMember()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="83" column="4">
+ <function name="obsoleteMember" fullname="TestQDoc::Test::obsoleteMember" href="testqdoc-test-obsolete.html#obsoleteMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void obsoleteMember()">
+ <description>
<para>Use <link raw="someFunction()" href="testqdoc-test.html#someFunction" type="function">someFunction()</link> instead.</para>
</description>
</function>
- <function name="someFunction" fullname="TestQDoc::Test::someFunction" href="testqdoc-test.html#someFunction" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="36" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="int" signature="int someFunction(int v)">
+ <function name="someFunction" fullname="TestQDoc::Test::someFunction" href="testqdoc-test.html#someFunction" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="int" signature="int someFunction(int v)">
<parameter type="int" name="v" default=""/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="111" column="4">
+ <description>
<para>Function that takes a parameter <argument>v</argument>. Also returns the value of <argument>v</argument>.</para>
</description>
</function>
- <function name="someFunctionDefaultArg" fullname="TestQDoc::Test::someFunctionDefaultArg" href="testqdoc-test.html#someFunctionDefaultArg" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="37" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void someFunctionDefaultArg(int i, bool b)">
+ <function name="someFunctionDefaultArg" fullname="TestQDoc::Test::someFunctionDefaultArg" href="testqdoc-test.html#someFunctionDefaultArg" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void someFunctionDefaultArg(int i, bool b)">
<parameter type="int" name="i" default=""/>
<parameter type="bool" name="b" default="false"/>
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="103" column="4">
+ <description>
<para>Function that takes a parameter <argument>i</argument> and <argument>b</argument>.</para>
</description>
</function>
- <function name="virtualFun" fullname="TestQDoc::Test::virtualFun" href="testqdoc-test.html#virtualFun" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="42" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="false" type="void" signature="void virtualFun()">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="126" column="4">
+ <function name="virtualFun" fullname="TestQDoc::Test::virtualFun" href="testqdoc-test.html#virtualFun" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="false" type="void" signature="void virtualFun()">
+ <description>
<para>Function that must be reimplemented.</para>
</description>
</function>
</class>
- <class name="TestDerived" fullname="TestQDoc::TestDerived" href="testqdoc-testderived.html" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="45" documented="true" bases="TestQDoc::Test" module="TestCPP" brief="A derived class in a namespace">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="55" column="4">
+ <class name="TestDerived" fullname="TestQDoc::TestDerived" href="testqdoc-testderived.html" status="active" access="public" location="testcpp.h" documented="true" bases="TestQDoc::Test" module="TestCPP" brief="A derived class in a namespace">
+ <description>
<brief>A derived class in a namespace.</brief>
</description>
- <function name="virtualFun" fullname="TestQDoc::TestDerived::virtualFun" href="testqdoc-testderived.html#virtualFun" status="active" access="public" location="testcpp.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.h" lineno="47" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="true" type="void" signature="void virtualFun() override">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/testcpp.cpp" line="134" column="4"/>
+ <function name="virtualFun" fullname="TestQDoc::TestDerived::virtualFun" href="testqdoc-testderived.html#virtualFun" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="true" type="void" signature="void virtualFun() override">
+ <description />
</function>
</class>
</namespace>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/third.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/third.webxml
index d826bb421..529ffd896 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/html/third.webxml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/third.webxml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<WebXML>
<document>
- <class name="Third" href="third.html" status="active" access="public" location="aaa.h" filepath="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/aaa.h" lineno="2" documented="true" module="TestModule">
- <description path="/home/levon/work/official/qttools/tests/auto/qdoc/generatedoutput/bug80259/src/main.cpp" line="49" column="4">
+ <class name="Third" href="third.html" status="active" access="public" location="aaa.h" documented="true" module="TestModule">
+ <description>
<para>This is a third class</para>
</description>
</class>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc-test.html b/tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc-test.html
new file mode 100644
index 000000000..52a10f706
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc-test.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testcpp.cpp -->
+ <title>Test Class | TestCPP</title>
+</head>
+<body>
+<li>Test</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#public-functions">Public Functions</a></li>
+<li class="level1"><a href="#protected-functions">Protected Functions</a></li>
+<li class="level1"><a href="#macros">Macros</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">Test Class</h1>
+<span class="small-subtitle">class <a href="testqdoc.html">TestQDoc</a>::Test</span>
+<!-- $$$Test-brief -->
+<p>A class in a namespace. <a href="#details">More...</a></p>
+<!-- @@@Test -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;Test&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Inherited By:</td><td class="memItemRight bottomAlign"> <p><a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></p>
+</td></tr></table></div><ul>
+<li><a href="testqdoc-test-members.html">List of all members, including inherited members</a></li>
+<li><a href="testqdoc-test-obsolete.html">Obsolete members</a></li>
+</ul>
+<a name="public-functions"></a>
+<h2 id="public-functions">Public Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#inlineFunction">inlineFunction</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> int </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunction">someFunction</a></b>(int <i>v</i>)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunctionDefaultArg">someFunctionDefaultArg</a></b>(int <i>i</i>, bool <i>b</i> = false)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> virtual void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#virtualFun">virtualFun</a></b>()</td></tr>
+</table></div>
+<a name="protected-functions"></a>
+<h2 id="protected-functions">Protected Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#overload">overload</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#overload-1">overload</a></b>(bool <i>b</i>)</td></tr>
+</table></div>
+<a name="macros"></a>
+<h2 id="macros">Macros</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#QDOCTEST_MACRO2">QDOCTEST_MACRO2</a></b>(<i>x</i>)</td></tr>
+</table></div>
+<a name="details"></a>
+<!-- $$$Test-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@Test -->
+<div class="func">
+<h2>Member Function Documentation</h2>
+<!-- $$$ -->
+<div class="fngroup">
+<h3 class="fn fngroupitem" id="overload"><a name="overload"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>()</h3><h3 class="fn fngroupitem" id="overload-1"><a name="overload-1"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>(<span class="type">bool</span> <i>b</i>)</h3></div>
+<p>Overloads that share a documentation comment, optionally taking a parameter <i>b</i>.</p>
+<p>This function was introduced in Test 1.2.</p>
+<!-- @@@ -->
+<!-- $$$inlineFunction[overload1]$$$inlineFunction -->
+<h3 class="fn" id="inlineFunction"><a name="inlineFunction"></a><span class="type">void</span> Test::<span class="name">inlineFunction</span>()</h3>
+<p>An inline function, documented using the \fn QDoc command.</p>
+<!-- @@@inlineFunction -->
+<!-- $$$someFunction[overload1]$$$someFunctionint -->
+<h3 class="fn" id="someFunction"><a name="someFunction"></a><span class="type">int</span> Test::<span class="name">someFunction</span>(<span class="type">int</span> <i>v</i>)</h3>
+<p>Function that takes a parameter <i>v</i>. Also returns the value of <i>v</i>.</p>
+<p>This function was introduced in Test 1.0.</p>
+<!-- @@@someFunction -->
+<!-- $$$someFunctionDefaultArg[overload1]$$$someFunctionDefaultArgintbool -->
+<h3 class="fn" id="someFunctionDefaultArg"><a name="someFunctionDefaultArg"></a><span class="type">void</span> Test::<span class="name">someFunctionDefaultArg</span>(<span class="type">int</span> <i>i</i>, <span class="type">bool</span> <i>b</i> = false)</h3>
+<p>Function that takes a parameter <i>i</i> and <i>b</i>.</p>
+<p>This function was introduced in Qt 2.0.</p>
+<!-- @@@someFunctionDefaultArg -->
+<!-- $$$virtualFun[overload1]$$$virtualFun -->
+<h3 class="fn" id="virtualFun"><a name="virtualFun"></a><code>[virtual] </code><span class="type">void</span> Test::<span class="name">virtualFun</span>()</h3>
+<p>Function that must be reimplemented.</p>
+<!-- @@@virtualFun -->
+</div>
+<div class="macros">
+<h2>Macro Documentation</h2>
+<!-- $$$QDOCTEST_MACRO2[overload1]$$$QDOCTEST_MACRO2 -->
+<h3 class="fn" id="QDOCTEST_MACRO2"><a name="QDOCTEST_MACRO2"></a><span class="name">QDOCTEST_MACRO2</span>(<i>x</i>)</h3>
+<p>A macro with argument <i>x</i>.</p>
+<p>This function was introduced in Test 1.1.</p>
+<!-- @@@QDOCTEST_MACRO2 -->
+</div>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc.html b/tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc.html
new file mode 100644
index 000000000..a259e40af
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/ignoresince/testqdoc.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testcpp.cpp -->
+ <title>TestQDoc Namespace | TestCPP</title>
+</head>
+<body>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#classes">Classes</a></li>
+<li class="level1"><a href="#macros">Macros</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+<li class="level2"><a href="#usage">Usage</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">TestQDoc Namespace</h1>
+<!-- $$$TestQDoc-brief -->
+<p>A namespace. <a href="#details">More...</a></p>
+<!-- @@@TestQDoc -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;TestCPP&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr></table></div><ul>
+</ul>
+<a name="classes"></a>
+<h2 id="classes">Classes</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> class </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html">Test</a></b></td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> class </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-testderived.html">TestDerived</a></b></td></tr>
+</table></div>
+<a name="macros"></a>
+<h2 id="macros">Macros</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> </td><td class="memItemRight bottomAlign"><b><a href="testqdoc.html#QDOCTEST_MACRO">QDOCTEST_MACRO</a></b></td></tr>
+</table></div>
+<a name="details"></a>
+<!-- $$$TestQDoc-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+<a name="usage"></a>
+<h3 id="usage">Usage</h3>
+<p>This namespace is for testing QDoc output.</p>
+</div>
+<!-- @@@TestQDoc -->
+<div class="classes">
+<h2>Classes</h2>
+<h3> class <a href="testqdoc-test.html">Test</a></h3><!-- $$$Test-brief -->
+<p>A class in a namespace. <a href="testqdoc-test.html#details">More...</a></p>
+<!-- @@@Test -->
+<h3> class <a href="testqdoc-testderived.html">TestDerived</a></h3><!-- $$$TestDerived-brief -->
+<p>A derived class in a namespace. <a href="testqdoc-testderived.html#details">More...</a></p>
+<!-- @@@TestDerived -->
+</div>
+<div class="macros">
+<h2>Macro Documentation</h2>
+<!-- $$$QDOCTEST_MACRO[overload1]$$$QDOCTEST_MACRO -->
+<h3 class="fn" id="QDOCTEST_MACRO"><a name="QDOCTEST_MACRO"></a><span class="name">QDOCTEST_MACRO</span></h3>
+<!-- @@@QDOCTEST_MACRO -->
+</div>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/index.html b/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/index.html
index d1fb02484..fd9fdd50a 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/index.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/index.html
@@ -20,6 +20,8 @@
<h2 id="qml-types">QML Types</h2>
<div class="table"><table class="annotated">
<tr class="odd topAlign"><td class="tblName"><p><a href="qml-qdoc-test-abstractparent.html">AbstractParent</a></p></td><td class="tblDescr"><p>Abstract base QML type</p></td></tr>
+<tr class="even topAlign"><td class="tblName"><p><a href="qml-qdoc-test-child.html">Child</a></p></td><td class="tblDescr"><p>A Child inheriting its parent</p></td></tr>
+<tr class="odd topAlign"><td class="tblName"><p><a href="qml-int.html">int</a></p></td><td class="tblDescr"><p>An integer basic type</p></td></tr>
</table></div>
<p>Test include file that is part of the sourcedirs.</p>
</div>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent-members.html b/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent-members.html
index 48c8fa485..f9d64de75 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent-members.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent-members.html
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
-<!-- parent.qdoc -->
+<!-- includefromparent.qdoc -->
<title>List of All Members for AbstractParent | Test</title>
</head>
<body>
@@ -11,7 +11,6 @@
<p>This is the complete list of members for <a href="qml-qdoc-test-abstractparent.html">AbstractParent</a>, including inherited members.</p>
<ul>
<li class="fn"><b><b><a href="qml-qdoc-test-abstractparent.html#children-prop">children</a></b></b> : list&lt;Child&gt; [default]</li>
-<li class="fn">void <b><b><a href="qml-qdoc-test-abstractparent.html#rear-method-1">rear</a></b></b>(<i>child</i>)</li>
<li class="fn">void <b><b><a href="qml-qdoc-test-abstractparent.html#rear-method">rear</a></b></b>(<i>child</i>)</li>
</ul>
</body>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent.html b/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent.html
index cbb0f36aa..f7c294ae0 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/includefromexampledirs/qml-qdoc-test-abstractparent.html
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
-<!-- parent.qdoc -->
+<!-- includefromparent.qdoc -->
<title>AbstractParent QML Type | Test</title>
</head>
<body>
@@ -34,12 +34,12 @@
<a name="methods"></a>
<h2 id="methods">Methods</h2>
<ul>
-<li class="fn">void <b><b><a href="qml-qdoc-test-abstractparent.html#rear-method-1">rear</a></b></b>(<i>child</i>)</li>
<li class="fn">void <b><b><a href="qml-qdoc-test-abstractparent.html#rear-method">rear</a></b></b>(<i>child</i>)</li>
</ul>
<!-- $$$AbstractParent-description -->
<a name="details"></a>
<h2 id="details">Detailed Description</h2>
+<p>Test include file that is part of the sourcedirs.</p>
<!-- @@@AbstractParent -->
<h2>Property Documentation</h2>
<!-- $$$children -->
@@ -54,16 +54,6 @@
</div></div><!-- @@@children -->
<br/>
<h2>Method Documentation</h2>
-<!-- $$$rear$$$rear -->
-<div class="qmlitem"><div class="qmlproto">
-<div class="table"><table class="qmlname">
-<tr valign="top" class="odd" id="rear-method-1">
-<td class="tblQmlFuncNode"><p>
-<a name="rear-method-1"></a><span class="type">void</span> <span class="name">rear</span>(<i>child</i>)</p></td></tr>
-</table></div></div>
-<div class="qmldoc"><p>Do some abstract parenting on <i>child</i>.</p>
-</div></div><!-- @@@rear -->
-<br/>
<!-- $$$rear[overload1]$$$rear -->
<div class="qmlitem"><div class="qmlproto">
<div class="table"><table class="qmlname">
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/qdoc-test-qmlmodule.xml b/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/qdoc-test-qmlmodule.xml
new file mode 100644
index 000000000..b99e58480
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/qdoc-test-qmlmodule.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title></db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>QML Types for the Test module.</db:para>
+</db:abstract>
+</db:info>
+<db:anchor xml:id="details"/>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/test-componentset-example.xml b/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/test-componentset-example.xml
new file mode 100644
index 000000000..4e1dbf915
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/test-componentset-example.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>QML Documentation Example</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>Example for documenting QML types.</db:para>
+</db:abstract>
+</db:info>
+<db:para>This example demonstrates one of the ways to document QML types.</db:para>
+<db:para>In particular, there are sample types that are documented with QDoc commands comments. There are documentation comments for the QML types and their public interfaces. The types are grouped into a module, the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module.</db:para>
+<db:para>The uicomponents.qdoc file generates the overview page for the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module page.</db:para>
+<db:para>The generated documentation is available in the <db:link xlink:href="uicomponents-qmlmodule.xml">UI Components</db:link> module.</db:para>
+<db:section xml:id="qml-class">
+<db:title>QML Class</db:title>
+<db:para>The QML types use the \qmltype to document the type. In addition, they have the \inmodule command in order for QDoc to associate them to the <db:code>UIComponents</db:code> module.</db:para>
+<db:para>QDoc uses the \brief command to place a basic description when listing the types.</db:para>
+</db:section>
+<db:section xml:id="properties-signals-handlers-and-methods">
+<db:title>Properties, Signals, Handlers, and Methods</db:title>
+<db:para>The types have their properties, signals, handlers, and methods defined in their respective QML files. QDoc associates the properties and methods to the types, therefore, you only need to place the documentation above the property, method, or signal.</db:para>
+<db:para>To document the type of a <db:emphasis>property alias</db:emphasis>, you must use the \qmlproperty command to specify the data type.</db:para>
+<db:programlisting language="cpp">\qmlproperty &lt;@type&gt;int&lt;/@type&gt; anAliasedProperty
+An aliased property of type &lt;@type&gt;int&lt;/@type&gt;&lt;@op&gt;.&lt;/@op&gt;
+</db:programlisting>
+<db:section xml:id="internal-documentation">
+<db:title>Internal Documentation</db:title>
+<db:para>You may declare that a documentation is for internal use by placing the \internal command after the beginning QDoc comment <db:code>/*</db:code>. QDoc will prevent the internal documentation from appearing in the public API.</db:para>
+<db:para>If you wish to omit certain parts of the documentation, you may use the \omit and \endomit command.</db:para>
+</db:section>
+</db:section>
+<db:section xml:id="qml-types-with-c-implementation">
+<db:title>QML Types with C++ Implementation</db:title>
+<db:para>This example only demonstrates the documentation for types in QML files, but the regular QML commands may be placed inside C++ classes to define the public API of the QML type.</db:para>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/testcpp-module.xml b/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/testcpp-module.xml
new file mode 100644
index 000000000..d2ba83a13
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/noautolist-docbook/testcpp-module.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>QDoc Test C++ Classes</db:title>
+<db:productname>Test</db:productname>
+<db:titleabbrev>A test project for QDoc build artifacts</db:titleabbrev>
+<db:abstract>
+<db:para>A test module page.</db:para>
+</db:abstract>
+</db:info>
+<db:para>A test module page.</db:para>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+</db:section>
+</db:article>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/noautolist/qdoc-test-qmlmodule.html b/tests/auto/qdoc/generatedoutput/expected_output/noautolist/qdoc-test-qmlmodule.html
new file mode 100644
index 000000000..8efd70c0f
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/noautolist/qdoc-test-qmlmodule.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- type.cpp -->
+ <title>Test</title>
+</head>
+<body>
+<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
+<span class="subtitle"></span>
+<!-- $$$QDoc.Test-description -->
+<div class="descr"> <a name="details"></a>
+</div>
+<!-- @@@QDoc.Test -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/noautolist/test-componentset-example.html b/tests/auto/qdoc/generatedoutput/expected_output/noautolist/test-componentset-example.html
new file mode 100644
index 000000000..5331c2b35
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/noautolist/test-componentset-example.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- examples.qdoc -->
+ <title>QML Documentation Example | Test</title>
+</head>
+<body>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#qml-class">QML Class</a></li>
+<li class="level1"><a href="#properties-signals-handlers-and-methods">Properties, Signals, Handlers, and Methods</a></li>
+<li class="level2"><a href="#internal-documentation">Internal Documentation</a></li>
+<li class="level1"><a href="#qml-types-with-c-implementation">QML Types with C++ Implementation</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">QML Documentation Example</h1>
+<span class="subtitle"></span>
+<!-- $$$componentset-brief -->
+<p>Example for documenting QML types.</p>
+<!-- @@@componentset -->
+<!-- $$$componentset-description -->
+<div class="descr"> <a name="details"></a>
+<p>This example demonstrates one of the ways to document QML types.</p>
+<p>In particular, there are sample types that are documented with QDoc commands comments. There are documentation comments for the QML types and their public interfaces. The types are grouped into a module, the <a href="uicomponents-qmlmodule.html">UI Components</a> module.</p>
+<p>The uicomponents.qdoc file generates the overview page for the <a href="uicomponents-qmlmodule.html">UI Components</a> module page.</p>
+<p>The generated documentation is available in the <a href="uicomponents-qmlmodule.html">UI Components</a> module.</p>
+<a name="qml-class"></a>
+<h4 id="qml-class">QML Class</h4>
+<p>The QML types use the \qmltype to document the type. In addition, they have the \inmodule command in order for QDoc to associate them to the <code>UIComponents</code> module.</p>
+<p>QDoc uses the \brief command to place a basic description when listing the types.</p>
+<a name="properties-signals-handlers-and-methods"></a>
+<h4 id="properties-signals-handlers-and-methods">Properties, Signals, Handlers, and Methods</h4>
+<p>The types have their properties, signals, handlers, and methods defined in their respective QML files. QDoc associates the properties and methods to the types, therefore, you only need to place the documentation above the property, method, or signal.</p>
+<p>To document the type of a <i>property alias</i>, you must use the \qmlproperty command to specify the data type.</p>
+<pre class="cpp">\qmlproperty <span class="type">int</span> anAliasedProperty
+An aliased property of type <span class="type">int</span><span class="operator">.</span></pre>
+<a name="internal-documentation"></a>
+<h5 id="internal-documentation">Internal Documentation</h5>
+<p>You may declare that a documentation is for internal use by placing the \internal command after the beginning QDoc comment <code>/*</code>. QDoc will prevent the internal documentation from appearing in the public API.</p>
+<p>If you wish to omit certain parts of the documentation, you may use the \omit and \endomit command.</p>
+<a name="qml-types-with-c-implementation"></a>
+<h4 id="qml-types-with-c-implementation">QML Types with C++ Implementation</h4>
+<p>This example only demonstrates the documentation for types in QML files, but the regular QML commands may be placed inside C++ classes to define the public API of the QML type.</p>
+</div>
+<!-- @@@componentset -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/noautolist/testcpp-module.html b/tests/auto/qdoc/generatedoutput/expected_output/noautolist/testcpp-module.html
new file mode 100644
index 000000000..8108b0979
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/noautolist/testcpp-module.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testcpp.cpp -->
+ <title>QDoc Test C++ Classes | Test</title>
+</head>
+<body>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">QDoc Test C++ Classes</h1>
+<span class="subtitle"></span>
+<!-- $$$TestCPP-brief -->
+<p>A test module page. <a href="#details">More...</a></p>
+<!-- @@@TestCPP -->
+<!-- $$$TestCPP-description -->
+<a name="details"></a>
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@TestCPP -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html
index 74b47375e..2e294ffff 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<!-- qdoctests-outputfromqdocfiles.qdoc -->
- <title>Testing QDoc's link command | Test</title>
+ <title>Testing QDoc's link command | OutputFromQDocFiles</title>
</head>
<body>
<div class="sidebar">
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html
index c4975e349..8b60812bb 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<!-- qdoctests-outputfromqdocfiles.qdoc -->
- <title>Testing QDoc output from .qdoc files | Test</title>
+ <title>Testing QDoc output from .qdoc files | OutputFromQDocFiles</title>
</head>
<body>
<div class="sidebar">
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qml-int.html b/tests/auto/qdoc/generatedoutput/expected_output/qml-int.html
index 651f840cb..0b21da628 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/qml-int.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/qml-int.html
@@ -15,9 +15,25 @@
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">int QML Basic Type</h1>
<span class="subtitle"></span>
+<a name="methods"></a>
+<h2 id="methods">Methods</h2>
+<ul>
+<li class="fn">int <b><b><a href="qml-int.html#abs-method">abs</a></b></b>()</li>
+</ul>
<!-- $$$int-description -->
<div class="descr"> <a name="details"></a>
</div>
<!-- @@@int -->
+<h2>Method Documentation</h2>
+<!-- $$$abs[overload1]$$$abs -->
+<div class="qmlitem"><div class="qmlproto">
+<div class="table"><table class="qmlname">
+<tr valign="top" class="odd" id="abs-method">
+<td class="tblQmlFuncNode"><p>
+<a name="abs-method"></a><span class="type"><a href="qml-int.html">int</a></span> <span class="name">abs</span>()</p></td></tr>
+</table></div></div>
+<div class="qmldoc"><p>Returns the absolute value of this integer.</p>
+</div></div><!-- @@@abs -->
+<br/>
</body>
</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-type.html b/tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-type.html
index 166cbee81..f18e97082 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-type.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-type.html
@@ -143,6 +143,7 @@
<a name="completed-signal"></a><span class="name">completed</span>(<i>status</i>)</p></td></tr>
</table></div></div>
<div class="qmldoc"><p>This signal is emitted when the operation completed with <i>status</i>.</p>
+<p><b>Note: </b>The corresponding handler is <code>onCompleted</code>.</p>
</div></div><!-- @@@completed -->
<br/>
<h2>Attached Signal Documentation</h2>
@@ -154,6 +155,7 @@
<a name="configured-signal"></a><span class="name">configured</span>()</p></td></tr>
</table></div></div>
<div class="qmldoc"><p>This attached signal is emitted when the type was configured.</p>
+<p><b>Note: </b>The corresponding handler is <code>onConfigured</code>.</p>
</div></div><!-- @@@configured -->
<br/>
<h2>Method Documentation</h2>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/scopedenum/testqdoc-test.html b/tests/auto/qdoc/generatedoutput/expected_output/scopedenum/testqdoc-test.html
new file mode 100644
index 000000000..3fc1f2bc7
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/scopedenum/testqdoc-test.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testcpp.cpp -->
+ <title>Test Class | TestCPP</title>
+</head>
+<body>
+<li>Test</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#public-types">Public Types</a></li>
+<li class="level1"><a href="#public-functions">Public Functions</a></li>
+<li class="level1"><a href="#protected-functions">Protected Functions</a></li>
+<li class="level1"><a href="#macros">Macros</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">Test Class</h1>
+<span class="small-subtitle">class <a href="testqdoc.html">TestQDoc</a>::Test</span>
+<!-- $$$Test-brief -->
+<p>A class in a namespace. <a href="#details">More...</a></p>
+<!-- @@@Test -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;Test&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Inherited By:</td><td class="memItemRight bottomAlign"> <p><a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></p>
+</td></tr></table></div><ul>
+<li><a href="testqdoc-test-members.html">List of all members, including inherited members</a></li>
+<li><a href="testqdoc-test-obsolete.html">Obsolete members</a></li>
+</ul>
+<a name="public-types"></a>
+<h2 id="public-types">Public Types</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> enum class </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#ScopedEnum-enum">ScopedEnum</a></b> { This, That, All }</td></tr>
+</table></div>
+<a name="public-functions"></a>
+<h2 id="public-functions">Public Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#inlineFunction">inlineFunction</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> int </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunction">someFunction</a></b>(int <i>v</i>)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunctionDefaultArg">someFunctionDefaultArg</a></b>(int <i>i</i>, bool <i>b</i> = false)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> virtual void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#virtualFun">virtualFun</a></b>()</td></tr>
+</table></div>
+<a name="protected-functions"></a>
+<h2 id="protected-functions">Protected Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#overload">overload</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#overload-1">overload</a></b>(bool <i>b</i>)</td></tr>
+</table></div>
+<a name="macros"></a>
+<h2 id="macros">Macros</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#QDOCTEST_MACRO2">QDOCTEST_MACRO2</a></b>(<i>x</i>)</td></tr>
+</table></div>
+<a name="details"></a>
+<!-- $$$Test-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@Test -->
+<div class="types">
+<h2>Member Type Documentation</h2>
+<!-- $$$ScopedEnum$$$This$$$That$$$All$$$OmittedValue -->
+<h3 class="fn" id="ScopedEnum-enum"><a name="ScopedEnum-enum"></a>enum class Test::<span class="name">ScopedEnum</span></h3>
+<div class="table"><table class="valuelist"><tr valign="top" class="odd"><th class="tblConst">Constant</th><th class="tblval">Value</th><th class="tbldscr">Description</th></tr>
+<tr><td class="topAlign"><code>TestQDoc::Test::ScopedEnum::This</code></td><td class="topAlign tblval"><code>0x01</code></td><td class="topAlign">Something</td></tr>
+<tr><td class="topAlign"><code>TestQDoc::Test::ScopedEnum::That</code></td><td class="topAlign tblval"><code>0x02</code></td><td class="topAlign">Something else</td></tr>
+<tr><td class="topAlign"><code>TestQDoc::Test::ScopedEnum::All</code></td><td class="topAlign tblval"><code>This | That</code></td><td class="topAlign">Everything</td></tr>
+</table></div>
+<!-- @@@ScopedEnum -->
+</div>
+<div class="func">
+<h2>Member Function Documentation</h2>
+<!-- $$$ -->
+<div class="fngroup">
+<h3 class="fn fngroupitem" id="overload"><a name="overload"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>()</h3><h3 class="fn fngroupitem" id="overload-1"><a name="overload-1"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>(<span class="type">bool</span> <i>b</i>)</h3></div>
+<p>Overloads that share a documentation comment, optionally taking a parameter <i>b</i>.</p>
+<p>This function was introduced in Test 1.2.</p>
+<!-- @@@ -->
+<!-- $$$inlineFunction[overload1]$$$inlineFunction -->
+<h3 class="fn" id="inlineFunction"><a name="inlineFunction"></a><span class="type">void</span> Test::<span class="name">inlineFunction</span>()</h3>
+<p>An inline function, documented using the \fn QDoc command.</p>
+<!-- @@@inlineFunction -->
+<!-- $$$someFunction[overload1]$$$someFunctionint -->
+<h3 class="fn" id="someFunction"><a name="someFunction"></a><span class="type">int</span> Test::<span class="name">someFunction</span>(<span class="type">int</span> <i>v</i>)</h3>
+<p>Function that takes a parameter <i>v</i>. Also returns the value of <i>v</i>.</p>
+<!-- @@@someFunction -->
+<!-- $$$someFunctionDefaultArg[overload1]$$$someFunctionDefaultArgintbool -->
+<h3 class="fn" id="someFunctionDefaultArg"><a name="someFunctionDefaultArg"></a><span class="type">void</span> Test::<span class="name">someFunctionDefaultArg</span>(<span class="type">int</span> <i>i</i>, <span class="type">bool</span> <i>b</i> = false)</h3>
+<p>Function that takes a parameter <i>i</i> and <i>b</i>.</p>
+<!-- @@@someFunctionDefaultArg -->
+<!-- $$$virtualFun[overload1]$$$virtualFun -->
+<h3 class="fn" id="virtualFun"><a name="virtualFun"></a><code>[virtual] </code><span class="type">void</span> Test::<span class="name">virtualFun</span>()</h3>
+<p>Function that must be reimplemented.</p>
+<!-- @@@virtualFun -->
+</div>
+<div class="macros">
+<h2>Macro Documentation</h2>
+<!-- $$$QDOCTEST_MACRO2[overload1]$$$QDOCTEST_MACRO2 -->
+<h3 class="fn" id="QDOCTEST_MACRO2"><a name="QDOCTEST_MACRO2"></a><span class="name">QDOCTEST_MACRO2</span>(<i>x</i>)</h3>
+<p>A macro with argument <i>x</i>.</p>
+<p>This function was introduced in Test 1.1.</p>
+<!-- @@@QDOCTEST_MACRO2 -->
+</div>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/template/bar.html b/tests/auto/qdoc/generatedoutput/expected_output/template/bar.html
new file mode 100644
index 000000000..552cbe9cd
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/template/bar.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testtemplate.cpp -->
+ <title>Bar Class | TestCPP</title>
+</head>
+<body>
+<li>Bar</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">Bar Class</h1>
+<span class="small-subtitle">template &lt;typename T, typename D&gt; class Bar</span>
+<!-- $$$Bar-brief -->
+<p>Another class template. <a href="#details">More...</a></p>
+<!-- @@@Bar -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;Bar&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr></table></div><ul>
+</ul>
+<a name="details"></a>
+<!-- $$$Bar-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@Bar -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/template/baz.html b/tests/auto/qdoc/generatedoutput/expected_output/template/baz.html
new file mode 100644
index 000000000..4ab135c20
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/template/baz.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testtemplate.cpp -->
+ <title>Baz Class | TestCPP</title>
+</head>
+<body>
+<li>Baz</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">Baz Class</h1>
+<span class="small-subtitle">template &lt;template &lt;typename&gt; class X, typename Y&gt; class Baz</span>
+<!-- $$$Baz-brief -->
+<p>Class template template. <a href="#details">More...</a></p>
+<!-- @@@Baz -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;Baz&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr></table></div><ul>
+</ul>
+<a name="details"></a>
+<!-- $$$Baz-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@Baz -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/template/foo.html b/tests/auto/qdoc/generatedoutput/expected_output/template/foo.html
new file mode 100644
index 000000000..9e92a01b5
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/template/foo.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testtemplate.cpp -->
+ <title>Foo Class | TestCPP</title>
+</head>
+<body>
+<li>Foo</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">Foo Class</h1>
+<span class="small-subtitle">template &lt;typename T&gt; class Foo</span>
+<!-- $$$Foo-brief -->
+<p>Class template. <a href="#details">More...</a></p>
+<!-- @@@Foo -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;Foo&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr></table></div><ul>
+</ul>
+<a name="details"></a>
+<!-- $$$Foo-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@Foo -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/template/testqdoc-test.html b/tests/auto/qdoc/generatedoutput/expected_output/template/testqdoc-test.html
new file mode 100644
index 000000000..4ec52916a
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/template/testqdoc-test.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testcpp.cpp -->
+ <title>Test Class | TestCPP</title>
+</head>
+<body>
+<li>Test</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#public-functions">Public Functions</a></li>
+<li class="level1"><a href="#protected-functions">Protected Functions</a></li>
+<li class="level1"><a href="#macros">Macros</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">Test Class</h1>
+<span class="small-subtitle">class <a href="testqdoc.html">TestQDoc</a>::Test</span>
+<!-- $$$Test-brief -->
+<p>A class in a namespace. <a href="#details">More...</a></p>
+<!-- @@@Test -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;Test&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Inherited By:</td><td class="memItemRight bottomAlign"> <p><a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></p>
+</td></tr></table></div><ul>
+<li><a href="testqdoc-test-members.html">List of all members, including inherited members</a></li>
+<li><a href="testqdoc-test-obsolete.html">Obsolete members</a></li>
+</ul>
+<a name="public-functions"></a>
+<h2 id="public-functions">Public Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#inlineFunction">inlineFunction</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> int </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunction">someFunction</a></b>(int <i>v</i>)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunctionDefaultArg">someFunctionDefaultArg</a></b>(int <i>i</i>, bool <i>b</i> = false)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> virtual void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#virtualFun">virtualFun</a></b>()</td></tr>
+</table></div>
+<a name="protected-functions"></a>
+<h2 id="protected-functions">Protected Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#funcTemplate">funcTemplate</a></b>(T1 <i>a</i>, T2 <i>b</i>)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#overload">overload</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#overload-1">overload</a></b>(bool <i>b</i>)</td></tr>
+</table></div>
+<a name="macros"></a>
+<h2 id="macros">Macros</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#QDOCTEST_MACRO2">QDOCTEST_MACRO2</a></b>(<i>x</i>)</td></tr>
+</table></div>
+<a name="details"></a>
+<!-- $$$Test-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+</div>
+<!-- @@@Test -->
+<div class="func">
+<h2>Member Function Documentation</h2>
+<!-- $$$ -->
+<div class="fngroup">
+<h3 class="fn fngroupitem" id="overload"><a name="overload"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>()</h3><h3 class="fn fngroupitem" id="overload-1"><a name="overload-1"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>(<span class="type">bool</span> <i>b</i>)</h3></div>
+<p>Overloads that share a documentation comment, optionally taking a parameter <i>b</i>.</p>
+<p>This function was introduced in Test 1.2.</p>
+<!-- @@@ -->
+<!-- $$$funcTemplate[overload1]$$$funcTemplateT1T2 -->
+<h3 class="fn" id="funcTemplate"><a name="funcTemplate"></a><code>[protected] </code>template &lt;typename T1, typename T2&gt; <span class="type">void</span> Test::<span class="name">funcTemplate</span>(<span class="type">T1</span> <i>a</i>, <span class="type">T2</span> <i>b</i>)</h3>
+<p>Function template with two parameters, <i>a</i> and <i>b</i>.</p>
+<!-- @@@funcTemplate -->
+<!-- $$$inlineFunction[overload1]$$$inlineFunction -->
+<h3 class="fn" id="inlineFunction"><a name="inlineFunction"></a><span class="type">void</span> Test::<span class="name">inlineFunction</span>()</h3>
+<p>An inline function, documented using the \fn QDoc command.</p>
+<!-- @@@inlineFunction -->
+<!-- $$$someFunction[overload1]$$$someFunctionint -->
+<h3 class="fn" id="someFunction"><a name="someFunction"></a><span class="type">int</span> Test::<span class="name">someFunction</span>(<span class="type">int</span> <i>v</i>)</h3>
+<p>Function that takes a parameter <i>v</i>. Also returns the value of <i>v</i>.</p>
+<!-- @@@someFunction -->
+<!-- $$$someFunctionDefaultArg[overload1]$$$someFunctionDefaultArgintbool -->
+<h3 class="fn" id="someFunctionDefaultArg"><a name="someFunctionDefaultArg"></a><span class="type">void</span> Test::<span class="name">someFunctionDefaultArg</span>(<span class="type">int</span> <i>i</i>, <span class="type">bool</span> <i>b</i> = false)</h3>
+<p>Function that takes a parameter <i>i</i> and <i>b</i>.</p>
+<!-- @@@someFunctionDefaultArg -->
+<!-- $$$virtualFun[overload1]$$$virtualFun -->
+<h3 class="fn" id="virtualFun"><a name="virtualFun"></a><code>[virtual] </code><span class="type">void</span> Test::<span class="name">virtualFun</span>()</h3>
+<p>Function that must be reimplemented.</p>
+<!-- @@@virtualFun -->
+</div>
+<div class="macros">
+<h2>Macro Documentation</h2>
+<!-- $$$QDOCTEST_MACRO2[overload1]$$$QDOCTEST_MACRO2 -->
+<h3 class="fn" id="QDOCTEST_MACRO2"><a name="QDOCTEST_MACRO2"></a><span class="name">QDOCTEST_MACRO2</span>(<i>x</i>)</h3>
+<p>A macro with argument <i>x</i>.</p>
+<p>This function was introduced in Test 1.1.</p>
+<!-- @@@QDOCTEST_MACRO2 -->
+</div>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html b/tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html
new file mode 100644
index 000000000..dc123674d
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- cmaketest.qdoc -->
+ <title>CMake Example Project | Test</title>
+</head>
+<body>
+<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">CMake Example Project</h1>
+<span class="subtitle"></span>
+<!-- $$$cmaketest-description -->
+<div class="descr"> <a name="details"></a>
+<p>Files:</p>
+<ul>
+<li><a href="test-cmaketest-cmakelists-txt.html">cmaketest/CMakeLists.txt</a></li>
+<li><a href="test-cmaketest-main-cpp.html">cmaketest/main.cpp</a></li>
+</ul>
+</div>
+<!-- @@@cmaketest -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/test.qhp b/tests/auto/qdoc/generatedoutput/expected_output/test.qhp
new file mode 100644
index 000000000..459892df1
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/test.qhp
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+ <namespace>org.qt-project.test.001</namespace>
+ <virtualFolder>test</virtualFolder>
+ <metaData name="version" value="0.0.1"/>
+ <filterSection>
+ <toc>
+ <section ref="uicomponents-qmlmodule.html" title="UI Components">
+ <section ref="uicomponents-qmlmodule.html" title="Test">
+ <section ref="qdoc-test-qmlmodule.html" title=""/>
+ <section ref="test-cmaketest-example.html" title="CMake Example Project"/>
+ <section ref="testcpp-module.html" title="QDoc Test C++ Classes"/>
+ <section ref="test-componentset-example.html" title="QML Documentation Example"/>
+ <section ref="uicomponents-qmlmodule.html" title="UI Components"/>
+ </section>
+ <section ref="testcpp-module.html" title="Classes">
+ <section ref="testqdoc.html" title="TestQDoc"/>
+ <section ref="testqdoc-test.html" title="TestQDoc::Test Class Reference">
+ <section ref="testqdoc-test-members.html" title="List of all members"/>
+ <section ref="testqdoc-test-obsolete.html" title="Obsolete members"/>
+ </section>
+ <section ref="testqdoc-testderived.html" title="TestQDoc::TestDerived Class Reference">
+ <section ref="testqdoc-testderived-members.html" title="List of all members"/>
+ </section>
+ </section>
+ <section ref="uicomponents-qmlmodule.html" title="QML Types">
+ <section ref="qml-qdoc-test-abstractparent.html" title="AbstractParent Type Reference">
+ <section ref="qml-qdoc-test-abstractparent-members.html" title="List of all members"/>
+ </section>
+ <section ref="qml-qdoc-test-child.html" title="Child Type Reference">
+ <section ref="qml-qdoc-test-child-members.html" title="List of all members"/>
+ </section>
+ <section ref="qml-qdoc-test-doctest.html" title="DocTest Type Reference">
+ <section ref="qml-qdoc-test-doctest-members.html" title="List of all members"/>
+ </section>
+ <section ref="qml-qdoc-test-type.html" title="Type Type Reference">
+ <section ref="qml-qdoc-test-type-members.html" title="List of all members"/>
+ </section>
+ <section ref="qml-uicomponents-progressbar.html" title="ProgressBar Type Reference">
+ <section ref="qml-uicomponents-progressbar-members.html" title="List of all members"/>
+ </section>
+ <section ref="qml-uicomponents-switch.html" title="Switch Type Reference">
+ <section ref="qml-uicomponents-switch-members.html" title="List of all members"/>
+ </section>
+ <section ref="qml-uicomponents-tabwidget.html" title="TabWidget Type Reference">
+ <section ref="qml-uicomponents-tabwidget-members.html" title="List of all members"/>
+ </section>
+ <section ref="qml-int.html" title="int Type Reference"/>
+ </section>
+ </section>
+ </toc>
+ <keywords>
+ <keyword name="AbstractParent" id="QML.AbstractParent" ref="qml-qdoc-test-abstractparent.html"/>
+ <keyword name="Child" id="QML.Child" ref="qml-qdoc-test-child.html"/>
+ <keyword name="DocTest" id="QML.DocTest" ref="qml-qdoc-test-doctest.html"/>
+ <keyword name="ProgressBar" id="QML.ProgressBar" ref="qml-uicomponents-progressbar.html"/>
+ <keyword name="QDOCTEST_MACRO" id="QDOCTEST_MACRO" ref="testqdoc.html#QDOCTEST_MACRO"/>
+ <keyword name="QDOCTEST_MACRO2" id="QDOCTEST_MACRO2" ref="testqdoc-test.html#QDOCTEST_MACRO2"/>
+ <keyword name="QDoc Test C++ Classes" id="QDoc Test C++ Classes" ref="testcpp-module.html"/>
+ <keyword name="Switch" id="QML.Switch" ref="qml-uicomponents-switch.html"/>
+ <keyword name="TabWidget" id="QML.TabWidget" ref="qml-uicomponents-tabwidget.html"/>
+ <keyword name="Test" id="TestQDoc::Test" ref="testqdoc-test.html"/>
+ <keyword name="TestDerived" id="TestQDoc::TestDerived" ref="testqdoc-testderived.html"/>
+ <keyword name="TestQDoc" id="TestQDoc" ref="testqdoc.html"/>
+ <keyword name="Type" id="QML.Type" ref="qml-qdoc-test-type.html"/>
+ <keyword name="UI Components" id="UI Components" ref="uicomponents-qmlmodule.html"/>
+ <keyword name="abs" id="int::abs" ref="qml-int.html#abs-method"/>
+ <keyword name="active" id="DocTest::active" ref="qml-qdoc-test-doctest.html#active-prop"/>
+ <keyword name="anotherObsoleteMember" id="Test::anotherObsoleteMember" ref="testqdoc-test-obsolete.html#anotherObsoleteMember"/>
+ <keyword name="children" id="AbstractParent::children" ref="qml-qdoc-test-abstractparent.html#children-prop"/>
+ <keyword name="color" id="ProgressBar::color" ref="qml-uicomponents-progressbar.html#color-prop"/>
+ <keyword name="completed" id="Type::completed" ref="qml-qdoc-test-type.html#completed-signal"/>
+ <keyword name="configured" id="Type::configured" ref="qml-qdoc-test-type.html#configured-signal"/>
+ <keyword name="copy" id="Type::copy" ref="qml-qdoc-test-type.html#copy-method"/>
+ <keyword name="current" id="TabWidget::current" ref="qml-uicomponents-tabwidget.html#current-prop"/>
+ <keyword name="deprecatedMember" id="Test::deprecatedMember" ref="testqdoc-test-obsolete.html#deprecatedMember"/>
+ <keyword name="disable" id="Type::disable" ref="qml-qdoc-test-type.html#disable-method"/>
+ <keyword name="enable" id="Type::enable" ref="qml-qdoc-test-type.html#enable-method"/>
+ <keyword name="fail" id="DocTest::fail" ref="qml-qdoc-test-doctest.html#fail-method"/>
+ <keyword name="fifth" id="Type::fifth" ref="qml-qdoc-test-type.html#fifth-prop"/>
+ <keyword name="fourth" id="Type::fourth" ref="qml-qdoc-test-type.html#fourth-prop"/>
+ <keyword name="group.first" id="Type::group.first" ref="qml-qdoc-test-type.html#group.first-prop"/>
+ <keyword name="group.second" id="Type::group.second" ref="qml-qdoc-test-type.html#group.second-prop"/>
+ <keyword name="group.third" id="Type::group.third" ref="qml-qdoc-test-type.html#group.third-prop"/>
+ <keyword name="id" id="Type::id" ref="qml-qdoc-test-type.html#id-prop"/>
+ <keyword name="inlineFunction" id="Test::inlineFunction" ref="testqdoc-test.html#inlineFunction"/>
+ <keyword name="int" id="QML.int" ref="qml-int.html"/>
+ <keyword name="maximum" id="ProgressBar::maximum" ref="qml-uicomponents-progressbar.html#maximum-prop"/>
+ <keyword name="minimum" id="ProgressBar::minimum" ref="qml-uicomponents-progressbar.html#minimum-prop"/>
+ <keyword name="name" id="DocTest::name" ref="qml-qdoc-test-doctest.html#name-prop"/>
+ <keyword name="name" id="Type::name" ref="qml-qdoc-test-type.html#name-prop"/>
+ <keyword name="obsoleteMember" id="Test::obsoleteMember" ref="testqdoc-test-obsolete.html#obsoleteMember"/>
+ <keyword name="on" id="Switch::on" ref="qml-uicomponents-switch.html#on-prop"/>
+ <keyword name="overload" id="Test::overload" ref="testqdoc-test.html#overload"/>
+ <keyword name="rear" id="AbstractParent::rear" ref="qml-qdoc-test-abstractparent.html#rear-method"/>
+ <keyword name="sampleReadOnlyProperty" id="TabWidget::sampleReadOnlyProperty" ref="qml-uicomponents-tabwidget.html#sampleReadOnlyProperty-prop"/>
+ <keyword name="secondColor" id="ProgressBar::secondColor" ref="qml-uicomponents-progressbar.html#secondColor-prop"/>
+ <keyword name="someFunction" id="Test::someFunction" ref="testqdoc-test.html#someFunction"/>
+ <keyword name="someFunctionDefaultArg" id="Test::someFunctionDefaultArg" ref="testqdoc-test.html#someFunctionDefaultArg"/>
+ <keyword name="toggle" id="Switch::toggle" ref="qml-uicomponents-switch.html#toggle-method"/>
+ <keyword name="type" id="Type::type" ref="qml-qdoc-test-type.html#type-attached-prop"/>
+ <keyword name="value" id="ProgressBar::value" ref="qml-uicomponents-progressbar.html#value-prop"/>
+ <keyword name="virtualFun" id="Test::virtualFun" ref="testqdoc-test.html#virtualFun"/>
+ <keyword name="virtualFun" id="TestDerived::virtualFun" ref="testqdoc-testderived.html#virtualFun"/>
+ </keywords>
+ <files>
+ <file>qdoc-test-qmlmodule.html</file>
+ <file>qml-int.html</file>
+ <file>qml-qdoc-test-abstractparent-members.html</file>
+ <file>qml-qdoc-test-abstractparent.html</file>
+ <file>qml-qdoc-test-child-members.html</file>
+ <file>qml-qdoc-test-child.html</file>
+ <file>qml-qdoc-test-doctest-members.html</file>
+ <file>qml-qdoc-test-doctest.html</file>
+ <file>qml-qdoc-test-type-members.html</file>
+ <file>qml-qdoc-test-type.html</file>
+ <file>qml-uicomponents-progressbar-members.html</file>
+ <file>qml-uicomponents-progressbar.html</file>
+ <file>qml-uicomponents-switch-members.html</file>
+ <file>qml-uicomponents-switch.html</file>
+ <file>qml-uicomponents-tabwidget-members.html</file>
+ <file>qml-uicomponents-tabwidget.html</file>
+ <file>test-cmaketest-cmakelists-txt.html</file>
+ <file>test-cmaketest-example.html</file>
+ <file>test-cmaketest-main-cpp.html</file>
+ <file>test-componentset-componentset-pro.html</file>
+ <file>test-componentset-example.html</file>
+ <file>test-componentset-progressbar-qml.html</file>
+ <file>test-componentset-switch-qml.html</file>
+ <file>test-componentset-tabwidget-qml.html</file>
+ <file>testcpp-module.html</file>
+ <file>testqdoc-test-members.html</file>
+ <file>testqdoc-test-obsolete.html</file>
+ <file>testqdoc-test.html</file>
+ <file>testqdoc-testderived-members.html</file>
+ <file>testqdoc-testderived.html</file>
+ <file>testqdoc.html</file>
+ <file>uicomponents-qmlmodule.html</file>
+ </files>
+ </filterSection>
+</QtHelpProject>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testcpp.index b/tests/auto/qdoc/generatedoutput/expected_output/testcpp.index
new file mode 100644
index 000000000..ae997fa52
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/testcpp.index
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QDOCINDEX>
+<INDEX url="" title="TestCPP Reference Documentation" version="" project="TestCPP">
+ <namespace name="" status="active" access="public" module="testcpp">
+ <function name="QDOCTEST_MACRO" href="testqdoc.html#QDOCTEST_MACRO" status="active" access="public" documented="true" related="true" meta="macrowithoutparams" virtual="non" const="false" static="false" final="false" override="false" type="" signature="QDOCTEST_MACRO"/>
+ <function name="QDOCTEST_MACRO2" href="testqdoc-test.html#QDOCTEST_MACRO2" status="active" access="public" documented="true" related="true" since="Test 1.1" meta="macrowithparams" virtual="non" const="false" static="false" final="false" override="false" type="" brief="A macro with argument x" signature="QDOCTEST_MACRO2( x)">
+ <parameter type="" name="x" default=""/>
+ </function>
+ <namespace name="TestQDoc" href="testqdoc.html" status="active" access="public" location="testcpp.h" documented="true" module="TestCPP" brief="A namespace">
+ <contents name="usage" title="Usage" level="1"/>
+ <function name="QDOCTEST_MACRO" href="testqdoc.html#QDOCTEST_MACRO" status="active" access="public" documented="true" related="true" meta="macrowithoutparams" virtual="non" const="false" static="false" final="false" override="false" type="" signature="QDOCTEST_MACRO"/>
+ <class name="Test" fullname="TestQDoc::Test" href="testqdoc-test.html" status="active" access="public" location="testcpp.h" documented="true" module="TestCPP" brief="A class in a namespace">
+ <function name="QDOCTEST_MACRO2" href="testqdoc-test.html#QDOCTEST_MACRO2" status="active" access="public" documented="true" related="true" since="Test 1.1" meta="macrowithparams" virtual="non" const="false" static="false" final="false" override="false" type="" brief="A macro with argument x" signature="QDOCTEST_MACRO2( x)">
+ <parameter type="" name="x" default=""/>
+ </function>
+ <function name="anotherObsoleteMember" fullname="TestQDoc::Test::anotherObsoleteMember" href="testqdoc-test-obsolete.html#anotherObsoleteMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void anotherObsoleteMember()"/>
+ <function name="deprecatedMember" fullname="TestQDoc::Test::deprecatedMember" href="testqdoc-test-obsolete.html#deprecatedMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void deprecatedMember()"/>
+ <function name="inlineFunction" fullname="TestQDoc::Test::inlineFunction" href="testqdoc-test.html#inlineFunction" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" brief="An inline function, documented using the \fn QDoc command" signature="void inlineFunction()"/>
+ <function name="obsoleteMember" fullname="TestQDoc::Test::obsoleteMember" href="testqdoc-test-obsolete.html#obsoleteMember" status="obsolete" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void obsoleteMember()"/>
+ <function name="overload" fullname="TestQDoc::Test::overload" href="testqdoc-test.html#overload" status="active" access="protected" location="testcpp.h" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void overload()"/>
+ <function name="overload" fullname="TestQDoc::Test::overload" href="testqdoc-test.html#overload-1" status="active" access="protected" location="testcpp.h" meta="plain" virtual="non" const="false" static="false" final="false" override="false" overload="true" overload-number="1" type="void" signature="void overload(bool b)">
+ <parameter type="bool" name="b" default=""/>
+ </function>
+ <function name="someFunction" fullname="TestQDoc::Test::someFunction" href="testqdoc-test.html#someFunction" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="int" signature="int someFunction(int v)">
+ <parameter type="int" name="v" default=""/>
+ </function>
+ <function name="someFunctionDefaultArg" fullname="TestQDoc::Test::someFunctionDefaultArg" href="testqdoc-test.html#someFunctionDefaultArg" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="non" const="false" static="false" final="false" override="false" type="void" signature="void someFunctionDefaultArg(int i, bool b)">
+ <parameter type="int" name="i" default=""/>
+ <parameter type="bool" name="b" default="false"/>
+ </function>
+ <function name="virtualFun" fullname="TestQDoc::Test::virtualFun" href="testqdoc-test.html#virtualFun" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="false" type="void" signature="void virtualFun()"/>
+ </class>
+ <class name="TestDerived" fullname="TestQDoc::TestDerived" href="testqdoc-testderived.html" status="active" access="public" location="testcpp.h" documented="true" bases="TestQDoc::Test" module="TestCPP" brief="A derived class in a namespace">
+ <function name="virtualFun" fullname="TestQDoc::TestDerived::virtualFun" href="testqdoc-testderived.html#virtualFun" status="active" access="public" location="testcpp.h" documented="true" meta="plain" virtual="virtual" const="false" static="false" final="false" override="true" type="void" signature="void virtualFun() override"/>
+ </class>
+ </namespace>
+ <module name="TestCPP" href="testcpp-module.html" status="active" documented="true" seen="true" title="QDoc Test C++ Classes" module="TestCPP" members="TestQDoc,Test,TestDerived" brief="A test module page"/>
+ </namespace>
+</INDEX>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html
index f373f725a..84c0c4fe3 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html
+++ b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html
@@ -19,7 +19,7 @@
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Test Class</h1>
-<span class="small-subtitle">(<a href="testqdoc-test.html">TestQDoc::Test</a>)<br/></span>
+<span class="small-subtitle">class <a href="testqdoc.html">TestQDoc</a>::Test</span>
<!-- $$$Test-brief -->
<p>A class in a namespace. <a href="#details">More...</a></p>
<!-- @@@Test -->
@@ -61,6 +61,7 @@
<div class="fngroup">
<h3 class="fn fngroupitem" id="overload"><a name="overload"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>()</h3><h3 class="fn fngroupitem" id="overload-1"><a name="overload-1"></a><code>[protected] </code><span class="type">void</span> Test::<span class="name">overload</span>(<span class="type">bool</span> <i>b</i>)</h3></div>
<p>Overloads that share a documentation comment, optionally taking a parameter <i>b</i>.</p>
+<p>This function was introduced in Test 1.2.</p>
<!-- @@@ -->
<!-- $$$inlineFunction[overload1]$$$inlineFunction -->
<h3 class="fn" id="inlineFunction"><a name="inlineFunction"></a><span class="type">void</span> Test::<span class="name">inlineFunction</span>()</h3>
diff --git a/tests/auto/qdoc/generatedoutput/generatedoutput.pro b/tests/auto/qdoc/generatedoutput/generatedoutput.pro
index 81434cebc..be9377bec 100644
--- a/tests/auto/qdoc/generatedoutput/generatedoutput.pro
+++ b/tests/auto/qdoc/generatedoutput/generatedoutput.pro
@@ -5,5 +5,3 @@ TARGET = tst_generatedOutput
SOURCES += \
tst_generatedoutput.cpp
-
-QMAKE_DOCS = $$PWD/test.qdocconf
diff --git a/tests/auto/qdoc/generatedoutput/test.qdocconf b/tests/auto/qdoc/generatedoutput/test.qdocconf
deleted file mode 100644
index fe51e1c67..000000000
--- a/tests/auto/qdoc/generatedoutput/test.qdocconf
+++ /dev/null
@@ -1,8 +0,0 @@
-project = Test
-description = "A test project for QDoc build artifacts"
-moduleheader =
-
-sources = qdoctests-outputfromqdocfiles.qdoc
-
-macro.beginqdoc = "\\c {/*!}"
-macro.endqdoc = "\\c */"
diff --git a/tests/auto/qdoc/generatedoutput/testcpp.qdocconf b/tests/auto/qdoc/generatedoutput/testcpp.qdocconf
deleted file mode 100644
index 70c226cf2..000000000
--- a/tests/auto/qdoc/generatedoutput/testcpp.qdocconf
+++ /dev/null
@@ -1,7 +0,0 @@
-project = TestCPP
-includepaths += -I.
-
-headers = testcpp.h
-sources = testcpp.cpp
-
-macro.CMDFN = \\\\fn
diff --git a/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/TestModule.h b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/TestModule.h
new file mode 100644
index 000000000..06f046a71
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/TestModule.h
@@ -0,0 +1,3 @@
+#include "aaa.h"
+#include "bbb.h"
+#include "ccc.h"
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/aaa.h b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/aaa.h
index dea5c1841..dea5c1841 100644
--- a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/aaa.h
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/aaa.h
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/bbb.h b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/bbb.h
index 0dc6e52c6..0dc6e52c6 100644
--- a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/bbb.h
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/bbb.h
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/ccc.h b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/ccc.h
index d3a1557e1..d3a1557e1 100644
--- a/tests/auto/qdoc/generatedoutput/bug80259/inc/testmodule/ccc.h
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/inc/testmodule/ccc.h
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/src/main.cpp b/tests/auto/qdoc/generatedoutput/testdata/bug80259/src/main.cpp
index a8991e18f..a8991e18f 100644
--- a/tests/auto/qdoc/generatedoutput/bug80259/src/main.cpp
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/src/main.cpp
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/src/qdoc/index.qdoc b/tests/auto/qdoc/generatedoutput/testdata/bug80259/src/qdoc/index.qdoc
index 35ef7e087..35ef7e087 100644
--- a/tests/auto/qdoc/generatedoutput/bug80259/src/qdoc/index.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/src/qdoc/index.qdoc
diff --git a/tests/auto/qdoc/generatedoutput/bug80259/testmodule.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/bug80259/testmodule.qdocconf
index c02fb6fcf..23a4b27f6 100644
--- a/tests/auto/qdoc/generatedoutput/bug80259/testmodule.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/testmodule.qdocconf
@@ -2,9 +2,9 @@ project = TestModule
moduleheader = TestModule.h
-headerdirs = inc
-sourcedirs = src
-includepaths += ./bug80259/inc/testmodule
+headerdirs = ./inc
+sourcedirs = ./src
+includepaths += ./inc/testmodule
sources.fileextensions = "*.cpp *.qdoc"
headers.fileextensions = "*.h"
diff --git a/tests/auto/qdoc/generatedoutput/testdata/bug80259/webxml_testmodule.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/bug80259/webxml_testmodule.qdocconf
new file mode 100644
index 000000000..dc9234fbb
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/bug80259/webxml_testmodule.qdocconf
@@ -0,0 +1,2 @@
+include(testmodule.qdocconf)
+include(../configs/webxml.qdocconf)
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/docbook.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook.qdocconf
new file mode 100644
index 000000000..68afd29e8
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook.qdocconf
@@ -0,0 +1,7 @@
+outputformats = DocBook
+DocBook.nosubdirs = true
+DocBook.outputsubdir = docbook
+
+# TODO: DocBook generator has trouble handling shared comment nodes
+# allow two warnings related to these
+warninglimit = 2
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_test.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_test.qdocconf
new file mode 100644
index 000000000..e8095e405
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_test.qdocconf
@@ -0,0 +1,2 @@
+include(test.qdocconf)
+include(docbook.qdocconf)
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testcpp.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testcpp.qdocconf
new file mode 100644
index 000000000..0abdf8169
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testcpp.qdocconf
@@ -0,0 +1,2 @@
+include(testcpp.qdocconf)
+include(docbook.qdocconf)
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testqml.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testqml.qdocconf
new file mode 100644
index 000000000..0a0a18b07
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/docbook_testqml.qdocconf
@@ -0,0 +1,2 @@
+include(testqml.qdocconf)
+include(docbook.qdocconf)
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf
new file mode 100644
index 000000000..a1ed619a3
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf
@@ -0,0 +1,37 @@
+# QML test includes a documented example
+include(testqml.qdocconf)
+version = 0.0.1
+
+examplesinstallpath = test
+
+# Configure .qhp generation
+qhp.projects = Test
+
+qhp.Test.file = test.qhp
+qhp.Test.namespace = org.qt-project.test.001
+qhp.Test.virtualFolder = test
+qhp.Test.indexTitle = UI Components
+qhp.Test.indexRoot =
+
+qhp.Test.subprojects = test classes qmltypes undefined
+qhp.Test.subprojects.test.title = Test
+qhp.Test.subprojects.test.indexTitle = UI Components
+qhp.Test.subprojects.test.selectors = doc:page fake:example module qmlmodule
+qhp.Test.subprojects.test.sortPages = true
+
+qhp.Test.subprojects.classes.title = Classes
+qhp.Test.subprojects.classes.indexTitle = QDoc Test C++ Classes
+qhp.Test.subprojects.classes.selectors = class namespace doc:headerfile boop:whatever
+qhp.Test.subprojects.classes.sortPages = true
+
+qhp.Test.subprojects.qmltypes.title = QML Types
+qhp.Test.subprojects.qmltypes.indexTitle = UI Components
+qhp.Test.subprojects.qmltypes.selectors = qmlmodule:UIComponents,QDoc.Test
+qhp.Test.subprojects.qmltypes.sortPages = true
+
+# Add some meta-data to the example
+manifestmeta.filters = test
+
+manifestmeta.test.names = *
+manifestmeta.test.attributes = isTest:true
+manifestmeta.test.tags = test
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/ignoresince.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/ignoresince.qdocconf
new file mode 100644
index 000000000..0aa0dbc45
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/ignoresince.qdocconf
@@ -0,0 +1,8 @@
+include(testcpp.qdocconf)
+defines += test_ignoresince
+
+ignoresince = 2.0
+ignoresince.Test = 1.0
+
+HTML.nosubdirs = true
+HTML.outputsubdir = ignoresince
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/noautolist.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/noautolist.qdocconf
new file mode 100644
index 000000000..fc720c57e
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/noautolist.qdocconf
@@ -0,0 +1,13 @@
+include(testqml.qdocconf)
+defines += test_noautolist
+
+outputformats = HTML DocBook
+
+HTML.nosubdirs = true
+DocBook.nosubdirs = true
+HTML.outputsubdir = noautolist
+DocBook.outputsubdir = noautolist-docbook
+
+# TODO: DocBook generator has trouble handling shared comment nodes
+# - allow two warnings related to these
+warninglimit = 2
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/scopedenum.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/scopedenum.qdocconf
new file mode 100644
index 000000000..adeaab554
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/scopedenum.qdocconf
@@ -0,0 +1,7 @@
+include(testcpp.qdocconf)
+defines += test_scopedenum
+
+sources += ../scopedenum/scopedenum.qdoc
+
+HTML.nosubdirs = true
+HTML.outputsubdir = scopedenum
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/test.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/test.qdocconf
new file mode 100644
index 000000000..e4cef822e
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/test.qdocconf
@@ -0,0 +1,12 @@
+project = OutputFromQDocFiles
+description = "A test project for QDoc build artifacts"
+moduleheader =
+
+sources = ../outputfromqdocfiles/qdoctests-outputfromqdocfiles.qdoc
+
+macro.beginqdoc = "\\c {/*!}"
+macro.endqdoc = "\\c */"
+
+# zero warning tolerance
+warninglimit = 0
+warninglimit.enabled = true
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp.qdocconf
new file mode 100644
index 000000000..7bb7810f1
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp.qdocconf
@@ -0,0 +1,14 @@
+project = TestCPP
+includepaths += -I../testcpp
+
+headers = ../testcpp/testcpp.h
+sources = ../testcpp/testcpp.cpp
+
+macro.CMDFN = \\\\fn
+macro.nothing = \\dontdocument ()
+macro.testnoautolist = \\if defined(test_noautolist)\n\\noautolist\n\\endif
+locationinfo = false
+
+# zero warning tolerance
+warninglimit = 0
+warninglimit.enabled = true
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp_singleexec.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp_singleexec.qdocconf
new file mode 100644
index 000000000..2ca75ea0a
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp_singleexec.qdocconf
@@ -0,0 +1,6 @@
+include(testcpp.qdocconf)
+
+# Config::getOutputDir() forces a subdir in single-exec mode (why?),
+# disable it here explicitly
+HTML.nosubdirs = true
+HTML.outputsubdir = .
diff --git a/tests/auto/qdoc/generatedoutput/testqml.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf
index f618fe1b8..8eec4ea4d 100644
--- a/tests/auto/qdoc/generatedoutput/testqml.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf
@@ -5,18 +5,18 @@ project = Test
description = "A test project for QDoc build artifacts"
outputdir = ./html
-exampledirs = qml
+exampledirs = ../qml
-headerdirs += .
-sourcedirs += qml
+headerdirs += ../
+sourcedirs += ../qml
# Exclude source files from other tests' subdirs
-excludedirs = ./bug80259
+excludedirs = ../bug80259
sources.fileextensions = "*.qml *.cpp *.qdoc"
headers.fileextensions = "*.h"
-examples.fileextensions = "*.qml"
+examples.fileextensions = "*.qml *.cpp"
macro.begincomment = "\\c{/*}"
macro.QDocTestVer = "1.1"
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/testtemplate.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/testtemplate.qdocconf
new file mode 100644
index 000000000..c53e43177
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/testtemplate.qdocconf
@@ -0,0 +1,8 @@
+include(testcpp.qdocconf)
+defines += test_template
+
+headers += ../testtemplate/testtemplate.h
+sources += ../testtemplate/testtemplate.cpp
+
+HTML.nosubdirs = true
+HTML.outputsubdir = template
diff --git a/tests/auto/qdoc/generatedoutput/webxml.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml.qdocconf
index d6e6290b8..903c7fcfe 100644
--- a/tests/auto/qdoc/generatedoutput/webxml.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml.qdocconf
@@ -1,3 +1,4 @@
+locationinfo = false
outputformats = WebXML
WebXML.quotinginformation = true
WebXML.nosubdirs = true
diff --git a/tests/auto/qdoc/generatedoutput/webxml_test.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml_test.qdocconf
index bac4f3b4e..bac4f3b4e 100644
--- a/tests/auto/qdoc/generatedoutput/webxml_test.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml_test.qdocconf
diff --git a/tests/auto/qdoc/generatedoutput/webxml_testcpp.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml_testcpp.qdocconf
index e242cef27..e242cef27 100644
--- a/tests/auto/qdoc/generatedoutput/webxml_testcpp.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml_testcpp.qdocconf
diff --git a/tests/auto/qdoc/generatedoutput/webxml_testqml.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml_testqml.qdocconf
index 537685700..537685700 100644
--- a/tests/auto/qdoc/generatedoutput/webxml_testqml.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/webxml_testqml.qdocconf
diff --git a/tests/auto/qdoc/generatedoutput/testdata/crossmodule/CrossModule b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/CrossModule
new file mode 100644
index 000000000..50bea93ab
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/CrossModule
@@ -0,0 +1,2 @@
+#include "../testcpp/TestCPP"
+#include "testtype.h"
diff --git a/tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule.qdocconf
new file mode 100644
index 000000000..fb4a6be77
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule.qdocconf
@@ -0,0 +1,10 @@
+project = CrossModule
+includepaths += -I.
+
+depends = testcpp
+
+headers = testtype.h
+sources = testtype.cpp
+
+HTML.nosubdirs = true
+HTML.outputsubdir = crossmodule
diff --git a/tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule_singleexec.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule_singleexec.qdocconf
new file mode 100644
index 000000000..d49498ec0
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/crossmodule_singleexec.qdocconf
@@ -0,0 +1,4 @@
+include(crossmodule.qdocconf)
+
+HTML.nosubdirs = true
+HTML.outputsubdir = crossmodule
diff --git a/tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.cpp b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.cpp
new file mode 100644
index 000000000..50d5d4845
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "testtype.h"
+
+/*!
+ \module CrossModule
+*/
+/*!
+ \class TestType
+ \inmodule CrossModule
+ \brief A class inheriting another class that lives in an external doc
+ module.
+
+ \section1 Linking
+
+ These links go to the parent class:
+ \list
+ \li \l {TestQDoc::TestDerived}
+ \li \l {TestQDoc::}{Test} class \l Usage.
+ \li QDOCTEST_MACRO
+ \endlist
+
+ \sa {TestQDoc::Test::}{someFunction()}
+*/
+
+/*!
+ Nothing to see here.
+*/
+void TestType::nothing()
+{
+}
diff --git a/tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.h b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.h
new file mode 100644
index 000000000..4ffb0c80b
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/crossmodule/testtype.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+
+#include "../testcpp/testcpp.h"
+
+class TestType : public TestQDoc::TestDerived
+{
+public:
+ TestType() {}
+ void nothing() {}
+};
diff --git a/tests/auto/qdoc/generatedoutput/testdata/dontdocument/TestCPP b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/TestCPP
new file mode 100644
index 000000000..7291e6d8f
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/TestCPP
@@ -0,0 +1,2 @@
+#include "../TestCPP"
+#include "dont.h"
diff --git a/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.cpp b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.cpp
new file mode 100644
index 000000000..33e208459
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "dont.h"
+
+/*!
+ \class UnseenClass
+ \inmodule TestCPP
+ \brief A public but undocumented class.
+*/
+UnseenClass::UnseenClass()
+{
+}
+
+/*!
+ \class SeenClass
+ \inmodule TestCPP
+ \brief A public but undocumented class.
+*/
+SeenClass::SeenClass()
+{
+}
diff --git a/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.h b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.h
new file mode 100644
index 000000000..5ef436b5c
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dont.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+
+class UnseenClass
+{
+public:
+ UnseenClass();
+};
+
+class SeenClass : public UnseenClass
+{
+public:
+ SeenClass();
+};
diff --git a/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dontdocument.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dontdocument.qdocconf
new file mode 100644
index 000000000..117920e56
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/dontdocument.qdocconf
@@ -0,0 +1,7 @@
+include(../configs/testcpp.qdocconf)
+
+headers += dont.h
+sources += dont.cpp test.qdoc
+
+HTML.nosubdirs = true
+HTML.outputsubdir = dontdocument
diff --git a/tests/auto/qdoc/generatedoutput/testdata/dontdocument/test.qdoc b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/test.qdoc
new file mode 100644
index 000000000..3f6e0be30
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/dontdocument/test.qdoc
@@ -0,0 +1,36 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \dontdocument (UnseenClass)
+*/
+
+/*! \page classes.html
+ \title Classes
+ \generatelist annotatedclasses
+*/
diff --git a/tests/auto/qdoc/generatedoutput/includefromexampledirs/excludes/anotherindex.qdoc b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/excludes/anotherindex.qdoc
index 75dd9197d..75dd9197d 100644
--- a/tests/auto/qdoc/generatedoutput/includefromexampledirs/excludes/anotherindex.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/excludes/anotherindex.qdoc
diff --git a/tests/auto/qdoc/generatedoutput/includefromexampledirs/excludes/parentinclude.qdoc b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/excludes/parentinclude.qdoc
index c95e22125..4933bc4bd 100644
--- a/tests/auto/qdoc/generatedoutput/includefromexampledirs/excludes/parentinclude.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/excludes/parentinclude.qdoc
@@ -29,6 +29,7 @@
/*!
//! abstract-type
\qmltype AbstractParent
+ \inqmlmodule QDoc.Test
\ingroup qmltypes
\qmlabstract
\brief Abstract base QML type.
@@ -49,16 +50,3 @@
\brief Do some abstract parenting on \a child.
//! rear-qmlmethod
*/
-
-/*!
- \qmltype Child
- \ingroup qmltypes
- \inherits AbstractParent
- \brief A Child inheriting its parent.
-*/
-
-/*!
- \qmlbasictype int
- \ingroup qmltypes
- \brief An integer basic type.
-*/
diff --git a/tests/auto/qdoc/generatedoutput/includefromexampledirs/includefromexampledirs.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/includefromexampledirs.qdocconf
index 05683c80b..d64985942 100644
--- a/tests/auto/qdoc/generatedoutput/includefromexampledirs/includefromexampledirs.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/includefromexampledirs.qdocconf
@@ -1,11 +1,12 @@
-include(../testqml.qdocconf)
+include(../configs/testqml.qdocconf)
-includepaths += ..
sourcedirs += src
excludedirs += excludes \
../qml/componentset
+excludefiles += ../qml/parent.qdoc
+
exampledirs += excludes
HTML.nosubdirs = true
diff --git a/tests/auto/qdoc/generatedoutput/includefromexampledirs/src/includefromparent.qdoc b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/src/includefromparent.qdoc
index 7b4c00b76..a9a526c64 100644
--- a/tests/auto/qdoc/generatedoutput/includefromexampledirs/src/includefromparent.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/src/includefromparent.qdoc
@@ -49,3 +49,18 @@
\include parent.qdocinc
*/
+
+/*!
+ \qmltype Child
+ \inqmlmodule QDoc.Test
+ \ingroup qmltypes
+ \inherits AbstractParent
+ \brief A Child inheriting its parent.
+*/
+
+/*!
+ \qmlbasictype int
+ \inqmlmodule QDoc.Test
+ \ingroup qmltypes
+ \brief An integer basic type.
+*/
diff --git a/tests/auto/qdoc/generatedoutput/includefromexampledirs/src/parent.qdocinc b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/src/parent.qdocinc
index 307c39dbd..307c39dbd 100644
--- a/tests/auto/qdoc/generatedoutput/includefromexampledirs/src/parent.qdocinc
+++ b/tests/auto/qdoc/generatedoutput/testdata/includefromexampledirs/src/parent.qdocinc
diff --git a/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc b/tests/auto/qdoc/generatedoutput/testdata/outputfromqdocfiles/qdoctests-outputfromqdocfiles.qdoc
index e56c447c4..e56c447c4 100644
--- a/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/outputfromqdocfiles/qdoctests-outputfromqdocfiles.qdoc
diff --git a/tests/auto/qdoc/generatedoutput/qml/DocTest.qml b/tests/auto/qdoc/generatedoutput/testdata/qml/DocTest.qml
index 1ddafcfe4..1ddafcfe4 100644
--- a/tests/auto/qdoc/generatedoutput/qml/DocTest.qml
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/DocTest.qml
diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt
new file mode 100644
index 000000000..c6a5c654b
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required (VERSION 2.8.11)
+project (QDOCTEST)
diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc
new file mode 100644
index 000000000..13767e147
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example cmaketest
+ \title CMake Example Project
+*/
diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp
new file mode 100644
index 000000000..68d71eb71
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp
@@ -0,0 +1 @@
+void main(){}
diff --git a/tests/auto/qdoc/generatedoutput/qml/componentset/ProgressBar.qml b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/ProgressBar.qml
index 2a40cc488..2a40cc488 100644
--- a/tests/auto/qdoc/generatedoutput/qml/componentset/ProgressBar.qml
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/ProgressBar.qml
diff --git a/tests/auto/qdoc/generatedoutput/qml/componentset/Switch.qml b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/Switch.qml
index db9616b69..db9616b69 100644
--- a/tests/auto/qdoc/generatedoutput/qml/componentset/Switch.qml
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/Switch.qml
diff --git a/tests/auto/qdoc/generatedoutput/qml/componentset/TabWidget.qml b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/TabWidget.qml
index 07fd40db9..07fd40db9 100644
--- a/tests/auto/qdoc/generatedoutput/qml/componentset/TabWidget.qml
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/TabWidget.qml
diff --git a/tests/auto/qdoc/generatedoutput/qml/componentset/componentset.pro b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/componentset.pro
index 5b44737c2..5b44737c2 100644
--- a/tests/auto/qdoc/generatedoutput/qml/componentset/componentset.pro
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/componentset.pro
diff --git a/tests/auto/qdoc/generatedoutput/qml/componentset/examples.qdoc b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/examples.qdoc
index 2f56c221c..bce12a4ae 100644
--- a/tests/auto/qdoc/generatedoutput/qml/componentset/examples.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/examples.qdoc
@@ -30,6 +30,8 @@
\title QML Documentation Example
\brief Example for documenting QML types.
+ \testnoautolist
+
\meta tag {test,sample}
\meta installpath tutorials
@@ -40,18 +42,18 @@
and their public interfaces. The types are grouped into a module, the
\l{UI Components} module.
- The \l{componentset/uicomponents.qdoc.sample}{uicomponents.qdoc} file generates
+ The uicomponents.qdoc file generates
the overview page for the \l{UI Components} module page.
The generated documentation is available in the \l{UI Components} module.
\section1 QML Class
- The QML types use the \l{qmltype-command}{\\qmltype} to document the
- type. In addition, they have the \l{inmodule-command}{\\inmodule}
+ The QML types use the \\qmltype to document the
+ type. In addition, they have the \\inmodule
command in order for QDoc to associate them to the \c UIComponents module.
- QDoc uses the \l{brief-command}{\\brief} command to place a basic
+ QDoc uses the \\brief command to place a basic
description when listing the types.
\section1 Properties, Signals, Handlers, and Methods
@@ -62,7 +64,7 @@
documentation above the property, method, or signal.
To document the type of a \e {property alias}, you must use the
- \l{qmlproperty-command}{\\qmlproperty} command to specify the data type.
+ \\qmlproperty command to specify the data type.
\code
\qmlproperty int anAliasedProperty
@@ -72,17 +74,17 @@
\section2 Internal Documentation
You may declare that a documentation is for internal use by placing the
- \l{internal-command}{\\internal} command after the beginning QDoc comment
+ \\internal command after the beginning QDoc comment
\begincomment. QDoc will prevent the internal documentation from appearing
in the public API.
If you wish to omit certain parts of the documentation, you may use the
- \l{omit-command}{\\omit} and \l{omit-command}{\\endomit} command.
+ \\omit and \\endomit command.
\section1 QML Types with C++ Implementation
This example only demonstrates the documentation for types in QML
- files, but the regular \l{qml-documentation}{QML commands} may be placed
+ files, but the regular QML commands may be placed
inside C++ classes to define the public API of the QML type.
*/
@@ -95,7 +97,7 @@
This is a listing of a list of UI components implemented by QML types. These
files are available for general import and they are based on the
- \l{Qt Quick Examples and Tutorials}{Qt Quick Code Samples}.
+ Qt Quick Code Samples.
This module is part of the \l{componentset}{UIComponents} example.
*/
diff --git a/tests/auto/qdoc/generatedoutput/qml/componentset/uicomponents.qdoc.sample b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/uicomponents.qdoc.sample
index 0c6d187ed..0c6d187ed 100644
--- a/tests/auto/qdoc/generatedoutput/qml/componentset/uicomponents.qdoc.sample
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/uicomponents.qdoc.sample
diff --git a/tests/auto/qdoc/generatedoutput/qml/parent.qdoc b/tests/auto/qdoc/generatedoutput/testdata/qml/parent.qdoc
index e0bed66c0..fed18491c 100644
--- a/tests/auto/qdoc/generatedoutput/qml/parent.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/parent.qdoc
@@ -57,3 +57,8 @@
\brief An integer basic type.
*/
+
+/*!
+ \qmlmethod int int::abs()
+ Returns the absolute value of this integer.
+*/
diff --git a/tests/auto/qdoc/generatedoutput/qml/type.cpp b/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp
index bf04bdb43..2e967c4a2 100644
--- a/tests/auto/qdoc/generatedoutput/qml/type.cpp
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp
@@ -31,6 +31,8 @@
/*!
\qmlmodule QDoc.Test \QDocTestVer
\brief QML Types for the Test module.
+
+ \testnoautolist
*/
/*!
diff --git a/tests/auto/qdoc/generatedoutput/qmlpropertygroups/parent.qdoc b/tests/auto/qdoc/generatedoutput/testdata/qmlpropertygroups/parent.qdoc
index c7002e96b..c7002e96b 100644
--- a/tests/auto/qdoc/generatedoutput/qmlpropertygroups/parent.qdoc
+++ b/tests/auto/qdoc/generatedoutput/testdata/qmlpropertygroups/parent.qdoc
diff --git a/tests/auto/qdoc/generatedoutput/qmlpropertygroups/qmlpropertygroups.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/qmlpropertygroups/qmlpropertygroups.qdocconf
index 6ed830c82..62952b429 100644
--- a/tests/auto/qdoc/generatedoutput/qmlpropertygroups/qmlpropertygroups.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/qmlpropertygroups/qmlpropertygroups.qdocconf
@@ -1,6 +1,5 @@
-include(../testqml.qdocconf)
+include(../configs/testqml.qdocconf)
-includepaths += ..
sourcedirs += .
HTML.nosubdirs = true
diff --git a/tests/auto/qdoc/generatedoutput/testdata/scopedenum/scopedenum.qdoc b/tests/auto/qdoc/generatedoutput/testdata/scopedenum/scopedenum.qdoc
new file mode 100644
index 000000000..4262c1ce6
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/scopedenum/scopedenum.qdoc
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \enum TestQDoc::Test::ScopedEnum
+
+ \value This Something
+ \value That Something else
+ \value All Everything
+ \omitvalue OmittedValue
+*/
diff --git a/tests/auto/qdoc/generatedoutput/testdata/singleexec/singleexec.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/singleexec/singleexec.qdocconf
new file mode 100644
index 000000000..037cfc74a
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/singleexec/singleexec.qdocconf
@@ -0,0 +1,2 @@
+../configs/testcpp_singleexec.qdocconf
+../crossmodule/crossmodule_singleexec.qdocconf
diff --git a/tests/auto/qdoc/generatedoutput/testdata/testcpp/TestCPP b/tests/auto/qdoc/generatedoutput/testdata/testcpp/TestCPP
new file mode 100644
index 000000000..4ed786108
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/testcpp/TestCPP
@@ -0,0 +1,5 @@
+#include "testcpp.h"
+
+#ifdef test_template
+# include "testtemplate.h"
+#endif
diff --git a/tests/auto/qdoc/generatedoutput/testcpp.cpp b/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.cpp
index f33a6a83c..8422494ac 100644
--- a/tests/auto/qdoc/generatedoutput/testcpp.cpp
+++ b/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.cpp
@@ -34,6 +34,8 @@ namespace TestQDoc {
\qtvariable testcpp
\title QDoc Test C++ Classes
\brief A test module page.
+
+ \testnoautolist
*/
/*!
@@ -50,6 +52,11 @@ namespace TestQDoc {
\class TestQDoc::Test
\inmodule TestCPP
\brief A class in a namespace.
+
+\if defined(test_ignoresince)
+ //! omitted by ignoresince
+ \since 1.1
+\endif
*/
/*!
@@ -61,6 +68,10 @@ namespace TestQDoc {
/*!
\macro QDOCTEST_MACRO
\relates TestQDoc
+\if defined(test_ignoresince)
+ //! omitted by ignoresince.Test
+ \since Test 0.9
+\endif
*/
/*!
@@ -91,9 +102,7 @@ void Test::obsoleteMember()
}
/*!
- \obsolete
-
- Use obsoleteMember() instead.
+ \obsolete Use obsoleteMember() instead.
*/
void Test::anotherObsoleteMember()
{
@@ -102,6 +111,9 @@ void Test::anotherObsoleteMember()
/*!
Function that takes a parameter \a i and \a b.
+\if defined(test_ignoresince)
+ \since 2.0
+\endif
*/
void Test::someFunctionDefaultArg(int i, bool b = false)
{
@@ -111,6 +123,9 @@ void Test::someFunctionDefaultArg(int i, bool b = false)
/*!
Function that takes a parameter \a v.
Also returns the value of \a v.
+\if defined(test_ignoresince)
+ \since Test 1.0
+\endif
*/
int Test::someFunction(int v)
{
@@ -141,10 +156,21 @@ void TestDerived::virtualFun()
/*!
\fn TestQDoc::Test::overload()
- \fn TestQDoc::Test::overload(bool b)
+ \fn Test::overload(bool b)
+ \since Test 1.2
+ //! The second overload should match even without the fully qualified path
Overloads that share a documentation comment, optionally taking
a parameter \a b.
*/
+/*!
+\if defined(test_template)
+ \fn template <typename T1, typename T2> void TestQDoc::Test::funcTemplate(T1 a, T2 b)
+ \brief Function template with two parameters, \a a and \a b.
+\else
+ \nothing
+\endif
+*/
+
} // namespace TestQDoc
diff --git a/tests/auto/qdoc/generatedoutput/testcpp.h b/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.h
index c34ada99b..4ae33a404 100644
--- a/tests/auto/qdoc/generatedoutput/testcpp.h
+++ b/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.h
@@ -33,6 +33,14 @@ namespace TestQDoc {
class Test {
public:
+#ifdef test_scopedenum
+ enum class ScopedEnum : unsigned char {
+ This = 0x01,
+ That = 0x02,
+ All = This | That,
+ OmittedValue = 99
+ };
+#endif
int someFunction(int v);
void someFunctionDefaultArg(int i, bool b);
void obsoleteMember();
@@ -44,6 +52,11 @@ public:
protected:
void overload() {}
void overload(bool b) { if (!b) return; }
+#ifdef test_template
+ template <typename T1, typename T2> void funcTemplate(T1 a, T2 b) {
+ a = b;
+ }
+#endif
};
class TestDerived : public Test {
diff --git a/tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.cpp b/tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.cpp
new file mode 100644
index 000000000..e9755769f
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "testtemplate.h"
+
+/*!
+ \class Foo
+ \inmodule TestCPP
+ \brief Class template.
+*/
+
+/*!
+ \class Bar
+ \inmodule TestCPP
+ \brief Another class template.
+*/
+
+/*!
+ \class Baz
+ \inmodule TestCPP
+ \brief Class template template.
+*/
diff --git a/tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.h b/tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.h
new file mode 100644
index 000000000..d60ab0da4
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/testtemplate/testtemplate.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+
+template <typename T>
+class Foo {
+public:
+ Foo() {}
+private:
+ T t;
+};
+
+template <typename T, typename D>
+class Bar {
+public:
+ Bar() {}
+private:
+ T t;
+ D d;
+};
+
+template<template<typename> class X, typename Y>
+struct Baz
+{
+ X<Y> z;
+ Baz() : z() {}
+};
diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
index 3fa2c954f..b3c69af71 100644
--- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
+++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include <QProcess>
#include <QTemporaryDir>
+#include <QDirIterator>
#include <QtTest>
class tst_generatedOutput : public QObject
@@ -37,31 +38,46 @@ private slots:
void initTestCase();
void init();
+ // HTML generator
void htmlFromQDocFile();
void htmlFromCpp();
void htmlFromQml();
void htmlFromCppBug80259();
+ // WebXML generator
void webXmlFromQDocFile();
void webXmlFromCpp();
void webXmlFromQml();
void webXmlFromCppBug80259();
- void examplesManifestXml();
+ // DocBook generator
+ void docBookFromQDocFile();
+ void docBookFromCpp();
+ void docBookFromQml();
+
+ // Output format independent tests
+ void examplesManifestXmlAndQhp();
+ void ignoresinceVariable();
+ void templateParameters();
+ void scopedEnum();
+ void dontDocument();
void inheritedQmlPropertyGroups();
+ void crossModuleLinking();
void includeFromExampleDirs();
+ void singleExec();
+ void preparePhase();
+ void generatePhase();
+ void noAutoList();
private:
QScopedPointer<QTemporaryDir> m_outputDir;
QString m_qdoc;
- void removeFullPathStrings(QString& str);
void runQDocProcess(const QStringList &arguments);
void compareLineByLine(const QStringList &expectedFiles);
- void testAndCompare(const char *input,
- const char *outNames,
- const char *extraParams = nullptr,
+ void testAndCompare(const char *input, const char *outNames, const char *extraParams = nullptr,
const char *outputPathPrefix = nullptr);
+ void copyIndexFiles();
};
void tst_generatedOutput::initTestCase()
@@ -77,7 +93,7 @@ void tst_generatedOutput::init()
m_outputDir.reset(new QTemporaryDir());
if (!m_outputDir->isValid()) {
const QString errorMessage =
- "Couldn't create temporary directory: " + m_outputDir->errorString();
+ "Couldn't create temporary directory: " + m_outputDir->errorString();
QFAIL(qPrintable(errorMessage));
}
}
@@ -105,13 +121,6 @@ void tst_generatedOutput::runQDocProcess(const QStringList &arguments)
QFAIL("Running QDoc failed. See output above.");
}
-void tst_generatedOutput::removeFullPathStrings(QString &str)
-{
- QRegularExpression re("(location|path|filepath)=\"[^\"]+\"");
- QRegularExpressionMatch match = re.match(str);
- str.replace(re, match.captured(1) + "=\"REMOVED_BY_TEST\"");
-}
-
void tst_generatedOutput::compareLineByLine(const QStringList &expectedFiles)
{
for (const auto &file : expectedFiles) {
@@ -135,20 +144,16 @@ void tst_generatedOutput::compareLineByLine(const QStringList &expectedFiles)
QString prefix = file + delim + QString::number(lineNumber) + delim;
QString expectedLine = prefix + expectedIn.readLine();
QString actualLine = prefix + actualIn.readLine();
- removeFullPathStrings(actualLine);
- removeFullPathStrings(expectedLine);
QCOMPARE(actualLine, expectedLine);
}
}
}
-void tst_generatedOutput::testAndCompare(const char *input,
- const char *outNames,
- const char *extraParams,
- const char *outputPathPrefix)
+void tst_generatedOutput::testAndCompare(const char *input, const char *outNames,
+ const char *extraParams, const char *outputPathPrefix)
{
- QStringList args{ "-outputdir", m_outputDir->path() + "/" + outputPathPrefix,
- QFINDTESTDATA(input) };
+ QStringList args { "-outputdir", m_outputDir->path() + "/" + outputPathPrefix,
+ QFINDTESTDATA(input) };
if (extraParams)
args << QString(QLatin1String(extraParams)).split(QChar(' '));
@@ -165,17 +170,30 @@ void tst_generatedOutput::testAndCompare(const char *input,
compareLineByLine(expectedOuts);
}
+// Copy <project>.index to <project>/<project>.index in the outputdir
+void tst_generatedOutput::copyIndexFiles()
+{
+ QDirIterator it(m_outputDir->path(), QStringList("*.index"), QDir::Files, QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ QFileInfo fileInfo(it.next());
+ QDir indexDir(m_outputDir->path());
+ QVERIFY(indexDir.mkpath(fileInfo.baseName()));
+ QVERIFY(indexDir.cd(fileInfo.baseName()));
+ if (!indexDir.exists(fileInfo.fileName()))
+ QVERIFY(QFile::copy(fileInfo.filePath(), indexDir.filePath(fileInfo.fileName())));
+ }
+}
void tst_generatedOutput::htmlFromQDocFile()
{
- testAndCompare("test.qdocconf",
+ testAndCompare("testdata/configs/test.qdocconf",
"qdoctests-qdocfileoutput.html "
"qdoctests-qdocfileoutput-linking.html");
}
void tst_generatedOutput::htmlFromCpp()
{
- testAndCompare("testcpp.qdocconf",
+ testAndCompare("testdata/configs/testcpp.qdocconf",
"testcpp-module.html "
"testqdoc-test.html "
"testqdoc-test-members.html "
@@ -184,8 +202,9 @@ void tst_generatedOutput::htmlFromCpp()
void tst_generatedOutput::htmlFromQml()
{
- testAndCompare("testqml.qdocconf",
+ testAndCompare("testdata/configs/testqml.qdocconf",
"test-componentset-example.html "
+ "test-cmaketest-example.html "
"uicomponents-qmlmodule.html "
"qdoc-test-qmlmodule.html "
"qml-qdoc-test-abstractparent.html "
@@ -201,7 +220,7 @@ void tst_generatedOutput::htmlFromQml()
void tst_generatedOutput::htmlFromCppBug80259()
{
- testAndCompare("bug80259/testmodule.qdocconf",
+ testAndCompare("testdata/bug80259/testmodule.qdocconf",
"first.html "
"second.html "
"third.html "
@@ -210,55 +229,168 @@ void tst_generatedOutput::htmlFromCppBug80259()
void tst_generatedOutput::webXmlFromQDocFile()
{
- testAndCompare("webxml_test.qdocconf",
+ testAndCompare("testdata/configs/webxml_test.qdocconf",
"html/qdoctests-qdocfileoutput.webxml "
"html/qdoctests-qdocfileoutput-linking.webxml");
}
void tst_generatedOutput::webXmlFromCpp()
{
- testAndCompare("webxml_testcpp.qdocconf",
+ testAndCompare("testdata/configs/webxml_testcpp.qdocconf",
"html/testcpp-module.webxml "
"html/testqdoc-test.webxml "
"html/testqdoc-testderived.webxml");
}
-
void tst_generatedOutput::webXmlFromQml()
{
- testAndCompare("webxml_testqml.qdocconf",
+ testAndCompare("testdata/configs/webxml_testqml.qdocconf",
"html/test-componentset-example.webxml "
"html/uicomponents-qmlmodule.webxml");
}
void tst_generatedOutput::webXmlFromCppBug80259()
{
- testAndCompare("bug80259/webxml_testmodule.qdocconf",
+ testAndCompare("testdata/bug80259/webxml_testmodule.qdocconf",
"html/first.webxml "
"html/second.webxml "
"html/third.webxml "
"html/index.webxml");
}
-void tst_generatedOutput::examplesManifestXml()
+void tst_generatedOutput::docBookFromQDocFile()
+{
+ testAndCompare("testdata/configs/docbook_test.qdocconf",
+ "docbook/qdoctests-qdocfileoutput.xml "
+ "docbook/qdoctests-qdocfileoutput-linking.xml");
+}
+
+void tst_generatedOutput::docBookFromCpp()
+{
+ testAndCompare("testdata/configs/docbook_testcpp.qdocconf",
+ "docbook/testcpp-module.xml "
+ "docbook/testqdoc-test.xml "
+ "docbook/testqdoc-testderived.xml "
+ "docbook/testqdoc.xml");
+}
+
+void tst_generatedOutput::docBookFromQml()
+{
+ testAndCompare("testdata/configs/docbook_testqml.qdocconf",
+ "docbook/test-componentset-example.xml "
+ "docbook/uicomponents-qmlmodule.xml "
+ "docbook/qdoc-test-qmlmodule.xml "
+ "docbook/qml-qdoc-test-abstractparent.xml "
+ "docbook/qml-qdoc-test-child.xml "
+ "docbook/qml-qdoc-test-doctest.xml "
+ "docbook/qml-qdoc-test-type.xml "
+ "docbook/qml-uicomponents-progressbar.xml "
+ "docbook/qml-uicomponents-switch.xml "
+ "docbook/qml-uicomponents-tabwidget.xml "
+ "docbook/qml-int.xml");
+}
+
+void tst_generatedOutput::examplesManifestXmlAndQhp()
+{
+ testAndCompare("testdata/configs/examples-qhp.qdocconf",
+ "examples-manifest.xml "
+ "test.qhp");
+}
+
+void tst_generatedOutput::ignoresinceVariable()
+{
+ testAndCompare("testdata/configs/ignoresince.qdocconf",
+ "ignoresince/testqdoc.html "
+ "ignoresince/testqdoc-test.html");
+}
+
+void tst_generatedOutput::templateParameters()
+{
+ testAndCompare("testdata/configs/testtemplate.qdocconf",
+ "template/testqdoc-test.html "
+ "template/foo.html "
+ "template/bar.html "
+ "template/baz.html");
+}
+
+void tst_generatedOutput::scopedEnum()
{
- testAndCompare("examples-qhp.qdocconf",
- "examples-manifest.xml");
+ testAndCompare("testdata/configs/scopedenum.qdocconf", "scopedenum/testqdoc-test.html");
+}
+
+void tst_generatedOutput::dontDocument()
+{
+ testAndCompare("testdata/dontdocument/dontdocument.qdocconf",
+ "dontdocument/classes.html "
+ "dontdocument/seenclass.html");
}
void tst_generatedOutput::inheritedQmlPropertyGroups()
{
- testAndCompare("qmlpropertygroups/qmlpropertygroups.qdocconf",
+ testAndCompare("testdata/qmlpropertygroups/qmlpropertygroups.qdocconf",
"qmlpropertygroups/qml-qdoc-test-anotherchild-members.html");
}
+void tst_generatedOutput::crossModuleLinking()
+{
+ htmlFromCpp();
+ copyIndexFiles();
+ QString indexDir = QLatin1String("-indexdir ") + m_outputDir->path();
+ testAndCompare("testdata/crossmodule/crossmodule.qdocconf",
+ "crossmodule/testtype.html "
+ "crossmodule/testtype-members.html",
+ indexDir.toLatin1().data());
+}
+
void tst_generatedOutput::includeFromExampleDirs()
{
- testAndCompare("includefromexampledirs/includefromexampledirs.qdocconf",
+ testAndCompare("testdata/includefromexampledirs/includefromexampledirs.qdocconf",
"includefromexampledirs/index.html "
"includefromexampledirs/qml-qdoc-test-abstractparent.html "
"includefromexampledirs/qml-qdoc-test-abstractparent-members.html");
}
+
+void tst_generatedOutput::singleExec()
+{
+ // Build both testcpp and crossmodule projects in single-exec mode
+ testAndCompare("testdata/singleexec/singleexec.qdocconf",
+ "testcpp-module.html "
+ "testqdoc-test.html "
+ "testqdoc-test-members.html "
+ "testqdoc.html "
+ "crossmodule/testtype.html "
+ "crossmodule/testtype-members.html",
+ "-single-exec");
+}
+
+void tst_generatedOutput::preparePhase()
+{
+ testAndCompare("testdata/configs/testcpp.qdocconf",
+ "testcpp.index",
+ "-prepare");
+}
+
+void tst_generatedOutput::generatePhase()
+{
+ testAndCompare("testdata/configs/testcpp.qdocconf",
+ "testcpp-module.html "
+ "testqdoc-test.html "
+ "testqdoc-test-members.html "
+ "testqdoc.html",
+ "-generate");
+}
+
+void tst_generatedOutput::noAutoList()
+{
+ testAndCompare("testdata/configs/noautolist.qdocconf",
+ "noautolist/testcpp-module.html "
+ "noautolist/test-componentset-example.html "
+ "noautolist/qdoc-test-qmlmodule.html "
+ "noautolist-docbook/testcpp-module.xml "
+ "noautolist-docbook/test-componentset-example.xml "
+ "noautolist-docbook/qdoc-test-qmlmodule.xml");
+}
+
QTEST_APPLESS_MAIN(tst_generatedOutput)
#include "tst_generatedoutput.moc"
diff --git a/tests/auto/qdoc/qdoc.pro b/tests/auto/qdoc/qdoc.pro
index 97117dc6f..c7af516ae 100644
--- a/tests/auto/qdoc/qdoc.pro
+++ b/tests/auto/qdoc/qdoc.pro
@@ -1,4 +1,6 @@
TEMPLATE = subdirs
SUBDIRS = \
- generatedoutput
+ config \
+ generatedoutput \
+ utilities
diff --git a/tests/auto/qdoc/utilities/tst_utilities.cpp b/tests/auto/qdoc/utilities/tst_utilities.cpp
new file mode 100644
index 000000000..0f63b1daf
--- /dev/null
+++ b/tests/auto/qdoc/utilities/tst_utilities.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "utilities.h"
+
+#include <QtTest/QtTest>
+
+QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQdoc, "qt.test")
+QT_END_NAMESPACE
+
+class tst_Utilities : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void loggingCategoryName();
+ void loggingCategoryDefaults();
+ void startDebugging();
+ void stopDebugging();
+ void debugging();
+};
+
+void tst_Utilities::loggingCategoryName()
+{
+ const QString expected = "qt.test";
+ QCOMPARE(lcQdoc().categoryName(), expected);
+}
+
+void tst_Utilities::loggingCategoryDefaults()
+{
+ QVERIFY(lcQdoc().isCriticalEnabled());
+ QVERIFY(lcQdoc().isWarningEnabled());
+ QVERIFY(!lcQdoc().isDebugEnabled());
+ QVERIFY(lcQdoc().isInfoEnabled());
+}
+
+void tst_Utilities::startDebugging()
+{
+ QVERIFY(!lcQdoc().isDebugEnabled());
+ Utilities::startDebugging("test");
+ QVERIFY(lcQdoc().isDebugEnabled());
+}
+
+void tst_Utilities::stopDebugging()
+{
+ Utilities::startDebugging("test");
+ QVERIFY(lcQdoc().isDebugEnabled());
+ Utilities::stopDebugging("test");
+ QVERIFY(!lcQdoc().isDebugEnabled());
+}
+
+void tst_Utilities::debugging()
+{
+ QVERIFY(!lcQdoc().isDebugEnabled());
+ QVERIFY(!Utilities::debugging());
+ Utilities::startDebugging("test");
+ QVERIFY(lcQdoc().isDebugEnabled());
+ QVERIFY(Utilities::debugging());
+}
+
+QTEST_APPLESS_MAIN(tst_Utilities)
+
+#include "tst_utilities.moc"
diff --git a/tests/auto/qdoc/utilities/utilities.pro b/tests/auto/qdoc/utilities/utilities.pro
new file mode 100644
index 000000000..57489f2b1
--- /dev/null
+++ b/tests/auto/qdoc/utilities/utilities.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+QT = core testlib
+TARGET = tst_utilities
+INCLUDEPATH += $$PWD/../../../../src/qdoc
+
+HEADERS += \
+ $$PWD/../../../../src/qdoc/loggingcategory.h \
+ $$PWD/../../../../src/qdoc/utilities.h
+
+SOURCES += \
+ tst_utilities.cpp \
+ $$PWD/../../../../src/qdoc/utilities.cpp
diff --git a/tests/auto/windeployqt/tst_windeployqt.cpp b/tests/auto/windeployqt/tst_windeployqt.cpp
index f20e59180..04aece287 100644
--- a/tests/auto/windeployqt/tst_windeployqt.cpp
+++ b/tests/auto/windeployqt/tst_windeployqt.cpp
@@ -152,7 +152,7 @@ void tst_windeployqt::deploy()
const QChar pathSeparator(QLatin1Char(';')); // ### fixme: Qt 5.6: QDir::listSeparator()
const QString origPath = env.value(pathKey);
QString newPath;
- const QStringList pathElements = origPath.split(pathSeparator, QString::SkipEmptyParts);
+ const QStringList pathElements = origPath.split(pathSeparator, Qt::SkipEmptyParts);
for (const QString &pathElement : pathElements) {
if (pathElement.compare(qtBinDir, Qt::CaseInsensitive)
&& !pathElement.contains(QLatin1String("\\lib"), Qt::CaseInsensitive)) {