1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 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 "qhelpenginecore.h"
41 #include "qhelpengine_p.h"
42 #include "qhelpdbreader_p.h"
43 #include "qhelpcollectionhandler_p.h"
44 #include "qhelpfilterengine.h"
45 
46 #include <QtCore/QDir>
47 #include <QtCore/QFile>
48 #include <QtCore/QPluginLoader>
49 #include <QtCore/QFileInfo>
50 #include <QtCore/QThread>
51 #include <QtHelp/QHelpLink>
52 #include <QtWidgets/QApplication>
53 #include <QtSql/QSqlQuery>
54 
55 QT_BEGIN_NAMESPACE
56 
init(const QString & collectionFile,QHelpEngineCore * helpEngineCore)57 void QHelpEngineCorePrivate::init(const QString &collectionFile,
58                                   QHelpEngineCore *helpEngineCore)
59 {
60     q = helpEngineCore;
61     collectionHandler = new QHelpCollectionHandler(collectionFile, helpEngineCore);
62     connect(collectionHandler, &QHelpCollectionHandler::error,
63             this, &QHelpEngineCorePrivate::errorReceived);
64     filterEngine->setCollectionHandler(collectionHandler);
65     needsSetup = true;
66 }
67 
~QHelpEngineCorePrivate()68 QHelpEngineCorePrivate::~QHelpEngineCorePrivate()
69 {
70     delete collectionHandler;
71 }
72 
setup()73 bool QHelpEngineCorePrivate::setup()
74 {
75     error.clear();
76     if (!needsSetup)
77         return true;
78 
79     needsSetup = false;
80     emit q->setupStarted();
81 
82     const QVariant readOnlyVariant = q->property("_q_readonly");
83     const bool readOnly = readOnlyVariant.isValid()
84             ? readOnlyVariant.toBool() : false;
85     collectionHandler->setReadOnly(readOnly);
86     const bool opened = collectionHandler->openCollectionFile();
87     if (opened)
88         q->currentFilter();
89 
90     emit q->setupFinished();
91 
92     return opened;
93 }
94 
errorReceived(const QString & msg)95 void QHelpEngineCorePrivate::errorReceived(const QString &msg)
96 {
97     error = msg;
98 }
99 
100 /*!
101     \class QHelpEngineCore
102     \since 4.4
103     \inmodule QtHelp
104     \brief The QHelpEngineCore class provides the core functionality
105     of the help system.
106 
107     Before the help engine can be used, it must be initialized by
108     calling setupData(). At the beginning of the setup process the
109     signal setupStarted() is emitted. From this point on until
110     the signal setupFinished() is emitted, is the help data in an
111     undefined meaning unusable state.
112 
113     The core help engine can be used to perform different tasks.
114     By calling documentsForIdentifier() the engine returns
115     URLs specifying the file locations inside the help system. The
116     actual file data can then be retrived by calling fileData().
117 
118     The help engine can contain any number of custom filters.
119     The management of the filters, including adding new filters,
120     changing filter definitions, or removing existing filters,
121     is done through the QHelpFilterEngine class, which can be accessed
122     by the filterEngine() method.
123 
124     \note QHelpFilterEngine replaces the older filter API that is
125     deprecated since Qt 5.13. Call setUsesFilterEngine() with \c true to
126     enable the new functionality.
127 
128     The help engine also offers the possibility to set and read values
129     in a persistent way comparable to ini files or Windows registry
130     entries. For more information see setValue() or value().
131 
132     This class does not offer any GUI components or functionality for
133     indices or contents. If you need one of those use QHelpEngine
134     instead.
135 
136     When creating a custom help viewer the viewer can be
137     configured by writing a custom collection file which could contain various
138     keywords to be used to configure the help engine. These keywords and values
139     and their meaning can be found in the help information for
140     \l{assistant-custom-help-viewer.html#creating-a-custom-help-collection-file}
141     {creating a custom help collection file} for Assistant.
142 */
143 
144 /*!
145     \fn void QHelpEngineCore::setupStarted()
146 
147     This signal is emitted when setup is started.
148 */
149 
150 /*!
151     \fn void QHelpEngineCore::setupFinished()
152 
153     This signal is emitted when the setup is complete.
154 */
155 
156 /*!
157     \fn void QHelpEngineCore::readersAboutToBeInvalidated()
158     \obsolete
159 */
160 
161 /*!
162     \fn void QHelpEngineCore::currentFilterChanged(const QString &newFilter)
163     \obsolete
164 
165     QHelpFilterEngine::filterActivated() should be used instead.
166 
167     This signal is emitted when the current filter is changed to
168     \a newFilter.
169 */
170 
171 /*!
172     \fn void QHelpEngineCore::warning(const QString &msg)
173 
174     This signal is emitted when a non critical error occurs.
175     The warning message is stored in \a msg.
176 */
177 
178 /*!
179     Constructs a new core help engine with a \a parent. The help engine
180     uses the information stored in the \a collectionFile to provide help.
181     If the collection file does not exist yet, it'll be created.
182 */
QHelpEngineCore(const QString & collectionFile,QObject * parent)183 QHelpEngineCore::QHelpEngineCore(const QString &collectionFile, QObject *parent)
184     : QObject(parent)
185 {
186     d = new QHelpEngineCorePrivate();
187     d->filterEngine = new QHelpFilterEngine(this);
188     d->init(collectionFile, this);
189 }
190 
191 /*!
192     \internal
193 */
QHelpEngineCore(QHelpEngineCorePrivate * helpEngineCorePrivate,QObject * parent)194 QHelpEngineCore::QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
195                                  QObject *parent)
196     : QObject(parent)
197 {
198     d = helpEngineCorePrivate;
199     d->filterEngine = new QHelpFilterEngine(this);
200 }
201 
202 /*!
203     Destructs the help engine.
204 */
~QHelpEngineCore()205 QHelpEngineCore::~QHelpEngineCore()
206 {
207     delete d;
208 }
209 
210 /*!
211     \property QHelpEngineCore::collectionFile
212     \brief the absolute file name of the collection file currently used.
213     \since 4.5
214 
215     Setting this property leaves the help engine in an invalid state. It is
216     important to invoke setupData() or any getter function in order to setup
217     the help engine again.
218 */
collectionFile() const219 QString QHelpEngineCore::collectionFile() const
220 {
221     return d->collectionHandler->collectionFile();
222 }
223 
setCollectionFile(const QString & fileName)224 void QHelpEngineCore::setCollectionFile(const QString &fileName)
225 {
226     if (fileName == collectionFile())
227         return;
228 
229     if (d->collectionHandler) {
230         delete d->collectionHandler;
231         d->collectionHandler = nullptr;
232     }
233     d->init(fileName, this);
234     d->needsSetup = true;
235 }
236 
237 /*!
238     \since 5.13
239 
240     Returns the filter engine associated with this help engine.
241     The filter engine allows for adding, changing, and removing existing
242     filters for this help engine. To use the engine you also have to call
243     \l setUsesFilterEngine() set to \c true.
244 */
filterEngine() const245 QHelpFilterEngine *QHelpEngineCore::filterEngine() const
246 {
247     return d->filterEngine;
248 }
249 
250 /*!
251     Sets up the help engine by processing the information found
252     in the collection file and returns true if successful; otherwise
253     returns false.
254 
255     By calling the function, the help
256     engine is forced to initialize itself immediately. Most of
257     the times, this function does not have to be called
258     explicitly because getter functions which depend on a correctly
259     set up help engine do that themselves.
260 
261     \note \c{qsqlite4.dll} needs to be deployed with the application as the
262     help system uses the sqlite driver when loading help collections.
263 */
setupData()264 bool QHelpEngineCore::setupData()
265 {
266     d->needsSetup = true;
267     return d->setup();
268 }
269 
270 /*!
271     Creates the file \a fileName and copies all contents from
272     the current collection file into the newly created file,
273     and returns true if successful; otherwise returns false.
274 
275     The copying process makes sure that file references to Qt
276     Collection files (\c{.qch}) files are updated accordingly.
277 */
copyCollectionFile(const QString & fileName)278 bool QHelpEngineCore::copyCollectionFile(const QString &fileName)
279 {
280     if (!d->setup())
281         return false;
282     return d->collectionHandler->copyCollectionFile(fileName);
283 }
284 
285 /*!
286     Returns the namespace name defined for the Qt compressed help file (.qch)
287     specified by its \a documentationFileName. If the file is not valid, an
288     empty string is returned.
289 
290     \sa documentationFileName()
291 */
namespaceName(const QString & documentationFileName)292 QString QHelpEngineCore::namespaceName(const QString &documentationFileName)
293 {
294     QHelpDBReader reader(documentationFileName,
295         QHelpGlobal::uniquifyConnectionName(QLatin1String("GetNamespaceName"),
296         QThread::currentThread()), nullptr);
297     if (reader.init())
298         return reader.namespaceName();
299     return QString();
300 }
301 
302 /*!
303     Registers the Qt compressed help file (.qch) contained in the file
304     \a documentationFileName. One compressed help file, uniquely
305     identified by its namespace can only be registered once.
306     True is returned if the registration was successful, otherwise
307     false.
308 
309     \sa unregisterDocumentation(), error()
310 */
registerDocumentation(const QString & documentationFileName)311 bool QHelpEngineCore::registerDocumentation(const QString &documentationFileName)
312 {
313     d->error.clear();
314     d->needsSetup = true;
315     return d->collectionHandler->registerDocumentation(documentationFileName);
316 }
317 
318 /*!
319     Unregisters the Qt compressed help file (.qch) identified by its
320     \a namespaceName from the help collection. Returns true
321     on success, otherwise false.
322 
323     \sa registerDocumentation(), error()
324 */
unregisterDocumentation(const QString & namespaceName)325 bool QHelpEngineCore::unregisterDocumentation(const QString &namespaceName)
326 {
327     d->error.clear();
328     d->needsSetup = true;
329     return d->collectionHandler->unregisterDocumentation(namespaceName);
330 }
331 
332 /*!
333     Returns the absolute file name of the Qt compressed help file (.qch)
334     identified by the \a namespaceName. If there is no Qt compressed help file
335     with the specified namespace registered, an empty string is returned.
336 
337     \sa namespaceName()
338 */
documentationFileName(const QString & namespaceName)339 QString QHelpEngineCore::documentationFileName(const QString &namespaceName)
340 {
341     if (!d->setup())
342         return QString();
343 
344     const QHelpCollectionHandler::FileInfo fileInfo =
345             d->collectionHandler->registeredDocumentation(namespaceName);
346 
347     if (fileInfo.namespaceName.isEmpty())
348         return QString();
349 
350     if (QDir::isAbsolutePath(fileInfo.fileName))
351         return fileInfo.fileName;
352 
353     return QFileInfo(QFileInfo(d->collectionHandler->collectionFile()).absolutePath()
354                      + QLatin1Char('/') + fileInfo.fileName).absoluteFilePath();
355 }
356 
357 /*!
358     Returns a list of all registered Qt compressed help files of the current collection file.
359     The returned names are the namespaces of the registered Qt compressed help files (.qch).
360 */
registeredDocumentations() const361 QStringList QHelpEngineCore::registeredDocumentations() const
362 {
363     QStringList list;
364     if (!d->setup())
365         return list;
366     const QHelpCollectionHandler::FileInfoList &docList
367             = d->collectionHandler->registeredDocumentations();
368     for (const QHelpCollectionHandler::FileInfo &info : docList)
369         list.append(info.namespaceName);
370     return list;
371 }
372 
373 /*!
374     \obsolete
375 
376     QHelpFilterEngine::filters() should be used instead.
377 
378     Returns a list of custom filters.
379 
380     \sa addCustomFilter(), removeCustomFilter()
381 */
customFilters() const382 QStringList QHelpEngineCore::customFilters() const
383 {
384     if (!d->setup())
385         return QStringList();
386     return d->collectionHandler->customFilters();
387 }
388 
389 /*!
390     \obsolete
391 
392     QHelpFilterEngine::setFilterData() should be used instead.
393 
394     Adds the new custom filter \a filterName. The filter attributes
395     are specified by \a attributes. If the filter already exists,
396     its attribute set is replaced. The function returns true if
397     the operation succeeded, otherwise it returns false.
398 
399     \sa customFilters(), removeCustomFilter()
400 */
addCustomFilter(const QString & filterName,const QStringList & attributes)401 bool QHelpEngineCore::addCustomFilter(const QString &filterName,
402                                       const QStringList &attributes)
403 {
404     d->error.clear();
405     d->needsSetup = true;
406     return d->collectionHandler->addCustomFilter(filterName, attributes);
407 }
408 
409 /*!
410     \obsolete
411 
412     QHelpFilterEngine::removeFilter() should be used instead.
413 
414     Returns true if the filter \a filterName was removed successfully,
415     otherwise false.
416 
417     \sa addCustomFilter(), customFilters()
418 */
removeCustomFilter(const QString & filterName)419 bool QHelpEngineCore::removeCustomFilter(const QString &filterName)
420 {
421     d->error.clear();
422     d->needsSetup = true;
423     return d->collectionHandler->removeCustomFilter(filterName);
424 }
425 
426 /*!
427     \obsolete
428 
429     QHelpFilterEngine::availableComponents() should be used instead.
430 
431     Returns a list of all defined filter attributes.
432 */
filterAttributes() const433 QStringList QHelpEngineCore::filterAttributes() const
434 {
435     if (!d->setup())
436         return QStringList();
437     return d->collectionHandler->filterAttributes();
438 }
439 
440 /*!
441     \obsolete
442 
443     QHelpFilterEngine::filterData() should be used instead.
444 
445     Returns a list of filter attributes used by the custom
446     filter \a filterName.
447 */
filterAttributes(const QString & filterName) const448 QStringList QHelpEngineCore::filterAttributes(const QString &filterName) const
449 {
450     if (!d->setup())
451         return QStringList();
452     return d->collectionHandler->filterAttributes(filterName);
453 }
454 
455 /*!
456     \obsolete
457     \property QHelpEngineCore::currentFilter
458     \brief the name of the custom filter currently applied.
459     \since 4.5
460 
461     QHelpFilterEngine::activeFilter() should be used instead.
462 
463     Setting this property will save the new custom filter permanently in the
464     help collection file. To set a custom filter without saving it
465     permanently, disable the auto save filter mode.
466 
467     \sa autoSaveFilter()
468 */
currentFilter() const469 QString QHelpEngineCore::currentFilter() const
470 {
471     if (!d->setup())
472         return QString();
473 
474     if (d->currentFilter.isEmpty()) {
475         const QString &filter =
476             d->collectionHandler->customValue(QLatin1String("CurrentFilter"),
477                 QString()).toString();
478         if (!filter.isEmpty()
479             && d->collectionHandler->customFilters().contains(filter))
480             d->currentFilter = filter;
481     }
482     return d->currentFilter;
483 }
484 
setCurrentFilter(const QString & filterName)485 void QHelpEngineCore::setCurrentFilter(const QString &filterName)
486 {
487     if (!d->setup() || filterName == d->currentFilter)
488         return;
489     d->currentFilter = filterName;
490     if (d->autoSaveFilter) {
491         d->collectionHandler->setCustomValue(QLatin1String("CurrentFilter"),
492             d->currentFilter);
493     }
494     emit currentFilterChanged(d->currentFilter);
495 }
496 
497 /*!
498     \obsolete
499 
500     QHelpFilterEngine::filterData() should be used instead.
501 
502     Returns a list of filter attributes for the different filter sections
503     defined in the Qt compressed help file with the given namespace
504     \a namespaceName.
505 */
filterAttributeSets(const QString & namespaceName) const506 QList<QStringList> QHelpEngineCore::filterAttributeSets(const QString &namespaceName) const
507 {
508     if (!d->setup())
509         return QList<QStringList>();
510 
511     return d->collectionHandler->filterAttributeSets(namespaceName);
512 }
513 
514 /*!
515     \obsolete
516 
517     files() should be used instead.
518 
519     Returns a list of files contained in the Qt compressed help file \a
520     namespaceName. The files can be filtered by \a filterAttributes as
521     well as by their extension \a extensionFilter (e.g. 'html').
522 */
files(const QString namespaceName,const QStringList & filterAttributes,const QString & extensionFilter)523 QList<QUrl> QHelpEngineCore::files(const QString namespaceName,
524                                    const QStringList &filterAttributes,
525                                    const QString &extensionFilter)
526 {
527     QList<QUrl> res;
528     if (!d->setup())
529         return res;
530 
531     QUrl url;
532     url.setScheme(QLatin1String("qthelp"));
533     url.setAuthority(namespaceName);
534 
535     const QStringList &files = d->collectionHandler->files(
536                 namespaceName, filterAttributes, extensionFilter);
537     for (const QString &file : files) {
538         url.setPath(QLatin1String("/") + file);
539         res.append(url);
540     }
541     return res;
542 }
543 
544 /*!
545     Returns a list of files contained in the Qt compressed help file
546     for \a namespaceName. The files can be filtered by \a filterName as
547     well as by their extension \a extensionFilter (for example, 'html').
548 */
files(const QString namespaceName,const QString & filterName,const QString & extensionFilter)549 QList<QUrl> QHelpEngineCore::files(const QString namespaceName,
550     const QString &filterName,
551     const QString &extensionFilter)
552 {
553     QList<QUrl> res;
554     if (!d->setup())
555         return res;
556 
557     QUrl url;
558     url.setScheme(QLatin1String("qthelp"));
559     url.setAuthority(namespaceName);
560 
561     const QStringList &files = d->collectionHandler->files(
562                 namespaceName, filterName, extensionFilter);
563     for (const QString &file : files) {
564         url.setPath(QLatin1String("/") + file);
565         res.append(url);
566     }
567     return res;
568 }
569 
570 /*!
571     Returns the corrected URL for the \a url that may refer to
572     a different namespace defined by the virtual folder defined
573     as a part of the \a url. If the virtual folder matches the namespace
574     of the \a url, the method just checks if the file exists and returns
575     the same \a url. When the virtual folder doesn't match the namespace
576     of the \a url, it tries to find the best matching namespace according
577     to the active filter. When the namespace is found, it returns the
578     corrected URL if the file exists, otherwise it returns an invalid URL.
579 */
findFile(const QUrl & url) const580 QUrl QHelpEngineCore::findFile(const QUrl &url) const
581 {
582     if (!d->setup())
583         return url;
584 
585     QUrl result = d->usesFilterEngine
586             ? d->collectionHandler->findFile(url, d->filterEngine->activeFilter())
587             : d->collectionHandler->findFile(url, filterAttributes(currentFilter())); // obsolete
588     if (!result.isEmpty())
589         return result;
590 
591     result = d->usesFilterEngine
592             ? d->collectionHandler->findFile(url, QString())
593             : d->collectionHandler->findFile(url, QStringList()); // obsolete
594     if (!result.isEmpty())
595         return result;
596 
597     return url;
598 }
599 
600 /*!
601     Returns the data of the file specified by \a url. If the
602     file does not exist, an empty QByteArray is returned.
603 
604     \sa findFile()
605 */
fileData(const QUrl & url) const606 QByteArray QHelpEngineCore::fileData(const QUrl &url) const
607 {
608     if (!d->setup())
609         return QByteArray();
610 
611     return d->collectionHandler->fileData(url);
612 }
613 
614 #if QT_DEPRECATED_SINCE(5, 15)
615 /*!
616     \obsolete
617 
618     Use documentsForIdentifier() instead.
619 
620     Returns a map of the documents found for the \a id. The map contains the
621     document titles and their URLs. The returned map contents depend on
622     the current filter, and therefore only the identifiers registered for
623     the current filter will be returned.
624 */
linksForIdentifier(const QString & id) const625 QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id) const
626 {
627     if (!d->setup())
628         return QMap<QString, QUrl>();
629 
630     if (d->usesFilterEngine)
631         return d->collectionHandler->linksForIdentifier(id, d->filterEngine->activeFilter());
632 
633     // obsolete
634     return d->collectionHandler->linksForIdentifier(id, filterAttributes(d->currentFilter));
635 }
636 #endif
637 
638 /*!
639     \since 5.15
640 
641     Returns a list of all the document links found for the \a id.
642     The returned list contents depend on the current filter, and therefore only the keywords
643     registered for the current filter will be returned.
644 */
documentsForIdentifier(const QString & id) const645 QList<QHelpLink> QHelpEngineCore::documentsForIdentifier(const QString &id) const
646 {
647     return documentsForIdentifier(id, d->usesFilterEngine
648                                   ? d->filterEngine->activeFilter()
649                                   : d->currentFilter);
650 }
651 
652 /*!
653     \since 5.15
654 
655     Returns a list of the document links found for the \a id, filtered by \a filterName.
656     The returned list contents depend on the passed filter, and therefore only the keywords
657     registered for this filter will be returned. If you want to get all results unfiltered,
658     pass empty string as \a filterName.
659 */
documentsForIdentifier(const QString & id,const QString & filterName) const660 QList<QHelpLink> QHelpEngineCore::documentsForIdentifier(const QString &id, const QString &filterName) const
661 {
662     if (!d->setup())
663         return QList<QHelpLink>();
664 
665     if (d->usesFilterEngine)
666         return d->collectionHandler->documentsForIdentifier(id, filterName);
667 
668     return d->collectionHandler->documentsForIdentifier(id, filterAttributes(filterName));
669 }
670 
671 #if QT_DEPRECATED_SINCE(5, 15)
672 /*!
673     \obsolete
674 
675     Use documentsForKeyword() instead.
676 
677     Returns a map of all the documents found for the \a keyword. The map
678     contains the document titles and URLs. The returned map contents depend
679     on the current filter, and therefore only the keywords registered for
680     the current filter will be returned.
681 */
linksForKeyword(const QString & keyword) const682 QMap<QString, QUrl> QHelpEngineCore::linksForKeyword(const QString &keyword) const
683 {
684     if (!d->setup())
685         return QMap<QString, QUrl>();
686 
687     if (d->usesFilterEngine)
688         return d->collectionHandler->linksForKeyword(keyword, d->filterEngine->activeFilter());
689 
690     // obsolete
691     return d->collectionHandler->linksForKeyword(keyword, filterAttributes(d->currentFilter));
692 }
693 #endif
694 
695 /*!
696     \since 5.15
697 
698     Returns a list of all the document links found for the \a keyword.
699     The returned list contents depend on the current filter, and therefore only the keywords
700     registered for the current filter will be returned.
701 */
documentsForKeyword(const QString & keyword) const702 QList<QHelpLink> QHelpEngineCore::documentsForKeyword(const QString &keyword) const
703 {
704     return documentsForKeyword(keyword, d->usesFilterEngine
705                                ? d->filterEngine->activeFilter()
706                                : d->currentFilter);
707 }
708 
709 /*!
710     \since 5.15
711 
712     Returns a list of the document links found for the \a keyword, filtered by \a filterName.
713     The returned list contents depend on the passed filter, and therefore only the keywords
714     registered for this filter will be returned. If you want to get all results unfiltered,
715     pass empty string as \a filterName.
716 */
documentsForKeyword(const QString & keyword,const QString & filterName) const717 QList<QHelpLink> QHelpEngineCore::documentsForKeyword(const QString &keyword, const QString &filterName) const
718 {
719     if (!d->setup())
720         return QList<QHelpLink>();
721 
722     if (d->usesFilterEngine)
723         return d->collectionHandler->documentsForKeyword(keyword, filterName);
724 
725     return d->collectionHandler->documentsForKeyword(keyword, filterAttributes(filterName));
726 }
727 
728 /*!
729     Removes the \a key from the settings section in the
730     collection file. Returns true if the value was removed
731     successfully, otherwise false.
732 
733     \sa customValue(), setCustomValue()
734 */
removeCustomValue(const QString & key)735 bool QHelpEngineCore::removeCustomValue(const QString &key)
736 {
737     d->error.clear();
738     return d->collectionHandler->removeCustomValue(key);
739 }
740 
741 /*!
742     Returns the value assigned to the \a key. If the requested
743     key does not exist, the specified \a defaultValue is
744     returned.
745 
746     \sa setCustomValue(), removeCustomValue()
747 */
customValue(const QString & key,const QVariant & defaultValue) const748 QVariant QHelpEngineCore::customValue(const QString &key, const QVariant &defaultValue) const
749 {
750     if (!d->setup())
751         return QVariant();
752     return d->collectionHandler->customValue(key, defaultValue);
753 }
754 
755 /*!
756     Save the \a value under the \a key. If the key already exist,
757     the value will be overwritten. Returns true if the value was
758     saved successfully, otherwise false.
759 
760     \sa customValue(), removeCustomValue()
761 */
setCustomValue(const QString & key,const QVariant & value)762 bool QHelpEngineCore::setCustomValue(const QString &key, const QVariant &value)
763 {
764     d->error.clear();
765     return d->collectionHandler->setCustomValue(key, value);
766 }
767 
768 /*!
769     Returns the meta data for the Qt compressed help file \a
770     documentationFileName. If there is no data available for
771     \a name, an invalid QVariant() is returned. The meta
772     data is defined when creating the Qt compressed help file and
773     cannot be modified later. Common meta data includes e.g.
774     the author of the documentation.
775 */
metaData(const QString & documentationFileName,const QString & name)776 QVariant QHelpEngineCore::metaData(const QString &documentationFileName,
777                                    const QString &name)
778 {
779     QHelpDBReader reader(documentationFileName, QLatin1String("GetMetaData"), nullptr);
780 
781     if (reader.init())
782         return reader.metaData(name);
783     return QVariant();
784 }
785 
786 /*!
787     Returns a description of the last error that occurred.
788 */
error() const789 QString QHelpEngineCore::error() const
790 {
791     return d->error;
792 }
793 
794 /*!
795     \property QHelpEngineCore::autoSaveFilter
796     \brief whether QHelpEngineCore is in auto save filter mode or not.
797     \since 4.5
798 
799     If QHelpEngineCore is in auto save filter mode, the current filter is
800     automatically saved when it is changed by the QHelpFilterEngine::setActiveFilter()
801     function. The filter is saved persistently in the help collection file.
802 
803     By default, this mode is on.
804 */
setAutoSaveFilter(bool save)805 void QHelpEngineCore::setAutoSaveFilter(bool save)
806 {
807     d->autoSaveFilter = save;
808 }
809 
autoSaveFilter() const810 bool QHelpEngineCore::autoSaveFilter() const
811 {
812     return d->autoSaveFilter;
813 }
814 
815 /*!
816     \since 5.13
817 
818     Enables or disables the new filter engine functionality
819     inside the help engine, according to the passed \a uses parameter.
820 
821     \sa filterEngine()
822 */
setUsesFilterEngine(bool uses)823 void QHelpEngineCore::setUsesFilterEngine(bool uses)
824 {
825     d->usesFilterEngine = uses;
826 }
827 
828 /*!
829     \since 5.13
830 
831     Returns whether the help engine uses the new filter functionality.
832 
833     \sa filterEngine()
834 */
usesFilterEngine() const835 bool QHelpEngineCore::usesFilterEngine() const
836 {
837     return d->usesFilterEngine;
838 }
839 
840 QT_END_NAMESPACE
841