diff options
Diffstat (limited to 'src/assistant')
-rw-r--r-- | src/assistant/help/help.pro | 17 | ||||
-rw-r--r-- | src/assistant/help/helpsystem.qrc | 4 | ||||
-rw-r--r-- | src/assistant/help/images/mac/minus.png | bin | 0 -> 488 bytes | |||
-rw-r--r-- | src/assistant/help/images/mac/plus.png | bin | 0 -> 810 bytes | |||
-rw-r--r-- | src/assistant/help/images/win/minus.png | bin | 0 -> 429 bytes | |||
-rw-r--r-- | src/assistant/help/images/win/plus.png | bin | 0 -> 709 bytes | |||
-rw-r--r-- | src/assistant/help/qfilternamedialog.cpp | 65 | ||||
-rw-r--r-- | src/assistant/help/qfilternamedialog.ui | 55 | ||||
-rw-r--r-- | src/assistant/help/qfilternamedialog_p.h | 56 | ||||
-rw-r--r-- | src/assistant/help/qhelpfiltersettings.cpp | 170 | ||||
-rw-r--r-- | src/assistant/help/qhelpfiltersettings_p.h | 85 | ||||
-rw-r--r-- | src/assistant/help/qhelpfiltersettingswidget.cpp | 428 | ||||
-rw-r--r-- | src/assistant/help/qhelpfiltersettingswidget.h | 78 | ||||
-rw-r--r-- | src/assistant/help/qhelpfiltersettingswidget.ui | 83 | ||||
-rw-r--r-- | src/assistant/help/qoptionswidget.cpp | 229 | ||||
-rw-r--r-- | src/assistant/help/qoptionswidget_p.h | 76 |
16 files changed, 1344 insertions, 2 deletions
diff --git a/src/assistant/help/help.pro b/src/assistant/help/help.pro index cd7781dde..ff7a81374 100644 --- a/src/assistant/help/help.pro +++ b/src/assistant/help/help.pro @@ -12,10 +12,13 @@ DEFINES -= QT_ASCII_CAST_WARNINGS RESOURCES += helpsystem.qrc SOURCES += \ qcompressedhelpinfo.cpp \ + qfilternamedialog.cpp \ qhelpenginecore.cpp \ qhelpengine.cpp \ qhelpfilterdata.cpp \ qhelpfilterengine.cpp \ + qhelpfiltersettings.cpp \ + qhelpfiltersettingswidget.cpp \ qhelpdbreader.cpp \ qhelpcontentwidget.cpp \ qhelpindexwidget.cpp \ @@ -26,15 +29,19 @@ SOURCES += \ qhelpsearchindexwriter_default.cpp \ qhelpsearchindexreader_default.cpp \ qhelpsearchindexreader.cpp \ - qhelp_global.cpp + qhelp_global.cpp \ + qoptionswidget.cpp HEADERS += \ qcompressedhelpinfo.h \ + qfilternamedialog_p.h \ qhelpenginecore.h \ qhelpengine.h \ qhelpengine_p.h \ qhelpfilterdata.h \ qhelpfilterengine.h \ + qhelpfiltersettings_p.h \ + qhelpfiltersettingswidget.h \ qhelp_global.h \ qhelpdbreader_p.h \ qhelpcontentwidget.h \ @@ -45,6 +52,12 @@ HEADERS += \ qhelpsearchresultwidget.h \ qhelpsearchindexwriter_default_p.h \ qhelpsearchindexreader_default_p.h \ - qhelpsearchindexreader_p.h + qhelpsearchindexreader_p.h \ + qoptionswidget_p.h + +FORMS += \ + qhelpfiltersettingswidget.ui \ + qfilternamedialog.ui + load(qt_module) diff --git a/src/assistant/help/helpsystem.qrc b/src/assistant/help/helpsystem.qrc index 785923aad..611008639 100644 --- a/src/assistant/help/helpsystem.qrc +++ b/src/assistant/help/helpsystem.qrc @@ -4,5 +4,9 @@ <file>images/1rightarrow.png</file> <file>images/3leftarrow.png</file> <file>images/3rightarrow.png</file> + <file>images/mac/minus.png</file> + <file>images/mac/plus.png</file> + <file>images/win/minus.png</file> + <file>images/win/plus.png</file> </qresource> </RCC> diff --git a/src/assistant/help/images/mac/minus.png b/src/assistant/help/images/mac/minus.png Binary files differnew file mode 100644 index 000000000..8d2eaed52 --- /dev/null +++ b/src/assistant/help/images/mac/minus.png diff --git a/src/assistant/help/images/mac/plus.png b/src/assistant/help/images/mac/plus.png Binary files differnew file mode 100644 index 000000000..1ee45423e --- /dev/null +++ b/src/assistant/help/images/mac/plus.png diff --git a/src/assistant/help/images/win/minus.png b/src/assistant/help/images/win/minus.png Binary files differnew file mode 100644 index 000000000..c0dc274bb --- /dev/null +++ b/src/assistant/help/images/win/minus.png diff --git a/src/assistant/help/images/win/plus.png b/src/assistant/help/images/win/plus.png Binary files differnew file mode 100644 index 000000000..ecf058941 --- /dev/null +++ b/src/assistant/help/images/win/plus.png diff --git a/src/assistant/help/qfilternamedialog.cpp b/src/assistant/help/qfilternamedialog.cpp new file mode 100644 index 000000000..8563a3355 --- /dev/null +++ b/src/assistant/help/qfilternamedialog.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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: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 "qfilternamedialog_p.h" + +QT_BEGIN_NAMESPACE + +QFilterNameDialog::QFilterNameDialog(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, &QFilterNameDialog::updateOkButton); + m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true); +} + +void QFilterNameDialog::setFilterName(const QString &filter) +{ + m_ui.lineEdit->setText(filter); + m_ui.lineEdit->selectAll(); +} + +QString QFilterNameDialog::filterName() const +{ + return m_ui.lineEdit->text(); +} + +void QFilterNameDialog::updateOkButton() +{ + m_ui.buttonBox->button(QDialogButtonBox::Ok) + ->setDisabled(m_ui.lineEdit->text().isEmpty()); +} + +QT_END_NAMESPACE diff --git a/src/assistant/help/qfilternamedialog.ui b/src/assistant/help/qfilternamedialog.ui new file mode 100644 index 000000000..1da584a80 --- /dev/null +++ b/src/assistant/help/qfilternamedialog.ui @@ -0,0 +1,55 @@ +<?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/help/qfilternamedialog_p.h b/src/assistant/help/qfilternamedialog_p.h new file mode 100644 index 000000000..f805e9308 --- /dev/null +++ b/src/assistant/help/qfilternamedialog_p.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** 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: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 QFILTERNAMEDIALOG_H +#define QFILTERNAMEDIALOG_H + +#include <QtWidgets/QDialog> +#include "ui_qfilternamedialog.h" + +QT_BEGIN_NAMESPACE + +class QFilterNameDialog : public QDialog +{ + Q_OBJECT + +public: + QFilterNameDialog(QWidget *parent = nullptr); + + void setFilterName(const QString &filter); + QString filterName() const; + +private slots: + void updateOkButton(); + +private: + Ui::FilterNameDialogClass m_ui; +}; + +QT_END_NAMESPACE + +#endif // QFILTERNAMEDIALOG_H diff --git a/src/assistant/help/qhelpfiltersettings.cpp b/src/assistant/help/qhelpfiltersettings.cpp new file mode 100644 index 000000000..e9a1c3f4e --- /dev/null +++ b/src/assistant/help/qhelpfiltersettings.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** 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 "qhelpfiltersettings_p.h" +#include "qhelpfilterdata.h" + +#include <QtCore/QMap> +#include <QtHelp/QHelpFilterEngine> + +QT_BEGIN_NAMESPACE + +class QHelpFilterSettingsPrivate : public QSharedData +{ +public: + QHelpFilterSettingsPrivate() = default; + QHelpFilterSettingsPrivate(const QHelpFilterSettingsPrivate &other) = default; + ~QHelpFilterSettingsPrivate() = default; + + QMap<QString, QHelpFilterData> m_filterToData; + QString m_currentFilter; +}; + +QHelpFilterSettings::QHelpFilterSettings() + : d(new QHelpFilterSettingsPrivate) +{ +} + +QHelpFilterSettings::QHelpFilterSettings(const QHelpFilterSettings &) = default; + +QHelpFilterSettings::QHelpFilterSettings(QHelpFilterSettings &&) = default; + +QHelpFilterSettings::~QHelpFilterSettings() = default; + +QHelpFilterSettings &QHelpFilterSettings::operator=(const QHelpFilterSettings &) = default; + +QHelpFilterSettings &QHelpFilterSettings::operator=(QHelpFilterSettings &&) = default; + +void QHelpFilterSettings::setFilter(const QString &filterName, + const QHelpFilterData &filterData) +{ + d->m_filterToData.insert(filterName, filterData); +} + +void QHelpFilterSettings::removeFilter(const QString &filterName) +{ + d->m_filterToData.remove(filterName); +} + +QStringList QHelpFilterSettings::filterNames() const +{ + return d->m_filterToData.keys(); +} + +QHelpFilterData QHelpFilterSettings::filterData(const QString &filterName) const +{ + return d->m_filterToData.value(filterName); +} + +QMap<QString, QHelpFilterData> QHelpFilterSettings::filters() const +{ + return d->m_filterToData; +} + +void QHelpFilterSettings::setCurrentFilter(const QString &filterName) +{ + d->m_currentFilter = filterName; +} + +QString QHelpFilterSettings::currentFilter() const +{ + return d->m_currentFilter; +} + +QHelpFilterSettings QHelpFilterSettings::readSettings(QHelpFilterEngine *filterEngine) +{ + QHelpFilterSettings filterSettings; + + const QStringList allFilters = filterEngine->filters(); + for (const QString &filter : allFilters) + filterSettings.setFilter(filter, filterEngine->filterData(filter)); + + filterSettings.setCurrentFilter(filterEngine->activeFilter()); + + return filterSettings; +} + +static QMap<QString, QHelpFilterData> subtract(const QMap<QString, QHelpFilterData> &minuend, + const QMap<QString, QHelpFilterData> &subtrahend) +{ + QMap<QString, QHelpFilterData> 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 QHelpFilterSettings::applySettings(QHelpFilterEngine *filterEngine, + const QHelpFilterSettings &settings) +{ + bool changed = false; + const QHelpFilterSettings oldSettings = readSettings(filterEngine); + + const QMap<QString, QHelpFilterData> filtersToRemove = subtract( + oldSettings.filters(), + settings.filters()); + const QMap<QString, QHelpFilterData> filtersToAdd = subtract( + settings.filters(), + oldSettings.filters()); + + const QString ¤tFilter = filterEngine->activeFilter(); + + for (const QString &filter : filtersToRemove.keys()) { + filterEngine->removeFilter(filter); + if (currentFilter == filter && !filtersToAdd.contains(filter)) + filterEngine->setActiveFilter(QString()); + changed = true; + } + + for (auto it = filtersToAdd.cbegin(); it != filtersToAdd.cend(); ++it) { + filterEngine->setFilterData(it.key(), it.value()); + changed = true; + } + + if (changed) + filterEngine->setActiveFilter(settings.currentFilter()); + + return changed; +} + +QT_END_NAMESPACE diff --git a/src/assistant/help/qhelpfiltersettings_p.h b/src/assistant/help/qhelpfiltersettings_p.h new file mode 100644 index 000000000..50e30e492 --- /dev/null +++ b/src/assistant/help/qhelpfiltersettings_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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 QHELPFILTERSETTINGS_H +#define QHELPFILTERSETTINGS_H + +#include <QtCore/QSharedDataPointer> + +QT_BEGIN_NAMESPACE + +template <class K, class T> +class QMap; +class QHelpFilterData; +class QHelpFilterEngine; +class QHelpFilterSettingsPrivate; + +class QHelpFilterSettings final +{ +public: + QHelpFilterSettings(); + QHelpFilterSettings(const QHelpFilterSettings &other); + QHelpFilterSettings(QHelpFilterSettings &&other); + ~QHelpFilterSettings(); + + QHelpFilterSettings &operator=(const QHelpFilterSettings &other); + QHelpFilterSettings &operator=(QHelpFilterSettings &&other); + + void swap(QHelpFilterSettings &other) noexcept + { d.swap(other.d); } + + void setFilter(const QString &filterName, const QHelpFilterData &filterData); + void removeFilter(const QString &filterName); + QStringList filterNames() const; + QHelpFilterData filterData(const QString &filterName) const; + QMap<QString, QHelpFilterData> filters() const; + + void setCurrentFilter(const QString &filterName); + QString currentFilter() const; + + static QHelpFilterSettings readSettings(QHelpFilterEngine *filterEngine); + static bool applySettings(QHelpFilterEngine *filterEngine, const QHelpFilterSettings &settings); + +private: + QSharedDataPointer<QHelpFilterSettingsPrivate> d; +}; + +QT_END_NAMESPACE + +#endif // QHELPFILTERSETTINGS_H diff --git a/src/assistant/help/qhelpfiltersettingswidget.cpp b/src/assistant/help/qhelpfiltersettingswidget.cpp new file mode 100644 index 000000000..15cc4f475 --- /dev/null +++ b/src/assistant/help/qhelpfiltersettingswidget.cpp @@ -0,0 +1,428 @@ +/**************************************************************************** +** +** 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 "qhelpfilterdata.h" +#include "qhelpfiltersettings_p.h" +#include "qhelpfiltersettingswidget.h" +#include "ui_qhelpfiltersettingswidget.h" +#include "qfilternamedialog_p.h" + +#include <QtWidgets/QMessageBox> +#include <QtCore/QVersionNumber> + +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; +} + +class QHelpFilterSettingsWidgetPrivate +{ + QHelpFilterSettingsWidget *q_ptr; + Q_DECLARE_PUBLIC(QHelpFilterSettingsWidget) +public: + QHelpFilterSettingsWidgetPrivate() = default; + + QHelpFilterSettings filterSettings() const; + void setFilterSettings(const QHelpFilterSettings &settings); + + void updateCurrentFilter(); + 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); + QString getUniqueFilterName(const QString &windowTitle, + const QString &initialFilterName); + QString suggestedNewFilterName(const QString &initialFilterName) const; + + QMap<QString, QListWidgetItem *> m_filterToItem; + QHash<QListWidgetItem *, QString> m_itemToFilter; + + Ui::QHelpFilterSettingsWidget m_ui; + QStringList m_components; + QList<QVersionNumber> m_versions; + QHelpFilterSettings m_filterSettings; +}; + +void QHelpFilterSettingsWidgetPrivate::setFilterSettings(const QHelpFilterSettings &settings) +{ + QString currentFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); + if (currentFilter.isEmpty()) { + if (!m_filterSettings.currentFilter().isEmpty()) + currentFilter = m_filterSettings.currentFilter(); + else + currentFilter = settings.currentFilter(); + } + + m_filterSettings = settings; + + m_ui.filterWidget->clear(); + m_ui.componentWidget->clear(); + m_ui.versionWidget->clear(); + m_itemToFilter.clear(); + m_filterToItem.clear(); + + for (const QString &filterName : m_filterSettings.filterNames()) { + 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(); +} + +QHelpFilterSettings QHelpFilterSettingsWidgetPrivate::filterSettings() const +{ + return m_filterSettings; +} + +void QHelpFilterSettingsWidgetPrivate::updateCurrentFilter() +{ + 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.renameButton->setEnabled(filterSelected); + m_ui.removeButton->setEnabled(filterSelected); + + m_ui.componentWidget->setOptions(m_components, + m_filterSettings.filterData(currentFilter).components()); + m_ui.versionWidget->setOptions(versionsToStringList(m_versions), + versionsToStringList(m_filterSettings.filterData(currentFilter).versions())); +} + +void QHelpFilterSettingsWidgetPrivate::componentsChanged(const QStringList &components) +{ + const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); + if (currentFilter.isEmpty()) + return; + + QHelpFilterData filterData = m_filterSettings.filterData(currentFilter); + filterData.setComponents(components); + m_filterSettings.setFilter(currentFilter, filterData); +} + +void QHelpFilterSettingsWidgetPrivate::versionsChanged(const QStringList &versions) +{ + const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); + if (currentFilter.isEmpty()) + return; + + QHelpFilterData filterData = m_filterSettings.filterData(currentFilter); + filterData.setVersions(stringListToVersions(versions)); + m_filterSettings.setFilter(currentFilter, filterData); +} + +void QHelpFilterSettingsWidgetPrivate::addFilterClicked() +{ + Q_Q(QHelpFilterSettingsWidget); + + const QString newFilterName = getUniqueFilterName(q->tr("Add Filter"), + suggestedNewFilterName(q->tr("New Filter"))); + if (newFilterName.isEmpty()) + return; + + addFilter(newFilterName); +} + +void QHelpFilterSettingsWidgetPrivate::renameFilterClicked() +{ + Q_Q(QHelpFilterSettingsWidget); + + const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); + if (currentFilter.isEmpty()) + return; + + const QString newFilterName = getUniqueFilterName(q->tr("Rename Filter"), currentFilter); + if (newFilterName.isEmpty()) + return; + + const QHelpFilterData oldFilterData = m_filterSettings.filterData(currentFilter); + removeFilter(currentFilter); + addFilter(newFilterName, oldFilterData); + + if (m_filterSettings.currentFilter() == currentFilter) + m_filterSettings.setCurrentFilter(newFilterName); +} + +void QHelpFilterSettingsWidgetPrivate::removeFilterClicked() +{ + Q_Q(QHelpFilterSettingsWidget); + + const QString ¤tFilter = m_itemToFilter.value(m_ui.filterWidget->currentItem()); + if (currentFilter.isEmpty()) + return; + + if (QMessageBox::question(q, q->tr("Remove Filter"), + q->tr("Are you sure you want to remove the \"%1\" filter?") + .arg(currentFilter), + QMessageBox::Yes | QMessageBox::No) + != QMessageBox::Yes) { + return; + } + + removeFilter(currentFilter); + + if (m_filterSettings.currentFilter() == currentFilter) + m_filterSettings.setCurrentFilter(QString()); +} + +void QHelpFilterSettingsWidgetPrivate::addFilter(const QString &filterName, + const QHelpFilterData &filterData) +{ + QListWidgetItem *item = new QListWidgetItem(filterName); + m_filterSettings.setFilter(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 QHelpFilterSettingsWidgetPrivate::removeFilter(const QString &filterName) +{ + QListWidgetItem *item = m_filterToItem.value(filterName); + m_itemToFilter.remove(item); + m_filterToItem.remove(filterName); + delete item; + + m_filterSettings.removeFilter(filterName); +} + +QString QHelpFilterSettingsWidgetPrivate::getUniqueFilterName(const QString &windowTitle, + const QString &initialFilterName) +{ + Q_Q(QHelpFilterSettingsWidget); + + QString newFilterName = initialFilterName; + while (1) { + QFilterNameDialog dialog(q); + 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(q, q->tr("Filter Exists"), + q->tr("The filter \"%1\" already exists.") + .arg(newFilterName), + QMessageBox::Retry | QMessageBox::Cancel) + == QMessageBox::Cancel) { + return QString(); + } + } + + return newFilterName; +} + +QString QHelpFilterSettingsWidgetPrivate::suggestedNewFilterName(const QString &initialFilterName) const +{ + QString newFilterName = initialFilterName; + + int counter = 1; + while (m_filterToItem.contains(newFilterName)) { + newFilterName = initialFilterName + QLatin1Char(' ') + + QString::number(++counter); + } + + return newFilterName; +} + +/*! + \class QHelpFilterSettingsWidget + \inmodule QtHelp + \since 5.15 + \brief The QHelpFilterSettingsWidget class provides a widget that allows + for creating, editing and removing filters. + + The instance of QHelpFilterSettingsWidget may be a part of + a preferences dialog. Before showing the dialog, \l setAvailableComponents() + and \l setAvailableVersions() should be called, otherwise the filter + settings widget will only offer a creation of empty filters, + which wouldn't be useful. In addition, \l readSettings should also + be called to fill up the filter settings widget with the list of filters + already stored in the filter engine. The creation of new filters, + modifications to existing filters and removal of unneeded filters are + handled by the widget automatically. If you want to store the current + state of the widget and apply it to the filter engine e.g. after + the user clicked the apply button - call \l applySettings(). +*/ + +/*! + Constructs a filter settings widget with \a parent as parent widget. +*/ +QHelpFilterSettingsWidget::QHelpFilterSettingsWidget(QWidget *parent) + : QWidget(parent) + , d_ptr(new QHelpFilterSettingsWidgetPrivate()) +{ + Q_D(QHelpFilterSettingsWidget); + d->q_ptr = this; + d->m_ui.setupUi(this); + + // TODO: make resources configurable + QString resourcePath = QLatin1String(":/qt-project.org/assistant/images/"); +#ifdef Q_OS_MACOS + resourcePath.append(QLatin1String("mac")); +#else + resourcePath.append(QLatin1String("win")); +#endif + d->m_ui.addButton->setIcon(QIcon(resourcePath + QLatin1String("/plus.png"))); + d->m_ui.removeButton->setIcon(QIcon(resourcePath + QLatin1String("/minus.png"))); + + connect(d->m_ui.componentWidget, &QOptionsWidget::optionSelectionChanged, + [this](const QStringList &options) { + Q_D(QHelpFilterSettingsWidget); + d->componentsChanged(options); + }); + connect(d->m_ui.versionWidget, &QOptionsWidget::optionSelectionChanged, + [this](const QStringList &options) { + Q_D(QHelpFilterSettingsWidget); + d->versionsChanged(options); + }); + connect(d->m_ui.filterWidget, &QListWidget::currentItemChanged, + this, [this](QListWidgetItem *) { + Q_D(QHelpFilterSettingsWidget); + d->updateCurrentFilter(); + }); + connect(d->m_ui.filterWidget, &QListWidget::itemDoubleClicked, + [this](QListWidgetItem *) { + Q_D(QHelpFilterSettingsWidget); + d->renameFilterClicked(); + }); + + // TODO: repeat these actions on context menu + connect(d->m_ui.addButton, &QAbstractButton::clicked, + [this]() { + Q_D(QHelpFilterSettingsWidget); + d->addFilterClicked(); + }); + connect(d->m_ui.renameButton, &QAbstractButton::clicked, + [this]() { + Q_D(QHelpFilterSettingsWidget); + d->renameFilterClicked(); + }); + connect(d->m_ui.removeButton, &QAbstractButton::clicked, + [this]() { + Q_D(QHelpFilterSettingsWidget); + d->removeFilterClicked(); + }); + + d->m_ui.componentWidget->setNoOptionText(tr("No Component")); + d->m_ui.componentWidget->setInvalidOptionText(tr("Invalid Component")); + d->m_ui.versionWidget->setNoOptionText(tr("No Version")); + d->m_ui.versionWidget->setInvalidOptionText(tr("Invalid Version")); +} + +/*! + Destroys the filter settings widget. +*/ +QHelpFilterSettingsWidget::~QHelpFilterSettingsWidget() = default; + +/*! + Sets the list of all available components to \a components. + \sa QHelpFilterEngine::availableComponents() +*/ +void QHelpFilterSettingsWidget::setAvailableComponents(const QStringList &components) +{ + Q_D(QHelpFilterSettingsWidget); + d->m_components = components; + d->updateCurrentFilter(); +} + +/*! + Sets the list of all available version numbers to \a versions. + \sa QHelpFilterEngine::availableVersions() +*/ +void QHelpFilterSettingsWidget::setAvailableVersions(const QList<QVersionNumber> &versions) +{ + Q_D(QHelpFilterSettingsWidget); + d->m_versions = versions; + d->updateCurrentFilter(); +} + +/*! + Reads the filter settings stored inside \a filterEngine and sets up + this filter settings widget accordingly. +*/ +void QHelpFilterSettingsWidget::readSettings(QHelpFilterEngine *filterEngine) +{ + Q_D(QHelpFilterSettingsWidget); + const QHelpFilterSettings settings = QHelpFilterSettings::readSettings(filterEngine); + d->setFilterSettings(settings); +} + +/*! + Writes the filter settings, currently presented in this filter settings + widget, to the \a filterEngine. The old settings stored in the filter + engine will be overwritten. +*/ +bool QHelpFilterSettingsWidget::applySettings(QHelpFilterEngine *filterEngine) +{ + Q_D(QHelpFilterSettingsWidget); + return QHelpFilterSettings::applySettings(filterEngine, d->filterSettings()); +} + +QT_END_NAMESPACE diff --git a/src/assistant/help/qhelpfiltersettingswidget.h b/src/assistant/help/qhelpfiltersettingswidget.h new file mode 100644 index 000000000..1b6606054 --- /dev/null +++ b/src/assistant/help/qhelpfiltersettingswidget.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 QHELPFILTERSETTINGSWIDGET_H +#define QHELPFILTERSETTINGSWIDGET_H + +#include <QtHelp/qhelp_global.h> + +#include <QtWidgets/QWidget> + +QT_BEGIN_NAMESPACE + +class QVersionNumber; + +class QHelpFilterEngine; +class QHelpFilterSettingsWidgetPrivate; + +class QHELP_EXPORT QHelpFilterSettingsWidget : public QWidget +{ + Q_OBJECT +public: + QHelpFilterSettingsWidget(QWidget *parent); + + ~QHelpFilterSettingsWidget(); + + void setAvailableComponents(const QStringList &components); + void setAvailableVersions(const QList<QVersionNumber> &versions); + + // TODO: filterEngine may be moved to c'tor or to setFilterEngine() setter + void readSettings(QHelpFilterEngine *filterEngine); + bool applySettings(QHelpFilterEngine *filterEngine); + +private: + QScopedPointer<class QHelpFilterSettingsWidgetPrivate> d_ptr; + Q_DECLARE_PRIVATE(QHelpFilterSettingsWidget) + Q_DISABLE_COPY_MOVE(QHelpFilterSettingsWidget) +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/assistant/help/qhelpfiltersettingswidget.ui b/src/assistant/help/qhelpfiltersettingswidget.ui new file mode 100644 index 000000000..7e16e3f7b --- /dev/null +++ b/src/assistant/help/qhelpfiltersettingswidget.ui @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QHelpFilterSettingsWidget</class> + <widget class="QWidget" name="QHelpFilterSettingsWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>347</width> + <height>127</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="3"> + <widget class="QLabel" name="filterLabel"> + <property name="text"> + <string>Filter</string> + </property> + </widget> + </item> + <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="QOptionsWidget" name="componentWidget" native="true"/> + </item> + <item row="1" column="4" rowspan="2"> + <widget class="QOptionsWidget" name="versionWidget" native="true"/> + </item> + <item row="2" column="0"> + <widget class="QToolButton" name="addButton"> + <property name="text"> + <string>Add...</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QToolButton" name="renameButton"> + <property name="text"> + <string>Rename...</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QToolButton" name="removeButton"> + <property name="text"> + <string>Remove</string> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>QOptionsWidget</class> + <extends>QWidget</extends> + <header>qoptionswidget_p.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/assistant/help/qoptionswidget.cpp b/src/assistant/help/qoptionswidget.cpp new file mode 100644 index 000000000..21fdfe07a --- /dev/null +++ b/src/assistant/help/qoptionswidget.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** 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: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 "qoptionswidget_p.h" + +#include <QtWidgets/QComboBox> +#include <QtWidgets/QItemDelegate> +#include <QtWidgets/QListWidget> +#include <QtWidgets/QVBoxLayout> + +QT_BEGIN_NAMESPACE + +class ListWidgetDelegate : public QItemDelegate +{ +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; +} + +QOptionsWidget::QOptionsWidget(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, &QOptionsWidget::itemChanged); +} + +void QOptionsWidget::clear() +{ + setOptions(QStringList(), QStringList()); +} + +void QOptionsWidget::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 QOptionsWidget::validOptions() const +{ + return m_validOptions; +} + +QStringList QOptionsWidget::selectedOptions() const +{ + return m_selectedOptions; +} + +void QOptionsWidget::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 QOptionsWidget::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 QOptionsWidget::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 *QOptionsWidget::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 QOptionsWidget::appendSeparator() +{ + QListWidgetItem *separatorItem = new QListWidgetItem(m_listWidget); + ListWidgetDelegate::setSeparator(separatorItem); + m_listWidget->insertItem(m_listWidget->count(), separatorItem); +} + +void QOptionsWidget::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/help/qoptionswidget_p.h b/src/assistant/help/qoptionswidget_p.h new file mode 100644 index 000000000..ff075e464 --- /dev/null +++ b/src/assistant/help/qoptionswidget_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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: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 QOPTIONSWIDGET_H +#define QOPTIONSWIDGET_H + +#include <QtWidgets/QWidget> +#include <QtCore/QMap> + +QT_BEGIN_NAMESPACE + +class QListWidget; +class QListWidgetItem; + +class QOptionsWidget : public QWidget +{ + Q_OBJECT +public: + QOptionsWidget(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 |