From 870f1266f917dd60cc2d08cf33389eb4d2a78a00 Mon Sep 17 00:00:00 2001 From: matthiasdanner Date: Thu, 17 Jul 2025 09:51:44 +0200 Subject: [PATCH] Sketcher: Fix Constraint Filter Handling (#22072) * Fix SpecialFilter Handling for selected and associated constraints Fix show constraints in 3d view if no constraints in list and filter to only show selected is disabled --------- Co-authored-by: Matthias Danner <28687794+matthiasdanner@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Chris Hennes --- .../Sketcher/Gui/TaskSketcherConstraints.cpp | 208 +++++++----------- .../Sketcher/Gui/TaskSketcherConstraints.h | 3 +- 2 files changed, 86 insertions(+), 125 deletions(-) diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp index e57ad24140..e5c960d562 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp @@ -719,16 +719,20 @@ void ConstraintView::swapNamedOfSelectedItems() ConstraintFilterList::ConstraintFilterList(QWidget* parent) : QListWidget(parent) { - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Sketcher/General"); - int filterState = hGrp->GetInt( - "ConstraintFilterState", - std::numeric_limits::max()); // INT_MAX = 01111111111111111111111111111111 in binary. - normalFilterCount = filterItems.size() - 2;// All filter but selected and associated selectedFilterIndex = normalFilterCount; associatedFilterIndex = normalFilterCount + 1; + // default filters are all except for special filters + int defaultFilter = 0; + for (int i = 0; i < normalFilterCount; i++) { + defaultFilter |= 1 << i; + } + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Sketcher/General"); + int filterState = hGrp->GetInt("SelectedConstraintFilters", defaultFilter); + for (auto const& filterItem : filterItems) { Q_UNUSED(filterItem); auto it = new QListWidgetItem(); @@ -957,11 +961,17 @@ TaskSketcherConstraints::TaskSketcherConstraints(ViewProviderSketch* sketchView) //NOLINTBEGIN connectionConstraintsChanged = sketchView->signalConstraintsChanged.connect( - std::bind(&SketcherGui::TaskSketcherConstraints::slotConstraintsChanged, this)); + std::bind(&SketcherGui::TaskSketcherConstraints::updateList, this)); //NOLINTEND this->groupLayout()->addWidget(proxy); + // Initialize special filters + for (int i = filterList->normalFilterCount; i < filterList->count(); i++) { + if (filterList->item(i)->checkState() == Qt::Checked) { + onFilterListItemChanged(filterList->item(i)); + } + } multiFilterStatus = filterList->getMultiFilter(); ui->listWidgetConstraints->setStyleSheet(QStringLiteral("margin-top: 0px")); @@ -972,11 +982,7 @@ TaskSketcherConstraints::TaskSketcherConstraints(ViewProviderSketch* sketchView) std::bind(&TaskSketcherConstraints::onChangedSketchView, this, sp::_1, sp::_2)); //NOLINTEND - slotConstraintsChanged();// Populate constraints list - // Initialize special filters - for (int i = filterList->normalFilterCount; i < filterList->count(); i++) { - onFilterListItemChanged(filterList->item(i)); - } + updateList(); } TaskSketcherConstraints::~TaskSketcherConstraints() @@ -1022,9 +1028,7 @@ void TaskSketcherConstraints::onSettingsRestrictVisibilityChanged(bool value) hGrp->SetBool("VisualisationTrackingFilter", value); } - // Act - if (value) - change3DViewVisibilityToTrackFilter(); + change3DViewVisibilityToTrackFilter(value); } void TaskSketcherConstraints::onSettingsAutoConstraintsChanged(bool value) @@ -1097,7 +1101,6 @@ void TaskSketcherConstraints::onListWidgetConstraintsEmitShowSelection3DVisibili void TaskSketcherConstraints::changeFilteredVisibility(bool show, ActionTarget target) { assert(sketchView); - const Sketcher::SketchObject* sketch = sketchView->getSketchObject(); auto selecteditems = ui->listWidgetConstraints->selectedItems(); @@ -1133,35 +1136,7 @@ void TaskSketcherConstraints::changeFilteredVisibility(bool show, ActionTarget t } if (!constrIds.empty()) { - - Gui::Command::openCommand( - QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space")); - - std::stringstream stream; - - stream << '['; - - for (size_t i = 0; i < constrIds.size() - 1; i++) { - stream << constrIds[i] << ","; - } - stream << constrIds[constrIds.size() - 1] << ']'; - - std::string constrIdList = stream.str(); - - try { - Gui::cmdAppObjectArgs( - sketch, "setVirtualSpace(%s, %s)", constrIdList, show ? "False" : "True"); - } - catch (const Base::Exception&) { - Gui::Command::abortCommand(); - - Gui::TranslatedUserError( - sketch, tr("Error"), tr("Impossible to update visibility tracking")); - - return; - } - - Gui::Command::commitCommand(); + doSetVirtualSpace(constrIds, !show); } } @@ -1249,22 +1224,8 @@ void TaskSketcherConstraints::onListWidgetConstraintsItemChanged(QListWidgetItem } } - // update constraint virtual space status - Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space")); - try { - Gui::cmdAppObjectArgs( - sketch, - "setVirtualSpace(%d, %s)", - it->ConstraintNbr, - ((item->checkState() == Qt::Checked) != sketchView->getIsShownVirtualSpace()) ? "False" - : "True"); - Gui::Command::commitCommand(); - } - catch (const Base::Exception& e) { - Gui::Command::abortCommand(); - - Gui::NotifyUserError(sketch, QT_TRANSLATE_NOOP("Notifications", "Value Error"), e.what()); - } + std::vector constraintNum = {it->ConstraintNbr}; + doSetVirtualSpace(constraintNum, (item->checkState() == Qt::Checked) == sketchView->getIsShownVirtualSpace()); inEditMode = false; } @@ -1325,16 +1286,14 @@ void TaskSketcherConstraints::updateList() multiFilterStatus = filterList->getMultiFilter();// moved here in case the filter is changed programmatically. + // new constraints have to be added first + slotConstraintsChanged(); + // enforce constraint visibility ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Sketcher"); bool visibilityTracksFilter = hGrp->GetBool("VisualisationTrackingFilter", false); - - if (visibilityTracksFilter) - change3DViewVisibilityToTrackFilter();// it will call slotConstraintChanged via update - // mechanism - else - slotConstraintsChanged(); + change3DViewVisibilityToTrackFilter(visibilityTracksFilter); } void TaskSketcherConstraints::onSelectionChanged(const Gui::SelectionChanges& msg) @@ -1501,7 +1460,7 @@ void TaskSketcherConstraints::onListWidgetConstraintsItemSelectionChanged() this->blockSelection(block); } -void TaskSketcherConstraints::change3DViewVisibilityToTrackFilter() +void TaskSketcherConstraints::change3DViewVisibilityToTrackFilter(bool filterEnabled) { assert(sketchView); // Build up ListView with the constraints @@ -1513,8 +1472,7 @@ void TaskSketcherConstraints::change3DViewVisibilityToTrackFilter() for (std::size_t i = 0; i < vals.size(); ++i) { ConstraintItem* it = static_cast(ui->listWidgetConstraints->item(i)); - - bool visible = !isConstraintFiltered(it); + bool visible = !filterEnabled || !isConstraintFiltered(it); // If the constraint is filteredout and it was previously shown in 3D view if (!visible && it->isInVirtualSpace() == sketchView->getIsShownVirtualSpace()) { @@ -1524,58 +1482,58 @@ void TaskSketcherConstraints::change3DViewVisibilityToTrackFilter() constrIdsToCurrentSpace.push_back(it->ConstraintNbr); } } + if (!constrIdsToVirtualSpace.empty()) { + bool ret = doSetVirtualSpace(constrIdsToVirtualSpace, true); + if (!ret) { + return; + } + } - if (!constrIdsToVirtualSpace.empty() || !constrIdsToCurrentSpace.empty()) { + if (!constrIdsToCurrentSpace.empty()) { + bool ret = doSetVirtualSpace(constrIdsToCurrentSpace, false); - Gui::Command::openCommand( + if (!ret) { + return; + } + } + + if (constrIdsToVirtualSpace.empty() && constrIdsToCurrentSpace.empty()) { + slotConstraintsChanged(); + } +} + +bool TaskSketcherConstraints::doSetVirtualSpace(const std::vector& constrIds, bool isvirtualspace) { + assert(sketchView); + const Sketcher::SketchObject* sketch = sketchView->getSketchObject(); + + std::stringstream stream; + + stream << '['; + + for (size_t i = 0; i < constrIds.size() - 1; i++) { + stream << constrIds[i] << ","; + } + stream << constrIds[constrIds.size() - 1] << ']'; + + std::string constrIdList = stream.str(); + + Gui::Command::openCommand( QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space")); - - auto doSetVirtualSpace = [&sketch](const std::vector& constrIds, bool isvirtualspace) { - std::stringstream stream; - - stream << '['; - - for (size_t i = 0; i < constrIds.size() - 1; i++) { - stream << constrIds[i] << ","; - } - stream << constrIds[constrIds.size() - 1] << ']'; - - std::string constrIdList = stream.str(); - - try { - Gui::cmdAppObjectArgs(sketch, - "setVirtualSpace(%s, %s)", - constrIdList, - isvirtualspace ? "True" : "False"); - } - catch (const Base::Exception&) { - Gui::Command::abortCommand(); - - Gui::TranslatedUserError( - sketch, tr("Error"), tr("Impossible to update visibility tracking:") + QLatin1String(" ")); - - return false; - } - - return true; - }; - - - if (!constrIdsToVirtualSpace.empty()) { - bool ret = doSetVirtualSpace(constrIdsToVirtualSpace, true); - if (!ret) - return; - } - - if (!constrIdsToCurrentSpace.empty()) { - bool ret = doSetVirtualSpace(constrIdsToCurrentSpace, false); - - if (!ret) - return; - } - + try { + Gui::cmdAppObjectArgs(sketch, + "setVirtualSpace(%s, %s)", + constrIdList, + isvirtualspace ? "True" : "False"); Gui::Command::commitCommand(); } + catch (const Base::Exception& e) { + Gui::Command::abortCommand(); + + Gui::TranslatedUserError( + sketch, tr("Error"), tr("Impossible to update visibility tracking:") + QLatin1String(" ") + QLatin1String(e.what())); + return false; + } + return true; } bool TaskSketcherConstraints::isConstraintFiltered(QListWidgetItem* item) @@ -1760,22 +1718,24 @@ void TaskSketcherConstraints::onFilterListItemChanged(QListWidgetItem* item) else if (filterindex == filterList->selectedFilterIndex) {// Selected constraints if (item->checkState() == Qt::Checked) { specialFilterMode = SpecialFilterType::Selected; - filterList->item(filterList->associatedFilterIndex) - ->setCheckState(Qt::Unchecked);// Disable 'associated' updateSelectionFilter(); } - else + else { specialFilterMode = SpecialFilterType::None; + } + filterList->item(filterList->associatedFilterIndex) + ->setCheckState(Qt::Unchecked); // Disable 'associated' } else {// Associated constraints if (item->checkState() == Qt::Checked) { specialFilterMode = SpecialFilterType::Associated; - filterList->item(filterList->selectedFilterIndex) - ->setCheckState(Qt::Unchecked);// Disable 'selected' updateAssociatedConstraintsFilter(); } - else + else { specialFilterMode = SpecialFilterType::None; + } + filterList->item(filterList->selectedFilterIndex) + ->setCheckState(Qt::Unchecked); // Disable 'selected' } filterList->blockSignals(tmpBlock); @@ -1789,7 +1749,7 @@ void TaskSketcherConstraints::onFilterListItemChanged(QListWidgetItem* item) } ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Sketcher/General"); - hGrp->SetInt("ConstraintFilterState", filterState); + hGrp->SetInt("SelectedConstraintFilters", filterState); // if tracking, it will call slotConstraintChanged via update mechanism as Multi Filter affects // not only visibility, but also filtered list content, if not tracking will still update the diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h index d745dbf456..b79559201f 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h @@ -167,7 +167,8 @@ public: private: void slotConstraintsChanged(); bool isConstraintFiltered(QListWidgetItem* item); - void change3DViewVisibilityToTrackFilter(); + void change3DViewVisibilityToTrackFilter(bool filterEnabled); + bool doSetVirtualSpace(const std::vector& constrIds, bool isvirtualspace); void changeFilteredVisibility(bool show, ActionTarget target = ActionTarget::All); void updateSelectionFilter(); void updateAssociatedConstraintsFilter();