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