diff options
Diffstat (limited to 'src/assistant/assistant')
30 files changed, 850 insertions, 1197 deletions
diff --git a/src/assistant/assistant/assistant.pro b/src/assistant/assistant/assistant.pro index b63be28c7..5da0b0077 100644 --- a/src/assistant/assistant/assistant.pro +++ b/src/assistant/assistant/assistant.pro @@ -23,14 +23,14 @@ HEADERS += aboutdialog.h \ cmdlineparser.h \ contentwindow.h \ findwidget.h \ - filternamedialog.h \ + helpdocsettings.h \ + helpdocsettingswidget.h \ helpenginewrapper.h \ helpbrowsersupport.h \ helpviewer.h \ helpviewer_p.h \ indexwindow.h \ mainwindow.h \ - optionswidget.h \ preferencesdialog.h \ qtdocinstaller.h \ remotecontrol.h \ @@ -56,14 +56,14 @@ SOURCES += aboutdialog.cpp \ cmdlineparser.cpp \ contentwindow.cpp \ findwidget.cpp \ - filternamedialog.cpp \ + helpdocsettings.cpp \ + helpdocsettingswidget.cpp \ helpenginewrapper.cpp \ helpbrowsersupport.cpp \ helpviewer.cpp \ indexwindow.cpp \ main.cpp \ mainwindow.cpp \ - optionswidget.cpp \ preferencesdialog.cpp \ qtdocinstaller.cpp \ remotecontrol.cpp \ @@ -97,7 +97,7 @@ win32 { FORMS += bookmarkdialog.ui \ bookmarkmanagerwidget.ui \ bookmarkwidget.ui \ - filternamedialog.ui \ + helpdocsettingswidget.ui \ preferencesdialog.ui \ topicchooser.ui diff --git a/src/assistant/assistant/assistant.qch b/src/assistant/assistant/assistant.qch Binary files differindex fded08e62..b58b7ecca 100644 --- a/src/assistant/assistant/assistant.qch +++ b/src/assistant/assistant/assistant.qch diff --git a/src/assistant/assistant/assistant_images.qrc b/src/assistant/assistant/assistant_images.qrc index e55b6b27e..948de970f 100644 --- a/src/assistant/assistant/assistant_images.qrc +++ b/src/assistant/assistant/assistant_images.qrc @@ -10,9 +10,7 @@ <file>images/mac/editcopy.png</file> <file>images/mac/find.png</file> <file>images/mac/home.png</file> - <file>images/mac/minus.png</file> <file>images/mac/next.png</file> - <file>images/mac/plus.png</file> <file>images/mac/previous.png</file> <file>images/mac/print.png</file> <file>images/mac/synctoc.png</file> @@ -25,9 +23,7 @@ <file>images/win/editcopy.png</file> <file>images/win/find.png</file> <file>images/win/home.png</file> - <file>images/win/minus.png</file> <file>images/win/next.png</file> - <file>images/win/plus.png</file> <file>images/win/previous.png</file> <file>images/win/print.png</file> <file>images/win/synctoc.png</file> diff --git a/src/assistant/assistant/bookmarkdialog.cpp b/src/assistant/assistant/bookmarkdialog.cpp index 8207da04e..1ffe6dc84 100644 --- a/src/assistant/assistant/bookmarkdialog.cpp +++ b/src/assistant/assistant/bookmarkdialog.cpp @@ -60,7 +60,7 @@ BookmarkDialog::BookmarkDialog(BookmarkModel *sourceModel, const QString &title, bookmarkProxyModel = new BookmarkFilterModel(this); bookmarkProxyModel->setSourceModel(bookmarkModel); ui.bookmarkFolders->setModel(bookmarkProxyModel); - connect(ui.bookmarkFolders, QOverload<int>::of(&QComboBox::currentIndexChanged), + connect(ui.bookmarkFolders, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), this, QOverload<int>::of(&BookmarkDialog::currentIndexChanged)); bookmarkTreeModel = new BookmarkTreeModel(this); diff --git a/src/assistant/assistant/centralwidget.cpp b/src/assistant/assistant/centralwidget.cpp index 4a4fba7ed..bac8f6fc8 100644 --- a/src/assistant/assistant/centralwidget.cpp +++ b/src/assistant/assistant/centralwidget.cpp @@ -545,7 +545,7 @@ void CentralWidget::highlightSearchTerms() const bool wholePhrase = searchInput.startsWith(QLatin1Char('"')) && searchInput.endsWith(QLatin1Char('"')); const QStringList &words = wholePhrase ? QStringList(searchInput.mid(1, searchInput.length() - 2)) : - searchInput.split(QRegExp("\\W+"), QString::SkipEmptyParts); + searchInput.split(QRegExp("\\W+"), Qt::SkipEmptyParts); HelpViewer *viewer = currentHelpViewer(); for (const QString &word : words) viewer->findText(word, {}, false, true); @@ -568,12 +568,12 @@ void CentralWidget::handleSourceChanged(const QUrl &url) emit sourceChanged(url); } -void CentralWidget::slotHighlighted(const QString &link) +void CentralWidget::slotHighlighted(const QUrl &link) { TRACE_OBJ - QString resolvedLink = m_resolvedLinks.value(link); + QUrl resolvedLink = m_resolvedLinks.value(link); if (!link.isEmpty() && resolvedLink.isEmpty()) { - resolvedLink = HelpEngineWrapper::instance().findFile(link).toString(); + resolvedLink = HelpEngineWrapper::instance().findFile(link); m_resolvedLinks.insert(link, resolvedLink); } emit highlighted(resolvedLink); @@ -605,7 +605,7 @@ void CentralWidget::connectSignals(HelpViewer *page) this, &CentralWidget::backwardAvailable); connect(page, &HelpViewer::sourceChanged, this, &CentralWidget::handleSourceChanged); - connect(page, QOverload<const QString &>::of(&HelpViewer::highlighted), + connect(page, QOverload<const QUrl &>::of(&HelpViewer::highlighted), this, &CentralWidget::slotHighlighted); } diff --git a/src/assistant/assistant/centralwidget.h b/src/assistant/assistant/centralwidget.h index 34de716a4..4943c2ff3 100644 --- a/src/assistant/assistant/centralwidget.h +++ b/src/assistant/assistant/centralwidget.h @@ -129,7 +129,7 @@ signals: void currentViewerChanged(); void copyAvailable(bool yes); void sourceChanged(const QUrl &url); - void highlighted(const QString &link); + void highlighted(const QUrl &link); void forwardAvailable(bool available); void backwardAvailable(bool available); void addBookmark(const QString &title, const QString &url); @@ -142,7 +142,7 @@ private slots: void highlightSearchTerms(); void printPreviewToPrinter(QPrinter *printer); void handleSourceChanged(const QUrl &url); - void slotHighlighted(const QString &link); + void slotHighlighted(const QUrl& link); private: void initPrinter(); @@ -160,7 +160,7 @@ private: FindWidget *m_findWidget; QStackedWidget *m_stackedWidget; TabBar *m_tabBar; - QHash<QString, QString> m_resolvedLinks; + QHash<QUrl, QUrl> m_resolvedLinks; }; QT_END_NAMESPACE diff --git a/src/assistant/assistant/filternamedialog.cpp b/src/assistant/assistant/filternamedialog.cpp deleted file mode 100644 index 4c17d3332..000000000 --- a/src/assistant/assistant/filternamedialog.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Assistant of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** 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-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtWidgets/QPushButton> - -#include "filternamedialog.h" - -QT_BEGIN_NAMESPACE - -FilterNameDialog::FilterNameDialog(QWidget *parent) - : QDialog(parent) -{ - m_ui.setupUi(this); - connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, - this, &QDialog::accept); - connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked, - this, &QDialog::reject); - connect(m_ui.lineEdit, &QLineEdit::textChanged, - this, &FilterNameDialog::updateOkButton); - 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 -{ - return m_ui.lineEdit->text(); -} - -void FilterNameDialog::updateOkButton() -{ - m_ui.buttonBox->button(QDialogButtonBox::Ok) - ->setDisabled(m_ui.lineEdit->text().isEmpty()); -} - -QT_END_NAMESPACE diff --git a/src/assistant/assistant/filternamedialog.h b/src/assistant/assistant/filternamedialog.h deleted file mode 100644 index 522b611af..000000000 --- a/src/assistant/assistant/filternamedialog.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Assistant of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** 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-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FILTERNAMEDIALOG_H -#define FILTERNAMEDIALOG_H - -#include <QtWidgets/QDialog> -#include "ui_filternamedialog.h" - -QT_BEGIN_NAMESPACE - -class FilterNameDialog : public QDialog -{ - Q_OBJECT - -public: - FilterNameDialog(QWidget *parent = nullptr); - - void setFilterName(const QString &filter); - QString filterName() const; - -private slots: - void updateOkButton(); - -private: - Ui::FilterNameDialogClass m_ui; -}; - -QT_END_NAMESPACE - -#endif // FILTERNAMEDIALOG_H diff --git a/src/assistant/assistant/filternamedialog.ui b/src/assistant/assistant/filternamedialog.ui deleted file mode 100644 index 1da584a80..000000000 --- a/src/assistant/assistant/filternamedialog.ui +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>FilterNameDialogClass</class> - <widget class="QDialog" name="FilterNameDialogClass"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>312</width> - <height>77</height> - </rect> - </property> - <property name="windowTitle"> - <string>Add Filter</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Filter Name:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="lineEdit"/> - </item> - <item row="1" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>1</height> - </size> - </property> - </spacer> - </item> - <item row="2" column="0" colspan="2"> - <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> - <layoutdefault spacing="6" margin="11"/> - <resources/> - <connections/> -</ui> diff --git a/src/assistant/assistant/helpdocsettings.cpp b/src/assistant/assistant/helpdocsettings.cpp new file mode 100644 index 000000000..dc4afdb86 --- /dev/null +++ b/src/assistant/assistant/helpdocsettings.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 "helpdocsettings.h" + +#include <QtHelp/QCompressedHelpInfo> +#include <QtHelp/QHelpEngineCore> +#include <QtHelp/QHelpFilterEngine> + +#include <QtCore/QVersionNumber> + +#include <QtDebug> + +QT_BEGIN_NAMESPACE + +class HelpDocSettingsPrivate : public QSharedData +{ +public: + HelpDocSettingsPrivate() = default; + HelpDocSettingsPrivate(const HelpDocSettingsPrivate &other) = default; + ~HelpDocSettingsPrivate() = default; + + QMap<QString, QString> m_namespaceToComponent; + QMap<QString, QStringList> m_componentToNamespace; + + QMap<QString, QVersionNumber> m_namespaceToVersion; + QMap<QVersionNumber, QStringList> m_versionToNamespace; + + QMap<QString, QString> m_namespaceToFileName; + QMap<QString, QString> m_fileNameToNamespace; +}; + + +HelpDocSettings::HelpDocSettings() + : d(new HelpDocSettingsPrivate) +{ +} + +HelpDocSettings::HelpDocSettings(const HelpDocSettings &) = default; + +HelpDocSettings::HelpDocSettings(HelpDocSettings &&) = default; + +HelpDocSettings::~HelpDocSettings() = default; + +HelpDocSettings &HelpDocSettings::operator=(const HelpDocSettings &) = default; + +HelpDocSettings &HelpDocSettings::operator=(HelpDocSettings &&) = default; + +bool HelpDocSettings::addDocumentation(const QString &fileName) +{ + const QCompressedHelpInfo info = QCompressedHelpInfo::fromCompressedHelpFile(fileName); + + if (info.isNull()) + return false; + + const QString namespaceName = info.namespaceName(); + + if (d->m_namespaceToFileName.contains(namespaceName)) + return false; + + if (d->m_fileNameToNamespace.contains(fileName)) + return false; + + const QString component = info.component(); + const QVersionNumber version = info.version(); + + d->m_namespaceToFileName.insert(namespaceName, fileName); + d->m_fileNameToNamespace.insert(fileName, namespaceName); + + d->m_namespaceToComponent.insert(namespaceName, component); + d->m_componentToNamespace[component].append(namespaceName); + + d->m_namespaceToVersion.insert(namespaceName, version); + d->m_versionToNamespace[version].append(namespaceName); + + return true; +} + +bool HelpDocSettings::removeDocumentation(const QString &namespaceName) +{ + if (namespaceName.isEmpty()) + return false; + + const QString fileName = d->m_namespaceToFileName.value(namespaceName); + if (fileName.isEmpty()) + return false; + + const QString component = d->m_namespaceToComponent.value(namespaceName); + const QVersionNumber version = d->m_namespaceToVersion.value(namespaceName); + + d->m_namespaceToComponent.remove(namespaceName); + d->m_namespaceToVersion.remove(namespaceName); + d->m_namespaceToFileName.remove(namespaceName); + d->m_fileNameToNamespace.remove(fileName); + d->m_componentToNamespace[component].removeOne(namespaceName); + if (d->m_componentToNamespace[component].isEmpty()) + d->m_componentToNamespace.remove(component); + d->m_versionToNamespace[version].removeOne(namespaceName); + if (d->m_versionToNamespace[version].isEmpty()) + d->m_versionToNamespace.remove(version); + + return true; +} + +QString HelpDocSettings::namespaceName(const QString &fileName) const +{ + return d->m_fileNameToNamespace.value(fileName); +} + +QStringList HelpDocSettings::components() const +{ + return d->m_componentToNamespace.keys(); +} + +QList<QVersionNumber> HelpDocSettings::versions() const +{ + return d->m_versionToNamespace.keys(); +} + +QStringList HelpDocSettings::namespaces() const +{ + return d->m_namespaceToFileName.keys(); +} + +QMap<QString, QString> HelpDocSettings::namespaceToFileName() const +{ + return d->m_namespaceToFileName; +} + +HelpDocSettings HelpDocSettings::readSettings(QHelpEngineCore *helpEngine) +{ + QHelpFilterEngine *filterEngine = helpEngine->filterEngine(); + + HelpDocSettings docSettings; + docSettings.d->m_namespaceToComponent = filterEngine->namespaceToComponent(); + docSettings.d->m_namespaceToVersion = filterEngine->namespaceToVersion(); + for (auto it = docSettings.d->m_namespaceToComponent.constBegin(); + it != docSettings.d->m_namespaceToComponent.constEnd(); ++it) { + const QString namespaceName = it.key(); + const QString namespaceFileName = helpEngine->documentationFileName(namespaceName); + docSettings.d->m_namespaceToFileName.insert(namespaceName, namespaceFileName); + docSettings.d->m_fileNameToNamespace.insert(namespaceFileName, namespaceName); + docSettings.d->m_componentToNamespace[it.value()].append(namespaceName); + } + for (auto it = docSettings.d->m_namespaceToVersion.constBegin(); + it != docSettings.d->m_namespaceToVersion.constEnd(); ++it) { + docSettings.d->m_versionToNamespace[it.value()].append(it.key()); + } + + return docSettings; +} + +static QMap<QString, QString> subtract(const QMap<QString, QString> &minuend, + const QMap<QString, QString> &subtrahend) +{ + auto result = minuend; + + 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); + } + + return result; +} + +bool HelpDocSettings::applySettings(QHelpEngineCore *helpEngine, + const HelpDocSettings &settings) +{ + const HelpDocSettings oldSettings = readSettings(helpEngine); + + const QMap<QString, QString> docsToRemove = subtract( + oldSettings.namespaceToFileName(), + settings.namespaceToFileName()); + const QMap<QString, QString> docsToAdd = subtract( + settings.namespaceToFileName(), + oldSettings.namespaceToFileName()); + + bool changed = false; + for (const QString &namespaceName : docsToRemove.keys()) { + if (!helpEngine->unregisterDocumentation(namespaceName)) + qWarning() << "Cannot unregister documentation:" << namespaceName; + changed = true; + } + + for (const QString &fileName : docsToAdd.values()) { + if (!helpEngine->registerDocumentation(fileName)) + qWarning() << "Cannot register documentation file:" << fileName; + changed = true; + } + + return changed; +} + +QT_END_NAMESPACE diff --git a/src/assistant/assistant/helpdocsettings.h b/src/assistant/assistant/helpdocsettings.h new file mode 100644 index 000000000..7476eb63a --- /dev/null +++ b/src/assistant/assistant/helpdocsettings.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 HELPDOCSETTINGS_H +#define HELPDOCSETTINGS_H + +#include <QtCore/QSharedDataPointer> + +QT_BEGIN_NAMESPACE + +class QVersionNumber; +class QHelpEngineCore; +class HelpDocSettingsPrivate; + +class HelpDocSettings final +{ +public: + HelpDocSettings(); + HelpDocSettings(const HelpDocSettings &other); + HelpDocSettings(HelpDocSettings &&other); + ~HelpDocSettings(); + + HelpDocSettings &operator=(const HelpDocSettings &other); + HelpDocSettings &operator=(HelpDocSettings &&other); + + void swap(HelpDocSettings &other) noexcept + { d.swap(other.d); } + + bool addDocumentation(const QString &fileName); + bool removeDocumentation(const QString &namespaceName); + QString namespaceName(const QString &fileName) const; + QStringList components() const; + QList<QVersionNumber> versions() const; + QStringList namespaces() const; + QMap<QString, QString> namespaceToFileName() const; + + static HelpDocSettings readSettings(QHelpEngineCore *helpEngine); + static bool applySettings(QHelpEngineCore *helpEngine, const HelpDocSettings &settings); + +private: + QSharedDataPointer<HelpDocSettingsPrivate> d; +}; + +QT_END_NAMESPACE + +#endif // HELPDOCSETTINGS_H diff --git a/src/assistant/assistant/helpdocsettingswidget.cpp b/src/assistant/assistant/helpdocsettingswidget.cpp new file mode 100644 index 000000000..94ca2b25a --- /dev/null +++ b/src/assistant/assistant/helpdocsettingswidget.cpp @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 "helpdocsettings.h" +#include "helpdocsettingswidget.h" +#include "ui_helpdocsettingswidget.h" + +#include <QtWidgets/QFileDialog> +#include <QtWidgets/QPushButton> + +QT_BEGIN_NAMESPACE + +class HelpDocSettingsWidgetPrivate +{ + HelpDocSettingsWidget *q_ptr; + Q_DECLARE_PUBLIC(HelpDocSettingsWidget) +public: + HelpDocSettingsWidgetPrivate() = default; + + void addDocumentation(); + void removeDocumentation(); + void applyDocListFilter(QListWidgetItem *item); + + QMap<QString, QListWidgetItem *> m_namespaceToItem; + QHash<QListWidgetItem *, QString> m_itemToNamespace; + + Ui::HelpDocSettingsWidget m_ui; + HelpDocSettings m_settings; +}; + +void HelpDocSettingsWidgetPrivate::addDocumentation() +{ + Q_Q(HelpDocSettingsWidget); + + const QStringList &fileNames = QFileDialog::getOpenFileNames(q, + q->tr("Add Documentation"), QString(), q->tr("Qt Compressed Help Files (*.qch)")); + if (fileNames.isEmpty()) + return; + + bool added = false; + + for (const QString &fileName : fileNames) { + if (!m_settings.addDocumentation(fileName)) + continue; + + if (!added) { + added = true; + m_ui.registeredDocsListWidget->clearSelection(); + } + + const QString namespaceName = m_settings.namespaceName(fileName); + 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); + + item->setSelected(true); + applyDocListFilter(item); + } + + if (added) + emit q->docSettingsChanged(m_settings); +} + +void HelpDocSettingsWidgetPrivate::removeDocumentation() +{ + Q_Q(HelpDocSettingsWidget); + + 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; + + m_settings.removeDocumentation(namespaceName); + } + + emit q->docSettingsChanged(m_settings); +} + +void HelpDocSettingsWidgetPrivate::applyDocListFilter(QListWidgetItem *item) +{ + const QString namespaceName = m_itemToNamespace.value(item); + const QString nameFilter = m_ui.registeredDocsFilterLineEdit->text(); + + const bool matches = nameFilter.isEmpty() || namespaceName.contains(nameFilter); + + if (!matches) + item->setSelected(false); + item->setHidden(!matches); +} + +HelpDocSettingsWidget::HelpDocSettingsWidget(QWidget *parent) + : QWidget(parent) + , d_ptr(new HelpDocSettingsWidgetPrivate()) +{ + Q_D(HelpDocSettingsWidget); + d->q_ptr = this; + d->m_ui.setupUi(this); + + connect(d->m_ui.docAddButton, &QAbstractButton::clicked, + [this]() { + Q_D(HelpDocSettingsWidget); + d->addDocumentation(); + }); + connect(d->m_ui.docRemoveButton, &QAbstractButton::clicked, + [this]() { + Q_D(HelpDocSettingsWidget); + d->removeDocumentation(); + }); + connect(d->m_ui.registeredDocsFilterLineEdit, &QLineEdit::textChanged, + [this](const QString &) { + Q_D(HelpDocSettingsWidget); + for (const auto item : d->m_namespaceToItem) + d->applyDocListFilter(item); + }); + connect(d->m_ui.registeredDocsListWidget, &QListWidget::itemSelectionChanged, + [this]() { + Q_D(HelpDocSettingsWidget); + d->m_ui.docRemoveButton->setEnabled( + !d->m_ui.registeredDocsListWidget->selectedItems().isEmpty()); + }); +} + +HelpDocSettingsWidget::~HelpDocSettingsWidget() = default; + +void HelpDocSettingsWidget::setDocSettings(const HelpDocSettings &settings) +{ + Q_D(HelpDocSettingsWidget); + d->m_settings = settings; + + d->m_ui.registeredDocsListWidget->clear(); + d->m_namespaceToItem.clear(); + d->m_itemToNamespace.clear(); + + for (const QString &namespaceName : d->m_settings.namespaces()) { + QListWidgetItem *item = new QListWidgetItem(namespaceName); + d->m_namespaceToItem.insert(namespaceName, item); + d->m_itemToNamespace.insert(item, namespaceName); + d->m_ui.registeredDocsListWidget->addItem(item); + d->applyDocListFilter(item); + } + + d->m_ui.docRemoveButton->setEnabled( + !d->m_ui.registeredDocsListWidget->selectedItems().isEmpty()); +} + +HelpDocSettings HelpDocSettingsWidget::docSettings() const +{ + Q_D(const HelpDocSettingsWidget); + return d->m_settings; +} + +QT_END_NAMESPACE diff --git a/src/assistant/assistant/helpdocsettingswidget.h b/src/assistant/assistant/helpdocsettingswidget.h new file mode 100644 index 000000000..3ed089353 --- /dev/null +++ b/src/assistant/assistant/helpdocsettingswidget.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 HELPDOCSETTINGSWIDGET_H +#define HELPDOCSETTINGSWIDGET_H + +#include <QtWidgets/QWidget> + +QT_BEGIN_NAMESPACE + +class HelpDocSettings; +class HelpDocSettingsWidgetPrivate; + +class HelpDocSettingsWidget : public QWidget +{ + Q_OBJECT +public: + HelpDocSettingsWidget(QWidget *parent = nullptr); + + ~HelpDocSettingsWidget(); + + void setDocSettings(const HelpDocSettings &settings); + HelpDocSettings docSettings() const; + +Q_SIGNALS: + void docSettingsChanged(const HelpDocSettings &settings); + +private: + QScopedPointer<class HelpDocSettingsWidgetPrivate> d_ptr; + Q_DECLARE_PRIVATE(HelpDocSettingsWidget) + Q_DISABLE_COPY_MOVE(HelpDocSettingsWidget) +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/assistant/assistant/helpdocsettingswidget.ui b/src/assistant/assistant/helpdocsettingswidget.ui new file mode 100644 index 000000000..4897dfe86 --- /dev/null +++ b/src/assistant/assistant/helpdocsettingswidget.ui @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>HelpDocSettingsWidget</class> + <widget class="QWidget" name="HelpDocSettingsWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>268</width> + <height>128</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="docLabel"> + <property name="text"> + <string>Registered Documentation</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLineEdit" name="registeredDocsFilterLineEdit"> + <property name="placeholderText"> + <string><Filter></string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="1" rowspan="2"> + <layout class="QVBoxLayout" name="buttonLayout"> + <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 name="buttonSpacer"> + <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> + <resources/> + <connections/> +</ui> diff --git a/src/assistant/assistant/helpenginewrapper.cpp b/src/assistant/assistant/helpenginewrapper.cpp index 17e4bde8c..d69138ff8 100644 --- a/src/assistant/assistant/helpenginewrapper.cpp +++ b/src/assistant/assistant/helpenginewrapper.cpp @@ -670,6 +670,12 @@ void HelpEngineWrapper::setTopicChooserGeometry(const QByteArray &geometry) d->m_helpEngine->setCustomValue(TopicChooserGeometryKey, geometry); } +QHelpEngineCore *HelpEngineWrapper::helpEngine() const +{ + return d->m_helpEngine; +} + + // -- TimeoutForwarder TimeoutForwarder::TimeoutForwarder(const QString &fileName) diff --git a/src/assistant/assistant/helpenginewrapper.h b/src/assistant/assistant/helpenginewrapper.h index 6026a0473..81d8ffa1f 100644 --- a/src/assistant/assistant/helpenginewrapper.h +++ b/src/assistant/assistant/helpenginewrapper.h @@ -46,6 +46,7 @@ class QHelpIndexModel; class QHelpIndexWidget; class QHelpSearchEngine; class QHelpFilterEngine; +class QHelpEngineCore; enum { ShowHomePage = 0, @@ -175,6 +176,8 @@ public: const QByteArray topicChooserGeometry() const; void setTopicChooserGeometry(const QByteArray &geometry); + QHelpEngineCore *helpEngine() const; + signals: // For asynchronous doc updates triggered by external actions. diff --git a/src/assistant/assistant/helpviewer.h b/src/assistant/assistant/helpviewer.h index 1b4f23a9a..e63173b1e 100644 --- a/src/assistant/assistant/helpviewer.h +++ b/src/assistant/assistant/helpviewer.h @@ -121,7 +121,7 @@ signals: void sourceChanged(const QUrl &url); void forwardAvailable(bool enabled); void backwardAvailable(bool enabled); - void highlighted(const QString &link); + void highlighted(const QUrl &link); void printRequested(); #elif !defined(BROWSER_QTWEBKIT) // Provide signals present in QWebView for browsers that do not inherit QWebView diff --git a/src/assistant/assistant/helpviewer_qtb.cpp b/src/assistant/assistant/helpviewer_qtb.cpp index 85fe532b1..09e042062 100644 --- a/src/assistant/assistant/helpviewer_qtb.cpp +++ b/src/assistant/assistant/helpviewer_qtb.cpp @@ -160,7 +160,7 @@ void HelpViewer::doSetSource(const QUrl &url, QTextDocument::ResourceType type) bool helpOrAbout = (url.toString() == QLatin1String("help")); const QUrl resolvedUrl = (helpOrAbout ? LocalHelpFile : HelpEngineWrapper::instance().findFile(url)); - QTextBrowser::setSource(resolvedUrl); + QTextBrowser::doSetSource(resolvedUrl, type); if (!resolvedUrl.isValid()) { helpOrAbout = (url.toString() == QLatin1String("about:blank")); diff --git a/src/assistant/assistant/helpviewer_qwv.cpp b/src/assistant/assistant/helpviewer_qwv.cpp index f8acb7b46..7d9cfc07f 100644 --- a/src/assistant/assistant/helpviewer_qwv.cpp +++ b/src/assistant/assistant/helpviewer_qwv.cpp @@ -166,8 +166,10 @@ HelpViewer::HelpViewer(qreal zoom, QWidget *parent) SLOT(actionChanged())); connect(pageAction(QWebPage::Forward), SIGNAL(changed()), this, SLOT(actionChanged())); - connect(page(), SIGNAL(linkHovered(QString,QString,QString)), this, - SIGNAL(highlighted(QString))); + connect(page(), &QWebPage::linkHovered, this, + [this] (const QString &link, const QString &, const QString &) { + emit this->highlighted(QUrl(link)); + }); connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(sourceChanged(QUrl))); connect(this, SIGNAL(loadStarted()), this, SLOT(setLoadStarted())); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool))); diff --git a/src/assistant/assistant/images/mac/minus.png b/src/assistant/assistant/images/mac/minus.png Binary files differdeleted file mode 100644 index 8d2eaed52..000000000 --- a/src/assistant/assistant/images/mac/minus.png +++ /dev/null diff --git a/src/assistant/assistant/images/mac/plus.png b/src/assistant/assistant/images/mac/plus.png Binary files differdeleted file mode 100644 index 1ee45423e..000000000 --- a/src/assistant/assistant/images/mac/plus.png +++ /dev/null diff --git a/src/assistant/assistant/images/win/minus.png b/src/assistant/assistant/images/win/minus.png Binary files differdeleted file mode 100644 index c0dc274bb..000000000 --- a/src/assistant/assistant/images/win/minus.png +++ /dev/null diff --git a/src/assistant/assistant/images/win/plus.png b/src/assistant/assistant/images/win/plus.png Binary files differdeleted file mode 100644 index ecf058941..000000000 --- a/src/assistant/assistant/images/win/plus.png +++ /dev/null diff --git a/src/assistant/assistant/main.cpp b/src/assistant/assistant/main.cpp index 3ddbdbc29..cd6487751 100644 --- a/src/assistant/assistant/main.cpp +++ b/src/assistant/assistant/main.cpp @@ -265,69 +265,49 @@ void setupTranslations() } // Anonymous namespace. -int main(int argc, char *argv[]) -{ - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton); - TRACE_OBJ - QScopedPointer<QCoreApplication> a(createApplication(argc, argv)); -#if QT_CONFIG(library) - a->addLibraryPath(a->applicationDirPath() + QLatin1String("/plugins")); -#endif - setupTranslations(); - -#if defined(BROWSER_QTWEBKIT) - if (qobject_cast<QApplication *>(a.data())) { - QFont f; - f.setStyleHint(QFont::SansSerif); - QWebSettings::globalSettings()->setFontFamily(QWebSettings::StandardFont, f.defaultFamily()); - } -#endif // BROWSER_QTWEBKIT - - // Parse arguments. - CmdLineParser cmd(a->arguments()); - CmdLineParser::Result res = cmd.parse(); - if (res == CmdLineParser::Help) - return 0; - else if (res == CmdLineParser::Error) - return -1; +enum ExitStatus { + ExitSuccess = 0, + ExitFailure, + NoExit +}; +static ExitStatus preliminarySetup(CmdLineParser *cmd) +{ /* * Create the collection objects that we need. We always have the * cached collection file. Depending on whether the user specified * one, we also may have an input collection file. */ - const QString collectionFile = cmd.collectionFile(); + const QString collectionFile = cmd->collectionFile(); const bool collectionFileGiven = !collectionFile.isEmpty(); QScopedPointer<QHelpEngineCore> collection; if (collectionFileGiven) { collection.reset(new QHelpEngineCore(collectionFile)); collection->setProperty("_q_readonly", QVariant::fromValue<bool>(true)); if (!collection->setupData()) { - cmd.showMessage(QCoreApplication::translate("Assistant", - "Error reading collection file '%1': %2."). - arg(collectionFile).arg(collection->error()), true); - return EXIT_FAILURE; + cmd->showMessage(QCoreApplication::translate("Assistant", + "Error reading collection file '%1': %2.") + .arg(collectionFile).arg(collection->error()), true); + return ExitFailure; } } const QString &cachedCollectionFile = collectionFileGiven - ? constructCachedCollectionFilePath(*collection) - : MainWindow::defaultHelpCollectionFileName(); + ? constructCachedCollectionFilePath(*collection) + : MainWindow::defaultHelpCollectionFileName(); if (collectionFileGiven && !QFileInfo(cachedCollectionFile).exists() - && !collection->copyCollectionFile(cachedCollectionFile)) { - cmd.showMessage(QCoreApplication::translate("Assistant", - "Error creating collection file '%1': %2."). - arg(cachedCollectionFile).arg(collection->error()), true); - return EXIT_FAILURE; + && !collection->copyCollectionFile(cachedCollectionFile)) { + cmd->showMessage(QCoreApplication::translate("Assistant", + "Error creating collection file '%1': %2.") + .arg(cachedCollectionFile).arg(collection->error()), true); + return ExitFailure; } QHelpEngineCore cachedCollection(cachedCollectionFile); if (!cachedCollection.setupData()) { - cmd.showMessage(QCoreApplication::translate("Assistant", - "Error reading collection file '%1': %2."). - arg(cachedCollectionFile). - arg(cachedCollection.error()), true); - return EXIT_FAILURE; + cmd->showMessage(QCoreApplication::translate("Assistant", + "Error reading collection file '%1': %2.") + .arg(cachedCollectionFile) + .arg(cachedCollection.error()), true); + return ExitFailure; } stripNonexistingDocs(cachedCollection); @@ -335,56 +315,94 @@ int main(int argc, char *argv[]) if (CollectionConfiguration::isNewer(*collection, cachedCollection)) CollectionConfiguration::copyConfiguration(*collection, cachedCollection); - if (!synchronizeDocs(*collection, cachedCollection, cmd)) - return EXIT_FAILURE; + if (!synchronizeDocs(*collection, cachedCollection, *cmd)) + return ExitFailure; } - if (cmd.registerRequest() != CmdLineParser::None) { + if (cmd->registerRequest() != CmdLineParser::None) { const QStringList &cachedDocs = - cachedCollection.registeredDocumentations(); + cachedCollection.registeredDocumentations(); const QString &namespaceName = - QHelpEngineCore::namespaceName(cmd.helpFile()); - if (cmd.registerRequest() == CmdLineParser::Register) { + QHelpEngineCore::namespaceName(cmd->helpFile()); + if (cmd->registerRequest() == CmdLineParser::Register) { if (collectionFileGiven - && !registerDocumentation(*collection, cmd, true)) - return EXIT_FAILURE; + && !registerDocumentation(*collection, *cmd, true)) + return ExitFailure; if (!cachedDocs.contains(namespaceName) - && !registerDocumentation(cachedCollection, cmd, !collectionFileGiven)) - return EXIT_FAILURE; - return EXIT_SUCCESS; + && !registerDocumentation(cachedCollection, *cmd, !collectionFileGiven)) + return ExitFailure; + return ExitSuccess; } - if (cmd.registerRequest() == CmdLineParser::Unregister) { + if (cmd->registerRequest() == CmdLineParser::Unregister) { if (collectionFileGiven - && !unregisterDocumentation(*collection, namespaceName, cmd, true)) - return EXIT_FAILURE; + && !unregisterDocumentation(*collection, namespaceName, *cmd, true)) + return ExitFailure; if (cachedDocs.contains(namespaceName) - && !unregisterDocumentation(cachedCollection, namespaceName, - cmd, !collectionFileGiven)) - return EXIT_FAILURE; - return EXIT_SUCCESS; + && !unregisterDocumentation(cachedCollection, namespaceName, + *cmd, !collectionFileGiven)) + return ExitFailure; + return ExitSuccess; } } - if (cmd.removeSearchIndex()) { + if (cmd->removeSearchIndex()) { return removeSearchIndex(cachedCollectionFile) - ? EXIT_SUCCESS : EXIT_FAILURE; + ? ExitSuccess : ExitFailure; } if (!QSqlDatabase::isDriverAvailable(QLatin1String("QSQLITE"))) { - cmd.showMessage(QCoreApplication::translate("Assistant", - "Cannot load sqlite database driver!"), - true); - return EXIT_FAILURE; + cmd->showMessage(QCoreApplication::translate("Assistant", + "Cannot load sqlite database driver!"), + true); + return ExitFailure; } - if (!cmd.currentFilter().isEmpty()) { + if (!cmd->currentFilter().isEmpty()) { if (collectionFileGiven) - collection->setCurrentFilter(cmd.currentFilter()); - cachedCollection.setCurrentFilter(cmd.currentFilter()); + collection->setCurrentFilter(cmd->currentFilter()); + cachedCollection.setCurrentFilter(cmd->currentFilter()); } if (collectionFileGiven) - cmd.setCollectionFile(cachedCollectionFile); + cmd->setCollectionFile(cachedCollectionFile); + + return NoExit; +} + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton); + TRACE_OBJ + QScopedPointer<QCoreApplication> a(createApplication(argc, argv)); +#if QT_CONFIG(library) + a->addLibraryPath(a->applicationDirPath() + QLatin1String("/plugins")); +#endif + setupTranslations(); + +#if defined(BROWSER_QTWEBKIT) + if (qobject_cast<QApplication *>(a.data())) { + QFont f; + f.setStyleHint(QFont::SansSerif); + QWebSettings::globalSettings()->setFontFamily(QWebSettings::StandardFont, f.defaultFamily()); + } +#endif // BROWSER_QTWEBKIT + + // Parse arguments. + CmdLineParser cmd(a->arguments()); + CmdLineParser::Result res = cmd.parse(); + if (res == CmdLineParser::Help) + return 0; + else if (res == CmdLineParser::Error) + return -1; + + const ExitStatus status = preliminarySetup(&cmd); + switch (status) { + case ExitFailure: return EXIT_FAILURE; + case ExitSuccess: return EXIT_SUCCESS; + default: break; + } MainWindow *w = new MainWindow(&cmd); w->show(); diff --git a/src/assistant/assistant/mainwindow.cpp b/src/assistant/assistant/mainwindow.cpp index a6b257eb7..56312583d 100644 --- a/src/assistant/assistant/mainwindow.cpp +++ b/src/assistant/assistant/mainwindow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Assistant of the Qt Toolkit. @@ -676,7 +676,7 @@ void MainWindow::setupActions() connect(m_centralWidget, &CentralWidget::backwardAvailable, globalActions, &GlobalActions::updateActions); connect(m_centralWidget, &CentralWidget::highlighted, - this, [this](const QString &link) { statusBar()->showMessage(link);} ); + this, [this](const QUrl &link) { statusBar()->showMessage(link.toString());} ); // index window connect(m_indexWindow, &IndexWindow::linkActivated, @@ -906,7 +906,7 @@ void MainWindow::showAboutDialog() "<p>Version %2</p>" "<p>Browser: %3</p></center>" "<p>Copyright (C) %4 The Qt Company Ltd.</p>") - .arg(tr("Qt Assistant"), QLatin1String(QT_VERSION_STR), browser, QStringLiteral("2019")), + .arg(tr("Qt Assistant"), QLatin1String(QT_VERSION_STR), browser, QStringLiteral("2020")), resources); QLatin1String path(":/qt-project.org/assistant/images/assistant-128.png"); aboutDia.setPixmap(QString(path)); diff --git a/src/assistant/assistant/optionswidget.cpp b/src/assistant/assistant/optionswidget.cpp deleted file mode 100644 index bc089c5bf..000000000 --- a/src/assistant/assistant/optionswidget.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** 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:GPL-EXCEPT$ -** 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 General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** 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-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "optionswidget.h" - -#include <QtWidgets/QComboBox> -#include <QtWidgets/QItemDelegate> -#include <QtWidgets/QListWidget> -#include <QtWidgets/QVBoxLayout> - -#include <algorithm> - -QT_BEGIN_NAMESPACE - -class ListWidgetDelegate : public QItemDelegate -{ -// Q_OBJECT not needed -public: - ListWidgetDelegate(QWidget *w) : QItemDelegate(w), m_widget(w) {} - - static bool isSeparator(const QModelIndex &index) { - return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator"); - } - static void setSeparator(QListWidgetItem *item) { - item->setData(Qt::AccessibleDescriptionRole, QString::fromLatin1("separator")); - item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled)); - } - -protected: - void paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const override { - if (isSeparator(index)) { - QRect rect = option.rect; - if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(option.widget)) - rect.setWidth(view->viewport()->width()); - QStyleOption opt; - opt.rect = rect; - m_widget->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, m_widget); - } else { - QItemDelegate::paint(painter, option, index); - } - } - - QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const override { - if (isSeparator(index)) { - int pm = m_widget->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, m_widget); - return QSize(pm, pm); - } - return QItemDelegate::sizeHint(option, index); - } -private: - QWidget *m_widget; -}; - -static QStringList subtract(const QStringList &minuend, const QStringList &subtrahend) -{ - QStringList result = minuend; - for (const QString &str : subtrahend) - result.removeOne(str); - return result; -} - -///////////////// - -OptionsWidget::OptionsWidget(QWidget *parent) - : QWidget(parent) - , m_noOptionText(tr("No Option")) - , m_invalidOptionText(tr("Invalid Option")) -{ - m_listWidget = new QListWidget(this); - m_listWidget->setItemDelegate(new ListWidgetDelegate(m_listWidget)); - QVBoxLayout *layout = new QVBoxLayout(this); - layout->addWidget(m_listWidget); - layout->setContentsMargins(QMargins()); - - connect(m_listWidget, &QListWidget::itemChanged, this, &OptionsWidget::itemChanged); -} - -void OptionsWidget::clear() -{ - setOptions(QStringList(), QStringList()); -} - -void OptionsWidget::setOptions(const QStringList &validOptions, - const QStringList &selectedOptions) -{ - m_listWidget->clear(); - m_optionToItem.clear(); - m_itemToOption.clear(); - - m_validOptions = validOptions; - m_validOptions.removeDuplicates(); - std::sort(m_validOptions.begin(), m_validOptions.end()); - - m_selectedOptions = selectedOptions; - m_selectedOptions.removeDuplicates(); - std::sort(m_selectedOptions.begin(), m_selectedOptions.end()); - - m_invalidOptions = subtract(m_selectedOptions, m_validOptions); - const QStringList validSelectedOptions = subtract(m_selectedOptions, m_invalidOptions); - const QStringList validUnselectedOptions = subtract(m_validOptions, m_selectedOptions); - - for (const QString &option : validSelectedOptions) - appendItem(option, true, true); - - for (const QString &option : m_invalidOptions) - appendItem(option, false, true); - - if ((validSelectedOptions.count() + m_invalidOptions.count()) - && validUnselectedOptions.count()) { - appendSeparator(); - } - - for (const QString &option : validUnselectedOptions) { - appendItem(option, true, false); - if (option.isEmpty() && validUnselectedOptions.count() > 1) // special No Option item - appendSeparator(); - } -} - -QStringList OptionsWidget::validOptions() const -{ - return m_validOptions; -} - -QStringList OptionsWidget::selectedOptions() const -{ - return m_selectedOptions; -} - -void OptionsWidget::setNoOptionText(const QString &text) -{ - if (m_noOptionText == text) - return; - - m_noOptionText = text; - - // update GUI - const auto itEnd = m_optionToItem.constEnd(); - for (auto it = m_optionToItem.constBegin(); it != itEnd; ++it) { - const QString optionName = it.key(); - if (optionName.isEmpty()) - it.value()->setText(optionText(optionName, m_validOptions.contains(optionName))); - } -} - -void OptionsWidget::setInvalidOptionText(const QString &text) -{ - if (m_invalidOptionText == text) - return; - - m_invalidOptionText = text; - - // update GUI - for (const QString &option : m_invalidOptions) - m_optionToItem.value(option)->setText(optionText(option, false)); -} - -QString OptionsWidget::optionText(const QString &optionName, bool valid) const -{ - QString text = optionName; - if (optionName.isEmpty()) - text = QLatin1Char('[') + m_noOptionText + QLatin1Char(']'); - if (!valid) - text += QLatin1String("\t[") + m_invalidOptionText + QLatin1Char(']'); - return text; -} - -QListWidgetItem *OptionsWidget::appendItem(const QString &optionName, bool valid, bool selected) -{ - QListWidgetItem *optionItem = new QListWidgetItem(optionText(optionName, valid), m_listWidget); - optionItem->setCheckState(selected ? Qt::Checked : Qt::Unchecked); - m_listWidget->insertItem(m_listWidget->count(), optionItem); - m_optionToItem[optionName] = optionItem; - m_itemToOption[optionItem] = optionName; - return optionItem; -} - -void OptionsWidget::appendSeparator() -{ - QListWidgetItem *separatorItem = new QListWidgetItem(m_listWidget); - ListWidgetDelegate::setSeparator(separatorItem); - m_listWidget->insertItem(m_listWidget->count(), separatorItem); -} - -void OptionsWidget::itemChanged(QListWidgetItem *item) -{ - const auto it = m_itemToOption.constFind(item); - if (it == m_itemToOption.constEnd()) - return; - - const QString option = *it; - - if (item->checkState() == Qt::Checked && !m_selectedOptions.contains(option)) { - m_selectedOptions.append(option); - std::sort(m_selectedOptions.begin(), m_selectedOptions.end()); - } else if (item->checkState() == Qt::Unchecked && m_selectedOptions.contains(option)) { - m_selectedOptions.removeOne(option); - } else { - return; - } - - emit optionSelectionChanged(m_selectedOptions); -} - - -QT_END_NAMESPACE diff --git a/src/assistant/assistant/optionswidget.h b/src/assistant/assistant/optionswidget.h deleted file mode 100644 index 52c876bad..000000000 --- a/src/assistant/assistant/optionswidget.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** 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:GPL-EXCEPT$ -** 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 General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** 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-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef OPTIONSWIDGET_H -#define OPTIONSWIDGET_H - -#include <QtWidgets/QWidget> -#include <QtCore/QMap> - -QT_BEGIN_NAMESPACE - -class QListWidget; -class QListWidgetItem; - -class OptionsWidget : public QWidget -{ - Q_OBJECT -public: - OptionsWidget(QWidget *parent = nullptr); - - void clear(); - void setOptions(const QStringList &validOptions, - const QStringList &selectedOptions); - QStringList validOptions() const; - QStringList selectedOptions() const; - - void setNoOptionText(const QString &text); - void setInvalidOptionText(const QString &text); - -signals: - void optionSelectionChanged(const QStringList &options); - -private: - QString optionText(const QString &optionName, bool valid) const; - QListWidgetItem *appendItem(const QString &optionName, bool valid, bool selected); - void appendSeparator(); - void itemChanged(QListWidgetItem *item); - - QListWidget *m_listWidget = nullptr; - QString m_noOptionText; - QString m_invalidOptionText; - QStringList m_validOptions; - QStringList m_invalidOptions; - QStringList m_selectedOptions; - QMap<QString, QListWidgetItem *> m_optionToItem; - QMap<QListWidgetItem *, QString> m_itemToOption; -}; - -QT_END_NAMESPACE - -#endif // OPTIONSWIDGET_H diff --git a/src/assistant/assistant/preferencesdialog.cpp b/src/assistant/assistant/preferencesdialog.cpp index 66d6381d3..5dd24a102 100644 --- a/src/assistant/assistant/preferencesdialog.cpp +++ b/src/assistant/assistant/preferencesdialog.cpp @@ -28,42 +28,24 @@ #include "preferencesdialog.h" #include "centralwidget.h" -#include "filternamedialog.h" #include "fontpanel.h" #include "helpenginewrapper.h" #include "openpagesmanager.h" +#include "helpdocsettingswidget.h" #include <QtCore/QVersionNumber> + #include <QtGui/QFontDatabase> -#include <QtWidgets/QMessageBox> -#include <QtHelp/QCompressedHelpInfo> #include <QtHelp/QHelpEngineCore> #include <QtHelp/QHelpFilterData> #include <QtHelp/QHelpFilterEngine> - -#include <QtWidgets/QFileDialog> +#include <QtHelp/QHelpFilterSettingsWidget> #include <QtDebug> QT_BEGIN_NAMESPACE -static QStringList versionsToStringList(const QList<QVersionNumber> &versions) -{ - QStringList versionList; - for (const QVersionNumber &version : versions) - versionList.append(version.isNull() ? QString() : version.toString()); - return versionList; -} - -static QList<QVersionNumber> stringListToVersions(const QStringList &versionList) -{ - QList<QVersionNumber> versions; - for (const QString &versionString : versionList) - versions.append(QVersionNumber::fromString(versionString)); - return versions; -} - PreferencesDialog::PreferencesDialog(QWidget *parent) : QDialog(parent) , m_appFontChanged(false) @@ -74,18 +56,6 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) { m_ui.setupUi(this); - QString resourcePath = QLatin1String(":/qt-project.org/assistant/images/"); -#ifdef Q_OS_MACOS - resourcePath.append(QLatin1String("mac")); -#else - resourcePath.append(QLatin1String("win")); -#endif - - m_ui.filterAddButton->setIcon(QIcon(resourcePath + QLatin1String("/plus.png"))); - m_ui.filterRemoveButton->setIcon(QIcon(resourcePath + QLatin1String("/minus.png"))); - - // TODO: filter docs via lineedit - connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &PreferencesDialog::okClicked); connect(m_ui.buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, @@ -93,56 +63,30 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked, this, &QDialog::reject); - m_originalSetup = readOriginalSetup(); - m_currentSetup = m_originalSetup; + m_docSettings = HelpDocSettings::readSettings(helpEngine.helpEngine()); if (m_hideDocsTab) { m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.docsTab)); } else { - connect(m_ui.docAddButton, &QAbstractButton::clicked, - this, &PreferencesDialog::addDocumentation); - connect(m_ui.docRemoveButton, &QAbstractButton::clicked, - this, &PreferencesDialog::removeDocumentation); - connect(m_ui.registeredDocsFilterLineEdit, &QLineEdit::textChanged, - this, [this](const QString &) { - for (const auto item : m_namespaceToItem) - applyDocListFilter(item); - }); - connect(m_ui.registeredDocsListWidget, &QListWidget::itemSelectionChanged, - this, [this](){ - m_ui.docRemoveButton->setEnabled( - !m_ui.registeredDocsListWidget->selectedItems().isEmpty()); + connect(m_ui.docSettingsWidget, &HelpDocSettingsWidget::docSettingsChanged, + [this](const HelpDocSettings &settings) { + m_docSettings = settings; + if (m_hideFiltersTab) + return; + + m_ui.filterSettingsWidget->setAvailableComponents(m_docSettings.components()); + m_ui.filterSettingsWidget->setAvailableVersions(m_docSettings.versions()); }); - updateDocumentationPage(); + m_ui.docSettingsWidget->setDocSettings(m_docSettings); } if (m_hideFiltersTab) { m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.filtersTab)); } else { - connect(m_ui.componentWidget, &OptionsWidget::optionSelectionChanged, - this, &PreferencesDialog::componentsChanged); - connect(m_ui.versionWidget, &OptionsWidget::optionSelectionChanged, - this, &PreferencesDialog::versionsChanged); - 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); - - m_ui.componentWidget->setNoOptionText(tr("No Component")); - m_ui.componentWidget->setInvalidOptionText(tr("Invalid Component")); - m_ui.versionWidget->setNoOptionText(tr("No Version")); - m_ui.versionWidget->setInvalidOptionText(tr("Invalid Version")); - - updateFilterPage(); + m_ui.filterSettingsWidget->setAvailableComponents(m_docSettings.components()); + m_ui.filterSettingsWidget->setAvailableVersions(m_docSettings.versions()); + m_ui.filterSettingsWidget->readSettings(helpEngine.filterEngine()); } updateFontSettingsPage(); @@ -152,331 +96,6 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) setFont(helpEngine.appFont()); } -FilterSetup PreferencesDialog::readOriginalSetup() const -{ - FilterSetup filterSetup; - - filterSetup.m_namespaceToComponent = helpEngine.filterEngine()->namespaceToComponent(); - filterSetup.m_namespaceToVersion = helpEngine.filterEngine()->namespaceToVersion(); - 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); - } - for (auto it = filterSetup.m_namespaceToVersion.constBegin(); - it != filterSetup.m_namespaceToVersion.constEnd(); ++it) { - filterSetup.m_versionToNamespace[it.value()].append(it.key()); - } - - const QStringList allFilters = helpEngine.filterEngine()->filters(); - for (const QString &filter : allFilters) - filterSetup.m_filterToData.insert(filter, helpEngine.filterEngine()->filterData(filter)); - - filterSetup.m_currentFilter = helpEngine.filterEngine()->activeFilter(); - - return filterSetup; -} - -void PreferencesDialog::updateFilterPage() -{ - if (m_hideFiltersTab) - return; - - QString currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); - if (currentFilter.isEmpty()) - currentFilter = m_currentSetup.m_currentFilter; - - m_currentSetup = m_originalSetup; - - m_ui.filterWidget->clear(); - m_ui.componentWidget->clear(); - m_ui.versionWidget->clear(); - m_itemToFilter.clear(); - m_filterToItem.clear(); - - for (const QString &filterName : m_currentSetup.m_filterToData.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); - } - - 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 ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); - - const bool filterSelected = !currentFilter.isEmpty(); - m_ui.componentWidget->setEnabled(filterSelected); - m_ui.versionWidget->setEnabled(filterSelected); - m_ui.filterRenameButton->setEnabled(filterSelected); - m_ui.filterRemoveButton->setEnabled(filterSelected); - - m_ui.componentWidget->setOptions(m_currentSetup.m_componentToNamespace.keys(), - m_currentSetup.m_filterToData.value(currentFilter).components()); - m_ui.versionWidget->setOptions(versionsToStringList(m_currentSetup.m_versionToNamespace.keys()), - versionsToStringList(m_currentSetup.m_filterToData.value(currentFilter).versions())); -} - -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); - applyDocListFilter(item); - m_ui.registeredDocsListWidget->addItem(item); - } - m_ui.docRemoveButton->setEnabled( - !m_ui.registeredDocsListWidget->selectedItems().isEmpty()); -} - -void PreferencesDialog::applyDocListFilter(QListWidgetItem *item) -{ - const QString namespaceName = m_itemToNamespace.value(item); - const QString nameFilter = m_ui.registeredDocsFilterLineEdit->text(); - - const bool matches = nameFilter.isEmpty() || namespaceName.contains(nameFilter); - - if (!matches) - item->setSelected(false); - item->setHidden(!matches); -} - -void PreferencesDialog::filterSelected(QListWidgetItem *item) -{ - Q_UNUSED(item) - - updateCurrentFilter(); -} - -void PreferencesDialog::componentsChanged(const QStringList &components) -{ - const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); - if (currentFilter.isEmpty()) - return; - - m_currentSetup.m_filterToData[currentFilter].setComponents(components); -} - -void PreferencesDialog::versionsChanged(const QStringList &versions) -{ - const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); - if (currentFilter.isEmpty()) - return; - - m_currentSetup.m_filterToData[currentFilter].setVersions(stringListToVersions(versions)); -} - -QString PreferencesDialog::suggestedNewFilterName(const QString &initialFilterName) const -{ - QString newFilterName = initialFilterName; - - int counter = 1; - while (m_filterToItem.contains(newFilterName)) { - newFilterName = initialFilterName + QLatin1Char(' ') - + QString::number(++counter); - } - - return newFilterName; -} - -QString PreferencesDialog::getUniqueFilterName(const QString &windowTitle, - const QString &initialFilterName) -{ - 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); -} - -void PreferencesDialog::renameFilterClicked() -{ - const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); - if (currentFilter.isEmpty()) - return; - - const QString newFilterName = getUniqueFilterName(tr("Rename Filter"), currentFilter); - if (newFilterName.isEmpty()) - return; - - const QHelpFilterData oldFilterData = m_currentSetup.m_filterToData.value(currentFilter); - removeFilter(currentFilter); - addFilter(newFilterName, oldFilterData); - - if (m_currentSetup.m_currentFilter == currentFilter) - m_currentSetup.m_currentFilter = newFilterName; -} - -void PreferencesDialog::removeFilterClicked() -{ - const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); - if (currentFilter.isEmpty()) - return; - - 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; - } - - removeFilter(currentFilter); - - if (m_currentSetup.m_currentFilter == currentFilter) - m_currentSetup.m_currentFilter.clear(); -} - -void PreferencesDialog::addFilter(const QString &filterName, - const QHelpFilterData &filterData) -{ - QListWidgetItem *item = new QListWidgetItem(filterName); - m_currentSetup.m_filterToData.insert(filterName, filterData); - 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(); -} - -void PreferencesDialog::removeFilter(const QString &filterName) -{ - QListWidgetItem *item = m_filterToItem.value(filterName); - m_itemToFilter.remove(item); - m_filterToItem.remove(filterName); - delete item; - - m_currentSetup.m_filterToData.remove(filterName); -} - -void PreferencesDialog::addDocumentation() -{ - const QStringList &fileNames = QFileDialog::getOpenFileNames(this, - tr("Add Documentation"), QString(), tr("Qt Compressed Help Files (*.qch)")); - if (fileNames.isEmpty()) - return; - - bool added = false; - - for (const QString &fileName : fileNames) { - const QCompressedHelpInfo info = QCompressedHelpInfo::fromCompressedHelpFile(fileName); - const QString namespaceName = info.namespaceName(); - - if (m_currentSetup.m_namespaceToFileName.contains(namespaceName)) - continue; - - if (m_currentSetup.m_fileNameToNamespace.contains(fileName)) - continue; - - const QString component = info.component(); - const QVersionNumber version = info.version(); - - m_currentSetup.m_namespaceToFileName.insert(namespaceName, fileName); - m_currentSetup.m_fileNameToNamespace.insert(fileName, namespaceName); - - m_currentSetup.m_namespaceToComponent.insert(namespaceName, component); - m_currentSetup.m_componentToNamespace[component].append(namespaceName); - - m_currentSetup.m_namespaceToVersion.insert(namespaceName, version); - m_currentSetup.m_versionToNamespace[version].append(namespaceName); - - if (!added) { - added = true; - m_ui.registeredDocsListWidget->clearSelection(); - } - - 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); - item->setSelected(true); - applyDocListFilter(item); - } - - if (added) - updateCurrentFilter(); -} - -void PreferencesDialog::removeDocumentation() -{ - 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); - const QVersionNumber version = m_currentSetup.m_namespaceToVersion.value(namespaceName); - m_currentSetup.m_namespaceToComponent.remove(namespaceName); - m_currentSetup.m_namespaceToVersion.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); - m_currentSetup.m_versionToNamespace[version].removeOne(namespaceName); - if (m_currentSetup.m_versionToNamespace[version].isEmpty()) - m_currentSetup.m_versionToNamespace.remove(version); - } - - updateCurrentFilter(); -} - void PreferencesDialog::okClicked() { applyChanges(); @@ -486,74 +105,27 @@ void PreferencesDialog::okClicked() void PreferencesDialog::applyClicked() { applyChanges(); - m_originalSetup = readOriginalSetup(); - m_currentSetup = m_originalSetup; - updateDocumentationPage(); - updateFilterPage(); -} -template <class T> -static QMap<QString, T> subtract(const QMap<QString, T> &minuend, - const QMap<QString, T> &subtrahend) -{ - QMap<QString, T> result = minuend; + m_docSettings = HelpDocSettings::readSettings(helpEngine.helpEngine()); - 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); + if (!m_hideDocsTab) + m_ui.docSettingsWidget->setDocSettings(m_docSettings); + if (!m_hideFiltersTab) { + m_ui.filterSettingsWidget->setAvailableComponents(m_docSettings.components()); + m_ui.filterSettingsWidget->setAvailableVersions(m_docSettings.versions()); + m_ui.filterSettingsWidget->readSettings(helpEngine.filterEngine()); } - - return result; } void PreferencesDialog::applyChanges() { 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; - } - - for (const QString &fileName : docsToAdd.values()) { - if (!helpEngine.registerDocumentation(fileName)) - qWarning() << "Cannot register documentation file:" << fileName; - changed = true; - } - - const QMap<QString, QHelpFilterData> filtersToRemove = subtract( - m_originalSetup.m_filterToData, - m_currentSetup.m_filterToData); - const QMap<QString, QHelpFilterData> filtersToAdd = subtract( - m_currentSetup.m_filterToData, - m_originalSetup.m_filterToData); - - const QString ¤tFilter = 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; - } - - for (auto it = filtersToAdd.cbegin(); it != filtersToAdd.cend(); ++it) { - helpEngine.filterEngine()->setFilterData(it.key(), it.value()); - changed = true; - } + if (!m_hideDocsTab) + changed = HelpDocSettings::applySettings(helpEngine.helpEngine(), m_docSettings); + if (!m_hideFiltersTab) + changed = changed || m_ui.filterSettingsWidget->applySettings(helpEngine.filterEngine()); if (changed) { - helpEngine.filterEngine()->setActiveFilter(m_currentSetup.m_currentFilter); - // In order to update the filtercombobox and indexwidget // according to the new filter configuration. helpEngine.setupData(); @@ -628,13 +200,13 @@ void PreferencesDialog::updateFontSettingsPage() const QList<QComboBox*> &appCombos = m_appFontPanel->findChildren<QComboBox*>(); for (QComboBox* box : appCombos) { - connect(box, QOverload<int>::of(&QComboBox::currentIndexChanged), + connect(box, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), this, &PreferencesDialog::appFontSettingChanged); } const QList<QComboBox*> &browserCombos = m_browserFontPanel->findChildren<QComboBox*>(); for (QComboBox* box : browserCombos) { - connect(box, QOverload<int>::of(&QComboBox::currentIndexChanged), + connect(box, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), this, &PreferencesDialog::browserFontSettingChanged); } } diff --git a/src/assistant/assistant/preferencesdialog.h b/src/assistant/assistant/preferencesdialog.h index b0601e280..a65066fde 100644 --- a/src/assistant/assistant/preferencesdialog.h +++ b/src/assistant/assistant/preferencesdialog.h @@ -29,31 +29,17 @@ #ifndef PREFERENCESDIALOG_H #define PREFERENCESDIALOG_H -#include <QtCore/QVersionNumber> +#include <QtCore/QMap> #include <QtWidgets/QDialog> #include <QtHelp/QHelpFilterData> #include "ui_preferencesdialog.h" +#include "helpdocsettings.h" QT_BEGIN_NAMESPACE class FontPanel; class HelpEngineWrapper; class QFileSystemWatcher; -class QVersionNumber; - -struct FilterSetup { - QMap<QString, QString> m_namespaceToComponent; - QMap<QString, QStringList> m_componentToNamespace; - - QMap<QString, QVersionNumber> m_namespaceToVersion; - QMap<QVersionNumber, QStringList> m_versionToNamespace; - - QMap<QString, QString> m_namespaceToFileName; - QMap<QString, QString> m_fileNameToNamespace; - - QMap<QString, QHelpFilterData> m_filterToData; - QString m_currentFilter; -}; class PreferencesDialog : public QDialog { @@ -63,17 +49,6 @@ public: PreferencesDialog(QWidget *parent = nullptr); private slots: - void filterSelected(QListWidgetItem *item); - void componentsChanged(const QStringList &components); - void versionsChanged(const QStringList &versions); - void addFilterClicked(); - void renameFilterClicked(); - void removeFilterClicked(); - void addFilter(const QString &filterName, - const QHelpFilterData &filterData = QHelpFilterData()); - void removeFilter(const QString &filterName); - void addDocumentation(); - void removeDocumentation(); void okClicked(); void applyClicked(); void applyChanges(); @@ -92,28 +67,12 @@ signals: void updateUserInterface(); private: - QString suggestedNewFilterName(const QString &initialFilterName) const; - QString getUniqueFilterName(const QString &windowTitle, - const QString &initialFilterName = QString()); - void applyDocListFilter(QListWidgetItem *item); - - void updateFilterPage(); - void updateCurrentFilter(); - void updateDocumentationPage(); void updateFontSettingsPage(); void updateOptionsPage(); - FilterSetup readOriginalSetup() const; Ui::PreferencesDialogClass m_ui; - 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; + HelpDocSettings m_docSettings; FontPanel *m_appFontPanel; FontPanel *m_browserFontPanel; diff --git a/src/assistant/assistant/preferencesdialog.ui b/src/assistant/assistant/preferencesdialog.ui index 68dbf68e2..2d1c480a6 100644 --- a/src/assistant/assistant/preferencesdialog.ui +++ b/src/assistant/assistant/preferencesdialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>395</width> - <height>341</height> + <height>376</height> </rect> </property> <property name="windowTitle"> @@ -17,7 +17,7 @@ <item> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> - <number>1</number> + <number>2</number> </property> <widget class="QWidget" name="fontsTab"> <attribute name="title"> @@ -69,60 +69,21 @@ <attribute name="title"> <string>Filters</string> </attribute> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="3"> - <widget class="QLabel" name="componentsLabel"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="text"> - <string>Components:</string> - </property> - </widget> - </item> - <item row="0" column="4"> - <widget class="QLabel" name="versionsLabel"> - <property name="text"> - <string>Versions:</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="3"> - <widget class="QListWidget" name="filterWidget"/> - </item> - <item row="1" column="3" rowspan="2"> - <widget class="OptionsWidget" name="componentWidget" native="true"/> - </item> - <item row="1" column="4" rowspan="2"> - <widget class="OptionsWidget" name="versionWidget" native="true"/> - </item> - <item row="2" column="0"> - <widget class="QToolButton" name="filterAddButton"> - <property name="text"> - <string>Add...</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <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> - </widget> - </item> - <item row="0" column="0" colspan="3"> - <widget class="QLabel" name="filterLabel"> - <property name="text"> - <string>Filter:</string> - </property> - </widget> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QHelpFilterSettingsWidget" name="filterSettingsWidget" native="true"/> </item> </layout> </widget> @@ -130,61 +91,21 @@ <attribute name="title"> <string>Documentation</string> </attribute> - <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 row="1" column="0"> - <widget class="QLineEdit" name="registeredDocsFilterLineEdit"> - <property name="placeholderText"> - <string><Filter></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> - <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> - </item> - <item row="2" column="0"> - <widget class="QListWidget" name="registeredDocsListWidget"> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - </widget> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="HelpDocSettingsWidget" name="docSettingsWidget" native="true"/> </item> </layout> </widget> @@ -359,9 +280,15 @@ <layoutdefault spacing="6" margin="11"/> <customwidgets> <customwidget> - <class>OptionsWidget</class> + <class>HelpDocSettingsWidget</class> + <extends>QWidget</extends> + <header>helpdocsettingswidget.h</header> + <container>1</container> + </customwidget> + <customwidget> + <class>QHelpFilterSettingsWidget</class> <extends>QWidget</extends> - <header>optionswidget.h</header> + <header>qhelpfiltersettingswidget.h</header> <container>1</container> </customwidget> </customwidgets> |