summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2018-07-12 16:38:30 +0200
committerJarek Kobus <jaroslaw.kobus@qt.io>2018-07-26 05:55:57 +0000
commit30a75f7f0d540b5fd312b3cb2cf850e4e177c68b (patch)
tree1bfa56e2abdce37412158ec9548eb833df1a9462
parentcaf3b6c291d3659d9fbc083ccf26fa178a3d38dc (diff)
downloadqttools-30a75f7f0d540b5fd312b3cb2cf850e4e177c68b.tar.gz
Merge qcollectiongenerator into qhelpgenerator tool
Change-Id: I3c961d7c13ce4f9a3aa36dd0554ec5184fbc5953 Reviewed-by: Kai Koehne <kai.koehne@qt.io>
-rw-r--r--.gitignore2
-rw-r--r--examples/assistant/doc/src/simpletextviewer.qdoc4
-rw-r--r--src/assistant/assistant.pro5
-rw-r--r--src/assistant/assistant/doc/snippets/doc_src_assistant-manual.qdoc2
-rw-r--r--src/assistant/assistant/doc/src/assistant-manual.qdoc4
-rw-r--r--src/assistant/help/Qt5HelpConfigExtras.cmake.in15
-rw-r--r--src/assistant/help/doc/snippets/doc_src_qthelp.qdoc2
-rw-r--r--src/assistant/help/doc/src/qthelp.qdoc37
-rw-r--r--src/assistant/qcollectiongenerator/main.cpp610
-rw-r--r--src/assistant/qcollectiongenerator/qcollectiongenerator.pro11
-rw-r--r--src/assistant/qhelpgenerator/collectionconfigreader.cpp258
-rw-r--r--src/assistant/qhelpgenerator/collectionconfigreader.h117
-rw-r--r--src/assistant/qhelpgenerator/main.cpp319
-rw-r--r--src/assistant/qhelpgenerator/qhelpgenerator.pro8
14 files changed, 683 insertions, 711 deletions
diff --git a/.gitignore b/.gitignore
index c592523a6..b3fc428a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,12 +74,10 @@ bin/rcc*
bin/uic*
bin/patternist*
bin/phonon*
-bin/qcollectiongenerator*
bin/qdbus*
bin/qhelpgenerator*
bin/xmlpatterns*
bin/cetest*
-bin/collectiongenerator
bin/helpconverter
bin/helpgenerator
bin/kmap2qmap*
diff --git a/examples/assistant/doc/src/simpletextviewer.qdoc b/examples/assistant/doc/src/simpletextviewer.qdoc
index 374256bbf..b8efba659 100644
--- a/examples/assistant/doc/src/simpletextviewer.qdoc
+++ b/examples/assistant/doc/src/simpletextviewer.qdoc
@@ -301,10 +301,10 @@
As the last step, we have to generate the binary collection file
out of the help collection project file. This is done by running the
- \c qcollectiongenerator tool.
+ \c qhelpgenerator tool.
\code
- qcollectiongenerator simpletextviewer.qhcp -o simpletextviewer.qhc
+ qhelpgenerator simpletextviewer.qhcp -o simpletextviewer.qhc
\endcode
To test all our customizations made to \QA, we add the collection
diff --git a/src/assistant/assistant.pro b/src/assistant/assistant.pro
index 122a93b73..ec6377db5 100644
--- a/src/assistant/assistant.pro
+++ b/src/assistant/assistant.pro
@@ -3,15 +3,12 @@ TEMPLATE = subdirs
SUBDIRS += \
help \
assistant \
- qhelpgenerator \
- qcollectiongenerator
+ qhelpgenerator
assistant.depends = help
qhelpgenerator.depends = help
-qcollectiongenerator.depends = help
qtNomakeTools( \
assistant \
qhelpgenerator \
- qcollectiongenerator \
)
diff --git a/src/assistant/assistant/doc/snippets/doc_src_assistant-manual.qdoc b/src/assistant/assistant/doc/snippets/doc_src_assistant-manual.qdoc
index 6356b208a..feae78784 100644
--- a/src/assistant/assistant/doc/snippets/doc_src_assistant-manual.qdoc
+++ b/src/assistant/assistant/doc/snippets/doc_src_assistant-manual.qdoc
@@ -154,5 +154,5 @@ assistant -collectionFile mycollection.qhc
//! [9]
//! [10]
-qcollectiongenerator mycollection.qhcp -o mycollection.qhc
+qhelpgenerator mycollection.qhcp -o mycollection.qhc
//! [10]
diff --git a/src/assistant/assistant/doc/src/assistant-manual.qdoc b/src/assistant/assistant/doc/src/assistant-manual.qdoc
index cbd6ccde4..9badfc260 100644
--- a/src/assistant/assistant/doc/src/assistant-manual.qdoc
+++ b/src/assistant/assistant/doc/src/assistant-manual.qdoc
@@ -189,7 +189,7 @@
\section2 Creating a Custom Help Collection File
The help collection file (*.qhc) used by \QA is created when running the
- \c qcollectiongenerator tool on a help collection project file (*.qhcp).
+ \c qhelpgenerator tool on a help collection project file (*.qhcp).
The project file format is XML and it supports the following tags:
\table
@@ -279,7 +279,7 @@
\snippet doc_src_assistant-manual.qdoc 1
- To create the binary collection file, run the \c qcollectiongenerator tool:
+ To create the binary collection file, run the \c qhelpgenerator tool:
\snippet doc_src_assistant-manual.qdoc 10
diff --git a/src/assistant/help/Qt5HelpConfigExtras.cmake.in b/src/assistant/help/Qt5HelpConfigExtras.cmake.in
index 3b97923a9..b8ce04427 100644
--- a/src/assistant/help/Qt5HelpConfigExtras.cmake.in
+++ b/src/assistant/help/Qt5HelpConfigExtras.cmake.in
@@ -1,19 +1,4 @@
-if (NOT TARGET Qt5::qcollectiongenerator)
- add_executable(Qt5::qcollectiongenerator IMPORTED)
-
-!!IF isEmpty(CMAKE_BIN_DIR_IS_ABSOLUTE)
- set(imported_location \"${_qt5Help_install_prefix}/$${CMAKE_BIN_DIR}qcollectiongenerator$$CMAKE_BIN_SUFFIX\")
-!!ELSE
- set(imported_location \"$${CMAKE_BIN_DIR}qcollectiongenerator$$CMAKE_BIN_SUFFIX\")
-!!ENDIF
- _qt5_Help_check_file_exists(${imported_location})
-
- set_target_properties(Qt5::qcollectiongenerator PROPERTIES
- IMPORTED_LOCATION ${imported_location}
- )
-endif()
-
if (NOT TARGET Qt5::qhelpgenerator)
add_executable(Qt5::qhelpgenerator IMPORTED)
diff --git a/src/assistant/help/doc/snippets/doc_src_qthelp.qdoc b/src/assistant/help/doc/snippets/doc_src_qthelp.qdoc
index 303119f85..648598079 100644
--- a/src/assistant/help/doc/snippets/doc_src_qthelp.qdoc
+++ b/src/assistant/help/doc/snippets/doc_src_qthelp.qdoc
@@ -71,7 +71,7 @@ qhelpgenerator doc.qhp -o doc.qch
//! [4]
-qcollectiongenerator mycollection.qhcp -o mycollection.qhc
+qhelpgenerator mycollection.qhcp -o mycollection.qhc
//! [4]
diff --git a/src/assistant/help/doc/src/qthelp.qdoc b/src/assistant/help/doc/src/qthelp.qdoc
index 69afe5b2a..7b096882c 100644
--- a/src/assistant/help/doc/src/qthelp.qdoc
+++ b/src/assistant/help/doc/src/qthelp.qdoc
@@ -103,33 +103,32 @@
\row
\li \l {Qt Help Project}
\li .qhp
- \li The input file for the help generator consisting of the table
- of contents, indices, and references to the actual documentation
- files (*.html). It also defines a unique namespace for the
- documentation.
+ \li Contains the table of contents, indices, and references to the
+ actual documentation files (*.html). It also defines a unique
+ namespace for the documentation. This file is passed to the help
+ generator for creating a compressed help file.
\row
\li Qt Compressed Help
\li .qch
- \li The output file of the help generator. This binary file contains
- all the information specified in the help project file along with
- all the compressed documentation files.
+ \li Contains all the information specified in the help project file
+ along with all the compressed documentation files.
\row
\li \l {Qt Help Collection Project}
\li .qhcp
- \li The input file for the help collection generator. It contains
- references to the compressed help files that should be included in
- the collection; it also may contain other information for
- customizing Qt Assistant.
+ \li An XML file that contains references to the compressed help
+ files that should be included in the help collection. In
+ addition, it may contain information for customizing Qt
+ Assistant. This file can be passed to the help generator for
+ creating a help collection file.
\row
\li Qt Help Collection
\li .qhc
- \li The output of the help collection generator. This is the file
- QHelpEngine operates on. It contains references to any number of
- compressed help files as well as additional information, such as
- custom filters.
+ \li The help collection file that QHelpEngine operates on. It can
+ contain references to any number of compressed help files as
+ well as additional information, such as custom filters.
\endtable
\section1 Generating Qt Help
@@ -165,11 +164,9 @@
\snippet doc_src_qthelp.qdoc 4
- Instead of running two tools, one for generating the compressed
- help and another for generating the collection file, it is also
- possible to just run the qcollectiongenerator tool with a
- slightly modified project file instructing the generator to
- create the compressed help first.
+ To generate both the compressed help and the collection file in one go,
+ modify the help collection project file so that it instructs the help
+ generator to create the compressed help first:
\snippet doc_src_qthelp.qdoc 5
diff --git a/src/assistant/qcollectiongenerator/main.cpp b/src/assistant/qcollectiongenerator/main.cpp
deleted file mode 100644
index 4b2074599..000000000
--- a/src/assistant/qcollectiongenerator/main.cpp
+++ /dev/null
@@ -1,610 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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: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 "../shared/collectionconfiguration.h"
-#include "../shared/helpgenerator.h"
-
-#include <private/qhelpprojectdata_p.h>
-
-#include <QtCore/QDataStream>
-#include <QtCore/QDir>
-#include <QtCore/QMap>
-#include <QtCore/QFileInfo>
-#include <QtCore/QDateTime>
-#include <QtCore/QBuffer>
-#include <QtCore/QTranslator>
-#include <QtCore/QLocale>
-#include <QtCore/QLibraryInfo>
-#include <QtHelp/QHelpEngineCore>
-#include <QtCore/QRegExp>
-#include <QtCore/QXmlStreamReader>
-
-#include <QtGui/QGuiApplication>
-
-QT_USE_NAMESPACE
-
-class QCG {
- Q_DECLARE_TR_FUNCTIONS(QCollectionGenerator)
-};
-
-class CollectionConfigReader : public QXmlStreamReader
-{
-public:
- void readData(const QByteArray &contents);
-
- QString title() const { return m_title; }
- QString homePage() const { return m_homePage; }
- QString startPage() const { return m_startPage; }
- QString applicationIcon() const { return m_applicationIcon; }
- QString currentFilter() const { return m_currentFilter; }
- bool enableFilterFunctionality() const
- { return m_enableFilterFunctionality; }
- bool hideFilterFunctionality() const
- { return m_hideFilterFunctionality; }
- bool enableAddressBar() const { return m_enableAddressBar; }
- bool hideAddressBar() const { return m_hideAddressBar; }
- bool enableDocumentationManager() const
- { return m_enableDocumentationManager; }
-
- QMap<QString, QString> aboutMenuTexts() const
- { return m_aboutMenuTexts; }
- QString aboutIcon() const { return m_aboutIcon; }
- QMap<QString, QString> aboutTextFiles() const
- { return m_aboutTextFiles; }
-
- QMap<QString, QString> filesToGenerate() const
- { return m_filesToGenerate; }
-
- QStringList filesToRegister() const { return m_filesToRegister; }
-
- QString cacheDirectory() const { return m_cacheDirectory; }
- bool cacheDirRelativeToCollection() const { return m_cacheDirRelativeToCollection; }
-
- bool fullTextSearchFallbackEnabled() const {
- return m_enableFullTextSearchFallback;
- }
-
-private:
- void raiseErrorWithLine();
- void readConfig();
- void readAssistantSettings();
- void readMenuTexts();
- void readAboutDialog();
- void readDocFiles();
- void readGenerate();
- void readFiles();
- void readRegister();
-
- QString m_title;
- QString m_homePage;
- QString m_startPage;
- QString m_applicationIcon;
- QString m_currentFilter;
- bool m_enableFilterFunctionality;
- bool m_hideFilterFunctionality;
- bool m_enableAddressBar;
- bool m_hideAddressBar;
- bool m_enableDocumentationManager;
- QMap<QString, QString> m_aboutMenuTexts;
- QString m_aboutIcon;
- QMap<QString, QString> m_aboutTextFiles;
- QMap<QString, QString> m_filesToGenerate;
- QStringList m_filesToRegister;
- QString m_cacheDirectory;
- bool m_cacheDirRelativeToCollection;
- bool m_enableFullTextSearchFallback;
-};
-
-void CollectionConfigReader::raiseErrorWithLine()
-{
- raiseError(QCG::tr("Unknown token at line %1.").arg(lineNumber()));
-}
-
-void CollectionConfigReader::readData(const QByteArray &contents)
-{
- m_enableFilterFunctionality = true;
- m_hideFilterFunctionality = true;
- m_enableAddressBar = true;
- m_hideAddressBar = true;
- m_enableDocumentationManager = true;
- m_enableFullTextSearchFallback = false;
-
- addData(contents);
- while (!atEnd()) {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("QHelpCollectionProject")
- && attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
- readConfig();
- else
- raiseError(QCG::tr("Unknown token at line %1. "
- "Expected \"QtHelpCollectionProject\".")
- .arg(lineNumber()));
- }
- }
-}
-
-void CollectionConfigReader::readConfig()
-{
- bool ok = false;
- while (!atEnd()) {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("assistant"))
- readAssistantSettings();
- else if (name() == QLatin1String("docFiles"))
- readDocFiles();
- else
- raiseErrorWithLine();
- } else if (isEndElement() && name() == QLatin1String("QHelpCollectionProject")) {
- ok = true;
- }
- }
- if (!ok && !hasError())
- raiseError(QCG::tr("Missing end tags."));
-}
-
-void CollectionConfigReader::readAssistantSettings()
-{
- while (!atEnd()) {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("title")) {
- m_title = readElementText();
- } else if (name() == QLatin1String("homePage")) {
- m_homePage = readElementText();
- } else if (name() == QLatin1String("startPage")) {
- m_startPage = readElementText();
- } else if (name() == QLatin1String("currentFilter")) {
- m_currentFilter = readElementText();
- } else if (name() == QLatin1String("applicationIcon")) {
- m_applicationIcon = readElementText();
- } else if (name() == QLatin1String("enableFilterFunctionality")) {
- if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
- m_hideFilterFunctionality = false;
- if (readElementText() == QLatin1String("false"))
- m_enableFilterFunctionality = false;
- } else if (name() == QLatin1String("enableDocumentationManager")) {
- if (readElementText() == QLatin1String("false"))
- m_enableDocumentationManager = false;
- } else if (name() == QLatin1String("enableAddressBar")) {
- if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
- m_hideAddressBar = false;
- if (readElementText() == QLatin1String("false"))
- m_enableAddressBar = false;
- } else if (name() == QLatin1String("aboutMenuText")) {
- readMenuTexts();
- } else if (name() == QLatin1String("aboutDialog")) {
- readAboutDialog();
- } else if (name() == "cacheDirectory") {
- m_cacheDirRelativeToCollection =
- attributes().value(QLatin1String("base"))
- == QLatin1String("collection");
- m_cacheDirectory = readElementText();
- } else if (name() == QLatin1String("enableFullTextSearchFallback")) {
- if (readElementText() == QLatin1String("true"))
- m_enableFullTextSearchFallback = true;
- } else {
- raiseErrorWithLine();
- }
- } else if (isEndElement() && name() == QLatin1String("assistant")) {
- break;
- }
- }
-}
-
-void CollectionConfigReader::readMenuTexts()
-{
- while (!atEnd())
- {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("text")) {
- QString lang = attributes().value(QLatin1String("language")).toString();
- if (lang.isEmpty())
- lang = QLatin1String("default");
- m_aboutMenuTexts.insert(lang, readElementText());
- } else {
- raiseErrorWithLine();
- }
- } else if (isEndElement() && name() == QLatin1String("aboutMenuText")) {
- break;
- }
- }
-}
-
-void CollectionConfigReader::readAboutDialog()
-{
- while (!atEnd())
- {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("file")) {
- QString lang = attributes().value(QLatin1String("language")).toString();
- if (lang.isEmpty())
- lang = QLatin1String("default");
- m_aboutTextFiles.insert(lang, readElementText());
- } else if (name() == QLatin1String("icon")) {
- m_aboutIcon = readElementText();
- } else {
- raiseErrorWithLine();
- }
- } else if (isEndElement() && name() == QLatin1String("aboutDialog")) {
- break;
- }
- }
-}
-
-void CollectionConfigReader::readDocFiles()
-{
- while (!atEnd()) {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("generate")) {
- readGenerate();
- } else if (name() == QLatin1String("register")) {
- readRegister();
- } else {
- raiseErrorWithLine();
- }
- } else if (isEndElement() && name() == QLatin1String("docFiles")) {
- break;
- }
- }
-}
-
-void CollectionConfigReader::readGenerate()
-{
- while (!atEnd()) {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("file"))
- readFiles();
- else
- raiseErrorWithLine();
- } else if (isEndElement() && name() == QLatin1String("generate")) {
- break;
- }
- }
-}
-
-void CollectionConfigReader::readFiles()
-{
- QString input;
- QString output;
- while (!atEnd()) {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("input"))
- input = readElementText();
- else if (name() == QLatin1String("output"))
- output = readElementText();
- else
- raiseErrorWithLine();
- } else if (isEndElement() && name() == QLatin1String("file")) {
- break;
- }
- }
- if (input.isEmpty() || output.isEmpty()) {
- raiseError(QCG::tr("Missing input or output file for help file generation."));
- return;
- }
- m_filesToGenerate.insert(input, output);
-}
-
-void CollectionConfigReader::readRegister()
-{
- while (!atEnd()) {
- readNext();
- if (isStartElement()) {
- if (name() == QLatin1String("file"))
- m_filesToRegister.append(readElementText());
- else
- raiseErrorWithLine();
- } else if (isEndElement() && name() == QLatin1String("register")) {
- break;
- }
- }
-}
-
-namespace {
- QString absoluteFileName(const QString &basePath, const QString &fileName)
- {
- return QFileInfo(fileName).isAbsolute() ?
- fileName : basePath + QDir::separator() + fileName;
- }
-}
-
-int main(int argc, char *argv[])
-{
- QString error;
- QString arg;
- QString collectionFile;
- QString configFile;
- QString basePath;
- bool showHelp = false;
- bool showVersion = false;
-
- // don't require a window manager even though we're a QGuiApplication
- qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("minimal"));
- QGuiApplication app(argc, argv);
-
-#ifndef Q_OS_WIN32
- QTranslator translator;
- QTranslator qtTranslator;
- QTranslator qt_helpTranslator;
- QString sysLocale = QLocale::system().name();
- QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
- if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
- && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
- && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
- app.installTranslator(&translator);
- app.installTranslator(&qtTranslator);
- app.installTranslator(&qt_helpTranslator);
- }
-#endif // Q_OS_WIN32
-
- for (int i=1; i<argc; ++i) {
- arg = QString::fromLocal8Bit(argv[i]);
- if (arg == QLatin1String("-o")) {
- if (++i < argc) {
- QFileInfo fi(QString::fromLocal8Bit(argv[i]));
- collectionFile = fi.absoluteFilePath();
- } else {
- error = QCG::tr("Missing output file name.");
- }
- } else if (arg == QLatin1String("-h")) {
- showHelp = true;
- } else if (arg == QLatin1String("-v")) {
- showVersion = true;
- } else {
- QFileInfo fi(arg);
- configFile = fi.absoluteFilePath();
- basePath = fi.absolutePath();
- }
- }
-
- if (showVersion) {
- fputs(qPrintable(QCG::tr("Qt Collection Generator version 1.0 (Qt %1)\n")
- .arg(QT_VERSION_STR)), stdout);
- return 0;
- }
-
- if (configFile.isEmpty() && !showHelp)
- error = QCG::tr("Missing collection config file.");
-
- QString help = QCG::tr("\nUsage:\n\n"
- "qcollectiongenerator <collection-config-file> [options]\n\n"
- " -o <collection-file> Generates a collection file\n"
- " called <collection-file>. If\n"
- " this option is not specified\n"
- " a default name will be used.\n"
- " -v Displays the version of\n"
- " qcollectiongenerator.\n\n");
-
- if (showHelp) {
- fputs(qPrintable(help), stdout);
- return 0;
- }else if (!error.isEmpty()) {
- fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
- return -1;
- }
-
- QFile file(configFile);
- if (!file.open(QIODevice::ReadOnly)) {
- fputs(qPrintable(QCG::tr("Could not open %1.\n").arg(configFile)), stderr);
- return -1;
- }
-
- if (collectionFile.isEmpty()) {
- QFileInfo fi(configFile);
- collectionFile = basePath + QDir::separator()
- + fi.baseName() + QLatin1String(".qhc");
- }
-
- fputs(qPrintable(QCG::tr("Reading collection config file...\n")), stdout);
- CollectionConfigReader config;
- config.readData(file.readAll());
- if (config.hasError()) {
- fputs(qPrintable(QCG::tr("Collection config file error: %1\n")
- .arg(config.errorString())), stderr);
- return -1;
- }
-
- const QMap<QString, QString> &filesToGenerate = config.filesToGenerate();
- for (auto it = filesToGenerate.cbegin(), end = filesToGenerate.cend(); it != end; ++it) {
- fputs(qPrintable(QCG::tr("Generating help for %1...\n").arg(it.key())), stdout);
- QHelpProjectData helpData;
- if (!helpData.readData(absoluteFileName(basePath, it.key()))) {
- fprintf(stderr, "%s\n", qPrintable(helpData.errorMessage()));
- return -1;
- }
-
- HelpGenerator helpGenerator;
- if (!helpGenerator.generate(&helpData, absoluteFileName(basePath, it.value()))) {
- fprintf(stderr, "%s\n", qPrintable(helpGenerator.error()));
- return -1;
- }
- }
-
- fputs(qPrintable(QCG::tr("Creating collection file...\n")), stdout);
-
- QFileInfo colFi(collectionFile);
- if (colFi.exists()) {
- if (!colFi.dir().remove(colFi.fileName())) {
- fputs(qPrintable(QCG::tr("The file %1 cannot be overwritten.\n")
- .arg(collectionFile)), stderr);
- return -1;
- }
- }
-
- QHelpEngineCore helpEngine(collectionFile);
- if (!helpEngine.setupData()) {
- fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
- return -1;
- }
-
- for (const QString &file : config.filesToRegister()) {
- if (!helpEngine.registerDocumentation(absoluteFileName(basePath, file))) {
- fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
- return -1;
- }
- }
- if (!config.filesToRegister().isEmpty()) {
- if (Q_UNLIKELY(qEnvironmentVariableIsSet("SOURCE_DATE_EPOCH"))) {
- QDateTime dt;
- dt.setSecsSinceEpoch(qEnvironmentVariableIntValue("SOURCE_DATE_EPOCH"));
- CollectionConfiguration::updateLastRegisterTime(helpEngine, dt);
- } else {
- CollectionConfiguration::updateLastRegisterTime(helpEngine);
- }
- }
-
- if (!config.title().isEmpty())
- CollectionConfiguration::setWindowTitle(helpEngine, config.title());
-
- if (!config.homePage().isEmpty()) {
- CollectionConfiguration::setDefaultHomePage(helpEngine,
- config.homePage());
- }
-
- if (!config.startPage().isEmpty()) {
- CollectionConfiguration::setLastShownPages(helpEngine,
- QStringList(config.startPage()));
- }
-
- if (!config.currentFilter().isEmpty()) {
- helpEngine.setCurrentFilter(config.currentFilter());
- }
-
- if (!config.cacheDirectory().isEmpty()) {
- CollectionConfiguration::setCacheDir(helpEngine, config.cacheDirectory(),
- config.cacheDirRelativeToCollection());
- }
-
- CollectionConfiguration::setFilterFunctionalityEnabled(helpEngine,
- config.enableFilterFunctionality());
- CollectionConfiguration::setFilterToolbarVisible(helpEngine,
- !config.hideFilterFunctionality());
- CollectionConfiguration::setDocumentationManagerEnabled(helpEngine,
- config.enableDocumentationManager());
- CollectionConfiguration::setAddressBarEnabled(helpEngine,
- config.enableAddressBar());
- CollectionConfiguration::setAddressBarVisible(helpEngine,
- !config.hideAddressBar());
- uint time = QDateTime::currentMSecsSinceEpoch() / 1000;
- if (Q_UNLIKELY(qEnvironmentVariableIsSet("SOURCE_DATE_EPOCH")))
- time = qEnvironmentVariableIntValue("SOURCE_DATE_EPOCH");
- CollectionConfiguration::setCreationTime(helpEngine, time);
- CollectionConfiguration::setFullTextSearchFallbackEnabled(helpEngine,
- config.fullTextSearchFallbackEnabled());
-
- if (!config.applicationIcon().isEmpty()) {
- QFile icon(absoluteFileName(basePath, config.applicationIcon()));
- if (!icon.open(QIODevice::ReadOnly)) {
- fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
- return -1;
- }
- CollectionConfiguration::setApplicationIcon(helpEngine, icon.readAll());
- }
-
- if (config.aboutMenuTexts().count()) {
- QByteArray ba;
- QDataStream s(&ba, QIODevice::WriteOnly);
- const QMap<QString, QString> &aboutMenuTexts = config.aboutMenuTexts();
- for (auto it = aboutMenuTexts.cbegin(), end = aboutMenuTexts.cend(); it != end; ++it)
- s << it.key() << it.value();
- CollectionConfiguration::setAboutMenuTexts(helpEngine, ba);
- }
-
- if (!config.aboutIcon().isEmpty()) {
- QFile icon(absoluteFileName(basePath, config.aboutIcon()));
- if (!icon.open(QIODevice::ReadOnly)) {
- fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
- return -1;
- }
- CollectionConfiguration::setAboutIcon(helpEngine, icon.readAll());
- }
-
- if (config.aboutTextFiles().count()) {
- QByteArray ba;
- QDataStream s(&ba, QIODevice::WriteOnly);
- QMap<QString, QByteArray> imgData;
-
- QRegExp srcRegExp(QLatin1String("src=(\"(.+)\"|([^\"\\s]+)).*>"));
- srcRegExp.setMinimal(true);
- QRegExp imgRegExp(QLatin1String("(<img[^>]+>)"));
- imgRegExp.setMinimal(true);
-
- const QMap<QString, QString> &aboutMenuTexts = config.aboutTextFiles();
- for (auto it = aboutMenuTexts.cbegin(), end = aboutMenuTexts.cend(); it != end; ++it) {
- s << it.key();
- QFileInfo fi(absoluteFileName(basePath, it.value()));
- QFile f(fi.absoluteFilePath());
- if (!f.open(QIODevice::ReadOnly)) {
- fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(f.fileName())), stderr);
- return -1;
- }
- QByteArray data = f.readAll();
- s << data;
-
- QString contents = QString::fromUtf8(data);
- int pos = 0;
- while ((pos = imgRegExp.indexIn(contents, pos)) != -1) {
- QString imgTag = imgRegExp.cap(1);
- pos += imgRegExp.matchedLength();
-
- if (srcRegExp.indexIn(imgTag, 0) != -1) {
- QString src = srcRegExp.cap(2);
- if (src.isEmpty())
- src = srcRegExp.cap(3);
-
- QFile img(fi.absolutePath() + QDir::separator() + src);
- if (img.open(QIODevice::ReadOnly)) {
- if (!imgData.contains(src))
- imgData.insert(src, img.readAll());
- } else {
- fputs(qPrintable(QCG::tr("Cannot open referenced image file %1.\n")
- .arg(img.fileName())), stderr);
- }
- }
- }
- }
- CollectionConfiguration::setAboutTexts(helpEngine, ba);
- if (imgData.count()) {
- QByteArray imageData;
- QBuffer buffer(&imageData);
- buffer.open(QIODevice::WriteOnly);
- QDataStream out(&buffer);
- out << imgData;
- CollectionConfiguration::setAboutImages(helpEngine, imageData);
- }
- }
-
- return 0;
-}
diff --git a/src/assistant/qcollectiongenerator/qcollectiongenerator.pro b/src/assistant/qcollectiongenerator/qcollectiongenerator.pro
deleted file mode 100644
index cf9b9a257..000000000
--- a/src/assistant/qcollectiongenerator/qcollectiongenerator.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-QT += network help-private
-TARGET = qcollectiongenerator
-SOURCES += ../shared/helpgenerator.cpp \
- main.cpp \
- ../shared/collectionconfiguration.cpp
-HEADERS += ../shared/helpgenerator.h \
- ../shared/collectionconfiguration.h
-QTPLUGIN.platforms = qminimal
-
-QMAKE_TARGET_DESCRIPTION = "Qt Help Collection File Generator"
-load(qt_tool)
diff --git a/src/assistant/qhelpgenerator/collectionconfigreader.cpp b/src/assistant/qhelpgenerator/collectionconfigreader.cpp
new file mode 100644
index 000000000..155430c9c
--- /dev/null
+++ b/src/assistant/qhelpgenerator/collectionconfigreader.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "collectionconfigreader.h"
+
+#include <QtGui/QGuiApplication>
+
+class QCG {
+ Q_DECLARE_TR_FUNCTIONS(QCollectionGenerator)
+};
+
+void CollectionConfigReader::raiseErrorWithLine()
+{
+ raiseError(QCG::tr("Unknown token at line %1.").arg(lineNumber()));
+}
+
+void CollectionConfigReader::readData(const QByteArray &contents)
+{
+ m_enableFilterFunctionality = true;
+ m_hideFilterFunctionality = true;
+ m_enableAddressBar = true;
+ m_hideAddressBar = true;
+ m_enableDocumentationManager = true;
+ m_enableFullTextSearchFallback = false;
+
+ addData(contents);
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("QHelpCollectionProject")
+ && attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
+ readConfig();
+ else
+ raiseError(QCG::tr("Unknown token at line %1. "
+ "Expected \"QtHelpCollectionProject\".")
+ .arg(lineNumber()));
+ }
+ }
+}
+
+void CollectionConfigReader::readConfig()
+{
+ bool ok = false;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("assistant"))
+ readAssistantSettings();
+ else if (name() == QLatin1String("docFiles"))
+ readDocFiles();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("QHelpCollectionProject")) {
+ ok = true;
+ }
+ }
+ if (!ok && !hasError())
+ raiseError(QCG::tr("Missing end tags."));
+}
+
+void CollectionConfigReader::readAssistantSettings()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("title")) {
+ m_title = readElementText();
+ } else if (name() == QLatin1String("homePage")) {
+ m_homePage = readElementText();
+ } else if (name() == QLatin1String("startPage")) {
+ m_startPage = readElementText();
+ } else if (name() == QLatin1String("currentFilter")) {
+ m_currentFilter = readElementText();
+ } else if (name() == QLatin1String("applicationIcon")) {
+ m_applicationIcon = readElementText();
+ } else if (name() == QLatin1String("enableFilterFunctionality")) {
+ if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
+ m_hideFilterFunctionality = false;
+ if (readElementText() == QLatin1String("false"))
+ m_enableFilterFunctionality = false;
+ } else if (name() == QLatin1String("enableDocumentationManager")) {
+ if (readElementText() == QLatin1String("false"))
+ m_enableDocumentationManager = false;
+ } else if (name() == QLatin1String("enableAddressBar")) {
+ if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
+ m_hideAddressBar = false;
+ if (readElementText() == QLatin1String("false"))
+ m_enableAddressBar = false;
+ } else if (name() == QLatin1String("aboutMenuText")) {
+ readMenuTexts();
+ } else if (name() == QLatin1String("aboutDialog")) {
+ readAboutDialog();
+ } else if (name() == "cacheDirectory") {
+ m_cacheDirRelativeToCollection =
+ attributes().value(QLatin1String("base"))
+ == QLatin1String("collection");
+ m_cacheDirectory = readElementText();
+ } else if (name() == QLatin1String("enableFullTextSearchFallback")) {
+ if (readElementText() == QLatin1String("true"))
+ m_enableFullTextSearchFallback = true;
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("assistant")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readMenuTexts()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("text")) {
+ QString lang = attributes().value(QLatin1String("language")).toString();
+ if (lang.isEmpty())
+ lang = QLatin1String("default");
+ m_aboutMenuTexts.insert(lang, readElementText());
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("aboutMenuText")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readAboutDialog()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file")) {
+ QString lang = attributes().value(QLatin1String("language")).toString();
+ if (lang.isEmpty())
+ lang = QLatin1String("default");
+ m_aboutTextFiles.insert(lang, readElementText());
+ } else if (name() == QLatin1String("icon")) {
+ m_aboutIcon = readElementText();
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("aboutDialog")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readDocFiles()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("generate")) {
+ readGenerate();
+ } else if (name() == QLatin1String("register")) {
+ readRegister();
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("docFiles")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readGenerate()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ readFiles();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("generate")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readFiles()
+{
+ QString input;
+ QString output;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("input"))
+ input = readElementText();
+ else if (name() == QLatin1String("output"))
+ output = readElementText();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("file")) {
+ break;
+ }
+ }
+ if (input.isEmpty() || output.isEmpty()) {
+ raiseError(QCG::tr("Missing input or output file for help file generation."));
+ return;
+ }
+ m_filesToGenerate.insert(input, output);
+}
+
+void CollectionConfigReader::readRegister()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ m_filesToRegister.append(readElementText());
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("register")) {
+ break;
+ }
+ }
+}
+
+
diff --git a/src/assistant/qhelpgenerator/collectionconfigreader.h b/src/assistant/qhelpgenerator/collectionconfigreader.h
new file mode 100644
index 000000000..eaf332b6b
--- /dev/null
+++ b/src/assistant/qhelpgenerator/collectionconfigreader.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 COLLECTIONCONFIGREADER_H
+#define COLLECTIONCONFIGREADER_H
+
+#include <QtCore/QMap>
+#include <QtCore/QObject>
+#include <QtCore/QXmlStreamReader>
+
+QT_USE_NAMESPACE
+
+class CollectionConfigReader : public QXmlStreamReader
+{
+public:
+ void readData(const QByteArray &contents);
+
+ QString title() const { return m_title; }
+ QString homePage() const { return m_homePage; }
+ QString startPage() const { return m_startPage; }
+ QString applicationIcon() const { return m_applicationIcon; }
+ QString currentFilter() const { return m_currentFilter; }
+ bool enableFilterFunctionality() const
+ { return m_enableFilterFunctionality; }
+ bool hideFilterFunctionality() const
+ { return m_hideFilterFunctionality; }
+ bool enableAddressBar() const { return m_enableAddressBar; }
+ bool hideAddressBar() const { return m_hideAddressBar; }
+ bool enableDocumentationManager() const
+ { return m_enableDocumentationManager; }
+
+ QMap<QString, QString> aboutMenuTexts() const
+ { return m_aboutMenuTexts; }
+ QString aboutIcon() const { return m_aboutIcon; }
+ QMap<QString, QString> aboutTextFiles() const
+ { return m_aboutTextFiles; }
+
+ QMap<QString, QString> filesToGenerate() const
+ { return m_filesToGenerate; }
+
+ QStringList filesToRegister() const { return m_filesToRegister; }
+
+ QString cacheDirectory() const { return m_cacheDirectory; }
+ bool cacheDirRelativeToCollection() const { return m_cacheDirRelativeToCollection; }
+
+ bool fullTextSearchFallbackEnabled() const {
+ return m_enableFullTextSearchFallback;
+ }
+
+private:
+ void raiseErrorWithLine();
+ void readConfig();
+ void readAssistantSettings();
+ void readMenuTexts();
+ void readAboutDialog();
+ void readDocFiles();
+ void readGenerate();
+ void readFiles();
+ void readRegister();
+
+ QMap<QString, QString> m_aboutMenuTexts;
+ QMap<QString, QString> m_aboutTextFiles;
+ QMap<QString, QString> m_filesToGenerate;
+ QStringList m_filesToRegister;
+ QString m_title;
+ QString m_homePage;
+ QString m_startPage;
+ QString m_applicationIcon;
+ QString m_currentFilter;
+ QString m_aboutIcon;
+ QString m_cacheDirectory;
+ bool m_enableFilterFunctionality;
+ bool m_hideFilterFunctionality;
+ bool m_enableAddressBar;
+ bool m_hideAddressBar;
+ bool m_enableDocumentationManager;
+ bool m_cacheDirRelativeToCollection;
+ bool m_enableFullTextSearchFallback;
+};
+
+#endif
diff --git a/src/assistant/qhelpgenerator/main.cpp b/src/assistant/qhelpgenerator/main.cpp
index a93f4a258..bca4ec248 100644
--- a/src/assistant/qhelpgenerator/main.cpp
+++ b/src/assistant/qhelpgenerator/main.cpp
@@ -26,14 +26,20 @@
**
****************************************************************************/
+#include "../shared/collectionconfiguration.h"
#include "../shared/helpgenerator.h"
+#include "collectionconfigreader.h"
+#include <QtCore/QBuffer>
+#include <QtCore/QDataStream>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
-#include <QtGui/QGuiApplication>
-#include <QtCore/QTranslator>
-#include <QtCore/QLocale>
#include <QtCore/QLibraryInfo>
+#include <QtCore/QTranslator>
+
+#include <QtGui/QGuiApplication>
+
+#include <QtHelp/QHelpEngineCore>
#include <private/qhelpprojectdata_p.h>
@@ -43,12 +49,207 @@ class QHG {
Q_DECLARE_TR_FUNCTIONS(QHelpGenerator)
};
+static const char QHP[] = "qhp";
+static const char QCH[] = "qch";
+
+static const char QHCP[] = "qhcp";
+static const char QHC[] = "qhc";
+
+namespace {
+ QString absoluteFilePath(const QString &basePath, const QString &fileName)
+ {
+ return QDir(basePath).absoluteFilePath(fileName);
+ }
+}
+
+int generateCollectionFile(const QByteArray &data, const QString &basePath, const QString outputFile)
+{
+ fputs(qPrintable(QHG::tr("Reading collection config file...\n")), stdout);
+ CollectionConfigReader config;
+ config.readData(data);
+ if (config.hasError()) {
+ fputs(qPrintable(QHG::tr("Collection config file error: %1\n")
+ .arg(config.errorString())), stderr);
+ return -1;
+ }
+
+ const QMap<QString, QString> &filesToGenerate = config.filesToGenerate();
+ for (auto it = filesToGenerate.cbegin(), end = filesToGenerate.cend(); it != end; ++it) {
+ fputs(qPrintable(QHG::tr("Generating help for %1...\n").arg(it.key())), stdout);
+ QHelpProjectData helpData;
+ if (!helpData.readData(absoluteFilePath(basePath, it.key()))) {
+ fprintf(stderr, "%s\n", qPrintable(helpData.errorMessage()));
+ return -1;
+ }
+
+ HelpGenerator helpGenerator;
+ if (!helpGenerator.generate(&helpData, absoluteFilePath(basePath, it.value()))) {
+ fprintf(stderr, "%s\n", qPrintable(helpGenerator.error()));
+ return -1;
+ }
+ }
+
+ fputs(qPrintable(QHG::tr("Creating collection file...\n")), stdout);
+
+ QFileInfo colFi(outputFile);
+ if (colFi.exists()) {
+ if (!colFi.dir().remove(colFi.fileName())) {
+ fputs(qPrintable(QHG::tr("The file %1 cannot be overwritten.\n")
+ .arg(outputFile)), stderr);
+ return -1;
+ }
+ }
+
+ QHelpEngineCore helpEngine(outputFile);
+ if (!helpEngine.setupData()) {
+ fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
+ return -1;
+ }
+
+ for (const QString &file : config.filesToRegister()) {
+ if (!helpEngine.registerDocumentation(absoluteFilePath(basePath, file))) {
+ fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
+ return -1;
+ }
+ }
+ if (!config.filesToRegister().isEmpty()) {
+ if (Q_UNLIKELY(qEnvironmentVariableIsSet("SOURCE_DATE_EPOCH"))) {
+ QDateTime dt;
+ dt.setSecsSinceEpoch(qEnvironmentVariableIntValue("SOURCE_DATE_EPOCH"));
+ CollectionConfiguration::updateLastRegisterTime(helpEngine, dt);
+ } else {
+ CollectionConfiguration::updateLastRegisterTime(helpEngine);
+ }
+ }
+
+ if (!config.title().isEmpty())
+ CollectionConfiguration::setWindowTitle(helpEngine, config.title());
+
+ if (!config.homePage().isEmpty()) {
+ CollectionConfiguration::setDefaultHomePage(helpEngine,
+ config.homePage());
+ }
+
+ if (!config.startPage().isEmpty()) {
+ CollectionConfiguration::setLastShownPages(helpEngine,
+ QStringList(config.startPage()));
+ }
+
+ if (!config.currentFilter().isEmpty()) {
+ helpEngine.setCurrentFilter(config.currentFilter());
+ }
+
+ if (!config.cacheDirectory().isEmpty()) {
+ CollectionConfiguration::setCacheDir(helpEngine, config.cacheDirectory(),
+ config.cacheDirRelativeToCollection());
+ }
+
+ CollectionConfiguration::setFilterFunctionalityEnabled(helpEngine,
+ config.enableFilterFunctionality());
+ CollectionConfiguration::setFilterToolbarVisible(helpEngine,
+ !config.hideFilterFunctionality());
+ CollectionConfiguration::setDocumentationManagerEnabled(helpEngine,
+ config.enableDocumentationManager());
+ CollectionConfiguration::setAddressBarEnabled(helpEngine,
+ config.enableAddressBar());
+ CollectionConfiguration::setAddressBarVisible(helpEngine,
+ !config.hideAddressBar());
+ uint time = QDateTime::currentMSecsSinceEpoch() / 1000;
+ if (Q_UNLIKELY(qEnvironmentVariableIsSet("SOURCE_DATE_EPOCH")))
+ time = qEnvironmentVariableIntValue("SOURCE_DATE_EPOCH");
+ CollectionConfiguration::setCreationTime(helpEngine, time);
+ CollectionConfiguration::setFullTextSearchFallbackEnabled(helpEngine,
+ config.fullTextSearchFallbackEnabled());
+
+ if (!config.applicationIcon().isEmpty()) {
+ QFile icon(absoluteFilePath(basePath, config.applicationIcon()));
+ if (!icon.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QHG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
+ return -1;
+ }
+ CollectionConfiguration::setApplicationIcon(helpEngine, icon.readAll());
+ }
+
+ if (config.aboutMenuTexts().count()) {
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ const QMap<QString, QString> &aboutMenuTexts = config.aboutMenuTexts();
+ for (auto it = aboutMenuTexts.cbegin(), end = aboutMenuTexts.cend(); it != end; ++it)
+ s << it.key() << it.value();
+ CollectionConfiguration::setAboutMenuTexts(helpEngine, ba);
+ }
+
+ if (!config.aboutIcon().isEmpty()) {
+ QFile icon(absoluteFilePath(basePath, config.aboutIcon()));
+ if (!icon.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QHG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
+ return -1;
+ }
+ CollectionConfiguration::setAboutIcon(helpEngine, icon.readAll());
+ }
+
+ if (config.aboutTextFiles().count()) {
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ QMap<QString, QByteArray> imgData;
+
+ QRegExp srcRegExp(QLatin1String("src=(\"(.+)\"|([^\"\\s]+)).*>"));
+ srcRegExp.setMinimal(true);
+ QRegExp imgRegExp(QLatin1String("(<img[^>]+>)"));
+ imgRegExp.setMinimal(true);
+
+ const QMap<QString, QString> &aboutMenuTexts = config.aboutTextFiles();
+ for (auto it = aboutMenuTexts.cbegin(), end = aboutMenuTexts.cend(); it != end; ++it) {
+ s << it.key();
+ QFileInfo fi(absoluteFilePath(basePath, it.value()));
+ QFile f(fi.absoluteFilePath());
+ if (!f.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QHG::tr("Cannot open %1.\n").arg(f.fileName())), stderr);
+ return -1;
+ }
+ QByteArray data = f.readAll();
+ s << data;
+
+ QString contents = QString::fromUtf8(data);
+ int pos = 0;
+ while ((pos = imgRegExp.indexIn(contents, pos)) != -1) {
+ QString imgTag = imgRegExp.cap(1);
+ pos += imgRegExp.matchedLength();
+
+ if (srcRegExp.indexIn(imgTag, 0) != -1) {
+ QString src = srcRegExp.cap(2);
+ if (src.isEmpty())
+ src = srcRegExp.cap(3);
+
+ QFile img(fi.absolutePath() + QDir::separator() + src);
+ if (img.open(QIODevice::ReadOnly)) {
+ if (!imgData.contains(src))
+ imgData.insert(src, img.readAll());
+ } else {
+ fputs(qPrintable(QHG::tr("Cannot open referenced image file %1.\n")
+ .arg(img.fileName())), stderr);
+ }
+ }
+ }
+ }
+ CollectionConfiguration::setAboutTexts(helpEngine, ba);
+ if (imgData.count()) {
+ QByteArray imageData;
+ QBuffer buffer(&imageData);
+ buffer.open(QIODevice::WriteOnly);
+ QDataStream out(&buffer);
+ out << imgData;
+ CollectionConfiguration::setAboutImages(helpEngine, imageData);
+ }
+ }
+ return 0;
+}
+
int main(int argc, char *argv[])
{
QString error;
- QString arg;
- QString compressedFile;
- QString projectFile;
+ QString outputFile;
+ QString inputFile;
QString basePath;
bool showHelp = false;
bool showVersion = false;
@@ -75,11 +276,11 @@ int main(int argc, char *argv[])
#endif // Q_OS_WIN32
for (int i = 1; i < argc; ++i) {
- arg = QString::fromLocal8Bit(argv[i]);
+ const QString arg = QString::fromLocal8Bit(argv[i]);
if (arg == QLatin1String("-o")) {
if (++i < argc) {
QFileInfo fi(QString::fromLocal8Bit(argv[i]));
- compressedFile = fi.absoluteFilePath();
+ outputFile = fi.absoluteFilePath();
} else {
error = QHG::tr("Missing output file name.");
}
@@ -92,8 +293,8 @@ int main(int argc, char *argv[])
} else if (arg == QLatin1String("-s")) {
silent = true;
} else {
- QFileInfo fi(arg);
- projectFile = fi.absoluteFilePath();
+ const QFileInfo fi(arg);
+ inputFile = fi.absoluteFilePath();
basePath = fi.absolutePath();
}
}
@@ -104,15 +305,40 @@ int main(int argc, char *argv[])
return 0;
}
- if (projectFile.isEmpty() && !showHelp)
- error = QHG::tr("Missing Qt help project file.");
+ enum InputType {
+ InputQhp,
+ InputQhcp,
+ InputUnknown
+ };
+
+ InputType inputType = InputUnknown;
+
+ if (!showHelp) {
+ if (inputFile.isEmpty()) {
+ error = QHG::tr("Missing input file name.");
+ } else {
+ const QFileInfo fi(inputFile);
+ if (fi.suffix() == QHP)
+ inputType = InputQhp;
+ else if (fi.suffix() == QHCP)
+ inputType = InputQhcp;
+
+ if (inputType == InputUnknown)
+ error = QHG::tr("Unknown input file type.");
+ }
+ }
- QString help = QHG::tr("\nUsage:\n\n"
- "qhelpgenerator <help-project-file> [options]\n\n"
- " -o <compressed-file> Generates a Qt compressed help\n"
- " file called <compressed-file>.\n"
+ const QString help = QHG::tr("\nUsage:\n\n"
+ "qhelpgenerator <file> [options]\n\n"
+ " -o <output-file> Generates a Qt compressed help\n"
+ " called <output-file> (*.qch) for the\n"
+ " Qt help project <file> (*.qhp).\n"
+ " Generates a Qt help collection\n"
+ " called <output-file> (*.qhc) for the\n"
+ " Qt help collection project <file> (*.qhcp).\n"
" If this option is not specified\n"
- " a default name will be used.\n"
+ " a default name will be used\n"
+ " (*.qch for *.qhp and *.qhc for *.qhcp).\n"
" -c Checks whether all links in HTML files\n"
" point to files in this help project.\n"
" -s Suppresses status messages.\n"
@@ -122,26 +348,30 @@ int main(int argc, char *argv[])
if (showHelp) {
fputs(qPrintable(help), stdout);
return 0;
- }else if (!error.isEmpty()) {
+ } else if (!error.isEmpty()) {
fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
return -1;
}
- QFile file(projectFile);
+ // detect input file type (qhp or qhcp)
+
+ QFile file(inputFile);
if (!file.open(QIODevice::ReadOnly)) {
- fputs(qPrintable(QHG::tr("Could not open %1.\n").arg(projectFile)), stderr);
+ fputs(qPrintable(QHG::tr("Could not open %1.\n").arg(inputFile)), stderr);
return -1;
}
- if (compressedFile.isEmpty()) {
- if (!checkLinks) {
- QFileInfo fi(projectFile);
- compressedFile = basePath + QDir::separator()
- + fi.baseName() + QLatin1String(".qch");
+ const QString outputExtension = inputType == InputQhp ? QCH : QHC;
+
+ if (outputFile.isEmpty()) {
+ if (inputType == InputQhcp || !checkLinks) {
+ QFileInfo fi(inputFile);
+ outputFile = basePath + QDir::separator()
+ + fi.baseName() + QLatin1Char('.') + outputExtension;
}
} else {
// check if the output dir exists -- create if it doesn't
- QFileInfo fi(compressedFile);
+ QFileInfo fi(outputFile);
QDir parentDir = fi.dir();
if (!parentDir.exists()) {
if (!parentDir.mkpath(QLatin1String("."))) {
@@ -151,22 +381,29 @@ int main(int argc, char *argv[])
}
}
- QHelpProjectData *helpData = new QHelpProjectData();
- if (!helpData->readData(projectFile)) {
- fprintf(stderr, "%s\n", qPrintable(helpData->errorMessage()));
- return -1;
- }
+ if (inputType == InputQhp) {
+ QHelpProjectData *helpData = new QHelpProjectData();
+ if (!helpData->readData(inputFile)) {
+ fprintf(stderr, "%s\n", qPrintable(helpData->errorMessage()));
+ return -1;
+ }
+
+ HelpGenerator generator(silent);
+ bool success = true;
+ if (checkLinks)
+ success = generator.checkLinks(*helpData);
+ if (success && !outputFile.isEmpty())
+ success = generator.generate(helpData, outputFile);
+ delete helpData;
+ if (!success) {
+ fprintf(stderr, "%s\n", qPrintable(generator.error()));
+ return -1;
+ }
+ } else {
+ const QByteArray data = file.readAll();
+ return generateCollectionFile(data, basePath, outputFile);
- HelpGenerator generator(silent);
- bool success = true;
- if (checkLinks)
- success = generator.checkLinks(*helpData);
- if (success && !compressedFile.isEmpty())
- success = generator.generate(helpData, compressedFile);
- delete helpData;
- if (!success) {
- fprintf(stderr, "%s\n", qPrintable(generator.error()));
- return -1;
}
+
return 0;
}
diff --git a/src/assistant/qhelpgenerator/qhelpgenerator.pro b/src/assistant/qhelpgenerator/qhelpgenerator.pro
index d4e84a74f..0e7b08b48 100644
--- a/src/assistant/qhelpgenerator/qhelpgenerator.pro
+++ b/src/assistant/qhelpgenerator/qhelpgenerator.pro
@@ -2,10 +2,14 @@ QT += network help-private
QTPLUGIN.platforms = qminimal
-SOURCES += ../shared/helpgenerator.cpp \
+SOURCES += ../shared/collectionconfiguration.cpp \
+ ../shared/helpgenerator.cpp \
+ collectionconfigreader.cpp \
main.cpp
-HEADERS += ../shared/helpgenerator.h
+HEADERS += ../shared/collectionconfiguration.h \
+ ../shared/helpgenerator.h \
+ collectionconfigreader.h
QMAKE_TARGET_DESCRIPTION = "Qt Compressed Help File Generator"
load(qt_tool)