diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 884ce8a5ca..eb4914bec3 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -612,6 +612,8 @@ Hole::Hole() ADD_PROPERTY_TYPE(HoleCutType, (0L), "Hole", App::Prop_None, "Head cut type"); HoleCutType.setEnums(HoleCutType_None_Enums); + ADD_PROPERTY_TYPE(HoleCutCustomValues, (false), "Hole", App::Prop_None, "Custom cut values"); + ADD_PROPERTY_TYPE(HoleCutDiameter, (0.0), "Hole", App::Prop_None, "Head cut diameter"); ADD_PROPERTY_TYPE(HoleCutDepth, (0.0), "Hole", App::Prop_None, "Head cut deth"); @@ -684,6 +686,8 @@ void Hole::updateHoleCutParams() } if (HoleCutDepth.getValue() == 0.0) HoleCutDepth.setValue(dimen.depth); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(true); } else if (holeCutType == "Countersink") { @@ -702,6 +706,8 @@ void Hole::updateHoleCutParams() if (HoleCutCountersinkAngle.getValue() == 0.0) { HoleCutCountersinkAngle.setValue(counter.angle); } + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(false); } @@ -718,9 +724,31 @@ void Hole::updateHoleCutParams() // valid values for visual feedback HoleCutDiameter.setValue(Diameter.getValue() + 0.1); HoleCutDepth.setValue(0.1); + // we force custom values since there are no normed ones + HoleCutCustomValues.setReadOnly(true); + // important to set only if not already true, to avoid loop call of updateHoleCutParams() + if (!HoleCutCustomValues.getValue()) { + HoleCutCustomValues.setValue(true); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + } } else { - HoleCutDiameter.setValue(dimen.diameter); - HoleCutDepth.setValue(dimen.depth); + // set normed values if not overwritten or if previously there + // were no normed values available and thus HoleCutCustomValues is checked and read-only + if (!HoleCutCustomValues.getValue() + || (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly())) { + HoleCutDiameter.setValue(dimen.diameter); + HoleCutDepth.setValue(dimen.depth); + HoleCutDiameter.setReadOnly(true); + HoleCutDepth.setReadOnly(true); + if (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly()) + HoleCutCustomValues.setValue(false); + } + else { + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + } + HoleCutCustomValues.setReadOnly(false); } } else if (counter.cut_type == CutDimensionSet::Countersink) { const CounterSinkDimension &dimen = counter.get_sink(threadSize); @@ -728,12 +756,37 @@ void Hole::updateHoleCutParams() // valid values for visual feedback HoleCutDiameter.setValue(Diameter.getValue() + 0.1); // there might be an angle of zero (if no norm exists for the size) - if (HoleCutCountersinkAngle.getValue() == 0.0) { + if (HoleCutCountersinkAngle.getValue() == 0.0) { HoleCutCountersinkAngle.setValue(counter.angle); } + // we force custom values since there are no normed ones + HoleCutCustomValues.setReadOnly(true); + // important to set only if not already true, to avoid loop call of updateHoleCutParams() + if (!HoleCutCustomValues.getValue()) { + HoleCutCustomValues.setValue(true); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); + } } else { - HoleCutDiameter.setValue(dimen.diameter); - HoleCutCountersinkAngle.setValue(counter.angle); + // set normed values if not overwritten or if previously there + // were no normed values available and thus HoleCutCustomValues is checked and read-only + if (!HoleCutCustomValues.getValue() + || (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly())) { + HoleCutDiameter.setValue(dimen.diameter); + HoleCutDiameter.setReadOnly(true); + HoleCutDepth.setReadOnly(true); + HoleCutCountersinkAngle.setValue(counter.angle); + HoleCutCountersinkAngle.setReadOnly(true); + if (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly()) + HoleCutCustomValues.setValue(false); + } + else { + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); + } + HoleCutCustomValues.setReadOnly(false); } } } @@ -745,6 +798,8 @@ void Hole::updateHoleCutParams() else if (holeCutType == "Cheesehead (deprecated)") { HoleCutDiameter.setValue(diameterVal * 1.6); HoleCutDepth.setValue(diameterVal * 0.6); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); } else if (holeCutType == "Countersink socket screw (deprecated)") { HoleCutDiameter.setValue(diameterVal * 2.0); @@ -752,10 +807,15 @@ void Hole::updateHoleCutParams() if (HoleCutCountersinkAngle.getValue() == 0.0) { HoleCutCountersinkAngle.setValue(90.0); } + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); } else if (holeCutType == "Cap screw (deprecated)") { HoleCutDiameter.setValue(diameterVal * 1.5); HoleCutDepth.setValue(diameterVal * 1.25); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); } } else { // we have an UTS profile or none @@ -771,6 +831,8 @@ void Hole::updateHoleCutParams() } if (HoleCutDepth.getValue() == 0.0) HoleCutDepth.setValue(diameterVal * 0.9); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); } else if (holeCutType == "Countersink") { if (HoleCutDiameter.getValue() == 0.0 || HoleCutDiameter.getValue() <= diameterVal) { @@ -787,6 +849,9 @@ void Hole::updateHoleCutParams() else HoleCutCountersinkAngle.setValue(90.0); } + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); } } } @@ -1062,24 +1127,37 @@ void Hole::onChanged(const App::Property *prop) } if (holeCutType == "None") { + HoleCutCustomValues.setReadOnly(true); HoleCutDiameter.setReadOnly(true); HoleCutDepth.setReadOnly(true); HoleCutCountersinkAngle.setReadOnly(true); } else if (holeCutType == "Counterbore") { + HoleCutCustomValues.setReadOnly(true); HoleCutDiameter.setReadOnly(false); HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(true); } else if (holeCutType == "Countersink") { + HoleCutCustomValues.setReadOnly(true); HoleCutDiameter.setReadOnly(false); HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(false); } else { // screw definition - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(false); + HoleCutCustomValues.setReadOnly(false); + if (HoleCutCustomValues.getValue()) { + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + // we must not set HoleCutCountersinkAngle here because the info if this can + // be enabled is first available in updateHoleCutParams and thus handled there + updateHoleCutParams(); + } + else { + HoleCutDiameter.setReadOnly(true); + HoleCutDepth.setReadOnly(true); + HoleCutCountersinkAngle.setReadOnly(true); + } } // Signal changes to these @@ -1161,32 +1239,17 @@ void Hole::onChanged(const App::Property *prop) updateHoleCutParams(); } else if (prop == &HoleCutType) { - std::string holeCutType; - if (HoleCutType.isValid()) - holeCutType = HoleCutType.getValueAsString(); - if (holeCutType == "None") { - HoleCutDiameter.setReadOnly(true); - HoleCutDepth.setReadOnly(true); - HoleCutCountersinkAngle.setReadOnly(true); - } - else if (holeCutType == "Counterbore") { - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(true); - } - else if (holeCutType == "Countersink") { - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(false); - } - else { // screw definition - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(false); - } ProfileBased::onChanged(&HoleCutDiameter); ProfileBased::onChanged(&HoleCutDepth); ProfileBased::onChanged(&HoleCutCountersinkAngle); + + // the read-only states are set in updateHoleCutParams() + updateHoleCutParams(); + } + else if (prop == &HoleCutCustomValues) { + // when going back to standardized values, we must recalculate + // also to find out if HoleCutCountersinkAngle can be ReadOnly + // both an also the read-only states is done in updateHoleCutParams() updateHoleCutParams(); } else if (prop == &DepthType) { diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index 9ec22ccd3f..c28ef80465 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -57,6 +57,7 @@ public: App::PropertyLength Diameter; App::PropertyEnumeration ThreadDirection; App::PropertyEnumeration HoleCutType; + App::PropertyBool HoleCutCustomValues; App::PropertyLength HoleCutDiameter; App::PropertyLength HoleCutDepth; App::PropertyAngle HoleCutCountersinkAngle; diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index fd35108360..c1648446f7 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -115,34 +115,16 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare ++cursor; } ui->HoleCutType->setCurrentIndex(pcHole->HoleCutType.getValue()); + ui->HoleCutCustomValues->setChecked(pcHole->HoleCutCustomValues.getValue()); + ui->HoleCutCustomValues->setDisabled(pcHole->HoleCutCustomValues.isReadOnly()); + // HoleCutDiameter must not be smaller or equal than the Diameter + ui->HoleCutDiameter->setMinimum(pcHole->Diameter.getValue() + 0.1); ui->HoleCutDiameter->setValue(pcHole->HoleCutDiameter.getValue()); + ui->HoleCutDiameter->setDisabled(pcHole->HoleCutDiameter.isReadOnly()); ui->HoleCutDepth->setValue(pcHole->HoleCutDepth.getValue()); + ui->HoleCutDepth->setDisabled(pcHole->HoleCutDepth.isReadOnly()); ui->HoleCutCountersinkAngle->setValue(pcHole->HoleCutCountersinkAngle.getValue()); - - std::string holeCutType; - if (pcHole->HoleCutType.isValid()) - holeCutType = pcHole->HoleCutType.getValueAsString(); - - if (holeCutType == "None") { - ui->HoleCutDiameter->setEnabled(false); - ui->HoleCutDepth->setEnabled(false); - ui->HoleCutCountersinkAngle->setEnabled(false); - } - else if (holeCutType == "Counterbore") { - ui->HoleCutDiameter->setEnabled(true); - ui->HoleCutDepth->setEnabled(true); - ui->HoleCutCountersinkAngle->setEnabled(false); - } - else if (holeCutType == "Countersink") { - ui->HoleCutDiameter->setEnabled(true); - ui->HoleCutDepth->setEnabled(true); - ui->HoleCutCountersinkAngle->setEnabled(true); - } - else { // screw definition - ui->HoleCutDiameter->setEnabled(true); - ui->HoleCutDepth->setEnabled(true); - ui->HoleCutCountersinkAngle->setEnabled(true); - } + ui->HoleCutCountersinkAngle->setDisabled(pcHole->HoleCutCountersinkAngle.isReadOnly()); ui->DepthType->setCurrentIndex(pcHole->DepthType.getValue()); ui->Depth->setValue(pcHole->Depth.getValue()); @@ -189,6 +171,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare connect(ui->directionRightHand, SIGNAL(clicked(bool)), this, SLOT(threadDirectionChanged())); connect(ui->directionLeftHand, SIGNAL(clicked(bool)), this, SLOT(threadDirectionChanged())); connect(ui->HoleCutType, SIGNAL(currentIndexChanged(int)), this, SLOT(holeCutTypeChanged(int))); + connect(ui->HoleCutCustomValues, SIGNAL(clicked(bool)), this, SLOT(holeCutCustomValuesChanged())); connect(ui->HoleCutDiameter, SIGNAL(valueChanged(double)), this, SLOT(holeCutDiameterChanged(double))); connect(ui->HoleCutDepth, SIGNAL(valueChanged(double)), this, SLOT(holeCutDepthChanged(double))); connect(ui->HoleCutCountersinkAngle, SIGNAL(valueChanged(double)), this, SLOT(holeCutCountersinkAngleChanged(double))); @@ -282,8 +265,65 @@ void TaskHoleParameters::holeCutTypeChanged(int index) // therefore reset it, it will be reset to sensible values by setting the new HoleCutType pcHole->HoleCutDepth.setValue(0.0); + // when holeCutType was changed, reset HoleCutCustomValues to false because it should + // be a purpose decision to overwrite the normed values + // we will handle the case that there is no normed value later in this routine + ui->HoleCutCustomValues->setChecked(false); + pcHole->HoleCutCustomValues.setValue(false); + pcHole->HoleCutType.setValue(index); + + // recompute to get the info about the HoleCutType properties recomputeFeature(); + + // apply the result to the widgets + ui->HoleCutCustomValues->setDisabled(pcHole->HoleCutCustomValues.isReadOnly()); + ui->HoleCutCustomValues->setChecked(pcHole->HoleCutCustomValues.getValue()); + + // HoleCutCustomValues is only enabled for screw definitions + // we must do this after recomputeFeature() because this gives us the info if + // the type is a countersink and thus if HoleCutCountersinkAngle can be enabled + std::string HoleCutTypeString = pcHole->HoleCutType.getValueAsString(); + if (HoleCutTypeString == "None" || HoleCutTypeString == "Counterbore" + || HoleCutTypeString == "Countersink") { + ui->HoleCutCustomValues->setEnabled(false); + } + else { // screw definition + // we can have the case that we have no normed values + // in this case HoleCutCustomValues is read-only AND true + if (ui->HoleCutCustomValues->isChecked()) { + ui->HoleCutDiameter->setEnabled(true); + ui->HoleCutDepth->setEnabled(true); + if (!pcHole->HoleCutCountersinkAngle.isReadOnly()) + ui->HoleCutCountersinkAngle->setEnabled(true); + } + else { + ui->HoleCutDiameter->setEnabled(false); + ui->HoleCutDepth->setEnabled(false); + ui->HoleCutCountersinkAngle->setEnabled(false); + } + } +} + +void TaskHoleParameters::holeCutCustomValuesChanged() +{ + PartDesign::Hole* pcHole = static_cast(vp->getObject()); + + pcHole->HoleCutCustomValues.setValue(ui->HoleCutCustomValues->isChecked()); + + if (ui->HoleCutCustomValues->isChecked()) { + ui->HoleCutDiameter->setEnabled(true); + ui->HoleCutDepth->setEnabled(true); + if (!pcHole->HoleCutCountersinkAngle.isReadOnly()) + ui->HoleCutCountersinkAngle->setEnabled(true); + } + else { + ui->HoleCutDiameter->setEnabled(false); + ui->HoleCutDepth->setEnabled(false); + ui->HoleCutCountersinkAngle->setEnabled(false); + } + + recomputeFeature(); } void TaskHoleParameters::holeCutDiameterChanged(double value) @@ -482,6 +522,9 @@ void TaskHoleParameters::threadTypeChanged(int index) if (holeCutIndex > -1) ui->HoleCutType->setCurrentIndex(holeCutIndex); + // we must set the read-only state according to the new HoleCutType + holeCutTypeChanged(ui->HoleCutType->currentIndex()); + recomputeFeature(); } @@ -512,6 +555,10 @@ void TaskHoleParameters::threadDiameterChanged(double value) PartDesign::Hole* pcHole = static_cast(vp->getObject()); pcHole->Diameter.setValue(value); + + // HoleCutDiameter must not be smaller or equal than the Diameter + ui->HoleCutDiameter->setMinimum(value + 0.1); + recomputeFeature(); } @@ -824,6 +871,11 @@ long TaskHoleParameters::getHoleCutType() const return ui->HoleCutType->currentIndex(); } +bool TaskHoleParameters::getHoleCutCustomValues() const +{ + return ui->HoleCutCustomValues->isChecked(); +} + Base::Quantity TaskHoleParameters::getHoleCutDiameter() const { return ui->HoleCutDiameter->value(); @@ -910,6 +962,8 @@ void TaskHoleParameters::apply() FCMD_OBJ_CMD(obj,"ThreadDirection = " << getThreadDirection()); if (!pcHole->HoleCutType.isReadOnly()) FCMD_OBJ_CMD(obj,"HoleCutType = " << getHoleCutType()); + if (!pcHole->HoleCutCustomValues.isReadOnly()) + FCMD_OBJ_CMD(obj, "HoleCutCustomValues = " << (getHoleCutCustomValues() ? 1 : 0)); if (!pcHole->DepthType.isReadOnly()) FCMD_OBJ_CMD(obj,"DepthType = " << getDepthType()); if (!pcHole->DrillPoint.isReadOnly()) diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.h b/src/Mod/PartDesign/Gui/TaskHoleParameters.h index 894c4314a6..2ec266cac8 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.h +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.h @@ -69,6 +69,7 @@ public: Base::Quantity getDiameter() const; long getThreadDirection() const; long getHoleCutType() const; + bool getHoleCutCustomValues() const; Base::Quantity getHoleCutDiameter() const; Base::Quantity getHoleCutDepth() const; Base::Quantity getHoleCutCountersinkAngle() const; @@ -94,6 +95,7 @@ private Q_SLOTS: void threadDiameterChanged(double value); void threadDirectionChanged(); void holeCutTypeChanged(int index); + void holeCutCustomValuesChanged(); void holeCutDiameterChanged(double value); void holeCutDepthChanged(double value); void holeCutCountersinkAngleChanged(double value); diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui index 27a6b7ac60..acb1d821e9 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui @@ -6,8 +6,8 @@ 0 0 - 335 - 463 + 342 + 486 @@ -362,6 +362,22 @@ Only available for holes without thread + + + + 0 + 0 + + + + Check to override the values predefined by the 'Type' + + + Custom values + + + + @@ -374,7 +390,7 @@ Only available for holes without thread - + @@ -402,7 +418,7 @@ Only available for holes without thread - + @@ -415,7 +431,7 @@ Only available for holes without thread - + @@ -440,7 +456,7 @@ Only available for holes without thread - + @@ -453,7 +469,7 @@ Only available for holes without thread - + @@ -475,7 +491,7 @@ Only available for holes without thread - + @@ -491,7 +507,7 @@ Only available for holes without thread - + @@ -507,7 +523,7 @@ Only available for holes without thread - + @@ -523,7 +539,7 @@ Only available for holes without thread - + @@ -539,7 +555,7 @@ Only available for holes without thread - + @@ -555,7 +571,7 @@ Only available for holes without thread - + @@ -572,14 +588,14 @@ account for the depth of blind holes - + <b>Misc</b> - + @@ -592,7 +608,7 @@ account for the depth of blind holes - + @@ -614,7 +630,7 @@ over 90: larger hole radius at the bottom - + @@ -630,7 +646,7 @@ over 90: larger hole radius at the bottom - + @@ -656,6 +672,7 @@ over 90: larger hole radius at the bottom DepthType Depth HoleCutType + HoleCutCustomValues HoleCutDiameter HoleCutDepth HoleCutCountersinkAngle