diff --git a/ChangeLog.txt b/ChangeLog.txt index 4dd97a2af..cc164a9cf 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -25,6 +25,8 @@ - [smart-pattern/valentina#163] Show/hide grainline when export. - Improve calculating notches. - Simplify number of versions for DXF AAMA/ASTM. +- New notch type - Check Notch. +- Control a notch width and angle with formulas. # Valentina 0.7.52 September 12, 2022 - Fix crash when default locale is ru. diff --git a/src/app/puzzle/xml/vplayoutfilereader.cpp b/src/app/puzzle/xml/vplayoutfilereader.cpp index d39f5dba8..e84776665 100644 --- a/src/app/puzzle/xml/vplayoutfilereader.cpp +++ b/src/app/puzzle/xml/vplayoutfilereader.cpp @@ -691,6 +691,7 @@ auto VPLayoutFileReader::ReadNotch() -> VLayoutPassmark passmark.isBuiltIn = ReadAttributeBool(attribs, ML::AttrBuiltIn, falseStr); passmark.baseLine = StringToLine(ReadAttributeEmptyString(attribs, ML::AttrBaseLine)); passmark.lines = StringToLines(ReadAttributeEmptyString(attribs, ML::AttrPath)); + passmark.isClockwiseOpening = ReadAttributeBool(attribs, ML::AttrClockwiseOpening, falseStr); QString defaultType = QString::number(static_cast(PassmarkLineType::OneLine)); passmark.type = static_cast(ReadAttributeUInt(attribs, ML::AttrType, defaultType)); diff --git a/src/app/puzzle/xml/vplayoutfilewriter.cpp b/src/app/puzzle/xml/vplayoutfilewriter.cpp index 0771ff8f2..86810cafe 100644 --- a/src/app/puzzle/xml/vplayoutfilewriter.cpp +++ b/src/app/puzzle/xml/vplayoutfilewriter.cpp @@ -334,6 +334,8 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece) SetAttribute(ML::AttrType, static_cast(passmark.type)); SetAttribute(ML::AttrBaseLine, LineToString(passmark.baseLine)); SetAttribute(ML::AttrPath, LinesToString(passmark.lines)); + SetAttributeOrRemoveIf(ML::AttrClockwiseOpening, passmark.isClockwiseOpening, + [](bool clockwise) noexcept { return not clockwise; }); writeEndElement(); } writeEndElement(); diff --git a/src/app/puzzle/xml/vplayoutliterals.cpp b/src/app/puzzle/xml/vplayoutliterals.cpp index 4748d90fd..b581f6ee2 100644 --- a/src/app/puzzle/xml/vplayoutliterals.cpp +++ b/src/app/puzzle/xml/vplayoutliterals.cpp @@ -113,6 +113,7 @@ const QString AttrX = QStringLiteral("x"); // NOLINT(cert-err const QString AttrY = QStringLiteral("y"); // NOLINT(cert-err58-cpp) const QString AttrTurnPoint = QStringLiteral("turnPoint"); // NOLINT(cert-err58-cpp) const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT(cert-err58-cpp) +const QString AttrClockwiseOpening = QStringLiteral("clockwiseOpening"); // NOLINT(cert-err58-cpp) const QString oneWayUpStr = QStringLiteral("oneWayUp"); // NOLINT(cert-err58-cpp) const QString oneWayDownStr = QStringLiteral("oneWayDown"); // NOLINT(cert-err58-cpp) diff --git a/src/app/puzzle/xml/vplayoutliterals.h b/src/app/puzzle/xml/vplayoutliterals.h index 750f81ccd..ba2c51bd7 100644 --- a/src/app/puzzle/xml/vplayoutliterals.h +++ b/src/app/puzzle/xml/vplayoutliterals.h @@ -118,6 +118,7 @@ extern const QString AttrX; extern const QString AttrY; extern const QString AttrTurnPoint; extern const QString AttrCurvePoint; +extern const QString AttrClockwiseOpening; extern const QString oneWayUpStr; extern const QString oneWayDownStr; diff --git a/src/app/valentina/dialogs/dialogpatternproperties.cpp b/src/app/valentina/dialogs/dialogpatternproperties.cpp index 1f786c81a..70353375e 100644 --- a/src/app/valentina/dialogs/dialogpatternproperties.cpp +++ b/src/app/valentina/dialogs/dialogpatternproperties.cpp @@ -138,20 +138,22 @@ DialogPatternProperties::DialogPatternProperties(VPattern *doc, VContainer *pat ui->checkBoxPatternReadOnly->setDisabled(true); } - //----------------------- Passmark length m_variables = pattern->DataMeasurements().keys() + pattern->DataIncrements().keys(); - m_completer = new QCompleter(m_variables, this); - m_completer->setCompletionMode(QCompleter::PopupCompletion); - m_completer->setModelSorting(QCompleter::UnsortedModel); - m_completer->setFilterMode(Qt::MatchContains); - m_completer->setCaseSensitivity(Qt::CaseSensitive); - connect(m_completer, QOverload::of(&QCompleter::activated), this, [this]() - { - ValidatePassmarkLength(); - DescEdited(); - }); - ui->lineEditPassmarkLength->setCompleter(m_completer); + //----------------------- Passmark length + m_completerLength = new QCompleter(m_variables, this); + m_completerLength->setCompletionMode(QCompleter::PopupCompletion); + m_completerLength->setModelSorting(QCompleter::UnsortedModel); + m_completerLength->setFilterMode(Qt::MatchContains); + m_completerLength->setCaseSensitivity(Qt::CaseSensitive); + connect(m_completerLength, QOverload::of(&QCompleter::activated), this, + [this]() + { + ValidatePassmarkLength(); + DescEdited(); + }); + + ui->lineEditPassmarkLength->setCompleter(m_completerLength); connect(ui->lineEditPassmarkLength, &QLineEdit::textEdited, this, [this]() { ValidatePassmarkLength(); @@ -163,6 +165,32 @@ DialogPatternProperties::DialogPatternProperties(VPattern *doc, VContainer *pat ui->lineEditPassmarkLength->setText(m_oldPassmarkLength); ValidatePassmarkLength(); + //----------------------- Passmark width + m_completerWidth = new QCompleter(m_variables, this); + m_completerWidth->setCompletionMode(QCompleter::PopupCompletion); + m_completerWidth->setModelSorting(QCompleter::UnsortedModel); + m_completerWidth->setFilterMode(Qt::MatchContains); + m_completerWidth->setCaseSensitivity(Qt::CaseSensitive); + connect(m_completerWidth, QOverload::of(&QCompleter::activated), this, + [this]() + { + ValidatePassmarkWidth(); + DescEdited(); + }); + + ui->lineEditPassmarkWidth->setCompleter(m_completerWidth); + connect(ui->lineEditPassmarkWidth, &QLineEdit::textEdited, this, + [this]() + { + ValidatePassmarkWidth(); + DescEdited(); + }); + + ui->lineEditPassmarkWidth->installEventFilter(this); + m_oldPassmarkWidth = doc->GetPassmarkWidthVariable(); + ui->lineEditPassmarkWidth->setText(m_oldPassmarkWidth); + ValidatePassmarkWidth(); + //Initialization change value. Set to default value after initialization m_defaultChanged = false; m_securityChanged = false; @@ -189,7 +217,7 @@ auto DialogPatternProperties::eventFilter(QObject *object, QEvent *event) -> boo auto *keyEvent = static_cast(event); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast) if ((keyEvent->key() == Qt::Key_Space) && ((keyEvent->modifiers() & Qt::ControlModifier) != 0U)) { - m_completer->complete(); + m_completerLength->complete(); return true; } } @@ -197,6 +225,21 @@ auto DialogPatternProperties::eventFilter(QObject *object, QEvent *event) -> boo return false;// clazy:exclude=base-class-event } + if (ui->lineEditPassmarkWidth == qobject_cast(object)) + { + if (event->type() == QEvent::KeyPress) + { + auto *keyEvent = static_cast(event); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast) + if ((keyEvent->key() == Qt::Key_Space) && ((keyEvent->modifiers() & Qt::ControlModifier) != 0U)) + { + m_completerWidth->complete(); + return true; + } + } + + return false; // clazy:exclude=base-class-event + } + return QDialog::eventFilter(object, event); } @@ -240,12 +283,25 @@ void DialogPatternProperties::SaveDescription() m_doc->SetDescription(ui->plainTextEditDescription->document()->toPlainText()); m_doc->SetLabelPrefix(qvariant_cast(ui->comboBoxLabelLanguage->currentData())); m_doc->SetPassmarkLengthVariable(ui->lineEditPassmarkLength->text()); + m_doc->SetPassmarkWidthVariable(ui->lineEditPassmarkWidth->text()); m_doc->SetDefaultPieceLabelPath(ui->lineEditPieceLabelPath->text()); - if (m_oldPassmarkLength != ui->lineEditPassmarkLength->text()) + const bool lengthChanged = m_oldPassmarkLength != ui->lineEditPassmarkLength->text(); + const bool widthChanged = m_oldPassmarkWidth != ui->lineEditPassmarkWidth->text(); + + if (lengthChanged || widthChanged) { emit UpddatePieces(); - m_oldPassmarkLength = ui->lineEditPassmarkLength->text(); + + if (lengthChanged) + { + m_oldPassmarkLength = ui->lineEditPassmarkLength->text(); + } + + if (widthChanged) + { + m_oldPassmarkWidth = ui->lineEditPassmarkWidth->text(); + } } m_descriptionChanged = false; @@ -285,6 +341,26 @@ void DialogPatternProperties::ValidatePassmarkLength() const ui->lineEditPassmarkLength->setPalette(palette); } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPatternProperties::ValidatePassmarkWidth() const +{ + const QString text = ui->lineEditPassmarkWidth->text(); + QPalette palette = ui->lineEditPassmarkWidth->palette(); + const QPalette::ColorRole foregroundRole = ui->lineEditPassmarkWidth->foregroundRole(); + + QRegularExpression rx(NameRegExp()); + if (not text.isEmpty()) + { + palette.setColor(foregroundRole, rx.match(text).hasMatch() && m_variables.contains(text) ? Qt::black : Qt::red); + } + else + { + palette.setColor(foregroundRole, Qt::black); + } + + ui->lineEditPassmarkWidth->setPalette(palette); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPatternProperties::InitImage() { diff --git a/src/app/valentina/dialogs/dialogpatternproperties.h b/src/app/valentina/dialogs/dialogpatternproperties.h index 0d4c5ce4e..a3e18b2f9 100644 --- a/src/app/valentina/dialogs/dialogpatternproperties.h +++ b/src/app/valentina/dialogs/dialogpatternproperties.h @@ -79,9 +79,11 @@ private: QAction *m_changeImageAction{nullptr}; QAction *m_saveImageAction{nullptr}; QAction *m_showImageAction{nullptr}; - QCompleter *m_completer{nullptr}; + QCompleter *m_completerLength{nullptr}; + QCompleter *m_completerWidth{nullptr}; QStringList m_variables{}; QString m_oldPassmarkLength{}; + QString m_oldPassmarkWidth{}; QPointer m_tmpImage{}; void SaveDescription(); @@ -90,6 +92,7 @@ private: void InitImage(); void ValidatePassmarkLength() const; + void ValidatePassmarkWidth() const; }; #endif // DIALOGPATTERNPROPERTIES_H diff --git a/src/app/valentina/dialogs/dialogpatternproperties.ui b/src/app/valentina/dialogs/dialogpatternproperties.ui index c360ecf3a..916d03a7b 100644 --- a/src/app/valentina/dialogs/dialogpatternproperties.ui +++ b/src/app/valentina/dialogs/dialogpatternproperties.ui @@ -122,6 +122,20 @@ + + + + Passmark width: + + + + + + + true + + + diff --git a/src/libs/ifc/schema/layout/v0.1.5.xsd b/src/libs/ifc/schema/layout/v0.1.5.xsd index 6c512804b..0e06c3f6f 100644 --- a/src/libs/ifc/schema/layout/v0.1.5.xsd +++ b/src/libs/ifc/schema/layout/v0.1.5.xsd @@ -115,6 +115,7 @@ + @@ -309,6 +310,7 @@ + @@ -474,22 +476,24 @@ - - + - + - + - + - + - + - + + + + diff --git a/src/libs/ifc/schema/pattern/v0.9.2.xsd b/src/libs/ifc/schema/pattern/v0.9.2.xsd index b20abf52a..d2156de63 100644 --- a/src/libs/ifc/schema/pattern/v0.9.2.xsd +++ b/src/libs/ifc/schema/pattern/v0.9.2.xsd @@ -409,13 +409,18 @@ + - + + + + + @@ -473,9 +478,14 @@ + + + + + @@ -673,6 +683,7 @@ + @@ -681,6 +692,10 @@ + + + + @@ -1023,6 +1038,7 @@ + diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index b87e514ad..064eaee90 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -127,6 +127,7 @@ const QString VAbstractPattern::AttrNodePassmark = QStringLiteral("passmark const QString VAbstractPattern::AttrNodePassmarkLine = QStringLiteral("passmarkLine"); const QString VAbstractPattern::AttrNodePassmarkAngle = QStringLiteral("passmarkAngle"); const QString VAbstractPattern::AttrNodeShowSecondPassmark = QStringLiteral("showSecondPassmark"); +const QString VAbstractPattern::AttrNodePassmarkOpening = QStringLiteral("passmarkClockwiseOpening"); const QString VAbstractPattern::AttrNodeTurnPoint = QStringLiteral("turnPoint"); const QString VAbstractPattern::AttrSABefore = QStringLiteral("before"); const QString VAbstractPattern::AttrSAAfter = QStringLiteral("after"); @@ -139,6 +140,10 @@ const QString VAbstractPattern::AttrNumber = QStringLiteral("number") const QString VAbstractPattern::AttrCheckUniqueness = QStringLiteral("checkUniqueness"); const QString VAbstractPattern::AttrManualPassmarkLength = QStringLiteral("manualPassmarkLength"); const QString VAbstractPattern::AttrPassmarkLength = QStringLiteral("passmarkLength"); +const QString VAbstractPattern::AttrManualPassmarkWidth = QStringLiteral("manualPassmarkWidth"); +const QString VAbstractPattern::AttrPassmarkWidth = QStringLiteral("passmarkWidth"); +const QString VAbstractPattern::AttrManualPassmarkAngle = QStringLiteral("manualPassmarkAngle"); +const QString VAbstractPattern::AttrPassmarkAngle = QStringLiteral("passmarkAngleFormula"); const QString VAbstractPattern::AttrOpacity = QStringLiteral("opacity"); const QString VAbstractPattern::AttrTags = QStringLiteral("tags"); const QString VAbstractPattern::AttrTransform = QStringLiteral("transform"); @@ -786,27 +791,36 @@ auto VAbstractPattern::ParseSANode(const QDomElement &domElement) -> VPieceNode const bool reverse = VDomDocument::GetParametrUInt(domElement, VAbstractPattern::AttrNodeReverse, QChar('0')); const bool excluded = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrNodeExcluded, falseStr); const bool uniqeness = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrCheckUniqueness, trueStr); - const QString saBefore = VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrSABefore, - currentSeamAllowance); - const QString saAfter = VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrSAAfter, - currentSeamAllowance); - const PieceNodeAngle angle = static_cast(VDomDocument::GetParametrUInt(domElement, AttrAngle, - QChar('0'))); + const QString saBefore = + VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrSABefore, currentSeamAllowance); + const QString saAfter = + VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrSAAfter, currentSeamAllowance); + const PieceNodeAngle angle = + static_cast(VDomDocument::GetParametrUInt(domElement, AttrAngle, QChar('0'))); const bool passmark = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrNodePassmark, falseStr); - const PassmarkLineType passmarkLine = StringToPassmarkLineType(VDomDocument::GetParametrString(domElement, - VAbstractPattern::AttrNodePassmarkLine, - strOne)); - const PassmarkAngleType passmarkAngle = StringToPassmarkAngleType(VDomDocument::GetParametrString(domElement, - VAbstractPattern::AttrNodePassmarkAngle, - strStraightforward)); + const PassmarkLineType passmarkLine = StringToPassmarkLineType( + VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrNodePassmarkLine, strOne)); + const PassmarkAngleType passmarkAngleType = StringToPassmarkAngleType( + VDomDocument::GetParametrString(domElement, VAbstractPattern::AttrNodePassmarkAngle, strStraightforward)); + + const bool showSecond = + VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrNodeShowSecondPassmark, trueStr); + const bool passmarkOpening = + VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrNodePassmarkOpening, falseStr); - const bool showSecond = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrNodeShowSecondPassmark, - trueStr); const bool manualPassmarkLength = - VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrManualPassmarkLength, falseStr); + VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrManualPassmarkLength, falseStr); const QString passmarkLength = - VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrPassmarkLength); + VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrPassmarkLength); + + const bool manualPassmarkWidth = + VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrManualPassmarkWidth, falseStr); + const QString passmarkWidth = VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrPassmarkWidth); + + const bool manualPassmarkAngle = + VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrManualPassmarkAngle, falseStr); + const QString passmarkAngle = VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrPassmarkAngle); const bool turnPoint = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrNodeTurnPoint, trueStr); @@ -850,11 +864,16 @@ auto VAbstractPattern::ParseSANode(const QDomElement &domElement) -> VPieceNode node.SetExcluded(excluded); node.SetCheckUniqueness(uniqeness); node.SetShowSecondPassmark(showSecond); + node.SetPassmarkClockwiseOpening(passmarkOpening); node.SetPassmark(passmark); node.SetPassmarkLineType(passmarkLine); - node.SetPassmarkAngleType(passmarkAngle); + node.SetPassmarkAngleType(passmarkAngleType); node.SetManualPassmarkLength(manualPassmarkLength); node.SetFormulaPassmarkLength(passmarkLength); + node.SetManualPassmarkWidth(manualPassmarkWidth); + node.SetFormulaPassmarkWidth(passmarkWidth); + node.SetManualPassmarkAngle(manualPassmarkAngle); + node.SetFormulaPassmarkAngle(passmarkAngle); node.SetTurnPoint(turnPoint); return node; @@ -1319,6 +1338,31 @@ void VAbstractPattern::SetPassmarkLengthVariable(const QString &name) } } +//--------------------------------------------------------------------------------------------------------------------- +auto VAbstractPattern::GetPassmarkWidthVariable() const -> QString +{ + const QDomElement pattern = documentElement(); + + if (pattern.isNull()) + { + return {}; + } + + return GetParametrEmptyString(pattern, AttrPassmarkWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetPassmarkWidthVariable(const QString &name) +{ + QDomElement pattern = documentElement(); + + if (not pattern.isNull()) + { + SetAttribute(pattern, AttrPassmarkWidth, name); + modified = true; + } +} + //--------------------------------------------------------------------------------------------------------------------- auto VAbstractPattern::GetImage() const -> VPatternImage { diff --git a/src/libs/ifc/xml/vabstractpattern.h b/src/libs/ifc/xml/vabstractpattern.h index e5fc78187..eea5a29ad 100644 --- a/src/libs/ifc/xml/vabstractpattern.h +++ b/src/libs/ifc/xml/vabstractpattern.h @@ -106,9 +106,9 @@ public: auto ListExpressions() const -> QVector; auto ListIncrementExpressions() const -> QVector; - virtual void CreateEmptyFile()=0; + virtual void CreateEmptyFile() = 0; - void ChangeActivPP(const QString& name, const Document &parse = Document::FullParse); + void ChangeActivPP(const QString &name, const Document &parse = Document::FullParse); auto GetNameActivPP() const -> QString; auto CheckExistNamePP(const QString &name) const -> bool; auto CountPP() const -> int; @@ -119,95 +119,98 @@ public: auto GetActivNodeElement(const QString &name, QDomElement &element) const -> bool; auto getCursor() const -> quint32; - void setCursor(const quint32 &value); + void setCursor(const quint32 &value); - virtual void setXMLContent(const QString &fileName) override; + virtual void setXMLContent(const QString &fileName) override; - virtual void IncrementReferens(quint32 id) const=0; - virtual void DecrementReferens(quint32 id) const=0; + virtual void IncrementReferens(quint32 id) const = 0; + virtual void DecrementReferens(quint32 id) const = 0; virtual auto GenerateLabel(const LabelType &type, const QString &reservedName = QString()) const -> QString = 0; virtual auto GenerateSuffix() const -> QString = 0; - virtual void UpdateToolData(const quint32 &id, VContainer *data)=0; + virtual void UpdateToolData(const quint32 &id, VContainer *data) = 0; virtual void Clear(); static auto getTool(quint32 id) -> VDataTool *; - static void AddTool(quint32 id, VDataTool *tool); - static void RemoveTool(quint32 id); + static void AddTool(quint32 id, VDataTool *tool); + static void RemoveTool(quint32 id); static auto ParsePieceNodes(const QDomElement &domElement) -> VPiecePath; static auto ParsePieceCSARecords(const QDomElement &domElement) -> QVector; static auto ParsePieceInternalPaths(const QDomElement &domElement) -> QVector; static auto ParsePiecePointRecords(const QDomElement &domElement) -> QVector; - void AddToolOnRemove(VDataTool *tool); + void AddToolOnRemove(VDataTool *tool); auto getHistory() -> QVector *; auto getLocalHistory() const -> QVector; auto MPath() const -> QString; - void SetMPath(const QString &path); + void SetMPath(const QString &path); auto SiblingNodeId(const quint32 &nodeId) const -> quint32; auto getPatternPieces() const -> QStringList; auto GetDescription() const -> QString; - void SetDescription(const QString &text); + void SetDescription(const QString &text); auto GetNotes() const -> QString; - void SetNotes(const QString &text); + void SetNotes(const QString &text); auto GetPatternName() const -> QString; - void SetPatternName(const QString& qsName); + void SetPatternName(const QString &qsName); auto GetCompanyName() const -> QString; - void SetCompanyName(const QString& qsName); + void SetCompanyName(const QString &qsName); auto GetPatternNumber() const -> QString; - void SetPatternNumber(const QString &qsNum); + void SetPatternNumber(const QString &qsNum); auto GetCustomerName() const -> QString; - void SetCustomerName(const QString& qsName); + void SetCustomerName(const QString &qsName); auto GetCustomerBirthDate() const -> QDate; - void SetCustomerBirthDate(const QDate& date); + void SetCustomerBirthDate(const QDate &date); auto GetCustomerEmail() const -> QString; - void SetCustomerEmail(const QString& email); + void SetCustomerEmail(const QString &email); auto GetLabelDateFormat() const -> QString; - void SetLabelDateFormat(const QString &format); + void SetLabelDateFormat(const QString &format); auto GetLabelTimeFormat() const -> QString; - void SetLabelTimeFormat(const QString &format); + void SetLabelTimeFormat(const QString &format); - void SetPatternLabelTemplate(const QVector &lines); + void SetPatternLabelTemplate(const QVector &lines); auto GetPatternLabelTemplate() const -> QVector; auto SetWatermarkPath(const QString &path) -> bool; auto GetWatermarkPath() const -> QString; - void SetPatternMaterials(const QMap &materials); + void SetPatternMaterials(const QMap &materials); auto GetPatternMaterials() const -> QMap; auto GetFinalMeasurements() const -> QVector; - void SetFinalMeasurements(const QVector &measurements); + void SetFinalMeasurements(const QVector &measurements); auto GetDefaultPieceLabelPath() const -> QString; - void SetDefaultPieceLabelPath(const QString &path); + void SetDefaultPieceLabelPath(const QString &path); void SetPatternWasChanged(bool changed); auto GetPatternWasChanged() const -> bool; auto GetPassmarkLengthVariable() const -> QString; - void SetPassmarkLengthVariable(const QString &name); + void SetPassmarkLengthVariable(const QString &name); + + auto GetPassmarkWidthVariable() const -> QString; + void SetPassmarkWidthVariable(const QString &name); auto GetImage() const -> VPatternImage; auto SetImage(const VPatternImage &image) -> bool; - void DeleteImage(); + void DeleteImage(); auto GetBackgroundImages() const -> QVector; void SaveBackgroundImages(const QVector &images); @@ -216,24 +219,24 @@ public: void DeleteBackgroundImage(const QUuid &id); auto GetVersion() const -> QString; - void SetVersion(); + void SetVersion(); auto IsModified() const -> bool; - void SetModified(bool modified); + void SetModified(bool modified); auto GetDraw(const QString &name) const -> QDomElement; - void ParseGroups(const QDomElement &domElement); + void ParseGroups(const QDomElement &domElement); auto CreateGroups(const QString &patternPieceName = QString()) -> QDomElement; auto CreateGroup(quint32 id, const QString &name, const QStringList &tags, const QMap &groupData, vidtype tool = null_id) -> QDomElement; auto GroupLinkedToTool(vidtype toolId) const -> vidtype; auto GetGroupName(quint32 id) -> QString; - void SetGroupName(quint32 id, const QString &name); + void SetGroupName(quint32 id, const QString &name); auto GetGroupTags(vidtype id) -> QStringList; - void SetGroupTags(quint32 id, const QStringList &tags); + void SetGroupTags(quint32 id, const QStringList &tags); auto GetDimensionAValue() -> double; void SetDimensionAValue(double value); @@ -327,6 +330,7 @@ public: static const QString AttrNodePassmarkLine; static const QString AttrNodePassmarkAngle; static const QString AttrNodeShowSecondPassmark; + static const QString AttrNodePassmarkOpening; static const QString AttrNodeTurnPoint; static const QString AttrSABefore; static const QString AttrSAAfter; @@ -339,6 +343,10 @@ public: static const QString AttrCheckUniqueness; static const QString AttrManualPassmarkLength; static const QString AttrPassmarkLength; + static const QString AttrManualPassmarkWidth; + static const QString AttrPassmarkWidth; + static const QString AttrManualPassmarkAngle; + static const QString AttrPassmarkAngle; static const QString AttrOpacity; static const QString AttrTags; static const QString AttrTransform; diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp index db0a33812..70fe56984 100644 --- a/src/libs/vdxf/vdxfengine.cpp +++ b/src/libs/vdxf/vdxfengine.cpp @@ -89,7 +89,7 @@ // Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer26, (UTF8STRING("26"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer80, (UTF8STRING("80"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer81, (UTF8STRING("81"))) // NOLINT - // Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer82, (UTF8STRING("82"))) // NOLINT + Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer82, (UTF8STRING("82"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer83, (UTF8STRING("83"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer84, (UTF8STRING("84"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer85, (UTF8STRING("85"))) // NOLINT @@ -1175,10 +1175,10 @@ void VDxfEngine::ExportASTMNotch(const QSharedPointer &detailBloc // Slit notch notch->layer = *layer4; break; - case PassmarkLineType::VMark: - case PassmarkLineType::VMark2: + case PassmarkLineType::ExternalVMark: + case PassmarkLineType::InternalVMark: { // V-Notch - QLineF boundaryLine(ConstFirst(passmark.lines).p2(), ConstLast(passmark.lines).p2()); + QLineF boundaryLine(ConstFirst(passmark.lines).p1(), ConstLast(passmark.lines).p2()); notch->thickness = FromPixel(boundaryLine.length(), m_varInsunits); // width notch->layer = *layer4; break; @@ -1207,6 +1207,22 @@ void VDxfEngine::ExportASTMNotch(const QSharedPointer &detailBloc notch->layer = *layer83; break; } + case PassmarkLineType::CheckMark: + { // Check Notch + const QLineF &line1 = ConstFirst(passmark.lines); + const QLineF &line2 = ConstLast(passmark.lines); + + qreal width = QLineF(line1.p1(), line2.p2()).length(); + + if (not passmark.isClockwiseOpening) + { // a counter clockwise opening + width *= -1; + } + + notch->thickness = FromPixel(width, m_varInsunits); // width + notch->layer = *layer82; + break; + } case PassmarkLineType::LAST_ONE_DO_NOT_USE: Q_UNREACHABLE(); break; diff --git a/src/libs/vgeometry/vgeometrydef.cpp b/src/libs/vgeometry/vgeometrydef.cpp index ce943abb3..289dd8de9 100644 --- a/src/libs/vgeometry/vgeometrydef.cpp +++ b/src/libs/vgeometry/vgeometrydef.cpp @@ -36,7 +36,7 @@ #include const quint32 VLayoutPassmark::streamHeader = 0x943E2759; // CRC-32Q string "VLayoutPassmark" -const quint16 VLayoutPassmark::classVersion = 1; +const quint16 VLayoutPassmark::classVersion = 2; // Friend functions //--------------------------------------------------------------------------------------------------------------------- @@ -44,14 +44,7 @@ auto operator<<(QDataStream &dataStream, const VLayoutPassmark &data) -> QDataSt { dataStream << VLayoutPassmark::streamHeader << VLayoutPassmark::classVersion; - // Added in classVersion = 1 - dataStream << data.lines; - dataStream << data.type; - dataStream << data.baseLine; - dataStream << data.isBuiltIn; - - // Added in classVersion = 2 - + dataStream << data.lines << data.type << data.baseLine << data.isBuiltIn << data.isClockwiseOpening; return dataStream; } @@ -81,15 +74,12 @@ auto operator>>(QDataStream &dataStream, VLayoutPassmark &data) -> QDataStream & throw VException(message); } - dataStream >> data.lines; - dataStream >> data.type; - dataStream >> data.baseLine; - dataStream >> data.isBuiltIn; + dataStream >> data.lines >> data.type >> data.baseLine >> data.isBuiltIn; -// if (actualClassVersion >= 2) -// { - -// } + if (actualClassVersion >= 2) + { + dataStream >> data.isClockwiseOpening; + } return dataStream; } diff --git a/src/libs/vgeometry/vgeometrydef.h b/src/libs/vgeometry/vgeometrydef.h index afd4dc05e..319240f87 100644 --- a/src/libs/vgeometry/vgeometrydef.h +++ b/src/libs/vgeometry/vgeometrydef.h @@ -66,10 +66,11 @@ enum class PlaceLabelType : quint8 struct VLayoutPassmark { - QVector lines{}; + QVector lines{}; PassmarkLineType type{PassmarkLineType::OneLine}; - QLineF baseLine{}; - bool isBuiltIn{false}; + QLineF baseLine{}; + bool isBuiltIn{false}; + bool isClockwiseOpening{false}; friend auto operator<<(QDataStream& dataStream, const VLayoutPassmark& data) -> QDataStream&; friend auto operator>>(QDataStream& dataStream, VLayoutPassmark& data) -> QDataStream&; diff --git a/src/libs/vlayout/vabstractpiece.cpp b/src/libs/vlayout/vabstractpiece.cpp index 58efa9fcf..6da0c6a7e 100644 --- a/src/libs/vlayout/vabstractpiece.cpp +++ b/src/libs/vlayout/vabstractpiece.cpp @@ -1556,6 +1556,28 @@ auto VSAPoint::toJson() const -> QJsonObject pointObject[QLatin1String("angle")] = static_cast(m_angle); } + if (m_manualPassmarkLength) + { + pointObject[QLatin1String("manualPassmarkLength")] = m_manualPassmarkLength; + pointObject[QLatin1String("passmarkLength")] = m_passmarkLength; + } + + if (m_manualPassmarkWidth) + { + pointObject[QLatin1String("manualPassmarkWidth")] = m_manualPassmarkWidth; + pointObject[QLatin1String("passmarkWidth")] = m_passmarkWidth; + } + else + { + pointObject[QLatin1String("passmarkClockwiseOpening")] = m_passmarkClockwiseOpening; + } + + if (m_manualPassmarkAngle) + { + pointObject[QLatin1String("manualPassmarkAngle")] = m_manualPassmarkAngle; + pointObject[QLatin1String("passmarkAngle")] = m_passmarkAngle; + } + return pointObject; } diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index fa6c430f7..4fd3f0deb 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -293,6 +293,7 @@ auto PrepareSAPassmark(const VPiece &piece, const VContainer *pattern, const VPa layoutPassmark.lines = lines; layoutPassmark.type = pData.passmarkLineType; layoutPassmark.isBuiltIn = false; + layoutPassmark.isClockwiseOpening = pData.passmarkSAPoint.IsPassmarkClockwiseOpening(); ok = true; return layoutPassmark; @@ -354,6 +355,7 @@ auto PreapreBuiltInSAPassmark(const VPiece &piece, const VContainer *pattern, co layoutPassmark.baseLine = ConstFirst (baseLines); layoutPassmark.type = pData.passmarkLineType; layoutPassmark.isBuiltIn = true; + layoutPassmark.isClockwiseOpening = pData.passmarkSAPoint.IsPassmarkClockwiseOpening(); ok = true; return layoutPassmark; diff --git a/src/libs/vlayout/vsapoint.h b/src/libs/vlayout/vsapoint.h index bb7b96946..52dde4eb6 100644 --- a/src/libs/vlayout/vsapoint.h +++ b/src/libs/vlayout/vsapoint.h @@ -66,7 +66,12 @@ public: Q_DECL_CONSTEXPR auto GetAngleType() const -> PieceNodeAngle; Q_DECL_CONSTEXPR auto IsManualPasskmarkLength() const -> bool; + Q_DECL_CONSTEXPR auto IsManualPasskmarkWidth() const -> bool; + Q_DECL_CONSTEXPR auto IsManualPasskmarkAngle() const -> bool; + Q_DECL_CONSTEXPR auto GetPasskmarkLength() const -> qreal; + Q_DECL_CONSTEXPR auto GetPasskmarkWidth() const -> qreal; + Q_DECL_CONSTEXPR auto GetPasskmarkAngle() const -> qreal; Q_DECL_RELAXED_CONSTEXPR auto GetSABefore(qreal width) const -> qreal; Q_DECL_RELAXED_CONSTEXPR auto GetSAAfter(qreal width) const -> qreal; @@ -77,11 +82,19 @@ public: Q_DECL_RELAXED_CONSTEXPR void SetAngleType(PieceNodeAngle value); Q_DECL_RELAXED_CONSTEXPR void SetManualPasskmarkLength(bool value); + Q_DECL_RELAXED_CONSTEXPR void SetManualPasskmarkWidth(bool value); + Q_DECL_RELAXED_CONSTEXPR void SetManualPasskmarkAngle(bool value); + Q_DECL_RELAXED_CONSTEXPR void SetPasskmarkLength(qreal value); + Q_DECL_RELAXED_CONSTEXPR void SetPasskmarkWidth(qreal value); + Q_DECL_RELAXED_CONSTEXPR void SetPasskmarkAngle(qreal value); Q_DECL_RELAXED_CONSTEXPR auto MaxLocalSA(qreal width) const -> qreal; Q_DECL_RELAXED_CONSTEXPR auto PassmarkLength(qreal width) const -> qreal; + Q_DECL_CONSTEXPR auto IsPassmarkClockwiseOpening() const -> bool; + Q_DECL_RELAXED_CONSTEXPR void SetPassmarkClockwiseOpening(bool clockwise); + auto toJson() const -> QJsonObject; static constexpr qreal passmarkFactor{0.5}; @@ -89,11 +102,16 @@ public: static constexpr qreal minSAWidth{accuracyPointOnLine + accuracyPointOnLine*0.5}; private: - qreal m_before{-1}; - qreal m_after{-1}; + qreal m_before{-1}; + qreal m_after{-1}; PieceNodeAngle m_angle{PieceNodeAngle::ByLength}; - bool m_manualPassmarkLength{false}; - qreal m_passmarkLength{0}; + bool m_manualPassmarkLength{false}; + bool m_manualPassmarkWidth{false}; + bool m_manualPassmarkAngle{false}; + qreal m_passmarkLength{0}; + qreal m_passmarkWidth{0}; + qreal m_passmarkAngle{0}; + bool m_passmarkClockwiseOpening{false}; }; Q_DECLARE_METATYPE(VSAPoint) // NOLINT @@ -176,24 +194,72 @@ Q_DECL_CONSTEXPR inline auto VSAPoint::IsManualPasskmarkLength() const -> bool return m_manualPassmarkLength; } +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline auto VSAPoint::IsManualPasskmarkWidth() const -> bool +{ + return m_manualPassmarkWidth; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline auto VSAPoint::IsManualPasskmarkAngle() const -> bool +{ + return m_manualPassmarkAngle; +} + //--------------------------------------------------------------------------------------------------------------------- Q_DECL_RELAXED_CONSTEXPR inline void VSAPoint::SetManualPasskmarkLength(bool value) { m_manualPassmarkLength = value; } +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_RELAXED_CONSTEXPR inline void VSAPoint::SetManualPasskmarkWidth(bool value) +{ + m_manualPassmarkWidth = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_RELAXED_CONSTEXPR inline void VSAPoint::SetManualPasskmarkAngle(bool value) +{ + m_manualPassmarkAngle = value; +} + //--------------------------------------------------------------------------------------------------------------------- Q_DECL_CONSTEXPR inline auto VSAPoint::GetPasskmarkLength() const -> qreal { return m_passmarkLength; } +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline auto VSAPoint::GetPasskmarkWidth() const -> qreal +{ + return m_passmarkWidth; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_CONSTEXPR inline auto VSAPoint::GetPasskmarkAngle() const -> qreal +{ + return m_passmarkAngle; +} + //--------------------------------------------------------------------------------------------------------------------- Q_DECL_RELAXED_CONSTEXPR inline void VSAPoint::SetPasskmarkLength(qreal value) { m_passmarkLength = value; } +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_RELAXED_CONSTEXPR inline void VSAPoint::SetPasskmarkWidth(qreal value) +{ + m_passmarkWidth = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_RELAXED_CONSTEXPR inline void VSAPoint::SetPasskmarkAngle(qreal value) +{ + m_passmarkAngle = value; +} + //--------------------------------------------------------------------------------------------------------------------- Q_DECL_RELAXED_CONSTEXPR inline auto VSAPoint::MaxLocalSA(qreal width) const -> qreal { @@ -213,6 +279,18 @@ Q_DECL_RELAXED_CONSTEXPR inline auto VSAPoint::PassmarkLength(qreal width) const return m_passmarkLength; } +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_RELAXED_CONSTEXPR inline bool VSAPoint::IsPassmarkClockwiseOpening() const +{ + return m_passmarkClockwiseOpening; +} + +//--------------------------------------------------------------------------------------------------------------------- +Q_DECL_RELAXED_CONSTEXPR inline void VSAPoint::SetPassmarkClockwiseOpening(bool clockwise) +{ + m_passmarkClockwiseOpening = clockwise; +} + QT_WARNING_POP #endif // VSAPOINT_H diff --git a/src/libs/vmisc/def.cpp b/src/libs/vmisc/def.cpp index c9279dd60..c885ecc5b 100644 --- a/src/libs/vmisc/def.cpp +++ b/src/libs/vmisc/def.cpp @@ -328,6 +328,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, strVMark, (QLatin1String("vMark"))) // Q_GLOBAL_STATIC_WITH_ARGS(const QString, strVMark2, (QLatin1String("vMark2"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, strUMark, (QLatin1String("uMark"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, strBoxMark, (QLatin1String("boxMark"))) // NOLINT +Q_GLOBAL_STATIC_WITH_ARGS(const QString, strCheckMark, (QLatin1String("checkMark"))) // NOLINT //--------------------------------------------------------------------------------------------------------------------- auto PassmarkLineTypeToString(PassmarkLineType type) -> QString @@ -342,14 +343,16 @@ auto PassmarkLineTypeToString(PassmarkLineType type) -> QString return strThree; case PassmarkLineType::TMark: return *strTMark; - case PassmarkLineType::VMark: + case PassmarkLineType::ExternalVMark: return *strVMark; - case PassmarkLineType::VMark2: + case PassmarkLineType::InternalVMark: return *strVMark2; case PassmarkLineType::UMark: return *strUMark; case PassmarkLineType::BoxMark: return *strBoxMark; + case PassmarkLineType::CheckMark: + return *strCheckMark; default: break; } @@ -361,7 +364,7 @@ auto PassmarkLineTypeToString(PassmarkLineType type) -> QString auto StringToPassmarkLineType(const QString &value) -> PassmarkLineType { const QStringList values{strOne, strTwo, strThree, *strTMark, *strVMark, - *strVMark2, *strUMark, *strBoxMark}; + *strVMark2, *strUMark, *strBoxMark, *strCheckMark}; switch(values.indexOf(value)) { @@ -374,13 +377,15 @@ auto StringToPassmarkLineType(const QString &value) -> PassmarkLineType case 3: // strTMark return PassmarkLineType::TMark; case 4: // strVMark - return PassmarkLineType::VMark; + return PassmarkLineType::ExternalVMark; case 5: // strVMark2 - return PassmarkLineType::VMark2; + return PassmarkLineType::InternalVMark; case 6: // strUMark return PassmarkLineType::UMark; case 7: // strBoxMark return PassmarkLineType::BoxMark; + case 8: // strCheckMark + return PassmarkLineType::CheckMark; default: break; } diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index 4819e2412..9c7a049d8 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -111,10 +111,11 @@ enum class PassmarkLineType : quint8 TwoLines = 1, ThreeLines = 2, TMark = 3, - VMark = 4, - VMark2 = 5, + ExternalVMark = 4, + InternalVMark = 5, UMark = 6, BoxMark = 7, + CheckMark = 8, LAST_ONE_DO_NOT_USE }; diff --git a/src/libs/vpatterndb/vpassmark.cpp b/src/libs/vpatterndb/vpassmark.cpp index 0dbe1ad6d..a1f1cb53d 100644 --- a/src/libs/vpatterndb/vpassmark.cpp +++ b/src/libs/vpatterndb/vpassmark.cpp @@ -28,12 +28,16 @@ #include -#include "vpassmark.h" -#include "../vmisc/vabstractvalapplication.h" #include "../ifc/exception/vexceptioninvalidnotch.h" #include "../vgeometry/vabstractcurve.h" #include "../vgeometry/varc.h" #include "../vlayout/vrawsapoint.h" +#include "../vmisc/vabstractvalapplication.h" +#include "qmath.h" +#include "qnumeric.h" +#include "qtpreprocessorsupport.h" +#include "vgeometrydef.h" +#include "vpassmark.h" #include @@ -128,157 +132,6 @@ auto FixNotchPoint(const QVector &seamAllowance, const QPointF ¬chBa return fixed; } -//--------------------------------------------------------------------------------------------------------------------- -auto CreateOnePassmarkLines(const QLineF &line) -> QVector -{ - return {line}; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto CreateTwoPassmarkLines(const QLineF &line, const QVector &seamAllowance) -> QVector -{ - QPointF l1p1; - { - QLineF line1 = line; - line1.setAngle(line1.angle() + 90); - line1.setLength(passmarkGap/2.); - l1p1 = line1.p2(); - } - - QPointF l2p1; - { - QLineF line2 = line; - line2.setAngle(line2.angle() - 90); - line2.setLength(passmarkGap/2.); - l2p1 = line2.p2(); - } - - QPointF l1p2; - { - QLineF line1 = QLineF(line.p2(), line.p1()); - line1.setAngle(line1.angle() - 90); - line1.setLength(passmarkGap/2.); - l1p2 = line1.p2(); - } - - QPointF l2p2; - { - QLineF line2 = QLineF(line.p2(), line.p1()); - line2.setAngle(line2.angle() + 90); - line2.setLength(passmarkGap/2.); - l2p2 = line2.p2(); - } - - QVector lines; - QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); - lines.append(QLineF(seg.p2(), seg.p1())); - - seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); - lines.append(QLineF(seg.p2(), seg.p1())); - return lines; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto CreateThreePassmarkLines(const QLineF &line, const QVector &seamAllowance) -> QVector -{ - QPointF l1p1; - { - QLineF line1 = line; - line1.setAngle(line1.angle() + 90); - line1.setLength(passmarkGap); - l1p1 = line1.p2(); - } - - QPointF l2p1; - { - QLineF line2 = line; - line2.setAngle(line2.angle() - 90); - line2.setLength(passmarkGap); - l2p1 = line2.p2(); - } - - QPointF l1p2; - { - QLineF line1 = QLineF(line.p2(), line.p1()); - line1.setAngle(line1.angle() - 90); - line1.setLength(passmarkGap); - l1p2 = line1.p2(); - } - - QPointF l2p2; - { - QLineF line2 = QLineF(line.p2(), line.p1()); - line2.setAngle(line2.angle() + 90); - line2.setLength(passmarkGap); - l2p2 = line2.p2(); - } - - QVector lines; - QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); - lines.append(QLineF(seg.p2(), seg.p1())); - - lines.append(line); - - seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); - lines.append(QLineF(seg.p2(), seg.p1())); - return lines; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto CreateTMarkPassmark(const QLineF &line) -> QVector -{ - QPointF p1; - { - QLineF tmpLine = QLineF(line.p2(), line.p1()); - tmpLine.setAngle(tmpLine.angle() - 90); - tmpLine.setLength(line.length() * 0.75 / 2); - p1 = tmpLine.p2(); - } - - QPointF p2; - { - QLineF tmpLine = QLineF(line.p2(), line.p1()); - tmpLine.setAngle(tmpLine.angle() + 90); - tmpLine.setLength(line.length() * 0.75 / 2); - p2 = tmpLine.p2(); - } - - QVector lines; - lines.append(line); - lines.append(QLineF(p1, p2)); - return lines; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto CreateVMarkPassmark(const QLineF &line) -> QVector -{ - QLineF l1 = line; - l1.setAngle(l1.angle() - 35); - - QLineF l2 = line; - l2.setAngle(l2.angle() + 35); - - QVector lines; - lines.append(l1); - lines.append(l2); - return lines; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto CreateVMark2Passmark(const QLineF &line, const QVector &seamAllowance) -> QVector -{ - QLineF l1 = QLineF(line.p2(), line.p1()); - l1.setAngle(l1.angle() + 35); - - QLineF l2 = QLineF(line.p2(), line.p1()); - l2.setAngle(l2.angle() - 35); - - QVector lines; - lines.append(VPassmark::FindIntersection(l1, seamAllowance)); - lines.append(VPassmark::FindIntersection(l2, seamAllowance)); - return lines; -} - //--------------------------------------------------------------------------------------------------------------------- auto PointsToSegments(const QVector &points) -> QVector { @@ -299,77 +152,111 @@ auto PointsToSegments(const QVector &points) -> QVector } //--------------------------------------------------------------------------------------------------------------------- -auto CreateUMarkPassmark(const QLineF &line, const QVector &seamAllowance) -> QVector +auto PassmarkLength(const VPiecePassmarkData &passmarkData, qreal width, bool &ok) -> qreal { - const qreal radius = line.length() * VPassmark::passmarkRadiusFactor; - - QLineF baseLine = line; - baseLine.setLength(baseLine.length() - radius); // keep defined depth - - QPointF l1p1; + auto ValidateLength = [passmarkData](qreal length) { - QLineF line1 = baseLine; - line1.setAngle(line1.angle() + 90); - line1.setLength(radius); - l1p1 = line1.p2(); + if (length <= accuracyPointOnLine) + { + const QString errorMsg = QObject::tr("Found null notch for point '%1' in piece '%2'. Length is less " + "than minimal allowed.") + .arg(passmarkData.nodeName, passmarkData.pieceName); + VAbstractApplication::VApp()->IsPedantic() + ? throw VException(errorMsg) + : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; + + return false; + } + return true; + }; + + qreal length = 0; + if (not passmarkData.passmarkSAPoint.IsManualPasskmarkLength()) + { + if (passmarkData.globalPassmarkLength > accuracyPointOnLine) + { + ok = true; + return passmarkData.globalPassmarkLength; + } + + length = qMin(width * VSAPoint::passmarkFactor, VSAPoint::maxPassmarkLength); + if (not ValidateLength(length)) + { + ok = false; + return length; + } + + ok = true; + return length; } - QPointF l2p1; + length = passmarkData.passmarkSAPoint.GetPasskmarkLength(); + if (not ValidateLength(length)) { - QLineF line2 = baseLine; - line2.setAngle(line2.angle() - 90); - line2.setLength(radius); - l2p1 = line2.p2(); + ok = false; + return length; } - QPointF l1p2; - { - QLineF line1 = QLineF(baseLine.p2(), baseLine.p1()); - line1.setAngle(line1.angle() - 90); - line1.setLength(radius); - l1p2 = line1.p2(); - } - - QPointF l2p2; - { - QLineF line2 = QLineF(baseLine.p2(), baseLine.p1()); - line2.setAngle(line2.angle() + 90); - line2.setLength(radius); - l2p2 = line2.p2(); - } - - QLineF axis = QLineF(baseLine.p2(), baseLine.p1()); - axis.setLength(radius); - - QVector points; - - QLineF seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); - seg = QLineF(seg.p2(), seg.p1()); - points.append(seg.p1()); - points.append(seg.p2()); - - VArc arc(VPointF(baseLine.p2()), radius, QLineF(baseLine.p2(), l2p2).angle(), QLineF(baseLine.p2(), l1p2).angle()); - arc.SetApproximationScale(10); - points += arc.GetPoints(); - - seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); - seg = QLineF(seg.p2(), seg.p1()); - points.append(seg.p2()); - points.append(seg.p1()); - - return PointsToSegments(points); + ok = true; + return length; } //--------------------------------------------------------------------------------------------------------------------- -auto CreateBoxMarkPassmark(const QLineF &line, const QVector &seamAllowance) -> QVector +auto PassmarkAngle(const VPiecePassmarkData &passmarkData, qreal angle) -> qreal { - const qreal radius = line.length() * VPassmark::passmarkRadiusFactor; + return passmarkData.passmarkSAPoint.IsManualPasskmarkAngle() ? passmarkData.passmarkSAPoint.GetPasskmarkAngle() + : angle; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto PassmarkWidth(const VPiecePassmarkData &passmarkData, qreal width) -> qreal +{ + auto ValidateWidth = [passmarkData](qreal width) + { + if (qAbs(width) <= accuracyPointOnLine) + { + const QString errorMsg = + QObject::tr("Error: notch for point '%1' in piece '%2'. Width is less than minimal allowed.") + .arg(passmarkData.nodeName, passmarkData.pieceName); + VAbstractApplication::VApp()->IsPedantic() + ? throw VException(errorMsg) + : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; + } + }; + + if (not passmarkData.passmarkSAPoint.IsManualPasskmarkWidth()) + { + if (qAbs(passmarkData.globalPassmarkWidth) > accuracyPointOnLine) + { + return passmarkData.globalPassmarkWidth; + } + + ValidateWidth(width); + return width; + } + + ValidateWidth(passmarkData.passmarkSAPoint.GetPasskmarkWidth()); + return passmarkData.passmarkSAPoint.GetPasskmarkWidth(); +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateOnePassmarkLines(const VPiecePassmarkData &passmarkData, const QLineF &line) -> QVector +{ + Q_UNUSED(passmarkData); + return {line}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateTwoPassmarkLines(const VPiecePassmarkData &passmarkData, const QLineF &line, + const QVector &seamAllowance) -> QVector +{ + const qreal width = PassmarkWidth(passmarkData, passmarkGap); QPointF l1p1; { QLineF line1 = line; line1.setAngle(line1.angle() + 90); - line1.setLength(radius); + line1.setLength(width / 2.); l1p1 = line1.p2(); } @@ -377,7 +264,7 @@ auto CreateBoxMarkPassmark(const QLineF &line, const QVector &seamAllow { QLineF line2 = line; line2.setAngle(line2.angle() - 90); - line2.setLength(radius); + line2.setLength(width / 2.); l2p1 = line2.p2(); } @@ -385,7 +272,7 @@ auto CreateBoxMarkPassmark(const QLineF &line, const QVector &seamAllow { QLineF line1 = QLineF(line.p2(), line.p1()); line1.setAngle(line1.angle() - 90); - line1.setLength(radius); + line1.setLength(width / 2.); l1p2 = line1.p2(); } @@ -393,10 +280,239 @@ auto CreateBoxMarkPassmark(const QLineF &line, const QVector &seamAllow { QLineF line2 = QLineF(line.p2(), line.p1()); line2.setAngle(line2.angle() + 90); - line2.setLength(radius); + line2.setLength(width / 2.); l2p2 = line2.p2(); } + QVector lines; + QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); + lines.append(QLineF(seg.p2(), seg.p1())); + + seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); + lines.append(QLineF(seg.p2(), seg.p1())); + return lines; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateThreePassmarkLines(const VPiecePassmarkData &passmarkData, const QLineF &line, + const QVector &seamAllowance) -> QVector +{ + const qreal width = PassmarkWidth(passmarkData, passmarkGap); + + QPointF l1p1; + { + QLineF line1 = line; + line1.setAngle(line1.angle() + 90); + line1.setLength(width / 2.); + l1p1 = line1.p2(); + } + + QPointF l2p1; + { + QLineF line2 = line; + line2.setAngle(line2.angle() - 90); + line2.setLength(width / 2.); + l2p1 = line2.p2(); + } + + QPointF l1p2; + { + QLineF line1 = QLineF(line.p2(), line.p1()); + line1.setAngle(line1.angle() - 90); + line1.setLength(width / 2.); + l1p2 = line1.p2(); + } + + QPointF l2p2; + { + QLineF line2 = QLineF(line.p2(), line.p1()); + line2.setAngle(line2.angle() + 90); + line2.setLength(width / 2.); + l2p2 = line2.p2(); + } + + QVector lines; + QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); + lines.append(QLineF(seg.p2(), seg.p1())); + + lines.append(line); + + seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); + lines.append(QLineF(seg.p2(), seg.p1())); + return lines; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateTMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &line) -> QVector +{ + const qreal width = PassmarkWidth(passmarkData, line.length() * 0.75); + + QPointF p1; + { + QLineF tmpLine = QLineF(line.p2(), line.p1()); + tmpLine.setAngle(tmpLine.angle() - 90); + tmpLine.setLength(width / 2.); + p1 = tmpLine.p2(); + } + + QPointF p2; + { + QLineF tmpLine = QLineF(line.p2(), line.p1()); + tmpLine.setAngle(tmpLine.angle() + 90); + tmpLine.setLength(width / 2.); + p2 = tmpLine.p2(); + } + + return {line, {QLineF(p1, p2).center(), p2}, {p2, p1}}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateExternalVMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &line) -> QVector +{ + constexpr qreal defAngle = 35; + const qreal defWidth = line.length() * qTan(qDegreesToRadians(defAngle)); + const qreal width = PassmarkWidth(passmarkData, defWidth * 2.); + const qreal angle = qRadiansToDegrees(qAtan(qAbs(width) / 2. / line.length())); + + QLineF l1 = line; + l1.setAngle(l1.angle() - angle); + + QLineF l2 = line; + l2.setAngle(l2.angle() + angle); + + return {l1, {l2.p2(), l2.p1()}}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateInternalVMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &line, + const QVector &seamAllowance) -> QVector +{ + constexpr qreal defAngle = 35; + const qreal defWidth = line.length() * qTan(qDegreesToRadians(defAngle)); + const qreal width = PassmarkWidth(passmarkData, defWidth * 2.); + const qreal angle = qRadiansToDegrees(qAtan(qAbs(width) / 2. / line.length())); + + QLineF l1 = QLineF(line.p2(), line.p1()); + l1.setAngle(l1.angle() + angle); + l1 = VPassmark::FindIntersection(l1, seamAllowance); + + QLineF l2 = QLineF(line.p2(), line.p1()); + l2.setAngle(l2.angle() - angle); + + return {{l1.p2(), l1.p1()}, VPassmark::FindIntersection(l2, seamAllowance)}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateUMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &line, + const QVector &seamAllowance) -> QVector +{ + const qreal defWidth = line.length() * VPassmark::passmarkRadiusFactor * 2; + const qreal width = PassmarkWidth(passmarkData, defWidth); + const qreal radius = width / 2.; + + QVector points; + QLineF baseLine = line; + + QPointF l1p1; + { + QLineF line = baseLine; + line.setAngle(line.angle() - 90); + line.setLength(radius); + l1p1 = line.p2(); + } + + QPointF l2p1; + { + QLineF line = baseLine; + line.setAngle(line.angle() + 90); + line.setLength(radius); + l2p1 = line.p2(); + } + + if (baseLine.length() - radius > accuracyPointOnLine) + { + baseLine.setLength(baseLine.length() - radius); // keep defined depth + + QPointF l1p2; + { + QLineF line = QLineF(baseLine.p2(), baseLine.p1()); + line.setAngle(line.angle() + 90); + line.setLength(radius); + l1p2 = line.p2(); + } + + QPointF l2p2; + { + QLineF line = QLineF(baseLine.p2(), baseLine.p1()); + line.setAngle(line.angle() - 90); + line.setLength(radius); + l2p2 = line.p2(); + } + + QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); + seg = QLineF(seg.p2(), seg.p1()); + points.append(seg.p1()); + points.append(seg.p2()); + + VArc arc(VPointF(baseLine.p2()), radius, QLineF(baseLine.p2(), l1p2).angle(), + QLineF(baseLine.p2(), l2p2).angle()); + arc.SetApproximationScale(10); + points += arc.GetPoints(); + + seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); + points.append(seg.p1()); + points.append(seg.p2()); + } + else + { + VArc arc(VPointF(baseLine.p1()), radius, QLineF(baseLine.p1(), l1p1).angle(), + QLineF(baseLine.p1(), l2p1).angle()); + arc.SetApproximationScale(10); + points += arc.GetPoints(); + } + + return PointsToSegments(points); +} + +//--------------------------------------------------------------------------------------------------------------------- +auto CreateBoxMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &line, + const QVector &seamAllowance) -> QVector +{ + const qreal defWidth = line.length() * VPassmark::passmarkRadiusFactor; + const qreal width = PassmarkWidth(passmarkData, defWidth); + + QPointF l1p1; + { + QLineF tmp = line; + tmp.setAngle(tmp.angle() - 90); + tmp.setLength(width / 2.); + l1p1 = tmp.p2(); + } + + QPointF l1p2; + { + QLineF tmp = QLineF(line.p2(), line.p1()); + tmp.setAngle(tmp.angle() + 90); + tmp.setLength(width / 2.); + l1p2 = tmp.p2(); + } + + QPointF l2p1; + { + QLineF tmp = line; + tmp.setAngle(tmp.angle() + 90); + tmp.setLength(width / 2.); + l2p1 = tmp.p2(); + } + + QPointF l2p2; + { + QLineF tmp = QLineF(line.p2(), line.p1()); + tmp.setAngle(tmp.angle() - 90); + tmp.setLength(width / 2.); + l2p2 = tmp.p2(); + } + QVector points; QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); @@ -411,202 +527,34 @@ auto CreateBoxMarkPassmark(const QLineF &line, const QVector &seamAllow } //--------------------------------------------------------------------------------------------------------------------- -auto CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType angleType, const QVector &lines, - const QVector &seamAllowance, PassmarkSide side) -> QVector +auto CreateCheckMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &line, + const QVector &seamAllowance) -> QVector { - if (lines.isEmpty()) + constexpr qreal defAngle = 45; + qreal defWidth = line.length() * qTan(qDegreesToRadians(defAngle)); + + if (not passmarkData.passmarkSAPoint.IsPassmarkClockwiseOpening()) { - return {}; + defWidth *= -1; } - QVector passmarksLines; + const qreal width = PassmarkWidth(passmarkData, defWidth); + const qreal angle = qRadiansToDegrees(qAtan(qAbs(width) / line.length())); - auto CreateLinesWithCorrection = [&passmarksLines, side, angleType, lines, seamAllowance] - (QVector (*create)(const QLineF &, const QVector &)) - { - if (angleType == PassmarkAngleType::Straightforward) - { - passmarksLines += (*create)(ConstFirst(lines), seamAllowance); - } - else - { - if (side == PassmarkSide::All || side == PassmarkSide::Left) - { - passmarksLines += (*create)(ConstFirst(lines), seamAllowance); - } + if (width > 0) + { // clockwise + QLineF l1(line.p2(), line.p1()); + l1.setAngle(l1.angle() + angle); + l1 = VPassmark::FindIntersection(l1, seamAllowance); - if (side == PassmarkSide::All || side == PassmarkSide::Right) - { - passmarksLines += (*create)(ConstLast(lines), seamAllowance); - } - } - }; - - auto CreateLines = [&passmarksLines, side, angleType, lines](QVector (*create)(const QLineF &)) - { - if (angleType == PassmarkAngleType::Straightforward) - { - passmarksLines += (*create)(ConstFirst(lines)); - } - else - { - if (side == PassmarkSide::All || side == PassmarkSide::Left) - { - passmarksLines += (*create)(ConstFirst(lines)); - } - - if (side == PassmarkSide::All || side == PassmarkSide::Right) - { - passmarksLines += (*create)(ConstLast(lines)); - } - } - }; - - if (angleType == PassmarkAngleType::Straightforward - || angleType == PassmarkAngleType::Intersection - || angleType == PassmarkAngleType::IntersectionOnlyLeft - || angleType == PassmarkAngleType::IntersectionOnlyRight - || angleType == PassmarkAngleType::Intersection2 - || angleType == PassmarkAngleType::Intersection2OnlyLeft - || angleType == PassmarkAngleType::Intersection2OnlyRight) - { - switch (lineType) - { - case PassmarkLineType::TwoLines: - CreateLinesWithCorrection(CreateTwoPassmarkLines); - break; - case PassmarkLineType::ThreeLines: - CreateLinesWithCorrection(CreateThreePassmarkLines); - break; - case PassmarkLineType::TMark: - CreateLines(CreateTMarkPassmark); - break; - case PassmarkLineType::VMark: - CreateLines(CreateVMarkPassmark); - break; - case PassmarkLineType::VMark2: - CreateLinesWithCorrection(CreateVMark2Passmark); - break; - case PassmarkLineType::UMark: - CreateLinesWithCorrection(CreateUMarkPassmark); - break; - case PassmarkLineType::BoxMark: - CreateLinesWithCorrection(CreateBoxMarkPassmark); - break; - case PassmarkLineType::OneLine: - default: - CreateLines(CreateOnePassmarkLines); - break; - } - } - else - { - switch (lineType) - { - case PassmarkLineType::TMark: - passmarksLines += CreateTMarkPassmark(ConstFirst(lines)); - break; - case PassmarkLineType::OneLine: - case PassmarkLineType::TwoLines: - case PassmarkLineType::ThreeLines: - case PassmarkLineType::VMark: - case PassmarkLineType::VMark2: - case PassmarkLineType::UMark: - case PassmarkLineType::BoxMark: - default: - passmarksLines.append(ConstFirst(lines)); - break; - } + return {{l1.p2(), l1.p1()}, {line.p2(), line.p1()}}; } - return passmarksLines; -} + QLineF l2(line.p2(), line.p1()); + l2.setAngle(l2.angle() - angle); + l2 = VPassmark::FindIntersection(l2, seamAllowance); -//--------------------------------------------------------------------------------------------------------------------- -auto PassmarkLength(const VPiecePassmarkData &passmarkData, qreal width, bool &ok) -> qreal -{ - qreal length = 0; - if (not passmarkData.passmarkSAPoint.IsManualPasskmarkLength()) - { - if (passmarkData.globalPassmarkLength > accuracyPointOnLine) - { - ok = true; - return passmarkData.globalPassmarkLength; - } - - length = qMin(width * VSAPoint::passmarkFactor, VSAPoint::maxPassmarkLength); - - if (length <= accuracyPointOnLine) - { - const QString errorMsg = QObject::tr("Found null notch for point '%1' in piece '%2'. Length is less " - "than minimal allowed.") - .arg(passmarkData.nodeName, passmarkData.pieceName); - VAbstractApplication::VApp()->IsPedantic() - ? throw VException(errorMsg) - : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; - - ok = false; - return length; - } - - ok = true; - return length; - } - - length = passmarkData.passmarkSAPoint.GetPasskmarkLength(); - - ok = true; - return length; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData, - const QPointF &seamPassmarkSAPoint, const QVector &seamAllowance) - -> QVector -{ - QLineF edge1; - QLineF edge2; - - if (seamPassmarkType == PassmarkStatus::Common) - { - if (passmarkData.passmarkSAPoint.GetAngleType() == PieceNodeAngle::ByFirstEdgeSymmetry) - { - edge1 = QLineF(seamPassmarkSAPoint, seamAllowance.at(seamAllowance.size() - 2)); - edge2 = QLineF(seamPassmarkSAPoint, seamAllowance.at(1)); - } - else - { - const QLineF bigLine1 = VAbstractPiece::ParallelLine(passmarkData.previousSAPoint, - passmarkData.passmarkSAPoint, passmarkData.saWidth ); - const QLineF bigLine2 = VAbstractPiece::ParallelLine(passmarkData.passmarkSAPoint, passmarkData.nextSAPoint, - passmarkData.saWidth ); - - edge1 = QLineF(seamPassmarkSAPoint, bigLine1.p1()); - edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2()); - } - } - else if(seamPassmarkType == PassmarkStatus::Rollback) - { - edge1 = QLineF(seamPassmarkSAPoint, seamAllowance.at(seamAllowance.size() - 2)); - edge2 = QLineF(seamPassmarkSAPoint, seamAllowance.at(1)); - } - else - { // Should never happen - return {}; - } - - bool ok = false; - const qreal length = PassmarkLength(passmarkData, passmarkData.passmarkSAPoint.MaxLocalSA(passmarkData.saWidth), - ok); - if (not ok) - { - return {}; - } - - edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.); - edge1.setLength(length); - - return {edge1}; + return {line, l2}; } //--------------------------------------------------------------------------------------------------------------------- @@ -630,8 +578,7 @@ auto PassmarkToPath(const QVector &passmark) -> QPainterPath //------------------------------VPiecePassmarkData--------------------------------------------------------------------- auto VPiecePassmarkData::toJson() const -> QJsonObject { - QJsonObject dataObject - { + QJsonObject dataObject{ {"previousSAPoint", previousSAPoint.toJson()}, {"passmarkSAPoint", passmarkSAPoint.toJson()}, {"nextSAPoint", nextSAPoint.toJson()}, @@ -644,7 +591,8 @@ auto VPiecePassmarkData::toJson() const -> QJsonObject {"isShowSecondPassmark", isShowSecondPassmark}, {"passmarkIndex", passmarkIndex}, {"id", static_cast(id)}, - {"globalPassmarkLength", static_cast(globalPassmarkLength)}, + {"globalPassmarkLength", globalPassmarkLength}, + {"globalPassmarkWidth", globalPassmarkWidth}, }; return dataObject; @@ -739,8 +687,8 @@ auto VPassmark::SAPassmark(const QVector &seamAllowance, const QVector< return lines; } - lines = CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines, seamAllowance, side); -// DumpPassmarkShape(lines, QStringLiteral("passmarkShape.json.XXXXXX")); // Uncomment for dumping test data + lines = CreatePassmarkLines(lines, seamAllowance, side); + // DumpPassmarkShape(lines, QStringLiteral("passmarkShape.json.XXXXXX")); // Uncomment for dumping test data return lines; } @@ -770,6 +718,171 @@ auto VPassmark::FindIntersection(const QLineF &line, const QVector &sea return line; } +//--------------------------------------------------------------------------------------------------------------------- +auto VPassmark::PassmarkIntersection(const QVector &path, QLineF line, qreal width) const -> QLineF +{ + line.setLength(line.length() * 100); // Hope 100 is enough + + // DumpVector(path, QStringLiteral("points.json.XXXXXX")); // Uncomment for dumping test data + + const QVector intersections = VAbstractCurve::CurveIntersectLine(path, line); + + // DumpVector(intersections, QStringLiteral("intersections.json.XXXXXX")); // Uncomment for dumping test data + + if (not intersections.isEmpty()) + { + if (ConstLast(intersections) != m_data.passmarkSAPoint) + { + line = QLineF(ConstLast(intersections), m_data.passmarkSAPoint); + + bool ok = false; + const qreal length = PassmarkLength(m_data, width, ok); + if (not ok) + { + return {}; + } + line.setLength(length); + + return line; + } + + const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Notch " + "collapse.") + .arg(m_data.nodeName, m_data.pieceName); + VAbstractApplication::VApp()->IsPedantic() + ? throw VExceptionInvalidNotch(errorMsg) + : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; + } + else + { + const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Cannot find " + "intersection.") + .arg(m_data.nodeName, m_data.pieceName); + VAbstractApplication::VApp()->IsPedantic() + ? throw VExceptionInvalidNotch(errorMsg) + : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; + } + + return {}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPassmark::PassmarkStraightforwardBaseLine(const QPointF &seamPassmarkSAPoint) const -> QVector +{ + bool ok = false; + const qreal length = PassmarkLength(m_data, m_data.passmarkSAPoint.MaxLocalSA(m_data.saWidth), ok); + + if (not ok) + { + return {}; + } + + QLineF line = QLineF(seamPassmarkSAPoint, m_data.passmarkSAPoint); + line.setLength(length); + line.setAngle(PassmarkAngle(m_data, line.angle())); + return {line}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPassmark::PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const QPointF &seamPassmarkSAPoint, + const QVector &seamAllowance) const -> QVector +{ + QLineF edge1; + QLineF edge2; + + if (seamPassmarkType == PassmarkStatus::Common) + { + if (m_data.passmarkSAPoint.GetAngleType() == PieceNodeAngle::ByFirstEdgeSymmetry) + { + edge1 = QLineF(seamPassmarkSAPoint, seamAllowance.at(seamAllowance.size() - 2)); + edge2 = QLineF(seamPassmarkSAPoint, seamAllowance.at(1)); + } + else + { + const QLineF bigLine1 = + VAbstractPiece::ParallelLine(m_data.previousSAPoint, m_data.passmarkSAPoint, m_data.saWidth); + const QLineF bigLine2 = + VAbstractPiece::ParallelLine(m_data.passmarkSAPoint, m_data.nextSAPoint, m_data.saWidth); + + edge1 = QLineF(seamPassmarkSAPoint, bigLine1.p1()); + edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2()); + } + } + else if (seamPassmarkType == PassmarkStatus::Rollback) + { + edge1 = QLineF(seamPassmarkSAPoint, seamAllowance.at(seamAllowance.size() - 2)); + edge2 = QLineF(seamPassmarkSAPoint, seamAllowance.at(1)); + } + else + { // Should never happen + return {}; + } + + bool ok = false; + const qreal length = PassmarkLength(m_data, m_data.passmarkSAPoint.MaxLocalSA(m_data.saWidth), ok); + if (not ok) + { + return {}; + } + + edge1.setAngle(edge1.angle() + edge1.angleTo(edge2) / 2.); + edge1.setLength(length); + + return {edge1}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPassmark::PassmarkIntersectionBaseLine(const QVector &path, PassmarkSide side) const -> QVector +{ + QVector lines; + if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection || + m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft) && + (side == PassmarkSide::All || side == PassmarkSide::Left)) + { + // first passmark + lines += PassmarkIntersection(path, QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint), + m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); + } + + if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection || + m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight) && + (side == PassmarkSide::All || side == PassmarkSide::Right)) + { + // second passmark + lines += PassmarkIntersection(path, QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint), + m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); + } + + return lines; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPassmark::PassmarkIntersection2BaseLine(const QVector &path, PassmarkSide side) const -> QVector +{ + QVector lines; + if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 || + m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft) && + (side == PassmarkSide::All || side == PassmarkSide::Left)) + { + // first passmark + QLineF line(m_data.passmarkSAPoint, m_data.previousSAPoint); + line.setAngle(line.angle() - 90); + lines += PassmarkIntersection(path, line, m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); + } + + if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 || + m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight) && + (side == PassmarkSide::All || side == PassmarkSide::Right)) + { + // second passmark + QLineF line(m_data.passmarkSAPoint, m_data.nextSAPoint); + line.setAngle(line.angle() + 90); + lines += PassmarkIntersection(path, line, m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); + } + + return lines; +} + //--------------------------------------------------------------------------------------------------------------------- auto VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContainer *data) const -> QVector { @@ -786,7 +899,7 @@ auto VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContainer *data) c QVector points; CastTo(piece.MainPathPoints(data), points); - return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines, points, PassmarkSide::All); + return CreatePassmarkLines(lines, points, PassmarkSide::All); } //--------------------------------------------------------------------------------------------------------------------- @@ -837,6 +950,7 @@ auto VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const -> QVector< edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.); edge1.setLength(length); + edge1.setAngle(PassmarkAngle(m_data, edge1.angle())); return {edge1}; } @@ -909,123 +1023,28 @@ auto VPassmark::SAPassmarkBaseLine(const QVector &seamAllowance, const qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; } - auto PassmarkIntersection = [this, path] (QLineF line, qreal width) - { - line.setLength(line.length()*100); // Hope 100 is enough - -// DumpVector(path, QStringLiteral("points.json.XXXXXX")); // Uncomment for dumping test data - - const QVector intersections = VAbstractCurve::CurveIntersectLine(path, line); - -// DumpVector(intersections, QStringLiteral("intersections.json.XXXXXX")); // Uncomment for dumping test data - - if (not intersections.isEmpty()) - { - if (ConstLast(intersections) != m_data.passmarkSAPoint) - { - line = QLineF(ConstLast(intersections), m_data.passmarkSAPoint); - - bool ok = false; - const qreal length = PassmarkLength(m_data, width, ok); - if (not ok) - { - return QLineF(); - } - line.setLength(length); - - return line; - } - - const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Notch " - "collapse.") - .arg(m_data.nodeName, m_data.pieceName); - VAbstractApplication::VApp()->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : - qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; - } - else - { - const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Cannot find " - "intersection.") - .arg(m_data.nodeName, m_data.pieceName); - VAbstractApplication::VApp()->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : - qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; - } - - return QLineF(); - }; - if (m_data.passmarkAngleType == PassmarkAngleType::Straightforward) { - bool ok = false; - const qreal length = PassmarkLength(m_data, m_data.passmarkSAPoint.MaxLocalSA(m_data.saWidth), ok); - - if (not ok) - { - return {}; - } - - QLineF line = QLineF(seamPassmarkSAPoint, m_data.passmarkSAPoint); - line.setLength(length); - return {line}; + return PassmarkStraightforwardBaseLine(seamPassmarkSAPoint); } if (m_data.passmarkAngleType == PassmarkAngleType::Bisector) { - return PassmarkBisectorBaseLine(seamPassmarkType, m_data, seamPassmarkSAPoint, path); + return PassmarkBisectorBaseLine(seamPassmarkType, seamPassmarkSAPoint, path); } if (m_data.passmarkAngleType == PassmarkAngleType::Intersection || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight) { - QVector lines; - if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection - || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft) - && (side == PassmarkSide::All || side == PassmarkSide::Left)) - { - // first passmark - lines += PassmarkIntersection(QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint), - m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); - } - - if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection - || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight) - && (side == PassmarkSide::All || side == PassmarkSide::Right)) - { - // second passmark - lines += PassmarkIntersection(QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint), - m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); - } - - return lines; + return PassmarkIntersectionBaseLine(path, side); } if (m_data.passmarkAngleType == PassmarkAngleType::Intersection2 || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight) { - QVector lines; - if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 - || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft) - && (side == PassmarkSide::All || side == PassmarkSide::Left)) - { - // first passmark - QLineF line(m_data.passmarkSAPoint, m_data.previousSAPoint); - line.setAngle(line.angle()-90); - lines += PassmarkIntersection(line, m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); - } - - if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 - || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight) - && (side == PassmarkSide::All || side == PassmarkSide::Right)) - { - // second passmark - QLineF line(m_data.passmarkSAPoint, m_data.nextSAPoint); - line.setAngle(line.angle()+90); - lines += PassmarkIntersection(line, m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); - } - - return lines; + return PassmarkIntersection2BaseLine(path, side); } return {}; @@ -1042,3 +1061,102 @@ auto VPassmark::BuiltInSAPassmarkPath(const VPiece &piece, const VContainer *dat { return PassmarkToPath(BuiltInSAPassmark(piece, data)); } + +//--------------------------------------------------------------------------------------------------------------------- +auto VPassmark::CreatePassmarkLines(const QVector &lines, const QVector &seamAllowance, + PassmarkSide side) const -> QVector +{ + if (lines.isEmpty()) + { + return {}; + } + + auto CreateLinesWithCorrection = + [this, side, lines, seamAllowance]( + QVector (*create)(const VPiecePassmarkData &passmarkData, const QLineF &, const QVector &)) + { + if (m_data.passmarkAngleType == PassmarkAngleType::Straightforward) + { + return (*create)(m_data, ConstFirst(lines), seamAllowance); + } + + QVector passmarksLines; + + if (side == PassmarkSide::All || side == PassmarkSide::Left) + { + passmarksLines += (*create)(m_data, ConstFirst(lines), seamAllowance); + } + + if (side == PassmarkSide::All || side == PassmarkSide::Right) + { + passmarksLines += (*create)(m_data, ConstLast(lines), seamAllowance); + } + + return passmarksLines; + }; + + auto CreateLines = + [this, side, lines](QVector (*create)(const VPiecePassmarkData &passmarkData, const QLineF &)) + { + if (m_data.passmarkAngleType == PassmarkAngleType::Straightforward) + { + return (*create)(m_data, ConstFirst(lines)); + } + + QVector passmarksLines; + + if (side == PassmarkSide::All || side == PassmarkSide::Left) + { + passmarksLines += (*create)(m_data, ConstFirst(lines)); + } + + if (side == PassmarkSide::All || side == PassmarkSide::Right) + { + passmarksLines += (*create)(m_data, ConstLast(lines)); + } + + return passmarksLines; + }; + + if (m_data.passmarkAngleType != PassmarkAngleType::Bisector) + { + switch (m_data.passmarkLineType) + { + case PassmarkLineType::TwoLines: + return CreateLinesWithCorrection(CreateTwoPassmarkLines); + case PassmarkLineType::ThreeLines: + return CreateLinesWithCorrection(CreateThreePassmarkLines); + case PassmarkLineType::TMark: + return CreateLines(CreateTMarkPassmark); + case PassmarkLineType::ExternalVMark: + return CreateLines(CreateExternalVMarkPassmark); + case PassmarkLineType::InternalVMark: + return CreateLinesWithCorrection(CreateInternalVMarkPassmark); + case PassmarkLineType::UMark: + return CreateLinesWithCorrection(CreateUMarkPassmark); + case PassmarkLineType::BoxMark: + return CreateLinesWithCorrection(CreateBoxMarkPassmark); + case PassmarkLineType::CheckMark: + return CreateLinesWithCorrection(CreateCheckMarkPassmark); + case PassmarkLineType::OneLine: + default: + return CreateLines(CreateOnePassmarkLines); + } + } + + switch (m_data.passmarkLineType) + { + case PassmarkLineType::TMark: + return CreateTMarkPassmark(m_data, ConstFirst(lines)); + case PassmarkLineType::OneLine: + case PassmarkLineType::TwoLines: + case PassmarkLineType::ThreeLines: + case PassmarkLineType::ExternalVMark: + case PassmarkLineType::InternalVMark: + case PassmarkLineType::UMark: + case PassmarkLineType::BoxMark: + case PassmarkLineType::CheckMark: + default: + return {ConstFirst(lines)}; + } +} diff --git a/src/libs/vpatterndb/vpassmark.h b/src/libs/vpatterndb/vpassmark.h index c99a5751f..1a7552267 100644 --- a/src/libs/vpatterndb/vpassmark.h +++ b/src/libs/vpatterndb/vpassmark.h @@ -63,6 +63,7 @@ struct VPiecePassmarkData vsizetype passmarkIndex{-1}; // NOLINT(misc-non-private-member-variables-in-classes) vidtype id{NULL_ID}; // NOLINT(misc-non-private-member-variables-in-classes) qreal globalPassmarkLength{0}; // NOLINT(misc-non-private-member-variables-in-classes) + qreal globalPassmarkWidth{0}; // NOLINT(misc-non-private-member-variables-in-classes) auto toJson() const -> QJsonObject; }; @@ -104,6 +105,17 @@ public: private: VPiecePassmarkData m_data{}; bool m_null{true}; + + auto PassmarkIntersection(const QVector &path, QLineF line, qreal width) const -> QLineF; + + auto PassmarkStraightforwardBaseLine(const QPointF &seamPassmarkSAPoint) const -> QVector; + auto PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const QPointF &seamPassmarkSAPoint, + const QVector &seamAllowance) const -> QVector; + auto PassmarkIntersectionBaseLine(const QVector &path, PassmarkSide side) const -> QVector; + auto PassmarkIntersection2BaseLine(const QVector &path, PassmarkSide side) const -> QVector; + + auto CreatePassmarkLines(const QVector &lines, const QVector &seamAllowance, + PassmarkSide side) const -> QVector; }; #endif // VPASSMARK_H diff --git a/src/libs/vpatterndb/vpiece.cpp b/src/libs/vpatterndb/vpiece.cpp index a514b41aa..19c3c587b 100644 --- a/src/libs/vpatterndb/vpiece.cpp +++ b/src/libs/vpatterndb/vpiece.cpp @@ -1116,6 +1116,7 @@ auto VPiece::CreatePassmark(const QVector &path, vsizetype previousI passmarkData.passmarkIndex = passmarkIndex; passmarkData.id = path.at(passmarkIndex).GetId(); passmarkData.globalPassmarkLength = ToPixel(GlobalPassmarkLength(data), *data->GetPatternUnit()); + passmarkData.globalPassmarkWidth = ToPixel(GlobalPassmarkWidth(data), *data->GetPatternUnit()); // cppcheck-suppress unknownMacro QT_WARNING_POP @@ -1202,6 +1203,40 @@ auto VPiece::GlobalPassmarkLength(const VContainer *data) const -> qreal return length; } +//--------------------------------------------------------------------------------------------------------------------- +qreal VPiece::GlobalPassmarkWidth(const VContainer *data) const +{ + QString passmarkWidthVariable = VAbstractValApplication::VApp()->getCurrentDocument()->GetPassmarkWidthVariable(); + if (passmarkWidthVariable.isEmpty()) + { + return 0; + } + + qreal width = 0; + + try + { + QSharedPointer var = data->GetVariable(passmarkWidthVariable); + width = *var->GetValue(); + + if (VAbstractValApplication::VApp()->toPixel(width) <= accuracyPointOnLine) + { + const QString errorMsg = QObject::tr("Invalid global value for a passmark width. Piece '%1'. Width is " + "less than minimal allowed.") + .arg(GetName()); + VAbstractApplication::VApp()->IsPedantic() + ? throw VException(errorMsg) + : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; + } + } + catch (const VExceptionBadId &) + { + width = 0; + } + + return width; +} + //--------------------------------------------------------------------------------------------------------------------- #if !defined(V_NO_ASSERT) // Use for writing tests diff --git a/src/libs/vpatterndb/vpiece.h b/src/libs/vpatterndb/vpiece.h index abde4916d..52a772f09 100644 --- a/src/libs/vpatterndb/vpiece.h +++ b/src/libs/vpatterndb/vpiece.h @@ -173,6 +173,7 @@ private: auto DBToJson(const VContainer *data) const -> QJsonObject; auto GlobalPassmarkLength(const VContainer *data) const -> qreal; + auto GlobalPassmarkWidth(const VContainer *data) const -> qreal; void TestInternalPathCuttingPathIntersection(const VContainer *data) const; void TestInternalPathsIntersections(const VContainer *data) const; diff --git a/src/libs/vpatterndb/vpiecenode.cpp b/src/libs/vpatterndb/vpiecenode.cpp index 65545a509..55721da6e 100644 --- a/src/libs/vpatterndb/vpiecenode.cpp +++ b/src/libs/vpatterndb/vpiecenode.cpp @@ -317,14 +317,44 @@ void VPieceNode::SetFormulaPassmarkLength(const QString &formula) } } +//--------------------------------------------------------------------------------------------------------------------- +auto VPieceNode::GetFormulaPassmarkWidth() const -> QString +{ + return d->m_formulaPassmarkWidth; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetFormulaPassmarkWidth(const QString &formula) +{ + if (d->m_typeTool == Tool::NodePoint) + { + d->m_formulaPassmarkWidth = formula; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPieceNode::GetFormulaPassmarkAngle() const -> QString +{ + return d->m_formulaPassmarkAngle; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetFormulaPassmarkAngle(const QString &formula) +{ + if (d->m_typeTool == Tool::NodePoint) + { + d->m_formulaPassmarkAngle = formula; + } +} + //--------------------------------------------------------------------------------------------------------------------- auto VPieceNode::GetPassmarkLength(const VContainer *data, Unit unit) const -> qreal { if (d->m_manualPassmarkLength) { VFormula formula(d->m_formulaPassmarkLength, data); - formula.setCheckZero(false); - formula.setCheckLessThanZero(false); + formula.setCheckZero(true); + formula.setCheckLessThanZero(true); formula.Eval(); if (formula.error()) @@ -349,6 +379,74 @@ auto VPieceNode::GetPassmarkLength(const VContainer *data, Unit unit) const -> q return -1; } +//--------------------------------------------------------------------------------------------------------------------- +auto VPieceNode::GetPassmarkWidth(const VContainer *data, Unit unit) const -> qreal +{ + if (d->m_manualPassmarkWidth) + { + VFormula formula(d->m_formulaPassmarkWidth, data); + formula.setCheckZero(true); + formula.setCheckLessThanZero(false); + formula.Eval(); + + if (formula.error()) + { + QString nodeName; + try + { + nodeName = data->GetGObject(d->m_id)->name(); + } + catch (const VExceptionBadId &) + { + } + + const QString errorMsg = QObject::tr("Cannot calculate passmark width for point '%1'. Reason: %2.") + .arg(nodeName, formula.Reason()); + VAbstractApplication::VApp()->IsPedantic() + ? throw VException(errorMsg) + : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; + return 0; + } + + return ToPixel(formula.getDoubleValue(), unit); + } + return -1; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPieceNode::GetPassmarkAngle(const VContainer *data) const -> qreal +{ + if (d->m_manualPassmarkAngle) + { + VFormula formula(d->m_formulaPassmarkAngle, data); + formula.setCheckZero(false); + formula.setCheckLessThanZero(false); + formula.Eval(); + + if (formula.error()) + { + QString nodeName; + try + { + nodeName = data->GetGObject(d->m_id)->name(); + } + catch (const VExceptionBadId &) + { + } + + const QString errorMsg = QObject::tr("Cannot calculate passmark angle for point '%1'. Reason: %2.") + .arg(nodeName, formula.Reason()); + VAbstractApplication::VApp()->IsPedantic() + ? throw VException(errorMsg) + : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; + return 0; + } + + return formula.getDoubleValue(); + } + return 0; +} + //--------------------------------------------------------------------------------------------------------------------- auto VPieceNode::GetAngleType() const -> PieceNodeAngle { @@ -427,6 +525,18 @@ void VPieceNode::SetShowSecondPassmark(bool value) d->m_isShowSecondPassmark = value; } +//--------------------------------------------------------------------------------------------------------------------- +auto VPieceNode::IsPassmarkClockwiseOpening() const -> bool +{ + return d->m_isPassmarkClockwiseOpening; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetPassmarkClockwiseOpening(bool value) +{ + d->m_isPassmarkClockwiseOpening = value; +} + //--------------------------------------------------------------------------------------------------------------------- auto VPieceNode::IsCheckUniqueness() const -> bool { @@ -451,6 +561,30 @@ void VPieceNode::SetManualPassmarkLength(bool value) d->m_manualPassmarkLength = value; } +//--------------------------------------------------------------------------------------------------------------------- +auto VPieceNode::IsManualPassmarkWidth() const -> bool +{ + return d->m_manualPassmarkWidth; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetManualPassmarkWidth(bool value) +{ + d->m_manualPassmarkWidth = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto VPieceNode::IsManualPassmarkAngle() const -> bool +{ + return d->m_manualPassmarkAngle; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceNode::SetManualPassmarkAngle(bool value) +{ + d->m_manualPassmarkAngle = value; +} + //--------------------------------------------------------------------------------------------------------------------- auto VPieceNode::IsTurnPoint() const -> bool { diff --git a/src/libs/vpatterndb/vpiecenode.h b/src/libs/vpatterndb/vpiecenode.h index 5735e2aea..3db38b895 100644 --- a/src/libs/vpatterndb/vpiecenode.h +++ b/src/libs/vpatterndb/vpiecenode.h @@ -83,7 +83,15 @@ public: auto GetFormulaPassmarkLength() const -> QString; void SetFormulaPassmarkLength(const QString &formula); + auto GetFormulaPassmarkWidth() const -> QString; + void SetFormulaPassmarkWidth(const QString &formula); + + auto GetFormulaPassmarkAngle() const -> QString; + void SetFormulaPassmarkAngle(const QString &formula); + auto GetPassmarkLength(const VContainer *data, Unit unit) const -> qreal; + auto GetPassmarkWidth(const VContainer *data, Unit unit) const -> qreal; + auto GetPassmarkAngle(const VContainer *data) const -> qreal; auto GetAngleType() const -> PieceNodeAngle; void SetAngleType(PieceNodeAngle type); @@ -103,12 +111,21 @@ public: auto IsShowSecondPassmark() const -> bool; void SetShowSecondPassmark(bool value); + auto IsPassmarkClockwiseOpening() const -> bool; + void SetPassmarkClockwiseOpening(bool value); + auto IsCheckUniqueness() const -> bool; void SetCheckUniqueness(bool value); auto IsManualPassmarkLength() const -> bool; void SetManualPassmarkLength(bool value); + auto IsManualPassmarkWidth() const -> bool; + void SetManualPassmarkWidth(bool value); + + auto IsManualPassmarkAngle() const -> bool; + void SetManualPassmarkAngle(bool value); + auto IsTurnPoint() const -> bool; void SetTurnPoint(bool value); private: diff --git a/src/libs/vpatterndb/vpiecenode_p.h b/src/libs/vpatterndb/vpiecenode_p.h index 99652bc54..c66d06062 100644 --- a/src/libs/vpatterndb/vpiecenode_p.h +++ b/src/libs/vpatterndb/vpiecenode_p.h @@ -92,6 +92,8 @@ public: QString m_formulaWidthBefore{currentSeamAllowance}; // NOLINT(misc-non-private-member-variables-in-classes) QString m_formulaWidthAfter{currentSeamAllowance}; // NOLINT(misc-non-private-member-variables-in-classes) QString m_formulaPassmarkLength{}; // NOLINT(misc-non-private-member-variables-in-classes) + QString m_formulaPassmarkWidth{}; // NOLINT(misc-non-private-member-variables-in-classes) + QString m_formulaPassmarkAngle{}; // NOLINT(misc-non-private-member-variables-in-classes) PieceNodeAngle m_angleType{PieceNodeAngle::ByLength}; // NOLINT(misc-non-private-member-variables-in-classes) @@ -100,7 +102,8 @@ public: PassmarkAngleType m_passmarkAngleType{// NOLINT(misc-non-private-member-variables-in-classes) PassmarkAngleType::Straightforward}; - bool m_isShowSecondPassmark{true}; // NOLINT(misc-non-private-member-variables-in-classes) + bool m_isShowSecondPassmark{true}; // NOLINT(misc-non-private-member-variables-in-classes) + bool m_isPassmarkClockwiseOpening{false}; // NOLINT(misc-non-private-member-variables-in-classes) /** @brief m_checkUniqueness need in cases where different points have the same coordinates, become one point. * By default the check enabled. Disable it only if in a path cannot be used just one point. For example if @@ -108,6 +111,8 @@ public: bool m_checkUniqueness{true}; // NOLINT(misc-non-private-member-variables-in-classes) bool m_manualPassmarkLength{false}; // NOLINT(misc-non-private-member-variables-in-classes) + bool m_manualPassmarkWidth{false}; // NOLINT(misc-non-private-member-variables-in-classes) + bool m_manualPassmarkAngle{false}; // NOLINT(misc-non-private-member-variables-in-classes) bool m_turnPoint{true}; // NOLINT(misc-non-private-member-variables-in-classes) @@ -115,7 +120,7 @@ private: Q_DISABLE_ASSIGN_MOVE(VPieceNodeData) // NOLINT static constexpr quint32 streamHeader = 0x2198CBC8; // CRC-32Q string "VPieceNodeData" - static constexpr quint16 classVersion = 2; + static constexpr quint16 classVersion = 3; }; // See https://stackoverflow.com/a/46719572/3045403 @@ -133,7 +138,8 @@ inline auto operator<<(QDataStream &out, const VPieceNodeData &p) -> QDataStream out << p.m_id << p.m_typeTool << p.m_reverse << p.m_excluded << p.m_isPassmark << p.m_formulaWidthBefore << p.m_formulaWidthAfter << p.m_formulaPassmarkLength << p.m_angleType << p.m_passmarkLineType << p.m_passmarkAngleType << p.m_isShowSecondPassmark << p.m_checkUniqueness << p.m_manualPassmarkLength - << p.m_turnPoint; + << p.m_turnPoint << p.m_formulaPassmarkWidth << p.m_formulaPassmarkAngle << p.m_manualPassmarkWidth + << p.m_manualPassmarkAngle << p.m_isPassmarkClockwiseOpening; return out; } @@ -184,6 +190,12 @@ inline auto operator>>(QDataStream &in, VPieceNodeData &p) -> QDataStream & in >> p.m_turnPoint; } + if (actualClassVersion >= 3) + { + in >> p.m_formulaPassmarkWidth >> p.m_formulaPassmarkAngle >> p.m_manualPassmarkWidth >> + p.m_manualPassmarkAngle >> p.m_isPassmarkClockwiseOpening; + } + return in; } diff --git a/src/libs/vpatterndb/vpiecepath.cpp b/src/libs/vpatterndb/vpiecepath.cpp index 9caf186b0..23dbdc908 100644 --- a/src/libs/vpatterndb/vpiecepath.cpp +++ b/src/libs/vpatterndb/vpiecepath.cpp @@ -212,10 +212,8 @@ auto IntersectionWithCuttingContour(const QVector &cuttingPath, const Q *connection = first; return true; } - else - { - return VAbstractCurve::CurveIntersectAxis(first, FindTipDirection(points), cuttingPath, connection); - } + + return VAbstractCurve::CurveIntersectAxis(first, FindTipDirection(points), cuttingPath, connection); } //--------------------------------------------------------------------------------------------------------------------- @@ -1143,6 +1141,11 @@ auto VPiecePath::PreparePointEkv(const VPieceNode &node, const VContainer *data) p.SetAngleType(node.GetAngleType()); p.SetManualPasskmarkLength(node.IsManualPassmarkLength()); p.SetPasskmarkLength(node.GetPassmarkLength(data, *data->GetPatternUnit())); + p.SetManualPasskmarkWidth(node.IsManualPassmarkWidth()); + p.SetPasskmarkWidth(node.GetPassmarkWidth(data, *data->GetPatternUnit())); + p.SetManualPasskmarkAngle(node.IsManualPassmarkAngle()); + p.SetPasskmarkAngle(node.GetPassmarkAngle(data)); + p.SetPassmarkClockwiseOpening(node.IsPassmarkClockwiseOpening()); return p; } diff --git a/src/libs/vtest/abstracttest.cpp b/src/libs/vtest/abstracttest.cpp index c6e123bf3..ed0bfd404 100644 --- a/src/libs/vtest/abstracttest.cpp +++ b/src/libs/vtest/abstracttest.cpp @@ -207,6 +207,11 @@ void AbstractTest::PassmarkDataFromJson(const QString &json, VPiecePassmarkData AbstractTest::ReadDoubleValue(passmarkData, QStringLiteral("globalPassmarkLength"), globalPassmarkLength, QString::number(NULL_ID)); data.globalPassmarkLength = globalPassmarkLength; + + qreal globalPassmarkWidth; + AbstractTest::ReadDoubleValue(passmarkData, QStringLiteral("globalPassmarkWidth"), globalPassmarkWidth, + QString::number(NULL_ID)); + data.globalPassmarkWidth = globalPassmarkWidth; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtest/abstracttest.h b/src/libs/vtest/abstracttest.h index d4215ef8d..65204b65a 100644 --- a/src/libs/vtest/abstracttest.h +++ b/src/libs/vtest/abstracttest.h @@ -310,6 +310,50 @@ inline auto AbstractTest::PointFromJson(const QJsonObject &pointObject, VSAPoint AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("angle"), angleType, QString::number(static_cast(PieceNodeAngle::ByLength))); point.SetAngleType(angleType); + + bool manualPassmarkLength = false; + AbstractTest::ReadBooleanValue(pointObject, QLatin1String("manualPassmarkLength"), manualPassmarkLength, + QStringLiteral("0")); + point.SetManualPasskmarkLength(manualPassmarkLength); + + if (manualPassmarkLength) + { + qreal passmarkLength = 0; + AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("passmarkLength"), passmarkLength, + QStringLiteral("0")); + point.SetPasskmarkLength(passmarkLength); + } + + bool manualPassmarkWidth = false; + AbstractTest::ReadBooleanValue(pointObject, QLatin1String("manualPassmarkWidth"), manualPassmarkWidth, + QStringLiteral("0")); + point.SetManualPasskmarkWidth(manualPassmarkWidth); + + if (manualPassmarkWidth) + { + qreal passmarkWidth = 0; + AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("passmarkWidth"), passmarkWidth, QStringLiteral("0")); + point.SetPasskmarkWidth(passmarkWidth); + } + else + { + bool passmarkClockwiseOpening = false; + AbstractTest::ReadBooleanValue(pointObject, QLatin1String("passmarkClockwiseOpening"), passmarkClockwiseOpening, + QStringLiteral("0")); + point.SetPassmarkClockwiseOpening(passmarkClockwiseOpening); + } + + bool manualPassmarkAngle = false; + AbstractTest::ReadBooleanValue(pointObject, QLatin1String("manualPassmarkAngle"), manualPassmarkAngle, + QStringLiteral("0")); + point.SetManualPasskmarkAngle(manualPassmarkAngle); + + if (manualPassmarkAngle) + { + qreal passmarkAngle = 0; + AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("passmarkAngle"), passmarkAngle, QStringLiteral("0")); + point.SetPasskmarkAngle(passmarkAngle); + } } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/dialogs/dialogtoolbox.cpp b/src/libs/vtools/dialogs/dialogtoolbox.cpp index 9556d56f7..2f5e409f1 100644 --- a/src/libs/vtools/dialogs/dialogtoolbox.cpp +++ b/src/libs/vtools/dialogs/dialogtoolbox.cpp @@ -180,7 +180,7 @@ auto RowNode(QListWidget *listWidget, int i) -> VPieceNode if (i < 0 || i >= listWidget->count()) { - return VPieceNode(); + return {}; } const QListWidgetItem *rowItem = listWidget->item(i); @@ -651,10 +651,10 @@ auto GetNodeName(const VContainer *data, const VPieceNode &node, bool showPassma case PassmarkLineType::TMark: name += QStringLiteral("â”´"); break; - case PassmarkLineType::VMark: + case PassmarkLineType::ExternalVMark: name += QStringLiteral("⊼"); break; - case PassmarkLineType::VMark2: + case PassmarkLineType::InternalVMark: name += QStringLiteral("⊽"); break; case PassmarkLineType::UMark: @@ -663,6 +663,9 @@ auto GetNodeName(const VContainer *data, const VPieceNode &node, bool showPassma case PassmarkLineType::BoxMark: name += QStringLiteral("⎕"); break; + case PassmarkLineType::CheckMark: + name += QStringLiteral("✓"); + break; default: break; } diff --git a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp index 6fd24ec30..db8ca0ec2 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp +++ b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp @@ -34,10 +34,17 @@ #include "../../../tools/vtoolseamallowance.h" #include "../../support/dialogeditwrongformula.h" #include "../vmisc/vmodifierkey.h" + #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) #include "../vmisc/backport/qoverload.h" #endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0) +#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0) +#include "../vmisc/backport/qscopeguard.h" +#else +#include +#endif + #include #include @@ -64,7 +71,9 @@ DialogPiecePath::DialogPiecePath(const VContainer *data, quint32 toolId, QWidget m_timerWidthBefore(new QTimer(this)), m_timerWidthAfter(new QTimer(this)), m_timerVisible(new QTimer(this)), - m_timerPassmarkLength(new QTimer(this)) + m_timerPassmarkLength(new QTimer(this)), + m_timerPassmarkWidth(new QTimer(this)), + m_timerPassmarkAngle(new QTimer(this)) { ui->setupUi(this); InitOkCancel(ui); @@ -265,7 +274,7 @@ void DialogPiecePath::CheckState() } const int tabPassmarksIndex = ui->tabWidget->indexOf(ui->tabPassmarks); - if (m_flagFormulaPassmarkLength) + if (m_flagFormulaPassmarkLength && m_flagFormulaPassmarkWidth && m_flagFormulaPassmarkAngle) { ui->tabWidget->setTabIcon(tabPassmarksIndex, QIcon()); } @@ -276,7 +285,8 @@ void DialogPiecePath::CheckState() ui->tabWidget->setTabIcon(tabPassmarksIndex, icon); } - ui->comboBoxPassmarks->setEnabled(m_flagFormulaPassmarkLength); + ui->comboBoxPassmarks->setEnabled(m_flagFormulaPassmarkLength && m_flagFormulaPassmarkWidth && + m_flagFormulaPassmarkAngle); } //--------------------------------------------------------------------------------------------------------------------- @@ -516,134 +526,72 @@ void DialogPiecePath::PassmarkChanged(int index) ui->groupBoxMarkType->setDisabled(true); ui->groupBoxAngleType->setDisabled(true); ui->groupBoxManualLength->setDisabled(true); + ui->groupBoxManualWidth->setDisabled(true); + ui->groupBoxManualAngle->setDisabled(true); + ui->labelEditPassmarkLength->setDisabled(true); + ui->labelEditPassmarkWidth->setDisabled(true); + ui->labelEditPassmarkAngle->setDisabled(true); + + ui->checkBoxClockwiseOpening->setDisabled(true); ui->checkBoxShowSecondPassmark->setDisabled(true); + + ui->checkBoxClockwiseOpening->blockSignals(true); ui->checkBoxShowSecondPassmark->blockSignals(true); ui->groupBoxManualLength->blockSignals(true); + ui->groupBoxManualWidth->blockSignals(true); + ui->groupBoxManualAngle->blockSignals(true); ui->groupBoxMarkType->blockSignals(true); ui->groupBoxAngleType->blockSignals(true); + ui->checkBoxClockwiseOpening->setChecked(false); + ui->groupBoxManualLength->setChecked(false); + ui->groupBoxManualWidth->setChecked(false); + ui->groupBoxManualAngle->setChecked(false); - if (index != -1) - { - const VPiecePath path = CreatePath(); - const int nodeIndex = path.indexOfNode(ui->comboBoxPassmarks->currentData().toUInt()); - if (nodeIndex != -1) + auto EnableSignals = qScopeGuard( + [this] { - const VPieceNode &node = path.at(nodeIndex); + ui->checkBoxClockwiseOpening->blockSignals(false); + ui->checkBoxShowSecondPassmark->blockSignals(false); + ui->groupBoxManualLength->blockSignals(false); + ui->groupBoxManualWidth->blockSignals(false); + ui->groupBoxManualAngle->blockSignals(false); + ui->groupBoxMarkType->blockSignals(false); + ui->groupBoxAngleType->blockSignals(false); + }); - // Passmark length - ui->groupBoxManualLength->setEnabled(true); - - if (node.IsManualPassmarkLength()) - { - ui->groupBoxManualLength->setChecked(true); - - QString passmarkLength = node.GetFormulaPassmarkLength(); - passmarkLength = VAbstractApplication::VApp()->TrVars() - ->FormulaToUser(passmarkLength, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); - if (passmarkLength.length() > 80)// increase height if needed. - { - this->DeployPassmarkLength(); - } - - if (passmarkLength.isEmpty()) - { - qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); - ui->plainTextEditPassmarkLength->setPlainText(VAbstractApplication::VApp()->LocaleToString(length)); - } - else - { - ui->plainTextEditPassmarkLength->setPlainText(passmarkLength); - } - } - else - { - qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); - ui->plainTextEditPassmarkLength->setPlainText(VAbstractApplication::VApp()->LocaleToString(length)); - } - - MoveCursorToEnd(ui->plainTextEditPassmarkLength); - - // Line type - ui->groupBoxMarkType->setEnabled(true); - - switch(node.GetPassmarkLineType()) - { - case PassmarkLineType::OneLine: - ui->radioButtonOneLine->setChecked(true); - break; - case PassmarkLineType::TwoLines: - ui->radioButtonTwoLines->setChecked(true); - break; - case PassmarkLineType::ThreeLines: - ui->radioButtonThreeLines->setChecked(true); - break; - case PassmarkLineType::TMark: - ui->radioButtonTMark->setChecked(true); - break; - case PassmarkLineType::VMark: - ui->radioButtonVMark->setChecked(true); - break; - case PassmarkLineType::VMark2: - ui->radioButtonVMark2->setChecked(true); - break; - case PassmarkLineType::UMark: - ui->radioButtonUMark->setChecked(true); - break; - case PassmarkLineType::BoxMark: - ui->radioButtonBoxMark->setChecked(true); - break; - default: - break; - } - - // Angle type - ui->groupBoxAngleType->setEnabled(true); - - switch(node.GetPassmarkAngleType()) - { - case PassmarkAngleType::Straightforward: - ui->radioButtonStraightforward->setChecked(true); - break; - case PassmarkAngleType::Bisector: - ui->radioButtonBisector->setChecked(true); - break; - case PassmarkAngleType::Intersection: - ui->radioButtonIntersection->setChecked(true); - break; - case PassmarkAngleType::IntersectionOnlyLeft: - ui->radioButtonIntersectionOnlyLeft->setChecked(true); - break; - case PassmarkAngleType::IntersectionOnlyRight: - ui->radioButtonIntersectionOnlyRight->setChecked(true); - break; - case PassmarkAngleType::Intersection2: - ui->radioButtonIntersection2->setChecked(true); - break; - case PassmarkAngleType::Intersection2OnlyLeft: - ui->radioButtonIntersection2OnlyLeft->setChecked(true); - break; - case PassmarkAngleType::Intersection2OnlyRight: - ui->radioButtonIntersection2OnlyRight->setChecked(true); - break; - default: - break; - } - - // Show the second option - ui->checkBoxShowSecondPassmark->setEnabled(true); - ui->checkBoxShowSecondPassmark->setChecked(node.IsShowSecondPassmark()); - } + if (index == -1) + { + return; } - ui->checkBoxShowSecondPassmark->blockSignals(false); + const VPiecePath path = CreatePath(); + const int nodeIndex = path.indexOfNode(ui->comboBoxPassmarks->currentData().toUInt()); + if (nodeIndex == -1) + { + return; + } - ui->groupBoxManualLength->blockSignals(false); - ui->groupBoxMarkType->blockSignals(false); - ui->groupBoxAngleType->blockSignals(false); + const VPieceNode &node = path.at(nodeIndex); + + InitPassmarkLengthFormula(node); + InitPassmarkWidthFormula(node); + InitPassmarkAngleFormula(node); + InitPassmarkShapeType(node); + InitPassmarkAngleType(node); + + if (node.GetPassmarkLineType() == PassmarkLineType::CheckMark) + { + ui->checkBoxClockwiseOpening->setEnabled(true); + ui->checkBoxClockwiseOpening->setChecked(node.IsPassmarkClockwiseOpening()); + } + + // Show the second option + ui->checkBoxShowSecondPassmark->setEnabled(true); + ui->checkBoxShowSecondPassmark->setChecked(node.IsShowSecondPassmark()); } //--------------------------------------------------------------------------------------------------------------------- @@ -700,11 +648,11 @@ void DialogPiecePath::PassmarkLineTypeChanged(int id) } else if (id == ui->buttonGroupMarkType->id(ui->radioButtonVMark)) { - lineType = PassmarkLineType::VMark; + lineType = PassmarkLineType::ExternalVMark; } else if (id == ui->buttonGroupMarkType->id(ui->radioButtonVMark2)) { - lineType = PassmarkLineType::VMark2; + lineType = PassmarkLineType::InternalVMark; } else if (id == ui->buttonGroupMarkType->id(ui->radioButtonUMark)) { @@ -714,6 +662,10 @@ void DialogPiecePath::PassmarkLineTypeChanged(int id) { lineType = PassmarkLineType::BoxMark; } + else if (id == ui->buttonGroupMarkType->id(ui->radioButtonCheckMark)) + { + lineType = PassmarkLineType::CheckMark; + } rowNode.SetPassmarkLineType(lineType); rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); @@ -796,6 +748,24 @@ void DialogPiecePath::PassmarkShowSecondChanged(int state) } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::PassmarkClockwiseOrientationChanged(int state) +{ + const int i = ui->comboBoxPassmarks->currentIndex(); + if (i != -1) + { + QListWidgetItem *rowItem = GetItemById(ui->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetPassmarkClockwiseOpening(state); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + ListChanged(); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::EvalWidth() { @@ -913,19 +883,94 @@ void DialogPiecePath::EvalVisible() //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::EvalPassmarkLength() { - FormulaData formulaData; - formulaData.formula = ui->plainTextEditPassmarkLength->toPlainText(); - formulaData.variables = data->DataVariables(); - formulaData.labelEditFormula = ui->labelEditPassmarkLength; - formulaData.labelResult = ui->labelResultPassmarkLength; - formulaData.postfix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true); - formulaData.checkZero = false; - formulaData.checkLessThanZero = false; + if (ui->groupBoxManualLength->isChecked()) + { + if (ui->comboBoxPassmarks->count() > 0) + { + FormulaData formulaData; + formulaData.formula = ui->plainTextEditPassmarkLength->toPlainText(); + formulaData.variables = data->DataVariables(); + formulaData.labelEditFormula = ui->labelEditPassmarkLength; + formulaData.labelResult = ui->labelResultPassmarkLength; + formulaData.postfix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true); + formulaData.checkZero = true; + formulaData.checkLessThanZero = true; - Eval(formulaData, m_flagFormulaPassmarkLength); + Eval(formulaData, m_flagFormulaPassmarkLength); - UpdateNodePassmarkLength(VTranslateVars::TryFormulaFromUser( - ui->plainTextEditPassmarkLength->toPlainText(), VAbstractApplication::VApp()->Settings()->GetOsSeparator())); + UpdateNodePassmarkLength( + VTranslateVars::TryFormulaFromUser(ui->plainTextEditPassmarkLength->toPlainText(), + VAbstractApplication::VApp()->Settings()->GetOsSeparator())); + } + else + { + ChangeColor(ui->labelEditPassmarkLength, OkColor(this)); + ui->labelResultPassmarkLength->setText(tr("")); + m_flagFormulaPassmarkLength = true; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EvalPassmarkWidth() +{ + if (ui->groupBoxManualWidth->isChecked()) + { + if (ui->comboBoxPassmarks->count() > 0) + { + FormulaData formulaData; + formulaData.formula = ui->plainTextEditPassmarkWidth->toPlainText(); + formulaData.variables = data->DataVariables(); + formulaData.labelEditFormula = ui->labelEditPassmarkWidth; + formulaData.labelResult = ui->labelResultPassmarkWidth; + formulaData.postfix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true); + formulaData.checkZero = true; + formulaData.checkLessThanZero = false; + + Eval(formulaData, m_flagFormulaPassmarkWidth); + + UpdateNodePassmarkWidth( + VTranslateVars::TryFormulaFromUser(ui->plainTextEditPassmarkWidth->toPlainText(), + VAbstractApplication::VApp()->Settings()->GetOsSeparator())); + } + else + { + ChangeColor(ui->labelEditPassmarkWidth, OkColor(this)); + ui->labelResultPassmarkWidth->setText(tr("")); + m_flagFormulaPassmarkWidth = true; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EvalPassmarkAngle() +{ + if (ui->groupBoxManualWidth->isChecked()) + { + if (ui->comboBoxPassmarks->count() > 0) + { + FormulaData formulaData; + formulaData.formula = ui->plainTextEditPassmarkAngle->toPlainText(); + formulaData.variables = data->DataVariables(); + formulaData.labelEditFormula = ui->labelEditPassmarkAngle; + formulaData.labelResult = ui->labelResultPassmarkAngle; + formulaData.postfix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true); + formulaData.checkZero = false; + formulaData.checkLessThanZero = false; + + Eval(formulaData, m_flagFormulaPassmarkAngle); + + UpdateNodePassmarkAngle( + VTranslateVars::TryFormulaFromUser(ui->plainTextEditPassmarkAngle->toPlainText(), + VAbstractApplication::VApp()->Settings()->GetOsSeparator())); + } + else + { + ChangeColor(ui->labelEditPassmarkAngle, OkColor(this)); + ui->labelResultPassmarkAngle->setText(tr("")); + m_flagFormulaPassmarkAngle = true; + } + } } //--------------------------------------------------------------------------------------------------------------------- @@ -995,6 +1040,32 @@ void DialogPiecePath::FXPassmarkLength() } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::FXPassmarkWidth() +{ + QScopedPointer dialog(new DialogEditWrongFormula(data, toolId, this)); + dialog->setWindowTitle(tr("Edit passmark width")); + dialog->SetFormula(GetFormulaPassmarkWidth()); + dialog->setPostfix(UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetFormulaPassmarkWidth(dialog->GetFormula()); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::FXPassmarkAngle() +{ + QScopedPointer dialog(new DialogEditWrongFormula(data, toolId, this)); + dialog->setWindowTitle(tr("Edit passmark angle")); + dialog->SetFormula(GetFormulaPassmarkAngle()); + dialog->setPostfix(UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetFormulaPassmarkAngle(dialog->GetFormula()); + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::DeployWidthFormulaTextEdit() { @@ -1025,6 +1096,18 @@ void DialogPiecePath::DeployPassmarkLength() DeployFormula(this, ui->plainTextEditPassmarkLength, ui->pushButtonGrowPassmarkLength, m_formulaBasePassmarkLength); } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::DeployPassmarkWidth() +{ + DeployFormula(this, ui->plainTextEditPassmarkWidth, ui->pushButtonGrowPassmarkWidth, m_formulaBasePassmarkWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::DeployPassmarkAngle() +{ + DeployFormula(this, ui->plainTextEditPassmarkAngle, ui->pushButtonGrowPassmarkAngle, m_formulaBasePassmarkAngle); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::SetMoveControls() { @@ -1171,14 +1254,43 @@ void DialogPiecePath::InitSeamAllowanceTab() //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::InitPassmarksTab() { + // Length formula this->m_formulaBasePassmarkLength = ui->plainTextEditPassmarkLength->height(); ui->plainTextEditPassmarkLength->installEventFilter(this); - m_timerPassmarkLength->setSingleShot(true); + connect(m_timerPassmarkLength, &QTimer::timeout, this, &DialogPiecePath::EvalPassmarkLength); - connect(ui->groupBoxManualLength, &QGroupBox::toggled, this, &DialogPiecePath::EnabledManualPassmarkLength); + connect(ui->toolButtonExprLength, &QPushButton::clicked, this, &DialogPiecePath::FXPassmarkLength); + connect(ui->plainTextEditPassmarkLength, &QPlainTextEdit::textChanged, this, + [this]() { m_timerPassmarkLength->start(formulaTimerTimeout); }); + connect(ui->pushButtonGrowPassmarkLength, &QPushButton::clicked, this, &DialogPiecePath::DeployPassmarkLength); + // Width formula + this->m_formulaBasePassmarkWidth = ui->plainTextEditPassmarkWidth->height(); + ui->plainTextEditPassmarkWidth->installEventFilter(this); + m_timerPassmarkWidth->setSingleShot(true); + + connect(m_timerPassmarkWidth, &QTimer::timeout, this, &DialogPiecePath::EvalPassmarkWidth); + connect(ui->groupBoxManualWidth, &QGroupBox::toggled, this, &DialogPiecePath::EnabledManualPassmarkWidth); + connect(ui->toolButtonExprWidth, &QPushButton::clicked, this, &DialogPiecePath::FXPassmarkWidth); + connect(ui->plainTextEditPassmarkWidth, &QPlainTextEdit::textChanged, this, + [this]() { m_timerPassmarkWidth->start(formulaTimerTimeout); }); + connect(ui->pushButtonGrowPassmarkWidth, &QPushButton::clicked, this, &DialogPiecePath::DeployPassmarkWidth); + + // Angle formula + this->m_formulaBasePassmarkAngle = ui->plainTextEditPassmarkAngle->height(); + ui->plainTextEditPassmarkAngle->installEventFilter(this); + m_timerPassmarkAngle->setSingleShot(true); + + connect(m_timerPassmarkAngle, &QTimer::timeout, this, &DialogPiecePath::EvalPassmarkAngle); + connect(ui->groupBoxManualAngle, &QGroupBox::toggled, this, &DialogPiecePath::EnabledManualPassmarkAngle); + connect(ui->toolButtonExprAngle, &QPushButton::clicked, this, &DialogPiecePath::FXPassmarkAngle); + connect(ui->plainTextEditPassmarkAngle, &QPlainTextEdit::textChanged, this, + [this]() { m_timerPassmarkAngle->start(formulaTimerTimeout); }); + connect(ui->pushButtonGrowPassmarkAngle, &QPushButton::clicked, this, &DialogPiecePath::DeployPassmarkAngle); + + // notch list InitPassmarksList(); connect(ui->comboBoxPassmarks, QOverload::of(&QComboBox::currentIndexChanged), this, &DialogPiecePath::PassmarkChanged); @@ -1195,14 +1307,8 @@ void DialogPiecePath::InitPassmarksTab() connect(ui->checkBoxShowSecondPassmark, &QCheckBox::stateChanged, this, &DialogPiecePath::PassmarkShowSecondChanged); - connect(ui->toolButtonExprLength, &QPushButton::clicked, this, &DialogPiecePath::FXPassmarkLength); - - connect(ui->plainTextEditPassmarkLength, &QPlainTextEdit::textChanged, this, [this]() - { - m_timerPassmarkLength->start(formulaTimerTimeout); - }); - - connect(ui->pushButtonGrowPassmarkLength, &QPushButton::clicked, this, &DialogPiecePath::DeployPassmarkLength); + connect(ui->checkBoxClockwiseOpening, &QCheckBox::stateChanged, this, + &DialogPiecePath::PassmarkClockwiseOrientationChanged); } //--------------------------------------------------------------------------------------------------------------------- @@ -1501,6 +1607,38 @@ void DialogPiecePath::UpdateNodePassmarkLength(const QString &formula) } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::UpdateNodePassmarkWidth(const QString &formula) +{ + const int index = ui->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(ui->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaPassmarkWidth(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::UpdateNodePassmarkAngle(const QString &formula) +{ + const int index = ui->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(ui->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaPassmarkAngle(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::EnabledManualPassmarkLength() { @@ -1513,11 +1651,66 @@ void DialogPiecePath::EnabledManualPassmarkLength() auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); rowNode.SetManualPassmarkLength(ui->groupBoxManualLength->isChecked()); rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + ui->toolButtonExprLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->plainTextEditPassmarkLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->pushButtonGrowPassmarkLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->labelEditPassmarkLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->label_8->setEnabled(ui->groupBoxManualLength->isChecked()); + EvalPassmarkLength(); } } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EnabledManualPassmarkWidth() +{ + const int index = ui->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(ui->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetManualPassmarkWidth(ui->groupBoxManualWidth->isChecked()); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + ui->toolButtonExprWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->plainTextEditPassmarkWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->pushButtonGrowPassmarkWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->labelEditPassmarkWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->label_4->setEnabled(ui->groupBoxManualWidth->isChecked()); + + EvalPassmarkWidth(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::EnabledManualPassmarkAngle() +{ + const int index = ui->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(ui->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetManualPassmarkAngle(ui->groupBoxManualAngle->isChecked()); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + ui->toolButtonExprAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->plainTextEditPassmarkAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->pushButtonGrowPassmarkAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->labelEditPassmarkAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->label_7->setEnabled(ui->groupBoxManualAngle->isChecked()); + + EvalPassmarkAngle(); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::SetFormulaSAWidth(const QString &formula) { @@ -1754,6 +1947,48 @@ void DialogPiecePath::SetFormulaPassmarkLength(const QString &formula) MoveCursorToEnd(ui->plainTextEditPassmarkLength); } +//--------------------------------------------------------------------------------------------------------------------- +auto DialogPiecePath::GetFormulaPassmarkWidth() const -> QString +{ + QString formula = ui->plainTextEditPassmarkWidth->toPlainText(); + return VTranslateVars::TryFormulaFromUser(formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetFormulaPassmarkWidth(const QString &formula) +{ + const QString f = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + // increase height if needed. + if (f.length() > 80) + { + this->DeployPassmarkWidth(); + } + ui->plainTextEditPassmarkWidth->setPlainText(f); + MoveCursorToEnd(ui->plainTextEditPassmarkWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +auto DialogPiecePath::GetFormulaPassmarkAngle() const -> QString +{ + QString formula = ui->plainTextEditPassmarkWidth->toPlainText(); + return VTranslateVars::TryFormulaFromUser(formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::SetFormulaPassmarkAngle(const QString &formula) +{ + const QString f = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + // increase height if needed. + if (f.length() > 80) + { + this->DeployPassmarkAngle(); + } + ui->plainTextEditPassmarkAngle->setPlainText(f); + MoveCursorToEnd(ui->plainTextEditPassmarkAngle); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPiecePath::RefreshPathList(const VPiecePath &path) { @@ -1765,3 +2000,218 @@ void DialogPiecePath::RefreshPathList(const VPiecePath &path) } ui->listWidget->blockSignals(false); } + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitPassmarkLengthFormula(const VPieceNode &node) +{ + // notch depth + ui->groupBoxManualLength->setEnabled(true); + + if (node.IsManualPassmarkLength()) + { + ui->groupBoxManualLength->setChecked(true); + + ui->toolButtonExprLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->plainTextEditPassmarkLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->pushButtonGrowPassmarkLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->labelEditPassmarkLength->setEnabled(ui->groupBoxManualLength->isChecked()); + ui->label_8->setEnabled(ui->groupBoxManualLength->isChecked()); + + QString passmarkLength = node.GetFormulaPassmarkLength(); + passmarkLength = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + passmarkLength, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + if (passmarkLength.length() > 80) // increase height if needed. + { + this->DeployPassmarkLength(); + } + + if (passmarkLength.isEmpty()) + { + qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + ui->plainTextEditPassmarkLength->setPlainText(VAbstractApplication::VApp()->LocaleToString(length)); + } + else + { + ui->plainTextEditPassmarkLength->setPlainText(passmarkLength); + } + } + else + { + qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + ui->plainTextEditPassmarkLength->setPlainText(VAbstractApplication::VApp()->LocaleToString(length)); + } + + MoveCursorToEnd(ui->plainTextEditPassmarkLength); + ChangeColor(ui->labelEditPassmarkLength, OkColor(this)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitPassmarkWidthFormula(const VPieceNode &node) +{ + // notch width + if (node.GetPassmarkLineType() != PassmarkLineType::OneLine) + { + ui->groupBoxManualWidth->setEnabled(true); + + if (node.IsManualPassmarkWidth()) + { + ui->groupBoxManualWidth->setChecked(true); + + ui->toolButtonExprWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->plainTextEditPassmarkWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->pushButtonGrowPassmarkWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->labelEditPassmarkWidth->setEnabled(ui->groupBoxManualWidth->isChecked()); + ui->label_4->setEnabled(ui->groupBoxManualWidth->isChecked()); + + QString passmarkWidth = node.GetFormulaPassmarkWidth(); + passmarkWidth = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + passmarkWidth, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + if (passmarkWidth.length() > 80) // increase height if needed. + { + this->DeployPassmarkWidth(); + } + + if (passmarkWidth.isEmpty()) + { + qreal width = UnitConvertor(0.85, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + ui->plainTextEditPassmarkWidth->setPlainText(VAbstractApplication::VApp()->LocaleToString(width)); + } + else + { + ui->plainTextEditPassmarkWidth->setPlainText(passmarkWidth); + } + } + else + { + qreal width = UnitConvertor(0.85, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + ui->plainTextEditPassmarkWidth->setPlainText(VAbstractApplication::VApp()->LocaleToString(width)); + } + + MoveCursorToEnd(ui->plainTextEditPassmarkWidth); + } + else + { + qreal width = UnitConvertor(0.85, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + ui->plainTextEditPassmarkWidth->setPlainText(VAbstractApplication::VApp()->LocaleToString(width)); + } + ChangeColor(ui->labelEditPassmarkWidth, OkColor(this)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitPassmarkAngleFormula(const VPieceNode &node) +{ + // notch angle + if (node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward) + { + ui->groupBoxManualAngle->setEnabled(true); + + if (node.IsManualPassmarkAngle()) + { + ui->groupBoxManualAngle->setChecked(true); + + ui->toolButtonExprAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->plainTextEditPassmarkAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->pushButtonGrowPassmarkAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->labelEditPassmarkAngle->setEnabled(ui->groupBoxManualAngle->isChecked()); + ui->label_7->setEnabled(ui->groupBoxManualAngle->isChecked()); + + QString passmarkAngle = node.GetFormulaPassmarkLength(); + passmarkAngle = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + passmarkAngle, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + if (passmarkAngle.length() > 80) // increase height if needed. + { + this->DeployPassmarkAngle(); + } + + ui->plainTextEditPassmarkAngle->setPlainText(passmarkAngle.isEmpty() ? QString::number(0) : passmarkAngle); + } + else + { + ui->plainTextEditPassmarkAngle->setPlainText(QString::number(0)); + } + + MoveCursorToEnd(ui->plainTextEditPassmarkAngle); + } + else + { + ui->plainTextEditPassmarkAngle->setPlainText(QString::number(0)); + } + ChangeColor(ui->labelEditPassmarkAngle, OkColor(this)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitPassmarkShapeType(const VPieceNode &node) +{ + // Line type + ui->groupBoxMarkType->setEnabled(true); + + switch (node.GetPassmarkLineType()) + { + case PassmarkLineType::OneLine: + ui->radioButtonOneLine->setChecked(true); + break; + case PassmarkLineType::TwoLines: + ui->radioButtonTwoLines->setChecked(true); + break; + case PassmarkLineType::ThreeLines: + ui->radioButtonThreeLines->setChecked(true); + break; + case PassmarkLineType::TMark: + ui->radioButtonTMark->setChecked(true); + break; + case PassmarkLineType::ExternalVMark: + ui->radioButtonVMark->setChecked(true); + break; + case PassmarkLineType::InternalVMark: + ui->radioButtonVMark2->setChecked(true); + break; + case PassmarkLineType::UMark: + ui->radioButtonUMark->setChecked(true); + break; + case PassmarkLineType::BoxMark: + ui->radioButtonBoxMark->setChecked(true); + break; + case PassmarkLineType::CheckMark: + ui->radioButtonCheckMark->setChecked(true); + break; + default: + break; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPiecePath::InitPassmarkAngleType(const VPieceNode &node) +{ + // Angle type + ui->groupBoxAngleType->setEnabled(true); + + switch (node.GetPassmarkAngleType()) + { + case PassmarkAngleType::Straightforward: + ui->radioButtonStraightforward->setChecked(true); + break; + case PassmarkAngleType::Bisector: + ui->radioButtonBisector->setChecked(true); + break; + case PassmarkAngleType::Intersection: + ui->radioButtonIntersection->setChecked(true); + break; + case PassmarkAngleType::IntersectionOnlyLeft: + ui->radioButtonIntersectionOnlyLeft->setChecked(true); + break; + case PassmarkAngleType::IntersectionOnlyRight: + ui->radioButtonIntersectionOnlyRight->setChecked(true); + break; + case PassmarkAngleType::Intersection2: + ui->radioButtonIntersection2->setChecked(true); + break; + case PassmarkAngleType::Intersection2OnlyLeft: + ui->radioButtonIntersection2OnlyLeft->setChecked(true); + break; + case PassmarkAngleType::Intersection2OnlyRight: + ui->radioButtonIntersection2OnlyRight->setChecked(true); + break; + default: + break; + } +} diff --git a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.h b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.h index fcc7279bb..f5325e5dd 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.h +++ b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.h @@ -78,24 +78,31 @@ private slots: void PassmarkLineTypeChanged(int id); void PassmarkAngleTypeChanged(int id); void PassmarkShowSecondChanged(int state); + void PassmarkClockwiseOrientationChanged(int state); void EvalWidth(); void EvalWidthBefore(); void EvalWidthAfter(); void EvalVisible(); void EvalPassmarkLength(); + void EvalPassmarkWidth(); + void EvalPassmarkAngle(); void FXWidth(); void FXWidthBefore(); void FXWidthAfter(); void FXVisible(); void FXPassmarkLength(); + void FXPassmarkWidth(); + void FXPassmarkAngle(); void DeployWidthFormulaTextEdit(); void DeployWidthBeforeFormulaTextEdit(); void DeployWidthAfterFormulaTextEdit(); void DeployVisibleFormulaTextEdit(); void DeployPassmarkLength(); + void DeployPassmarkWidth(); + void DeployPassmarkAngle(); void SetMoveControls(); @@ -110,17 +117,23 @@ private: QTimer *m_timerWidthAfter; QTimer *m_timerVisible; QTimer *m_timerPassmarkLength; + QTimer *m_timerPassmarkWidth; + QTimer *m_timerPassmarkAngle; int m_formulaBaseWidth{0}; int m_formulaBaseWidthBefore{0}; int m_formulaBaseWidthAfter{0}; int m_formulaBaseVisible{0}; int m_formulaBasePassmarkLength{0}; + int m_formulaBasePassmarkWidth{0}; + int m_formulaBasePassmarkAngle{0}; bool m_flagFormulaBefore{true}; bool m_flagFormulaAfter{true}; bool m_flagFormulaVisible{true}; bool m_flagFormulaPassmarkLength{true}; + bool m_flagFormulaPassmarkWidth{true}; + bool m_flagFormulaPassmarkAngle{true}; bool m_flagName{true}; // We have default name of piece. bool m_flagError{false}; bool m_flagFormula{false}; @@ -159,8 +172,12 @@ private: void UpdateNodeSABefore(const QString &formula); void UpdateNodeSAAfter(const QString &formula); void UpdateNodePassmarkLength(const QString &formula); + void UpdateNodePassmarkWidth(const QString &formula); + void UpdateNodePassmarkAngle(const QString &formula); void EnabledManualPassmarkLength(); + void EnabledManualPassmarkWidth(); + void EnabledManualPassmarkAngle(); auto GetFormulaSAWidthBefore() const -> QString; auto GetFormulaSAWidthAfter() const -> QString; @@ -171,9 +188,21 @@ private: auto GetFormulaPassmarkLength() const -> QString; void SetFormulaPassmarkLength(const QString &formula); + auto GetFormulaPassmarkWidth() const -> QString; + void SetFormulaPassmarkWidth(const QString &formula); + + auto GetFormulaPassmarkAngle() const -> QString; + void SetFormulaPassmarkAngle(const QString &formula); + auto IsShowNotch() const -> bool; void RefreshPathList(const VPiecePath &path); + + void InitPassmarkLengthFormula(const VPieceNode &node); + void InitPassmarkWidthFormula(const VPieceNode &node); + void InitPassmarkAngleFormula(const VPieceNode &node); + void InitPassmarkShapeType(const VPieceNode &node); + void InitPassmarkAngleType(const VPieceNode &node); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui index 189be3c2c..cc1933f45 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui +++ b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui @@ -6,8 +6,8 @@ 0 0 - 394 - 583 + 420 + 647 @@ -908,7 +908,7 @@ Passmarks - + @@ -927,481 +927,975 @@ - - - true + + + 0 - - Manual length - - - true - - - true - - - - - - - - - 0 - 0 - - - - - - - - - 255 - 0 - 0 - - - - - - - - - 255 - 0 - 0 - - - - - - - - - 159 - 158 - 158 - - - - - - - - Length: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - Formula wizard - - - f(x) - - - - :/icon/24x24/fx.png:/icon/24x24/fx.png - - - - 24 - 24 - - - - - - - - - 0 - 0 - - - - - 36 - true - - - - = - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 87 - 0 - - - - Value - - - - - - _ - - - - - - - - - - - true - - - - 0 - 0 - - - - - 16777215 - 28 - - - - Calculation - - - true - - - - - - - true - - - - 18 - 18 - - - - - 0 - 0 - - - - <html><head/><body><p>Show full calculation in message box</p></body></html> - - - - - - - ../../ - - - - 16 - 16 - - - - true - - - - - - + + + Type + + + + + + + + true + + + Marks + + + + + + true + + + One line + + + buttonGroupMarkType + + + + + + + true + + + Two lines + + + buttonGroupMarkType + + + + + + + true + + + Three lines + + + buttonGroupMarkType + + + + + + + true + + + T mark + + + buttonGroupMarkType + + + + + + + true + + + Acute angle that looks inside of piece + + + V mark + + + buttonGroupMarkType + + + + + + + true + + + Acute angle that looks outside of piece + + + V mark 2 + + + buttonGroupMarkType + + + + + + + U mark + + + buttonGroupMarkType + + + + + + + Box mark + + + buttonGroupMarkType + + + + + + + Check mark + + + buttonGroupMarkType + + + + + + + + + + true + + + Angle + + + + + + true + + + Straightforward + + + buttonGroupAngleType + + + + + + + true + + + Bisector + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark + + + Intersection + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only left passmark. + + + Intersection (only left) + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only right passmark. + + + Intersection (only right) + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark + + + Intersection 2 + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only left passmark. + + + Intersection 2 (only left) + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only right passmark. + + + Intersection 2 (only right) + + + buttonGroupAngleType + + + + + + + + + + + + false + + + Clockwise opening + + + + + + + + Manual shape + + + + + + true + + + Length + + + true + + + false + + + + + + + + false + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Length: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Formula wizard + + + f(x) + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + 36 + true + + + + = + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 87 + 0 + + + + Value + + + + + + _ + + + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../ + + + + 16 + 16 + + + + true + + + + + + + + + + + + false + + + Width + + + true + + + false + + + + + + + + false + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Width: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Formula wizard + + + f(x) + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + 36 + true + + + + = + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 87 + 0 + + + + Value + + + + + + _ + + + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../ + + + + 16 + 16 + + + + true + + + + + + + + + + + + true + + + Angle + + + true + + + false + + + + + + + + false + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Angle: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Formula wizard + + + f(x) + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + 36 + true + + + + = + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 87 + 0 + + + + Value + + + + + + _ + + + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../ + + + + 16 + 16 + + + + true + + + + + + + + + + - - - - - - true - - - Marks - - - - - - true - - - One line - - - buttonGroupMarkType - - - - - - - true - - - Two lines - - - buttonGroupMarkType - - - - - - - true - - - Three lines - - - buttonGroupMarkType - - - - - - - true - - - T mark - - - buttonGroupMarkType - - - - - - - true - - - Acute angle that looks inside of piece - - - V mark - - - buttonGroupMarkType - - - - - - - true - - - Acute angle that looks outside of piece - - - V mark 2 - - - buttonGroupMarkType - - - - - - - U mark - - - buttonGroupMarkType - - - - - - - Box mark - - - buttonGroupMarkType - - - - - - - - - - true - - - Angle - - - - - - true - - - Straightforward - - - buttonGroupAngleType - - - - - - - true - - - Bisector - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark - - - Intersection - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only left passmark. - - - Intersection (only left) - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only right passmark. - - - Intersection (only right) - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark - - - Intersection 2 - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only left passmark. - - - Intersection 2 (only left) - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only right passmark. - - - Intersection 2 (only right) - - - buttonGroupAngleType - - - - - - - - diff --git a/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp b/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp index 20c341c7a..4035462eb 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp +++ b/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp @@ -58,10 +58,17 @@ #include "ui_tabpaths.h" #include "ui_tabpins.h" #include "ui_tabplacelabels.h" + #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) #include "../vmisc/backport/qoverload.h" #endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0) +#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0) +#include "../vmisc/backport/qscopeguard.h" +#else +#include +#endif + #include #include #include @@ -145,6 +152,8 @@ DialogSeamAllowance::DialogSeamAllowance(const VContainer *data, quint32 toolId, m_timerWidthBefore(new QTimer(this)), m_timerWidthAfter(new QTimer(this)), m_timerPassmarkLength(new QTimer(this)), + m_timerPassmarkWidth(new QTimer(this)), + m_timerPassmarkAngle(new QTimer(this)), m_placeholdersMenu(new QMenu(this)) { ui->setupUi(this); @@ -581,17 +590,29 @@ void DialogSeamAllowance::CheckState() uiTabPaths->comboBoxNodes->setEnabled(flagFormulaBefore && flagFormulaAfter); - flagFormulaPassmarkLength = uiTabPassmarks->comboBoxPassmarks->count() == 0; - if (flagFormulaPassmarkLength) + if (uiTabPassmarks->comboBoxPassmarks->count() == 0) + { + flagFormulaPassmarkLength = true; + flagFormulaPassmarkWidth = true; + flagFormulaPassmarkAngle = true; + } + + if (flagFormulaPassmarkLength && flagFormulaPassmarkWidth && flagFormulaPassmarkAngle) { m_ftb->SetTabText(TabOrder::Passmarks, tr("Passmarks")); + uiTabPassmarks->tabWidget->setTabIcon(uiTabPassmarks->tabWidget->indexOf(uiTabPassmarks->tabManualShape), + QIcon()); } else { m_ftb->SetTabText(TabOrder::Passmarks, tr("Passmarks") + '*'); + const QIcon icon = QIcon::fromTheme(QStringLiteral("dialog-warning"), + QIcon(":/icons/win.icon.theme/16x16/status/dialog-warning.png")); + uiTabPassmarks->tabWidget->setTabIcon(uiTabPassmarks->tabWidget->indexOf(uiTabPassmarks->tabManualShape), icon); } - uiTabPassmarks->comboBoxPassmarks->setEnabled(flagFormulaPassmarkLength); + uiTabPassmarks->comboBoxPassmarks->setEnabled(flagFormulaPassmarkLength && flagFormulaPassmarkWidth && + flagFormulaPassmarkAngle); } //--------------------------------------------------------------------------------------------------------------------- @@ -1123,135 +1144,72 @@ void DialogSeamAllowance::PassmarkChanged(int index) uiTabPassmarks->groupBoxMarkType->setDisabled(true); uiTabPassmarks->groupBoxAngleType->setDisabled(true); uiTabPassmarks->groupBoxManualLength->setDisabled(true); + uiTabPassmarks->groupBoxManualWidth->setDisabled(true); + uiTabPassmarks->groupBoxManualAngle->setDisabled(true); + uiTabPassmarks->labelEditPassmarkLength->setDisabled(true); + uiTabPassmarks->labelEditPassmarkWidth->setDisabled(true); + uiTabPassmarks->labelEditPassmarkAngle->setDisabled(true); + + uiTabPassmarks->checkBoxClockwiseOpening->setDisabled(true); uiTabPassmarks->checkBoxShowSecondPassmark->setDisabled(true); + + uiTabPassmarks->checkBoxClockwiseOpening->blockSignals(true); uiTabPassmarks->checkBoxShowSecondPassmark->blockSignals(true); uiTabPassmarks->groupBoxManualLength->blockSignals(true); + uiTabPassmarks->groupBoxManualWidth->blockSignals(true); + uiTabPassmarks->groupBoxManualAngle->blockSignals(true); uiTabPassmarks->groupBoxMarkType->blockSignals(true); uiTabPassmarks->groupBoxAngleType->blockSignals(true); + uiTabPassmarks->checkBoxClockwiseOpening->setChecked(false); + uiTabPassmarks->groupBoxManualLength->setChecked(false); + uiTabPassmarks->groupBoxManualWidth->setChecked(false); + uiTabPassmarks->groupBoxManualAngle->setChecked(false); - if (index != -1) - { - const VPiece piece = CreatePiece(); - const int nodeIndex = piece.GetPath().indexOfNode(uiTabPassmarks->comboBoxPassmarks->currentData().toUInt()); - if (nodeIndex != -1) + auto EnableSignals = qScopeGuard( + [this] { - const VPieceNode &node = piece.GetPath().at(nodeIndex); + uiTabPassmarks->checkBoxClockwiseOpening->blockSignals(false); + uiTabPassmarks->checkBoxShowSecondPassmark->blockSignals(false); + uiTabPassmarks->groupBoxManualLength->blockSignals(false); + uiTabPassmarks->groupBoxManualWidth->blockSignals(false); + uiTabPassmarks->groupBoxManualAngle->blockSignals(false); + uiTabPassmarks->groupBoxMarkType->blockSignals(false); + uiTabPassmarks->groupBoxAngleType->blockSignals(false); + }); - // Passmark length - uiTabPassmarks->groupBoxManualLength->setEnabled(true); - - if (node.IsManualPassmarkLength()) - { - uiTabPassmarks->groupBoxManualLength->setChecked(true); - - QString passmarkLength = node.GetFormulaPassmarkLength(); - passmarkLength = VAbstractApplication::VApp()->TrVars() - ->FormulaToUser(passmarkLength, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); - if (passmarkLength.length() > 80)// increase height if needed. - { - this->DeployPassmarkLength(); - } - - if (passmarkLength.isEmpty()) - { - qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); - uiTabPassmarks->plainTextEditPassmarkLength->setPlainText( - VAbstractApplication::VApp()->LocaleToString(length)); - } - else - { - uiTabPassmarks->plainTextEditPassmarkLength->setPlainText(passmarkLength); - } - } - else - { - qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); - uiTabPassmarks->plainTextEditPassmarkLength->setPlainText( - VAbstractApplication::VApp()->LocaleToString(length)); - } - - MoveCursorToEnd(uiTabPassmarks->plainTextEditPassmarkLength); - - // Line type - uiTabPassmarks->groupBoxMarkType->setEnabled(true); - - switch(node.GetPassmarkLineType()) - { - case PassmarkLineType::OneLine: - uiTabPassmarks->radioButtonOneLine->setChecked(true); - break; - case PassmarkLineType::TwoLines: - uiTabPassmarks->radioButtonTwoLines->setChecked(true); - break; - case PassmarkLineType::ThreeLines: - uiTabPassmarks->radioButtonThreeLines->setChecked(true); - break; - case PassmarkLineType::TMark: - uiTabPassmarks->radioButtonTMark->setChecked(true); - break; - case PassmarkLineType::VMark: - uiTabPassmarks->radioButtonVMark->setChecked(true); - break; - case PassmarkLineType::VMark2: - uiTabPassmarks->radioButtonVMark2->setChecked(true); - break; - case PassmarkLineType::UMark: - uiTabPassmarks->radioButtonUMark->setChecked(true); - break; - case PassmarkLineType::BoxMark: - uiTabPassmarks->radioButtonBoxMark->setChecked(true); - break; - default: - break; - } - - // Angle type - uiTabPassmarks->groupBoxAngleType->setEnabled(true); - - switch(node.GetPassmarkAngleType()) - { - case PassmarkAngleType::Straightforward: - uiTabPassmarks->radioButtonStraightforward->setChecked(true); - break; - case PassmarkAngleType::Bisector: - uiTabPassmarks->radioButtonBisector->setChecked(true); - break; - case PassmarkAngleType::Intersection: - uiTabPassmarks->radioButtonIntersection->setChecked(true); - break; - case PassmarkAngleType::IntersectionOnlyLeft: - uiTabPassmarks->radioButtonIntersectionOnlyLeft->setChecked(true); - break; - case PassmarkAngleType::IntersectionOnlyRight: - uiTabPassmarks->radioButtonIntersectionOnlyRight->setChecked(true); - break; - case PassmarkAngleType::Intersection2: - uiTabPassmarks->radioButtonIntersection2->setChecked(true); - break; - case PassmarkAngleType::Intersection2OnlyLeft: - uiTabPassmarks->radioButtonIntersection2OnlyLeft->setChecked(true); - break; - case PassmarkAngleType::Intersection2OnlyRight: - uiTabPassmarks->radioButtonIntersection2OnlyRight->setChecked(true); - break; - default: - break; - } - - // Show the second option - uiTabPassmarks->checkBoxShowSecondPassmark->setEnabled(true); - uiTabPassmarks->checkBoxShowSecondPassmark->setChecked(node.IsShowSecondPassmark()); - } + if (index == -1) + { + return; } - uiTabPassmarks->checkBoxShowSecondPassmark->blockSignals(false); - uiTabPassmarks->groupBoxManualLength->blockSignals(false); - uiTabPassmarks->groupBoxMarkType->blockSignals(false); - uiTabPassmarks->groupBoxAngleType->blockSignals(false); + const VPiece piece = CreatePiece(); + const int nodeIndex = piece.GetPath().indexOfNode(uiTabPassmarks->comboBoxPassmarks->currentData().toUInt()); + if (nodeIndex == -1) + { + return; + } + + const VPieceNode &node = piece.GetPath().at(nodeIndex); + + InitPassmarkLengthFormula(node); + InitPassmarkWidthFormula(node); + InitPassmarkAngleFormula(node); + InitPassmarkShapeType(node); + InitPassmarkAngleType(node); + + if (node.GetPassmarkLineType() == PassmarkLineType::CheckMark) + { + uiTabPassmarks->checkBoxClockwiseOpening->setEnabled(true); + uiTabPassmarks->checkBoxClockwiseOpening->setChecked(node.IsPassmarkClockwiseOpening()); + } + + // Show the second option + uiTabPassmarks->checkBoxShowSecondPassmark->setEnabled(true); + uiTabPassmarks->checkBoxShowSecondPassmark->setChecked(node.IsShowSecondPassmark()); } //--------------------------------------------------------------------------------------------------------------------- @@ -1598,11 +1556,11 @@ void DialogSeamAllowance::PassmarkLineTypeChanged(int id) } else if (id == uiTabPassmarks->buttonGroupLineType->id(uiTabPassmarks->radioButtonVMark)) { - lineType = PassmarkLineType::VMark; + lineType = PassmarkLineType::ExternalVMark; } else if (id == uiTabPassmarks->buttonGroupLineType->id(uiTabPassmarks->radioButtonVMark2)) { - lineType = PassmarkLineType::VMark2; + lineType = PassmarkLineType::InternalVMark; } else if (id == uiTabPassmarks->buttonGroupLineType->id(uiTabPassmarks->radioButtonUMark)) { @@ -1612,6 +1570,10 @@ void DialogSeamAllowance::PassmarkLineTypeChanged(int id) { lineType = PassmarkLineType::BoxMark; } + else if (id == uiTabPassmarks->buttonGroupLineType->id(uiTabPassmarks->radioButtonCheckMark)) + { + lineType = PassmarkLineType::CheckMark; + } rowNode.SetPassmarkLineType(lineType); rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); @@ -1693,6 +1655,24 @@ void DialogSeamAllowance::PassmarkShowSecondChanged(int state) } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::PassmarkClockwiseOrientationChanged(int state) +{ + const int i = uiTabPassmarks->comboBoxPassmarks->currentIndex(); + if (i != -1) + { + QListWidgetItem *rowItem = GetItemById(uiTabPassmarks->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetPassmarkClockwiseOpening(state); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + ListChanged(); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSeamAllowance::UpdateGrainlineValues() { @@ -1997,11 +1977,66 @@ void DialogSeamAllowance::EnabledManualPassmarkLength() auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); rowNode.SetManualPassmarkLength(uiTabPassmarks->groupBoxManualLength->isChecked()); rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + uiTabPassmarks->toolButtonExprLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->plainTextEditPassmarkLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->pushButtonGrowPassmarkLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->labelEditPassmarkLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->label_3->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + EvalPassmarkLength(); } } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EnabledManualPassmarkWidth() +{ + const int index = uiTabPassmarks->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(uiTabPassmarks->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetManualPassmarkWidth(uiTabPassmarks->groupBoxManualWidth->isChecked()); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + uiTabPassmarks->toolButtonExprWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->plainTextEditPassmarkWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->pushButtonGrowPassmarkWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->labelEditPassmarkWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->label_4->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + + EvalPassmarkWidth(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EnabledManualPassmarkAngle() +{ + const int index = uiTabPassmarks->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(uiTabPassmarks->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetManualPassmarkAngle(uiTabPassmarks->groupBoxManualAngle->isChecked()); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + + uiTabPassmarks->toolButtonExprAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->plainTextEditPassmarkAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->pushButtonGrowPassmarkAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->labelEditPassmarkAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->label_5->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + + EvalPassmarkAngle(); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSeamAllowance::EditGrainlineFormula() { @@ -2362,6 +2397,64 @@ void DialogSeamAllowance::EvalPassmarkLength() } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EvalPassmarkWidth() +{ + if (uiTabPassmarks->groupBoxManualWidth->isChecked()) + { + if (uiTabPassmarks->comboBoxPassmarks->count() > 0) + { + FormulaData formulaData; + formulaData.formula = uiTabPassmarks->plainTextEditPassmarkWidth->toPlainText(); + formulaData.variables = data->DataVariables(); + formulaData.labelEditFormula = uiTabPassmarks->labelEditPassmarkWidth; + formulaData.labelResult = uiTabPassmarks->labelResultPassmarkWidth; + formulaData.postfix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true); + formulaData.checkZero = true; + formulaData.checkLessThanZero = false; + + Eval(formulaData, flagFormulaPassmarkWidth); + + UpdateNodePassmarkWidth(GetFormulaFromUser(uiTabPassmarks->plainTextEditPassmarkWidth)); + } + else + { + ChangeColor(uiTabPassmarks->labelEditPassmarkWidth, OkColor(this)); + uiTabPassmarks->labelResultPassmarkWidth->setText(tr("")); + flagFormulaPassmarkWidth = true; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::EvalPassmarkAngle() +{ + if (uiTabPassmarks->groupBoxManualAngle->isChecked()) + { + if (uiTabPassmarks->comboBoxPassmarks->count() > 0) + { + FormulaData formulaData; + formulaData.formula = uiTabPassmarks->plainTextEditPassmarkAngle->toPlainText(); + formulaData.variables = data->DataVariables(); + formulaData.labelEditFormula = uiTabPassmarks->labelEditPassmarkAngle; + formulaData.labelResult = uiTabPassmarks->labelResultPassmarkAngle; + formulaData.postfix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true); + formulaData.checkZero = false; + formulaData.checkLessThanZero = false; + + Eval(formulaData, flagFormulaPassmarkAngle); + + UpdateNodePassmarkAngle(GetFormulaFromUser(uiTabPassmarks->plainTextEditPassmarkAngle)); + } + else + { + ChangeColor(uiTabPassmarks->labelEditPassmarkAngle, OkColor(this)); + uiTabPassmarks->labelResultPassmarkAngle->setText(tr("")); + flagFormulaPassmarkAngle = true; + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSeamAllowance::FXWidth() { @@ -2413,7 +2506,33 @@ void DialogSeamAllowance::FXPassmarkLength() dialog->setPostfix(UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true)); if (dialog->exec() == QDialog::Accepted) { - SetFormularPassmarkLength(dialog->GetFormula()); + SetFormulaPassmarkLength(dialog->GetFormula()); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::FXPassmarkWidth() +{ + QScopedPointer dialog(new DialogEditWrongFormula(data, toolId, this)); + dialog->setWindowTitle(tr("Edit passmark width")); + dialog->SetFormula(GetFormulaFromUser(uiTabPassmarks->plainTextEditPassmarkWidth)); + dialog->setPostfix(UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetFormulaPassmarkWidth(dialog->GetFormula()); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::FXPassmarkAngle() +{ + QScopedPointer dialog(new DialogEditWrongFormula(data, toolId, this)); + dialog->setWindowTitle(tr("Edit passmark angle")); + dialog->SetFormula(GetFormulaFromUser(uiTabPassmarks->plainTextEditPassmarkAngle)); + dialog->setPostfix(UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true)); + if (dialog->exec() == QDialog::Accepted) + { + SetFormulaPassmarkAngle(dialog->GetFormula()); } } @@ -2444,6 +2563,20 @@ void DialogSeamAllowance::DeployPassmarkLength() m_formulaBasePassmarkLength); } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::DeployPassmarkWidth() +{ + DeployFormula(this, uiTabPassmarks->plainTextEditPassmarkWidth, uiTabPassmarks->pushButtonGrowPassmarkWidth, + m_formulaBasePassmarkWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::DeployPassmarkAngle() +{ + DeployFormula(this, uiTabPassmarks->plainTextEditPassmarkAngle, uiTabPassmarks->pushButtonGrowPassmarkAngle, + m_formulaBasePassmarkAngle); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSeamAllowance::GrainlinePinPointChanged() { @@ -2910,6 +3043,38 @@ void DialogSeamAllowance::UpdateNodePassmarkLength(const QString &formula) } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateNodePassmarkWidth(const QString &formula) +{ + const int index = uiTabPassmarks->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(uiTabPassmarks->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaPassmarkWidth(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::UpdateNodePassmarkAngle(const QString &formula) +{ + const int index = uiTabPassmarks->comboBoxPassmarks->currentIndex(); + if (index != -1) + { + QListWidgetItem *rowItem = GetItemById(uiTabPassmarks->comboBoxPassmarks->currentData().toUInt()); + if (rowItem) + { + auto rowNode = qvariant_cast(rowItem->data(Qt::UserRole)); + rowNode.SetFormulaPassmarkAngle(formula); + rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode)); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSeamAllowance::InitFancyTabBar() { @@ -3412,6 +3577,34 @@ void DialogSeamAllowance::InitPassmarksTab() connect(uiTabPassmarks->pushButtonGrowPassmarkLength, &QPushButton::clicked, this, &DialogSeamAllowance::DeployPassmarkLength); + // Width formula + this->m_formulaBasePassmarkWidth = uiTabPassmarks->plainTextEditPassmarkWidth->height(); + uiTabPassmarks->plainTextEditPassmarkWidth->installEventFilter(this); + m_timerPassmarkWidth->setSingleShot(true); + + connect(m_timerPassmarkWidth, &QTimer::timeout, this, &DialogSeamAllowance::EvalPassmarkWidth); + connect(uiTabPassmarks->groupBoxManualWidth, &QGroupBox::toggled, this, + &DialogSeamAllowance::EnabledManualPassmarkWidth); + connect(uiTabPassmarks->toolButtonExprWidth, &QPushButton::clicked, this, &DialogSeamAllowance::FXPassmarkWidth); + connect(uiTabPassmarks->plainTextEditPassmarkWidth, &QPlainTextEdit::textChanged, this, + [this]() { m_timerPassmarkWidth->start(formulaTimerTimeout); }); + connect(uiTabPassmarks->pushButtonGrowPassmarkWidth, &QPushButton::clicked, this, + &DialogSeamAllowance::DeployPassmarkWidth); + + // Angle formula + this->m_formulaBasePassmarkAngle = uiTabPassmarks->plainTextEditPassmarkAngle->height(); + uiTabPassmarks->plainTextEditPassmarkAngle->installEventFilter(this); + m_timerPassmarkAngle->setSingleShot(true); + + connect(m_timerPassmarkAngle, &QTimer::timeout, this, &DialogSeamAllowance::EvalPassmarkAngle); + connect(uiTabPassmarks->groupBoxManualAngle, &QGroupBox::toggled, this, + &DialogSeamAllowance::EnabledManualPassmarkAngle); + connect(uiTabPassmarks->toolButtonExprAngle, &QPushButton::clicked, this, &DialogSeamAllowance::FXPassmarkAngle); + connect(uiTabPassmarks->plainTextEditPassmarkAngle, &QPlainTextEdit::textChanged, this, + [this]() { m_timerPassmarkAngle->start(formulaTimerTimeout); }); + connect(uiTabPassmarks->pushButtonGrowPassmarkAngle, &QPushButton::clicked, this, + &DialogSeamAllowance::DeployPassmarkAngle); + // notch list InitPassmarksList(); connect(uiTabPassmarks->comboBoxPassmarks, QOverload::of(&QComboBox::currentIndexChanged), @@ -3430,6 +3623,8 @@ void DialogSeamAllowance::InitPassmarksTab() #endif connect(uiTabPassmarks->checkBoxShowSecondPassmark, &QCheckBox::stateChanged, this, &DialogSeamAllowance::PassmarkShowSecondChanged); + connect(uiTabPassmarks->checkBoxClockwiseOpening, &QCheckBox::stateChanged, this, + &DialogSeamAllowance::PassmarkClockwiseOrientationChanged); } //--------------------------------------------------------------------------------------------------------------------- @@ -3502,7 +3697,7 @@ void DialogSeamAllowance::SetFormulaSAWidth(const QString &formula) } //--------------------------------------------------------------------------------------------------------------------- -void DialogSeamAllowance::SetFormularPassmarkLength(const QString &formula) +void DialogSeamAllowance::SetFormulaPassmarkLength(const QString &formula) { const QString width = VAbstractApplication::VApp()->TrVars() ->FormulaToUser(formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); @@ -3516,6 +3711,36 @@ void DialogSeamAllowance::SetFormularPassmarkLength(const QString &formula) MoveCursorToEnd(uiTabPassmarks->plainTextEditPassmarkLength); } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetFormulaPassmarkWidth(const QString &formula) +{ + const QString width = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + // increase height if needed. + if (width.length() > 80) + { + this->DeployPassmarkWidth(); + } + uiTabPassmarks->plainTextEditPassmarkWidth->setPlainText(width); + + MoveCursorToEnd(uiTabPassmarks->plainTextEditPassmarkWidth); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::SetFormulaPassmarkAngle(const QString &formula) +{ + const QString width = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + // increase height if needed. + if (width.length() > 80) + { + this->DeployPassmarkAngle(); + } + uiTabPassmarks->plainTextEditPassmarkAngle->setPlainText(width); + + MoveCursorToEnd(uiTabPassmarks->plainTextEditPassmarkAngle); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSeamAllowance::UpdateCurrentCustomSARecord() { @@ -3961,6 +4186,225 @@ void DialogSeamAllowance::InitGradationPlaceholders() } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitPassmarkLengthFormula(const VPieceNode &node) +{ + // notch depth + uiTabPassmarks->groupBoxManualLength->setEnabled(true); + + if (node.IsManualPassmarkLength()) + { + uiTabPassmarks->groupBoxManualLength->setChecked(true); + + uiTabPassmarks->toolButtonExprLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->plainTextEditPassmarkLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->pushButtonGrowPassmarkLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->labelEditPassmarkLength->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + uiTabPassmarks->label_3->setEnabled(uiTabPassmarks->groupBoxManualLength->isChecked()); + + QString passmarkLength = node.GetFormulaPassmarkLength(); + passmarkLength = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + passmarkLength, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + if (passmarkLength.length() > 80) // increase height if needed. + { + this->DeployPassmarkLength(); + } + + if (passmarkLength.isEmpty()) + { + qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + uiTabPassmarks->plainTextEditPassmarkLength->setPlainText( + VAbstractApplication::VApp()->LocaleToString(length)); + } + else + { + uiTabPassmarks->plainTextEditPassmarkLength->setPlainText(passmarkLength); + } + } + else + { + qreal length = UnitConvertor(1, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + uiTabPassmarks->plainTextEditPassmarkLength->setPlainText(VAbstractApplication::VApp()->LocaleToString(length)); + } + + MoveCursorToEnd(uiTabPassmarks->plainTextEditPassmarkLength); + ChangeColor(uiTabPassmarks->labelEditPassmarkLength, OkColor(this)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitPassmarkWidthFormula(const VPieceNode &node) +{ + // notch width + if (node.GetPassmarkLineType() != PassmarkLineType::OneLine) + { + uiTabPassmarks->groupBoxManualWidth->setEnabled(true); + + if (node.IsManualPassmarkWidth()) + { + uiTabPassmarks->groupBoxManualWidth->setChecked(true); + + uiTabPassmarks->toolButtonExprWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->plainTextEditPassmarkWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->pushButtonGrowPassmarkWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->labelEditPassmarkWidth->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + uiTabPassmarks->label_4->setEnabled(uiTabPassmarks->groupBoxManualWidth->isChecked()); + + QString passmarkWidth = node.GetFormulaPassmarkWidth(); + passmarkWidth = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + passmarkWidth, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + if (passmarkWidth.length() > 80) // increase height if needed. + { + this->DeployPassmarkWidth(); + } + + if (passmarkWidth.isEmpty()) + { + qreal width = UnitConvertor(0.85, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + uiTabPassmarks->plainTextEditPassmarkWidth->setPlainText( + VAbstractApplication::VApp()->LocaleToString(width)); + } + else + { + uiTabPassmarks->plainTextEditPassmarkWidth->setPlainText(passmarkWidth); + } + } + else + { + qreal length = UnitConvertor(0.85, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + uiTabPassmarks->plainTextEditPassmarkWidth->setPlainText( + VAbstractApplication::VApp()->LocaleToString(length)); + } + + MoveCursorToEnd(uiTabPassmarks->plainTextEditPassmarkWidth); + } + else + { + qreal length = UnitConvertor(0.85, Unit::Cm, VAbstractValApplication::VApp()->patternUnits()); + uiTabPassmarks->plainTextEditPassmarkWidth->setPlainText(VAbstractApplication::VApp()->LocaleToString(length)); + } + ChangeColor(uiTabPassmarks->labelEditPassmarkWidth, OkColor(this)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitPassmarkAngleFormula(const VPieceNode &node) +{ + // notch angle + if (node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward) + { + uiTabPassmarks->groupBoxManualAngle->setEnabled(true); + + if (node.IsManualPassmarkAngle()) + { + uiTabPassmarks->groupBoxManualAngle->setChecked(true); + + uiTabPassmarks->toolButtonExprAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->plainTextEditPassmarkAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->pushButtonGrowPassmarkAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->labelEditPassmarkAngle->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + uiTabPassmarks->label_5->setEnabled(uiTabPassmarks->groupBoxManualAngle->isChecked()); + + QString passmarkAngle = node.GetFormulaPassmarkAngle(); + passmarkAngle = VAbstractApplication::VApp()->TrVars()->FormulaToUser( + passmarkAngle, VAbstractApplication::VApp()->Settings()->GetOsSeparator()); + if (passmarkAngle.length() > 80) // increase height if needed. + { + this->DeployPassmarkAngle(); + } + + uiTabPassmarks->plainTextEditPassmarkAngle->setPlainText(passmarkAngle.isEmpty() ? QString::number(0) + : passmarkAngle); + } + else + { + uiTabPassmarks->plainTextEditPassmarkAngle->setPlainText(QString::number(0)); + } + + MoveCursorToEnd(uiTabPassmarks->plainTextEditPassmarkAngle); + } + else + { + uiTabPassmarks->plainTextEditPassmarkAngle->setPlainText(QString::number(0)); + } + ChangeColor(uiTabPassmarks->labelEditPassmarkAngle, OkColor(this)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitPassmarkShapeType(const VPieceNode &node) +{ + // Line type + uiTabPassmarks->groupBoxMarkType->setEnabled(true); + + switch (node.GetPassmarkLineType()) + { + case PassmarkLineType::OneLine: + uiTabPassmarks->radioButtonOneLine->setChecked(true); + break; + case PassmarkLineType::TwoLines: + uiTabPassmarks->radioButtonTwoLines->setChecked(true); + break; + case PassmarkLineType::ThreeLines: + uiTabPassmarks->radioButtonThreeLines->setChecked(true); + break; + case PassmarkLineType::TMark: + uiTabPassmarks->radioButtonTMark->setChecked(true); + break; + case PassmarkLineType::ExternalVMark: + uiTabPassmarks->radioButtonVMark->setChecked(true); + break; + case PassmarkLineType::InternalVMark: + uiTabPassmarks->radioButtonVMark2->setChecked(true); + break; + case PassmarkLineType::UMark: + uiTabPassmarks->radioButtonUMark->setChecked(true); + break; + case PassmarkLineType::BoxMark: + uiTabPassmarks->radioButtonBoxMark->setChecked(true); + break; + case PassmarkLineType::CheckMark: + uiTabPassmarks->radioButtonCheckMark->setChecked(true); + break; + default: + break; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSeamAllowance::InitPassmarkAngleType(const VPieceNode &node) +{ + // Angle type + uiTabPassmarks->groupBoxAngleType->setEnabled(true); + + switch (node.GetPassmarkAngleType()) + { + case PassmarkAngleType::Straightforward: + uiTabPassmarks->radioButtonStraightforward->setChecked(true); + break; + case PassmarkAngleType::Bisector: + uiTabPassmarks->radioButtonBisector->setChecked(true); + break; + case PassmarkAngleType::Intersection: + uiTabPassmarks->radioButtonIntersection->setChecked(true); + break; + case PassmarkAngleType::IntersectionOnlyLeft: + uiTabPassmarks->radioButtonIntersectionOnlyLeft->setChecked(true); + break; + case PassmarkAngleType::IntersectionOnlyRight: + uiTabPassmarks->radioButtonIntersectionOnlyRight->setChecked(true); + break; + case PassmarkAngleType::Intersection2: + uiTabPassmarks->radioButtonIntersection2->setChecked(true); + break; + case PassmarkAngleType::Intersection2OnlyLeft: + uiTabPassmarks->radioButtonIntersection2OnlyLeft->setChecked(true); + break; + case PassmarkAngleType::Intersection2OnlyRight: + uiTabPassmarks->radioButtonIntersection2OnlyRight->setChecked(true); + break; + default: + break; + } +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSeamAllowance::SetMoveControls() { diff --git a/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.h b/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.h index c67db1119..927da0c4e 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.h +++ b/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.h @@ -107,6 +107,7 @@ private slots: void PassmarkLineTypeChanged(int id); void PassmarkAngleTypeChanged(int id); void PassmarkShowSecondChanged(int state); + void PassmarkClockwiseOrientationChanged(int state); void UpdateGrainlineValues(); void UpdateDetailLabelValues(); @@ -134,21 +135,29 @@ private slots: void EnabledDetailLabel(); void EnabledPatternLabel(); void EnabledManualPassmarkLength(); + void EnabledManualPassmarkWidth(); + void EnabledManualPassmarkAngle(); void EvalWidth(); void EvalWidthBefore(); void EvalWidthAfter(); void EvalPassmarkLength(); + void EvalPassmarkWidth(); + void EvalPassmarkAngle(); void FXWidth(); void FXWidthBefore(); void FXWidthAfter(); void FXPassmarkLength(); + void FXPassmarkWidth(); + void FXPassmarkAngle(); void DeployWidthFormulaTextEdit(); void DeployWidthBeforeFormulaTextEdit(); void DeployWidthAfterFormulaTextEdit(); void DeployPassmarkLength(); + void DeployPassmarkWidth(); + void DeployPassmarkAngle(); void GrainlinePinPointChanged(); void DetailPinPointChanged(); @@ -195,6 +204,8 @@ private: bool flagFormulaBefore{true}; bool flagFormulaAfter{true}; bool flagFormulaPassmarkLength{true}; + bool flagFormulaPassmarkWidth{true}; + bool flagFormulaPassmarkAngle{true}; bool flagMainPathIsValid{true}; bool flagName{true}; // We have default name of piece. bool flagUUID{true}; @@ -224,11 +235,15 @@ private: int m_formulaBaseWidthBefore{0}; int m_formulaBaseWidthAfter{0}; int m_formulaBasePassmarkLength{0}; + int m_formulaBasePassmarkWidth{0}; + int m_formulaBasePassmarkAngle{0}; QTimer *m_timerWidth{nullptr}; QTimer *m_timerWidthBefore{nullptr}; QTimer *m_timerWidthAfter{nullptr}; QTimer *m_timerPassmarkLength{nullptr}; + QTimer *m_timerPassmarkWidth{nullptr}; + QTimer *m_timerPassmarkAngle{nullptr}; qreal m_saWidth{0}; QVector m_templateLines{}; @@ -266,6 +281,8 @@ private: void UpdateNodeSABefore(const QString &formula); void UpdateNodeSAAfter(const QString &formula); void UpdateNodePassmarkLength(const QString &formula); + void UpdateNodePassmarkWidth(const QString &formula); + void UpdateNodePassmarkAngle(const QString &formula); void InitFancyTabBar(); void InitMainPathTab(); @@ -286,7 +303,9 @@ private: void InitAllPinComboboxes(); void SetFormulaSAWidth(const QString &formula); - void SetFormularPassmarkLength(const QString &formula); + void SetFormulaPassmarkLength(const QString &formula); + void SetFormulaPassmarkWidth(const QString &formula); + void SetFormulaPassmarkAngle(const QString &formula); void SetGrainlineAngle(QString angleFormula); void SetGrainlineLength(QString lengthFormula); @@ -317,6 +336,12 @@ private: void InitGradationPlaceholdersMenu(); void InitGradationPlaceholders(); + + void InitPassmarkLengthFormula(const VPieceNode &node); + void InitPassmarkWidthFormula(const VPieceNode &node); + void InitPassmarkAngleFormula(const VPieceNode &node); + void InitPassmarkShapeType(const VPieceNode &node); + void InitPassmarkAngleType(const VPieceNode &node); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/dialogs/tools/piece/tabs/tabpassmarks.ui b/src/libs/vtools/dialogs/tools/piece/tabs/tabpassmarks.ui index 8fbda01a1..4f4aac3d2 100644 --- a/src/libs/vtools/dialogs/tools/piece/tabs/tabpassmarks.ui +++ b/src/libs/vtools/dialogs/tools/piece/tabs/tabpassmarks.ui @@ -6,8 +6,8 @@ 0 0 - 426 - 556 + 449 + 586 @@ -24,11 +24,11 @@ 0 0 - 406 - 536 + 429 + 566 - + @@ -51,484 +51,981 @@ - - - true + + + 0 - - Manual length - - - true - - - true - - - - - - - - true - - - - 0 - 0 - - - - - - - - - 255 - 0 - 0 - - - - - - - - - 255 - 0 - 0 - - - - - - - - - 159 - 158 - 158 - - - - - - - - Length: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - true - - - Formula wizard - - - f(x) - - - - :/icon/24x24/fx.png:/icon/24x24/fx.png - - - - 24 - 24 - - - - - - - - - 0 - 0 - - - - - 36 - true - - - - = - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 87 - 0 - - - - Value - - - - - - _ - - - - - - - - - - - true - - - - 0 - 0 - - - - - 16777215 - 28 - - - - Calculation - - - true - - - - - - - true - - - - 18 - 18 - - - - - 0 - 0 - - - - <html><head/><body><p>Show full calculation in message box</p></body></html> - - - - - - - ../../../../ - - - - 16 - 16 - - - - true - - - - - - + + + Type + + + + + + + + true + + + Marks + + + + + + true + + + One line + + + buttonGroupLineType + + + + + + + true + + + Two lines + + + buttonGroupLineType + + + + + + + true + + + Three lines + + + buttonGroupLineType + + + + + + + true + + + T mark + + + buttonGroupLineType + + + + + + + true + + + Acute angle that looks inside of piece + + + External V mark + + + buttonGroupLineType + + + + + + + true + + + Acute angle that looks outside of piece + + + Internal V mark + + + buttonGroupLineType + + + + + + + U mark + + + buttonGroupLineType + + + + + + + Box mark + + + buttonGroupLineType + + + + + + + Check mark + + + buttonGroupLineType + + + + + + + + + + true + + + Angle + + + + + + true + + + Straightforward + + + buttonGroupAngleType + + + + + + + true + + + Bisector + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark + + + Intersection + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only left passmark. + + + Intersection (only left) + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only right passmark. + + + Intersection (only right) + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark + + + Intersection 2 + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only left passmark. + + + Intersection 2 (only left) + + + buttonGroupAngleType + + + + + + + true + + + Select if need designate the corner point as a passmark. Show only right passmark. + + + Intersection 2 (only right) + + + buttonGroupAngleType + + + + + + + + + + + + false + + + Clockwise opening + + + + + + + + Manual shape + + + + + + true + + + Length + + + true + + + false + + + + + + + + false + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Length: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Formula wizard + + + f(x) + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + 36 + true + + + + = + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 87 + 0 + + + + Value + + + + + + _ + + + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../../../ + + + + 16 + 16 + + + + true + + + + + + + + + + + + false + + + Width + + + true + + + false + + + + + + + + false + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Width: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Formula wizard + + + f(x) + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + 36 + true + + + + = + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + false + + + + 0 + 0 + + + + + 87 + 0 + + + + Value + + + + + + _ + + + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../../../ + + + + 16 + 16 + + + + true + + + + + + + + + + + + false + + + Angle + + + true + + + false + + + + + + + + false + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Angle: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Formula wizard + + + f(x) + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + 36 + true + + + + = + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + false + + + + 0 + 0 + + + + + 87 + 0 + + + + Value + + + + + + _ + + + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../../../ + + + + 16 + 16 + + + + true + + + + + + + + + + - - - - - - true - - - Marks - - - - - - true - - - One line - - - buttonGroupLineType - - - - - - - true - - - Two lines - - - buttonGroupLineType - - - - - - - true - - - Three lines - - - buttonGroupLineType - - - - - - - true - - - T mark - - - buttonGroupLineType - - - - - - - true - - - Acute angle that looks inside of piece - - - External V mark - - - buttonGroupLineType - - - - - - - true - - - Acute angle that looks outside of piece - - - Internal V mark - - - buttonGroupLineType - - - - - - - U mark - - - buttonGroupLineType - - - - - - - Box mark - - - buttonGroupLineType - - - - - - - - - - true - - - Angle - - - - - - true - - - Straightforward - - - buttonGroupAngleType - - - - - - - true - - - Bisector - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark - - - Intersection - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only left passmark. - - - Intersection (only left) - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only right passmark. - - - Intersection (only right) - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark - - - Intersection 2 - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only left passmark. - - - Intersection 2 (only left) - - - buttonGroupAngleType - - - - - - - true - - - Select if need designate the corner point as a passmark. Show only right passmark. - - - Intersection 2 (only right) - - - buttonGroupAngleType - - - - - - - - @@ -573,7 +1070,7 @@ - + diff --git a/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp b/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp index ff86efddc..bda10d4dd 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp +++ b/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp @@ -92,6 +92,7 @@ enum class ContextMenuOption : int VMark2, UMark, BoxMark, + CheckMark, Option, InLayout, ForbidFlipping, @@ -505,7 +506,7 @@ void VNodePoint::InitPassmarkLineTypeMenu(QMenu *menu, vidtype pieceId, QHash(PassmarkLineType::LAST_ONE_DO_NOT_USE) == 8, "Not all types were handled."); + Q_STATIC_ASSERT_X(static_cast(PassmarkLineType::LAST_ONE_DO_NOT_USE) == 9, "Not all types were handled."); contextMenu.insert(static_cast(ContextMenuOption::OneLine), InitPassmarkLineTypeAction(tr("One line"), PassmarkLineType::OneLine)); contextMenu.insert(static_cast(ContextMenuOption::TwoLines), @@ -515,14 +516,15 @@ void VNodePoint::InitPassmarkLineTypeMenu(QMenu *menu, vidtype pieceId, QHash(ContextMenuOption::TMark), InitPassmarkLineTypeAction(tr("T mark"), PassmarkLineType::TMark)); contextMenu.insert(static_cast(ContextMenuOption::VMark), - InitPassmarkLineTypeAction(tr("External V mark"), PassmarkLineType::VMark)); + InitPassmarkLineTypeAction(tr("External V mark"), PassmarkLineType::ExternalVMark)); contextMenu.insert(static_cast(ContextMenuOption::VMark2), - InitPassmarkLineTypeAction(tr("Internal V mark"), PassmarkLineType::VMark2)); + InitPassmarkLineTypeAction(tr("Internal V mark"), PassmarkLineType::InternalVMark)); contextMenu.insert(static_cast(ContextMenuOption::UMark), InitPassmarkLineTypeAction(tr("U mark"), PassmarkLineType::UMark)); contextMenu.insert(static_cast(ContextMenuOption::BoxMark), InitPassmarkLineTypeAction(tr("Box mark"), PassmarkLineType::BoxMark)); - + contextMenu.insert(static_cast(ContextMenuOption::CheckMark), + InitPassmarkLineTypeAction(tr("Check mark"), PassmarkLineType::CheckMark)); } //--------------------------------------------------------------------------------------------------------------------- @@ -582,7 +584,7 @@ void VNodePoint::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) ContextMenuOption selectedOption = static_cast( contextMenu.key(selectedAction, static_cast(ContextMenuOption::NoSelection))); - Q_STATIC_ASSERT_X(static_cast(ContextMenuOption::LAST_ONE_DO_NOT_USE) == 33, + Q_STATIC_ASSERT_X(static_cast(ContextMenuOption::LAST_ONE_DO_NOT_USE) == 34, "Not all options were handled."); QT_WARNING_PUSH @@ -688,10 +690,10 @@ void VNodePoint::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) SelectPassmarkLine(PassmarkLineType::TMark); break; case ContextMenuOption::VMark: - SelectPassmarkLine(PassmarkLineType::VMark); + SelectPassmarkLine(PassmarkLineType::ExternalVMark); break; case ContextMenuOption::VMark2: - SelectPassmarkLine(PassmarkLineType::VMark2); + SelectPassmarkLine(PassmarkLineType::InternalVMark); break; case ContextMenuOption::UMark: SelectPassmarkLine(PassmarkLineType::UMark); @@ -699,6 +701,9 @@ void VNodePoint::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) case ContextMenuOption::BoxMark: SelectPassmarkLine(PassmarkLineType::BoxMark); break; + case ContextMenuOption::CheckMark: + SelectPassmarkLine(PassmarkLineType::CheckMark); + break; }; QT_WARNING_POP } diff --git a/src/libs/vtools/tools/vabstracttool.cpp b/src/libs/vtools/tools/vabstracttool.cpp index 17acccbd7..3f009b8b9 100644 --- a/src/libs/vtools/tools/vabstracttool.cpp +++ b/src/libs/vtools/tools/vabstracttool.cpp @@ -550,23 +550,66 @@ auto VAbstractTool::AddSANode(VAbstractPattern *doc, const QString &tagName, con if (type == Tool::NodePoint) { - doc->SetAttribute(nod, VAbstractPattern::AttrNodePassmark, node.IsPassmark()); - doc->SetAttribute(nod, VAbstractPattern::AttrNodePassmarkLine, - PassmarkLineTypeToString(node.GetPassmarkLineType())); - doc->SetAttribute(nod, VAbstractPattern::AttrNodePassmarkAngle, - PassmarkAngleTypeToString(node.GetPassmarkAngleType())); - - if (not node.IsPassmark() - && node.GetPassmarkLineType() == PassmarkLineType::OneLine - && node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward) - { // For backward compatebility. - nod.removeAttribute(VAbstractPattern::AttrNodePassmark); - nod.removeAttribute(VAbstractPattern::AttrNodePassmarkLine); - nod.removeAttribute(VAbstractPattern::AttrNodePassmarkAngle); - } + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrNodePassmark, node.IsPassmark(), + [node](bool passmark) noexcept + { + return not passmark && + node.GetPassmarkLineType() == PassmarkLineType::OneLine && + node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward; + }); + doc->SetAttributeOrRemoveIf( + nod, VAbstractPattern::AttrNodePassmarkLine, PassmarkLineTypeToString(node.GetPassmarkLineType()), + [node](const QString &) noexcept + { + return not node.IsPassmark() && node.GetPassmarkLineType() == PassmarkLineType::OneLine && + node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward; + }); + doc->SetAttributeOrRemoveIf( + nod, VAbstractPattern::AttrNodePassmarkAngle, PassmarkAngleTypeToString(node.GetPassmarkAngleType()), + [node](const QString &) noexcept + { + return not node.IsPassmark() && node.GetPassmarkLineType() == PassmarkLineType::OneLine && + node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward; + }); doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrNodeTurnPoint, node.IsTurnPoint(), - [](bool value) noexcept {return value;}); + [](bool value) noexcept { return value; }); + + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrNodeShowSecondPassmark, + node.IsShowSecondPassmark(), [](bool show) noexcept { return show; }); + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrNodePassmarkOpening, + node.IsPassmarkClockwiseOpening(), + [](bool opening) noexcept { return not opening; }); + + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrManualPassmarkLength, + node.IsManualPassmarkLength(), + [](bool manualPassmarkLength) noexcept { return not manualPassmarkLength; }); + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrPassmarkLength, node.GetFormulaPassmarkLength(), + [node](const QString &) noexcept + { return not node.IsManualPassmarkLength(); }); + + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrManualPassmarkWidth, node.IsManualPassmarkWidth(), + [node](bool manualPassmarkWidth) noexcept { + return not manualPassmarkWidth || + node.GetPassmarkLineType() == PassmarkLineType::OneLine; + }); + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrPassmarkWidth, node.GetFormulaPassmarkWidth(), + [node](const QString &) noexcept { + return not node.IsManualPassmarkWidth() || + node.GetPassmarkLineType() == PassmarkLineType::OneLine; + }); + + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrManualPassmarkAngle, node.IsManualPassmarkAngle(), + [node](bool manualPassmarkAngle) noexcept { + return not manualPassmarkAngle || + node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward; + }); + doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrPassmarkAngle, node.GetFormulaPassmarkAngle(), + [node](const QString &) noexcept { + return not node.IsManualPassmarkAngle() || + node.GetPassmarkAngleType() == + PassmarkAngleType::Straightforward; + }); } else { // Wrong configuration. @@ -575,14 +618,6 @@ auto VAbstractTool::AddSANode(VAbstractPattern *doc, const QString &tagName, con nod.removeAttribute(VAbstractPattern::AttrNodePassmarkAngle); } - doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrNodeShowSecondPassmark, node.IsShowSecondPassmark(), - [](bool show) noexcept {return show;}); - - doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrManualPassmarkLength, node.IsManualPassmarkLength(), - [](bool manualPassmarkLength) noexcept {return not manualPassmarkLength;}); - doc->SetAttributeOrRemoveIf(nod, VAbstractPattern::AttrPassmarkLength, node.GetFormulaPassmarkLength(), - [node](const QString &) noexcept {return not node.IsManualPassmarkLength();}); - return nod; }