Resolved issue #818. Improve Piece path validation. Check uniqueness.
--HG-- branch : develop
This commit is contained in:
parent
5f500e9b4d
commit
cb5b7fcfcd
|
@ -46,6 +46,7 @@
|
|||
- [#667] Check for updates - Test version.
|
||||
- [#808] New feature. Global line width option.
|
||||
- [#814] Make "\" valid character.
|
||||
- [#818] Improve Piece path validation. Check uniqueness.
|
||||
|
||||
# Version 0.5.1
|
||||
- [#683] Tool Seam allowance's dialog is off screen on small resolutions.
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
<file>schema/pattern/v0.7.4.xsd</file>
|
||||
<file>schema/pattern/v0.7.5.xsd</file>
|
||||
<file>schema/pattern/v0.7.6.xsd</file>
|
||||
<file>schema/pattern/v0.7.7.xsd</file>
|
||||
<file>schema/standard_measurements/v0.3.0.xsd</file>
|
||||
<file>schema/standard_measurements/v0.4.0.xsd</file>
|
||||
<file>schema/standard_measurements/v0.4.1.xsd</file>
|
||||
|
|
1061
src/libs/ifc/schema/pattern/v0.7.7.xsd
Normal file
1061
src/libs/ifc/schema/pattern/v0.7.7.xsd
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -129,6 +129,7 @@ const QString VAbstractPattern::AttrEnd = QStringLiteral("end");
|
|||
const QString VAbstractPattern::AttrIncludeAs = QStringLiteral("includeAs");
|
||||
const QString VAbstractPattern::AttrRotation = QStringLiteral("rotation");
|
||||
const QString VAbstractPattern::AttrNumber = QStringLiteral("number");
|
||||
const QString VAbstractPattern::AttrCheckUniqueness = QStringLiteral("checkUniqueness");
|
||||
|
||||
const QString VAbstractPattern::AttrAll = QStringLiteral("all");
|
||||
|
||||
|
@ -686,6 +687,7 @@ VPieceNode VAbstractPattern::ParseSANode(const QDomElement &domElement)
|
|||
const quint32 id = VDomDocument::GetParametrUInt(domElement, AttrIdObject, NULL_ID_STR);
|
||||
const bool reverse = VDomDocument::GetParametrUInt(domElement, VAbstractPattern::AttrNodeReverse, "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,
|
||||
|
@ -738,6 +740,7 @@ VPieceNode VAbstractPattern::ParseSANode(const QDomElement &domElement)
|
|||
node.SetFormulaSAAfter(saAfter);
|
||||
node.SetAngleType(angle);
|
||||
node.SetExcluded(excluded);
|
||||
node.SetCheckUniqueness(uniqeness);
|
||||
node.SetShowSecondPassmark(showSecond);
|
||||
node.SetPassmark(passmark);
|
||||
node.SetPassmarkLineType(passmarkLine);
|
||||
|
|
|
@ -271,6 +271,7 @@ public:
|
|||
static const QString AttrIncludeAs;
|
||||
static const QString AttrRotation;
|
||||
static const QString AttrNumber;
|
||||
static const QString AttrCheckUniqueness;
|
||||
|
||||
static const QString AttrAll;
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@ class QDomElement;
|
|||
*/
|
||||
|
||||
const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0");
|
||||
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.7.6");
|
||||
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.7.6.xsd");
|
||||
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.7.7");
|
||||
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.7.7.xsd");
|
||||
|
||||
//VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
|
||||
//VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
|
||||
|
@ -222,7 +222,8 @@ QString VPatternConverter::XSDSchema(int ver) const
|
|||
std::make_pair(0x000703, QStringLiteral("://schema/pattern/v0.7.3.xsd")),
|
||||
std::make_pair(0x000704, QStringLiteral("://schema/pattern/v0.7.4.xsd")),
|
||||
std::make_pair(0x000705, QStringLiteral("://schema/pattern/v0.7.5.xsd")),
|
||||
std::make_pair(0x000706, CurrentSchema)
|
||||
std::make_pair(0x000706, QStringLiteral("://schema/pattern/v0.7.6.xsd")),
|
||||
std::make_pair(0x000707, CurrentSchema)
|
||||
};
|
||||
|
||||
if (schemas.contains(ver))
|
||||
|
@ -429,6 +430,10 @@ void VPatternConverter::ApplyPatches()
|
|||
ValidateXML(XSDSchema(0x000706), m_convertedFileName);
|
||||
V_FALLTHROUGH
|
||||
case (0x000706):
|
||||
ToV0_7_7();
|
||||
ValidateXML(XSDSchema(0x000707), m_convertedFileName);
|
||||
V_FALLTHROUGH
|
||||
case (0x000707):
|
||||
break;
|
||||
default:
|
||||
InvalidVersion(m_ver);
|
||||
|
@ -446,7 +451,7 @@ void VPatternConverter::DowngradeToCurrentMaxVersion()
|
|||
bool VPatternConverter::IsReadOnly() const
|
||||
{
|
||||
// Check if attribute readOnly was not changed in file format
|
||||
Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 7, 6),
|
||||
Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 7, 7),
|
||||
"Check attribute readOnly.");
|
||||
|
||||
// Possibly in future attribute readOnly will change position etc.
|
||||
|
@ -980,6 +985,16 @@ void VPatternConverter::ToV0_7_6()
|
|||
Save();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPatternConverter::ToV0_7_7()
|
||||
{
|
||||
// TODO. Delete if minimal supported version is 0.7.7
|
||||
Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 7, 7),
|
||||
"Time to refactor the code.");
|
||||
SetVersion(QStringLiteral("0.7.7"));
|
||||
Save();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPatternConverter::TagUnitToV0_2_0()
|
||||
{
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
static const QString PatternMaxVerStr;
|
||||
static const QString CurrentSchema;
|
||||
static Q_DECL_CONSTEXPR const int PatternMinVer = CONVERTER_VERSION_CHECK(0, 1, 0);
|
||||
static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 7, 6);
|
||||
static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 7, 7);
|
||||
|
||||
protected:
|
||||
virtual int MinVer() const Q_DECL_OVERRIDE;
|
||||
|
@ -119,6 +119,7 @@ private:
|
|||
void ToV0_7_4();
|
||||
void ToV0_7_5();
|
||||
void ToV0_7_6();
|
||||
void ToV0_7_7();
|
||||
|
||||
void TagUnitToV0_2_0();
|
||||
void TagIncrementToV0_2_0();
|
||||
|
|
|
@ -311,6 +311,18 @@ void VPieceNode::SetShowSecondPassmark(bool value)
|
|||
d->m_isShowSecondPassmark = value;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPieceNode::IsCheckUniqueness() const
|
||||
{
|
||||
return d->m_checkUniqueness;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceNode::SetCheckUniqueness(bool value)
|
||||
{
|
||||
d->m_checkUniqueness = (d->m_typeTool == Tool::NodePoint ? value : true);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPieceNode::IsExcluded() const
|
||||
{
|
||||
|
|
|
@ -99,6 +99,9 @@ public:
|
|||
|
||||
bool IsShowSecondPassmark() const;
|
||||
void SetShowSecondPassmark(bool value);
|
||||
|
||||
bool IsCheckUniqueness() const;
|
||||
void SetCheckUniqueness(bool value);
|
||||
private:
|
||||
QSharedDataPointer<VPieceNodeData> d;
|
||||
};
|
||||
|
|
|
@ -53,7 +53,8 @@ public:
|
|||
m_angleType(PieceNodeAngle::ByLength),
|
||||
m_passmarkLineType(PassmarkLineType::OneLine),
|
||||
m_passmarkAngleType(PassmarkAngleType::Straightforward),
|
||||
m_isShowSecondPassmark(true)
|
||||
m_isShowSecondPassmark(true),
|
||||
m_checkUniqueness(true)
|
||||
{}
|
||||
|
||||
VPieceNodeData(quint32 id, Tool typeTool, bool reverse)
|
||||
|
@ -68,7 +69,8 @@ public:
|
|||
m_angleType(PieceNodeAngle::ByLength),
|
||||
m_passmarkLineType(PassmarkLineType::OneLine),
|
||||
m_passmarkAngleType(PassmarkAngleType::Straightforward),
|
||||
m_isShowSecondPassmark(true)
|
||||
m_isShowSecondPassmark(true),
|
||||
m_checkUniqueness(true)
|
||||
{
|
||||
if (m_typeTool == Tool::NodePoint)
|
||||
{
|
||||
|
@ -89,7 +91,8 @@ public:
|
|||
m_angleType(node.m_angleType),
|
||||
m_passmarkLineType(node.m_passmarkLineType),
|
||||
m_passmarkAngleType(node.m_passmarkAngleType),
|
||||
m_isShowSecondPassmark(node.m_isShowSecondPassmark)
|
||||
m_isShowSecondPassmark(node.m_isShowSecondPassmark),
|
||||
m_checkUniqueness(node.m_checkUniqueness)
|
||||
{}
|
||||
|
||||
~VPieceNodeData() Q_DECL_EQ_DEFAULT;
|
||||
|
@ -126,6 +129,11 @@ public:
|
|||
|
||||
bool m_isShowSecondPassmark;
|
||||
|
||||
/** @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
|
||||
* gradation change a piece shape and the seond point should be remaind.*/
|
||||
bool m_checkUniqueness;
|
||||
|
||||
private:
|
||||
VPieceNodeData &operator=(const VPieceNodeData &) Q_DECL_EQ_DELETE;
|
||||
};
|
||||
|
|
|
@ -95,6 +95,40 @@ VPieceNode RowNode(QListWidget *listWidget, int i)
|
|||
SCASSERT(rowItem != nullptr);
|
||||
return qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool DoublePoint(const VPieceNode &firstNode, const VPieceNode &secondNode, const VContainer *data)
|
||||
{
|
||||
if (firstNode.GetTypeTool() == Tool::NodePoint && not (firstNode.GetId() == NULL_ID)
|
||||
&& secondNode.GetTypeTool() == Tool::NodePoint && not (secondNode.GetId() == NULL_ID))
|
||||
{
|
||||
// don't ignore the same point twice
|
||||
if (firstNode.GetId() == secondNode.GetId())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// But ignore the same coordinate if a user wants
|
||||
if (not firstNode.IsCheckUniqueness() || not secondNode.IsCheckUniqueness())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const QSharedPointer<VPointF> firstPoint = data->GeometricObject<VPointF>(firstNode.GetId());
|
||||
const QSharedPointer<VPointF> secondPoint = data->GeometricObject<VPointF>(secondNode.GetId());
|
||||
|
||||
return firstPoint->toQPointF() == secondPoint->toQPointF();
|
||||
}
|
||||
catch(const VExceptionBadId &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -508,20 +542,7 @@ bool DialogTool::FirstPointEqualLast(QListWidget *listWidget, const VContainer *
|
|||
const VPieceNode topNode = RowNode(listWidget, FindNotExcludedNodeDown(listWidget, 0));
|
||||
const VPieceNode bottomNode = RowNode(listWidget, FindNotExcludedNodeUp(listWidget, listWidget->count()-1));
|
||||
|
||||
QSharedPointer<VPointF> firstPoint;
|
||||
if (topNode.GetTypeTool() == Tool::NodePoint)
|
||||
{
|
||||
firstPoint = data->GeometricObject<VPointF>(topNode.GetId());
|
||||
}
|
||||
|
||||
QSharedPointer<VPointF> secondPoint;
|
||||
if (bottomNode.GetTypeTool() == Tool::NodePoint)
|
||||
{
|
||||
secondPoint = data->GeometricObject<VPointF>(bottomNode.GetId());
|
||||
}
|
||||
|
||||
return topNode.GetId() == bottomNode.GetId() || (not firstPoint.isNull() && not secondPoint.isNull()
|
||||
&& firstPoint->toQPointF() == secondPoint->toQPointF());
|
||||
return DoublePoint(topNode, bottomNode, data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -536,20 +557,7 @@ bool DialogTool::DoublePoints(QListWidget *listWidget, const VContainer *data)
|
|||
const VPieceNode firstNode = RowNode(listWidget, firstIndex);
|
||||
const VPieceNode secondNode = RowNode(listWidget, FindNotExcludedNodeDown(listWidget, firstIndex+1));
|
||||
|
||||
QSharedPointer<VPointF> firstPoint;
|
||||
if (firstNode.GetTypeTool() == Tool::NodePoint && not (firstNode.GetId() == NULL_ID))
|
||||
{
|
||||
firstPoint = data->GeometricObject<VPointF>(firstNode.GetId());
|
||||
}
|
||||
|
||||
QSharedPointer<VPointF> secondPoint;
|
||||
if (secondNode.GetTypeTool() == Tool::NodePoint && not (secondNode.GetId() == NULL_ID))
|
||||
{
|
||||
secondPoint = data->GeometricObject<VPointF>(secondNode.GetId());
|
||||
}
|
||||
|
||||
if (firstNode.GetId() == secondNode.GetId() || (not firstPoint.isNull() && not secondPoint.isNull()
|
||||
&& firstPoint->toQPointF() == secondPoint->toQPointF()))
|
||||
if (DoublePoint(firstNode, secondNode, data))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -616,27 +624,35 @@ QString DialogTool::GetNodeName(const VPieceNode &node, bool showPassmark) const
|
|||
name = QLatin1String("- ") + name;
|
||||
}
|
||||
}
|
||||
else if (showPassmark && node.IsPassmark())
|
||||
else
|
||||
{
|
||||
switch(node.GetPassmarkLineType())
|
||||
if (showPassmark && node.IsPassmark())
|
||||
{
|
||||
case PassmarkLineType::OneLine:
|
||||
name += QLatin1Char('|');
|
||||
break;
|
||||
case PassmarkLineType::TwoLines:
|
||||
name += QLatin1Literal("||");
|
||||
break;
|
||||
case PassmarkLineType::ThreeLines:
|
||||
name += QLatin1Literal("|||");
|
||||
break;
|
||||
case PassmarkLineType::TMark:
|
||||
name += QString("┴");
|
||||
break;
|
||||
case PassmarkLineType::VMark:
|
||||
name += QLatin1Char('^');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch(node.GetPassmarkLineType())
|
||||
{
|
||||
case PassmarkLineType::OneLine:
|
||||
name += QLatin1Char('|');
|
||||
break;
|
||||
case PassmarkLineType::TwoLines:
|
||||
name += QLatin1Literal("||");
|
||||
break;
|
||||
case PassmarkLineType::ThreeLines:
|
||||
name += QLatin1Literal("|||");
|
||||
break;
|
||||
case PassmarkLineType::TMark:
|
||||
name += QString("┴");
|
||||
break;
|
||||
case PassmarkLineType::VMark:
|
||||
name += QLatin1Char('^');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (not node.IsCheckUniqueness())
|
||||
{
|
||||
name = QLatin1Char('[') + name + QLatin1Char(']');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -284,6 +284,7 @@ void DialogPiecePath::ShowContextMenu(const QPoint &pos)
|
|||
VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
|
||||
|
||||
QAction *actionPassmark = nullptr;
|
||||
QAction *actionUniqueness = nullptr;
|
||||
QAction *actionReverse = nullptr;
|
||||
if (rowNode.GetTypeTool() != Tool::NodePoint)
|
||||
{
|
||||
|
@ -296,6 +297,10 @@ void DialogPiecePath::ShowContextMenu(const QPoint &pos)
|
|||
actionPassmark = menu->addAction(tr("Passmark"));
|
||||
actionPassmark->setCheckable(true);
|
||||
actionPassmark->setChecked(rowNode.IsPassmark());
|
||||
|
||||
actionUniqueness = menu->addAction(tr("Check uniqueness"));
|
||||
actionUniqueness->setCheckable(true);
|
||||
actionUniqueness->setChecked(rowNode.IsCheckUniqueness());
|
||||
}
|
||||
|
||||
QAction *actionDelete = menu->addAction(QIcon::fromTheme("edit-delete"), tr("Delete"));
|
||||
|
@ -317,6 +322,12 @@ void DialogPiecePath::ShowContextMenu(const QPoint &pos)
|
|||
rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
|
||||
rowItem->setText(GetNodeName(rowNode, true));
|
||||
}
|
||||
else if (selectedAction == actionUniqueness)
|
||||
{
|
||||
rowNode.SetCheckUniqueness(not rowNode.IsCheckUniqueness());
|
||||
rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
|
||||
rowItem->setText(GetNodeName(rowNode, true));
|
||||
}
|
||||
|
||||
ValidObjects(PathIsValid());
|
||||
ListChanged();
|
||||
|
|
|
@ -613,6 +613,7 @@ void DialogSeamAllowance::ShowMainPathContextMenu(const QPoint &pos)
|
|||
VPieceNode rowNode = qvariant_cast<VPieceNode>(rowItem->data(Qt::UserRole));
|
||||
|
||||
QAction *actionPassmark = nullptr;
|
||||
QAction *actionUniqueness = nullptr;
|
||||
QAction *actionReverse = nullptr;
|
||||
if (rowNode.GetTypeTool() != Tool::NodePoint)
|
||||
{
|
||||
|
@ -625,6 +626,10 @@ void DialogSeamAllowance::ShowMainPathContextMenu(const QPoint &pos)
|
|||
actionPassmark = menu->addAction(tr("Passmark"));
|
||||
actionPassmark->setCheckable(true);
|
||||
actionPassmark->setChecked(rowNode.IsPassmark());
|
||||
|
||||
actionUniqueness = menu->addAction(tr("Check uniqueness"));
|
||||
actionUniqueness->setCheckable(true);
|
||||
actionUniqueness->setChecked(rowNode.IsCheckUniqueness());
|
||||
}
|
||||
|
||||
QAction *actionExcluded = menu->addAction(tr("Excluded"));
|
||||
|
@ -657,6 +662,12 @@ void DialogSeamAllowance::ShowMainPathContextMenu(const QPoint &pos)
|
|||
rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
|
||||
rowItem->setText(GetNodeName(rowNode, true));
|
||||
}
|
||||
else if (selectedAction == actionUniqueness)
|
||||
{
|
||||
rowNode.SetCheckUniqueness(not rowNode.IsCheckUniqueness());
|
||||
rowItem->setData(Qt::UserRole, QVariant::fromValue(rowNode));
|
||||
rowItem->setText(GetNodeName(rowNode, true));
|
||||
}
|
||||
|
||||
ValidObjects(MainPathIsValid());
|
||||
ListChanged();
|
||||
|
|
|
@ -535,6 +535,18 @@ QDomElement VAbstractTool::AddSANode(VAbstractPattern *doc, const QString &tagNa
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
const bool uniqueness = node.IsCheckUniqueness();
|
||||
if (not uniqueness)
|
||||
{
|
||||
doc->SetAttribute(nod, VAbstractPattern::AttrCheckUniqueness, uniqueness);
|
||||
}
|
||||
else
|
||||
{ // For backward compatebility.
|
||||
nod.removeAttribute(VAbstractPattern::AttrCheckUniqueness);
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case (Tool::NodeArc):
|
||||
|
|
|
@ -179,7 +179,8 @@ bool SavePieceOptions::mergeWith(const QUndoCommand *command)
|
|||
|
||||
for (int i = 0; i < nodes.size(); ++i)
|
||||
{
|
||||
if (nodes.at(i).IsExcluded() != candidateNodes.at(i).IsExcluded())
|
||||
if (nodes.at(i).IsExcluded() != candidateNodes.at(i).IsExcluded()
|
||||
|| nodes.at(i).IsCheckUniqueness() != candidateNodes.at(i).IsCheckUniqueness())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -150,7 +150,8 @@ bool SavePiecePathOptions::mergeWith(const QUndoCommand *command)
|
|||
|
||||
for (int i = 0; i < nodes.size(); ++i)
|
||||
{
|
||||
if (nodes.at(i).IsExcluded() != candidateNodes.at(i).IsExcluded())
|
||||
if (nodes.at(i).IsExcluded() != candidateNodes.at(i).IsExcluded()
|
||||
|| nodes.at(i).IsCheckUniqueness() != candidateNodes.at(i).IsCheckUniqueness())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user