diff options
Diffstat (limited to 'src/assistant/help/qhelpindexwidget.cpp')
-rw-r--r-- | src/assistant/help/qhelpindexwidget.cpp | 315 |
1 files changed, 111 insertions, 204 deletions
diff --git a/src/assistant/help/qhelpindexwidget.cpp b/src/assistant/help/qhelpindexwidget.cpp index eaaf44ed3..bd330de26 100644 --- a/src/assistant/help/qhelpindexwidget.cpp +++ b/src/assistant/help/qhelpindexwidget.cpp @@ -1,151 +1,68 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Assistant of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qhelpindexwidget.h" #include "qhelpenginecore.h" -#include "qhelpengine_p.h" -#include "qhelpdbreader_p.h" -#include "qhelpcollectionhandler_p.h" +#include "qhelplink.h" -#include <QtCore/QThread> -#include <QtCore/QMutex> -#include <QtHelp/QHelpLink> -#include <QtWidgets/QListView> -#include <QtWidgets/QHeaderView> - -#include <algorithm> +#if QT_CONFIG(future) +#include <QtCore/qfuturewatcher.h> +#endif QT_BEGIN_NAMESPACE -class QHelpIndexProvider : public QThread -{ -public: - QHelpIndexProvider(QHelpEnginePrivate *helpEngine); - ~QHelpIndexProvider() override; - void collectIndices(const QString &customFilterName); - void stopCollecting(); - QStringList indices() const; - -private: - void run() override; - - QHelpEnginePrivate *m_helpEngine; - QString m_currentFilter; - QStringList m_filterAttributes; - QStringList m_indices; - mutable QMutex m_mutex; -}; - class QHelpIndexModelPrivate { -public: - QHelpIndexModelPrivate(QHelpEnginePrivate *hE) - : helpEngine(hE), - indexProvider(new QHelpIndexProvider(helpEngine)) +#if QT_CONFIG(future) + using FutureProvider = std::function<QFuture<QStringList>()>; + + struct WatcherDeleter { - } + void operator()(QFutureWatcherBase *watcher) { + watcher->disconnect(); + watcher->cancel(); + watcher->waitForFinished(); + delete watcher; + } + }; +#endif - QHelpEnginePrivate *helpEngine; - QHelpIndexProvider *indexProvider; - QStringList indices; +public: +#if QT_CONFIG(future) + void createIndex(const FutureProvider &futureProvider); +#endif + + QHelpIndexModel *q = nullptr; + QHelpEngineCore *helpEngine = nullptr; + QStringList indices = {}; +#if QT_CONFIG(future) + std::unique_ptr<QFutureWatcher<QStringList>, WatcherDeleter> watcher = {}; +#endif }; -QHelpIndexProvider::QHelpIndexProvider(QHelpEnginePrivate *helpEngine) - : QThread(helpEngine), - m_helpEngine(helpEngine) -{ -} - -QHelpIndexProvider::~QHelpIndexProvider() +#if QT_CONFIG(future) +void QHelpIndexModelPrivate::createIndex(const FutureProvider &futureProvider) { - stopCollecting(); -} - -void QHelpIndexProvider::collectIndices(const QString &customFilterName) -{ - m_mutex.lock(); - m_currentFilter = customFilterName; - m_filterAttributes = m_helpEngine->q->filterAttributes(customFilterName); - m_mutex.unlock(); - - if (isRunning()) - stopCollecting(); - start(LowPriority); -} - -void QHelpIndexProvider::stopCollecting() -{ - if (!isRunning()) - return; - wait(); -} - -QStringList QHelpIndexProvider::indices() const -{ - QMutexLocker lck(&m_mutex); - return m_indices; -} - -void QHelpIndexProvider::run() -{ - m_mutex.lock(); - const QString currentFilter = m_currentFilter; - const QStringList attributes = m_filterAttributes; - const QString collectionFile = m_helpEngine->collectionHandler->collectionFile(); - m_indices = QStringList(); - m_mutex.unlock(); - - if (collectionFile.isEmpty()) - return; + const bool wasRunning = bool(watcher); + watcher.reset(new QFutureWatcher<QStringList>); + QObject::connect(watcher.get(), &QFutureWatcherBase::finished, q, [this] { + if (!watcher->isCanceled()) { + indices = watcher->result(); + q->filter({}); + } + watcher.release()->deleteLater(); + emit q->indexCreated(); + }); + watcher->setFuture(futureProvider()); - QHelpCollectionHandler collectionHandler(collectionFile); - if (!collectionHandler.openCollectionFile()) + if (wasRunning) return; - const QStringList result = m_helpEngine->usesFilterEngine - ? collectionHandler.indicesForFilter(currentFilter) - : collectionHandler.indicesForFilter(attributes); - - m_mutex.lock(); - m_indices = result; - m_mutex.unlock(); + indices.clear(); + q->filter({}); + emit q->indexCreationStarted(); } +#endif /*! \class QHelpIndexModel @@ -153,8 +70,6 @@ void QHelpIndexProvider::run() \inmodule QtHelp \brief The QHelpIndexModel class provides a model that supplies index keywords to views. - - */ /*! @@ -173,14 +88,10 @@ void QHelpIndexProvider::run() This signal is emitted when the index has been created. */ -QHelpIndexModel::QHelpIndexModel(QHelpEnginePrivate *helpEngine) +QHelpIndexModel::QHelpIndexModel(QHelpEngineCore *helpEngine) : QStringListModel(helpEngine) -{ - d = new QHelpIndexModelPrivate(helpEngine); - - connect(d->indexProvider, &QThread::finished, - this, &QHelpIndexModel::insertIndices); -} + , d(new QHelpIndexModelPrivate{this, helpEngine}) +{} QHelpIndexModel::~QHelpIndexModel() { @@ -188,38 +99,43 @@ QHelpIndexModel::~QHelpIndexModel() } /*! - Creates a new index by querying the help system for - keywords for the specified \a customFilterName. + \since 6.8 + + Creates a new index by querying the help system for keywords for the current filter. */ -void QHelpIndexModel::createIndex(const QString &customFilterName) +void QHelpIndexModel::createIndexForCurrentFilter() { - const bool running = d->indexProvider->isRunning(); - d->indexProvider->collectIndices(customFilterName); - if (running) - return; - - d->indices = QStringList(); - filter(QString()); - emit indexCreationStarted(); +#if QT_CONFIG(future) + d->createIndex([this] { return d->helpEngine->provideIndexForCurrentFilter(); }); +#endif } -void QHelpIndexModel::insertIndices() +/*! + Creates a new index by querying the help system for + keywords for the specified custom \a filter name. +*/ +void QHelpIndexModel::createIndex(const QString &filter) { - if (d->indexProvider->isRunning()) - return; - - d->indices = d->indexProvider->indices(); - filter(QString()); - emit indexCreated(); +#if QT_CONFIG(future) + d->createIndex([this, filter] { return d->helpEngine->provideIndex(filter); }); +#endif } +// TODO: Remove me +void QHelpIndexModel::insertIndices() +{} + /*! Returns true if the index is currently built up, otherwise false. */ bool QHelpIndexModel::isCreatingIndex() const { - return d->indexProvider->isRunning(); +#if QT_CONFIG(future) + return bool(d->watcher); +#else + return false; +#endif } /*! @@ -229,7 +145,7 @@ bool QHelpIndexModel::isCreatingIndex() const */ QHelpEngineCore *QHelpIndexModel::helpEngine() const { - return d->helpEngine->q; + return d->helpEngine; } /*! @@ -246,58 +162,47 @@ QModelIndex QHelpIndexModel::filter(const QString &filter, const QString &wildca { if (filter.isEmpty()) { setStringList(d->indices); - return index(-1, 0, QModelIndex()); + return index(-1, 0, {}); } - QStringList lst; - int goodMatch = -1; - int perfectMatch = -1; - - if (!wildcard.isEmpty()) { - auto re = QRegularExpression::wildcardToRegularExpression(wildcard, - QRegularExpression::UnanchoredWildcardConversion); - const QRegularExpression regExp(re, QRegularExpression::CaseInsensitiveOption); - for (const QString &index : qAsConst(d->indices)) { - if (index.contains(regExp)) { - lst.append(index); + using Checker = std::function<bool(const QString &)>; + const auto checkIndices = [this, filter](const Checker &checker) { + QStringList filteredList; + int goodMatch = -1; + int perfectMatch = -1; + for (const QString &index : std::as_const(d->indices)) { + if (checker(index)) { + filteredList.append(index); if (perfectMatch == -1 && index.startsWith(filter, Qt::CaseInsensitive)) { if (goodMatch == -1) - goodMatch = lst.count() - 1; - if (filter.length() == index.length()){ - perfectMatch = lst.count() - 1; - } + goodMatch = filteredList.size() - 1; + if (filter.size() == index.size()) + perfectMatch = filteredList.size() - 1; } else if (perfectMatch > -1 && index == filter) { - perfectMatch = lst.count() - 1; - } - } - } - } else { - for (const QString &index : qAsConst(d->indices)) { - if (index.contains(filter, Qt::CaseInsensitive)) { - lst.append(index); - if (perfectMatch == -1 && index.startsWith(filter, Qt::CaseInsensitive)) { - if (goodMatch == -1) - goodMatch = lst.count() - 1; - if (filter.length() == index.length()){ - perfectMatch = lst.count() - 1; - } - } else if (perfectMatch > -1 && index == filter) { - perfectMatch = lst.count() - 1; + perfectMatch = filteredList.size() - 1; } } } + setStringList(filteredList); + return perfectMatch >= 0 ? perfectMatch : qMax(0, goodMatch); + }; + int perfectMatch = -1; + if (!wildcard.isEmpty()) { + const auto re = QRegularExpression::wildcardToRegularExpression(wildcard, + QRegularExpression::UnanchoredWildcardConversion); + const QRegularExpression regExp(re, QRegularExpression::CaseInsensitiveOption); + perfectMatch = checkIndices([regExp](const QString &index) { + return index.contains(regExp); + }); + } else { + perfectMatch = checkIndices([filter](const QString &index) { + return index.contains(filter, Qt::CaseInsensitive); + }); } - - if (perfectMatch == -1) - perfectMatch = qMax(0, goodMatch); - - setStringList(lst); - return index(perfectMatch, 0, QModelIndex()); + return index(perfectMatch, 0, {}); } - - /*! \class QHelpIndexWidget \inmodule QtHelp @@ -342,12 +247,10 @@ QModelIndex QHelpIndexModel::filter(const QString &filter, const QString &wildca */ QHelpIndexWidget::QHelpIndexWidget() - : QListView(nullptr) { setEditTriggers(QAbstractItemView::NoEditTriggers); setUniformItemSizes(true); - connect(this, &QAbstractItemView::activated, - this, &QHelpIndexWidget::showLink); + connect(this, &QAbstractItemView::activated, this, &QHelpIndexWidget::showLink); } void QHelpIndexWidget::showLink(const QModelIndex &index) @@ -363,8 +266,9 @@ void QHelpIndexWidget::showLink(const QModelIndex &index) const QString name = v.isValid() ? v.toString() : QString(); const QList<QHelpLink> &docs = indexModel->helpEngine()->documentsForKeyword(name); - if (docs.count() > 1) { + if (docs.size() > 1) { emit documentsActivated(docs, name); +#if QT_DEPRECATED_SINCE(5, 15) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED QMultiMap<QString, QUrl> links; @@ -372,12 +276,15 @@ void QHelpIndexWidget::showLink(const QModelIndex &index) links.insert(doc.title, doc.url); emit linksActivated(links, name); QT_WARNING_POP +#endif } else if (!docs.isEmpty()) { emit documentActivated(docs.first(), name); +#if QT_DEPRECATED_SINCE(5, 15) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit linkActivated(docs.first().url, name); QT_WARNING_POP +#endif } } @@ -399,7 +306,7 @@ void QHelpIndexWidget::activateCurrentItem() */ void QHelpIndexWidget::filterIndices(const QString &filter, const QString &wildcard) { - QHelpIndexModel *indexModel = qobject_cast<QHelpIndexModel*>(model()); + QHelpIndexModel *indexModel = qobject_cast<QHelpIndexModel *>(model()); if (!indexModel) return; const QModelIndex &idx = indexModel->filter(filter, wildcard); |