summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2018-07-27 15:06:43 +0200
committerJarek Kobus <jaroslaw.kobus@qt.io>2018-11-12 09:08:58 +0000
commit1f0b89f8e8da682a4bf0f82c077c363b4d43a707 (patch)
treeb9d0f5bf3b1796c8ccfe62e3b9f49c8dcfee677e
parent2095b1598ebe1d3ee91f9eeb1f7a13a4cbbf36f9 (diff)
Add new filter API, enclosed in QHelpFilterEngine
Implement new filter mechanism and provide component filtering. Task-number: QTCREATORBUG-19724 Task-number: QTCREATORBUG-7301 Change-Id: I48400e3bc969495a66c3002fed13a7c3ddb1e249 Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
-rw-r--r--src/assistant/assistant/filternamedialog.cpp10
-rw-r--r--src/assistant/assistant/filternamedialog.h2
-rw-r--r--src/assistant/assistant/helpenginewrapper.cpp75
-rw-r--r--src/assistant/assistant/helpenginewrapper.h17
-rw-r--r--src/assistant/assistant/mainwindow.cpp34
-rw-r--r--src/assistant/assistant/mainwindow.h2
-rw-r--r--src/assistant/assistant/openpagesmanager.cpp2
-rw-r--r--src/assistant/assistant/preferencesdialog.cpp617
-rw-r--r--src/assistant/assistant/preferencesdialog.h51
-rw-r--r--src/assistant/assistant/preferencesdialog.ui179
-rw-r--r--src/assistant/assistant/remotecontrol.cpp7
-rw-r--r--src/assistant/help/help.pro2
-rw-r--r--src/assistant/help/qhelpcollectionhandler.cpp4
-rw-r--r--src/assistant/help/qhelpcontentwidget.cpp42
-rw-r--r--src/assistant/help/qhelpcontentwidget.h1
-rw-r--r--src/assistant/help/qhelpengine.cpp10
-rw-r--r--src/assistant/help/qhelpengine_p.h3
-rw-r--r--src/assistant/help/qhelpenginecore.cpp161
-rw-r--r--src/assistant/help/qhelpenginecore.h22
-rw-r--r--src/assistant/help/qhelpfilterdata.cpp34
-rw-r--r--src/assistant/help/qhelpfilterengine.cpp277
-rw-r--r--src/assistant/help/qhelpfilterengine.h95
-rw-r--r--src/assistant/help/qhelpindexwidget.cpp16
-rw-r--r--src/assistant/help/qhelpindexwidget.h1
-rw-r--r--src/assistant/help/qhelpsearchengine.cpp3
-rw-r--r--src/assistant/help/qhelpsearchindexreader.cpp3
-rw-r--r--src/assistant/help/qhelpsearchindexreader_default.cpp72
-rw-r--r--src/assistant/help/qhelpsearchindexreader_default_p.h9
-rw-r--r--src/assistant/help/qhelpsearchindexreader_p.h4
29 files changed, 1150 insertions, 605 deletions
diff --git a/src/assistant/assistant/filternamedialog.cpp b/src/assistant/assistant/filternamedialog.cpp
index 33b19cff8..4c17d3332 100644
--- a/src/assistant/assistant/filternamedialog.cpp
+++ b/src/assistant/assistant/filternamedialog.cpp
@@ -25,7 +25,6 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "tracer.h"
#include <QtWidgets/QPushButton>
@@ -36,7 +35,6 @@ QT_BEGIN_NAMESPACE
FilterNameDialog::FilterNameDialog(QWidget *parent)
: QDialog(parent)
{
- TRACE_OBJ
m_ui.setupUi(this);
connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked,
this, &QDialog::accept);
@@ -47,15 +45,19 @@ FilterNameDialog::FilterNameDialog(QWidget *parent)
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true);
}
+void FilterNameDialog::setFilterName(const QString &filter)
+{
+ m_ui.lineEdit->setText(filter);
+ m_ui.lineEdit->selectAll();
+}
+
QString FilterNameDialog::filterName() const
{
- TRACE_OBJ
return m_ui.lineEdit->text();
}
void FilterNameDialog::updateOkButton()
{
- TRACE_OBJ
m_ui.buttonBox->button(QDialogButtonBox::Ok)
->setDisabled(m_ui.lineEdit->text().isEmpty());
}
diff --git a/src/assistant/assistant/filternamedialog.h b/src/assistant/assistant/filternamedialog.h
index 8e46bfd0b..522b611af 100644
--- a/src/assistant/assistant/filternamedialog.h
+++ b/src/assistant/assistant/filternamedialog.h
@@ -40,6 +40,8 @@ class FilterNameDialog : public QDialog
public:
FilterNameDialog(QWidget *parent = nullptr);
+
+ void setFilterName(const QString &filter);
QString filterName() const;
private slots:
diff --git a/src/assistant/assistant/helpenginewrapper.cpp b/src/assistant/assistant/helpenginewrapper.cpp
index 3aef5bb99..17e4bde8c 100644
--- a/src/assistant/assistant/helpenginewrapper.cpp
+++ b/src/assistant/assistant/helpenginewrapper.cpp
@@ -39,13 +39,13 @@
#include <QtCore/QTimer>
#include <QtHelp/QHelpContentModel>
#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpFilterEngine>
#include <QtHelp/QHelpIndexModel>
#include <QtHelp/QHelpSearchEngine>
QT_BEGIN_NAMESPACE
namespace {
- const QString Unfiltered;
const QString AppFontKey(QLatin1String("appFont"));
const QString AppWritingSystemKey(QLatin1String("appWritingSystem"));
const QString BookmarksKey(QLatin1String("Bookmarks"));
@@ -104,14 +104,6 @@ private:
QMap<QString, RecentSignal> m_recentQchUpdates;
};
-const QString HelpEngineWrapper::TrUnfiltered()
-{
- static QString s;
- if (s.isEmpty())
- s = HelpEngineWrapper::tr("Unfiltered");
- return s;
-}
-
HelpEngineWrapper *HelpEngineWrapper::helpEngineWrapper = nullptr;
HelpEngineWrapper &HelpEngineWrapper::instance(const QString &collectionFile)
@@ -154,8 +146,6 @@ HelpEngineWrapper::HelpEngineWrapper(const QString &collectionFile)
this, &HelpEngineWrapper::documentationRemoved);
connect(d, &HelpEngineWrapperPrivate::documentationUpdated,
this, &HelpEngineWrapper::documentationUpdated);
- connect(d->m_helpEngine, &QHelpEngineCore::currentFilterChanged,
- this, &HelpEngineWrapper::handleCurrentFilterChanged);
connect(d->m_helpEngine, &QHelpEngineCore::setupFinished,
this, &HelpEngineWrapper::setupFinished);
}
@@ -259,43 +249,6 @@ bool HelpEngineWrapper::setupData()
return d->m_helpEngine->setupData();
}
-bool HelpEngineWrapper::addCustomFilter(const QString &filterName,
- const QStringList &attributes)
-{
- TRACE_OBJ
- return d->m_helpEngine->addCustomFilter(filterName, attributes);
-}
-
-bool HelpEngineWrapper::removeCustomFilter(const QString &filterName)
-{
- TRACE_OBJ
- return d->m_helpEngine->removeCustomFilter(filterName);
-}
-
-void HelpEngineWrapper::setCurrentFilter(const QString &currentFilter)
-{
- TRACE_OBJ
- const QString &filter
- = currentFilter == TrUnfiltered() ? Unfiltered : currentFilter;
- d->m_helpEngine->setCurrentFilter(filter);
-}
-
-const QString HelpEngineWrapper::currentFilter() const
-{
- TRACE_OBJ
- const QString &filter = d->m_helpEngine->currentFilter();
- return filter == Unfiltered ? TrUnfiltered() : filter;
-}
-
-const QStringList HelpEngineWrapper::customFilters() const
-{
- TRACE_OBJ
- QStringList filters = d->m_helpEngine->customFilters();
- filters.removeOne(Unfiltered);
- filters.prepend(TrUnfiltered());
- return filters;
-}
-
QUrl HelpEngineWrapper::findFile(const QUrl &url) const
{
TRACE_OBJ
@@ -314,22 +267,15 @@ QMap<QString, QUrl> HelpEngineWrapper::linksForIdentifier(const QString &id) con
return d->m_helpEngine->linksForIdentifier(id);
}
-const QStringList HelpEngineWrapper::filterAttributes() const
-{
- TRACE_OBJ
- return d->m_helpEngine->filterAttributes();
-}
-
-const QStringList HelpEngineWrapper::filterAttributes(const QString &filterName) const
+QString HelpEngineWrapper::error() const
{
TRACE_OBJ
- return d->m_helpEngine->filterAttributes(filterName);
+ return d->m_helpEngine->error();
}
-QString HelpEngineWrapper::error() const
+QHelpFilterEngine *HelpEngineWrapper::filterEngine() const
{
- TRACE_OBJ
- return d->m_helpEngine->error();
+ return d->m_helpEngine->filterEngine();
}
const QStringList HelpEngineWrapper::qtDocInfo(const QString &component) const
@@ -694,14 +640,6 @@ void HelpEngineWrapper::setBrowserWritingSystem(QFontDatabase::WritingSystem sys
d->m_helpEngine->setCustomValue(BrowserWritingSystemKey, system);
}
-void HelpEngineWrapper::handleCurrentFilterChanged(const QString &filter)
-{
- TRACE_OBJ
- const QString &filterToReport
- = filter == Unfiltered ? TrUnfiltered() : filter;
- emit currentFilterChanged(filterToReport);
-}
-
bool HelpEngineWrapper::showTabs() const
{
TRACE_OBJ
@@ -753,9 +691,8 @@ HelpEngineWrapperPrivate::HelpEngineWrapperPrivate(const QString &collectionFile
m_qchWatcher(new QFileSystemWatcher(this))
{
TRACE_OBJ
- if (!m_helpEngine->customFilters().contains(Unfiltered))
- m_helpEngine->addCustomFilter(Unfiltered, QStringList());
initFileSystemWatchers();
+ m_helpEngine->setUsesFilterEngine(true);
}
void HelpEngineWrapperPrivate::initFileSystemWatchers()
diff --git a/src/assistant/assistant/helpenginewrapper.h b/src/assistant/assistant/helpenginewrapper.h
index 08474f697..6026a0473 100644
--- a/src/assistant/assistant/helpenginewrapper.h
+++ b/src/assistant/assistant/helpenginewrapper.h
@@ -45,6 +45,7 @@ class QHelpContentWidget;
class QHelpIndexModel;
class QHelpIndexWidget;
class QHelpSearchEngine;
+class QHelpFilterEngine;
enum {
ShowHomePage = 0,
@@ -76,19 +77,13 @@ public:
const QString collectionFile() const;
bool registerDocumentation(const QString &docFile);
bool unregisterDocumentation(const QString &namespaceName);
- bool addCustomFilter(const QString &filterName,
- const QStringList &attributes);
- bool removeCustomFilter(const QString &filterName);
- void setCurrentFilter(const QString &filterName);
- const QString currentFilter() const;
- const QStringList customFilters() const;
QUrl findFile(const QUrl &url) const;
QByteArray fileData(const QUrl &url) const;
QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
- const QStringList filterAttributes() const;
- const QStringList filterAttributes(const QString &filterName) const;
QString error() const;
+ QHelpFilterEngine *filterEngine() const;
+
/*
* To be called after assistant has finished looking for new documentation.
* This will mainly cause the search index to be updated, if necessary.
@@ -175,8 +170,6 @@ public:
bool showTabs() const;
void setShowTabs(bool show);
- static const QString TrUnfiltered();
-
bool fullTextSearchFallbackEnabled() const;
const QByteArray topicChooserGeometry() const;
@@ -189,12 +182,8 @@ signals:
void documentationUpdated(const QString &namespaceName);
// Forwarded from QHelpEngineCore.
- void currentFilterChanged(const QString &currentFilter);
void setupFinished();
-private slots:
- void handleCurrentFilterChanged(const QString &filter);
-
private:
HelpEngineWrapper(const QString &collectionFile);
~HelpEngineWrapper();
diff --git a/src/assistant/assistant/mainwindow.cpp b/src/assistant/assistant/mainwindow.cpp
index 392af9224..c9c120950 100644
--- a/src/assistant/assistant/mainwindow.cpp
+++ b/src/assistant/assistant/mainwindow.cpp
@@ -80,6 +80,7 @@
#include <QtHelp/QHelpEngineCore>
#include <QtHelp/QHelpIndexModel>
#include <QtHelp/QHelpSearchEngine>
+#include <QtHelp/QHelpFilterEngine>
#include <cstdlib>
@@ -268,8 +269,8 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
if (!m_cmdLine->currentFilter().isEmpty()) {
const QString &curFilter = m_cmdLine->currentFilter();
- if (helpEngineWrapper.customFilters().contains(curFilter))
- helpEngineWrapper.setCurrentFilter(curFilter);
+ if (helpEngineWrapper.filterEngine()->filters().contains(curFilter))
+ helpEngineWrapper.filterEngine()->setActiveFilter(curFilter);
}
if (usesDefaultCollection())
@@ -737,9 +738,9 @@ void MainWindow::setupFilterToolbar()
connect(&helpEngine, &HelpEngineWrapper::setupFinished,
this, &MainWindow::setupFilterCombo, Qt::QueuedConnection);
- connect(m_filterCombo, QOverload<const QString &>::of(&QComboBox::activated),
+ connect(m_filterCombo, QOverload<int>::of(&QComboBox::activated),
this, &MainWindow::filterDocumentation);
- connect(&helpEngine, &HelpEngineWrapper::currentFilterChanged,
+ connect(helpEngine.filterEngine(), &QHelpFilterEngine::filterActivated,
this, &MainWindow::currentFilterChanged);
setupFilterCombo();
@@ -1048,21 +1049,27 @@ void MainWindow::setupFilterCombo()
{
TRACE_OBJ
HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
- QString curFilter = m_filterCombo->currentText();
- if (curFilter.isEmpty())
- curFilter = helpEngine.currentFilter();
+ const QString currentFilter = helpEngine.filterEngine()->activeFilter();
m_filterCombo->clear();
- m_filterCombo->addItems(helpEngine.customFilters());
- int idx = m_filterCombo->findText(curFilter);
+ m_filterCombo->addItem(tr("Unfiltered"));
+ const QStringList allFilters = helpEngine.filterEngine()->filters();
+ if (!allFilters.isEmpty())
+ m_filterCombo->insertSeparator(1);
+ for (const QString &filter : allFilters)
+ m_filterCombo->addItem(filter, filter);
+
+ int idx = m_filterCombo->findData(currentFilter);
if (idx < 0)
idx = 0;
m_filterCombo->setCurrentIndex(idx);
}
-void MainWindow::filterDocumentation(const QString &customFilter)
+void MainWindow::filterDocumentation(int filterIndex)
{
TRACE_OBJ
- HelpEngineWrapper::instance().setCurrentFilter(customFilter);
+
+ const QString filter = m_filterCombo->itemData(filterIndex).toString();
+ HelpEngineWrapper::instance().filterEngine()->setActiveFilter(filter);
}
void MainWindow::expandTOC(int depth)
@@ -1143,8 +1150,9 @@ QString MainWindow::defaultHelpCollectionFileName()
void MainWindow::currentFilterChanged(const QString &filter)
{
TRACE_OBJ
- const int index = m_filterCombo->findText(filter);
- Q_ASSERT(index != -1);
+ int index = m_filterCombo->findData(filter);
+ if (index < 0)
+ index = 0;
m_filterCombo->setCurrentIndex(index);
}
diff --git a/src/assistant/assistant/mainwindow.h b/src/assistant/assistant/mainwindow.h
index 86451f839..c5bf5837e 100644
--- a/src/assistant/assistant/mainwindow.h
+++ b/src/assistant/assistant/mainwindow.h
@@ -90,7 +90,7 @@ private slots:
void showNewAddress(const QUrl &url);
void showTopicChooser(const QMap<QString, QUrl> &links, const QString &keyword);
void updateApplicationFont();
- void filterDocumentation(const QString &customFilter);
+ void filterDocumentation(int filterIndex);
void setupFilterCombo();
void lookForNewQtDocumentation();
void indexingStarted();
diff --git a/src/assistant/assistant/openpagesmanager.cpp b/src/assistant/assistant/openpagesmanager.cpp
index 3151cb534..f3acb4656 100644
--- a/src/assistant/assistant/openpagesmanager.cpp
+++ b/src/assistant/assistant/openpagesmanager.cpp
@@ -237,7 +237,7 @@ void OpenPagesManager::closeOrReloadPages(const QString &nameSpace, bool tryRelo
HelpViewer *page = m_model->pageAt(i);
if (page->source().host() != nameSpace)
continue;
- if (tryReload && HelpEngineWrapper::instance().findFile(page->source()).isValid())
+ if (tryReload && HelpEngineWrapper::instance().findFile(page->source()).isValid())
page->reload();
else if (m_model->rowCount() == 1)
page->setSource(QUrl(QLatin1String("about:blank")));
diff --git a/src/assistant/assistant/preferencesdialog.cpp b/src/assistant/assistant/preferencesdialog.cpp
index 4647f154f..bcc661690 100644
--- a/src/assistant/assistant/preferencesdialog.cpp
+++ b/src/assistant/assistant/preferencesdialog.cpp
@@ -32,106 +32,20 @@
#include "fontpanel.h"
#include "helpenginewrapper.h"
#include "openpagesmanager.h"
-#include "tracer.h"
-#include <QtCore/QAbstractListModel>
-#include <QtCore/QtAlgorithms>
-#include <QtCore/QFileSystemWatcher>
-#include <QtCore/QSortFilterProxyModel>
-#include <QtCore/QVector>
-
-#include <QtWidgets/QDesktopWidget>
-#include <QtWidgets/QFileDialog>
#include <QtGui/QFontDatabase>
-#include <QtWidgets/QHeaderView>
-#include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox>
#include <QtHelp/QHelpEngineCore>
+#include <QtHelp/QHelpFilterData>
+#include <QtHelp/QHelpFilterEngine>
+#include <QtHelp/QHelpCollectionDetails>
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-struct RegisteredDocEntry
-{
- QString nameSpace;
- QString fileName;
-};
-
-typedef QVector<RegisteredDocEntry> RegisteredDocEntries;
-
-class RegisteredDocsModel : public QAbstractListModel {
-public:
-
- explicit RegisteredDocsModel(const RegisteredDocEntries &e = RegisteredDocEntries(), QObject *parent = nullptr)
- : QAbstractListModel(parent), m_docEntries(e) {}
-
- int rowCount(const QModelIndex & = QModelIndex()) const override { return m_docEntries.size(); }
- QVariant data(const QModelIndex &index, int role) const override;
-
- bool contains(const QString &nameSpace) const
- {
- return m_docEntries.cend() !=
- std::find_if(m_docEntries.cbegin(), m_docEntries.cend(),
- [nameSpace] (const RegisteredDocEntry &e) { return e.nameSpace == nameSpace; });
- }
-
- void append(const RegisteredDocEntry &e);
-
- const RegisteredDocEntries &docEntries() const { return m_docEntries; }
- void setDocEntries(const RegisteredDocEntries &);
-
-private:
- RegisteredDocEntries m_docEntries;
-};
-
-QVariant RegisteredDocsModel::data(const QModelIndex &index, int role) const
-{
- QVariant result;
- const int row = index.row();
- if (index.isValid() && row < m_docEntries.size()) {
- switch (role) {
- case Qt::DisplayRole:
- result = QVariant(m_docEntries.at(row).nameSpace);
- break;
- case Qt::ToolTipRole:
- result = QVariant(QDir::toNativeSeparators(m_docEntries.at(row).fileName));
- break;
- default:
- break;
- }
- }
- return result;
-}
-
-void RegisteredDocsModel::append(const RegisteredDocEntry &e)
-{
- beginInsertRows(QModelIndex(), m_docEntries.size(), m_docEntries.size());
- m_docEntries.append(e);
- endInsertRows();
-}
+#include <QtWidgets/QFileDialog>
-void RegisteredDocsModel::setDocEntries(const RegisteredDocEntries &e)
-{
- beginResetModel();
- m_docEntries = e;
- endResetModel();
-}
+#include <QtDebug>
-static RegisteredDocEntries registeredDocEntries(const HelpEngineWrapper &wrapper)
-{
- RegisteredDocEntries result;
- const QStringList &nameSpaces = wrapper.registeredDocumentations();
- result.reserve(nameSpaces.size());
- for (const QString &nameSpace : nameSpaces) {
- RegisteredDocEntry entry;
- entry.nameSpace = nameSpace;
- entry.fileName = wrapper.documentationFileName(nameSpace);
- result.append(entry);
- }
- return result;
-}
+QT_BEGIN_NAMESPACE
PreferencesDialog::PreferencesDialog(QWidget *parent)
: QDialog(parent)
@@ -141,52 +55,50 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
, m_hideFiltersTab(!helpEngine.filterFunctionalityEnabled())
, m_hideDocsTab(!helpEngine.documentationManagerEnabled())
{
- TRACE_OBJ
m_ui.setupUi(this);
- m_registeredDocsModel =
- new RegisteredDocsModel(m_hideDocsTab ? RegisteredDocEntries() : registeredDocEntries(helpEngine));
- m_registereredDocsFilterModel = new QSortFilterProxyModel(m_ui.registeredDocsListView);
- m_registereredDocsFilterModel->setSourceModel(m_registeredDocsModel);
- m_ui.registeredDocsListView->setModel(m_registereredDocsFilterModel);
- connect(m_ui.registeredDocsFilterLineEdit, &QLineEdit::textChanged,
- m_registereredDocsFilterModel, &QSortFilterProxyModel::setFilterFixedString);
+ // TODO: filter docs via lineedit
connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked,
- this, &PreferencesDialog::applyChanges);
+ this, &PreferencesDialog::okClicked);
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked,
+ this, &PreferencesDialog::applyClicked);
connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked,
this, &QDialog::reject);
- if (!m_hideFiltersTab) {
- m_ui.attributeWidget->header()->hide();
- m_ui.attributeWidget->setRootIsDecorated(false);
-
- connect(m_ui.attributeWidget, &QTreeWidget::itemChanged,
- this, &PreferencesDialog::updateFilterMap);
- connect(m_ui.filterWidget, &QListWidget::currentItemChanged,
- this, &PreferencesDialog::updateAttributes);
+ m_originalSetup = readOriginalSetup();
+ m_currentSetup = m_originalSetup;
- connect(m_ui.filterAddButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::addFilter);
- connect(m_ui.filterRemoveButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::removeFilter);
-
- updateFilterPage();
+ if (m_hideDocsTab) {
+ m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.docsTab));
} else {
- m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.filtersTab));
- }
-
- if (!m_hideDocsTab) {
connect(m_ui.docAddButton, &QAbstractButton::clicked,
- this, &PreferencesDialog::addDocumentationLocal);
+ this, &PreferencesDialog::addDocumentation);
connect(m_ui.docRemoveButton, &QAbstractButton::clicked,
this, &PreferencesDialog::removeDocumentation);
- m_docsBackup.reserve(m_registeredDocsModel->rowCount());
- for (const RegisteredDocEntry &e : m_registeredDocsModel->docEntries())
- m_docsBackup.append(e.nameSpace);
+ updateDocumentationPage();
+ }
+
+ if (m_hideFiltersTab) {
+ m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.filtersTab));
} else {
- m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.docsTab));
+ connect(m_ui.componentWidget, &OptionsWidget::optionSelectionChanged,
+ this, &PreferencesDialog::componentsChanged);
+ connect(m_ui.filterWidget, &QListWidget::currentItemChanged,
+ this, &PreferencesDialog::filterSelected);
+ connect(m_ui.filterWidget, &QListWidget::itemDoubleClicked,
+ this, &PreferencesDialog::renameFilterClicked);
+
+ // TODO: repeat these actions on context menu
+ connect(m_ui.filterAddButton, &QAbstractButton::clicked,
+ this, &PreferencesDialog::addFilterClicked);
+ connect(m_ui.filterRenameButton, &QAbstractButton::clicked,
+ this, &PreferencesDialog::renameFilterClicked);
+ connect(m_ui.filterRemoveButton, &QAbstractButton::clicked,
+ this, &PreferencesDialog::removeFilterClicked);
+
+ updateFilterPage();
}
updateFontSettingsPage();
@@ -198,7 +110,6 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
PreferencesDialog::~PreferencesDialog()
{
- TRACE_OBJ
if (m_appFontChanged) {
helpEngine.setAppFont(m_appFontPanel->selectedFont());
helpEngine.setUseAppFont(m_appFontPanel->isChecked());
@@ -222,259 +133,365 @@ PreferencesDialog::~PreferencesDialog()
helpEngine.setStartOption(option);
}
+FilterSetup PreferencesDialog::readOriginalSetup() const
+{
+ FilterSetup filterSetup;
+
+ filterSetup.m_namespaceToComponent = helpEngine.filterEngine()->namespaceToComponent();
+ for (auto it = filterSetup.m_namespaceToComponent.constBegin();
+ it != filterSetup.m_namespaceToComponent.constEnd(); ++it) {
+ const QString namespaceName = it.key();
+ const QString namespaceFileName = helpEngine.documentationFileName(namespaceName);
+ filterSetup.m_namespaceToFileName.insert(namespaceName, namespaceFileName);
+ filterSetup.m_fileNameToNamespace.insert(namespaceFileName, namespaceName);
+ filterSetup.m_componentToNamespace[it.value()].append(namespaceName);
+ }
+ const QStringList allFilters = helpEngine.filterEngine()->filters();
+ for (const QString &filter : allFilters)
+ filterSetup.m_filterToComponents.insert(filter, helpEngine.filterEngine()->filterData(filter).components());
+
+ return filterSetup;
+}
+
void PreferencesDialog::showDialog()
{
- TRACE_OBJ
if (exec() != Accepted)
m_appFontChanged = m_browserFontChanged = false;
}
void PreferencesDialog::updateFilterPage()
{
- TRACE_OBJ
+ if (m_hideFiltersTab)
+ return;
+
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+
+ m_currentSetup = m_originalSetup;
+
m_ui.filterWidget->clear();
- m_ui.attributeWidget->clear();
+ m_ui.componentWidget->clear();
+ m_itemToFilter.clear();
+ m_filterToItem.clear();
+
+ for (const QString &filterName : m_currentSetup.m_filterToComponents.keys()) {
+ QListWidgetItem *item = new QListWidgetItem(filterName);
+ m_ui.filterWidget->addItem(item);
+ m_itemToFilter.insert(item, filterName);
+ m_filterToItem.insert(filterName, item);
+ if (filterName == currentFilter)
+ m_ui.filterWidget->setCurrentItem(item);
+ }
- m_filterMapBackup.clear();
- const QStringList &filters = helpEngine.customFilters();
- for (const QString &filter : filters) {
- if (filter == HelpEngineWrapper::TrUnfiltered())
- continue;
- QStringList atts = helpEngine.filterAttributes(filter);
- m_filterMapBackup.insert(filter, atts);
- if (!m_filterMap.contains(filter))
- m_filterMap.insert(filter, atts);
+ if (!m_ui.filterWidget->currentItem() && !m_filterToItem.isEmpty())
+ m_ui.filterWidget->setCurrentItem(m_filterToItem.first());
+
+ updateCurrentFilter();
+}
+
+void PreferencesDialog::updateCurrentFilter()
+{
+ if (m_hideFiltersTab)
+ return;
+
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+
+ const bool filterSelected = !currentFilter.isEmpty();
+ m_ui.componentWidget->setEnabled(filterSelected);
+ m_ui.filterRenameButton->setEnabled(filterSelected);
+ m_ui.filterRemoveButton->setEnabled(filterSelected);
+
+ m_ui.componentWidget->setOptions(m_currentSetup.m_componentToNamespace.keys(),
+ m_currentSetup.m_filterToComponents.value(currentFilter));
+}
+
+void PreferencesDialog::updateDocumentationPage()
+{
+ if (m_hideDocsTab)
+ return;
+
+ m_ui.registeredDocsListWidget->clear();
+ m_namespaceToItem.clear();
+ m_itemToNamespace.clear();
+
+ for (const QString &namespaceName : m_currentSetup.m_namespaceToFileName.keys()) {
+ QListWidgetItem *item = new QListWidgetItem(namespaceName);
+ m_namespaceToItem.insert(namespaceName, item);
+ m_itemToNamespace.insert(item, namespaceName);
+ m_ui.registeredDocsListWidget->addItem(item);
}
+}
+
+void PreferencesDialog::filterSelected(QListWidgetItem *item)
+{
+ Q_UNUSED(item)
+
+ updateCurrentFilter();
+}
+
+void PreferencesDialog::componentsChanged(const QStringList &components)
+{
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty())
+ return;
+
+ m_currentSetup.m_filterToComponents[currentFilter] = components;
+}
- m_ui.filterWidget->addItems(m_filterMap.keys());
+QString PreferencesDialog::suggestedNewFilterName(const QString &initialFilterName) const
+{
+ QString newFilterName = initialFilterName;
- for (const QString &a : helpEngine.filterAttributes())
- new QTreeWidgetItem(m_ui.attributeWidget, QStringList() << a);
+ int counter = 1;
+ while (m_filterToItem.contains(newFilterName)) {
+ newFilterName = initialFilterName + QLatin1Char(' ')
+ + QString::number(++counter);
+ }
- if (!m_filterMap.isEmpty())
- m_ui.filterWidget->setCurrentRow(0);
+ return newFilterName;
}
-void PreferencesDialog::updateAttributes(QListWidgetItem *item)
+QString PreferencesDialog::getUniqueFilterName(const QString &windowTitle,
+ const QString &initialFilterName)
{
- TRACE_OBJ
- const QStringList &checkedList = item ? m_filterMap.value(item->text()) : QStringList();
-
- for (int i = 0; i < m_ui.attributeWidget->topLevelItemCount(); ++i) {
- QTreeWidgetItem *itm = m_ui.attributeWidget->topLevelItem(i);
- if (checkedList.contains(itm->text(0)))
- itm->setCheckState(0, Qt::Checked);
- else
- itm->setCheckState(0, Qt::Unchecked);
+ QString newFilterName = initialFilterName;
+ while (1) {
+ FilterNameDialog dialog(this);
+ dialog.setWindowTitle(windowTitle);
+ dialog.setFilterName(newFilterName);
+ if (dialog.exec() == QDialog::Rejected)
+ return QString();
+
+ newFilterName = dialog.filterName();
+ if (!m_filterToItem.contains(newFilterName))
+ break;
+
+ if (QMessageBox::warning(this, tr("Filter Exists"),
+ tr("The filter \"%1\" already exists.")
+ .arg(newFilterName),
+ QMessageBox::Retry | QMessageBox::Cancel)
+ == QMessageBox::Cancel) {
+ return QString();
+ }
}
+
+ return newFilterName;
+}
+
+void PreferencesDialog::addFilterClicked()
+{
+ const QString newFilterName = getUniqueFilterName(tr("Add Filter"),
+ suggestedNewFilterName(tr("New Filter")));
+ if (newFilterName.isEmpty())
+ return;
+
+ addFilter(newFilterName, QStringList());
}
-void PreferencesDialog::updateFilterMap()
+void PreferencesDialog::renameFilterClicked()
{
- TRACE_OBJ
- if (!m_ui.filterWidget->currentItem())
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty())
return;
- QString filter = m_ui.filterWidget->currentItem()->text();
- if (!m_filterMap.contains(filter))
+
+ const QString newFilterName = getUniqueFilterName(tr("Rename Filter"), currentFilter);
+ if (newFilterName.isEmpty())
return;
- QStringList newAtts;
- QTreeWidgetItem *itm = nullptr;
- for (int i = 0; i < m_ui.attributeWidget->topLevelItemCount(); ++i) {
- itm = m_ui.attributeWidget->topLevelItem(i);
- if (itm->checkState(0) == Qt::Checked)
- newAtts.append(itm->text(0));
- }
- m_filterMap[filter] = newAtts;
+ const QStringList oldComponents = m_currentSetup.m_filterToComponents.value(currentFilter);
+ removeFilter(currentFilter);
+ addFilter(newFilterName, oldComponents);
}
-void PreferencesDialog::addFilter()
+void PreferencesDialog::removeFilterClicked()
{
- TRACE_OBJ
- FilterNameDialog dia(this);
- if (dia.exec() == QDialog::Rejected)
+ const QString &currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem());
+ if (currentFilter.isEmpty())
return;
- QString filterName = dia.filterName();
- if (!m_filterMap.contains(filterName)) {
- m_filterMap.insert(filterName, QStringList());
- m_ui.filterWidget->addItem(filterName);
+ if (QMessageBox::question(this, tr("Remove Filter"),
+ tr("Are you sure you want to remove the \"%1\" filter?")
+ .arg(currentFilter),
+ QMessageBox::Yes | QMessageBox::No)
+ != QMessageBox::Yes) {
+ return;
}
- QList<QListWidgetItem*> lst = m_ui.filterWidget
- ->findItems(filterName, Qt::MatchCaseSensitive);
- m_ui.filterWidget->setCurrentItem(lst.first());
+ removeFilter(currentFilter);
}
-void PreferencesDialog::removeFilter()
+void PreferencesDialog::addFilter(const QString &filterName, const QStringList &components)
{
- TRACE_OBJ
- QListWidgetItem *item =
- m_ui.filterWidget ->takeItem(m_ui.filterWidget->currentRow());
- if (!item)
- return;
+ QListWidgetItem *item = new QListWidgetItem(filterName);
+ m_currentSetup.m_filterToComponents.insert(filterName, components);
+ m_filterToItem.insert(filterName, item);
+ m_itemToFilter.insert(item, filterName);
+ m_ui.filterWidget->insertItem(m_filterToItem.keys().indexOf(filterName), item);
+
+ m_ui.filterWidget->setCurrentItem(item);
+ updateCurrentFilter();
+}
- m_filterMap.remove(item->text());
- m_removedFilters.append(item->text());
+void PreferencesDialog::removeFilter(const QString &filterName)
+{
+ QListWidgetItem *item = m_filterToItem.value(filterName);
+ m_itemToFilter.remove(item);
+ m_filterToItem.remove(filterName);
delete item;
- if (m_ui.filterWidget->count())
- m_ui.filterWidget->setCurrentRow(0);
+
+ m_currentSetup.m_filterToComponents.remove(filterName);
}
-void PreferencesDialog::addDocumentationLocal()
+void PreferencesDialog::addDocumentation()
{
- TRACE_OBJ
const QStringList &fileNames = QFileDialog::getOpenFileNames(this,
tr("Add Documentation"), QString(), tr("Qt Compressed Help Files (*.qch)"));
if (fileNames.isEmpty())
return;
- QStringList invalidFiles;
- QStringList alreadyRegistered;
+ bool added = false;
+
for (const QString &fileName : fileNames) {
- const QString nameSpace = QHelpEngineCore::namespaceName(fileName);
- if (nameSpace.isEmpty()) {
- invalidFiles.append(fileName);
+ const QHelpCollectionDetails details = QHelpCollectionDetails::helpDetails(fileName);
+ const QString namespaceName = details.namespaceName();
+
+ if (m_currentSetup.m_namespaceToFileName.contains(namespaceName))
continue;
- }
- if (m_registeredDocsModel->contains(nameSpace)) {
- alreadyRegistered.append(nameSpace);
- continue;
- }
+ if (m_currentSetup.m_fileNameToNamespace.contains(fileName))
+ continue;
- if (helpEngine.registerDocumentation(fileName)) {
- RegisteredDocEntry entry;
- entry.nameSpace = nameSpace;
- entry.fileName = fileName;
- m_registeredDocsModel->append(entry);
- m_unregDocs.removeAll(nameSpace);
- }
- }
+ const QString component = details.component();
+ m_currentSetup.m_namespaceToFileName.insert(namespaceName, fileName);
+ m_currentSetup.m_fileNameToNamespace.insert(fileName, namespaceName);
- if (!invalidFiles.isEmpty() || !alreadyRegistered.isEmpty()) {
- QString message;
- if (!alreadyRegistered.isEmpty()) {
- for (const QString &ns : qAsConst(alreadyRegistered)) {
- message += tr("The namespace %1 is already registered!")
- .arg(QString("<b>%1</b>").arg(ns)) + QLatin1String("<br>");
- }
- if (!invalidFiles.isEmpty())
- message.append(QLatin1String("<br>"));
- }
+ m_currentSetup.m_namespaceToComponent.insert(namespaceName, component);
+ m_currentSetup.m_componentToNamespace[component].append(namespaceName);
- if (!invalidFiles.isEmpty()) {
- message += tr("The specified file is not a valid Qt Help File!");
- message.append(QLatin1String("<ul>"));
- for (const QString &file : qAsConst(invalidFiles))
- message += QLatin1String("<li>") + file + QLatin1String("</li>");
- message.append(QLatin1String("</ul>"));
- }
- QMessageBox::warning(this, tr("Add Documentation"), message);
+ QListWidgetItem *item = new QListWidgetItem(namespaceName);
+ m_namespaceToItem.insert(namespaceName, item);
+ m_itemToNamespace.insert(item, namespaceName);
+ m_ui.registeredDocsListWidget->insertItem(m_namespaceToItem.keys().indexOf(namespaceName), item);
+
+ added = true;
}
- updateFilterPage();
+ if (added)
+ updateCurrentFilter();
}
-QList<int> PreferencesDialog::currentRegisteredDocsSelection() const
+void PreferencesDialog::removeDocumentation()
{
- QList<int> result;
- for (const QModelIndex &index : m_ui.registeredDocsListView->selectionModel()->selectedRows())
- result.append(m_registereredDocsFilterModel->mapToSource(index).row());
- std::sort(result.begin(), result.end());
- return result;
+ const QList<QListWidgetItem *> selectedItems = m_ui.registeredDocsListWidget->selectedItems();
+ if (selectedItems.isEmpty())
+ return;
+
+ for (QListWidgetItem *item : selectedItems) {
+ const QString namespaceName = m_itemToNamespace.value(item);
+ m_itemToNamespace.remove(item);
+ m_namespaceToItem.remove(namespaceName);
+ delete item;
+
+ const QString fileName = m_currentSetup.m_namespaceToFileName.value(namespaceName);
+ const QString component = m_currentSetup.m_namespaceToComponent.value(namespaceName);
+ m_currentSetup.m_namespaceToComponent.remove(namespaceName);
+ m_currentSetup.m_namespaceToFileName.remove(namespaceName);
+ m_currentSetup.m_fileNameToNamespace.remove(fileName);
+ m_currentSetup.m_componentToNamespace[component].removeOne(namespaceName);
+ if (m_currentSetup.m_componentToNamespace[component].isEmpty())
+ m_currentSetup.m_componentToNamespace.remove(component);
+ }
+
+ updateCurrentFilter();
}
-void PreferencesDialog::removeDocumentation()
+void PreferencesDialog::okClicked()
{
- TRACE_OBJ
+ applyChanges();
+ accept();
+}
- const QList<int> currentSelection = currentRegisteredDocsSelection();
- if (currentSelection.isEmpty())
- return;
+void PreferencesDialog::applyClicked()
+{
+ applyChanges();
+ m_originalSetup = readOriginalSetup();
+ m_currentSetup = m_originalSetup;
+ updateDocumentationPage();
+ updateFilterPage();
+}
- RegisteredDocEntries entries = m_registeredDocsModel->docEntries();
-
- bool foundBefore = false;
- for (int i = currentSelection.size() - 1; i >= 0; --i) {
- const int row = currentSelection.at(i);
- const QString &ns = entries.at(row).nameSpace;
- if (!foundBefore && OpenPagesManager::instance()->pagesOpenForNamespace(ns)) {
- if (0 == QMessageBox::information(this, tr("Remove Documentation"),
- tr("Some documents currently opened in Assistant reference the "
- "documentation you are attempting to remove. Removing the "
- "documentation will close those documents."), tr("Cancel"),
- tr("OK"))) return;
- foundBefore = true;
- }
+template <class T>
+static QMap<QString, T> subtract(const QMap<QString, T> &minuend,
+ const QMap<QString, T> &subtrahend)
+{
+ QMap<QString, T> result = minuend;
- m_unregDocs.append(ns);
- entries.removeAt(row);
+ for (auto itSubtrahend = subtrahend.cbegin(); itSubtrahend != subtrahend.cend(); ++itSubtrahend) {
+ auto itResult = result.find(itSubtrahend.key());
+ if (itResult != result.end() && itSubtrahend.value() == itResult.value())
+ result.erase(itResult);
}
- m_registeredDocsModel->setDocEntries(entries);
-
- if (m_registereredDocsFilterModel->rowCount()) {
- const QModelIndex &first = m_registereredDocsFilterModel->index(0, 0);
- m_ui.registeredDocsListView->selectionModel()->setCurrentIndex(first,
- QItemSelectionModel::ClearAndSelect);
- }
+ return result;
}
void PreferencesDialog::applyChanges()
{
- TRACE_OBJ
- bool filtersWereChanged = false;
- if (!m_hideFiltersTab) {
- if (m_filterMap.count() != m_filterMapBackup.count()) {
- filtersWereChanged = true;
- } else {
- for (auto it = m_filterMapBackup.cbegin(), end = m_filterMapBackup.cend(); it != end && !filtersWereChanged; ++it) {
- if (!m_filterMap.contains(it.key())) {
- filtersWereChanged = true;
- } else {
- const QStringList &a = it.value();
- const QStringList &b = m_filterMap.value(it.key());
- if (a.count() != b.count()) {
- filtersWereChanged = true;
- } else {
- for (const QString &aStr : a) {
- if (!b.contains(aStr)) {
- filtersWereChanged = true;
- break;
- }
- }
- }
- }
- }
- }
+ bool changed = false;
+
+ const QMap<QString, QString> docsToRemove = subtract(
+ m_originalSetup.m_namespaceToFileName,
+ m_currentSetup.m_namespaceToFileName);
+ const QMap<QString, QString> docsToAdd = subtract(
+ m_currentSetup.m_namespaceToFileName,
+ m_originalSetup.m_namespaceToFileName);
+
+ for (const QString &namespaceName : docsToRemove.keys()) {
+ if (!helpEngine.unregisterDocumentation(namespaceName))
+ qWarning() << "Cannot unregister documentation:" << namespaceName;
+ changed = true;
}
- if (filtersWereChanged) {
- for (const QString &filter : qAsConst(m_removedFilters))
- helpEngine.removeCustomFilter(filter);
- for (auto it = m_filterMap.cbegin(), end = m_filterMap.cend(); it != end; ++it)
- helpEngine.addCustomFilter(it.key(), it.value());
+ for (const QString &fileName : docsToAdd.values()) {
+ if (!helpEngine.registerDocumentation(fileName))
+ qWarning() << "Cannot register documentation file:" << fileName;
+ changed = true;
}
- for (const QString &doc : qAsConst(m_unregDocs)) {
- OpenPagesManager::instance()->closePages(doc);
- helpEngine.unregisterDocumentation(doc);
+ const QMap<QString, QStringList> filtersToRemove = subtract(
+ m_originalSetup.m_filterToComponents,
+ m_currentSetup.m_filterToComponents);
+ const QMap<QString, QStringList> filtersToAdd = subtract(
+ m_currentSetup.m_filterToComponents,
+ m_originalSetup.m_filterToComponents);
+
+ const QString &currentFilter = helpEngine.filterEngine()->activeFilter();
+
+ for (const QString &filter : filtersToRemove.keys()) {
+ helpEngine.filterEngine()->removeFilter(filter);
+ if (currentFilter == filter && !filtersToAdd.contains(filter))
+ helpEngine.filterEngine()->setActiveFilter(QString());
+ changed = true;
}
- if (filtersWereChanged || !m_unregDocs.isEmpty())
+ for (auto it = filtersToAdd.cbegin(); it != filtersToAdd.cend(); ++it) {
+ QHelpFilterData data;
+ data.setComponents(it.value());
+ helpEngine.filterEngine()->setFilterData(it.key(), data);
+ changed = true;
+ }
+
+ // in order to update the filtercombobox and indexwidget
+ // according to the new filter configuration
+ if (changed)
helpEngine.setupData();
helpEngine.setShowTabs(m_ui.showTabs->isChecked());
if (m_showTabs != m_ui.showTabs->isChecked())
emit updateUserInterface();
-
- accept();
}
void PreferencesDialog::updateFontSettingsPage()
{
- TRACE_OBJ
m_browserFontPanel = new FontPanel(this);
m_browserFontPanel->setCheckable(true);
m_ui.stackedWidget_2->insertWidget(0, m_browserFontPanel);
@@ -526,35 +543,30 @@ void PreferencesDialog::updateFontSettingsPage()
void PreferencesDialog::appFontSettingToggled(bool on)
{
- TRACE_OBJ
Q_UNUSED(on)
m_appFontChanged = true;
}
void PreferencesDialog::appFontSettingChanged(int index)
{
- TRACE_OBJ
Q_UNUSED(index)
m_appFontChanged = true;
}
void PreferencesDialog::browserFontSettingToggled(bool on)
{
- TRACE_OBJ
Q_UNUSED(on)
m_browserFontChanged = true;
}
void PreferencesDialog::browserFontSettingChanged(int index)
{
- TRACE_OBJ
Q_UNUSED(index)
m_browserFontChanged = true;
}
void PreferencesDialog::updateOptionsPage()
{
- TRACE_OBJ
m_ui.homePageLineEdit->setText(helpEngine.homePage());
int option = helpEngine.startOption();
@@ -573,13 +585,11 @@ void PreferencesDialog::updateOptionsPage()
void PreferencesDialog::setBlankPage()
{
- TRACE_OBJ
m_ui.homePageLineEdit->setText(QLatin1String("about:blank"));
}
void PreferencesDialog::setCurrentPage()
{
- TRACE_OBJ
QString homepage = CentralWidget::instance()->currentSource().toString();
if (homepage.isEmpty())
homepage = QLatin1String("help");
@@ -589,7 +599,6 @@ void PreferencesDialog::setCurrentPage()
void PreferencesDialog::setDefaultPage()
{
- TRACE_OBJ
m_ui.homePageLineEdit->setText(helpEngine.defaultHomePage());
}
diff --git a/src/assistant/assistant/preferencesdialog.h b/src/assistant/assistant/preferencesdialog.h
index 72dd81eda..1e45d9b6d 100644
--- a/src/assistant/assistant/preferencesdialog.h
+++ b/src/assistant/assistant/preferencesdialog.h
@@ -36,9 +36,17 @@ QT_BEGIN_NAMESPACE
class FontPanel;
class HelpEngineWrapper;
-class RegisteredDocsModel;
class QFileSystemWatcher;
-class QSortFilterProxyModel;
+
+struct FilterSetup {
+ QMap<QString, QString> m_namespaceToComponent;
+ QMap<QString, QStringList> m_componentToNamespace;
+
+ QMap<QString, QString> m_namespaceToFileName;
+ QMap<QString, QString> m_fileNameToNamespace;
+
+ QMap<QString, QStringList> m_filterToComponents;
+};
class PreferencesDialog : public QDialog
{
@@ -51,12 +59,17 @@ public:
void showDialog();
private slots:
- void updateAttributes(QListWidgetItem *item);
- void updateFilterMap();
- void addFilter();
- void removeFilter();
- void addDocumentationLocal();
+ void filterSelected(QListWidgetItem *item);
+ void componentsChanged(const QStringList &components);
+ void addFilterClicked();
+ void renameFilterClicked();
+ void removeFilterClicked();
+ void addFilter(const QString &filterName, const QStringList &components);
+ void removeFilter(const QString &filterName);
+ void addDocumentation();
void removeDocumentation();
+ void okClicked();
+ void applyClicked();
void applyChanges();
void appFontSettingToggled(bool on);
void appFontSettingChanged(int index);
@@ -73,19 +86,27 @@ signals:
void updateUserInterface();
private:
+ QString suggestedNewFilterName(const QString &initialFilterName) const;
+ QString getUniqueFilterName(const QString &windowTitle,
+ const QString &initialFilterName = QString());
void updateFilterPage();
+ void updateCurrentFilter();
+ void updateDocumentationPage();
void updateFontSettingsPage();
void updateOptionsPage();
- QList<int> currentRegisteredDocsSelection() const;
+ FilterSetup readOriginalSetup() const;
Ui::PreferencesDialogClass m_ui;
- QMap<QString, QStringList> m_filterMapBackup;
- QMap<QString, QStringList> m_filterMap;
- QStringList m_removedFilters;
- QStringList m_docsBackup;
- RegisteredDocsModel *m_registeredDocsModel;
- QSortFilterProxyModel *m_registereredDocsFilterModel;
- QStringList m_unregDocs;
+
+ FilterSetup m_originalSetup;
+ FilterSetup m_currentSetup;
+
+ QMap<QString, QListWidgetItem *> m_namespaceToItem;
+ QHash<QListWidgetItem *, QString> m_itemToNamespace;
+
+ QMap<QString, QListWidgetItem *> m_filterToItem;
+ QHash<QListWidgetItem *, QString> m_itemToFilter;
+
FontPanel *m_appFontPanel;
FontPanel *m_browserFontPanel;
bool m_appFontChanged;
diff --git a/src/assistant/assistant/preferencesdialog.ui b/src/assistant/assistant/preferencesdialog.ui
index ebefa2458..70a90dd74 100644
--- a/src/assistant/assistant/preferencesdialog.ui
+++ b/src/assistant/assistant/preferencesdialog.ui
@@ -6,24 +6,24 @@
<rect>
<x>0</x>
<y>0</y>
- <width>375</width>
- <height>342</height>
+ <width>378</width>
+ <height>341</height>
</rect>
</property>
<property name="windowTitle">
<string>Preferences</string>
</property>
- <layout class="QVBoxLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="fontsTab">
<attribute name="title">
<string>Fonts</string>
</attribute>
- <layout class="QGridLayout">
+ <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout">
<item>
@@ -69,45 +69,46 @@
<attribute name="title">
<string>Filters</string>
</attribute>
- <layout class="QGridLayout">
- <item row="0" column="0" colspan="2">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Filter:</string>
</property>
</widget>
</item>
- <item row="0" column="2">
+ <item row="0" column="3">
<widget class="QLabel" name="label_2">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
- <string>Attributes:</string>
+ <string>Components:</string>
</property>
</widget>
</item>
- <item row="1" column="0" colspan="2">
+ <item row="1" column="0" colspan="3">
<widget class="QListWidget" name="filterWidget"/>
</item>
- <item row="1" column="2" rowspan="2">
- <widget class="QTreeWidget" name="attributeWidget">
- <column>
- <property name="text">
- <string>1</string>
- </property>
- </column>
- </widget>
+ <item row="1" column="3">
+ <widget class="OptionsWidget" name="componentWidget" native="true"/>
</item>
<item row="2" column="0">
- <widget class="QPushButton" name="filterAddButton">
+ <widget class="QToolButton" name="filterAddButton">
<property name="text">
- <string>Add</string>
+ <string>Add...</string>
</property>
</widget>
</item>
<item row="2" column="1">
- <widget class="QPushButton" name="filterRemoveButton">
+ <widget class="QToolButton" name="filterRenameButton">
+ <property name="text">
+ <string>Rename...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QToolButton" name="filterRemoveButton">
<property name="text">
<string>Remove</string>
</property>
@@ -119,73 +120,62 @@
<attribute name="title">
<string>Documentation</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Registered Documentation:</string>
</property>
</widget>
</item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item row="1" column="0">
+ <widget class="QLineEdit" name="registeredDocsFilterLineEdit">
+ <property name="placeholderText">
+ <string>&lt;Filter&gt;</string>
+ </property>
+ <property name="clearButtonEnabled">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" rowspan="2">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <widget class="QLineEdit" name="registeredDocsFilterLineEdit">
- <property name="placeholderText">
- <string>&lt;Filter&gt;</string>
- </property>
- <property name="clearButtonEnabled">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListView" name="registeredDocsListView">
- <property name="selectionMode">
- <enum>QAbstractItemView::ExtendedSelection</enum>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QPushButton" name="docAddButton">
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ </widget>
</item>
<item>
- <layout class="QVBoxLayout">
- <property name="spacing">
- <number>6</number>
+ <widget class="QPushButton" name="docRemoveButton">
+ <property name="text">
+ <string>Remove</string>
</property>
- <item>
- <widget class="QPushButton" name="docAddButton">
- <property name="text">
- <string>Add...</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="docRemoveButton">
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
</item>
</layout>
</item>
+ <item row="2" column="0">
+ <widget class="QListWidget" name="registeredDocsListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="optionsTab">
@@ -348,38 +338,23 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout">
- <property name="spacing">
- <number>6</number>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
+ </widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>OptionsWidget</class>
+ <extends>QWidget</extends>
+ <header>optionswidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections>
<connection>
diff --git a/src/assistant/assistant/remotecontrol.cpp b/src/assistant/assistant/remotecontrol.cpp
index cab7b5db6..7fdbee41e 100644
--- a/src/assistant/assistant/remotecontrol.cpp
+++ b/src/assistant/assistant/remotecontrol.cpp
@@ -42,6 +42,7 @@
#include <QtWidgets/QApplication>
#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpFilterEngine>
#include <QtHelp/QHelpIndexWidget>
#include <QtHelp/QHelpSearchQueryWidget>
@@ -223,12 +224,12 @@ void RemoteControl::handleExpandTocCommand(const QString &arg)
void RemoteControl::handleSetCurrentFilterCommand(const QString &arg)
{
TRACE_OBJ
- if (helpEngine.customFilters().contains(arg)) {
+ if (helpEngine.filterEngine()->filters().contains(arg)) {
if (m_caching) {
clearCache();
m_currentFilter = arg;
} else {
- helpEngine.setCurrentFilter(arg);
+ helpEngine.filterEngine()->setActiveFilter(arg);
}
}
}
@@ -270,7 +271,7 @@ void RemoteControl::applyCache()
if (!links.isEmpty())
CentralWidget::instance()->setSource(links.first());
} else if (!m_currentFilter.isEmpty()) {
- helpEngine.setCurrentFilter(m_currentFilter);
+ helpEngine.filterEngine()->setActiveFilter(m_currentFilter);
}
if (m_syncContents)
diff --git a/src/assistant/help/help.pro b/src/assistant/help/help.pro
index 5bdc501fc..a1616b233 100644
--- a/src/assistant/help/help.pro
+++ b/src/assistant/help/help.pro
@@ -14,6 +14,7 @@ SOURCES += qhelpenginecore.cpp \
qhelpengine.cpp \
qhelpcollectiondetails.cpp \
qhelpfilterdata.cpp \
+ qhelpfilterengine.cpp \
qhelpdbreader.cpp \
qhelpcontentwidget.cpp \
qhelpindexwidget.cpp \
@@ -31,6 +32,7 @@ HEADERS += qhelpenginecore.h \
qhelpengine_p.h \
qhelpcollectiondetails.h \
qhelpfilterdata.h \
+ qhelpfilterengine.h \
qhelp_global.h \
qhelpdbreader_p.h \
qhelpcontentwidget.h \
diff --git a/src/assistant/help/qhelpcollectionhandler.cpp b/src/assistant/help/qhelpcollectionhandler.cpp
index e59acaac5..0cb6264dd 100644
--- a/src/assistant/help/qhelpcollectionhandler.cpp
+++ b/src/assistant/help/qhelpcollectionhandler.cpp
@@ -925,8 +925,8 @@ bool QHelpCollectionHandler::fileExists(const QUrl &url) const
if (fileInfo.namespaceName.isEmpty())
return false;
- m_query->prepare(QLatin1String("SELECT COUNT (DISTINCT NamespaceTable.Id)"
- "FROM"
+ m_query->prepare(QLatin1String("SELECT COUNT (DISTINCT NamespaceTable.Id) "
+ "FROM "
"FileNameTable, "
"NamespaceTable, "
"FolderTable "
diff --git a/src/assistant/help/qhelpcontentwidget.cpp b/src/assistant/help/qhelpcontentwidget.cpp
index 412e14528..901c4c56b 100644
--- a/src/assistant/help/qhelpcontentwidget.cpp
+++ b/src/assistant/help/qhelpcontentwidget.cpp
@@ -76,15 +76,18 @@ public:
~QHelpContentProvider() override;
void collectContents(const QString &customFilterName);
void stopCollecting();
- QHelpContentItem *rootItem();
+ QHelpContentItem *takeContentItem();
private:
void run() override;
QHelpEnginePrivate *m_helpEngine;
+ QString m_currentFilter;
QStringList m_filterAttributes;
- QQueue<QHelpContentItem*> m_rootItems;
+ QString m_collectionFile;
+ QHelpContentItem *m_rootItem = nullptr;
QMutex m_mutex;
+ bool m_usesFilterEngine = false;
bool m_abort = false;
};
@@ -194,7 +197,10 @@ QHelpContentProvider::~QHelpContentProvider()
void QHelpContentProvider::collectContents(const QString &customFilterName)
{
m_mutex.lock();
+ m_currentFilter = customFilterName;
m_filterAttributes = m_helpEngine->q->filterAttributes(customFilterName);
+ m_collectionFile = m_helpEngine->collectionHandler->collectionFile();
+ m_usesFilterEngine = m_helpEngine->usesFilterEngine;
m_mutex.unlock();
if (isRunning())
@@ -215,16 +221,16 @@ void QHelpContentProvider::stopCollecting()
// either way never resetting m_abort to false from within the run() method
m_abort = false;
}
- qDeleteAll(m_rootItems);
- m_rootItems.clear();
+ delete m_rootItem;
+ m_rootItem = nullptr;
}
-QHelpContentItem *QHelpContentProvider::rootItem()
+QHelpContentItem *QHelpContentProvider::takeContentItem()
{
QMutexLocker locker(&m_mutex);
- if (m_rootItems.isEmpty())
- return nullptr;
- return m_rootItems.dequeue();
+ QHelpContentItem *content = m_rootItem;
+ m_rootItem = nullptr;
+ return content;
}
// TODO: this is a copy from helpcollectionhandler, make it common
@@ -258,8 +264,12 @@ void QHelpContentProvider::run()
m_mutex.lock();
QHelpContentItem * const rootItem = new QHelpContentItem(QString(), QString(), nullptr);
+ const QString currentFilter = m_currentFilter;
const QStringList attributes = m_filterAttributes;
- const QString collectionFile = m_helpEngine->collectionHandler->collectionFile();
+ const QString collectionFile = m_collectionFile;
+ const bool usesFilterEngine = m_usesFilterEngine;
+ delete m_rootItem;
+ m_rootItem = nullptr;
m_mutex.unlock();
if (collectionFile.isEmpty())
@@ -269,8 +279,9 @@ void QHelpContentProvider::run()
if (!collectionHandler.openCollectionFile())
return;
- const QList<QHelpCollectionHandler::ContentsData> result
- = collectionHandler.contentsForFilter(attributes);
+ const QList<QHelpCollectionHandler::ContentsData> result = usesFilterEngine
+ ? collectionHandler.contentsForFilter(currentFilter)
+ : collectionHandler.contentsForFilter(attributes);
for (const auto &contentsData : result) {
m_mutex.lock();
@@ -328,7 +339,7 @@ CHECK_DEPTH:
}
m_mutex.lock();
- m_rootItems.enqueue(rootItem);
+ m_rootItem = rootItem;
m_abort = false;
m_mutex.unlock();
}
@@ -375,11 +386,6 @@ QHelpContentModel::~QHelpContentModel()
delete d;
}
-void QHelpContentModel::invalidateContents(bool onShutDown)
-{
- Q_UNUSED(onShutDown)
-}
-
/*!
Creates new contents by querying the help system
for contents specified for the \a customFilterName.
@@ -405,7 +411,7 @@ void QHelpContentModel::insertContents()
if (d->qhelpContentProvider->isRunning())
return;
- QHelpContentItem * const newRootItem = d->qhelpContentProvider->rootItem();
+ QHelpContentItem * const newRootItem = d->qhelpContentProvider->takeContentItem();
if (!newRootItem)
return;
beginResetModel();
diff --git a/src/assistant/help/qhelpcontentwidget.h b/src/assistant/help/qhelpcontentwidget.h
index 01594d60f..b316ebba9 100644
--- a/src/assistant/help/qhelpcontentwidget.h
+++ b/src/assistant/help/qhelpcontentwidget.h
@@ -100,7 +100,6 @@ Q_SIGNALS:
private Q_SLOTS:
void insertContents();
- void invalidateContents(bool onShutDown = false);
private:
QHelpContentModel(QHelpEnginePrivate *helpEngine);
diff --git a/src/assistant/help/qhelpengine.cpp b/src/assistant/help/qhelpengine.cpp
index 28825e2ed..19e44cd91 100644
--- a/src/assistant/help/qhelpengine.cpp
+++ b/src/assistant/help/qhelpengine.cpp
@@ -44,6 +44,7 @@
#include "qhelpindexwidget.h"
#include "qhelpsearchengine.h"
#include "qhelpcollectionhandler_p.h"
+#include "qhelpfilterengine.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
@@ -68,6 +69,8 @@ void QHelpEnginePrivate::init(const QString &collectionFile,
this, &QHelpEnginePrivate::scheduleApplyCurrentFilter);
connect(helpEngineCore, &QHelpEngineCore::currentFilterChanged,
this, &QHelpEnginePrivate::scheduleApplyCurrentFilter);
+ connect(helpEngineCore->filterEngine(), &QHelpFilterEngine::filterActivated,
+ this, &QHelpEnginePrivate::scheduleApplyCurrentFilter);
}
void QHelpEnginePrivate::scheduleApplyCurrentFilter()
@@ -85,8 +88,11 @@ void QHelpEnginePrivate::scheduleApplyCurrentFilter()
void QHelpEnginePrivate::applyCurrentFilter()
{
m_isApplyCurrentFilterScheduled = false;
- contentModel->createContents(currentFilter);
- indexModel->createIndex(currentFilter);
+ const QString filter = usesFilterEngine
+ ? q->filterEngine()->activeFilter()
+ : currentFilter;
+ contentModel->createContents(filter);
+ indexModel->createIndex(filter);
}
void QHelpEnginePrivate::setContentsWidgetBusy()
diff --git a/src/assistant/help/qhelpengine_p.h b/src/assistant/help/qhelpengine_p.h
index 847715eb3..558013e77 100644
--- a/src/assistant/help/qhelpengine_p.h
+++ b/src/assistant/help/qhelpengine_p.h
@@ -68,6 +68,7 @@ class QHelpIndexModel;
class QHelpIndexWidget;
class QHelpSearchEngine;
class QHelpCollectionHandler;
+class QHelpFilterEngine;
class QHelpEngineCorePrivate : public QObject
{
@@ -82,10 +83,12 @@ public:
bool setup();
QHelpCollectionHandler *collectionHandler = nullptr;
+ QHelpFilterEngine *filterEngine = nullptr;
QString currentFilter;
QString error;
bool needsSetup = true;
bool autoSaveFilter = true;
+ bool usesFilterEngine = false;
protected:
QHelpEngineCore *q;
diff --git a/src/assistant/help/qhelpenginecore.cpp b/src/assistant/help/qhelpenginecore.cpp
index fc6366d2a..6f1794a60 100644
--- a/src/assistant/help/qhelpenginecore.cpp
+++ b/src/assistant/help/qhelpenginecore.cpp
@@ -41,6 +41,7 @@
#include "qhelpengine_p.h"
#include "qhelpdbreader_p.h"
#include "qhelpcollectionhandler_p.h"
+#include "qhelpfilterengine.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
@@ -59,6 +60,7 @@ void QHelpEngineCorePrivate::init(const QString &collectionFile,
collectionHandler = new QHelpCollectionHandler(collectionFile, helpEngineCore);
connect(collectionHandler, &QHelpCollectionHandler::error,
this, &QHelpEngineCorePrivate::errorReceived);
+ filterEngine->setCollectionHandler(collectionHandler);
needsSetup = true;
}
@@ -111,11 +113,14 @@ void QHelpEngineCorePrivate::errorReceived(const QString &msg)
depends on the currently set custom filter. Depending on the filter,
the function may return different results.
- Every help engine can contain any number of custom filters. A custom
- filter is defined by a name and set of filter attributes and can be
- added to the help engine by calling addCustomFilter(). Analogous,
- it is removed by calling removeCustomFilter(). customFilters() returns
- all defined filters.
+ The help engine can contain any number of custom filters.
+ The management of the filters, including adding new filters,
+ changing filter definitions, or removing existing filters,
+ is done through the QHelpFilterEngine class, which can be accessed
+ by the filterEngine() method. This replaces older filter API that is
+ deprecated since Qt 5.13. Please call setUsesFilterEngine() with
+ \c true to enable the new functionality.
+
The help engine also offers the possibility to set and read values
in a persistant way comparable to ini files or Windows registry
@@ -152,6 +157,9 @@ void QHelpEngineCorePrivate::errorReceived(const QString &msg)
/*!
\fn void QHelpEngineCore::currentFilterChanged(const QString &newFilter)
+ \obsolete
+
+ QHelpFilterEngine::filterActivated() should be used instead.
This signal is emitted when the current filter is changed to
\a newFilter.
@@ -173,6 +181,7 @@ QHelpEngineCore::QHelpEngineCore(const QString &collectionFile, QObject *parent)
: QObject(parent)
{
d = new QHelpEngineCorePrivate();
+ d->filterEngine = new QHelpFilterEngine(this);
d->init(collectionFile, this);
}
@@ -184,6 +193,7 @@ QHelpEngineCore::QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
: QObject(parent)
{
d = helpEngineCorePrivate;
+ d->filterEngine = new QHelpFilterEngine(this);
}
/*!
@@ -222,6 +232,19 @@ void QHelpEngineCore::setCollectionFile(const QString &fileName)
}
/*!
+ \since 5.13
+
+ Returns the filter engine associated with this help engine.
+ The filter engine allows for adding, changing, and removing existing
+ filters for this help engine. To use the engine you also have to call
+ \l setUsesFilterEngine() set to \c true.
+*/
+QHelpFilterEngine *QHelpEngineCore::filterEngine() const
+{
+ return d->filterEngine;
+}
+
+/*!
Sets up the help engine by processing the information found
in the collection file and returns true if successful; otherwise
returns false.
@@ -345,6 +368,10 @@ QStringList QHelpEngineCore::registeredDocumentations() const
}
/*!
+ \obsolete
+
+ QHelpFilterEngine::filters() should be used instead.
+
Returns a list of custom filters.
\sa addCustomFilter(), removeCustomFilter()
@@ -357,6 +384,10 @@ QStringList QHelpEngineCore::customFilters() const
}
/*!
+ \obsolete
+
+ QHelpFilterEngine::setFilterData() should be used instead.
+
Adds the new custom filter \a filterName. The filter attributes
are specified by \a attributes. If the filter already exists,
its attribute set is replaced. The function returns true if
@@ -373,6 +404,10 @@ bool QHelpEngineCore::addCustomFilter(const QString &filterName,
}
/*!
+ \obsolete
+
+ QHelpFilterEngine::removeFilter() should be used instead.
+
Returns true if the filter \a filterName was removed successfully,
otherwise false.
@@ -386,6 +421,10 @@ bool QHelpEngineCore::removeCustomFilter(const QString &filterName)
}
/*!
+ \obsolete
+
+ QHelpFilterEngine::availableComponents() should be used instead.
+
Returns a list of all defined filter attributes.
*/
QStringList QHelpEngineCore::filterAttributes() const
@@ -396,6 +435,10 @@ QStringList QHelpEngineCore::filterAttributes() const
}
/*!
+ \obsolete
+
+ QHelpFilterEngine::filterData() should be used instead.
+
Returns a list of filter attributes used by the custom
filter \a filterName.
*/
@@ -407,10 +450,13 @@ QStringList QHelpEngineCore::filterAttributes(const QString &filterName) const
}
/*!
+ \obsolete
\property QHelpEngineCore::currentFilter
\brief the name of the custom filter currently applied.
\since 4.5
+ QHelpFilterEngine::activeFilter() should be used instead.
+
Setting this property will save the new custom filter permanently in the
help collection file. To set a custom filter without saving it
permanently, disable the auto save filter mode.
@@ -446,6 +492,10 @@ void QHelpEngineCore::setCurrentFilter(const QString &filterName)
}
/*!
+ \obsolete
+
+ QHelpFilterEngine::filterData() should be used instead.
+
Returns a list of filter attributes for the different filter sections
defined in the Qt compressed help file with the given namespace
\a namespaceName.
@@ -459,6 +509,10 @@ QList<QStringList> QHelpEngineCore::filterAttributeSets(const QString &namespace
}
/*!
+ \obsolete
+
+ files() should be used instead.
+
Returns a list of files contained in the Qt compressed help file \a
namespaceName. The files can be filtered by \a filterAttributes as
well as by their extension \a extensionFilter (e.g. 'html').
@@ -485,22 +539,55 @@ QList<QUrl> QHelpEngineCore::files(const QString namespaceName,
}
/*!
- Returns an invalid URL if the file \a url cannot be found.
- If the file exists, either the same url is returned or a
- different url if the file is located in a different namespace
- which is merged via a common virtual folder.
+ Returns a list of files contained in the Qt compressed help file
+ for \a namespaceName. The files can be filtered by \a filterName as
+ well as by their extension \a extensionFilter (for example, 'html').
+*/
+QList<QUrl> QHelpEngineCore::files(const QString namespaceName,
+ const QString &filterName,
+ const QString &extensionFilter)
+{
+ QList<QUrl> res;
+ if (!d->setup())
+ return res;
+
+ QUrl url;
+ url.setScheme(QLatin1String("qthelp"));
+ url.setAuthority(namespaceName);
+
+ const QStringList &files = d->collectionHandler->files(
+ namespaceName, filterName, extensionFilter);
+ for (const QString &file : files) {
+ url.setPath(QLatin1String("/") + file);
+ res.append(url);
+ }
+ return res;
+}
+
+/*!
+ Returns the corrected URL for the \a url that may refer to
+ a different namespace defined by the virtual folder defined
+ as a part of the \a url. If the virtual folder matches the namespace
+ of the \a url, the method just checks if the file exists and returns
+ the same \a url. When the virtual folder doesn't match the namespace
+ of the \a url, it tries to find the best matching namespace according
+ to the active filter. When the namespace is found, it returns the
+ corrected URL if the file exists, otherwise it returns an invalid URL.
*/
QUrl QHelpEngineCore::findFile(const QUrl &url) const
{
if (!d->setup())
return url;
- const QStringList &attributes = filterAttributes(currentFilter());
- QUrl result = d->collectionHandler->findFile(url, attributes);
+ QUrl result = d->usesFilterEngine
+ ? d->collectionHandler->findFile(url, d->filterEngine->activeFilter())
+ : d->collectionHandler->findFile(url, filterAttributes(currentFilter())); // obsolete
if (!result.isEmpty())
return result;
- result = d->collectionHandler->findFile(url, QStringList());
+ result = d->usesFilterEngine
+ ? d->collectionHandler->findFile(url, QString())
+ : d->collectionHandler->findFile(url, QStringList()); // obsolete
if (!result.isEmpty())
return result;
@@ -522,30 +609,37 @@ QByteArray QHelpEngineCore::fileData(const QUrl &url) const
}
/*!
- Returns documents found for the \a id. The map contains the
- document titles and their URLs.
- The returned map contents depends on the current filter, meaning only the keywords
- registered for the current filter will be returned.
+ Returns a map of the documents found for the \a id. The map contains the
+ document titles and their URLs. The returned map contents depend on
+ the current filter, and therefore only the identifiers registered for
+ the current filter will be returned.
*/
QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id) const
{
if (!d->setup())
return QMap<QString, QUrl>();
+ if (d->usesFilterEngine)
+ return d->collectionHandler->linksForIdentifier(id, d->filterEngine->activeFilter());
+
+ // obsolete
return d->collectionHandler->linksForIdentifier(id, filterAttributes(d->currentFilter));
}
/*!
- \since 4.5
-
- Returns all documents found for the \a keyword. The returned map consists of the
- document titles and their URLs.
+ Returns a map of all the documents found for the \a keyword. The map
+ contains the document titles and URLs. The returned map contents depend
+ on the current filter, and therefore only the keywords registered for
+ the current filter will be returned.
*/
QMap<QString, QUrl> QHelpEngineCore::linksForKeyword(const QString &keyword) const
{
if (!d->setup())
return QMap<QString, QUrl>();
+ if (d->usesFilterEngine)
+ return d->collectionHandler->linksForKeyword(keyword, d->filterEngine->activeFilter());
+
return d->collectionHandler->linksForKeyword(keyword, filterAttributes(d->currentFilter));
}
@@ -621,7 +715,7 @@ QString QHelpEngineCore::error() const
\since 4.5
If QHelpEngineCore is in auto save filter mode, the current filter is
- automatically saved when it is changed by the setCurrentFilter()
+ automatically saved when it is changed by the QHelpFilterEngine::setActiveFilter()
function. The filter is saved persistently in the help collection file.
By default, this mode is on.
@@ -636,4 +730,29 @@ bool QHelpEngineCore::autoSaveFilter() const
return d->autoSaveFilter;
}
+/*!
+ \since 5.13
+
+ Enables or disables the new filter engine functionality
+ inside the help engine, according to the passed \a uses parameter.
+
+ \sa filterEngine()
+*/
+void QHelpEngineCore::setUsesFilterEngine(bool uses)
+{
+ d->usesFilterEngine = uses;
+}
+
+/*!
+ \since 5.13
+
+ Returns whether the help engine uses the new filter functionality.
+
+ \sa filterEngine()
+*/
+bool QHelpEngineCore::usesFilterEngine() const
+{
+ return d->usesFilterEngine;
+}
+
QT_END_NAMESPACE
diff --git a/src/assistant/help/qhelpenginecore.h b/src/assistant/help/qhelpenginecore.h
index 6a2bf0e7d..91950290e 100644
--- a/src/assistant/help/qhelpenginecore.h
+++ b/src/assistant/help/qhelpenginecore.h
@@ -49,8 +49,8 @@
QT_BEGIN_NAMESPACE
-
class QHelpEngineCorePrivate;
+class QHelpFilterEngine;
class QHELP_EXPORT QHelpEngineCore : public QObject
{
@@ -63,6 +63,8 @@ public:
explicit QHelpEngineCore(const QString &collectionFile, QObject *parent = nullptr);
virtual ~QHelpEngineCore();
+ QHelpFilterEngine *filterEngine() const;
+
bool setupData();
QString collectionFile() const;
@@ -74,7 +76,10 @@ public:
bool registerDocumentation(const QString &documentationFileName);
bool unregisterDocumentation(const QString &namespaceName);
QString documentationFileName(const QString &namespaceName);
+ QStringList registeredDocumentations() const;
+ QByteArray fileData(const QUrl &url) const;
+#if QT_DEPRECATED_SINCE(5,13)
QStringList customFilters() const;
bool removeCustomFilter(const QString &filterName);
bool addCustomFilter(const QString &filterName,
@@ -86,13 +91,16 @@ public:
QString currentFilter() const;
void setCurrentFilter(const QString &filterName);
- QStringList registeredDocumentations() const;
QList<QStringList> filterAttributeSets(const QString &namespaceName) const;
QList<QUrl> files(const QString namespaceName,
const QStringList &filterAttributes,
const QString &extensionFilter = QString());
+#endif
+
+ QList<QUrl> files(const QString namespaceName,
+ const QString &filterName,
+ const QString &extensionFilter = QString());
QUrl findFile(const QUrl &url) const;
- QByteArray fileData(const QUrl &url) const;
QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
QMap<QString, QUrl> linksForKeyword(const QString &keyword) const;
@@ -110,12 +118,18 @@ public:
void setAutoSaveFilter(bool save);
bool autoSaveFilter() const;
+ void setUsesFilterEngine(bool uses);
+ bool usesFilterEngine() const;
+
Q_SIGNALS:
void setupStarted();
void setupFinished();
- void currentFilterChanged(const QString &newFilter);
void warning(const QString &msg);
+
+#if QT_DEPRECATED_SINCE(5,13)
+ void currentFilterChanged(const QString &newFilter);
void readersAboutToBeInvalidated();
+#endif
protected:
QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
diff --git a/src/assistant/help/qhelpfilterdata.cpp b/src/assistant/help/qhelpfilterdata.cpp
index 0cd6ad3fb..3063136ed 100644
--- a/src/assistant/help/qhelpfilterdata.cpp
+++ b/src/assistant/help/qhelpfilterdata.cpp
@@ -54,31 +54,65 @@ public:
QStringList m_components;
};
+/*!
+ \class QHelpFilterData
+ \since 5.13
+ \inmodule QtHelp
+ \brief The QHelpFilterData class provides details for the filters
+ used by QHelpFilterEngine.
+
+ By using setComponents() you may constrain the search results to
+ documents that belong only to components specified on the given list.
+
+ \sa QHelpFilterEngine
+*/
+
+/*!
+ Constructs the empty filter.
+*/
QHelpFilterData::QHelpFilterData()
: d(new QHelpFilterDataPrivate)
{
}
+/*!
+ Constructs a copy of \a other.
+*/
QHelpFilterData::QHelpFilterData(const QHelpFilterData &other)
: d(other.d)
{
}
+/*!
+ Destroys the filter.
+*/
QHelpFilterData::~QHelpFilterData()
{
}
+/*!
+ Assigns \a other to this filter and returns a reference to this filter.
+*/
QHelpFilterData &QHelpFilterData::operator=(const QHelpFilterData &other)
{
d = other.d;
return *this;
}
+/*!
+ Specifies the component list that is used for filtering
+ the search results. Only the results which match the \a components
+ will be returned.
+*/
void QHelpFilterData::setComponents(const QStringList &components)
{
d->m_components = components;
}
+/*!
+ Returns the component list that is used for filtering
+ the search results.
+*/
QStringList QHelpFilterData::components() const
{
return d->m_components;
diff --git a/src/assistant/help/qhelpfilterengine.cpp b/src/assistant/help/qhelpfilterengine.cpp
new file mode 100644
index 000000000..6a57e1cdc
--- /dev/null
+++ b/src/assistant/help/qhelpfilterengine.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+#include "qhelpfilterengine.h"
+#include "qhelpenginecore.h"
+#include "qhelpfilterdata.h"
+#include "qhelpdbreader_p.h"
+#include "qhelpcollectionhandler_p.h"
+
+#include <QtCore/QThread>
+
+QT_BEGIN_NAMESPACE
+
+static const char ActiveFilter[] = "activeFilter";
+
+class QHelpFilterEnginePrivate
+{
+public:
+ bool setup();
+
+ QHelpFilterEngine *q = nullptr;
+ QHelpEngineCore *m_helpEngine = nullptr;
+ QHelpCollectionHandler *m_collectionHandler = nullptr;
+ QString m_currentFilter;
+ bool m_needsSetup = true;
+};
+
+bool QHelpFilterEnginePrivate::setup()
+{
+ if (!m_collectionHandler)
+ return false;
+
+ if (!m_needsSetup)
+ return true;
+
+ if (!m_helpEngine->setupData())
+ return false;
+
+ m_needsSetup = false;
+
+ const QString filter = m_collectionHandler->customValue(
+ QLatin1String(ActiveFilter), QString()).toString();
+ if (!filter.isEmpty() && m_collectionHandler->filters().contains(filter))
+ m_currentFilter = filter;
+
+ emit q->filterActivated(m_currentFilter);
+ return true;
+}
+
+//////////////
+
+/*!
+ \class QHelpFilterEngine
+ \since 5.13
+ \inmodule QtHelp
+ \brief The QHelpFilterEngine class provides a filtered view of the
+ help contents.
+
+ The filter engine allows the management of filters associated with
+ a QHelpEngineCore instance. The help engine internally creates an
+ instance of the filter engine, which can be accessed by calling
+ QHelpEngineCore::filterEngine(). Therefore, the public constructor
+ of this class is disabled.
+
+ The filters are identified by a filter name string. Filter details are
+ described by the \l QHelpFilterData class.
+
+ The filter engine allows for adding new filters and changing the existing
+ filters' data through the setFilterData() method. An existing filter can
+ be removed through the removeFilter() method.
+
+ Out of the registered filters one can be marked as the active one.
+ The active filter will be used by the associated help engine for returning
+ filtered results of many different functions, such as content, index, or
+ search results. If no filter is marked active, the help engine returns the
+ full results list available.
+
+ The active filter is returned by activeFilter() and it can be changed by
+ setActiveFilter().
+
+ \sa QHelpEngineCore
+*/
+
+/*!
+ \fn void QHelpFilterEngine::filterActivated(const QString &newFilter)
+
+ This signal is emitted when the active filter is set. \a newFilter
+ specifies the name of the filter.
+
+ \sa setActiveFilter()
+*/
+
+/*!
+ \internal
+ Constructs the filter engine for \a helpEngine.
+*/
+QHelpFilterEngine::QHelpFilterEngine(QHelpEngineCore *helpEngine)
+ : QObject(helpEngine),
+ d(new QHelpFilterEnginePrivate)
+{
+ d->q = this;
+ d->m_helpEngine = helpEngine;
+}
+
+/*!
+ \internal
+ Destroys the existing filter engine.
+*/
+QHelpFilterEngine::~QHelpFilterEngine()
+{
+ delete d;
+}
+
+/*!
+ \internal
+ Sets the \a collectionHandler to be used for this filter engine.
+*/
+void QHelpFilterEngine::setCollectionHandler(QHelpCollectionHandler *collectionHandler)
+{
+ d->m_collectionHandler = collectionHandler;
+ d->m_currentFilter = QString();
+ d->m_needsSetup = true;
+}
+
+/*!
+ Returns the map of all the available namespaces as keys
+ together with their associated components as values.
+*/
+QMap<QString, QString> QHelpFilterEngine::namespaceToComponent() const
+{
+ if (!d->setup())
+ return QMap<QString, QString>();
+ return d->m_collectionHandler->namespaceToComponent();
+}
+
+/*!
+ Returns the list of all filter names defined inside the filter engine.
+*/
+QStringList QHelpFilterEngine::filters() const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->m_collectionHandler->filters();
+}
+
+/*!
+ Returns the list of all available components defined in all
+ registered documentation files.
+*/
+QStringList QHelpFilterEngine::availableComponents() const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->m_collectionHandler->availableComponents();
+}
+
+/*!
+ Returns the filter details associated with \a filterName.
+*/
+QHelpFilterData QHelpFilterEngine::filterData(const QString &filterName) const
+{
+ if (!d->setup())
+ return QHelpFilterData();
+ return d->m_collectionHandler->filterData(filterName);
+}
+
+/*!
+ Changes the existing filter details of the filter identified by
+ \a filterName to \a filterData. If the filter does not exist, a
+ new filter is created.
+
+ Returns \c true if setting the filter succeeded, otherwise returns \c false.
+*/
+bool QHelpFilterEngine::setFilterData(const QString &filterName, const QHelpFilterData &filterData)
+{
+ if (!d->setup())
+ return false;
+ return d->m_collectionHandler->setFilterData(filterName, filterData);
+}
+
+/*!
+ Removes the filter identified by \a filterName.
+
+ Returns \c true if removing the filter succeeded, otherwise returns
+ \c false.
+*/
+bool QHelpFilterEngine::removeFilter(const QString &filterName)
+{
+ if (!d->setup())
+ return false;
+ return d->m_collectionHandler->removeFilter(filterName);
+}
+
+/*!
+ Returns the name of the currently active filter.
+*/
+QString QHelpFilterEngine::activeFilter() const
+{
+ if (!d->setup())
+ return QString();
+ return d->m_currentFilter;
+}
+
+/*!
+ Changes the currently active filter to \a filterName.
+
+ Returns \c true if changing the filter succeeded, otherwise
+ returns \c false.
+*/
+bool QHelpFilterEngine::setActiveFilter(const QString &filterName)
+{
+ if (!d->setup())
+ return false;
+
+ if (filterName == d->m_currentFilter)
+ return true;
+
+ if (!filterName.isEmpty() && !d->m_collectionHandler->filters().contains(filterName))
+ return false;
+
+ d->m_currentFilter = filterName;
+ d->m_collectionHandler->setCustomValue(QLatin1String(ActiveFilter),
+ d->m_currentFilter);
+
+ emit filterActivated(d->m_currentFilter);
+
+ return true;
+}
+
+/*!
+ Returns the list of all registered documentation namespaces that match
+ the filter identified by \a filterName.
+*/
+QStringList QHelpFilterEngine::namespacesForFilter(const QString &filterName) const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->m_collectionHandler->namespacesForFilter(filterName);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/help/qhelpfilterengine.h b/src/assistant/help/qhelpfilterengine.h
new file mode 100644
index 000000000..717b0ed60
--- /dev/null
+++ b/src/assistant/help/qhelpfilterengine.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+#ifndef QHELPFILTERENGINE_H
+#define QHELPFILTERENGINE_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QUrl;
+template <class K, class T>
+class QMap;
+
+class QHelpCollectionHandler;
+class QHelpEngineCore;
+class QHelpFilterData;
+class QHelpFilterEnginePrivate;
+
+class QHELP_EXPORT QHelpFilterEngine : public QObject
+{
+ Q_OBJECT
+public:
+ QMap<QString, QString> namespaceToComponent() const;
+
+ QStringList filters() const;
+
+ QString activeFilter() const;
+ bool setActiveFilter(const QString &filterName);
+
+ QStringList availableComponents() const;
+
+ QHelpFilterData filterData(const QString &filterName) const;
+ bool setFilterData(const QString &filterName, const QHelpFilterData &filterData);
+
+ bool removeFilter(const QString &filterName);
+
+ QStringList namespacesForFilter(const QString &filterName) const;
+
+Q_SIGNALS:
+ void filterActivated(const QString &newFilter);
+
+protected:
+ explicit QHelpFilterEngine(QHelpEngineCore *helpEngine);
+ virtual ~QHelpFilterEngine();
+
+private:
+ void setCollectionHandler(QHelpCollectionHandler *collectionHandler);
+
+ QHelpFilterEnginePrivate *d;
+ friend class QHelpEngineCore;
+ friend class QHelpEngineCorePrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif // QHELPFILTERENGINE_H
diff --git a/src/assistant/help/qhelpindexwidget.cpp b/src/assistant/help/qhelpindexwidget.cpp
index e76dd4fb4..fa70dd438 100644
--- a/src/assistant/help/qhelpindexwidget.cpp
+++ b/src/assistant/help/qhelpindexwidget.cpp
@@ -65,8 +65,9 @@ private:
void run() override;
QHelpEnginePrivate *m_helpEngine;
- QStringList m_indices;
+ QString m_currentFilter;
QStringList m_filterAttributes;
+ QStringList m_indices;
mutable QMutex m_mutex;
};
@@ -98,6 +99,7 @@ QHelpIndexProvider::~QHelpIndexProvider()
void QHelpIndexProvider::collectIndices(const QString &customFilterName)
{
m_mutex.lock();
+ m_currentFilter = customFilterName;
m_filterAttributes = m_helpEngine->q->filterAttributes(customFilterName);
m_mutex.unlock();
@@ -122,9 +124,10 @@ QStringList QHelpIndexProvider::indices() const
void QHelpIndexProvider::run()
{
m_mutex.lock();
- m_indices.clear();
+ 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())
@@ -134,7 +137,9 @@ void QHelpIndexProvider::run()
if (!collectionHandler.openCollectionFile())
return;
- const QStringList result = collectionHandler.indicesForFilter(attributes);
+ const QStringList result = m_helpEngine->usesFilterEngine
+ ? collectionHandler.indicesForFilter(currentFilter)
+ : collectionHandler.indicesForFilter(attributes);
m_mutex.lock();
m_indices = result;
@@ -181,11 +186,6 @@ QHelpIndexModel::~QHelpIndexModel()
delete d;
}
-void QHelpIndexModel::invalidateIndex(bool onShutDown)
-{
- Q_UNUSED(onShutDown)
-}
-
/*!
Creates a new index by querying the help system for
keywords for the specified \a customFilterName.
diff --git a/src/assistant/help/qhelpindexwidget.h b/src/assistant/help/qhelpindexwidget.h
index 46d4937b7..58dda5e39 100644
--- a/src/assistant/help/qhelpindexwidget.h
+++ b/src/assistant/help/qhelpindexwidget.h
@@ -70,7 +70,6 @@ Q_SIGNALS:
private Q_SLOTS:
void insertIndices();
- void invalidateIndex(bool onShutDown = false);
private:
QHelpIndexModel(QHelpEnginePrivate *helpEngine);
diff --git a/src/assistant/help/qhelpsearchengine.cpp b/src/assistant/help/qhelpsearchengine.cpp
index 3ee9904e2..af7247cc3 100644
--- a/src/assistant/help/qhelpsearchengine.cpp
+++ b/src/assistant/help/qhelpsearchengine.cpp
@@ -231,7 +231,8 @@ private:
m_searchInput = searchInput;
indexReader->cancelSearching();
- indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), searchInput);
+ indexReader->search(helpEngine->collectionFile(), indexFilesFolder(),
+ searchInput, helpEngine->usesFilterEngine());
}
void cancelSearching()
diff --git a/src/assistant/help/qhelpsearchindexreader.cpp b/src/assistant/help/qhelpsearchindexreader.cpp
index 71be91f9f..8aaa5cc47 100644
--- a/src/assistant/help/qhelpsearchindexreader.cpp
+++ b/src/assistant/help/qhelpsearchindexreader.cpp
@@ -56,7 +56,7 @@ void QHelpSearchIndexReader::cancelSearching()
}
void QHelpSearchIndexReader::search(const QString &collectionFile, const QString &indexFilesFolder,
- const QString &searchInput)
+ const QString &searchInput, bool usesFilterEngine)
{
wait();
@@ -65,6 +65,7 @@ void QHelpSearchIndexReader::search(const QString &collectionFile, const QString
m_searchInput = searchInput;
m_collectionFile = collectionFile;
m_indexFilesFolder = indexFilesFolder;
+ m_usesFilterEngine = usesFilterEngine;
start(QThread::NormalPriority);
}
diff --git a/src/assistant/help/qhelpsearchindexreader_default.cpp b/src/assistant/help/qhelpsearchindexreader_default.cpp
index 25f9a13f2..650d8227f 100644
--- a/src/assistant/help/qhelpsearchindexreader_default.cpp
+++ b/src/assistant/help/qhelpsearchindexreader_default.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qhelpenginecore.h"
+#include "qhelpfilterengine.h"
#include "qhelpsearchindexreader_default_p.h"
#include <QtCore/QSet>
@@ -52,12 +53,20 @@ namespace qt {
void Reader::setIndexPath(const QString &path)
{
m_indexPath = path;
- m_namespaces.clear();
+ m_namespaceAttributes.clear();
+ m_filterEngineNamespaceList.clear();
+ m_useFilterEngine = false;
}
-void Reader::addNamespace(const QString &namespaceName, const QStringList &attributes)
+void Reader::addNamespaceAttributes(const QString &namespaceName, const QStringList &attributes)
{
- m_namespaces.insert(namespaceName, attributes);
+ m_namespaceAttributes.insert(namespaceName, attributes);
+}
+
+void Reader::setFilterEngineNamespaceList(const QStringList &namespaceList)
+{
+ m_useFilterEngine = true;
+ m_filterEngineNamespaceList = namespaceList;
}
static QString namespacePlaceholders(const QMultiMap<QString, QStringList> &namespaces)
@@ -106,18 +115,42 @@ static void bindNamespacesAndAttributes(QSqlQuery *query, const QMultiMap<QStrin
}
}
+static QString namespacePlaceholders(const QStringList &namespaceList)
+{
+ QString placeholders;
+ bool firstNS = true;
+ for (int i = namespaceList.count(); i; --i) {
+ if (firstNS)
+ firstNS = false;
+ else
+ placeholders += QLatin1String(" OR ");
+ placeholders += QLatin1String("namespace = ?");
+ }
+ return placeholders;
+}
+
+static void bindNamespacesAndAttributes(QSqlQuery *query, const QStringList &namespaceList)
+{
+ for (const QString &ns : namespaceList)
+ query->addBindValue(ns);
+}
+
QVector<QHelpSearchResult> Reader::queryTable(const QSqlDatabase &db,
const QString &tableName,
const QString &searchInput) const
{
- const QString &nsPlaceholders = namespacePlaceholders(m_namespaces);
+ const QString nsPlaceholders = m_useFilterEngine
+ ? namespacePlaceholders(m_filterEngineNamespaceList)
+ : namespacePlaceholders(m_namespaceAttributes);
QSqlQuery query(db);
query.prepare(QLatin1String("SELECT url, title, snippet(") + tableName +
QLatin1String(", -1, '<b>', '</b>', '...', '10') FROM ") + tableName +
QLatin1String(" WHERE (") + nsPlaceholders +
QLatin1String(") AND ") + tableName +
QLatin1String(" MATCH ? ORDER BY rank"));
- bindNamespacesAndAttributes(&query, m_namespaces);
+ m_useFilterEngine
+ ? bindNamespacesAndAttributes(&query, m_filterEngineNamespaceList)
+ : bindNamespacesAndAttributes(&query, m_namespaceAttributes);
query.addBindValue(searchInput);
query.exec();
@@ -140,6 +173,7 @@ void Reader::searchInDB(const QString &searchInput)
QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), uniqueId);
db.setConnectOptions(QLatin1String("QSQLITE_OPEN_READONLY"));
db.setDatabaseName(m_indexPath + QLatin1String("/fts"));
+
if (db.open()) {
const QVector<QHelpSearchResult> titleResults = queryTable(db,
QLatin1String("titles"), searchInput);
@@ -197,6 +231,7 @@ void QHelpSearchIndexReaderDefault::run()
const QString searchInput = m_searchInput;
const QString collectionFile = m_collectionFile;
const QString indexPath = m_indexFilesFolder;
+ const bool usesFilterEngine = m_usesFilterEngine;
lock.unlock();
@@ -207,26 +242,31 @@ void QHelpSearchIndexReaderDefault::run()
if (!engine.setupData())
return;
- const QStringList &registeredDocs = engine.registeredDocumentations();
-
emit searchingStarted();
- const QStringList &currentFilter = engine.filterAttributes(engine.currentFilter());
-
// setup the reader
m_reader.setIndexPath(indexPath);
- for (const QString &namespaceName : registeredDocs) {
- const QList<QStringList> &attributeSets =
- engine.filterAttributeSets(namespaceName);
- for (const QStringList &attributes : attributeSets) {
- if (attributesMatchFilter(attributes, currentFilter)) {
- m_reader.addNamespace(namespaceName, attributes);
+ if (usesFilterEngine) {
+ m_reader.setFilterEngineNamespaceList(
+ engine.filterEngine()->namespacesForFilter(
+ engine.filterEngine()->activeFilter()));
+ } else {
+ const QStringList &registeredDocs = engine.registeredDocumentations();
+ const QStringList &currentFilter = engine.filterAttributes(engine.currentFilter());
+
+ for (const QString &namespaceName : registeredDocs) {
+ const QList<QStringList> &attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ for (const QStringList &attributes : attributeSets) {
+ if (attributesMatchFilter(attributes, currentFilter)) {
+ m_reader.addNamespaceAttributes(namespaceName, attributes);
+ }
}
}
}
-
lock.relock();
if (m_cancel) {
emit searchingFinished(0); // TODO: check this, speed issue while locking???
diff --git a/src/assistant/help/qhelpsearchindexreader_default_p.h b/src/assistant/help/qhelpsearchindexreader_default_p.h
index b31b532c6..c183a2357 100644
--- a/src/assistant/help/qhelpsearchindexreader_default_p.h
+++ b/src/assistant/help/qhelpsearchindexreader_default_p.h
@@ -64,7 +64,8 @@ class Reader
{
public:
void setIndexPath(const QString &path);
- void addNamespace(const QString &namespaceName, const QStringList &attributes);
+ void addNamespaceAttributes(const QString &namespaceName, const QStringList &attributes);
+ void setFilterEngineNamespaceList(const QStringList &namespaceList);
void searchInDB(const QString &term);
QVector<QHelpSearchResult> searchResults() const;
@@ -74,9 +75,11 @@ private:
const QString &tableName,
const QString &searchInput) const;
- QString m_indexPath;
- QMultiMap<QString, QStringList> m_namespaces;
+ QMultiMap<QString, QStringList> m_namespaceAttributes;
+ QStringList m_filterEngineNamespaceList;
QVector<QHelpSearchResult> m_searchResults;
+ QString m_indexPath;
+ bool m_useFilterEngine = false;
};
diff --git a/src/assistant/help/qhelpsearchindexreader_p.h b/src/assistant/help/qhelpsearchindexreader_p.h
index f6f3ee305..57295693b 100644
--- a/src/assistant/help/qhelpsearchindexreader_p.h
+++ b/src/assistant/help/qhelpsearchindexreader_p.h
@@ -74,7 +74,8 @@ public:
void cancelSearching();
void search(const QString &collectionFile,
const QString &indexFilesFolder,
- const QString &searchInput);
+ const QString &searchInput,
+ bool usesFilterEngine = false);
int searchResultCount() const;
QVector<QHelpSearchResult> searchResults(int start, int end) const;
@@ -89,6 +90,7 @@ protected:
QString m_collectionFile;
QString m_searchInput;
QString m_indexFilesFolder;
+ bool m_usesFilterEngine = false;
private:
void run() override = 0;