Merge with feature

--HG--
branch : develop
This commit is contained in:
dismine 2014-12-17 17:14:07 +02:00
commit c36f2d47e7
31 changed files with 805 additions and 211 deletions

View file

@ -516,6 +516,7 @@ void VApplication::ClearOldLogs() const
qCDebug(vApp) << "Failed to lock"<<info.absoluteFilePath();
}
delete lock;
lock = nullptr;
}
}
else

View file

@ -69,6 +69,7 @@ DialogDetail::DialogDetail(const VContainer *data, const quint32 &toolId, QWidge
this, &DialogDetail::BiasYChanged);
connect(ui.checkBoxSeams, &QCheckBox::clicked, this, &DialogDetail::ClickedSeams);
connect(ui.checkBoxClosed, &QCheckBox::clicked, this, &DialogDetail::ClickedClosed);
connect(ui.checkBoxReverse, &QCheckBox::clicked, this, &DialogDetail::ClickedReverse);
connect(ui.lineEditNameDetail, &QLineEdit::textChanged, this, &DialogDetail::NamePointChanged);
connect(ui.toolButtonDelete, &QToolButton::clicked, this, &DialogDetail::DeleteItem);
@ -133,9 +134,10 @@ void DialogDetail::SaveData()
* @param typeNode type of node in detail
* @param mx offset respect to x
* @param my offset respect to y
* @param reverse reverse list of points
*/
void DialogDetail::NewItem(quint32 id, const Tool &typeTool, const NodeDetail &typeNode,
qreal mx, qreal my)
qreal mx, qreal my, bool reverse)
{
QString name;
switch (typeTool)
@ -171,14 +173,27 @@ void DialogDetail::NewItem(quint32 id, const Tool &typeTool, const NodeDetail &t
QListWidgetItem *item = new QListWidgetItem(name);
item->setFont(QFont("Times", 12, QFont::Bold));
VNodeDetail node(id, typeTool, typeNode, mx, my);
VNodeDetail node(id, typeTool, typeNode, mx, my, reverse);
item->setData(Qt::UserRole, QVariant::fromValue(node));
ui.listWidget->addItem(item);
ui.listWidget->setCurrentRow(ui.listWidget->count()-1);
ui.doubleSpinBoxBiasX->blockSignals(true);
ui.doubleSpinBoxBiasY->blockSignals(true);
ui.doubleSpinBoxBiasX->setValue(qApp->fromPixel(node.getMx()));
ui.doubleSpinBoxBiasY->setValue(qApp->fromPixel(node.getMy()));
if (node.getTypeTool() == Tool::NodePoint)
{
ui.checkBoxReverse->setChecked(false);
ui.checkBoxReverse->setEnabled(false);
}
else
{
ui.checkBoxReverse->setEnabled(true);
ui.checkBoxReverse->setChecked(node.getReverse());
}
ui.doubleSpinBoxBiasX->blockSignals(false);
ui.doubleSpinBoxBiasY->blockSignals(false);
}
@ -195,7 +210,7 @@ void DialogDetail::setDetails(const VDetail &value)
for (int i = 0; i < details.CountNode(); ++i)
{
NewItem(details.at(i).getId(), details.at(i).getTypeTool(), details.at(i).getTypeNode(), details.at(i).getMx(),
details.at(i).getMy());
details.at(i).getMy(), details.at(i).getReverse());
}
ui.lineEditNameDetail->setText(details.getName());
ui.checkBoxSeams->setChecked(details.getSeamAllowance());
@ -260,6 +275,17 @@ void DialogDetail::ClickedClosed(bool checked)
closed = checked;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogDetail::ClickedReverse(bool checked)
{
qint32 row = ui.listWidget->currentRow();
QListWidgetItem *item = ui.listWidget->item( row );
SCASSERT(item != nullptr);
VNodeDetail node = qvariant_cast<VNodeDetail>(item->data(Qt::UserRole));
node.setReverse(checked);
item->setData(Qt::UserRole, QVariant::fromValue(node));
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief ObjectChanged changed new object (point, arc, spline or spline path) form list
@ -271,10 +297,20 @@ void DialogDetail::ObjectChanged(int row)
{
return;
}
QListWidgetItem *item = ui.listWidget->item( row );
VNodeDetail node = qvariant_cast<VNodeDetail>(item->data(Qt::UserRole));
const QListWidgetItem *item = ui.listWidget->item( row );
const VNodeDetail node = qvariant_cast<VNodeDetail>(item->data(Qt::UserRole));
ui.doubleSpinBoxBiasX->setValue(qApp->fromPixel(node.getMx()));
ui.doubleSpinBoxBiasY->setValue(qApp->fromPixel(node.getMy()));
if (node.getTypeTool() == Tool::NodePoint)
{
ui.checkBoxReverse->setChecked(false);
ui.checkBoxReverse->setEnabled(false);
}
else
{
ui.checkBoxReverse->setEnabled(true);
ui.checkBoxReverse->setChecked(node.getReverse());
}
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -50,6 +50,7 @@ public slots:
void BiasYChanged(qreal d);
void ClickedSeams(bool checked);
void ClickedClosed(bool checked);
void ClickedReverse(bool checked);
void ObjectChanged(int row);
void DeleteItem();
virtual void UpdateList();
@ -73,7 +74,7 @@ private:
bool closed;
void NewItem(quint32 id, const Tool &typeTool, const NodeDetail &typeNode,
qreal mx = 0, qreal my = 0);
qreal mx = 0, qreal my = 0, bool reverse = false);
};
//---------------------------------------------------------------------------------------------------------------------

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>565</width>
<height>324</height>
<height>342</height>
</rect>
</property>
<property name="windowTitle">
@ -126,6 +126,17 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QCheckBox" name="checkBoxReverse">
<property name="text">
<string>Reverse</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
@ -244,6 +255,9 @@
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>

View file

@ -51,6 +51,76 @@ VAbstractCurve &VAbstractCurve::operator=(const VAbstractCurve &curve)
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse) const
{
QVector<QPointF> points = GetPoints();
if (reverse)
{
points = GetReversePoints(points);
}
points = FromBegin(points, begin);
points = ToEnd(points, end);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::FromBegin(const QVector<QPointF> &points, const QPointF &begin) const
{
if (points.count() >= 2)
{
QVector<QPointF> segment;
bool theBegin = false;
for (qint32 i = 0; i < points.count()-1; ++i)
{
if (theBegin == false)
{
if (PointInSegment(begin, points.at(i), points.at(i+1)))
{
theBegin = true;
segment.append(begin);
if (i == points.count()-2)
{
segment.append(points.at(i+1));
}
continue;
}
}
else
{
segment.append(points.at(i));
if (i == points.count()-2)
{
segment.append(points.at(i+1));
}
}
}
if (segment.isEmpty())
{
return points;
}
else
{
return segment;
}
}
else
{
return points;
}
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::ToEnd(const QVector<QPointF> &points, const QPointF &end) const
{
QVector<QPointF> reversed = GetReversePoints(points);
reversed = FromBegin(reversed, end);
return GetReversePoints(reversed);
}
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VAbstractCurve::GetPath(PathDirection direction) const
{

View file

@ -43,12 +43,18 @@ public:
VAbstractCurve(const GOType &type, const quint32 &idObject = NULL_ID, const Draw &mode = Draw::Calculation);
VAbstractCurve(const VAbstractCurve &curve);
VAbstractCurve& operator= (const VAbstractCurve &curve);
virtual QVector<QPointF> GetPoints() const =0;
QVector<QPointF> GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse = false) const;
virtual QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const;
virtual qreal GetLength() const =0;
virtual QVector<QPointF> IntersectLine(const QLineF &line) const;
protected:
QPainterPath ShowDirection(const QVector<QPointF> &points) const;
private:
QVector<QPointF> FromBegin(const QVector<QPointF> &points, const QPointF &begin) const;
QVector<QPointF> ToEnd(const QVector<QPointF> &points, const QPointF &end) const;
};
#endif // VABSTRACTCURVE_H

View file

@ -181,7 +181,8 @@ QVector<QPointF> VArc::GetPoints() const
points.append(line.p2());
}
} while (i <= angle);
return points;
// Detail points clockwise, but arc we draw counterclockwise. Main contour need reverse.
return GetReversePoints(points);
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -38,7 +38,14 @@
#include <QtMath>
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer *data) const
VEquidistant::VEquidistant(const VContainer *data)
:data(data)
{
SCASSERT(data != nullptr);
}
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VEquidistant::ContourPath(const quint32 &idDetail) const
{
SCASSERT(data != nullptr);
VDetail detail = data->GetDetail(idDetail);
@ -62,23 +69,20 @@ QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer
}
break;
case (Tool::NodeArc):
{
const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(detail.at(i).getId());
// Detail points clockwise, but arc we draw counterclockwise. Main contour need reverse.
const QVector<QPointF> reversedPoints = GetReversePoint(arc->GetPoints());
AddContour(reversedPoints, points, pointsEkv, detail, i);
}
break;
case (Tool::NodeSpline):
{
const QSharedPointer<VSpline> spline = data->GeometricObject<VSpline>(detail.at(i).getId());
AddContour(spline->GetPoints(), points, pointsEkv, detail, i);
}
break;
case (Tool::NodeSplinePath):
{
const QSharedPointer<VSplinePath> splinePath = data->GeometricObject<VSplinePath>(detail.at(i).getId());
AddContour(splinePath->GetPoints(), points, pointsEkv, detail, i);
const QSharedPointer<VAbstractCurve> curve=data->GeometricObject<VAbstractCurve>(detail.at(i).getId());
const QPointF begin = StartSegment(detail, i);
const QPointF end = EndSegment(detail, i);
QVector<QPointF> nodePoints = curve->GetSegmentPoints(begin, end, detail.at(i).getReverse());
points << nodePoints;
if (detail.getSeamAllowance() == true)
{
pointsEkv << biasPoints(nodePoints, detail.at(i).getMx(), detail.at(i).getMy());
}
}
break;
default:
@ -116,17 +120,51 @@ QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer
}
//---------------------------------------------------------------------------------------------------------------------
int VEquidistant::GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints)
QPointF VEquidistant::StartSegment(const VDetail &detail, const int &i) const
{
qreal length = 0;
QVector<QPointF> points;
points << contour << newPoints;
for (qint32 i = 0; i < points.size()-1; ++i)
QPointF begin;
if (detail.CountNode() > 1)
{
QLineF line(points.at(i), points.at(i+1));
length += line.length();
if (i == 0)
{
if (detail.at(detail.CountNode()-1).getTypeTool() == Tool::NodePoint)
{
begin = data->GeometricObject<VPointF>(detail.at(detail.CountNode()-1).getId())->toQPointF();
}
}
else
{
if (detail.at(i-1).getTypeTool() == Tool::NodePoint)
{
begin = data->GeometricObject<VPointF>(detail.at(i-1).getId())->toQPointF();
}
}
}
return qFloor(length);
return begin;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VEquidistant::EndSegment(const VDetail &detail, const int &i) const
{
QPointF end;
if (detail.CountNode() > 2)
{
if (i == detail.CountNode() - 1)
{
if (detail.at(0).getTypeTool() == Tool::NodePoint)
{
end = data->GeometricObject<VPointF>(detail.at(0).getId())->toQPointF();
}
}
else
{
if (detail.at(i+1).getTypeTool() == Tool::NodePoint)
{
end = data->GeometricObject<VPointF>(detail.at(i+1).getId())->toQPointF();
}
}
}
return end;
}
//---------------------------------------------------------------------------------------------------------------------
@ -320,18 +358,6 @@ QVector<QPointF> VEquidistant::CheckLoops(const QVector<QPointF> &points)
return ekvPoints;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VEquidistant::GetReversePoint(const QVector<QPointF> &points)
{
SCASSERT(points.size() > 0);
QVector<QPointF> reversePoints;
for (qint32 i = points.size() - 1; i >= 0; --i)
{
reversePoints.append(points.at(i));
}
return reversePoints;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VEquidistant::EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width)
{
@ -354,15 +380,22 @@ QVector<QPointF> VEquidistant::EkvPoint(const QLineF &line1, const QLineF &line2
case (QLineF::UnboundedIntersection):
{
QLineF line( line1.p2(), CrosPoint );
if (line.length() > width + qApp->toPixel(8))
{
QLineF lineL = QLineF(bigLine1.p2(), CrosPoint);
lineL.setLength(width);
points.append(lineL.p2());
const qreal length = line.length();
if (length > width*2.4)
{ // Cutting too long an acute angle
line.setLength(width); // Not sure about width value here
QLineF cutLine(line.p2(), CrosPoint); // Cut line is a perpendicular
cutLine.setLength(length); // Decided take this length
lineL = QLineF(bigLine2.p1(), CrosPoint);
lineL.setLength(width);
points.append(lineL.p2());
// We do not check intersection type because intersection must alwayse exist
QPointF px;
cutLine.setAngle(cutLine.angle()+90);
bigLine1.intersect( cutLine, &px );
points.append(px);
cutLine.setAngle(cutLine.angle()-180);
bigLine2.intersect( cutLine, &px );
points.append(px);
}
else
{
@ -400,28 +433,3 @@ QPointF VEquidistant::SingleParallelPoint(const QLineF &line, const qreal &angle
pLine.setLength( width );
return pLine.p2();
}
//---------------------------------------------------------------------------------------------------------------------
void VEquidistant::AddContour(const QVector<QPointF> &nodePoints, QVector<QPointF> &points, QVector<QPointF> &pointsEkv,
const VDetail &detail, int i)
{
int len1 = GetLengthContour(points, nodePoints);
QVector<QPointF> reversedPoints = GetReversePoint(nodePoints);
int lenReverse = GetLengthContour(points, reversedPoints);
if (len1 <= lenReverse)
{
points << nodePoints;
if (detail.getSeamAllowance() == true)
{
pointsEkv << biasPoints(nodePoints, detail.at(i).getMx(), detail.at(i).getMy());
}
}
else
{
points << reversedPoints;
if (detail.getSeamAllowance() == true)
{
pointsEkv << biasPoints(reversedPoints, detail.at(i).getMx(), detail.at(i).getMy());
}
}
}

View file

@ -42,21 +42,18 @@ class QLineF;
class VEquidistant
{
public:
VEquidistant(const VContainer *data);
~VEquidistant(){}
/**
* @brief ContourPath create painter path for detail.
* @param idDetail id of detail.
* @param data container with objects (points, arcs, splines).
* @return return painter path of contour detail.
*/
QPainterPath ContourPath(const quint32 &idDetail, const VContainer *data) const;
QPainterPath ContourPath(const quint32 &idDetail) const;
private:
/**
* @brief GetLengthContour return length of contour.
* @param contour container with points of contour.
* @param newPoints point whos we try to add to contour.
* @return length length of contour.
*/
static int GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints);
Q_DISABLE_COPY(VEquidistant)
const VContainer *data;
/**
* @brief biasPoints bias point.
* @param points vector of points.
@ -85,12 +82,6 @@ private:
* @return vector of points of equidistant.
*/
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
/**
* @brief GetReversePoint return revers container of points.
* @param points container with points.
* @return reverced points.
*/
static QVector<QPointF> GetReversePoint(const QVector<QPointF> &points);
/**
* @brief EkvPoint return vector of points of equidistant two lines. Last point of two lines must be equal.
* @param line1 first line.
@ -115,8 +106,8 @@ private:
*/
static QPointF SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width);
static void AddContour(const QVector<QPointF> &nodePoints, QVector<QPointF> &points,
QVector<QPointF> &pointsEkv, const VDetail &detail, int i);
QPointF StartSegment(const VDetail &detail, const int &i) const;
QPointF EndSegment(const VDetail &detail, const int &i) const;
};
#endif // VEQUIDISTANT_H

View file

@ -350,3 +350,70 @@ void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c
*b = p1.x() - line.p2().x();
*c = - *a * p1.x() - *b * p1.y();
}
//---------------------------------------------------------------------------------------------------------------------
bool VGObject::PointInSegment(const QPointF &t, const QPointF &p1, const QPointF &p2)
{
const qreal eps = 1e-8;
qreal a = p2.y() - p1.y();
qreal b = p1.x() - p2.x();
qreal c = - a * p1.x() - b * p1.y();
if (qAbs(a * t.x() + b * t.y() + c) > eps)
{
return false;
}
return PointInBox (t, p1, p2);
}
//---------------------------------------------------------------------------------------------------------------------
bool VGObject::PointInBox(const QPointF &t, const QPointF &p1, const QPointF &p2)
{
const qreal eps = 1e-8;
return (qAbs (t.x() - qMin(p1.x(), p2.x())) <= eps || qMin(p1.x(), p2.x()) <= t.x()) &&
(qAbs (qMax(p1.x(), p2.x()) - t.x()) <= eps || qMax(p1.x(), p2.x()) >= t.x()) &&
(qAbs (t.y() - qMin(p1.y(), p2.y())) <= eps || qMin(p1.y(), p2.y()) <= t.y()) &&
(qAbs (qMax(p1.y(), p2.y()) - t.y()) <= eps || qMax(p1.y(), p2.y()) >= t.y());
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetReversePoint return revers container of points.
* @param points container with points.
* @return reverced points.
*/
QVector<QPointF> VGObject::GetReversePoints(const QVector<QPointF> &points)
{
if (points.isEmpty())
{
return points;
}
QVector<QPointF> reversePoints;
for (qint32 i = points.size() - 1; i >= 0; --i)
{
reversePoints.append(points.at(i));
}
return reversePoints;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetLengthContour return length of contour.
* @param contour container with points of contour.
* @param newPoints point whos we try to add to contour.
* @return length length of contour.
*/
int VGObject::GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints)
{
qreal length = 0;
QVector<QPointF> points;
points << contour << newPoints;
for (qint32 i = 0; i < points.size()-1; ++i)
{
QLineF line(points.at(i), points.at(i+1));
length += line.length();
}
return qFloor(length);
}

View file

@ -77,6 +77,11 @@ public:
static QPointF ClosestPoint(const QLineF &line, const QPointF &point);
static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k);
static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c);
static bool PointInSegment (const QPointF &t, const QPointF &p1, const QPointF &p2);
static bool PointInBox (const QPointF &t, const QPointF &p1, const QPointF &p2);
static QVector<QPointF> GetReversePoints(const QVector<QPointF> &points);
static int GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints);
private:
QSharedDataPointer<VGObjectData> d;
};

View file

@ -35,8 +35,8 @@ VNodeDetail::VNodeDetail()
{}
//---------------------------------------------------------------------------------------------------------------------
VNodeDetail::VNodeDetail(quint32 id, Tool typeTool, NodeDetail typeNode, qreal mx, qreal my)
:d(new VNodeDetailData(id, typeTool, typeNode, mx, my))
VNodeDetail::VNodeDetail(quint32 id, Tool typeTool, NodeDetail typeNode, qreal mx, qreal my, bool reverse)
:d(new VNodeDetailData(id, typeTool, typeNode, mx, my, reverse))
{}
//---------------------------------------------------------------------------------------------------------------------
@ -118,3 +118,29 @@ void VNodeDetail::setMy(const qreal &value)
{
d->my = value;
}
//---------------------------------------------------------------------------------------------------------------------
bool VNodeDetail::getReverse() const
{
if (getTypeTool() == Tool::NodePoint)
{
return false;
}
else
{
return d->reverse;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VNodeDetail::setReverse(bool reverse)
{
if (getTypeTool() == Tool::NodePoint)
{
d->reverse = false;
}
else
{
d->reverse = reverse;
}
}

View file

@ -53,7 +53,7 @@ public:
* @param mx object bias x axis
* @param my object bias y axis
*/
VNodeDetail(quint32 id, Tool typeTool, NodeDetail typeNode, qreal mx = 0, qreal my = 0);
VNodeDetail(quint32 id, Tool typeTool, NodeDetail typeNode, qreal mx = 0, qreal my = 0, bool reverse = false);
/**
* @brief VNodeDetail copy constructor
* @param node node
@ -116,6 +116,9 @@ public:
* @param value bias y axis.
*/
void setMy(const qreal &value);
bool getReverse() const;
void setReverse(bool reverse);
private:
QSharedDataPointer<VNodeDetailData> d;
};

View file

@ -41,15 +41,16 @@ class VNodeDetailData : public QSharedData
{
public:
VNodeDetailData()
:id(NULL_ID), typeTool(Tool::NodePoint), typeNode(NodeDetail::Contour), mx(0), my(0)
:id(NULL_ID), typeTool(Tool::NodePoint), typeNode(NodeDetail::Contour), mx(0), my(0), reverse(false)
{}
VNodeDetailData(quint32 id, Tool typeTool, NodeDetail typeNode, qreal mx, qreal my)
:id(id), typeTool(typeTool), typeNode(typeNode), mx(mx), my(my)
VNodeDetailData(quint32 id, Tool typeTool, NodeDetail typeNode, qreal mx, qreal my, bool reverse)
:id(id), typeTool(typeTool), typeNode(typeNode), mx(mx), my(my), reverse(reverse)
{}
VNodeDetailData (const VNodeDetailData& node)
:QSharedData(node), id(node.id), typeTool(node.typeTool), typeNode(node.typeNode), mx(node.mx), my(node.my)
:QSharedData(node), id(node.id), typeTool(node.typeTool), typeNode(node.typeNode), mx(node.mx), my(node.my),
reverse(node.reverse)
{}
~VNodeDetailData() {}
@ -74,6 +75,10 @@ public:
* @brief my bias y axis.
*/
qreal my;
/**
* @brief reverse true if need reverse points list for node.
*/
bool reverse;
};
#ifdef Q_CC_GNU

View file

@ -1454,6 +1454,8 @@ void MainWindow::Clear()
qCDebug(vMainWindow)<<"Reseting main window";
delete lock; // Unlock pattern file
lock = nullptr;
ui->actionDetails->setChecked(false);
ui->actionDetails->setEnabled(false);
ui->actionDraw->setChecked(true);
@ -1901,7 +1903,7 @@ void MainWindow::ActionLayout(bool checked)
while (idetail.hasNext())
{
idetail.next();
QPainterPath path = VEquidistant().ContourPath(idetail.key(), pattern);
QPainterPath path = VEquidistant(pattern).ContourPath(idetail.key());
listDetails.append(new VItem(path, listDetails.size()));
}
QString description = doc->GetDescription();
@ -2453,6 +2455,7 @@ QStringList MainWindow::GetUnlokedRestoreFileList() const
restoreFiles.append(files.at(i));
}
delete lock;
lock = nullptr;
}
// Clearing list after filtering

View file

@ -217,9 +217,9 @@ void VNodeArc::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
void VNodeArc::RefreshGeometry()
{
const QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(id);
QPainterPath path;
path.addPath(arc->GetPath());
path.setFillRule( Qt::WindingFill );
this->setPath(path);
// const QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(id);
// QPainterPath path;
// path.addPath(arc->GetPath());
// path.setFillRule( Qt::WindingFill );
// this->setPath(path);
}

View file

@ -220,9 +220,9 @@ void VNodeSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
void VNodeSpline::RefreshGeometry()
{
const QSharedPointer<VSpline> spl = VAbstractTool::data.GeometricObject<VSpline>(id);
QPainterPath path;
path.addPath(spl->GetPath());
path.setFillRule( Qt::WindingFill );
this->setPath(path);
// const QSharedPointer<VSpline> spl = VAbstractTool::data.GeometricObject<VSpline>(id);
// QPainterPath path;
// path.addPath(spl->GetPath());
// path.setFillRule( Qt::WindingFill );
// this->setPath(path);
}

View file

@ -223,9 +223,9 @@ void VNodeSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
void VNodeSplinePath::RefreshGeometry()
{
const QSharedPointer<VSplinePath> splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
QPainterPath path;
path.addPath(splPath->GetPath());
path.setFillRule( Qt::WindingFill );
this->setPath(path);
// const QSharedPointer<VSplinePath> splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
// QPainterPath path;
// path.addPath(splPath->GetPath());
// path.setFillRule( Qt::WindingFill );
// this->setPath(path);
}

View file

@ -52,6 +52,7 @@ const QString VToolDetail::AttrClosed = QStringLiteral("closed");
const QString VToolDetail::AttrWidth = QStringLiteral("width");
const QString VToolDetail::AttrIdObject = QStringLiteral("idObject");
const QString VToolDetail::AttrNodeType = QStringLiteral("nodeType");
const QString VToolDetail::AttrReverse = QStringLiteral("reverse");
const QString VToolDetail::NodeTypeContour = QStringLiteral("Contour");
const QString VToolDetail::NodeTypeModeling = QStringLiteral("Modeling");
@ -181,7 +182,8 @@ void VToolDetail::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern
qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO;
break;
}
VNodeDetail node(id, detail.at(i).getTypeTool(), NodeDetail::Contour);
VNodeDetail node(id, detail.at(i).getTypeTool(), NodeDetail::Contour, detail.at(i).getMx(),
detail.at(i).getMy(), detail.at(i).getReverse());
det.append(node);
}
det.setName(detail.getName());
@ -455,6 +457,12 @@ void VToolDetail::AddNode(VPattern *doc, QDomElement &domElement, const VNodeDet
doc->SetAttribute(nod, AttrIdObject, node.getId());
doc->SetAttribute(nod, AttrMx, qApp->fromPixel(node.getMx()));
doc->SetAttribute(nod, AttrMy, qApp->fromPixel(node.getMy()));
if (node.getTypeTool() != Tool::NodePoint)
{
doc->SetAttribute(nod, AttrReverse, static_cast<quint8>(node.getReverse()));
}
if (node.getTypeNode() == NodeDetail::Contour)
{
doc->SetAttribute(nod, AttrNodeType, NodeTypeContour);
@ -503,7 +511,7 @@ void VToolDetail::ShowVisualization(bool show)
void VToolDetail::RefreshGeometry()
{
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
QPainterPath path = VEquidistant().ContourPath(id, this->getData());
QPainterPath path = VEquidistant(this->getData()).ContourPath(id);
this->setPath(path);
VDetail detail = VAbstractTool::data.GetDetail(id);
@ -511,6 +519,7 @@ void VToolDetail::RefreshGeometry()
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
//---------------------------------------------------------------------------------------------------------------------
void VToolDetail::DeleteTool(bool ask)
{
DeleteDetail *delDet = new DeleteDetail(doc, id);

View file

@ -74,6 +74,7 @@ public:
static const QString AttrWidth;
static const QString AttrIdObject;
static const QString AttrNodeType;
static const QString AttrReverse;
static const QString NodeTypeContour;
static const QString NodeTypeModeling;
static const QString NodeArc;

View file

@ -257,7 +257,7 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VPattern *doc, VContainer
qDebug()<<"May be wrong tool type!!! Ignoring."<<Q_FUNC_INFO;
break;
}
newDetail.append(VNodeDetail(id, det.at(i).getTypeTool(), NodeDetail::Contour));
newDetail.append(VNodeDetail(id, det.at(i).getTypeTool(), NodeDetail::Contour, 0, 0, det.at(i).getReverse()));
}
//---------------------------------------------------------------------------------------------------------------------
@ -694,6 +694,7 @@ QVector<VDetail> VToolUnionDetails::GetDetailFromFile(VPattern *doc, const QDomE
quint32 id = doc->GetParametrUInt(element, VToolDetail::AttrIdObject, NULL_ID_STR);
qreal mx = qApp->toPixel(doc->GetParametrDouble(element, VAbstractTool::AttrMx, "0.0"));
qreal my = qApp->toPixel(doc->GetParametrDouble(element, VAbstractTool::AttrMy, "0.0"));
const bool reversed = doc->GetParametrUInt(element, VToolDetail::AttrReverse, "0");
Tool tool = Tool::NodePoint;
NodeDetail nodeType = NodeDetail::Contour;
QString t = doc->GetParametrString(element, "type", "NodePoint");
@ -713,7 +714,7 @@ QVector<VDetail> VToolUnionDetails::GetDetailFromFile(VPattern *doc, const QDomE
{
tool = Tool::NodeSplinePath;
}
d.append(VNodeDetail(id, tool, nodeType, mx, my));
d.append(VNodeDetail(id, tool, nodeType, mx, my, reversed));
}
}
}

View file

@ -514,16 +514,6 @@ void VPattern::DecrementReferens(quint32 id) const
tool->decrementReferens();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief TestUniqueId test exist unique id in pattern file. Each id must be unique.
*/
void VPattern::TestUniqueId() const
{
QVector<quint32> vector;
CollectId(documentElement(), vector);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief SPointActiveDraw return id base point current pattern peace.
@ -717,7 +707,7 @@ MeasurementsType VPattern::MType() const
}
//---------------------------------------------------------------------------------------------------------------------
bool VPattern::SaveDocument(const QString &fileName, QString &error)
bool VPattern::SaveDocument(const QString &fileName, QString &error) const
{
try
{
@ -990,6 +980,7 @@ void VPattern::ParseDetailElement(const QDomElement &domElement, const Document
const quint32 id = GetParametrUInt(element, VToolDetail::AttrIdObject, NULL_ID_STR);
const qreal mx = qApp->toPixel(GetParametrDouble(element, VAbstractTool::AttrMx, "0.0"));
const qreal my = qApp->toPixel(GetParametrDouble(element, VAbstractTool::AttrMy, "0.0"));
const bool reverse = GetParametrUInt(element, VToolDetail::AttrReverse, "0");
const NodeDetail nodeType = NodeDetail::Contour;
const QString t = GetParametrString(element, AttrType, "NodePoint");
@ -1014,7 +1005,7 @@ void VPattern::ParseDetailElement(const QDomElement &domElement, const Document
continue;
break;
}
detail.append(VNodeDetail(id, tool, nodeType, mx, my));
detail.append(VNodeDetail(id, tool, nodeType, mx, my, reverse));
}
}
}
@ -2075,36 +2066,6 @@ void VPattern::ParseIncrementsElement(const QDomNode &node)
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetParametrId return value id attribute.
* @param domElement tag in xml tree.
* @return id value.
*/
quint32 VPattern::GetParametrId(const QDomElement &domElement) const
{
Q_ASSERT_X(domElement.isNull() == false, Q_FUNC_INFO, "domElement is null");
quint32 id = 0;
QString message = tr("Got wrong parameter id. Need only id > 0.");
try
{
id = GetParametrUInt(domElement, VDomDocument::AttrId, NULL_ID_STR);
if (id <= 0)
{
throw VExceptionWrongId(message, domElement);
}
}
catch (const VExceptionConversionError &e)
{
VExceptionWrongId excep(message, domElement);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
return id;
}
//---------------------------------------------------------------------------------------------------------------------
QMap<GHeights, bool> VPattern::GetGradationHeights() const
{
@ -2507,34 +2468,6 @@ QString VPattern::GenerateLabel(const LabelType &type) const
return QString();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief CollectId recursive function, try find id attribute in file. Throw exclusion if find not unique.
* @param node tag in xml tree.
* @param vector list with ids.
*/
void VPattern::CollectId(const QDomElement &node, QVector<quint32> &vector) const
{
if (node.hasAttribute(VDomDocument::AttrId))
{
const quint32 id = GetParametrId(node);
if (vector.contains(id))
{
throw VExceptionWrongId(tr("This id is not unique."), node);
}
vector.append(id);
}
for (qint32 i=0; i<node.childNodes().length(); ++i)
{
const QDomNode n = node.childNodes().at(i);
if (n.isElement())
{
CollectId(n.toElement(), vector);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::PrepareForParse(const Document &parse)
{

View file

@ -71,7 +71,6 @@ public:
void UpdateToolData(const quint32 &id, VContainer *data);
void IncrementReferens(quint32 id) const;
void DecrementReferens(quint32 id) const;
void TestUniqueId() const;
quint32 SPointActiveDraw();
bool isPatternModified() const;
void setPatternModified(bool value);
@ -150,10 +149,9 @@ public:
static const QString IncrementKgrowth;
static const QString IncrementDescription;
virtual bool SaveDocument(const QString &fileName, QString &error);
virtual bool SaveDocument(const QString &fileName, QString &error) const;
QStringList getPatternPieces() const;
QRectF ActiveDrawBoundingRect() const;
quint32 GetParametrId(const QDomElement& domElement) const;
QMap<GHeights, bool> GetGradationHeights() const;
void SetGradationHeights(const QMap<GHeights, bool> &options);
@ -265,7 +263,6 @@ private:
void ParseToolsElement(VMainGraphicsScene *scene, const QDomElement& domElement,
const Document &parse, const QString& type);
void ParseIncrementsElement(const QDomNode& node);
void CollectId(const QDomElement &node, QVector<quint32> &vector)const;
void PrepareForParse(const Document &parse);
void UpdateMeasurements();
void ToolsCommonAttributes(const QDomElement &domElement, quint32 &id);

View file

@ -3,5 +3,6 @@
<file>schema/individual_measurements.xsd</file>
<file>schema/standard_measurements.xsd</file>
<file>schema/pattern/v0.1.1.xsd</file>
<file>schema/pattern/v0.1.2.xsd</file>
</qresource>
</RCC>

View file

@ -0,0 +1,292 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document-->
<xs:element name="pattern">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="version" type="formatVersion"></xs:element>
<xs:element name="author" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="gradation" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="heights">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"></xs:attribute>
<xs:attribute name="h92" type="xs:boolean"></xs:attribute>
<xs:attribute name="h98" type="xs:boolean"></xs:attribute>
<xs:attribute name="h104" type="xs:boolean"></xs:attribute>
<xs:attribute name="h110" type="xs:boolean"></xs:attribute>
<xs:attribute name="h116" type="xs:boolean"></xs:attribute>
<xs:attribute name="h122" type="xs:boolean"></xs:attribute>
<xs:attribute name="h128" type="xs:boolean"></xs:attribute>
<xs:attribute name="h134" type="xs:boolean"></xs:attribute>
<xs:attribute name="h140" type="xs:boolean"></xs:attribute>
<xs:attribute name="h146" type="xs:boolean"></xs:attribute>
<xs:attribute name="h152" type="xs:boolean"></xs:attribute>
<xs:attribute name="h158" type="xs:boolean"></xs:attribute>
<xs:attribute name="h164" type="xs:boolean"></xs:attribute>
<xs:attribute name="h170" type="xs:boolean"></xs:attribute>
<xs:attribute name="h176" type="xs:boolean"></xs:attribute>
<xs:attribute name="h182" type="xs:boolean"></xs:attribute>
<xs:attribute name="h188" type="xs:boolean"></xs:attribute>
<xs:attribute name="h194" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="sizes">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"></xs:attribute>
<xs:attribute name="s22" type="xs:boolean"></xs:attribute>
<xs:attribute name="s24" type="xs:boolean"></xs:attribute>
<xs:attribute name="s26" type="xs:boolean"></xs:attribute>
<xs:attribute name="s28" type="xs:boolean"></xs:attribute>
<xs:attribute name="s30" type="xs:boolean"></xs:attribute>
<xs:attribute name="s32" type="xs:boolean"></xs:attribute>
<xs:attribute name="s34" type="xs:boolean"></xs:attribute>
<xs:attribute name="s36" type="xs:boolean"></xs:attribute>
<xs:attribute name="s38" type="xs:boolean"></xs:attribute>
<xs:attribute name="s40" type="xs:boolean"></xs:attribute>
<xs:attribute name="s42" type="xs:boolean"></xs:attribute>
<xs:attribute name="s44" type="xs:boolean"></xs:attribute>
<xs:attribute name="s46" type="xs:boolean"></xs:attribute>
<xs:attribute name="s48" type="xs:boolean"></xs:attribute>
<xs:attribute name="s50" type="xs:boolean"></xs:attribute>
<xs:attribute name="s52" type="xs:boolean"></xs:attribute>
<xs:attribute name="s54" type="xs:boolean"></xs:attribute>
<xs:attribute name="s56" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="measurements" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="type" type="measurementsTypes" use="required"></xs:attribute>
<xs:attribute name="path" type="xs:string" use="required"></xs:attribute>
<xs:attribute name="unit" type="units" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="increments" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="increment" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="ksize" type="xs:double" use="required"></xs:attribute>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="description" type="xs:string" use="required"></xs:attribute>
<xs:attribute name="kgrowth" type="xs:double" use="required"></xs:attribute>
<xs:attribute name="name" type="shortName" use="required"></xs:attribute>
<xs:attribute name="base" type="xs:double" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="draw" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="calculation" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="x" type="xs:double"></xs:attribute>
<xs:attribute name="y" type="xs:double"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="name" type="shortName"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="thirdPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="basePoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="pShoulder" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="length" type="xs:string"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="typeLine" type="xs:string"></xs:attribute>
<xs:attribute name="splinePath" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="spline" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="radius" type="xs:string"></xs:attribute>
<xs:attribute name="axisP1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="axisP2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="arc" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="curve" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeLine" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="angle1" type="xs:string"></xs:attribute>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="angle2" type="xs:string"></xs:attribute>
<xs:attribute name="radius" type="xs:string"></xs:attribute>
<xs:attribute name="center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="pathPoint" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="kAsm2" type="xs:string"></xs:attribute>
<xs:attribute name="pSpline" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="kCurve" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:double"></xs:attribute>
<xs:attribute name="kAsm2" type="xs:double"></xs:attribute>
<xs:attribute name="angle1" type="xs:double"></xs:attribute>
<xs:attribute name="angle2" type="xs:double"></xs:attribute>
<xs:attribute name="point1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="point4" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="modeling" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="tools" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="det" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="indexD1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="indexD2" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="details" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="detail" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="reverse" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="supplement" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="width" type="xs:double"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
<xs:attribute name="closed" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="shortName">
<xs:restriction base="xs:string">
<xs:pattern value="^([^0-9-*/^+=\s\(\)%:;!.,`'\&quot;]){1,1}([^-*/^+=\s\(\)%:;!.,`'\&quot;]){0,}$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="units">
<xs:restriction base="xs:string">
<xs:enumeration value="mm"/>
<xs:enumeration value="cm"/>
<xs:enumeration value="inch"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="measurementsTypes">
<xs:restriction base="xs:string">
<xs:enumeration value="standard"/>
<xs:enumeration value="individual"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="formatVersion">
<xs:restriction base="xs:string">
<xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View file

@ -28,6 +28,7 @@
#include "vabstractconverter.h"
#include "exception/vexception.h"
#include "exception/vexceptionwrongid.h"
#include <QFile>
@ -45,7 +46,7 @@ VAbstractConverter::~VAbstractConverter()
{}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractConverter::Convert() const
void VAbstractConverter::Convert()
{
if (ver == MaxVer())
{
@ -158,3 +159,40 @@ void VAbstractConverter::CheckVersion(int ver) const
throw VException(errorMsg);
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractConverter::SaveDocument(const QString &fileName, QString &error) const
{
try
{
TestUniqueId();
}
catch (const VExceptionWrongId &e)
{
error = tr("Error no unique id.");
return false;
}
return VDomDocument::SaveDocument(fileName, error);
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractConverter::Save() const
{
QString error;
if (SaveDocument(fileName, error) == false)
{
VException e(error);
throw e;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractConverter::SetVersion(const QString &version)
{
if (setTagText(TagVersion, version) == false)
{
VException e(tr("Could not change version."));
throw e;
}
}

View file

@ -38,7 +38,8 @@ public:
VAbstractConverter(const QString &fileName);
virtual ~VAbstractConverter();
void Convert() const;
void Convert();
virtual bool SaveDocument(const QString &fileName, QString &error) const;
protected:
int ver;
@ -46,6 +47,8 @@ protected:
int GetVersion(const QString &version) const;
void CheckVersion(int ver) const;
void Save() const;
void SetVersion(const QString &version);
virtual int MinVer() const =0;
virtual int MaxVer() const =0;
@ -54,7 +57,7 @@ protected:
virtual QString MaxVerStr() const =0;
virtual QString XSDSchema(int ver) const =0;
virtual void ApplyPatches() const =0;
virtual void ApplyPatches() =0;
private:
Q_DISABLE_COPY(VAbstractConverter)

View file

@ -30,6 +30,7 @@
#include "exception/vexceptionconversionerror.h"
#include "exception/vexceptionemptyparameter.h"
#include "exception/vexceptionbadid.h"
#include "exception/vexceptionwrongid.h"
#include <QAbstractMessageHandler>
#include <QXmlSchema>
@ -323,6 +324,36 @@ qreal VDomDocument::GetParametrDouble(const QDomElement &domElement, const QStri
return param;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetParametrId return value id attribute.
* @param domElement tag in xml tree.
* @return id value.
*/
quint32 VDomDocument::GetParametrId(const QDomElement &domElement) const
{
Q_ASSERT_X(domElement.isNull() == false, Q_FUNC_INFO, "domElement is null");
quint32 id = 0;
QString message = tr("Got wrong parameter id. Need only id > 0.");
try
{
id = GetParametrUInt(domElement, VDomDocument::AttrId, NULL_ID_STR);
if (id <= 0)
{
throw VExceptionWrongId(message, domElement);
}
}
catch (const VExceptionConversionError &e)
{
VExceptionWrongId excep(message, domElement);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
return id;
}
//---------------------------------------------------------------------------------------------------------------------
QString VDomDocument::UniqueTagText(const QString &tagName, const QString &defVal) const
{
@ -346,6 +377,39 @@ QString VDomDocument::UniqueTagText(const QString &tagName, const QString &defVa
return defVal;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief TestUniqueId test exist unique id in pattern file. Each id must be unique.
*/
void VDomDocument::TestUniqueId() const
{
QVector<quint32> vector;
CollectId(documentElement(), vector);
}
//---------------------------------------------------------------------------------------------------------------------
void VDomDocument::CollectId(const QDomElement &node, QVector<quint32> &vector) const
{
if (node.hasAttribute(VDomDocument::AttrId))
{
const quint32 id = GetParametrId(node);
if (vector.contains(id))
{
throw VExceptionWrongId(tr("This id is not unique."), node);
}
vector.append(id);
}
for (qint32 i=0; i<node.childNodes().length(); ++i)
{
const QDomNode n = node.childNodes().at(i);
if (n.isElement())
{
CollectId(n.toElement(), vector);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief ValidateXML validate xml file by xsd schema.
@ -514,7 +578,7 @@ QString VDomDocument::UnitsToStr(const Unit &unit, const bool translate)
}
//---------------------------------------------------------------------------------------------------------------------
bool VDomDocument::SaveDocument(const QString &fileName, QString &error)
bool VDomDocument::SaveDocument(const QString &fileName, QString &error) const
{
if (fileName.isEmpty())
{
@ -565,13 +629,12 @@ QString VDomDocument::Patch() const
}
//---------------------------------------------------------------------------------------------------------------------
void VDomDocument::setTagText(const QString &tag, const QString &text)
bool VDomDocument::setTagText(const QString &tag, const QString &text)
{
const QDomNodeList nodeList = this->elementsByTagName(tag);
if (nodeList.isEmpty())
{
qDebug()<<"Can't save tag "<<tag<<Q_FUNC_INFO;
return;
}
else
{
@ -587,10 +650,11 @@ void VDomDocument::setTagText(const QString &tag, const QString &text)
newTag.appendChild(newTagText);
parent.replaceChild(newTag, domElement);
return;
return true;
}
}
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -38,11 +38,6 @@
Q_DECLARE_LOGGING_CATEGORY(vXML)
/*
can be used like #if (V_FORMAT_VERSION >= V_FORMAT_VERSION_CHECK(4, 4, 0))
*/
#define V_FORMAT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
#ifdef Q_CC_GNU
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
@ -104,12 +99,13 @@ public:
QString GetParametrString(const QDomElement& domElement, const QString &name,
const QString &defValue = QString()) const;
qreal GetParametrDouble(const QDomElement& domElement, const QString &name, const QString &defValue) const;
quint32 GetParametrId(const QDomElement& domElement) const;
static void ValidateXML(const QString &schema, const QString &fileName);
void setXMLContent(const QString &fileName);
static Unit StrToUnits(const QString &unit);
static QString UnitsToStr(const Unit &unit, const bool translate = false);
virtual bool SaveDocument(const QString &fileName, QString &error);
virtual bool SaveDocument(const QString &fileName, QString &error) const;
QString Major() const;
QString Minor() const;
QString Patch() const;
@ -118,12 +114,16 @@ public:
QDomNode ParentNodeById(const quint32 &nodeId);
QDomElement CloneNodeById(const quint32 &nodeId);
QDomElement NodeById(const quint32 &nodeId);
static bool SafeCopy(const QString &source, const QString &destination, QString &error);
protected:
void setTagText(const QString &tag, const QString &text);
bool setTagText(const QString &tag, const QString &text);
QString UniqueTagText(const QString &tagName, const QString &defVal = QString()) const;
void TestUniqueId() const;
void CollectId(const QDomElement &node, QVector<quint32> &vector)const;
private:
Q_DISABLE_COPY(VDomDocument)
/** @brief Map used for finding element by id. */

View file

@ -40,8 +40,8 @@
*/
const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.1");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.1.1");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.1.1.xsd");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.1.2");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.1.2.xsd");
//---------------------------------------------------------------------------------------------------------------------
VPatternConverter::VPatternConverter(const QString &fileName)
@ -87,6 +87,8 @@ QString VPatternConverter::XSDSchema(int ver) const
switch(ver)
{
case (0x000101):
return QStringLiteral("://schema/pattern/v0.1.1.xsd");
case (0x000102):
return CurrentSchema;
default:
{
@ -98,13 +100,20 @@ QString VPatternConverter::XSDSchema(int ver) const
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ApplyPatches() const
void VPatternConverter::ApplyPatches()
{
try
{
switch(ver)
{
case (0x000101):
{
ToV0_1_2();
const QString schema = XSDSchema(0x000102);
ValidateXML(schema, fileName);
break;
}
case (0x000102):
break;
default:
break;
@ -128,3 +137,10 @@ void VPatternConverter::ApplyPatches() const
throw e;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ToV0_1_2()
{
SetVersion("0.1.2");
Save();
}

View file

@ -48,11 +48,13 @@ protected:
virtual QString MaxVerStr() const;
QString XSDSchema(int ver) const;
virtual void ApplyPatches() const;
virtual void ApplyPatches();
private:
Q_DISABLE_COPY(VPatternConverter)
static const QString PatternMinVerStr;
void ToV0_1_2();
};
#endif // VPATTERNCONVERTER_H