1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "helpdocsettings.h"
5
6#include <QtHelp/QCompressedHelpInfo>
7#include <QtHelp/QHelpEngineCore>
8#include <QtHelp/QHelpFilterEngine>
9
10#include <QtCore/QVersionNumber>
11
12#include <QtDebug>
13
14QT_BEGIN_NAMESPACE
15
16class HelpDocSettingsPrivate : public QSharedData
17{
18public:
19 HelpDocSettingsPrivate() = default;
20 HelpDocSettingsPrivate(const HelpDocSettingsPrivate &other) = default;
21 ~HelpDocSettingsPrivate() = default;
22
23 QMap<QString, QString> m_namespaceToComponent;
24 QMap<QString, QStringList> m_componentToNamespace;
25
26 QMap<QString, QVersionNumber> m_namespaceToVersion;
27 QMap<QVersionNumber, QStringList> m_versionToNamespace;
28
29 QMap<QString, QString> m_namespaceToFileName;
30 QMap<QString, QString> m_fileNameToNamespace;
31};
32
33
34HelpDocSettings::HelpDocSettings()
35 : d(new HelpDocSettingsPrivate)
36{
37}
38
39HelpDocSettings::HelpDocSettings(const HelpDocSettings &) = default;
40
41HelpDocSettings::HelpDocSettings(HelpDocSettings &&) = default;
42
43HelpDocSettings::~HelpDocSettings() = default;
44
45HelpDocSettings &HelpDocSettings::operator=(const HelpDocSettings &) = default;
46
47HelpDocSettings &HelpDocSettings::operator=(HelpDocSettings &&) = default;
48
49bool HelpDocSettings::addDocumentation(const QString &fileName)
50{
51 const QCompressedHelpInfo info = QCompressedHelpInfo::fromCompressedHelpFile(documentationFileName: fileName);
52
53 if (info.isNull())
54 return false;
55
56 const QString namespaceName = info.namespaceName();
57
58 if (d->m_namespaceToFileName.contains(key: namespaceName))
59 return false;
60
61 if (d->m_fileNameToNamespace.contains(key: fileName))
62 return false;
63
64 const QString component = info.component();
65 const QVersionNumber version = info.version();
66
67 d->m_namespaceToFileName.insert(key: namespaceName, value: fileName);
68 d->m_fileNameToNamespace.insert(key: fileName, value: namespaceName);
69
70 d->m_namespaceToComponent.insert(key: namespaceName, value: component);
71 d->m_componentToNamespace[component].append(t: namespaceName);
72
73 d->m_namespaceToVersion.insert(key: namespaceName, value: version);
74 d->m_versionToNamespace[version].append(t: namespaceName);
75
76 return true;
77}
78
79bool HelpDocSettings::removeDocumentation(const QString &namespaceName)
80{
81 if (namespaceName.isEmpty())
82 return false;
83
84 const QString fileName = d->m_namespaceToFileName.value(key: namespaceName);
85 if (fileName.isEmpty())
86 return false;
87
88 const QString component = d->m_namespaceToComponent.value(key: namespaceName);
89 const QVersionNumber version = d->m_namespaceToVersion.value(key: namespaceName);
90
91 d->m_namespaceToComponent.remove(key: namespaceName);
92 d->m_namespaceToVersion.remove(key: namespaceName);
93 d->m_namespaceToFileName.remove(key: namespaceName);
94 d->m_fileNameToNamespace.remove(key: fileName);
95 d->m_componentToNamespace[component].removeOne(t: namespaceName);
96 if (d->m_componentToNamespace[component].isEmpty())
97 d->m_componentToNamespace.remove(key: component);
98 d->m_versionToNamespace[version].removeOne(t: namespaceName);
99 if (d->m_versionToNamespace[version].isEmpty())
100 d->m_versionToNamespace.remove(key: version);
101
102 return true;
103}
104
105QString HelpDocSettings::namespaceName(const QString &fileName) const
106{
107 return d->m_fileNameToNamespace.value(key: fileName);
108}
109
110QStringList HelpDocSettings::components() const
111{
112 return d->m_componentToNamespace.keys();
113}
114
115QList<QVersionNumber> HelpDocSettings::versions() const
116{
117 return d->m_versionToNamespace.keys();
118}
119
120QStringList HelpDocSettings::namespaces() const
121{
122 return d->m_namespaceToFileName.keys();
123}
124
125QMap<QString, QString> HelpDocSettings::namespaceToFileName() const
126{
127 return d->m_namespaceToFileName;
128}
129
130HelpDocSettings HelpDocSettings::readSettings(QHelpEngineCore *helpEngine)
131{
132 QHelpFilterEngine *filterEngine = helpEngine->filterEngine();
133
134 HelpDocSettings docSettings;
135 docSettings.d->m_namespaceToComponent = filterEngine->namespaceToComponent();
136 docSettings.d->m_namespaceToVersion = filterEngine->namespaceToVersion();
137 for (auto it = docSettings.d->m_namespaceToComponent.constBegin();
138 it != docSettings.d->m_namespaceToComponent.constEnd(); ++it) {
139 const QString namespaceName = it.key();
140 const QString namespaceFileName = helpEngine->documentationFileName(namespaceName);
141 docSettings.d->m_namespaceToFileName.insert(key: namespaceName, value: namespaceFileName);
142 docSettings.d->m_fileNameToNamespace.insert(key: namespaceFileName, value: namespaceName);
143 docSettings.d->m_componentToNamespace[it.value()].append(t: namespaceName);
144 }
145 for (auto it = docSettings.d->m_namespaceToVersion.constBegin();
146 it != docSettings.d->m_namespaceToVersion.constEnd(); ++it) {
147 docSettings.d->m_versionToNamespace[it.value()].append(t: it.key());
148 }
149
150 return docSettings;
151}
152
153static QMap<QString, QString> subtract(const QMap<QString, QString> &minuend,
154 const QMap<QString, QString> &subtrahend)
155{
156 auto result = minuend;
157
158 for (auto itSubtrahend = subtrahend.cbegin(); itSubtrahend != subtrahend.cend(); ++itSubtrahend) {
159 auto itResult = result.find(key: itSubtrahend.key());
160 if (itResult != result.end() && itSubtrahend.value() == itResult.value())
161 result.erase(it: itResult);
162 }
163
164 return result;
165}
166
167bool HelpDocSettings::applySettings(QHelpEngineCore *helpEngine,
168 const HelpDocSettings &settings)
169{
170 const HelpDocSettings oldSettings = readSettings(helpEngine);
171
172 const QMap<QString, QString> docsToRemove = subtract(
173 minuend: oldSettings.namespaceToFileName(),
174 subtrahend: settings.namespaceToFileName());
175 const QMap<QString, QString> docsToAdd = subtract(
176 minuend: settings.namespaceToFileName(),
177 subtrahend: oldSettings.namespaceToFileName());
178
179 bool changed = false;
180 for (const QString &namespaceName : docsToRemove.keys()) {
181 if (!helpEngine->unregisterDocumentation(namespaceName))
182 qWarning() << "Cannot unregister documentation:" << namespaceName;
183 changed = true;
184 }
185
186 for (const QString &fileName : docsToAdd.values()) {
187 if (!helpEngine->registerDocumentation(documentationFileName: fileName))
188 qWarning() << "Cannot register documentation file:" << fileName;
189 changed = true;
190 }
191
192 return changed;
193}
194
195QT_END_NAMESPACE
196

source code of qttools/src/assistant/assistant/helpdocsettings.cpp