From 42aebdfa977f092bc0418e4959471427cc7c6e6b Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sun, 26 Nov 2023 16:01:22 +0100 Subject: [PATCH 1/2] Gui: Add ScrollArea to Preferences This adds QScrollArea widget to DlgPreferences which in turn allows preference pages to be scrollable. Stacked widget sizes are forced to selected widget so scroll area should appear when it is needed. Fixes #11511 --- src/Gui/DlgPreferences.ui | 70 ++++++++++++++++++++++++++++++++--- src/Gui/DlgPreferencesImp.cpp | 33 ++++++++++++++++- src/Gui/DlgPreferencesImp.h | 2 + 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/src/Gui/DlgPreferences.ui b/src/Gui/DlgPreferences.ui index 092907905d..844f91547f 100644 --- a/src/Gui/DlgPreferences.ui +++ b/src/Gui/DlgPreferences.ui @@ -6,10 +6,16 @@ 0 0 - 800 - 600 + 1000 + 900 + + + 1000 + 600 + + Preferences @@ -209,13 +215,65 @@ QFrame::item { padding: 6px 8px }; - + - - 1 - 1 + + 0 + 0 + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustIgnored + + + true + + + + + 0 + 0 + 726 + 669 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 1 + 1 + + + + + + diff --git a/src/Gui/DlgPreferencesImp.cpp b/src/Gui/DlgPreferencesImp.cpp index baa741cbb2..28fcbf1e97 100644 --- a/src/Gui/DlgPreferencesImp.cpp +++ b/src/Gui/DlgPreferencesImp.cpp @@ -114,6 +114,10 @@ DlgPreferencesImp::DlgPreferencesImp(QWidget* parent, Qt::WindowFlags fl) &QPushButton::clicked, this, &DlgPreferencesImp::showResetOptions); + connect(ui->groupWidgetStack, + &QStackedWidget::currentChanged, + this, + &DlgPreferencesImp::onStackWidgetChange); ui->groupsTreeView->setModel(&_model); @@ -193,6 +197,15 @@ PreferencesPageItem* DlgPreferencesImp::createGroup(const std::string &groupName auto groupPages = new QStackedWidget; groupPages->setProperty(GroupNameProperty, QVariant(groupNameQString)); + connect(groupPages, + &QStackedWidget::currentChanged, + this, + &DlgPreferencesImp::onStackWidgetChange); + + + if (ui->groupWidgetStack->count() > 0) { + groupPages->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + } ui->groupWidgetStack->addWidget(groupPages); auto item = new PreferencesPageItem; @@ -255,6 +268,11 @@ void DlgPreferencesImp::createPageInGroup(PreferencesPageItem *groupItem, const page->loadSettings(); auto pages = qobject_cast(groupItem->getWidget()); + + if (pages->count() > 0) { + page->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + } + pages->addWidget(page); } catch (const Base::Exception& e) { @@ -637,7 +655,6 @@ void DlgPreferencesImp::restartIfRequired() void DlgPreferencesImp::showEvent(QShowEvent* ev) { - this->adjustSize(); QDialog::showEvent(ev); } @@ -668,6 +685,20 @@ void DlgPreferencesImp::onPageSelected(const QModelIndex& index) updatePageDependentLabels(); } +void DlgPreferencesImp::onStackWidgetChange(int index) +{ + auto stack = qobject_cast(sender()); + + for (int i = 0; i < stack->count(); i++) { + auto current = stack->widget(i); + current->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + } + + if (auto selected = stack->widget(index)) { + selected->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + } +} + void DlgPreferencesImp::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { diff --git a/src/Gui/DlgPreferencesImp.h b/src/Gui/DlgPreferencesImp.h index 013aa1ced7..d683c5e900 100644 --- a/src/Gui/DlgPreferencesImp.h +++ b/src/Gui/DlgPreferencesImp.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -150,6 +151,7 @@ protected: protected Q_SLOTS: void onButtonBoxClicked(QAbstractButton*); void onPageSelected(const QModelIndex &index); + void onStackWidgetChange(int index); private: /** @name for internal use only */ From 593f1a23867f8d3b8dbcbcc5ec616524a911c5f1 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sun, 26 Nov 2023 17:16:20 +0100 Subject: [PATCH 2/2] Gui: Expand group after selection This commit ensures that after selecting item the group is automatically expanded. User can force expansion by explcitly clicking expand button, groups expanded that way will stay expanded unless user collapses them. Otherwise non-active group will be collapsed automatically. --- src/Gui/DlgPreferencesImp.cpp | 83 +++++++++++++++++++++++++++++++++-- src/Gui/DlgPreferencesImp.h | 9 +++- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/src/Gui/DlgPreferencesImp.cpp b/src/Gui/DlgPreferencesImp.cpp index 28fcbf1e97..47dfeb717b 100644 --- a/src/Gui/DlgPreferencesImp.cpp +++ b/src/Gui/DlgPreferencesImp.cpp @@ -53,10 +53,12 @@ #include "Tools.h" #include "WidgetFactory.h" +#include using namespace Gui::Dialog; -QWidget* PreferencesPageItem::getWidget() const { +QWidget* PreferencesPageItem::getWidget() const +{ return _widget; } @@ -70,6 +72,16 @@ void PreferencesPageItem::setWidget(QWidget* widget) _widget->setProperty(PropertyName, QVariant::fromValue(this)); } +bool PreferencesPageItem::isExpanded() const +{ + return _expanded; +} + +void PreferencesPageItem::setExpanded(bool expanded) +{ + _expanded = expanded; +} + Q_DECLARE_METATYPE(PreferencesPageItem*); const int DlgPreferencesImp::GroupNameRole = Qt::UserRole + 1; @@ -110,6 +122,14 @@ DlgPreferencesImp::DlgPreferencesImp(QWidget* parent, Qt::WindowFlags fl) &QTreeView::clicked, this, &DlgPreferencesImp::onPageSelected); + connect(ui->groupsTreeView, + &QTreeView::expanded, + this, + &DlgPreferencesImp::onGroupExpanded); + connect(ui->groupsTreeView, + &QTreeView::collapsed, + this, + &DlgPreferencesImp::onGroupCollapsed); connect(ui->buttonReset, &QPushButton::clicked, this, @@ -217,6 +237,7 @@ PreferencesPageItem* DlgPreferencesImp::createGroup(const std::string &groupName item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); item->setWidget(groupPages); + item->setSelectable(false); _model.invisibleRootItem()->appendRow(item); @@ -671,20 +692,50 @@ QModelIndex findRootIndex(const QModelIndex& index) void DlgPreferencesImp::onPageSelected(const QModelIndex& index) { - auto root = findRootIndex(index); + auto* currentItem = static_cast(_model.itemFromIndex(index)); - auto* groupItem = static_cast(_model.itemFromIndex(root)); + if (currentItem->hasChildren()) { + auto pageIndex = currentItem->child(0)->index(); + + ui->groupsTreeView->selectionModel()->select(pageIndex, QItemSelectionModel::ClearAndSelect); + + onPageSelected(pageIndex); + + return; + } + + auto groupIndex = findRootIndex(index); + + auto* groupItem = static_cast(_model.itemFromIndex(groupIndex)); auto* pagesStackWidget = static_cast(groupItem->getWidget()); ui->groupWidgetStack->setCurrentWidget(groupItem->getWidget()); - if (index != root) { + if (index != groupIndex) { pagesStackWidget->setCurrentIndex(index.row()); } updatePageDependentLabels(); } +void DlgPreferencesImp::onGroupExpanded(const QModelIndex& index) +{ + auto root = findRootIndex(index); + + auto* groupItem = static_cast(_model.itemFromIndex(root)); + + groupItem->setExpanded(true); +} + +void DlgPreferencesImp::onGroupCollapsed(const QModelIndex& index) +{ + auto root = findRootIndex(index); + + auto* groupItem = static_cast(_model.itemFromIndex(root)); + + groupItem->setExpanded(false); +} + void DlgPreferencesImp::onStackWidgetChange(int index) { auto stack = qobject_cast(sender()); @@ -697,6 +748,30 @@ void DlgPreferencesImp::onStackWidgetChange(int index) if (auto selected = stack->widget(index)) { selected->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); } + + auto currentItem = getCurrentPage(); + + if (!currentItem) { + return; + } + + ui->groupsTreeView->selectionModel()->select(currentItem->index(), QItemSelectionModel::ClearAndSelect); + + auto root = _model.invisibleRootItem(); + for (int i = 0; i < root->rowCount(); i++) { + auto currentGroup = static_cast(root->child(i)); + + if (!currentGroup->isExpanded()) { + ui->groupsTreeView->collapse(currentGroup->index()); + } + } + + auto parentItem = currentItem; + while ((parentItem = static_cast(parentItem->parent()))) { + bool wasExpanded = parentItem->isExpanded(); + ui->groupsTreeView->expand(parentItem->index()); + parentItem->setExpanded(wasExpanded); + } } void DlgPreferencesImp::changeEvent(QEvent *e) diff --git a/src/Gui/DlgPreferencesImp.h b/src/Gui/DlgPreferencesImp.h index d683c5e900..647cbdee6a 100644 --- a/src/Gui/DlgPreferencesImp.h +++ b/src/Gui/DlgPreferencesImp.h @@ -46,10 +46,14 @@ public: QWidget* getWidget() const; void setWidget(QWidget* widget); + bool isExpanded() const; + void setExpanded(bool expanded); + static constexpr char const* PropertyName = "SettingsPageItem"; private: - QWidget *_widget = nullptr; + QWidget* _widget = nullptr; + bool _expanded = false; }; /** @@ -153,6 +157,9 @@ protected Q_SLOTS: void onPageSelected(const QModelIndex &index); void onStackWidgetChange(int index); + void onGroupExpanded(const QModelIndex &index); + void onGroupCollapsed(const QModelIndex &index); + private: /** @name for internal use only */ //@{