From 398deb2f5bdc5e8aebadbac977edd8b8d0ed293e Mon Sep 17 00:00:00 2001 From: Paddle Date: Thu, 17 Nov 2022 07:30:58 +0100 Subject: [PATCH] SKETCHER: Constraint widget rework (issue 7518) see https://forum.freecadweb.org/viewtopic.php?f=34&t=71595&start=20 --- src/Mod/Sketcher/Gui/CMakeLists.txt | 6 - src/Mod/Sketcher/Gui/ConstraintFilters.h | 110 +- .../Gui/ConstraintMultiFilterDialog.cpp | 155 --- .../Gui/ConstraintMultiFilterDialog.h | 59 -- .../Gui/ConstraintMultiFilterDialog.ui | 255 ----- .../Sketcher/Gui/ConstraintSettingsDialog.cpp | 136 --- .../Sketcher/Gui/ConstraintSettingsDialog.h | 70 -- .../Sketcher/Gui/ConstraintSettingsDialog.ui | 195 ---- .../Sketcher/Gui/TaskSketcherConstraints.cpp | 938 ++++++++++-------- .../Sketcher/Gui/TaskSketcherConstraints.h | 49 +- .../Sketcher/Gui/TaskSketcherConstraints.ui | 251 +---- 11 files changed, 640 insertions(+), 1584 deletions(-) delete mode 100644 src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.cpp delete mode 100644 src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.h delete mode 100644 src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.ui delete mode 100644 src/Mod/Sketcher/Gui/ConstraintSettingsDialog.cpp delete mode 100644 src/Mod/Sketcher/Gui/ConstraintSettingsDialog.h delete mode 100644 src/Mod/Sketcher/Gui/ConstraintSettingsDialog.ui diff --git a/src/Mod/Sketcher/Gui/CMakeLists.txt b/src/Mod/Sketcher/Gui/CMakeLists.txt index e44c865a65..8b93cebf55 100644 --- a/src/Mod/Sketcher/Gui/CMakeLists.txt +++ b/src/Mod/Sketcher/Gui/CMakeLists.txt @@ -42,8 +42,6 @@ set(SketcherGui_UIC_SRCS SketcherSettingsDisplay.ui SketchRectangularArrayDialog.ui SketcherRegularPolygonDialog.ui - ConstraintMultiFilterDialog.ui - ConstraintSettingsDialog.ui ) SET(SketcherGui_SRCS @@ -145,10 +143,6 @@ SET(SketcherGui_SRCS SketchRectangularArrayDialog.cpp SketcherRegularPolygonDialog.h SketcherRegularPolygonDialog.cpp - ConstraintMultiFilterDialog.h - ConstraintMultiFilterDialog.cpp - ConstraintSettingsDialog.h - ConstraintSettingsDialog.cpp TaskDlgEditSketch.cpp TaskDlgEditSketch.h ViewProviderPython.cpp diff --git a/src/Mod/Sketcher/Gui/ConstraintFilters.h b/src/Mod/Sketcher/Gui/ConstraintFilters.h index dc4c571eb3..c48d12e626 100644 --- a/src/Mod/Sketcher/Gui/ConstraintFilters.h +++ b/src/Mod/Sketcher/Gui/ConstraintFilters.h @@ -39,27 +39,27 @@ namespace ConstraintFilter { enum class FilterValue { All = 0, Geometric = 1, - Datums = 2, - Named = 3, - NonDriving = 4, - Coincident = 5, - PointOnObject = 6, - Vertical = 7, - Horizontal = 8, - Parallel = 9, - Perpendicular = 10, - Tangent = 11, - Equality = 12, - Symmetric = 13, - Block = 14, - HorizontalDistance = 15, - VerticalDistance = 16, - Distance = 17, - Radius = 18, - Weight = 19, - Diameter = 20, - Angle = 21, - SnellsLaw = 22, + Coincident = 2, + PointOnObject = 3, + Vertical = 4, + Horizontal = 5, + Parallel = 6, + Perpendicular = 7, + Tangent = 8, + Equality = 9, + Symmetric = 10, + Block = 11, + Datums = 12, + HorizontalDistance = 13, + VerticalDistance = 14, + Distance = 15, + Radius = 16, + Weight = 17, + Diameter = 18, + Angle = 19, + SnellsLaw = 20, + Named = 21, + NonDriving = 22, InternalAlignment = 23, NumFilterValue // SpecialFilterValue shall start at the same index as this }; @@ -67,9 +67,8 @@ namespace ConstraintFilter { constexpr auto FilterValueLength = static_cast>(FilterValue::NumFilterValue); enum class SpecialFilterValue { - Multiple = FilterValueLength, // = 24 - Selection, // = 25 - AssociatedConstraints, // = 26 + Selection = FilterValueLength, // = 24 + AssociatedConstraints, // = 25 NumSpecialFilterValue }; @@ -84,15 +83,6 @@ namespace ConstraintFilter { return static_cast>(filterValue); } - /// Helper function to test whether a provided integral value corresponds to the provided filter value - template - inline bool isFilterMatch(T filterValue, std::underlying_type_t integralTypeValue) { - - auto underlyingFilterValue = static_cast>(filterValue); - - return (underlyingFilterValue == integralTypeValue); - } - /// Helper function to test whether a FilterValue value is set in a FilterValueBitset inline bool checkFilterBitset(FilterValueBitset set, FilterValue filter) { @@ -111,36 +101,42 @@ namespace ConstraintFilter { /// Array of FilterValue bit sets of size of the number of FilterValues indicating for each FilterValue, which other /// FilterValues are comprised therein. It defines the dependencies between filters. constexpr std::array< FilterValueBitset, FilterValueLength> filterAggregates { - buildBitset(FilterValue::All, FilterValue::Geometric, FilterValue::Datums, FilterValue::Named, FilterValue::NonDriving, FilterValue::Horizontal, + buildBitset(FilterValue::All, FilterValue::Geometric, FilterValue::Horizontal, FilterValue::Vertical, FilterValue::Coincident, FilterValue::PointOnObject, FilterValue::Parallel, FilterValue::Perpendicular, - FilterValue::Tangent, FilterValue::Equality, FilterValue::Symmetric, FilterValue::Block, FilterValue::Distance, + FilterValue::Tangent, FilterValue::Equality, FilterValue::Symmetric, FilterValue::Block, FilterValue::Datums, FilterValue::Distance, FilterValue::HorizontalDistance, FilterValue::VerticalDistance, FilterValue::Radius, FilterValue::Weight, FilterValue::Diameter, - FilterValue::Angle, FilterValue::SnellsLaw, FilterValue::InternalAlignment), // All = All other groups are covered (0) + FilterValue::Angle, FilterValue::SnellsLaw, FilterValue::Named, FilterValue::NonDriving, FilterValue::InternalAlignment), // All = All other groups are covered (0) buildBitset(FilterValue::Geometric, FilterValue::Horizontal, FilterValue::Vertical, FilterValue::Coincident, FilterValue::PointOnObject, FilterValue::Parallel, FilterValue::Perpendicular, FilterValue::Tangent, FilterValue::Equality, FilterValue::Symmetric, FilterValue::Block, FilterValue::InternalAlignment), // Geometric = All others not being datums (1) + + buildBitset(FilterValue::Coincident), // Coincident = Just this (2) + buildBitset(FilterValue::PointOnObject), // PointOnObject = Just this (3) + buildBitset(FilterValue::Vertical), // Vertical = Just this (4) + buildBitset(FilterValue::Horizontal), // Horizontal = Just this (5) + buildBitset(FilterValue::Parallel), // Parallel = Just this (6) + buildBitset(FilterValue::Perpendicular), // Perpendicular = Just this (7) + buildBitset(FilterValue::Tangent), // Tangent = Just this (8) + buildBitset(FilterValue::Equality), // Equality = Just this (9) + buildBitset(FilterValue::Symmetric), // Symmetric = Just this (10) + buildBitset(FilterValue::Block), // Block = Just this (11) + buildBitset(FilterValue::Datums, FilterValue::Distance, FilterValue::HorizontalDistance, FilterValue::VerticalDistance, FilterValue::Radius, - FilterValue::Weight, FilterValue::Diameter, FilterValue::Angle, FilterValue::SnellsLaw), // Datum = all others not being geometric (2) - buildBitset(FilterValue::Named), // Named = Just this (3) - buildBitset(FilterValue::NonDriving), // NonDriving = Just this (4) - buildBitset(FilterValue::Coincident), // Coincident = Just this (5) - buildBitset(FilterValue::PointOnObject), // PointOnObject = Just this (6) - buildBitset(FilterValue::Vertical), // Vertical = Just this (7) - buildBitset(FilterValue::Horizontal), // Horizontal = Just this (8) - buildBitset(FilterValue::Parallel), // Parallel = Just this (9) - buildBitset(FilterValue::Perpendicular), // Perpendicular = Just this (10) - buildBitset(FilterValue::Tangent), // Tangent = Just this (11) - buildBitset(FilterValue::Equality), // Equality = Just this (12) - buildBitset(FilterValue::Symmetric), // Symmetric = Just this (13) - buildBitset(FilterValue::Block), // Block = Just this (14) - buildBitset(FilterValue::HorizontalDistance), // HorizontalDistance = Just this (15) - buildBitset(FilterValue::VerticalDistance), // VerticalDistance = Just this (16) - buildBitset(FilterValue::Distance), // Distance = Just this (17) - buildBitset(FilterValue::Radius), // Radius = Just this (18) - buildBitset(FilterValue::Weight), // Weight = Just this (19) - buildBitset(FilterValue::Diameter), // Diameter = Just this (20) - buildBitset(FilterValue::Angle), // Angle = Just this (21) - buildBitset(FilterValue::SnellsLaw), // SnellsLaw = Just this (22) + FilterValue::Weight, FilterValue::Diameter, FilterValue::Angle, FilterValue::SnellsLaw), // Datum = all others not being geometric (12) + + buildBitset(FilterValue::HorizontalDistance), // HorizontalDistance = Just this (13) + buildBitset(FilterValue::VerticalDistance), // VerticalDistance = Just this (14) + buildBitset(FilterValue::Distance), // Distance = Just this (15) + buildBitset(FilterValue::Radius), // Radius = Just this (16) + buildBitset(FilterValue::Weight), // Weight = Just this (17) + buildBitset(FilterValue::Diameter), // Diameter = Just this (18) + buildBitset(FilterValue::Angle), // Angle = Just this (19) + buildBitset(FilterValue::SnellsLaw), // SnellsLaw = Just this (20) + + buildBitset(FilterValue::Named), // Named = Just this (21) + buildBitset(FilterValue::NonDriving), // NonDriving = Just this (22) + + buildBitset(FilterValue::InternalAlignment) // InternalAlignment = Just this (23) }; diff --git a/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.cpp b/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.cpp deleted file mode 100644 index 8cc4fc0147..0000000000 --- a/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2021 Abdullah Tahiri * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -#endif - -#include -#include -#include -#include - -#include "ui_ConstraintMultiFilterDialog.h" -#include "ConstraintMultiFilterDialog.h" - -using namespace SketcherGui; - -ConstraintMultiFilterDialog::ConstraintMultiFilterDialog() - : QDialog(Gui::getMainWindow()), ui(new Ui_ConstraintMultiFilterDialog) -{ - ui->setupUi(this); - - // make filter items checkable - ui->listMultiFilter->blockSignals(true); - for(int i = 0; i < ui->listMultiFilter->count(); i++) { - QListWidgetItem* item = ui->listMultiFilter->item(i); - - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - - item->setCheckState(Qt::Unchecked); - } - ui->listMultiFilter->blockSignals(false); - - QMetaObject::connectSlotsByName(this); -} - -ConstraintMultiFilterDialog::~ConstraintMultiFilterDialog() -{ -} - -void ConstraintMultiFilterDialog::setMultiFilter(const FilterValueBitset & bitset) -{ - ui->listMultiFilter->blockSignals(true); - for(int i = 0; i < ui->listMultiFilter->count(); i++) { - QListWidgetItem* item = ui->listMultiFilter->item(i); - - if(bitset[i]) - item->setCheckState(Qt::Checked); - else - item->setCheckState(Qt::Unchecked); - } - ui->listMultiFilter->blockSignals(false); -} - -FilterValueBitset ConstraintMultiFilterDialog::getMultiFilter() -{ - FilterValueBitset tmpBitset; - - for(int i = 0; i < ui->listMultiFilter->count(); i++) { - QListWidgetItem* item = ui->listMultiFilter->item(i); - - if(item->checkState() == Qt::Checked) - tmpBitset.set(i); - } - - return tmpBitset; - -} - -void ConstraintMultiFilterDialog::on_listMultiFilter_itemChanged(QListWidgetItem * item) -{ - int filterindex = ui->listMultiFilter->row(item); - - auto itemAggregate = filterAggregates[filterindex]; - - ui->listMultiFilter->blockSignals(true); - - for(int i = 0; i < ui->listMultiFilter->count(); i++) { - // any filter comprised on the filter of the activated item, gets the same check state - if(itemAggregate[i]) - ui->listMultiFilter->item(i)->setCheckState(item->checkState()); - - // if unchecking, in addition uncheck any group comprising the unchecked item - if(item->checkState() == Qt::Unchecked) { - if(filterAggregates[i][filterindex]) - ui->listMultiFilter->item(i)->setCheckState(Qt::Unchecked); - } - } - - // Now that all filters are correctly updated to match dependencies, - // if checking, in addition check any group comprising all items that are checked, and check it if all checked. - if(item->checkState() == Qt::Checked) { - for(int i = 0; i < ui->listMultiFilter->count(); i++) { - if(filterAggregates[i][filterindex]) { // only for groups comprising the changed filter - bool mustBeChecked = true; - - for(int j = 0; j < FilterValueLength; j++) { - if (i == j) - continue; - - if (filterAggregates[i][j]) // if it is in group - mustBeChecked = mustBeChecked && ui->listMultiFilter->item(j)->checkState() == Qt::Checked; - } - - if(mustBeChecked) - ui->listMultiFilter->item(i)->setCheckState(Qt::Checked); - } - } - } - - ui->listMultiFilter->blockSignals(false); -} - -void ConstraintMultiFilterDialog::setCheckStateAll(Qt::CheckState state) -{ - ui->listMultiFilter->blockSignals(true); - for(int i = 0; i < ui->listMultiFilter->count(); i++) { - ui->listMultiFilter->item(i)->setCheckState(state); - } - ui->listMultiFilter->blockSignals(false); -} - -void ConstraintMultiFilterDialog::on_checkAllButton_clicked(bool) -{ - setCheckStateAll(Qt::Checked); -} - -void ConstraintMultiFilterDialog::on_uncheckAllButton_clicked(bool) -{ - setCheckStateAll(Qt::Unchecked); -} - -#include "moc_ConstraintMultiFilterDialog.cpp" diff --git a/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.h b/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.h deleted file mode 100644 index 5b97159634..0000000000 --- a/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2021 Abdullah Tahiri * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#ifndef SKETCHERGUI_ConstraintMultiFilter_H -#define SKETCHERGUI_ConstraintMultiFilter_H - -#include - -#include "ConstraintFilters.h" - -namespace SketcherGui { - -using namespace ConstraintFilter; - -class Ui_ConstraintMultiFilterDialog; -class ConstraintMultiFilterDialog : public QDialog -{ - Q_OBJECT - -public: - ConstraintMultiFilterDialog(); - ~ConstraintMultiFilterDialog() override; - - void setMultiFilter(const FilterValueBitset & bitset); - FilterValueBitset getMultiFilter(); - -public Q_SLOTS: - void on_listMultiFilter_itemChanged(QListWidgetItem * item); - void on_checkAllButton_clicked(bool); - void on_uncheckAllButton_clicked(bool); - -protected: - void setCheckStateAll(Qt::CheckState); -private: - std::unique_ptr ui; -}; - -} - -#endif // SKETCHERGUI_ConstraintMultiFilter_H diff --git a/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.ui b/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.ui deleted file mode 100644 index 994e7498e4..0000000000 --- a/src/Mod/Sketcher/Gui/ConstraintMultiFilterDialog.ui +++ /dev/null @@ -1,255 +0,0 @@ - - - SketcherGui::ConstraintMultiFilterDialog - - - Qt::WindowModal - - - - 0 - 0 - 274 - 600 - - - - - 0 - 0 - - - - Multiple filter selection - - - - - - Check the filters to aggregate: - - - - - - - - 0 - 0 - - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::NoSelection - - - 0 - - - - All - - - - - Geometric - - - - - Datums - - - - - Named - - - - - Reference - - - - - Coincident - - - - - Point on Object - - - - - Vertical - - - - - Horizontal - - - - - Parallel - - - - - Perpendicular - - - - - Tangent - - - - - Equality - - - - - Symmetric - - - - - Block - - - - - Horizontal Distance - - - - - Vertical Distance - - - - - Distance - - - - - Radius - - - - - Weight - - - - - Diameter - - - - - Angle - - - - - Snell's Law - - - - - Internal Alignment - - - - - - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - Shows all the constraints in the list - - - Check All - - - - - - - - 0 - 0 - - - - Hides all the constraints in the list - - - Uncheck All - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - SketcherGui::ConstraintMultiFilterDialog - accept() - - - 20 - 20 - - - 20 - 20 - - - - - buttonBox - rejected() - SketcherGui::ConstraintMultiFilterDialog - reject() - - - 20 - 20 - - - 20 - 20 - - - - - diff --git a/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.cpp b/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.cpp deleted file mode 100644 index cb6e479e84..0000000000 --- a/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2021 Abdullah Tahiri * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -#endif - -#include -#include -#include -#include -#include - -#include "ui_ConstraintSettingsDialog.h" -#include "ConstraintSettingsDialog.h" - -using namespace SketcherGui; - -ConstraintSettingsDialog::ConstraintSettingsDialog() - : QDialog(Gui::getMainWindow()), ui(new Ui_ConstraintSettingsDialog) -{ - ui->setupUi(this); - - { // in case any signal is connected before this - QSignalBlocker block(this); - loadSettings(); - snapshotInitialSettings(); - } - - QObject::connect( - ui->filterInternalAlignment, SIGNAL(stateChanged(int)), - this , SLOT (on_filterInternalAlignment_stateChanged(int)) - ); - QObject::connect( - ui->extendedInformation, SIGNAL(stateChanged(int)), - this , SLOT (on_extendedInformation_stateChanged(int)) - ); - QObject::connect( - ui->visualisationTrackingFilter, SIGNAL(stateChanged(int)), - this , SLOT (on_visualisationTrackingFilter_stateChanged(int)) - ); -} - -void ConstraintSettingsDialog::saveSettings() -{ - ui->extendedInformation->onSave(); - ui->filterInternalAlignment->onSave(); - ui->visualisationTrackingFilter->onSave(); -} - -void ConstraintSettingsDialog::loadSettings() -{ - ui->extendedInformation->onRestore(); - ui->filterInternalAlignment->onRestore(); - ui->visualisationTrackingFilter->onRestore(); -} - -void ConstraintSettingsDialog::snapshotInitialSettings() -{ - auto isChecked = [] (auto prefwidget) {return prefwidget->checkState() == Qt::Checked;}; - - extendedInformation = isChecked(ui->extendedInformation); - filterInternalAlignment = isChecked(ui->filterInternalAlignment); - visualisationTrackingFilter = isChecked(ui->visualisationTrackingFilter); -} - -void ConstraintSettingsDialog::restoreInitialSettings() -{ - auto restoreCheck = [] (auto prefwidget, bool initialvalue) { - if( initialvalue != (prefwidget->checkState() == Qt::Checked)) // if the state really changed - initialvalue ? prefwidget->setCheckState(Qt::Checked) : prefwidget->setCheckState(Qt::Unchecked); - }; - - restoreCheck(ui->extendedInformation, extendedInformation); - restoreCheck(ui->filterInternalAlignment, filterInternalAlignment); - restoreCheck(ui->visualisationTrackingFilter, visualisationTrackingFilter); -} - -void ConstraintSettingsDialog::accept() -{ - saveSettings(); - QDialog::accept(); -} - -void ConstraintSettingsDialog::reject() -{ - restoreInitialSettings(); - saveSettings(); - QDialog::reject(); -} - -void ConstraintSettingsDialog::on_filterInternalAlignment_stateChanged(int state) -{ - ui->filterInternalAlignment->onSave(); - Q_EMIT emit_filterInternalAlignment_stateChanged(state); -} - -void ConstraintSettingsDialog::on_visualisationTrackingFilter_stateChanged(int state) -{ - ui->visualisationTrackingFilter->onSave(); - Q_EMIT emit_visualisationTrackingFilter_stateChanged(state); -} - -void ConstraintSettingsDialog::on_extendedInformation_stateChanged(int state) -{ - ui->extendedInformation->onSave(); - Q_EMIT emit_extendedInformation_stateChanged(state); -} - -ConstraintSettingsDialog::~ConstraintSettingsDialog() -{ -} - -#include "moc_ConstraintSettingsDialog.cpp" diff --git a/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.h b/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.h deleted file mode 100644 index 103f22504c..0000000000 --- a/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2021 Abdullah Tahiri * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#ifndef SKETCHERGUI_ConstraintSettingsDialog_H -#define SKETCHERGUI_ConstraintSettingsDialog_H - -#include - -#include "ConstraintFilters.h" - -namespace SketcherGui { - -using namespace ConstraintFilter; - -class Ui_ConstraintSettingsDialog; -class ConstraintSettingsDialog : public QDialog -{ - Q_OBJECT - -public: - ConstraintSettingsDialog(); - ~ConstraintSettingsDialog() override; - -Q_SIGNALS: - void emit_filterInternalAlignment_stateChanged(int); - void emit_extendedInformation_stateChanged(int); - void emit_visualisationTrackingFilter_stateChanged(int); - -public Q_SLOTS: - void accept() override; - void reject() override; - void on_filterInternalAlignment_stateChanged(int state); - void on_extendedInformation_stateChanged(int state); - void on_visualisationTrackingFilter_stateChanged(int state); - -private: - void saveSettings(); - void loadSettings(); - void snapshotInitialSettings(); - void restoreInitialSettings(); - -private: - std::unique_ptr ui; - bool extendedInformation; - bool filterInternalAlignment; - bool visualisationTrackingFilter; -}; - -} - -#endif // SKETCHERGUI_ConstraintSettingsDialog_H diff --git a/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.ui b/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.ui deleted file mode 100644 index 7117cc920c..0000000000 --- a/src/Mod/Sketcher/Gui/ConstraintSettingsDialog.ui +++ /dev/null @@ -1,195 +0,0 @@ - - - SketcherGui::ConstraintSettingsDialog - - - Qt::WindowModal - - - - 0 - 0 - 275 - 215 - - - - - 0 - 0 - - - - Constraint widget settings - - - - - - - 0 - 0 - - - - List control - - - - - - - 0 - 0 - - - - Extended information will be added to the list - - - Extended information - - - false - - - ExtendedConstraintInformation - - - Mod/Sketcher - - - - - - - - 0 - 0 - - - - Internal alignments will be hidden - - - Hide internal alignment - - - true - - - HideInternalAlignment - - - Mod/Sketcher - - - - - - - - - - - 0 - 0 - - - - 3D view control - - - - - - - 0 - 0 - - - - Constraint visualisation tracks filter selection so that filtered out constraints are hidden - - - Show only filtered constraints - - - false - - - VisualisationTrackingFilter - - - Mod/Sketcher - - - - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - Gui::PrefCheckBox - QCheckBox -
Gui/PrefWidgets.h
-
-
- - - - buttonBox - accepted() - SketcherGui::ConstraintSettingsDialog - accept() - - - 20 - 20 - - - 20 - 20 - - - - - buttonBox - rejected() - SketcherGui::ConstraintSettingsDialog - reject() - - - 20 - 20 - - - 20 - 20 - - - - -
diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp index df2a44c8f8..a53ca991d1 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp @@ -58,12 +58,10 @@ #include #include #include +#include #include "Utils.h" -#include "ConstraintMultiFilterDialog.h" -#include "ConstraintSettingsDialog.h" - using namespace SketcherGui; using namespace Gui::TaskView; @@ -434,6 +432,7 @@ protected: QListWidget * view; }; +/* ConstraintView list widget ------------------------------*/ ConstraintView::ConstraintView(QWidget *parent) : QListWidget(parent) { @@ -634,6 +633,73 @@ void ConstraintView::swapNamedOfSelectedItems() Gui::Command::commitCommand(); } +/* Filter constraints list widget ----------------------*/ +ConstraintFilterList::ConstraintFilterList(QWidget* parent) + : QListWidget(parent) +{ + { + QSignalBlocker block(this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "All"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "Geometric"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Coincident"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Point on Object"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Vertical"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Horizontal"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Parallel"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Perpendicular"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Tangent"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Equality"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Symmetric"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Block"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "Datums"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Horizontal Distance"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Vertical Distance"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Distance"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Radius"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Weight"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Diameter"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Angle"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", " - Snell's Law"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "Named"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "Reference"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "Internal Alignment"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "Selected constraints"), this); + new QListWidgetItem(QApplication::translate("ConstraintFilterList", "Associated constraints"), this); + + normalFilterCount = count() - 2; //All filter but selected and associated + selectedFilterIndex = normalFilterCount; + associatedFilterIndex = normalFilterCount + 1; + + for (int i = 0; i < count(); i++) { + QListWidgetItem* it = item(i); + + it->setFlags(it->flags() | Qt::ItemIsUserCheckable); + if(i < normalFilterCount) + it->setCheckState(Qt::Checked); + else //associated and selected should not be checked by default. + it->setCheckState(Qt::Unchecked); + } + } +} + +ConstraintFilterList::~ConstraintFilterList() +{ +} + +FilterValueBitset ConstraintFilterList::getMultiFilter() +{ + FilterValueBitset tmpBitset; + + for (int i = 0; i < normalFilterCount; i++) { + QListWidgetItem* it = item(i); + + if (it->checkState() == Qt::Checked) + tmpBitset.set(i); + } + + return tmpBitset; +} + // ---------------------------------------------------------------------------- TaskSketcherConstraints::TaskSketcherConstraints(ViewProviderSketch *sketchView) : @@ -648,79 +714,20 @@ TaskSketcherConstraints::TaskSketcherConstraints(ViewProviderSketch *sketchView) ui->listWidgetConstraints->setEditTriggers(QListWidget::EditKeyPressed); //QMetaObject::connectSlotsByName(this); - createVisibilityButtonActions(); + createFilterButtonActions(); + createSettingButtonActions(); - // connecting the needed signals - QObject::connect( - ui->comboBoxFilter, SIGNAL(currentIndexChanged(int)), - this , SLOT (on_comboBoxFilter_currentIndexChanged(int)) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(itemSelectionChanged()), - this , SLOT (on_listWidgetConstraints_itemSelectionChanged()) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(itemActivated(QListWidgetItem *)), - this , SLOT (on_listWidgetConstraints_itemActivated(QListWidgetItem *)) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(itemChanged(QListWidgetItem *)), - this , SLOT (on_listWidgetConstraints_itemChanged(QListWidgetItem *)) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(emitCenterSelectedItems()), - this , SLOT (on_listWidgetConstraints_emitCenterSelectedItems()) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(onUpdateDrivingStatus(QListWidgetItem *, bool)), - this , SLOT (on_listWidgetConstraints_updateDrivingStatus(QListWidgetItem *, bool)) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(onUpdateActiveStatus(QListWidgetItem *, bool)), - this , SLOT (on_listWidgetConstraints_updateActiveStatus(QListWidgetItem *, bool)) - ); - QObject::connect( - ui->showAllButton, SIGNAL(clicked(bool)), - this , SLOT (on_showAllButton_clicked(bool)) - ); - QObject::connect( - ui->hideAllButton, SIGNAL(clicked(bool)), - this , SLOT (on_hideAllButton_clicked(bool)) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(emitHideSelection3DVisibility()), - this , SLOT (on_listWidgetConstraints_emitHideSelection3DVisibility()) - ); - QObject::connect( - ui->listWidgetConstraints, SIGNAL(emitShowSelection3DVisibility()), - this , SLOT (on_listWidgetConstraints_emitShowSelection3DVisibility()) - ); - QObject::connect( - ui->multipleFilterButton, SIGNAL(clicked(bool)), - this , SLOT (on_multipleFilterButton_clicked(bool)) - ); - QObject::connect( - ui->settingsDialogButton, SIGNAL(clicked(bool)), - this , SLOT (on_settingsDialogButton_clicked(bool)) - ); - QObject::connect( - ui->visibilityButton, SIGNAL(clicked(bool)), - this , SLOT (on_visibilityButton_clicked(bool)) - ); - - QObject::connect( - qAsConst(ui->visibilityButton)->actions()[0], SIGNAL(changed()), - this , SLOT (on_visibilityButton_trackingaction_changed()) - ); - - connectionConstraintsChanged = sketchView->signalConstraintsChanged.connect( - boost::bind(&SketcherGui::TaskSketcherConstraints::slotConstraintsChanged, this)); + connectSignals(); this->groupLayout()->addWidget(proxy); multiFilterStatus.set(); // Match 'All' selection, all bits set. slotConstraintsChanged(); + + specialFilterMode = SpecialFilterType::None; + + ui->listWidgetConstraints->setStyleSheet(QString::fromLatin1("margin-top: 0px")); } TaskSketcherConstraints::~TaskSketcherConstraints() @@ -728,22 +735,340 @@ TaskSketcherConstraints::~TaskSketcherConstraints() connectionConstraintsChanged.disconnect(); } - -void TaskSketcherConstraints::createVisibilityButtonActions() +void TaskSketcherConstraints::connectSignals() { - QAction* action = new QAction(QString::fromLatin1("Show only filtered Constraints"),this); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::itemSelectionChanged, + this, &TaskSketcherConstraints::on_listWidgetConstraints_itemSelectionChanged + ); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::itemActivated, + this, &TaskSketcherConstraints::on_listWidgetConstraints_itemActivated + ); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::itemChanged, + this, &TaskSketcherConstraints::on_listWidgetConstraints_itemChanged + ); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::emitCenterSelectedItems, + this, &TaskSketcherConstraints::on_listWidgetConstraints_emitCenterSelectedItems + ); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::onUpdateDrivingStatus, + this, &TaskSketcherConstraints::on_listWidgetConstraints_updateDrivingStatus + ); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::onUpdateActiveStatus, + this, &TaskSketcherConstraints::on_listWidgetConstraints_updateActiveStatus + ); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::emitHideSelection3DVisibility, + this, &TaskSketcherConstraints::on_listWidgetConstraints_emitHideSelection3DVisibility + ); + QObject::connect( + ui->listWidgetConstraints, &ConstraintView::emitShowSelection3DVisibility, + this, &TaskSketcherConstraints::on_listWidgetConstraints_emitShowSelection3DVisibility + ); + QObject::connect( + ui->filterBox, &QCheckBox::stateChanged, + this, &TaskSketcherConstraints::on_filterBox_stateChanged + ); + QObject::connect( + ui->filterButton, &QToolButton::clicked, + ui->filterButton, &QToolButton::showMenu + ); + QObject::connect( + ui->showHideButton, &QToolButton::clicked, + this, &TaskSketcherConstraints::on_showHideButton_clicked + ); + QObject::connect( + ui->settingsButton, &QToolButton::clicked, + ui->settingsButton, &QToolButton::showMenu + ); + QObject::connect( + qAsConst(ui->settingsButton)->actions()[0], &QAction::changed, + this, &TaskSketcherConstraints::on_settings_extendedInformation_changed + ); + QObject::connect( + qAsConst(ui->settingsButton)->actions()[1], &QAction::changed, + this, &TaskSketcherConstraints::on_settings_hideInternalAligment_changed + ); + QObject::connect( + qAsConst(ui->settingsButton)->actions()[2], &QAction::changed, + this, &TaskSketcherConstraints::on_settings_restrictVisibility_changed + ); + QObject::connect( + filterList, &ConstraintFilterList::itemChanged, + this, &TaskSketcherConstraints::on_filterList_itemChanged + ); + + connectionConstraintsChanged = sketchView->signalConstraintsChanged.connect( + boost::bind(&SketcherGui::TaskSketcherConstraints::slotConstraintsChanged, this)); +} + + +/* Settings menu ==================================================*/ +void TaskSketcherConstraints::createSettingButtonActions() +{ + QAction* action = new QAction(QString::fromLatin1("Extended information"),this); + QAction* action2 = new QAction(QString::fromLatin1("Hide internal alignment"),this); + QAction* action3 = new QAction(QString::fromLatin1("Show only filtered Constraints"),this); action->setCheckable(true); + action2->setCheckable(true); + action3->setCheckable(true); ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); - bool visibilityTracksFilter = hGrp->GetBool("VisualisationTrackingFilter",false); - { QSignalBlocker block(this); - action->setChecked(visibilityTracksFilter); + action->setChecked(hGrp->GetBool("ExtendedConstraintInformation", false)); + action2->setChecked(hGrp->GetBool("HideInternalAlignment", false)); + action3->setChecked(hGrp->GetBool("VisualisationTrackingFilter", false)); } - ui->visibilityButton->addAction(action); + qAsConst(ui->settingsButton)->addAction(action); + qAsConst(ui->settingsButton)->addAction(action2); + qAsConst(ui->settingsButton)->addAction(action3); +} + +void TaskSketcherConstraints::on_settings_extendedInformation_changed() +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + hGrp->SetBool("ExtendedConstraintInformation", qAsConst(ui->settingsButton)->actions()[0]->isChecked()); + + slotConstraintsChanged(); +} + +void TaskSketcherConstraints::on_settings_hideInternalAligment_changed() +{ + // synchronise parameter + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + hGrp->SetBool("HideInternalAlignment", qAsConst(ui->settingsButton)->actions()[1]->isChecked()); + + slotConstraintsChanged(); +} + +void TaskSketcherConstraints::on_settings_restrictVisibility_changed() +{ + // synchronise VisualisationTrackingFilter parameter + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + + bool bstate = qAsConst(ui->settingsButton)->actions()[2]->isChecked(); + + if (hGrp->GetBool("VisualisationTrackingFilter", false) != bstate) { + hGrp->SetBool("VisualisationTrackingFilter", bstate); + } + + // Act + if (bstate) + change3DViewVisibilityToTrackFilter(); +} + +/* show filter button ==============================================*/ +void TaskSketcherConstraints::createFilterButtonActions() +{ + QWidgetAction* action = new QWidgetAction(this); + filterList = new ConstraintFilterList(this); + action->setDefaultWidget(filterList); + qAsConst(ui->filterButton)->addAction(action); +} + +void TaskSketcherConstraints::on_filterBox_stateChanged(int val) +{ + ui->filterButton->setEnabled(ui->filterBox->checkState() == Qt::Checked); + updateList(); +} + +/*hide all show all button =====================================================*/ +void TaskSketcherConstraints::on_showHideButton_clicked(bool val) +{ + bool allSelected = true; + for (int i = 0; i < ui->listWidgetConstraints->count(); ++i){ + QListWidgetItem* it = ui->listWidgetConstraints->item(i); + if (it->checkState() == Qt::Unchecked) { + allSelected = false; + break; + } + } + changeFilteredVisibility(!allSelected); +} + +/* Right click functionalities for constraint list view =========================*/ +void TaskSketcherConstraints::on_listWidgetConstraints_emitHideSelection3DVisibility() +{ + changeFilteredVisibility(false, ActionTarget::Selected); +} +void TaskSketcherConstraints::on_listWidgetConstraints_emitShowSelection3DVisibility() +{ + changeFilteredVisibility(true, ActionTarget::Selected); +} + +void TaskSketcherConstraints::changeFilteredVisibility(bool show, ActionTarget target) +{ + assert(sketchView); + const Sketcher::SketchObject* sketch = sketchView->getSketchObject(); + + auto selecteditems = ui->listWidgetConstraints->selectedItems(); + + std::vector constrIds; + + for (int i = 0; i < ui->listWidgetConstraints->count(); ++i) + { + QListWidgetItem* item = ui->listWidgetConstraints->item(i); + + bool processItem = false; + + if (target == ActionTarget::All) { + processItem = !item->isHidden(); + } + else if (target == ActionTarget::Selected) { + if (std::find(selecteditems.begin(), selecteditems.end(), item) != selecteditems.end()) + processItem = true; + } + + if (processItem) { // The item is shown in the filtered list + const ConstraintItem* it = dynamic_cast(item); + + if (!it) + continue; + + // must change state is shown and is to be hidden or hidden and must change state is shown + if ((it->isInVirtualSpace() == sketchView->getIsShownVirtualSpace() && !show) || + (it->isInVirtualSpace() != sketchView->getIsShownVirtualSpace() && show)) { + + constrIds.push_back(it->ConstraintNbr); + } + } + } + + 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& e) { + Gui::Command::abortCommand(); + + QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), + QString::fromLatin1("Impossible to update visibility tracking: ") + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); + + return; + } + + Gui::Command::commitCommand(); + } + +} + +void TaskSketcherConstraints::on_listWidgetConstraints_updateDrivingStatus(QListWidgetItem* item, bool status) +{ + Q_UNUSED(status); + ConstraintItem* citem = dynamic_cast(item); + if (!citem) + return; + + Gui::Application::Instance->commandManager().runCommandByName("Sketcher_ToggleDrivingConstraint"); + slotConstraintsChanged(); +} + +void TaskSketcherConstraints::on_listWidgetConstraints_updateActiveStatus(QListWidgetItem* item, bool status) +{ + Q_UNUSED(status); + ConstraintItem* citem = dynamic_cast(item); + if (!citem) + return; + + Gui::Application::Instance->commandManager().runCommandByName("Sketcher_ToggleActiveConstraint"); + slotConstraintsChanged(); +} + +void TaskSketcherConstraints::on_listWidgetConstraints_itemActivated(QListWidgetItem* item) +{ + ConstraintItem* it = dynamic_cast(item); + if (!it) + return; + + // if its the right constraint + if (it->isDimensional()) { + EditDatumDialog* editDatumDialog = new EditDatumDialog(this->sketchView, it->ConstraintNbr); + editDatumDialog->exec(false); + delete editDatumDialog; + } +} + +void TaskSketcherConstraints::on_listWidgetConstraints_itemChanged(QListWidgetItem* item) +{ + const ConstraintItem* it = dynamic_cast(item); + if (!it || inEditMode) + return; + + inEditMode = true; + + assert(sketchView); + + const Sketcher::SketchObject* sketch = sketchView->getSketchObject(); + const std::vector< Sketcher::Constraint* >& vals = sketch->Constraints.getValues(); + const Sketcher::Constraint* v = vals[it->ConstraintNbr]; + const std::string currConstraintName = v->Name; + + const std::string basename = Base::Tools::toStdString(it->data(Qt::EditRole).toString()); + + std::string newName(Sketcher::PropertyConstraintList::getConstraintName(basename, it->ConstraintNbr)); + + // we only start a rename if we are really sure the name has changed, which is: + // a) that the name generated by the constraints is different from the text in the widget item + // b) that the text in the widget item, basename, is not "" + // otherwise a checkbox change will trigger a rename on the first execution, bloating the constraint icons with the + // default constraint name "constraint1, constraint2" + if (newName != currConstraintName && !basename.empty()) { + std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(newName.c_str()); + + Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Rename sketch constraint")); + try { + Gui::cmdAppObjectArgs(sketch, "renameConstraint(%d, u'%s')", + it->ConstraintNbr, escapedstr.c_str()); + Gui::Command::commitCommand(); + } + catch (const Base::Exception& e) { + Gui::Command::abortCommand(); + + QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); + } + } + + // 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(); + + QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); + } + + inEditMode = false; } void TaskSketcherConstraints::updateSelectionFilter() @@ -794,12 +1119,12 @@ void TaskSketcherConstraints::updateAssociatedConstraintsFilter() } } } - - updateList(); } void TaskSketcherConstraints::updateList() { + multiFilterStatus = filterList->getMultiFilter(); //moved here in case the filter is changed programmatically. + // enforce constraint visibility ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); bool visibilityTracksFilter = hGrp->GetBool("VisualisationTrackingFilter",false); @@ -810,144 +1135,6 @@ void TaskSketcherConstraints::updateList() slotConstraintsChanged(); } -void TaskSketcherConstraints::on_multipleFilterButton_clicked(bool) -{ - ConstraintMultiFilterDialog mf; - - int filterindex = ui->comboBoxFilter->currentIndex(); - - if(!isFilterMatch(ConstraintFilter::SpecialFilterValue::Multiple, filterindex)) { - ui->comboBoxFilter->setCurrentIndex(getFilterIntegral(ConstraintFilter::SpecialFilterValue::Multiple)); // Change filter to multi filter selection - } - - mf.setMultiFilter(multiFilterStatus); - - if (mf.exec() == QDialog::Accepted) { - multiFilterStatus = mf.getMultiFilter(); - - // 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 list to match the multi-filter. - updateList(); - } - else - { - // restore previous filter if Multiple filter dialog is canceled - ui->comboBoxFilter->setCurrentIndex(filterindex); - } -} - -void TaskSketcherConstraints::on_settingsDialogButton_clicked(bool) -{ - ConstraintSettingsDialog cs; - - QObject::connect( - &cs, SIGNAL(emit_filterInternalAlignment_stateChanged(int)), - this , SLOT (on_filterInternalAlignment_stateChanged(int)) - ); - QObject::connect( - &cs, SIGNAL(emit_extendedInformation_stateChanged(int)), - this , SLOT (on_extendedInformation_stateChanged(int)) - ); - QObject::connect( - &cs, SIGNAL(emit_visualisationTrackingFilter_stateChanged(int)), - this , SLOT (on_visualisationTrackingFilter_stateChanged(int)) - ); - - cs.exec(); // The dialog reacted on any change, so the result of running the dialog is already reflected on return. -} - -void TaskSketcherConstraints::changeFilteredVisibility(bool show, ActionTarget target) -{ - assert(sketchView); - const Sketcher::SketchObject * sketch = sketchView->getSketchObject(); - - auto selecteditems = ui->listWidgetConstraints->selectedItems(); - - std::vector constrIds; - - for(int i = 0; i < ui->listWidgetConstraints->count(); ++i) - { - QListWidgetItem* item = ui->listWidgetConstraints->item(i); - - bool processItem = false; - - if(target == ActionTarget::All) { - processItem = !item->isHidden(); - } - else if(target == ActionTarget::Selected) { - if(std::find(selecteditems.begin(), selecteditems.end(), item) != selecteditems.end()) - processItem = true; - } - - if(processItem) { // The item is shown in the filtered list - const ConstraintItem *it = dynamic_cast(item); - - if (!it) - continue; - - // must change state is shown and is to be hidden or hidden and must change state is shown - if((it->isInVirtualSpace() == sketchView->getIsShownVirtualSpace() && !show) || - (it->isInVirtualSpace() != sketchView->getIsShownVirtualSpace() && show)) { - - constrIds.push_back(it->ConstraintNbr); - } - } - } - - 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 & e) { - Gui::Command::abortCommand(); - - QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), - QString::fromLatin1("Impossible to update visibility tracking: ") + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); - - return; - } - - Gui::Command::commitCommand(); - } - -} - -void TaskSketcherConstraints::on_showAllButton_clicked(bool) -{ - changeFilteredVisibility(true); -} - -void TaskSketcherConstraints::on_hideAllButton_clicked(bool) -{ - changeFilteredVisibility(false); -} - -void TaskSketcherConstraints::on_listWidgetConstraints_emitHideSelection3DVisibility() -{ - changeFilteredVisibility(false, ActionTarget::Selected); -} - -void TaskSketcherConstraints::on_listWidgetConstraints_emitShowSelection3DVisibility() -{ - changeFilteredVisibility(true, ActionTarget::Selected); -} - void TaskSketcherConstraints::onSelectionChanged(const Gui::SelectionChanges& msg) { assert(sketchView); @@ -958,14 +1145,14 @@ void TaskSketcherConstraints::onSelectionChanged(const Gui::SelectionChanges& ms ui->listWidgetConstraints->clearSelection(); ui->listWidgetConstraints->blockSignals(false); - if(isFilter(ConstraintFilter::SpecialFilterValue::Selection)) { + if(specialFilterMode == SpecialFilterType::Selected) { updateSelectionFilter(); bool block = this->blockSelection(true); // avoid to be notified by itself updateList(); this->blockSelection(block); } - else if (isFilter(ConstraintFilter::SpecialFilterValue::AssociatedConstraints)) { + else if (specialFilterMode == SpecialFilterType::Associated) { associatedConstraintsFilter.clear(); updateList(); } @@ -997,7 +1184,7 @@ void TaskSketcherConstraints::onSelectionChanged(const Gui::SelectionChanges& ms } } - if(isFilter(ConstraintFilter::SpecialFilterValue::Selection)) { + if(specialFilterMode == SpecialFilterType::Selected) { updateSelectionFilter(); bool block = this->blockSelection(true); // avoid to be notified by itself updateList(); @@ -1005,7 +1192,7 @@ void TaskSketcherConstraints::onSelectionChanged(const Gui::SelectionChanges& ms } } } - else if(isFilter(ConstraintFilter::SpecialFilterValue::AssociatedConstraints)) { // is NOT a constraint + else if(specialFilterMode == SpecialFilterType::Associated) { // is NOT a constraint int geoid = Sketcher::GeoEnum::GeoUndef; Sketcher::PointPos pointpos = Sketcher::PointPos::none; getSelectionGeoId(expr, geoid, pointpos); @@ -1015,6 +1202,7 @@ void TaskSketcherConstraints::onSelectionChanged(const Gui::SelectionChanges& ms // as one removal may imply removing a constraint that should be added by a different element // that is still selected. The necessary checks outweigh a full rebuild of the filter. updateAssociatedConstraintsFilter(); + updateList(); } } } @@ -1055,69 +1243,6 @@ void TaskSketcherConstraints::getSelectionGeoId(QString expr, int & geoid, Sketc } } -void TaskSketcherConstraints::on_comboBoxFilter_currentIndexChanged(int filterindex) -{ - selectionFilter.clear(); // reset the stored selection filter - associatedConstraintsFilter.clear(); - - if(isFilterMatch(ConstraintFilter::SpecialFilterValue::Selection, filterindex)) { - updateSelectionFilter(); - } - else if(isFilterMatch(ConstraintFilter::SpecialFilterValue::AssociatedConstraints, filterindex)) { - updateAssociatedConstraintsFilter(); - } - - updateList(); -} - -void TaskSketcherConstraints::on_filterInternalAlignment_stateChanged(int state) -{ - Q_UNUSED(state); - slotConstraintsChanged(); -} - -void TaskSketcherConstraints::on_visualisationTrackingFilter_stateChanged(int state) -{ - // Synchronise button drop state - { - QSignalBlocker block(this); - - if (qAsConst(ui->visibilityButton)->actions()[0]->isChecked() != (state == Qt::Checked)) - qAsConst(ui->visibilityButton)->actions()[0]->setChecked(state); - } - - if(state == Qt::Checked) - change3DViewVisibilityToTrackFilter(); -} - -void TaskSketcherConstraints::on_visibilityButton_trackingaction_changed() -{ - // synchronise VisualisationTrackingFilter parameter - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); - bool visibilityTracksFilter = hGrp->GetBool("VisualisationTrackingFilter",false); - - bool bstate = qAsConst(ui->visibilityButton)->actions()[0]->isChecked(); - - if(visibilityTracksFilter != bstate) { - hGrp->SetBool("VisualisationTrackingFilter", bstate); - } - - // Act - if(bstate) - change3DViewVisibilityToTrackFilter(); -} - -void TaskSketcherConstraints::on_visibilityButton_clicked(bool) -{ - change3DViewVisibilityToTrackFilter(); -} - -void TaskSketcherConstraints::on_extendedInformation_stateChanged(int state) -{ - Q_UNUSED(state); - slotConstraintsChanged(); -} - void TaskSketcherConstraints::on_listWidgetConstraints_emitCenterSelectedItems() { sketchView->centerSelection(); @@ -1144,101 +1269,6 @@ void TaskSketcherConstraints::on_listWidgetConstraints_itemSelectionChanged() this->blockSelection(block); } -void TaskSketcherConstraints::on_listWidgetConstraints_itemActivated(QListWidgetItem *item) -{ - ConstraintItem *it = dynamic_cast(item); - if (!it) - return; - - // if its the right constraint - if (it->isDimensional()) { - EditDatumDialog *editDatumDialog = new EditDatumDialog(this->sketchView, it->ConstraintNbr); - editDatumDialog->exec(false); - delete editDatumDialog; - } -} - -void TaskSketcherConstraints::on_listWidgetConstraints_updateDrivingStatus(QListWidgetItem *item, bool status) -{ - Q_UNUSED(status); - ConstraintItem *citem = dynamic_cast(item); - if (!citem) - return; - - Gui::Application::Instance->commandManager().runCommandByName("Sketcher_ToggleDrivingConstraint"); - slotConstraintsChanged(); -} - -void TaskSketcherConstraints::on_listWidgetConstraints_updateActiveStatus(QListWidgetItem *item, bool status) -{ - Q_UNUSED(status); - ConstraintItem *citem = dynamic_cast(item); - if (!citem) - return; - - Gui::Application::Instance->commandManager().runCommandByName("Sketcher_ToggleActiveConstraint"); - slotConstraintsChanged(); -} - -void TaskSketcherConstraints::on_listWidgetConstraints_itemChanged(QListWidgetItem *item) -{ - const ConstraintItem *it = dynamic_cast(item); - if (!it || inEditMode) - return; - - inEditMode = true; - - assert(sketchView); - - const Sketcher::SketchObject * sketch = sketchView->getSketchObject(); - const std::vector< Sketcher::Constraint * > &vals = sketch->Constraints.getValues(); - const Sketcher::Constraint* v = vals[it->ConstraintNbr]; - const std::string currConstraintName = v->Name; - - const std::string basename = Base::Tools::toStdString(it->data(Qt::EditRole).toString()); - - std::string newName(Sketcher::PropertyConstraintList::getConstraintName(basename, it->ConstraintNbr)); - - // we only start a rename if we are really sure the name has changed, which is: - // a) that the name generated by the constraints is different from the text in the widget item - // b) that the text in the widget item, basename, is not "" - // otherwise a checkbox change will trigger a rename on the first execution, bloating the constraint icons with the - // default constraint name "constraint1, constraint2" - if (newName != currConstraintName && !basename.empty()) { - std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(newName.c_str()); - - Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Rename sketch constraint")); - try { - Gui::cmdAppObjectArgs(sketch ,"renameConstraint(%d, u'%s')", - it->ConstraintNbr, escapedstr.c_str()); - Gui::Command::commitCommand(); - } - catch (const Base::Exception & e) { - Gui::Command::abortCommand(); - - QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), - QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); - } - } - - // 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(); - - QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), - QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); - } - - inEditMode = false; -} - void TaskSketcherConstraints::change3DViewVisibilityToTrackFilter() { assert(sketchView); @@ -1325,100 +1355,84 @@ bool TaskSketcherConstraints::isConstraintFiltered(QListWidgetItem * item) ConstraintItem * it = static_cast(item); const Sketcher::Constraint * constraint = vals[it->ConstraintNbr]; - int Filter = ui->comboBoxFilter->currentIndex(); - - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); bool hideInternalAlignment = hGrp->GetBool("HideInternalAlignment",false); bool visible = true; - bool showAll = isFilterMatch(FilterValue::All, Filter); - bool showGeometric = isFilterMatch(FilterValue::Geometric, Filter); - bool showDatums = (isFilterMatch(FilterValue::Datums, Filter) && constraint->isDriving); - bool showNamed = (isFilterMatch(FilterValue::Named, Filter) && !(constraint->Name.empty())); - bool showNonDriving = (isFilterMatch(FilterValue::NonDriving, Filter) && !constraint->isDriving); - auto geometricVisible = [showAll, showGeometric, showNamed, Filter, this](FilterValue filtervalue) { - return showAll || showGeometric || showNamed || isFilterMatch(filtervalue, Filter) || - (isFilterMatch(SpecialFilterValue::Multiple, Filter) && checkFilterBitset(multiFilterStatus, filtervalue)); - }; - - auto datumVisible = [showAll, showDatums, showNamed, showNonDriving, Filter, this](FilterValue filtervalue) { - return showAll || showDatums || showNamed || showNonDriving || isFilterMatch(filtervalue, Filter) || - (isFilterMatch(SpecialFilterValue::Multiple, Filter) && checkFilterBitset(multiFilterStatus, filtervalue)); - }; - - switch(constraint->Type) { + if(ui->filterBox->checkState() == Qt::Checked) { + //First select only the filtered one. + switch (constraint->Type) { case Sketcher::Horizontal: - visible = geometricVisible(FilterValue::Horizontal); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Horizontal); break; case Sketcher::Vertical: - visible = geometricVisible(FilterValue::Vertical); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Vertical); break; case Sketcher::Coincident: - visible = geometricVisible(FilterValue::Coincident); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Coincident); break; case Sketcher::PointOnObject: - visible = geometricVisible(FilterValue::PointOnObject); + visible = checkFilterBitset(multiFilterStatus, FilterValue::PointOnObject); break; case Sketcher::Parallel: - visible = geometricVisible(FilterValue::Parallel); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Parallel); break; case Sketcher::Perpendicular: - visible = geometricVisible(FilterValue::Perpendicular); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Perpendicular); break; case Sketcher::Tangent: - visible = geometricVisible(FilterValue::Tangent); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Tangent); break; case Sketcher::Equal: - visible = geometricVisible(FilterValue::Equality); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Equality); break; case Sketcher::Symmetric: - visible = geometricVisible(FilterValue::Symmetric); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Symmetric); break; case Sketcher::Block: - visible = geometricVisible(FilterValue::Block); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Block); break; case Sketcher::Distance: - visible = datumVisible(FilterValue::Distance); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Distance); break; case Sketcher::DistanceX: - visible = datumVisible(FilterValue::HorizontalDistance); + visible = checkFilterBitset(multiFilterStatus, FilterValue::HorizontalDistance); break; case Sketcher::DistanceY: - visible = datumVisible(FilterValue::VerticalDistance); + visible = checkFilterBitset(multiFilterStatus, FilterValue::VerticalDistance); break; case Sketcher::Radius: - visible = datumVisible(FilterValue::Radius); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Radius); break; case Sketcher::Weight: - visible = datumVisible(FilterValue::Weight); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Weight); break; case Sketcher::Diameter: - visible = datumVisible(FilterValue::Diameter); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Diameter); break; case Sketcher::Angle: - visible = datumVisible(FilterValue::Angle); + visible = checkFilterBitset(multiFilterStatus, FilterValue::Angle); break; case Sketcher::SnellsLaw: - visible = datumVisible(FilterValue::SnellsLaw); + visible = checkFilterBitset(multiFilterStatus, FilterValue::SnellsLaw); break; case Sketcher::InternalAlignment: - visible = geometricVisible(FilterValue::InternalAlignment) && - (!hideInternalAlignment || isFilterMatch(FilterValue::InternalAlignment,Filter)); + visible = checkFilterBitset(multiFilterStatus, FilterValue::InternalAlignment) && !hideInternalAlignment; default: break; + } + + //Then we re-filter based on selected/associated if such mode selected. + if (visible && specialFilterMode == SpecialFilterType::Selected) { + visible = (std::find(selectionFilter.begin(), selectionFilter.end(), it->ConstraintNbr) != selectionFilter.end()); + } + else if (visible && specialFilterMode == SpecialFilterType::Associated) { + visible = (std::find(associatedConstraintsFilter.begin(), associatedConstraintsFilter.end(), it->ConstraintNbr) != associatedConstraintsFilter.end()); + } } - // Constraint Type independent, selection filter - visible = visible || (isFilterMatch(SpecialFilterValue::Selection, Filter) && - std::find(selectionFilter.begin(), selectionFilter.end(), it->ConstraintNbr) != selectionFilter.end()); - - // Constraint Type independent, associated Constraints Filter - visible = visible || (isFilterMatch(SpecialFilterValue::AssociatedConstraints, Filter) && - std::find(associatedConstraintsFilter.begin(), associatedConstraintsFilter.end(), it->ConstraintNbr) != associatedConstraintsFilter.end()); - return !visible; } @@ -1483,11 +1497,77 @@ void TaskSketcherConstraints::changeEvent(QEvent *e) } } -template -bool TaskSketcherConstraints::isFilter(T filterValue) { - return isFilterMatch(filterValue, ui->comboBoxFilter->currentIndex()); +/* list for multi filter */ +void TaskSketcherConstraints::on_filterList_itemChanged(QListWidgetItem* item) +{ + int filterindex = filterList->row(item); + + filterList->blockSignals(true); + + if (filterindex < filterList->normalFilterCount) { + + auto itemAggregate = filterAggregates[filterindex]; + + /*First, if this is a group, we need to set the same state to all of its children. + ie any filter comprised on the filter of the activated item, gets the same check state.*/ + for (int i = 0; i < filterList->normalFilterCount; i++) { + if (itemAggregate[i]) + filterList->item(i)->setCheckState(item->checkState()); + } + + /* Now we also need to see if any modified group is all checked or all unchecked and set their status accordingly + If a group is partially checked or unchecked then we apply Qt::PartiallyChecked. + The for-loop index is starting from the end. This way sub-groups are first set, which enables the bigger group to be set correctly after. + Example: If we go from 0 to count, then the loop starts at 'All' group, which check state of 'Geometric' which is not updated yet.*/ + for (int i = filterList->normalFilterCount - 1; i >= 0; i--) { + if (filterAggregates[i][filterindex] && i != filterList->row(item)) { // only for groups comprising the changed filter && not for selected item. + bool mustBeChecked = true; + bool mustBeUnchecked = true; + + for (int j = 0; j < FilterValueLength; j++) { + if (i == j) + continue; + + if (filterAggregates[i][j]) { // if it is in group + mustBeChecked = mustBeChecked && filterList->item(j)->checkState() == Qt::Checked; + mustBeUnchecked = mustBeUnchecked && filterList->item(j)->checkState() == Qt::Unchecked; + } + } + + if (mustBeChecked) + filterList->item(i)->setCheckState(Qt::Checked); + else if (mustBeUnchecked) + filterList->item(i)->setCheckState(Qt::Unchecked); + else + filterList->item(i)->setCheckState(Qt::PartiallyChecked); + } + } + } + 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 + specialFilterMode = SpecialFilterType::None; + } + else { //Associated constraints + if (item->checkState() == Qt::Checked) { + specialFilterMode = SpecialFilterType::Associated; + filterList->item(filterList->selectedFilterIndex)->setCheckState(Qt::Unchecked); //Disable 'selected' + updateAssociatedConstraintsFilter(); + } + else + specialFilterMode = SpecialFilterType::None; + } + + filterList->blockSignals(false); + + // 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 list to match the multi-filter. + updateList(); } - #include "moc_TaskSketcherConstraints.cpp" + diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h index 1947be8a68..3e56c856fb 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.h @@ -39,6 +39,8 @@ class Property; namespace SketcherGui { +using namespace ConstraintFilter; + class ViewProviderSketch; class Ui_TaskSketcherConstraints; @@ -73,6 +75,21 @@ protected Q_SLOTS: void hideConstraints(); }; +class ConstraintFilterList : public QListWidget +{ + Q_OBJECT + +public: + explicit ConstraintFilterList(QWidget* parent = nullptr); + ~ConstraintFilterList() override; + + FilterValueBitset getMultiFilter(); + + int normalFilterCount; //All filters but selected and associated + int selectedFilterIndex; + int associatedFilterIndex; +}; + class TaskSketcherConstraints : public Gui::TaskView::TaskBox, public Gui::SelectionObserver { Q_OBJECT @@ -82,6 +99,12 @@ class TaskSketcherConstraints : public Gui::TaskView::TaskBox, public Gui::Selec Selected }; + enum class SpecialFilterType { + None, + Associated, + Selected + }; + public: explicit TaskSketcherConstraints(ViewProviderSketch *sketchView); ~TaskSketcherConstraints() override; @@ -89,6 +112,8 @@ public: /// Observer message from the Selection void onSelectionChanged(const Gui::SelectionChanges& msg) override; + SpecialFilterType specialFilterMode; + private: void slotConstraintsChanged(); bool isConstraintFiltered(QListWidgetItem * item); @@ -97,32 +122,27 @@ private: void updateSelectionFilter(); void updateAssociatedConstraintsFilter(); void updateList(); - void createVisibilityButtonActions(); - - template - bool isFilter(T filterValue); + void createFilterButtonActions(); + void createSettingButtonActions(); + void connectSignals(); void getSelectionGeoId(QString expr, int & geoid, Sketcher::PointPos & pos); public Q_SLOTS: - void on_comboBoxFilter_currentIndexChanged(int); void on_listWidgetConstraints_itemSelectionChanged(); void on_listWidgetConstraints_itemActivated(QListWidgetItem *item); void on_listWidgetConstraints_itemChanged(QListWidgetItem * item); void on_listWidgetConstraints_updateDrivingStatus(QListWidgetItem *item, bool status); void on_listWidgetConstraints_updateActiveStatus(QListWidgetItem *item, bool status); void on_listWidgetConstraints_emitCenterSelectedItems(); - void on_filterInternalAlignment_stateChanged(int state); - void on_extendedInformation_stateChanged(int state); - void on_visualisationTrackingFilter_stateChanged(int state); - void on_visibilityButton_trackingaction_changed(); - void on_visibilityButton_clicked(bool); - void on_showAllButton_clicked(bool); - void on_hideAllButton_clicked(bool); void on_listWidgetConstraints_emitShowSelection3DVisibility(); void on_listWidgetConstraints_emitHideSelection3DVisibility(); - void on_multipleFilterButton_clicked(bool); - void on_settingsDialogButton_clicked(bool); + void on_filterBox_stateChanged(int val); + void on_showHideButton_clicked(bool); + void on_settings_restrictVisibility_changed(); + void on_settings_extendedInformation_changed(); + void on_settings_hideInternalAligment_changed(); + void on_filterList_itemChanged(QListWidgetItem* item); protected: void changeEvent(QEvent *e) override; @@ -137,6 +157,7 @@ private: ConstraintFilter::FilterValueBitset multiFilterStatus; // Stores the filters to be aggregated to form the multifilter. std::vector selectionFilter; // holds the constraint ids of the selected constraints std::vector associatedConstraintsFilter; // holds the constraint ids of the constraints associated with the selected geometry + ConstraintFilterList* filterList; }; } //namespace SketcherGui diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.ui b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.ui index eb9fb18c50..359032c2de 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.ui +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.ui @@ -6,8 +6,8 @@ 0 0 - 417 - 388 + 299 + 350 @@ -19,7 +19,7 @@ 16777215 - 388 + 350 @@ -27,172 +27,58 @@ - + - + - + 0 0 + + Check to toggle filters + + + padding-right: 0px; margin-right: 0px + - Filter: + + + + false - - + + - + 0 0 - - 0 + + Click to show filters + + + padding-left: 0px; margin-left: 0px + + + false + + + Filters + + + QToolButton::MenuButtonPopup - - - All - - - - - Geometric - - - - - Datums - - - - - Named - - - - - Reference - - - - - Coincident - - - - - Point on Object - - - - - Vertical - - - - - Horizontal - - - - - Parallel - - - - - Perpendicular - - - - - Tangent - - - - - Equality - - - - - Symmetric - - - - - Block - - - - - Horizontal Distance - - - - - Vertical Distance - - - - - Distance - - - - - Radius - - - - - Weight - - - - - Diameter - - - - - Angle - - - - - Snell's Law - - - - - Internal Alignment - - - - - Multiple Filters - - - - - Selection Filter - - - - - Associated Constraint Filter - - - + - + 0 0 @@ -204,17 +90,21 @@ - Click to select multiple filters + Show/hide all listed constraints from 3D view. (same as ticking/unticking all listed constraints in list below) - Select Multiple + + + + + :/icons/Std_ToggleVisibility.svg:/icons/Std_ToggleVisibility.svg - + - + 0 0 @@ -229,64 +119,9 @@ :/icons/dialogs/Sketcher_Settings.svg:/icons/dialogs/Sketcher_Settings.svg - - - - - - - - - - - 0 - 0 - - - - Shows all the constraints in the list - - - Show Listed - - - - - - - - 0 - 0 - - - - Hides all the constraints in the list - - - Hide Listed - - - - - - - - 0 - 0 - - - - Restricts 3D visibility to the listed elements - - - Restrict Visibility - QToolButton::MenuButtonPopup - - Qt::ToolButtonTextOnly -