1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Assistant of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "helpdocsettings.h"
41
42#include <QtHelp/QCompressedHelpInfo>
43#include <QtHelp/QHelpEngineCore>
44#include <QtHelp/QHelpFilterEngine>
45
46#include <QtCore/QVersionNumber>
47
48#include <QtDebug>
49
50QT_BEGIN_NAMESPACE
51
52class HelpDocSettingsPrivate : public QSharedData
53{
54public:
55 HelpDocSettingsPrivate() = default;
56 HelpDocSettingsPrivate(const HelpDocSettingsPrivate &other) = default;
57 ~HelpDocSettingsPrivate() = default;
58
59 QMap<QString, QString> m_namespaceToComponent;
60 QMap<QString, QStringList> m_componentToNamespace;
61
62 QMap<QString, QVersionNumber> m_namespaceToVersion;
63 QMap<QVersionNumber, QStringList> m_versionToNamespace;
64
65 QMap<QString, QString> m_namespaceToFileName;
66 QMap<QString, QString> m_fileNameToNamespace;
67};
68
69
70HelpDocSettings::HelpDocSettings()
71 : d(new HelpDocSettingsPrivate)
72{
73}
74
75HelpDocSettings::HelpDocSettings(const HelpDocSettings &) = default;
76
77HelpDocSettings::HelpDocSettings(HelpDocSettings &&) = default;
78
79HelpDocSettings::~HelpDocSettings() = default;
80
81HelpDocSettings &HelpDocSettings::operator=(const HelpDocSettings &) = default;
82
83HelpDocSettings &HelpDocSettings::operator=(HelpDocSettings &&) = default;
84
85bool HelpDocSettings::addDocumentation(const QString &fileName)
86{
87 const QCompressedHelpInfo info = QCompressedHelpInfo::fromCompressedHelpFile(documentationFileName: fileName);
88
89 if (info.isNull())
90 return false;
91
92 const QString namespaceName = info.namespaceName();
93
94 if (d->m_namespaceToFileName.contains(akey: namespaceName))
95 return false;
96
97 if (d->m_fileNameToNamespace.contains(akey: fileName))
98 return false;
99
100 const QString component = info.component();
101 const QVersionNumber version = info.version();
102
103 d->m_namespaceToFileName.insert(akey: namespaceName, avalue: fileName);
104 d->m_fileNameToNamespace.insert(akey: fileName, avalue: namespaceName);
105
106 d->m_namespaceToComponent.insert(akey: namespaceName, avalue: component);
107 d->m_componentToNamespace[component].append(t: namespaceName);
108
109 d->m_namespaceToVersion.insert(akey: namespaceName, avalue: version);
110 d->m_versionToNamespace[version].append(t: namespaceName);
111
112 return true;
113}
114
115bool HelpDocSettings::removeDocumentation(const QString &namespaceName)
116{
117 if (namespaceName.isEmpty())
118 return false;
119
120 const QString fileName = d->m_namespaceToFileName.value(akey: namespaceName);
121 if (fileName.isEmpty())
122 return false;
123
124 const QString component = d->m_namespaceToComponent.value(akey: namespaceName);
125 const QVersionNumber version = d->m_namespaceToVersion.value(akey: namespaceName);
126
127 d->m_namespaceToComponent.remove(akey: namespaceName);
128 d->m_namespaceToVersion.remove(akey: namespaceName);
129 d->m_namespaceToFileName.remove(akey: namespaceName);
130 d->m_fileNameToNamespace.remove(akey: fileName);
131 d->m_componentToNamespace[component].removeOne(t: namespaceName);
132 if (d->m_componentToNamespace[component].isEmpty())
133 d->m_componentToNamespace.remove(akey: component);
134 d->m_versionToNamespace[version].removeOne(t: namespaceName);
135 if (d->m_versionToNamespace[version].isEmpty())
136 d->m_versionToNamespace.remove(akey: version);
137
138 return true;
139}
140
141QString HelpDocSettings::namespaceName(const QString &fileName) const
142{
143 return d->m_fileNameToNamespace.value(akey: fileName);
144}
145
146QStringList HelpDocSettings::components() const
147{
148 return d->m_componentToNamespace.keys();
149}
150
151QList<QVersionNumber> HelpDocSettings::versions() const
152{
153 return d->m_versionToNamespace.keys();
154}
155
156QStringList HelpDocSettings::namespaces() const
157{
158 return d->m_namespaceToFileName.keys();
159}
160
161QMap<QString, QString> HelpDocSettings::namespaceToFileName() const
162{
163 return d->m_namespaceToFileName;
164}
165
166HelpDocSettings HelpDocSettings::readSettings(QHelpEngineCore *helpEngine)
167{
168 QHelpFilterEngine *filterEngine = helpEngine->filterEngine();
169
170 HelpDocSettings docSettings;
171 docSettings.d->m_namespaceToComponent = filterEngine->namespaceToComponent();
172 docSettings.d->m_namespaceToVersion = filterEngine->namespaceToVersion();
173 for (auto it = docSettings.d->m_namespaceToComponent.constBegin();
174 it != docSettings.d->m_namespaceToComponent.constEnd(); ++it) {
175 const QString namespaceName = it.key();
176 const QString namespaceFileName = helpEngine->documentationFileName(namespaceName);
177 docSettings.d->m_namespaceToFileName.insert(akey: namespaceName, avalue: namespaceFileName);
178 docSettings.d->m_fileNameToNamespace.insert(akey: namespaceFileName, avalue: namespaceName);
179 docSettings.d->m_componentToNamespace[it.value()].append(t: namespaceName);
180 }
181 for (auto it = docSettings.d->m_namespaceToVersion.constBegin();
182 it != docSettings.d->m_namespaceToVersion.constEnd(); ++it) {
183 docSettings.d->m_versionToNamespace[it.value()].append(t: it.key());
184 }
185
186 return docSettings;
187}
188
189static QMap<QString, QString> subtract(const QMap<QString, QString> &minuend,
190 const QMap<QString, QString> &subtrahend)
191{
192 auto result = minuend;
193
194 for (auto itSubtrahend = subtrahend.cbegin(); itSubtrahend != subtrahend.cend(); ++itSubtrahend) {
195 auto itResult = result.find(akey: itSubtrahend.key());
196 if (itResult != result.end() && itSubtrahend.value() == itResult.value())
197 result.erase(it: itResult);
198 }
199
200 return result;
201}
202
203bool HelpDocSettings::applySettings(QHelpEngineCore *helpEngine,
204 const HelpDocSettings &settings)
205{
206 const HelpDocSettings oldSettings = readSettings(helpEngine);
207
208 const QMap<QString, QString> docsToRemove = subtract(
209 minuend: oldSettings.namespaceToFileName(),
210 subtrahend: settings.namespaceToFileName());
211 const QMap<QString, QString> docsToAdd = subtract(
212 minuend: settings.namespaceToFileName(),
213 subtrahend: oldSettings.namespaceToFileName());
214
215 bool changed = false;
216 for (const QString &namespaceName : docsToRemove.keys()) {
217 if (!helpEngine->unregisterDocumentation(namespaceName))
218 qWarning() << "Cannot unregister documentation:" << namespaceName;
219 changed = true;
220 }
221
222 for (const QString &fileName : docsToAdd.values()) {
223 if (!helpEngine->registerDocumentation(documentationFileName: fileName))
224 qWarning() << "Cannot register documentation file:" << fileName;
225 changed = true;
226 }
227
228 return changed;
229}
230
231QT_END_NAMESPACE
232

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