diff --git a/src/Mod/TechDraw/App/DrawViewDimension.cpp b/src/Mod/TechDraw/App/DrawViewDimension.cpp index 7db00ca15c..88c25c4a4c 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimension.cpp @@ -100,40 +100,39 @@ const char* DrawViewDimension::MeasureTypeEnums[]= {"True", DrawViewDimension::DrawViewDimension(void) { - ADD_PROPERTY_TYPE(References2D,(0,0),"",(App::Prop_None),"Projected Geometry References"); + ADD_PROPERTY_TYPE(References2D, (0,0), "", (App::Prop_None), "Projected Geometry References"); References2D.setScope(App::LinkScope::Global); - ADD_PROPERTY_TYPE(References3D,(0,0),"",(App::Prop_None),"3D Geometry References"); + ADD_PROPERTY_TYPE(References3D, (0,0), "", (App::Prop_None), "3D Geometry References"); References3D.setScope(App::LinkScope::Global); - ADD_PROPERTY_TYPE(FormatSpec,(getDefaultFormatSpec()) , "Format", App::Prop_Output,"Dimension Format"); - ADD_PROPERTY_TYPE(FormatSpecOverTolerance,(getDefaultFormatSpec(true)) , "Format", App::Prop_Output,"Dimension Overtolerance Format"); - ADD_PROPERTY_TYPE(FormatSpecUnderTolerance,(getDefaultFormatSpec(true)) , "Format", App::Prop_Output,"Dimension Undertolerance Format"); - ADD_PROPERTY_TYPE(Arbitrary,(false) ,"Format", App::Prop_Output,"Value overridden by user"); - ADD_PROPERTY_TYPE(ArbitraryTolerances,(false) ,"Format", App::Prop_Output,"Tolerance values overridden by user"); + ADD_PROPERTY_TYPE(FormatSpec, (getDefaultFormatSpec()), "Format", App::Prop_Output,"Dimension Format"); + ADD_PROPERTY_TYPE(FormatSpecTolerance, (getDefaultFormatSpec(true)), "Format", App::Prop_Output, "Dimension tolerance format"); + ADD_PROPERTY_TYPE(Arbitrary,(false), "Format", App::Prop_Output, "Value overridden by user"); + ADD_PROPERTY_TYPE(ArbitraryTolerances, (false), "Format", App::Prop_Output, "Tolerance values overridden by user"); - Type.setEnums(TypeEnums); //dimension type: length, radius etc - ADD_PROPERTY(Type,((long)0)); + Type.setEnums(TypeEnums); //dimension type: length, radius etc + ADD_PROPERTY(Type, ((long)0)); MeasureType.setEnums(MeasureTypeEnums); ADD_PROPERTY(MeasureType, ((long)1)); //Projected (or True) measurement - ADD_PROPERTY_TYPE(TheoreticalExact,(false),"", App::Prop_Output,"Set for theoretical exact (basic) dimension"); - ADD_PROPERTY_TYPE(OverTolerance ,(0.0),"", App::Prop_Output,"+ Tolerance value"); + ADD_PROPERTY_TYPE(TheoreticalExact,(false), "", App::Prop_Output, "Set for theoretical exact (basic) dimension"); + ADD_PROPERTY_TYPE(EqualTolerance, (true), "", App::Prop_Output, "If over- and undertolerance are equal"); + ADD_PROPERTY_TYPE(OverTolerance, (0.0), "", App::Prop_Output, "Overtolerance value\nIf 'Equal Tolerance' is true this is also the value for 'Under Tolerance'"); OverTolerance.setUnit(Base::Unit::Length); - ADD_PROPERTY_TYPE(UnderTolerance ,(0.0),"", App::Prop_Output,"- Tolerance value"); + ADD_PROPERTY_TYPE(UnderTolerance, (0.0), "", App::Prop_Output, "Undertolerance value\nIf 'Equal Tolerance' it will be replaced by negative value of 'Over Tolerance'"); UnderTolerance.setUnit(Base::Unit::Length); - ADD_PROPERTY_TYPE(Inverted,(false),"", App::Prop_Output,"The dimensional value is displayed inverted"); - - //hide the properties the user can't edit in the property editor -// References2D.setStatus(App::Property::Hidden,true); -// References3D.setStatus(App::Property::Hidden,true); + ADD_PROPERTY_TYPE(Inverted, (false), "", App::Prop_Output, "The dimensional value is displayed inverted"); //hide the DrawView properties that don't apply to Dimensions - ScaleType.setStatus(App::Property::ReadOnly,true); - ScaleType.setStatus(App::Property::Hidden,true); - Scale.setStatus(App::Property::ReadOnly,true); - Scale.setStatus(App::Property::Hidden,true); - Rotation.setStatus(App::Property::ReadOnly,true); - Rotation.setStatus(App::Property::Hidden,true); - Caption.setStatus(App::Property::Hidden,true); + ScaleType.setStatus(App::Property::ReadOnly, true); + ScaleType.setStatus(App::Property::Hidden, true); + Scale.setStatus(App::Property::ReadOnly, true); + Scale.setStatus(App::Property::Hidden, true); + Rotation.setStatus(App::Property::ReadOnly, true); + Rotation.setStatus(App::Property::Hidden, true); + Caption.setStatus(App::Property::Hidden, true); + + // by default EqualTolerance is true, thus make UnderTolerance read-only + UnderTolerance.setStatus(App::Property::ReadOnly, true); measurement = new Measure::Measurement(); //TODO: should have better initial datumLabel position than (0,0) in the DVP?? something closer to the object being measured? @@ -172,7 +171,8 @@ void DrawViewDimension::onChanged(const App::Property* prop) Base::Console().Warning("%s has no 3D References but is Type: True\n", getNameInDocument()); MeasureType.setValue("Projected"); } - } else if (prop == &References3D) { //have to rebuild the Measurement object + } + else if (prop == &References3D) { //have to rebuild the Measurement object // Base::Console().Message("DVD::onChanged - References3D\n"); clear3DMeasurements(); //Measurement object if (!(References3D.getValues()).empty()) { @@ -182,7 +182,8 @@ void DrawViewDimension::onChanged(const App::Property* prop) MeasureType.touch(); //run MeasureType logic for this case } } - } else if (prop == &Type) { //why?? + } + else if (prop == &Type) { //why?? FormatSpec.setValue(getDefaultFormatSpec().c_str()); DrawViewType type = static_cast(Type.getValue()); @@ -194,11 +195,31 @@ void DrawViewDimension::onChanged(const App::Property* prop) OverTolerance.setUnit(Base::Unit::Length); UnderTolerance.setUnit(Base::Unit::Length); } - } else if ( (prop == &FormatSpec) || + } + else if (prop == &EqualTolerance) { + // if EqualTolerance set negated overtolerance for untertolerance + if (EqualTolerance.getValue()) { + UnderTolerance.setValue(-1.0 * OverTolerance.getValue()); + UnderTolerance.setUnit(OverTolerance.getUnit()); + UnderTolerance.setReadOnly(true); + } + else { + UnderTolerance.setReadOnly(false); + } + requestPaint(); + } + else if (prop == &OverTolerance) { + // if EqualTolerance set negated overtolerance for untertolerance + if (EqualTolerance.getValue()) { + UnderTolerance.setValue(-1.0 * OverTolerance.getValue()); + UnderTolerance.setUnit(OverTolerance.getUnit()); + } + requestPaint(); + } + else if ( (prop == &FormatSpec) || (prop == &Arbitrary) || (prop == &MeasureType) || (prop == &TheoreticalExact) || - (prop == &OverTolerance) || (prop == &UnderTolerance) || (prop == &Inverted) ) { requestPaint(); @@ -208,6 +229,15 @@ void DrawViewDimension::onChanged(const App::Property* prop) DrawView::onChanged(prop); } +void DrawViewDimension::Restore(Base::XMLReader& reader) +// Old drawings did not have the equal tolerance options. +// We cannot just introduce it as being set to true because that would e.g. destroy tolerances like +1-2 +// Therefore set it to false for existing documents +{ + EqualTolerance.setValue(false); + DrawView::Restore(reader); +} + void DrawViewDimension::onDocumentRestored() { if (has3DReferences()) { @@ -249,6 +279,7 @@ short DrawViewDimension::mustExecute() const Arbitrary.isTouched() || MeasureType.isTouched() || TheoreticalExact.isTouched() || + EqualTolerance.isTouched() || OverTolerance.isTouched() || UnderTolerance.isTouched() || Inverted.isTouched() ); @@ -309,16 +340,16 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) m_linearPoints = getPointsTwoVerts(); } else if (getRefType() == vertexEdge) { m_linearPoints = getPointsEdgeVert(); - } //else tarfu + } m_hasGeometry = true; - } else if(Type.isValue("Radius")){ + } else if (Type.isValue("Radius")){ int idx = DrawUtil::getIndexFromName(subElements[0]); TechDraw::BaseGeom* base = getViewPart()->getGeomByIndex(idx); TechDraw::Circle* circle; arcPoints pts; pts.center = Base::Vector3d(0.0,0.0,0.0); pts.radius = 0.0; - if( (base && base->geomType == TechDraw::GeomType::CIRCLE) || + if ( (base && base->geomType == TechDraw::GeomType::CIRCLE) || (base && base->geomType == TechDraw::GeomType::ARCOFCIRCLE)) { circle = static_cast (base); pts.center = Base::Vector3d(circle->center.x,circle->center.y,0.0); @@ -398,7 +429,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) } m_arcPoints = pts; m_hasGeometry = true; - } else if(Type.isValue("Diameter")){ + } else if (Type.isValue("Diameter")){ int idx = DrawUtil::getIndexFromName(subElements[0]); TechDraw::BaseGeom* base = getViewPart()->getGeomByIndex(idx); TechDraw::Circle* circle; @@ -775,26 +806,40 @@ std::string DrawViewDimension::formatValue(qreal value, QString qFormatSpec, int return result; } +std::string DrawViewDimension::getFormattedToleranceValue(int partial) +{ + QString FormatSpec = QString::fromUtf8(FormatSpecTolerance.getStrValue().data()); + QString ToleranceString; + + if (ArbitraryTolerances.getValue()) + ToleranceString = FormatSpec; + else + ToleranceString = QString::fromUtf8(formatValue(OverTolerance.getValue(), FormatSpec, partial).c_str()); + + return ToleranceString.toStdString(); +} + std::pair DrawViewDimension::getFormattedToleranceValues(int partial) { - QString underFormatSpec = QString::fromUtf8(FormatSpecUnderTolerance.getStrValue().data()); - QString overFormatSpec = QString::fromUtf8(FormatSpecOverTolerance.getStrValue().data()); + QString FormatSpec = QString::fromUtf8(FormatSpecTolerance.getStrValue().data()); std::pair tolerances; QString underTolerance, overTolerance; if (ArbitraryTolerances.getValue()) { - underTolerance = underFormatSpec; - overTolerance = overFormatSpec; + underTolerance = FormatSpec; + overTolerance = FormatSpec; } else { if (DrawUtil::fpCompare(UnderTolerance.getValue(), 0.0)) { underTolerance = QString::fromUtf8(formatValue(UnderTolerance.getValue(), QString::fromUtf8("%.0f"), partial).c_str()); - } else { - underTolerance = QString::fromUtf8(formatValue(UnderTolerance.getValue(), underFormatSpec, partial).c_str()); + } + else { + underTolerance = QString::fromUtf8(formatValue(UnderTolerance.getValue(), FormatSpec, partial).c_str()); } if (DrawUtil::fpCompare(OverTolerance.getValue(), 0.0)) { overTolerance = QString::fromUtf8(formatValue(OverTolerance.getValue(), QString::fromUtf8("%.0f"), partial).c_str()); - } else { - overTolerance = QString::fromUtf8(formatValue(OverTolerance.getValue(), overFormatSpec, partial).c_str()); + } + else { + overTolerance = QString::fromUtf8(formatValue(OverTolerance.getValue(), FormatSpec, partial).c_str()); } } @@ -804,7 +849,6 @@ std::pair DrawViewDimension::getFormattedToleranceValu return tolerances; } - std::string DrawViewDimension::getFormattedDimensionValue(int partial) { QString qFormatSpec = QString::fromUtf8(FormatSpec.getStrValue().data()); @@ -881,11 +925,11 @@ double DrawViewDimension::getDimValue() Type.isValue("DistanceX") || Type.isValue("DistanceY") ) { result = measurement->length(); - } else if(Type.isValue("Radius")){ + } else if (Type.isValue("Radius")){ result = measurement->radius(); - } else if(Type.isValue("Diameter")){ + } else if (Type.isValue("Diameter")){ result = 2.0 * measurement->radius(); - } else if(Type.isValue("Angle")){ + } else if (Type.isValue("Angle")){ result = measurement->angle(); } else { //tarfu throw Base::ValueError("getDimValue() - Unknown Dimension Type (3)"); @@ -909,15 +953,15 @@ double DrawViewDimension::getDimValue() result = fabs(dimVec.y) / getViewPart()->getScale(); } - } else if(Type.isValue("Radius")){ + } else if (Type.isValue("Radius")){ arcPoints pts = m_arcPoints; result = pts.radius / getViewPart()->getScale(); //Projected BaseGeom is scaled for drawing - } else if(Type.isValue("Diameter")){ + } else if (Type.isValue("Diameter")){ arcPoints pts = m_arcPoints; result = (pts.radius * 2.0) / getViewPart()->getScale(); //Projected BaseGeom is scaled for drawing - } else if(Type.isValue("Angle")){ + } else if (Type.isValue("Angle")){ anglePoints pts = m_anglePoints; Base::Vector3d vertex = pts.vertex; Base::Vector3d leg0 = pts.ends.first - vertex; @@ -925,7 +969,7 @@ double DrawViewDimension::getDimValue() double legAngle = leg0.GetAngle(leg1) * 180.0 / M_PI; result = legAngle; - } else if(Type.isValue("Angle3Pt")){ //same as case "Angle"? + } else if (Type.isValue("Angle3Pt")){ //same as case "Angle"? anglePoints pts = m_anglePoints; Base::Vector3d vertex = pts.vertex; Base::Vector3d leg0 = pts.ends.first - vertex; @@ -1193,12 +1237,12 @@ bool DrawViewDimension::leaderIntersectsArc(Base::Vector3d s, Base::Vector3d poi const std::vector &subElements = References2D.getSubValues(); int idx = DrawUtil::getIndexFromName(subElements[0]); TechDraw::BaseGeom* base = getViewPart()->getGeomByIndex(idx); - if( base && base->geomType == TechDraw::GeomType::ARCOFCIRCLE ) { + if ( base && base->geomType == TechDraw::GeomType::ARCOFCIRCLE ) { TechDraw::AOC* aoc = static_cast (base); if (aoc->intersectsArc(s,pointOnCircle)) { result = true; } - } else if( base && base->geomType == TechDraw::GeomType::BSPLINE ) { + } else if ( base && base->geomType == TechDraw::GeomType::BSPLINE ) { TechDraw::BSpline* spline = static_cast (base); if (spline->isCircle()) { if (spline->intersectsArc(s,pointOnCircle)) { @@ -1258,14 +1302,12 @@ bool DrawViewDimension::has3DReferences(void) const return (References3D.getSize() > 0); } -bool DrawViewDimension::hasTolerance(void) const +bool DrawViewDimension::hasOverUnderTolerance(void) const { - bool result = true; - double overTol = OverTolerance.getValue(); - double underTol = UnderTolerance.getValue(); - if (DrawUtil::fpCompare(overTol,0.0) && - DrawUtil::fpCompare(underTol,0.0) ) { - result = false; + bool result = false; + if (!DrawUtil::fpCompare(OverTolerance.getValue(), 0.0) || + !DrawUtil::fpCompare(UnderTolerance.getValue(), 0.0) ) { + result = true; } return result; } @@ -1287,22 +1329,22 @@ bool DrawViewDimension::useDecimals() const std::string DrawViewDimension::getPrefix() const { std::string result = ""; - if(Type.isValue("Distance")) { + if (Type.isValue("Distance")) { result = ""; - } else if(Type.isValue("DistanceX")){ + } else if (Type.isValue("DistanceX")){ result = ""; - } else if(Type.isValue("DistanceY")){ + } else if (Type.isValue("DistanceY")){ result = ""; - } else if(Type.isValue("DistanceZ")){ + } else if (Type.isValue("DistanceZ")){ result = ""; - } else if(Type.isValue("Radius")){ + } else if (Type.isValue("Radius")){ result = "R"; - } else if(Type.isValue("Diameter")){ + } else if (Type.isValue("Diameter")){ Base::Reference hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Dimensions"); std::string diamSym = hGrp->GetASCII("DiameterSymbol","\xe2\x8c\x80"); result = diamSym; - } else if(Type.isValue("Angle")){ + } else if (Type.isValue("Angle")){ result = ""; } return result; diff --git a/src/Mod/TechDraw/App/DrawViewDimension.h b/src/Mod/TechDraw/App/DrawViewDimension.h index 20cad696d2..16cd078522 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.h +++ b/src/Mod/TechDraw/App/DrawViewDimension.h @@ -102,10 +102,10 @@ public: App::PropertyBool TheoreticalExact; App::PropertyBool Inverted; App::PropertyString FormatSpec; - App::PropertyString FormatSpecUnderTolerance; - App::PropertyString FormatSpecOverTolerance; + App::PropertyString FormatSpecTolerance; App::PropertyBool Arbitrary; App::PropertyBool ArbitraryTolerances; + App::PropertyBool EqualTolerance; App::PropertyQuantity OverTolerance; App::PropertyQuantity UnderTolerance; @@ -122,7 +122,7 @@ public: short mustExecute() const override; virtual bool has2DReferences(void) const; virtual bool has3DReferences(void) const; - bool hasTolerance(void) const; + bool hasOverUnderTolerance(void) const; /** @name methods override Feature */ //@{ @@ -137,6 +137,7 @@ public: //return PyObject as DrawViewDimensionPy virtual PyObject *getPyObject(void) override; + virtual std::string getFormattedToleranceValue(int partial); virtual std::pair getFormattedToleranceValues(int partial = 0); virtual std::string getFormattedDimensionValue(int partial = 0); virtual std::string formatValue(qreal value, QString qFormatSpec, int partial = 0); @@ -168,6 +169,7 @@ public: protected: virtual void handleChangedPropertyType(Base::XMLReader &, const char * , App::Property * ) override; + virtual void Restore(Base::XMLReader& reader) override; virtual void onChanged(const App::Property* prop) override; virtual void onDocumentRestored() override; std::string getPrefix() const; diff --git a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp index aba8dc5686..1f16006982 100644 --- a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp @@ -59,7 +59,6 @@ #include #include #include -//#include #include "Rez.h" #include "ZVALUE.h" @@ -311,19 +310,20 @@ void QGIDatumLabel::setDimString(QString t, qreal maxWidth) m_dimText->setTextWidth(maxWidth); } -void QGIDatumLabel::setTolString() +void QGIDatumLabel::setToleranceString() { prepareGeometryChange(); QGIViewDimension* qgivd = dynamic_cast(parentItem()); if( qgivd == nullptr ) { - return; //tarfu + return; } const auto dim( dynamic_cast(qgivd->getViewObject()) ); if( dim == nullptr ) { return; - } else if (!dim->hasTolerance()) { + // don't show if both are zero or if EqualTolerance is true + } else if (!dim->hasOverUnderTolerance() || dim->EqualTolerance.getValue()) { m_tolTextOver->hide(); - m_tolTextUnder->hide(); // don't show if both zero + m_tolTextUnder->hide(); return; } m_tolTextOver->show(); @@ -611,8 +611,6 @@ void QGIViewDimension::updateDim() return; } -// QString labelText = QString::fromUtf8(dim->getFormattedDimensionValue().c_str()); - //want this split into value and unit QString labelText; QString unitText; if (dim->Arbitrary.getValue()) { @@ -624,6 +622,16 @@ void QGIViewDimension::updateDim() labelText = QString::fromUtf8(dim->getFormattedDimensionValue(1).c_str()); //just the number pref/spec/suf unitText = QString::fromUtf8(dim->getFormattedDimensionValue(2).c_str()); //just the unit } + // if there is an equal over-/undertolerance, add the tolerance to dimension + if (dim->EqualTolerance.getValue() && !DrawUtil::fpCompare(dim->OverTolerance.getValue(), 0.0)) { + std::pair ToleranceText, ToleranceUnit; + QString tolerance = QString::fromStdString(dim->getFormattedToleranceValue(1).c_str()); + // tolerance might start with a plus sign that we don't want, so cut it off + if (tolerance.at(0) == QChar::fromLatin1('+')) + tolerance.remove(0, 1); + // add the tolerance to the dimension using the ± sign + labelText = labelText + QString::fromUtf8(" \xC2\xB1 ") + tolerance; + } } QFont font = datumLabel->getFont(); font.setFamily(QString::fromUtf8(vp->Font.getValue())); @@ -632,7 +640,7 @@ void QGIViewDimension::updateDim() prepareGeometryChange(); datumLabel->setDimString(labelText); - datumLabel->setTolString(); + datumLabel->setToleranceString(); datumLabel->setUnitString(unitText); datumLabel->setPosFromCenter(datumLabel->X(),datumLabel->Y()); diff --git a/src/Mod/TechDraw/Gui/QGIViewDimension.h b/src/Mod/TechDraw/Gui/QGIViewDimension.h index 934f6d62ed..1e6bb3eacc 100644 --- a/src/Mod/TechDraw/Gui/QGIViewDimension.h +++ b/src/Mod/TechDraw/Gui/QGIViewDimension.h @@ -77,7 +77,7 @@ public: void setDimString(QString t); void setDimString(QString t, qreal maxWidth); void setUnitString(QString t); - void setTolString(); + void setToleranceString(); void setPrettySel(void); void setPrettyPre(void); void setPrettyNormal(void);