8#include "../misc/dialogutils.h"
10#include "ui_settingsdialog.h"
12#include <QItemSelectionModel>
16#include <QStringBuilder>
35 , m_currentCategory(nullptr)
36 , m_tabBarAlwaysVisible(true)
39 makeHeading(m_ui->headingLabel);
40 setStyleSheet(dialogStyle());
43 m_categoryFilterModel->setSourceModel(m_categoryModel);
44 m_ui->categoriesListView->setModel(m_categoryFilterModel);
48 connect(m_ui->categoriesListView->selectionModel(), &QItemSelectionModel::currentChanged,
this, &SettingsDialog::currentCategoryChanged);
50 connect(m_ui->abortPushButton, &QPushButton::clicked,
this, &SettingsDialog::reject);
52 connect(m_ui->okPushButton, &QPushButton::clicked,
this, &SettingsDialog::accept);
57 connect(m_ui->filterLineEdit, &QLineEdit::textChanged, m_categoryFilterModel, &OptionCategoryFilterModel::setFilterFixedString);
58 connect(m_ui->filterLineEdit, &QLineEdit::textChanged,
this, &SettingsDialog::updateTabWidget);
74 m_tabBarAlwaysVisible = value;
75 if (m_currentCategory) {
76 m_ui->pagesTabWidget->tabBar()->setHidden(!value && m_currentCategory->
pages().size() == 1);
88 return m_categoryModel->
category(categoryIndex);
101 if (pageIndex < category->pages().length()) {
113 if (event->spontaneous()) {
132void SettingsDialog::currentCategoryChanged(
const QModelIndex &index)
143 if (m_currentCategory) {
144 m_currentCategory->
setCurrentIndex(m_ui->pagesTabWidget->currentIndex());
147 if (m_currentCategory !=
category) {
152 m_currentCategory =
nullptr;
153 m_ui->headingLabel->setText(tr(
"No category selected"));
169 const bool hasSingleCategory = singleCategory !=
nullptr;
170 m_ui->filterLineEdit->setHidden(hasSingleCategory);
171 m_ui->categoriesListView->setHidden(hasSingleCategory);
172 m_ui->headingLabel->setHidden(hasSingleCategory);
173 if (hasSingleCategory) {
174 m_ui->filterLineEdit->clear();
185 return m_ui->pagesTabWidget->cornerWidget(corner);
193 m_ui->pagesTabWidget->setCornerWidget(widget, corner);
201 m_ui->headingLayout->addWidget(widget);
209 m_categoryFilterModel->setFilterFixedString(QString());
210 m_ui->filterLineEdit->clear();
212 m_ui->categoriesListView->selectionModel()->select(
213 m_categoryFilterModel->mapFromSource(m_categoryModel->index(categoryIndex)), QItemSelectionModel::ClearAndSelect);
214 m_ui->pagesTabWidget->setCurrentIndex(pageIndex);
220void SettingsDialog::updateTabWidget()
222 if (!m_currentCategory) {
223 m_ui->pagesTabWidget->clear();
226 m_ui->pagesTabWidget->setUpdatesEnabled(
false);
227 const QString searchKeyWord = m_ui->filterLineEdit->text();
228 int index = 0, pageIndex = 0;
229 for (OptionPage *
const page : m_currentCategory->
pages()) {
231 QScrollArea *scrollArea;
232 if (index < m_ui->pagesTabWidget->count()) {
233 scrollArea = qobject_cast<QScrollArea *>(m_ui->pagesTabWidget->widget(index));
234 scrollArea->takeWidget();
235 m_ui->pagesTabWidget->setTabText(index,
page->
widget()->windowTitle());
236 m_ui->pagesTabWidget->setTabIcon(index,
page->
widget()->windowIcon());
238 scrollArea =
new QScrollArea(m_ui->pagesTabWidget);
239 scrollArea->setFrameStyle(QFrame::NoFrame);
240 scrollArea->setBackgroundRole(QPalette::Base);
241 scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
242 scrollArea->setWidgetResizable(
true);
243 m_ui->pagesTabWidget->addTab(scrollArea,
page->
widget()->windowTitle());
244 m_ui->pagesTabWidget->setTabIcon(index,
page->
widget()->windowIcon());
247 page->
widget()->layout()->setAlignment(Qt::AlignTop | Qt::AlignLeft);
253 m_ui->pagesTabWidget->setCurrentIndex(pageIndex);
257 while (index < m_ui->pagesTabWidget->count()) {
258 QScrollArea *
const scrollArea = qobject_cast<QScrollArea *>(m_ui->pagesTabWidget->widget(index));
259 scrollArea->takeWidget();
260 m_ui->pagesTabWidget->removeTab(index);
263 m_ui->pagesTabWidget->tabBar()->setHidden(!m_tabBarAlwaysVisible && m_ui->pagesTabWidget->count() == 1);
264 m_ui->pagesTabWidget->setUpdatesEnabled(
true);
275 QString errorMessage;
284 if (errorMessage.isEmpty()) {
285 errorMessage = tr(
"<p><b>Errors occurred when applying changes:</b></p><ul>");
288 if (errors.isEmpty()) {
290 % QStringLiteral(
"</i>: ") % tr(
"unknown error") % QStringLiteral(
"</li>"));
292 for (
const QString &error : errors) {
294 % QStringLiteral(
"</i>: ") % error % QStringLiteral(
"</li>"));
302 if (!errorMessage.isEmpty()) {
303 errorMessage.append(QStringLiteral(
"</ul>"));
304 QMessageBox::warning(
this, windowTitle(), errorMessage);
309 return errorMessage.isEmpty();
The OptionCategoryFilterModel class is used by SettingsDialog to filter option categories.
The OptionCategoryModel class is used by SettingsDialog to store and display option categories.
OptionCategory * category(const QModelIndex &index) const
Returns the category for the specified model index.
QList< OptionCategory * > categories
void setCategories(const QList< OptionCategory * > &categories)
Sets the categories for the model.
The OptionCategory class wraps associated option pages.
void setCurrentIndex(int currentIndex)
Sets the current index.
int currentIndex() const
Returns the index of the currently shown page.
void resetAllPages()
Resets all pages.
QList< OptionPage * > pages
The OptionPage class is the base class for SettingsDialog pages.
virtual bool apply()=0
Applies altered settings.
virtual void reset()=0
Discards altered settings and resets relevant widgets.
bool matches(const QString &searchKeyWord)
Returns whether the pages matches the specified searchKeyWord.
bool hasBeenShown() const
Returns an indication whether the option page has been shown yet.
QWidget * widget()
Returns the widget for the option page.
The SettingsDialog class provides a framework for creating settings dialogs with different categories...
OptionCategoryModel * categoryModel()
Returns the category model used by the settings dialog to manage the categories.
void setTabBarAlwaysVisible(bool value)
Sets whether the tab bar is always visible.
OptionCategory * category(int categoryIndex) const
Returns the category for the specified categoryIndex.
SettingsDialog(QWidget *parent=nullptr)
Constructs a settings dialog.
void showCategory(OptionCategory *category)
Sets the current category to the specified category and updates the relevant widgets to show it.
OptionPage * page(int categoryIndex, int pageIndex) const
Returns the page for the specified categoryIndex and the specified pageIndex.
void reset()
Resets all changes.
bool apply()
Applies all changes.
void addHeadingWidget(QWidget *widget)
Adds a widget next to the heading.
QWidget * cornerWidget(Qt::Corner corner=Qt::TopRightCorner) const
Returns the tab-widget's corner widget.
~SettingsDialog() override
Destroys the settings dialog.
void showEvent(QShowEvent *event) override
Resets all pages before the dialog is shown by the application.
void setSingleCategory(OptionCategory *singleCategory)
Enables single-category mode to show only the specified singleCategory.
void setCornerWidget(QWidget *widget, Qt::Corner corner=Qt::TopRightCorner)
Sets the tab-widget's corner widget.
void selectPage(int categoryIndex, int pageIndex)
Selects the specified page within the specified category.