diff options
108 files changed, 1458 insertions, 465 deletions
diff --git a/configure.json b/configure.json index 190c23708..2ff580062 100644 --- a/configure.json +++ b/configure.json @@ -1,5 +1,165 @@ { - "subconfigs": [ - "src/global" + "files": { + "publicHeader": "src/global/qttools-config.h", + "privateHeader": "src/global/qttools-config_p.h", + "publicPro": "src/global/qttools-config.pri", + "privatePro": "src/global/qttools-config.pri" + }, + "module": "tools", + "tests": { + "libclang": { + "label": "libclang", + "test": "libclang", + "type": "libclang" + } + }, + "features": { + "assistant": { + "label": "Qt Assistant", + "purpose": "Qt Assistant is a tool for viewing on-line documentation in Qt help file format.", + "output": [ "privateFeature" ] + }, + "clang": { + "label": "QDoc", + "condition": "tests.libclang", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "CLANG_LIBS", "value": "tests.libclang.libs" }, + { "type": "varAssign", "name": "CLANG_INCLUDEPATH", "value": "tests.libclang.includepath" }, + { "type": "varAssign", "name": "CLANG_LIBDIR", "value": "tests.libclang.libdir" }, + { "type": "varAssign", "name": "CLANG_DEFINES", "value": "tests.libclang.defines" }, + { "type": "varAssign", "name": "CLANG_VERSION", "value": "tests.libclang.version" }, + { "type": "varAssign", "name": "CLANG_MAJOR_VERSION", "value": "tests.libclang.major_version" }, + { "type": "varAssign", "name": "CLANG_MINOR_VERSION", "value": "tests.libclang.minor_version" }, + { "type": "varAssign", "name": "CLANG_PATCH_VERSION", "value": "tests.libclang.patch_version" } + ] + }, + "clangcpp": { + "label": "Clang-based lupdate parser", + "condition": "features.clang && tests.libclang.has_clangcpp", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "CLANGCPP_LIBS", "value": "tests.libclang.clangcpp_libs" } + ] + }, + "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" ] + } + }, + "report": [ + { + "type": "warning", + "condition": "!features.clang", + "message": "QDoc will not be compiled, probably because libclang could not be located. This means that you cannot build the Qt documentation.\n +Either ensure that llvm-config is in your PATH environment variable, or set LLVM_INSTALL_DIR to the location of your llvm installation. +On Linux systems, you may be able to install libclang by installing the libclang-dev or libclang-devel package, depending on your distribution. +On macOS, you can use Homebrew's llvm package. +On Windows, you must set LLVM_INSTALL_DIR to the installation path." + }, + { + "type": "warning", + "condition": "!features.clangcpp", + "message": "Clang-based lupdate parser will not be available. LLVM and Clang C++ libraries have not been found." + } + ], + "summary": [ + { + "section": "Qt Tools", + "entries": [ + "assistant", + "clang", + "clangcpp", + "designer", + "distancefieldgenerator", + "kmap2qmap", + "linguist", + "macdeployqt", + "makeqpf", + "pixeltool", + "qdbus", + "qev", + "qtattributionsscanner", + "qtdiag", + "qtpaths", + "qtplugininfo", + "windeployqt", + "winrtrunner" + ] + } ] } diff --git a/src/global/configure.pri b/configure.pri index 2d0601245..2d0601245 100644 --- a/src/global/configure.pri +++ b/configure.pri diff --git a/src/assistant/assistant.pro b/src/assistant/assistant.pro index 1529167c0..f3395abb0 100644 --- a/src/assistant/assistant.pro +++ b/src/assistant/assistant.pro @@ -1,4 +1,9 @@ requires(qtHaveModule(sql)) + +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(assistant)) + TEMPLATE = subdirs SUBDIRS += \ diff --git a/src/assistant/assistant/bookmarkdialog.cpp b/src/assistant/assistant/bookmarkdialog.cpp index 1ffe6dc84..cb775d30a 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, const QString &>::of(&QComboBox::currentIndexChanged), + connect(ui.bookmarkFolders, &QComboBox::currentIndexChanged, this, QOverload<int>::of(&BookmarkDialog::currentIndexChanged)); bookmarkTreeModel = new BookmarkTreeModel(this); 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/helpenginewrapper.cpp b/src/assistant/assistant/helpenginewrapper.cpp index d69138ff8..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 diff --git a/src/assistant/assistant/helpenginewrapper.h b/src/assistant/assistant/helpenginewrapper.h index 81d8ffa1f..df2ec8a73 100644 --- a/src/assistant/assistant/helpenginewrapper.h +++ b/src/assistant/assistant/helpenginewrapper.h @@ -47,6 +47,7 @@ class QHelpIndexWidget; class QHelpSearchEngine; class QHelpFilterEngine; class QHelpEngineCore; +struct QHelpLink; enum { ShowHomePage = 0, @@ -80,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; 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 cd6487751..88e89ed69 100644 --- a/src/assistant/assistant/main.cpp +++ b/src/assistant/assistant/main.cpp @@ -373,7 +373,6 @@ 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) diff --git a/src/assistant/assistant/mainwindow.cpp b/src/assistant/assistant/mainwindow.cpp index b3c0240ba..b651d43b5 100644 --- a/src/assistant/assistant/mainwindow.cpp +++ b/src/assistant/assistant/mainwindow.cpp @@ -682,7 +682,7 @@ void MainWindow::setupActions() // 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 +822,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/preferencesdialog.cpp b/src/assistant/assistant/preferencesdialog.cpp index 5dd24a102..ebd2a96e8 100644 --- a/src/assistant/assistant/preferencesdialog.cpp +++ b/src/assistant/assistant/preferencesdialog.cpp @@ -200,13 +200,13 @@ void PreferencesDialog::updateFontSettingsPage() const QList<QComboBox*> &appCombos = m_appFontPanel->findChildren<QComboBox*>(); for (QComboBox* box : appCombos) { - connect(box, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), + connect(box, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PreferencesDialog::appFontSettingChanged); } const QList<QComboBox*> &browserCombos = m_browserFontPanel->findChildren<QComboBox*>(); for (QComboBox* box : browserCombos) { - connect(box, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), + connect(box, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PreferencesDialog::browserFontSettingChanged); } } 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/help.pro b/src/assistant/help/help.pro index ff7a81374..800c4a38d 100644 --- a/src/assistant/help/help.pro +++ b/src/assistant/help/help.pro @@ -22,6 +22,7 @@ SOURCES += \ qhelpdbreader.cpp \ qhelpcontentwidget.cpp \ qhelpindexwidget.cpp \ + qhelplink.cpp \ qhelpcollectionhandler.cpp \ qhelpsearchengine.cpp \ qhelpsearchquerywidget.cpp \ @@ -46,6 +47,7 @@ HEADERS += \ qhelpdbreader_p.h \ qhelpcontentwidget.h \ qhelpindexwidget.h \ + qhelplink.h \ qhelpcollectionhandler_p.h \ qhelpsearchengine.h \ qhelpsearchquerywidget.h \ diff --git a/src/assistant/help/qhelpcollectionhandler.cpp b/src/assistant/help/qhelpcollectionhandler.cpp index 427521a9a..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> @@ -2375,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 " @@ -2402,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); @@ -2415,13 +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(); - 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())); + 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 5c0170d8c..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,6 +154,13 @@ 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; @@ -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 c9fbde232..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 @@ -620,33 +623,53 @@ QByteArray QHelpEngineCore::fileData(const QUrl &url) const */ QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id) const { - return linksForIdentifier(id, d->usesFilterEngine - ? d->filterEngine->activeFilter() - : d->currentFilter); + if (!d->setup()) + return QMap<QString, QUrl>(); + + if (d->usesFilterEngine) + return d->collectionHandler->linksForIdentifier(id, d->filterEngine->activeFilter()); + + // obsolete + return d->collectionHandler->linksForIdentifier(id, filterAttributes(d->currentFilter)); } +#endif /*! \since 5.15 - Returns a map of the documents found for the \a id, filtered by \a filterName. - The map contains the document titles and their URLs. The returned map contents depend on - the passed filter, and therefore only the identifiers registered for - this filter will be returned. If you want to get all results unfiltered, - pass empty string as \a filterName. + 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. */ -QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id, const QString &filterName) const +QList<QHelpLink> QHelpEngineCore::documentsForIdentifier(const QString &id) const { - if (!d->setup()) - return QMap<QString, QUrl>(); + return documentsForIdentifier(id, d->usesFilterEngine + ? d->filterEngine->activeFilter() + : d->currentFilter); +} - if (d->usesFilterEngine) - return d->collectionHandler->linksForIdentifier(id, filterName); +/*! + \since 5.15 - // obsolete - return d->collectionHandler->linksForIdentifier(id, filterAttributes(filterName)); + 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 @@ -654,33 +677,46 @@ QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id, const */ QMap<QString, QUrl> QHelpEngineCore::linksForKeyword(const QString &keyword) const { - return linksForKeyword(keyword, d->usesFilterEngine - ? d->filterEngine->activeFilter() - : d->currentFilter); + if (!d->setup()) + return QMap<QString, QUrl>(); + + 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 map of the documents found for the \a keyword, filtered by \a filterName. - The map contains the document titles and their URLs. The returned map 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. - + 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. */ -QMap<QString, QUrl> QHelpEngineCore::linksForKeyword(const QString &keyword, const QString &filterName) const +QList<QHelpLink> QHelpEngineCore::documentsForKeyword(const QString &keyword) const { - if (!d->setup()) - return QMap<QString, QUrl>(); + return documentsForKeyword(keyword, d->usesFilterEngine + ? d->filterEngine->activeFilter() + : d->currentFilter); +} - if (d->usesFilterEngine) - return d->collectionHandler->linksForKeyword(keyword, filterName); +/*! + \since 5.15 - // obsolete - return d->collectionHandler->linksForKeyword(keyword, filterAttributes(filterName)); -} + 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 cf0cf96c9..cc720a48d 100644 --- a/src/assistant/help/qhelpenginecore.h +++ b/src/assistant/help/qhelpenginecore.h @@ -51,13 +51,16 @@ QT_BEGIN_NAMESPACE class QHelpEngineCorePrivate; class QHelpFilterEngine; +struct QHelpLink; class QHELP_EXPORT QHelpEngineCore : public QObject { Q_OBJECT Q_PROPERTY(bool autoSaveFilter READ autoSaveFilter WRITE setAutoSaveFilter) Q_PROPERTY(QString collectionFile READ collectionFile WRITE setCollectionFile) +#if QT_DEPRECATED_SINCE(5, 15) Q_PROPERTY(QString currentFilter READ currentFilter WRITE setCurrentFilter) +#endif public: explicit QHelpEngineCore(const QString &collectionFile, QObject *parent = nullptr); @@ -102,10 +105,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; - QMap<QString, QUrl> linksForIdentifier(const QString &id, const QString &filterName) const; + QT_DEPRECATED_X("Use documentsForKeyword() instead") QMap<QString, QUrl> linksForKeyword(const QString &keyword) const; - QMap<QString, QUrl> linksForKeyword(const QString &keyword, const QString &filterName) 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/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/qhelpgenerator/qhelpgenerator.pro b/src/assistant/qhelpgenerator/qhelpgenerator.pro index dabd87ccc..bb22000c8 100644 --- a/src/assistant/qhelpgenerator/qhelpgenerator.pro +++ b/src/assistant/qhelpgenerator/qhelpgenerator.pro @@ -1,6 +1,7 @@ QT += network help-private QTPLUGIN.platforms = qminimal +QTPLUGIN.sqldrivers = qsqlite SOURCES += ../shared/collectionconfiguration.cpp \ helpgenerator.cpp \ diff --git a/src/designer/designer.pro b/src/designer/designer.pro index be734fb11..a4c2c27b8 100644 --- a/src/designer/designer.pro +++ b/src/designer/designer.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(designer)) + TEMPLATE = subdirs SUBDIRS = src diff --git a/src/designer/src/components/formeditor/dpi_chooser.cpp b/src/designer/src/components/formeditor/dpi_chooser.cpp index a254bf12a..5e2f9f605 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, const QString &>::of(&QComboBox::currentIndexChanged), + connect(m_predefinedCombo, QOverload<int>::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 062fc6e4f..85cc1f930 100644 --- a/src/designer/src/components/formeditor/embeddedoptionspage.cpp +++ b/src/designer/src/components/formeditor/embeddedoptionspage.cpp @@ -145,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, const QString &>::of(&QComboBox::currentIndexChanged), + EmbeddedOptionsControl::connect(m_profileCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), m_q, &EmbeddedOptionsControl::slotProfileIndexChanged); m_addButton->setIcon(createIconSet(QString::fromUtf8("plus.png"))); 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/qdesigner_appearanceoptions.cpp b/src/designer/src/designer/qdesigner_appearanceoptions.cpp index fbcfacc6e..66eb49c9f 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, const QString &>::of(&QComboBox::currentIndexChanged), + connect(m_ui->m_uiModeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QDesignerAppearanceOptionsWidget::slotUiModeComboChanged); m_ui->m_fontPanel->setCheckable(true); diff --git a/src/designer/src/lib/shared/formlayoutmenu.cpp b/src/designer/src/lib/shared/formlayoutmenu.cpp index 220c3805b..87e8561c3 100644 --- a/src/designer/src/lib/shared/formlayoutmenu.cpp +++ b/src/designer/src/lib/shared/formlayoutmenu.cpp @@ -155,7 +155,7 @@ FormLayoutRowDialog::FormLayoutRowDialog(QDesignerFormEditorInterface *core, m_ui.fieldClassComboBox->addItems(fieldWidgetClasses(core)); m_ui.fieldClassComboBox->setCurrentIndex(0); connect(m_ui.fieldClassComboBox, - QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), + QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FormLayoutRowDialog::fieldClassChanged); updateOkButton(); diff --git a/src/designer/src/lib/shared/newformwidget.cpp b/src/designer/src/lib/shared/newformwidget.cpp index 67e08c475..81812f2fb 100644 --- a/src/designer/src/lib/shared/newformwidget.cpp +++ b/src/designer/src/lib/shared/newformwidget.cpp @@ -179,7 +179,7 @@ NewFormWidget::NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parent m_deviceProfiles = settings.deviceProfiles(); m_ui->profileComboBox->addItem(tr("None")); connect(m_ui->profileComboBox, - QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), + &QComboBox::currentIndexChanged, this, &NewFormWidget::slotDeviceProfileIndexChanged); if (m_deviceProfiles.isEmpty()) { m_ui->profileComboBox->setEnabled(false); diff --git a/src/designer/src/lib/shared/previewconfigurationwidget.cpp b/src/designer/src/lib/shared/previewconfigurationwidget.cpp index 1f7649975..462d74005 100644 --- a/src/designer/src/lib/shared/previewconfigurationwidget.cpp +++ b/src/designer/src/lib/shared/previewconfigurationwidget.cpp @@ -317,7 +317,7 @@ PreviewConfigurationWidget::PreviewConfigurationWidget(QDesignerFormEditorInterf this, &PreviewConfigurationWidget::slotEditAppStyleSheet); connect(m_impl->skinRemoveButton(), &QAbstractButton::clicked, this, &PreviewConfigurationWidget::slotDeleteSkinEntry); - connect(m_impl->skinCombo(), QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), + connect(m_impl->skinCombo(), &QComboBox::currentIndexChanged, this, &PreviewConfigurationWidget::slotSkinChanged); m_impl->retrieveSettings(); diff --git a/src/distancefieldgenerator/distancefieldgenerator.pro b/src/distancefieldgenerator/distancefieldgenerator.pro index c37ca6888..e934716b8 100644 --- a/src/distancefieldgenerator/distancefieldgenerator.pro +++ b/src/distancefieldgenerator/distancefieldgenerator.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/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/global/configure.json b/src/global/configure.json deleted file mode 100644 index 00132db9a..000000000 --- a/src/global/configure.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "module": "tools", - "tests": { - "libclang": { - "label": "libclang", - "test": "libclang", - "type": "libclang" - } - }, - "features": { - "clang": { - "label": "QDoc", - "condition": "tests.libclang", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "CLANG_LIBS", "value": "tests.libclang.libs" }, - { "type": "varAssign", "name": "CLANG_INCLUDEPATH", "value": "tests.libclang.includepath" }, - { "type": "varAssign", "name": "CLANG_LIBDIR", "value": "tests.libclang.libdir" }, - { "type": "varAssign", "name": "CLANG_DEFINES", "value": "tests.libclang.defines" }, - { "type": "varAssign", "name": "CLANG_VERSION", "value": "tests.libclang.version" }, - { "type": "varAssign", "name": "CLANG_MAJOR_VERSION", "value": "tests.libclang.major_version" }, - { "type": "varAssign", "name": "CLANG_MINOR_VERSION", "value": "tests.libclang.minor_version" }, - { "type": "varAssign", "name": "CLANG_PATCH_VERSION", "value": "tests.libclang.patch_version" } - ] - }, - "clangcpp": { - "label": "Clang-based lupdate parser", - "condition": "features.clang && tests.libclang.has_clangcpp", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "CLANGCPP_LIBS", "value": "tests.libclang.clangcpp_libs" } - ] - } - }, - "report": [ - { - "type": "warning", - "condition": "!features.clang", - "message": "QDoc will not be compiled, probably because libclang could not be located. This means that you cannot build the Qt documentation.\n -Either ensure that llvm-config is in your PATH environment variable, or set LLVM_INSTALL_DIR to the location of your llvm installation. -On Linux systems, you may be able to install libclang by installing the libclang-dev or libclang-devel package, depending on your distribution. -On macOS, you can use Homebrew's llvm package. -On Windows, you must set LLVM_INSTALL_DIR to the installation path." - }, - { - "type": "warning", - "condition": "!features.clangcpp", - "message": "Clang-based lupdate parser will not be available. LLVM and Clang C++ libraries have not been found." - } - ], - "summary": [ - { - "section": "Qt Tools", - "entries": [ - "clang", - "clangcpp" - ] - } - ] -} diff --git a/src/kmap2qmap/kmap2qmap.pro b/src/kmap2qmap/kmap2qmap.pro index d08ec6bb4..18e38dece 100644 --- a/src/kmap2qmap/kmap2qmap.pro +++ b/src/kmap2qmap/kmap2qmap.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(kmap2qmap)) + QT = core input_support-private CONFIG += console diff --git a/src/linguist/linguist.pro b/src/linguist/linguist.pro index face6545f..341334239 100644 --- a/src/linguist/linguist.pro +++ b/src/linguist/linguist.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/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/lupdate/lupdate.pro b/src/linguist/lupdate/lupdate.pro index 6a9289650..48761dc62 100644 --- a/src/linguist/lupdate/lupdate.pro +++ b/src/linguist/lupdate/lupdate.pro @@ -1,13 +1,15 @@ option(host_build) QT = core-private tools-private +# Needed to get access to all the CLANG_FOO assignments. +include($$OUT_PWD/../../../src/global/qttools-config.pri) + qtHaveModule(qmldevtools-private) { QT += qmldevtools-private } else { DEFINES += QT_NO_QML } -include($$OUT_PWD/../../global/qttools-config.pri) qtConfig(clangcpp) { LIBS += $$CLANGCPP_LIBS $$CLANG_LIBS diff --git a/src/macdeployqt/macdeployqt.pro b/src/macdeployqt/macdeployqt.pro index a0d90b640..eb2c8dbd7 100644 --- a/src/macdeployqt/macdeployqt.pro +++ b/src/macdeployqt/macdeployqt.pro @@ -1,2 +1,6 @@ +include($$OUT_PWD/../../src/global/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 3ee9eb915..8914e835b 100644 --- a/src/macdeployqt/macdeployqt/main.cpp +++ b/src/macdeployqt/macdeployqt/main.cpp @@ -42,20 +42,22 @@ int main(int argc, char **argv) qDebug() << "Usage: macdeployqt app-bundle [options]"; qDebug() << ""; qDebug() << "Options:"; - qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug"; - qDebug() << " -no-plugins : Skip plugin deployment"; - qDebug() << " -dmg : Create a .dmg disk image"; - qDebug() << " -no-strip : Don't run 'strip' on the binaries"; - qDebug() << " -use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)"; - qDebug() << " -executable=<path> : Let the given executable use the deployed frameworks too"; - qDebug() << " -qmldir=<path> : Scan for QML imports in the given path"; - 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+)"; + qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug"; + qDebug() << " -no-plugins : Skip plugin deployment"; + qDebug() << " -dmg : Create a .dmg disk image"; + qDebug() << " -no-strip : Don't run 'strip' on the binaries"; + qDebug() << " -use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)"; + qDebug() << " -executable=<path> : Let the given executable use the deployed frameworks too"; + qDebug() << " -qmldir=<path> : Scan for QML imports in the given path"; + 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() << " -timestamp : Include a secure timestamp when code signing (requires internet connection)"; + qDebug() << " -sign-for-notarization=<ident>: Activate the necessary options for notarization (requires internet connection)"; + 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+)"; qDebug() << ""; qDebug() << "macdeployqt takes an application bundle as input and makes it"; qDebug() << "self-contained by copying in the Qt frameworks and plugins that"; @@ -100,6 +102,7 @@ int main(int argc, char **argv) extern bool hardenedRuntime; extern bool appstoreCompliant; extern bool deployFramework; + extern bool secureTimestamp; for (int i = 2; i < argc; ++i) { QByteArray argument = QByteArray(argv[i]); @@ -166,9 +169,23 @@ int main(int argc, char **argv) runCodesign = true; codesignIdentiy = argument.mid(index+1); } + } else if (argument.startsWith(QByteArray("-sign-for-notarization"))) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + if (index < 0 || index >= argument.size()) { + LogError() << "Missing code signing identity"; + } else { + runCodesign = true; + hardenedRuntime = true; + secureTimestamp = true; + codesignIdentiy = argument.mid(index+1); + } } else if (argument.startsWith(QByteArray("-hardened-runtime"))) { LogDebug() << "Argument found:" << argument; hardenedRuntime = true; + } else if (argument.startsWith(QByteArray("-timestamp"))) { + LogDebug() << "Argument found:" << argument; + secureTimestamp = 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 4cc092956..33e243715 100644 --- a/src/macdeployqt/shared/shared.cpp +++ b/src/macdeployqt/shared/shared.cpp @@ -54,6 +54,7 @@ QStringList librarySearchPath; QString codesignIdentiy; QString extraEntitlements; bool hardenedRuntime = false; +bool secureTimestamp = false; bool appstoreCompliant = false; int logLevel = 1; bool deployFramework = false; @@ -1391,7 +1392,9 @@ void codesignFile(const QString &identity, const QString &filePath) QString codeSignLogMessage = "codesign"; if (hardenedRuntime) - codeSignLogMessage += ", enable hardned runtime"; + codeSignLogMessage += ", enable hardened runtime"; + if (secureTimestamp) + codeSignLogMessage += ", include secure timestamp"; LogNormal() << codeSignLogMessage << filePath; QStringList codeSignOptions = { "--preserve-metadata=identifier,entitlements", "--force", "-s", @@ -1399,6 +1402,9 @@ void codesignFile(const QString &identity, const QString &filePath) if (hardenedRuntime) codeSignOptions << "-o" << "runtime"; + if (secureTimestamp) + codeSignOptions << "--timestamp"; + if (!extraEntitlements.isEmpty()) codeSignOptions << "--entitlements" << extraEntitlements; diff --git a/src/makeqpf/makeqpf.pro b/src/makeqpf/makeqpf.pro index 5a8abc882..5c135284b 100644 --- a/src/makeqpf/makeqpf.pro +++ b/src/makeqpf/makeqpf.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/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/pixeltool/pixeltool.pro b/src/pixeltool/pixeltool.pro index f3d1bf436..86a632a2e 100644 --- a/src/pixeltool/pixeltool.pro +++ b/src/pixeltool/pixeltool.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(pixeltool)) + QT += core-private gui-private widgets mac { diff --git a/src/qdbus/qdbus.pro b/src/qdbus/qdbus.pro index 860c1e11e..225c7efff 100644 --- a/src/qdbus/qdbus.pro +++ b/src/qdbus/qdbus.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/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/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp index a3d39dbd2..ba19d9abc 100644 --- a/src/qdoc/clangcodeparser.cpp +++ b/src/qdoc/clangcodeparser.cpp @@ -1106,25 +1106,32 @@ void ClangCodeParser::initializeParser() printParsingErrors_ = 1; version_ = config.getString(CONFIG_VERSION); const auto args = config.getStringList(CONFIG_INCLUDEPATHS); - QStringList squeezedArgs; + QSet<QString> seen; + includePaths_.clear(); + // Remove empty paths and duplicates and add -I and canonicalize if necessary for (const auto &p : args) { - if (p.startsWith(QLatin1String("-I"))) - squeezedArgs << p.mid(2).trimmed(); - else - squeezedArgs << p; + QByteArray option; + QString rawpath; + if (p.startsWith(QLatin1String("-I")) || p.startsWith(QLatin1String("-F"))) { + rawpath = p.mid(2).trimmed(); + option = p.left(2).toUtf8(); + } else if (p.startsWith(QLatin1String("-isystem"))) { + rawpath = p.mid(8).trimmed(); + option = "-isystem"; + } else { + rawpath = p; + option = "-I"; + } + if (rawpath.isEmpty() || seen.contains(rawpath)) + continue; + seen.insert(rawpath); + QByteArray path(rawpath.toUtf8()); + QFileInfo fi(QDir::current(), rawpath); + if (fi.exists()) + path = fi.canonicalFilePath().toUtf8(); + path.prepend(option); + includePaths_.append(path); } - // Remove empty paths and duplicates - squeezedArgs.removeAll({}); - squeezedArgs.removeDuplicates(); - includePaths_.resize(squeezedArgs.size()); - std::transform(squeezedArgs.begin(), squeezedArgs.end(), includePaths_.begin(), - [](const QString &s) { - QByteArray path(s.toUtf8()); - QFileInfo fi(QDir::current(), s); - if (fi.exists()) - path = fi.canonicalFilePath().toUtf8(); - return path.prepend("-I"); - }); CppCodeParser::initializeParser(); pchFileDir_.reset(nullptr); allHeaders_.clear(); @@ -1225,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 }; diff --git a/src/qdoc/config.cpp b/src/qdoc/config.cpp index a809e56bd..d1c85aca6 100644 --- a/src/qdoc/config.cpp +++ b/src/qdoc/config.cpp @@ -239,14 +239,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; -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 @@ -263,7 +263,7 @@ QMap<QString, QStringList> Config::includeFilesMap_; */ void Config::init(const QString &programName, const QStringList &args) { - prog = programName; + m_prog = programName; processCommandLineOptions(args); reset(); } @@ -278,9 +278,9 @@ Config::~Config() */ void Config::clear() { - loc = lastLocation_ = Location(); - configVars_.clear(); - includeFilesMap_.clear(); + m_location = m_lastLocation = Location(); + m_configVars.clear(); + m_includeFilesMap.clear(); } /*! @@ -327,21 +327,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); } /*! @@ -349,7 +353,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())); } /*! @@ -358,7 +362,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())); } /*! @@ -383,7 +387,7 @@ 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); if (m_parser.isSet(m_parser.prepareOption)) m_qdocPass = Prepare; @@ -512,21 +516,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 +566,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 +601,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 +620,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 +685,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 +706,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 +725,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 +735,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 +793,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 +869,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 +1017,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 +1245,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 +1255,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 +1310,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 +1319,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 4dc6fb5e1..0ef5ba2e3 100644 --- a/src/qdoc/config.h +++ b/src/qdoc/config.h @@ -66,22 +66,22 @@ protected: */ 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) { } }; @@ -101,7 +101,7 @@ public: enum QDocPass { Neither, Prepare, Generate }; void init(const QString &programName, const QStringList &args); - bool getDebug() const { return debug_; } + bool getDebug() const { return m_debug; } void clear(); void reset(); @@ -111,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; @@ -135,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); @@ -185,29 +186,31 @@ private: 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_; + QString m_prog {}; + Location m_location {}; + Location m_lastLocation {}; + ConfigVarMultimap m_configVars {}; - static QMap<QString, QString> uncompressedFiles; - static QMap<QString, QString> extractedDirs; - static QStack<QString> workingDirs_; - static QMap<QString, QStringList> includeFilesMap_; - QDocCommandLineParser m_parser; + 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; + QDocPass m_qdocPass { Neither }; }; struct ConfigStrings diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp index daf09023f..931c50e1d 100644 --- a/src/qdoc/cppcodeparser.cpp +++ b/src/qdoc/cppcodeparser.cpp @@ -48,8 +48,6 @@ QT_BEGIN_NAMESPACE /* qmake ignore Q_OBJECT */ -QStringList CppCodeParser::exampleFiles; -QStringList CppCodeParser::exampleDirs; QSet<QString> CppCodeParser::excludeDirs; QSet<QString> CppCodeParser::excludeFiles; @@ -120,8 +118,6 @@ void CppCodeParser::initializeParser() nodeTypeTestFuncMap_.insert(COMMAND_VARIABLE, &Node::isVariable); Config &config = Config::instance(); - exampleFiles = config.getCanonicalPathList(CONFIG_EXAMPLES); - exampleDirs = config.getCanonicalPathList(CONFIG_EXAMPLEDIRS); QStringList exampleFilePatterns = config.getStringList(CONFIG_EXAMPLES + Config::dot + CONFIG_FILEEXTENSIONS); @@ -535,7 +531,6 @@ void CppCodeParser::processMetaCommand(const Doc &doc, const QString &command, doc.location().warning(tr("Invalid '\\%1' not allowed in '\\%2'") .arg(COMMAND_RELATES, node->nodeTypeString())); } else if (!node->isRelatedNonmember() && - //!node->parent()->name().isEmpty() && !node->parent()->isNamespace() && !node->parent()->isHeader()) { if (!doc.isInternal()) { doc.location().warning(tr("Invalid '\\%1' ('%2' must be global)") @@ -768,58 +763,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) { @@ -839,16 +805,18 @@ 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")); } + const int pathLen = exampleDir.path().size() - en->name().size(); 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 41607434f..df92b71c4 100644 --- a/src/qdoc/cppcodeparser.h +++ b/src/qdoc/cppcodeparser.h @@ -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 5b52e9e1a..23d5205ff 100644 --- a/src/qdoc/doc.cpp +++ b/src/qdoc/doc.cpp @@ -2086,7 +2086,7 @@ void DocParser::expandMacro(const QString &name, const QString &def, int numPara for (int i = 0; i < numParams; ++i) { if (numParams == 1 || isLeftBraceAhead()) { - args << getArgument(true); + args << getArgument(); } else { location().warning(tr("Macro '\\%1' invoked with too few" " arguments (expected %2, got %3)") diff --git a/src/qdoc/doc/qdoc-guide/qdoc-guide.qdoc b/src/qdoc/doc/qdoc-guide/qdoc-guide.qdoc index 201706b70..c964493bc 100644 --- a/src/qdoc/doc/qdoc-guide/qdoc-guide.qdoc +++ b/src/qdoc/doc/qdoc-guide/qdoc-guide.qdoc @@ -205,18 +205,17 @@ The \l {Format-specific Configuration Variables} article outlines the usage of each variable. - \section2 Qt Index Reference + \section2 QDoc Index Files - Documentation projects can link to Qt APIs and other articles by specifying - the path to the \c qt.index file. When qdoc generates the Qt Reference - Documentation, it will also generate an index file, containing the URLs to - the articles. Other projects can use the links in the index file so that - they can link to other articles and API documentation within Qt. + Documentation projects can link to targets in other projects by specifying + a set of dependencies, or a set of direct paths to to index file(s) this + project depends on. When QDoc generates documentation for a project, + it will also generate an \c .index file containing URLs to each linkable + entity in the project. Other projects can then define a dependency to the + index file in order to link to the documentation within that project. - \badcode - indexes = $QT_INSTALL_DOCS/html/qt.index $OTHER_PROJECT/html/qt.index - \endcode - It is possible to specify multiple index files from several projects. + \b {See also}: \l {depends-variable}{depends} and + \l {indexes-variable}{indexes}. \section1 Macros and Other Configurations @@ -230,6 +229,8 @@ HTML file, which will appear as the Greek \pi symbol when viewed in browsers. + \b {See also:} \l {macro-variable}{macro}. + \section2 QML Additions QDoc is able to parse QML files for QDoc comments. QDoc will parse files diff --git a/src/qdoc/doc/qdoc-manual-qdocconf.qdoc b/src/qdoc/doc/qdoc-manual-qdocconf.qdoc index d15fd5515..6d26de344 100644 --- a/src/qdoc/doc/qdoc-manual-qdocconf.qdoc +++ b/src/qdoc/doc/qdoc-manual-qdocconf.qdoc @@ -90,6 +90,7 @@ \li \l {Cpp.ignoredirectives-variable} {Cpp.ignoredirectives} \li \l {Cpp.ignoretokens-variable} {Cpp.ignoretokens} \li \l {defines-variable} {defines} + \li \l {depends-variable} {depends} \li \l {edition-variable} {edition} \li \l {exampledirs-variable} {exampledirs} \li \l {examples-variable} {examples} @@ -109,6 +110,7 @@ \li \l {imagedirs-variable} {imagedirs} \li \l {images-variable} {images} \li \l {images.fileextensions-variable} {images.fileextensions} + \li \l {indexes-variable} {indexes} \li \l {language-variable} {language} \li \l {locationinfo-variable} {locationinfo} \li \l {macro-variable} {macro} @@ -118,6 +120,7 @@ \li \l {outputformats-variable} {outputformats} \li \l {outputprefixes-variable} {outputprefixes} \li \l {outputsuffixes-variable} {outputsuffixes} + \li \l {project-variable} {project} \li \l {sourcedirs-variable} {sourcedirs} \li \l {sources-variable} {sources} \li \l {sources.fileextensions-variable} {sources.fileextensions} @@ -250,6 +253,58 @@ See also \l {falsehoods-variable} {falsehoods} and \l {if-command} {\\if}. + \target depends-variable + \section1 depends + + The \c depends variable defines a list of other documentation projects + that this project depends on for resolving link targets for type + inheritance and anything else the documentation needs to link to. + + Like Qt itself, documentation for Qt is distributed across multiple + modules. In a multi-module documentation project, the minimum set + of dependencies for a single module consists of actual build + dependencies. In addition, if there is a documentation project + (module) that acts as a top-level entry point for the entire + documentation set and provides \l {navigation-variable}[navigation} + links, each module documentation should include it as a dependency. + + When QDoc generates documentation for a project, it will also generate + an \c .index file containing URLs to each linkable entity in the project. + Each dependency is a (lowercase) name of a project. This name must + match with the base name of the index file generated for that + project. + + \badcode + depends = \ + qtdoc \ + qtcore \ + qtquick + \endcode + + When invoking QDoc on a project that has dependencies and uses the + \c depends variable, one or more \c -indexdir path(s) must be passed + as command line option(s). QDoc uses these paths to search for + the dependencies' index files. + + \badcode + qdoc mydoc.qdocconf -outputdir $PWD/html -indexdir $QT_INSTALL_DOCS + \endcode + + With above, QDoc will search for a file + \c {$T_INSTALL_DOCS/qtdoc/qtdoc.index} for a dependency to \c qtdoc. + If an index file for a dependency is not found, QDoc will output a + warning. + + The \c depends command accepts also a special value of '*'. This + instructs QDoc to load all index files found in specified index + directories; that is, "depends on everything". + + \badcode + depends = * + \endcode + + See also \l indexes, \l project, and \l url. + \target edition-variable \section1 edition @@ -1729,24 +1784,30 @@ \target indexes-variable \section1 indexes - The \c indexes variable lists the index files that will be used to - generate references. - - For example. to make a derived Qt project contain links to the Qt - Reference documentation, you need to specify the associated index - file: + The \l {indexes-variable}[indexes} variable defines a set of paths + to index files to load. \badcode - indexes = $QTDIR/doc/html/qt.index + indexes = \ + $QT_INSTALL_DOCS/qtcore/qtcore.index \ + $SOME_OTHER_PROJECT/doc/foo.index \endcode - See also \l project and \l url. + The \c indexes variable provides an alternative to \l depends for + defining project's dependencies. As direct paths are provided, no + \c -indexdir command line option(s) are required when invoking QDoc. + + It is possible to define dependencies using either variable. Qt + documentation only uses the \c depends variable. + + See also \l depends, \l project and \l url. \target project-variable \section1 project The \c project variable provides a name for the project associated - with the \c .qdocconf file. + with the \c .qdocconf file. This is a mandatory variable that all + projects must set. The project's name is used to form a file name for the associated project's \e index file. @@ -1758,12 +1819,16 @@ This will cause an index file called \c qtcreator.index to be created. - See also \l description and \l indexes. + If the project name contains whitespace or special characters, + these are replaced with dashes ('-') in the generated index file + name. + + See also \l depends, \l indexes, and \l description. \target url-variable \section1 url - The \c url variable holds the base URL for the reference + The \c url variable holds the base URL for the documentation associated with the current project. The URL is stored in the generated index file for the @@ -1772,18 +1837,18 @@ other things listed in the index. \badcode - project = Qt - description = Qt Reference Documentation + project = QtCore + description = Qt Core Reference Documentation url = https://doc.qt.io/qt/ - ... + ... \endcode - This makes sure that whenever \c qt.index is used to generate - references to for example Qt classes, the base URL is \c - https://doc.qt.io/qt/. + This ensures that whenever QDoc generates + references to entities in the Qt Core module, the base URL is + \c https://doc.qt.io/qt/. - See also \l indexes and \l {url.examples}. + See also \l depends, \l indexes and \l {url.examples}. \target url.examples-variable \section1 url.examples @@ -1843,23 +1908,24 @@ This feature makes use of the comprehensive indexes generated by QDoc when it creates the Qt reference documentation. - For example, \l qtgui.qdocconf (the configuration file for Qt) + For example, \l qtgui.qdocconf (the configuration file for Qt GUI) contains the following variable definitions: \badcode - project = Qt - description = Qt Reference Documentation + project = QtGui + description = Qt GUI Reference Documentation url = http://doc.qt.io/qt/ ... \endcode The \l project variable name is used to form a file name for the - index file; in this case the \c qt.index file is created. The \l + index file; in this case the \c qtgui.index file is created. The \l url is stored in the index file. Afterwards, QDoc will use this as the base URL when constructing links to classes, functions, and other things listed in the index. + See also \l depends, \l indexes, \l project, and \l url. */ /*! diff --git a/src/qdoc/docbookgenerator.cpp b/src/qdoc/docbookgenerator.cpp index 063065511..f6476c9ec 100644 --- a/src/qdoc/docbookgenerator.cpp +++ b/src/qdoc/docbookgenerator.cpp @@ -4108,21 +4108,22 @@ void DocBookGenerator::generateCollectionNode(CollectionNode *cn) generateStatus(cn); generateSince(cn); - 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(); + 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(); + } } - nmm.clear(); } Text brief = cn->doc().briefText(); diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp index bcd02bc91..a10784ed8 100644 --- a/src/qdoc/htmlgenerator.cpp +++ b/src/qdoc/htmlgenerator.cpp @@ -1492,23 +1492,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(); @@ -2123,13 +2124,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"; @@ -3758,33 +3761,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"; diff --git a/src/qdoc/node.h b/src/qdoc/node.h index 9f78cc824..b7293f408 100644 --- a/src/qdoc/node.h +++ b/src/qdoc/node.h @@ -705,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_; }; diff --git a/src/qdoc/qdoc.pro b/src/qdoc/qdoc.pro index 6cc35dab9..3a4d7cbd1 100644 --- a/src/qdoc/qdoc.pro +++ b/src/qdoc/qdoc.pro @@ -13,7 +13,7 @@ qtHaveModule(qmldevtools-private) { DEFINES += QT_NO_FOREACH -include($$OUT_PWD/../global/qttools-config.pri) +include($$OUT_PWD/../../src/global/qttools-config.pri) LIBS += $$CLANG_LIBS !contains(QMAKE_DEFAULT_INCDIRS, $$CLANG_INCLUDEPATH): INCLUDEPATH += $$CLANG_INCLUDEPATH diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp index 12136dd4a..60cace3c9 100644 --- a/src/qdoc/qdocindexfiles.cpp +++ b/src/qdoc/qdocindexfiles.cpp @@ -110,7 +110,7 @@ void QDocIndexFiles::destroyQDocIndexFiles() void QDocIndexFiles::readIndexes(const QStringList &indexFiles) { for (const QString &file : indexFiles) { - qCInfo(lcQdoc) << "Loading index file: " << file; + qCDebug(lcQdoc) << "Loading index file: " << file; readIndexFile(file); } } @@ -1522,7 +1522,7 @@ void QDocIndexFiles::generateIndex(const QString &fileName, const QString &url, if (!file.open(QFile::WriteOnly | QFile::Text)) return; - qCInfo(lcQdoc) << "Writing index file:" << fileName; + qCDebug(lcQdoc) << "Writing index file:" << fileName; gen_ = g; QXmlStreamWriter writer(&file); diff --git a/src/qev/qev.pro b/src/qev/qev.pro index f00826ad1..2f2e399b5 100644 --- a/src/qev/qev.pro +++ b/src/qev/qev.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(qev)) + QT += widgets SOURCES += qev.cpp 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..161b75851 100644 --- a/src/qtattributionsscanner/qtattributionsscanner.pro +++ b/src/qtattributionsscanner/qtattributionsscanner.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(qtattributionsscanner)) + option(host_build) CONFIG += console diff --git a/src/qtdiag/qtdiag.pro b/src/qtdiag/qtdiag.pro index b9b3c6e56..410339804 100644 --- a/src/qtdiag/qtdiag.pro +++ b/src/qtdiag/qtdiag.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(qtdiag)) + CONFIG += console QT += core-private gui-private diff --git a/src/qtpaths/qtpaths.pro b/src/qtpaths/qtpaths.pro index f494c8148..f4f69b981 100644 --- a/src/qtpaths/qtpaths.pro +++ b/src/qtpaths/qtpaths.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/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..724b83b4e 100644 --- a/src/qtplugininfo/qtplugininfo.pro +++ b/src/qtplugininfo/qtplugininfo.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(qtplugininfo)) + SOURCES = qtplugininfo.cpp QT = core CONFIG += console diff --git a/src/shared/fontpanel/fontpanel.cpp b/src/shared/fontpanel/fontpanel.cpp index 8e4b6332d..0a2ab3a66 100644 --- a/src/shared/fontpanel/fontpanel.cpp +++ b/src/shared/fontpanel/fontpanel.cpp @@ -68,7 +68,7 @@ FontPanel::FontPanel(QWidget *parentWidget) : writingSystems.push_front(QFontDatabase::Any); for (QFontDatabase::WritingSystem ws : qAsConst(writingSystems)) m_writingSystemComboBox->addItem(QFontDatabase::writingSystemName(ws), QVariant(ws)); - connect(m_writingSystemComboBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), + connect(m_writingSystemComboBox, &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, const QString &>::of(&QComboBox::currentIndexChanged), + connect(m_styleComboBox, &QComboBox::currentIndexChanged, this, &FontPanel::slotStyleChanged); formLayout->addRow(tr("&Style"), m_styleComboBox); m_pointSizeComboBox->setEditable(false); - connect(m_pointSizeComboBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), + connect(m_pointSizeComboBox, &QComboBox::currentIndexChanged, this, &FontPanel::slotPointSizeChanged); formLayout->addRow(tr("&Point size"), m_pointSizeComboBox); diff --git a/src/src.pro b/src/src.pro index 9510a2af7..f54576388 100644 --- a/src/src.pro +++ b/src/src.pro @@ -27,7 +27,7 @@ qtConfig(commandlineparser) { SUBDIRS += global -include($$OUT_PWD/global/qttools-config.pri) +include($$OUT_PWD/../src/global/qttools-config.pri) QT_FOR_CONFIG += tools-private qtConfig(clang): qtConfig(thread): qtConfig(commandlineparser): SUBDIRS += qdoc diff --git a/src/windeployqt/windeployqt.pro b/src/windeployqt/windeployqt.pro index cd09c238f..19b131089 100644 --- a/src/windeployqt/windeployqt.pro +++ b/src/windeployqt/windeployqt.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/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..fb0d58e6e 100644 --- a/src/winrtrunner/winrtrunner.pro +++ b/src/winrtrunner/winrtrunner.pro @@ -1,3 +1,7 @@ +include($$OUT_PWD/../../src/global/qttools-config.pri) +QT_FOR_CONFIG += tools-private +requires(qtConfig(winrtrunner)) + option(host_build) CONFIG += force_bootstrap diff --git a/tests/auto/linguist/lupdate/testdata/good/parseobjc/main.mm b/tests/auto/linguist/lupdate/testdata/good/parseobjc/main.mm new file mode 100644 index 000000000..7cc1c34e3 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parseobjc/main.mm @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtCore/qcoreapplication.h> + +@interface NSObject +@end + +@interface Foo : NSObject +@property (nonatomic, retain) NSObject *child; +- (bool)someMethodWithArg:(NSObject*)child andAnotherArg:(int)age; +@end + +@implementation Foo +- (bool)someMethodWithArg:(NSObject*)child andAnotherArg:(int)age +{ + QCoreApplication::translate("Biz", "Baz"); + return self.child == child && age == 42; +} +@end + +int main() +{ + QCoreApplication::translate("Foo", "Bar"); + return 0; +} diff --git a/tests/auto/linguist/lupdate/testdata/good/parseobjc/project.pro b/tests/auto/linguist/lupdate/testdata/good/parseobjc/project.pro new file mode 100644 index 000000000..e9d4e1ec3 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parseobjc/project.pro @@ -0,0 +1,3 @@ +SOURCES += main.mm + +TRANSLATIONS = project.ts diff --git a/tests/auto/linguist/lupdate/testdata/good/parseobjc/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parseobjc/project.ts.result new file mode 100644 index 000000000..675d16449 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parseobjc/project.ts.result @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1"> +<context> + <name>Biz</name> + <message> + <location filename="main.mm" line="42"/> + <source>Baz</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Foo</name> + <message> + <location filename="main.mm" line="49"/> + <source>Bar</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/tests/auto/linguist/lupdate/tst_lupdate.cpp b/tests/auto/linguist/lupdate/tst_lupdate.cpp index b2ced9df8..ac6e4db2b 100644 --- a/tests/auto/linguist/lupdate/tst_lupdate.cpp +++ b/tests/auto/linguist/lupdate/tst_lupdate.cpp @@ -222,6 +222,9 @@ void tst_lupdate::good_data() #ifndef Q_OS_WIN dirs.removeAll(QLatin1String("backslashes")); #endif +#ifndef Q_OS_MACOS + dirs.removeAll(QLatin1String("parseobjc")); +#endif for (const QString &dir : qAsConst(dirs)) QTest::newRow(dir.toLocal8Bit()) << dir; 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 index 1e9383fb9..44a1ba953 100644 --- a/tests/auto/qdoc/config/tst_config.cpp +++ b/tests/auto/qdoc/config/tst_config.cpp @@ -28,6 +28,8 @@ #include "config.h" +#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> #include <QtCore/qhash.h> #include <QtCore/qstringlist.h> #include <QtTest/QtTest> @@ -43,6 +45,7 @@ class tst_Config : public QObject private slots: void classMembersInitializeToFalseOrEmpty(); void includePathsFromCommandLine(); + void getExampleProjectFile(); }; void tst_Config::classMembersInitializeToFalseOrEmpty() @@ -80,6 +83,32 @@ void tst_Config::includePathsFromCommandLine() 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/expected_output/demos-manifest.xml b/tests/auto/qdoc/generatedoutput/expected_output/demos-manifest.xml new file mode 100644 index 000000000..d83906f44 --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/demos-manifest.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<instructionals module="Test"> + <demos> + <demo name="Demo" docUrl="qthelp://org.qt-project.test.001/test/test-demos-demo-example.html" projectPath="test/demos/demo/demo.pro" isTest="true"> + <description><![CDATA[No description available]]></description> + <tags>demo,test</tags> + </demo> + </demos> +</instructionals> 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/nestedmacro/testcpp-module.html b/tests/auto/qdoc/generatedoutput/expected_output/nestedmacro/testcpp-module.html new file mode 100644 index 000000000..6ab4d245b --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/nestedmacro/testcpp-module.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> +<!-- testcpp.cpp --> + <title>QDoc Test C++ Classes | TestCPP</title> +</head> +<body> +<div class="sidebar"> +<div class="toc"> +<h3><a name="toc">Contents</a></h3> +<ul> +<li class="level1"><a href="#namespaces">Namespaces</a></li> +<li class="level1"><a href="#classes">Classes</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">QDoc Test C++ Classes</h1> +<span class="subtitle"></span> +<!-- $$$TestCPP-brief --> +<p>A test module page. <a href="#details">More...</a></p> +<!-- @@@TestCPP --> +<a name="namespaces"></a> +<h2 id="namespaces">Namespaces</h2> +<div class="table"><table class="annotated"> +<tr class="odd topAlign"><td class="tblName"><p><a href="testqdoc.html">TestQDoc</a></p></td><td class="tblDescr"><p>A namespace</p></td></tr> +</table></div> +<a name="classes"></a> +<h2 id="classes">Classes</h2> +<div class="table"><table class="annotated"> +<tr class="odd 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="even 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> +<!-- $$$TestCPP-description --> +<a name="details"></a> +<div class="descr"> +<h2 id="details">Detailed Description</h2> +<p><b>This module was introduced in version 5.15.</b></p> +</div> +<!-- @@@TestCPP --> +</body> +</html> 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 <@type>int</@type> anAliasedProperty +An aliased property of type <@type>int</@type><@op>.</@op> +</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/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 index 4816ef1d5..387e018ae 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/test.qhp +++ b/tests/auto/qdoc/generatedoutput/expected_output/test.qhp @@ -8,6 +8,8 @@ <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="test-demos-demo-example.html" title="Demo"/> <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"/> @@ -119,11 +121,15 @@ <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>test-demos-demo-example.html</file> <file>testcpp-module.html</file> <file>testqdoc-test-members.html</file> <file>testqdoc-test-obsolete.html</file> diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf index a1ed619a3..11695289e 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf +++ b/tests/auto/qdoc/generatedoutput/testdata/configs/examples-qhp.qdocconf @@ -4,6 +4,8 @@ version = 0.0.1 examplesinstallpath = test +exampledirs += ../examples + # Configure .qhp generation qhp.projects = Test diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/nestedmacro.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/nestedmacro.qdocconf new file mode 100644 index 000000000..64475be7e --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/testdata/configs/nestedmacro.qdocconf @@ -0,0 +1,9 @@ +include(testcpp.qdocconf) +defines += test_nestedmacro + +macro.ver = "5.15.0" +macro.ver.match = "^(\\d+\\.\\d+)" +macro.versionnote.HTML = "<p><b>This \1 was introduced in version \2.</b></p>\n" + +HTML.nosubdirs = true +HTML.outputsubdir = nestedmacro 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/testcpp.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp.qdocconf index b07aa71c0..7bb7810f1 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp.qdocconf +++ b/tests/auto/qdoc/generatedoutput/testdata/configs/testcpp.qdocconf @@ -6,6 +6,7 @@ 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 diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf index 2eb2c5036..8eec4ea4d 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf +++ b/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf @@ -16,7 +16,7 @@ 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/examples/demos/demo/demo.pro b/tests/auto/qdoc/generatedoutput/testdata/examples/demos/demo/demo.pro new file mode 100644 index 000000000..dbe8ff3c0 --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/testdata/examples/demos/demo/demo.pro @@ -0,0 +1,2 @@ +TEMPLATE = aux +message("Nothing to see here.") diff --git a/tests/auto/qdoc/generatedoutput/testdata/examples/demos/demo/doc/src/demo.qdoc b/tests/auto/qdoc/generatedoutput/testdata/examples/demos/demo/doc/src/demo.qdoc new file mode 100644 index 000000000..08b609126 --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/testdata/examples/demos/demo/doc/src/demo.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 demos/demo + \title Demo +*/ 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/testdata/qml/componentset/examples.qdoc b/tests/auto/qdoc/generatedoutput/testdata/qml/componentset/examples.qdoc index 0816e624c..bce12a4ae 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/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 diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp b/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp index bf04bdb43..2e967c4a2 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/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/testdata/singleexec/singleexec.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/singleexec/singleexec.qdocconf index eee0253d0..037cfc74a 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/singleexec/singleexec.qdocconf +++ b/tests/auto/qdoc/generatedoutput/testdata/singleexec/singleexec.qdocconf @@ -1,2 +1,2 @@ -./testdata/configs/testcpp_singleexec.qdocconf -./testdata/crossmodule/crossmodule_singleexec.qdocconf +../configs/testcpp_singleexec.qdocconf +../crossmodule/crossmodule_singleexec.qdocconf diff --git a/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.cpp b/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.cpp index b1acdccf0..17045eed5 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.cpp +++ b/tests/auto/qdoc/generatedoutput/testdata/testcpp/testcpp.cpp @@ -34,6 +34,12 @@ namespace TestQDoc { \qtvariable testcpp \title QDoc Test C++ Classes \brief A test module page. + + \testnoautolist + +\if defined(test_nestedmacro) + \versionnote {module} {\ver} +\endif */ /*! diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp index 5449a50e2..40fcdfcac 100644 --- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp +++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp @@ -67,6 +67,8 @@ private slots: void singleExec(); void preparePhase(); void generatePhase(); + void noAutoList(); + void nestedMacro(); private: QScopedPointer<QTemporaryDir> m_outputDir; @@ -203,6 +205,7 @@ void tst_generatedOutput::htmlFromQml() { 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 " @@ -292,6 +295,7 @@ void tst_generatedOutput::examplesManifestXmlAndQhp() { testAndCompare("testdata/configs/examples-qhp.qdocconf", "examples-manifest.xml " + "demos-manifest.xml " "test.qhp"); } @@ -378,6 +382,24 @@ void tst_generatedOutput::generatePhase() "-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"); +} + + +void tst_generatedOutput::nestedMacro() +{ + testAndCompare("testdata/configs/nestedmacro.qdocconf", + "nestedmacro/testcpp-module.html"); +} + QTEST_APPLESS_MAIN(tst_generatedOutput) #include "tst_generatedoutput.moc" |