1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2018 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 "qhelpfilterengine.h" |
41 | #include "qhelpenginecore.h" |
42 | #include "qhelpfilterdata.h" |
43 | #include "qhelpdbreader_p.h" |
44 | #include "qhelpcollectionhandler_p.h" |
45 | |
46 | #include <QtCore/QThread> |
47 | #include <QtCore/QVersionNumber> |
48 | |
49 | QT_BEGIN_NAMESPACE |
50 | |
51 | static const char ActiveFilter[] = "activeFilter" ; |
52 | |
53 | class QHelpFilterEnginePrivate |
54 | { |
55 | public: |
56 | bool setup(); |
57 | |
58 | QHelpFilterEngine *q = nullptr; |
59 | QHelpEngineCore *m_helpEngine = nullptr; |
60 | QHelpCollectionHandler *m_collectionHandler = nullptr; |
61 | QString m_currentFilter; |
62 | bool m_needsSetup = true; |
63 | }; |
64 | |
65 | bool QHelpFilterEnginePrivate::setup() |
66 | { |
67 | if (!m_collectionHandler) |
68 | return false; |
69 | |
70 | if (!m_needsSetup) |
71 | return true; |
72 | |
73 | if (!m_helpEngine->setupData()) |
74 | return false; |
75 | |
76 | m_needsSetup = false; |
77 | |
78 | const QString filter = m_collectionHandler->customValue( |
79 | key: QLatin1String(ActiveFilter), defaultValue: QString()).toString(); |
80 | if (!filter.isEmpty() && m_collectionHandler->filters().contains(str: filter)) |
81 | m_currentFilter = filter; |
82 | |
83 | emit q->filterActivated(newFilter: m_currentFilter); |
84 | return true; |
85 | } |
86 | |
87 | ////////////// |
88 | |
89 | /*! |
90 | \class QHelpFilterEngine |
91 | \since 5.13 |
92 | \inmodule QtHelp |
93 | \brief The QHelpFilterEngine class provides a filtered view of the |
94 | help contents. |
95 | |
96 | The filter engine allows the management of filters associated with |
97 | a QHelpEngineCore instance. The help engine internally creates an |
98 | instance of the filter engine, which can be accessed by calling |
99 | QHelpEngineCore::filterEngine(). Therefore, the public constructor |
100 | of this class is disabled. |
101 | |
102 | The filters are identified by a filter name string. Filter details are |
103 | described by the \l QHelpFilterData class. |
104 | |
105 | The filter engine allows for adding new filters and changing the existing |
106 | filters' data through the setFilterData() method. An existing filter can |
107 | be removed through the removeFilter() method. |
108 | |
109 | Out of the registered filters one can be marked as the active one. |
110 | The active filter will be used by the associated help engine for returning |
111 | filtered results of many different functions, such as content, index, or |
112 | search results. If no filter is marked active, the help engine returns the |
113 | full results list available. |
114 | |
115 | The active filter is returned by activeFilter() and it can be changed by |
116 | setActiveFilter(). |
117 | |
118 | \sa QHelpEngineCore |
119 | */ |
120 | |
121 | /*! |
122 | \fn void QHelpFilterEngine::filterActivated(const QString &newFilter) |
123 | |
124 | This signal is emitted when the active filter is set. \a newFilter |
125 | specifies the name of the filter. |
126 | |
127 | \sa setActiveFilter() |
128 | */ |
129 | |
130 | /*! |
131 | \internal |
132 | Constructs the filter engine for \a helpEngine. |
133 | */ |
134 | QHelpFilterEngine::QHelpFilterEngine(QHelpEngineCore *helpEngine) |
135 | : QObject(helpEngine), |
136 | d(new QHelpFilterEnginePrivate) |
137 | { |
138 | d->q = this; |
139 | d->m_helpEngine = helpEngine; |
140 | } |
141 | |
142 | /*! |
143 | \internal |
144 | Destroys the existing filter engine. |
145 | */ |
146 | QHelpFilterEngine::~QHelpFilterEngine() |
147 | { |
148 | delete d; |
149 | } |
150 | |
151 | /*! |
152 | \internal |
153 | Sets the \a collectionHandler to be used for this filter engine. |
154 | */ |
155 | void QHelpFilterEngine::setCollectionHandler(QHelpCollectionHandler *collectionHandler) |
156 | { |
157 | d->m_collectionHandler = collectionHandler; |
158 | d->m_currentFilter = QString(); |
159 | d->m_needsSetup = true; |
160 | } |
161 | |
162 | /*! |
163 | Returns the map of all the available namespaces as keys |
164 | together with their associated components as values. |
165 | */ |
166 | QMap<QString, QString> QHelpFilterEngine::namespaceToComponent() const |
167 | { |
168 | if (!d->setup()) |
169 | return QMap<QString, QString>(); |
170 | return d->m_collectionHandler->namespaceToComponent(); |
171 | } |
172 | |
173 | /*! |
174 | Returns the map of all the available namespaces as keys |
175 | together with their associated versions as values. |
176 | */ |
177 | QMap<QString, QVersionNumber> QHelpFilterEngine::namespaceToVersion() const |
178 | { |
179 | if (!d->setup()) |
180 | return QMap<QString, QVersionNumber>(); |
181 | |
182 | return d->m_collectionHandler->namespaceToVersion(); |
183 | } |
184 | |
185 | /*! |
186 | Returns the list of all filter names defined inside the filter engine. |
187 | */ |
188 | QStringList QHelpFilterEngine::filters() const |
189 | { |
190 | if (!d->setup()) |
191 | return QStringList(); |
192 | return d->m_collectionHandler->filters(); |
193 | } |
194 | |
195 | /*! |
196 | Returns the list of all available components defined in all |
197 | registered documentation files. |
198 | */ |
199 | QStringList QHelpFilterEngine::availableComponents() const |
200 | { |
201 | if (!d->setup()) |
202 | return QStringList(); |
203 | return d->m_collectionHandler->availableComponents(); |
204 | } |
205 | |
206 | /*! |
207 | \since 5.15 |
208 | |
209 | Returns the list of all available versions defined in all |
210 | registered documentation files. |
211 | */ |
212 | QList<QVersionNumber> QHelpFilterEngine::availableVersions() const |
213 | { |
214 | if (!d->setup()) |
215 | return QList<QVersionNumber>(); |
216 | return d->m_collectionHandler->availableVersions(); |
217 | } |
218 | |
219 | /*! |
220 | Returns the filter details associated with \a filterName. |
221 | */ |
222 | QHelpFilterData QHelpFilterEngine::filterData(const QString &filterName) const |
223 | { |
224 | if (!d->setup()) |
225 | return QHelpFilterData(); |
226 | return d->m_collectionHandler->filterData(filterName); |
227 | } |
228 | |
229 | /*! |
230 | Changes the existing filter details of the filter identified by |
231 | \a filterName to \a filterData. If the filter does not exist, a |
232 | new filter is created. |
233 | |
234 | Returns \c true if setting the filter succeeded, otherwise returns \c false. |
235 | */ |
236 | bool QHelpFilterEngine::setFilterData(const QString &filterName, const QHelpFilterData &filterData) |
237 | { |
238 | if (!d->setup()) |
239 | return false; |
240 | return d->m_collectionHandler->setFilterData(filterName, filterData); |
241 | } |
242 | |
243 | /*! |
244 | Removes the filter identified by \a filterName. |
245 | |
246 | Returns \c true if removing the filter succeeded, otherwise returns |
247 | \c false. |
248 | */ |
249 | bool QHelpFilterEngine::removeFilter(const QString &filterName) |
250 | { |
251 | if (!d->setup()) |
252 | return false; |
253 | return d->m_collectionHandler->removeFilter(filterName); |
254 | } |
255 | |
256 | /*! |
257 | Returns the name of the currently active filter. |
258 | */ |
259 | QString QHelpFilterEngine::activeFilter() const |
260 | { |
261 | if (!d->setup()) |
262 | return QString(); |
263 | return d->m_currentFilter; |
264 | } |
265 | |
266 | /*! |
267 | Changes the currently active filter to \a filterName. |
268 | |
269 | Returns \c true if changing the filter succeeded, otherwise |
270 | returns \c false. |
271 | */ |
272 | bool QHelpFilterEngine::setActiveFilter(const QString &filterName) |
273 | { |
274 | if (!d->setup()) |
275 | return false; |
276 | |
277 | if (filterName == d->m_currentFilter) |
278 | return true; |
279 | |
280 | if (!filterName.isEmpty() && !d->m_collectionHandler->filters().contains(str: filterName)) |
281 | return false; |
282 | |
283 | d->m_currentFilter = filterName; |
284 | d->m_collectionHandler->setCustomValue(key: QLatin1String(ActiveFilter), |
285 | value: d->m_currentFilter); |
286 | |
287 | emit filterActivated(newFilter: d->m_currentFilter); |
288 | |
289 | return true; |
290 | } |
291 | |
292 | /*! |
293 | Returns the list of all registered documentation namespaces that match |
294 | the filter identified by \a filterName. |
295 | */ |
296 | QStringList QHelpFilterEngine::namespacesForFilter(const QString &filterName) const |
297 | { |
298 | if (!d->setup()) |
299 | return QStringList(); |
300 | return d->m_collectionHandler->namespacesForFilter(filterName); |
301 | } |
302 | |
303 | /*! |
304 | \since 5.15 |
305 | |
306 | Returns a sorted list of available indices. |
307 | The returned list contents depend on the active filter, and therefore only |
308 | the indices registered for the active filter will be returned. |
309 | */ |
310 | QStringList QHelpFilterEngine::indices() const |
311 | { |
312 | return indices(filterName: activeFilter()); |
313 | } |
314 | |
315 | /*! |
316 | \since 5.15 |
317 | |
318 | Returns a sorted list of available indices, filtered by \a filterName. |
319 | The returned list contents depend on the passed filter, and therefore only |
320 | the indices registered for this filter will be returned. |
321 | If you want to get all available indices unfiltered, |
322 | pass empty string as \a filterName. |
323 | */ |
324 | QStringList QHelpFilterEngine::indices(const QString &filterName) const |
325 | { |
326 | if (!d->setup()) |
327 | return QStringList(); |
328 | return d->m_collectionHandler->indicesForFilter(filterName); |
329 | } |
330 | |
331 | QT_END_NAMESPACE |
332 | |