1 /************************************************************************
2  **
3  **  @file   vcontainer.cpp
4  **  @author Roman Telezhynskyi <dismine(at)gmail.com>
5  **  @date   November 15, 2013
6  **
7  **  @brief
8  **  @copyright
9  **  This source code is part of the Valentina project, a pattern making
10  **  program, whose allow create and modeling patterns of clothing.
11  **  Copyright (C) 2013-2015 Valentina project
12  **  <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
13  **
14  **  Valentina is free software: you can redistribute it and/or modify
15  **  it under the terms of the GNU General Public License as published by
16  **  the Free Software Foundation, either version 3 of the License, or
17  **  (at your option) any later version.
18  **
19  **  Valentina is distributed in the hope that it will be useful,
20  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  **  GNU General Public License for more details.
23  **
24  **  You should have received a copy of the GNU General Public License
25  **  along with Valentina.  If not, see <http://www.gnu.org/licenses/>.
26  **
27  *************************************************************************/
28 
29 #include "vcontainer.h"
30 
31 #include <climits>
32 #include <QVector>
33 #include <QtDebug>
34 #include <QUuid>
35 #include <QLoggingCategory>
36 
37 #include "../ifc/exception/vexception.h"
38 #include "../vgeometry/vabstractcubicbezierpath.h"
39 #include "../vgeometry/vabstractcurve.h"
40 #include "../vgeometry/vgeometrydef.h"
41 #include "../vgeometry/vgobject.h"
42 #include "../vgeometry/vpointf.h"
43 #include "../vgeometry/vspline.h"
44 #include "../vgeometry/varc.h"
45 #include "../vgeometry/vellipticalarc.h"
46 #include "../vmisc/diagnostic.h"
47 #include "../vmisc/vabstractapplication.h"
48 #include "variables/varcradius.h"
49 #include "variables/vcurveangle.h"
50 #include "variables/vcurvelength.h"
51 #include "variables/vcurveclength.h"
52 #include "variables/vincrement.h"
53 #include "variables/vlineangle.h"
54 #include "variables/vlinelength.h"
55 #include "variables/vmeasurement.h"
56 #include "variables/vvariable.h"
57 #include "vtranslatevars.h"
58 
59 QT_WARNING_PUSH
60 QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes")
61 QT_WARNING_DISABLE_INTEL(1418)
62 
63 Q_LOGGING_CATEGORY(vCon, "v.container")
64 
65 QT_WARNING_POP
66 
67 QMap<QString, quint32> VContainer::_id = QMap<QString, quint32>();
68 QMap<QString, QSet<QString>> VContainer::uniqueNames = QMap<QString, QSet<QString>>();
69 QMap<QString, quint32> VContainer::copyCounter = QMap<QString, quint32>();
70 
71 //---------------------------------------------------------------------------------------------------------------------
72 /**
73  * @brief VContainer create empty container
74  */
VContainer(const VTranslateVars * trVars,const Unit * patternUnit,const QString & nspace)75 VContainer::VContainer(const VTranslateVars *trVars, const Unit *patternUnit, const QString &nspace)
76     :d(new VContainerData(trVars, patternUnit, nspace))
77 {
78     if (nspace.isEmpty())
79     {
80         qFatal("Namesapce is empty.");
81     }
82 
83     if (VContainer::_id.contains(nspace))
84     {
85         qFatal("Namespace is not unique.");
86     }
87 
88     if (not _id.contains(d->nspace))
89     {
90         _id[d->nspace] = NULL_ID;
91     }
92 
93     if (not uniqueNames.contains(d->nspace))
94     {
95         uniqueNames[d->nspace] = QSet<QString>();
96     }
97 
98     if (not copyCounter.contains(d->nspace))
99     {
100         copyCounter[d->nspace] = 1;
101     }
102 }
103 
104 //---------------------------------------------------------------------------------------------------------------------
105 /**
106  * @brief operator = copy constructor
107  * @param data container
108  * @return copy container
109  */
operator =(const VContainer & data)110 VContainer &VContainer::operator =(const VContainer &data)
111 {
112     if ( &data == this )
113     {
114         return *this;
115     }
116     d = data.d;
117     ++copyCounter[d->nspace];
118     return *this;
119 }
120 
121 #ifdef Q_COMPILER_RVALUE_REFS
122 //---------------------------------------------------------------------------------------------------------------------
VContainer(const VContainer && data)123 VContainer::VContainer(const VContainer &&data) Q_DECL_NOTHROW
124     :d(data.d)
125 {}
126 
127 //---------------------------------------------------------------------------------------------------------------------
operator =(VContainer && data)128 VContainer &VContainer::operator=(VContainer &&data) Q_DECL_NOTHROW
129 {
130     std::swap(d, data.d);
131     return *this;
132 }
133 #endif
134 
135 //---------------------------------------------------------------------------------------------------------------------
136 /**
137  * @brief VContainer create container from another container
138  * @param data container
139  */
VContainer(const VContainer & data)140 VContainer::VContainer(const VContainer &data)
141     :d(data.d)
142 {
143     ++copyCounter[d->nspace];
144 }
145 
146 //---------------------------------------------------------------------------------------------------------------------
~VContainer()147 VContainer::~VContainer()
148 {}
149 
150 //---------------------------------------------------------------------------------------------------------------------
UniqueNamespace()151 QString VContainer::UniqueNamespace()
152 {
153     QString candidate;
154     do
155     {
156         candidate = QUuid::createUuid().toString();
157     }
158     while(_id.contains(candidate));
159 
160     return candidate;
161 }
162 
163 //---------------------------------------------------------------------------------------------------------------------
ClearNamespace(const QString & nspace)164 void VContainer::ClearNamespace(const QString &nspace)
165 {
166     _id.remove(nspace);
167     uniqueNames.remove(nspace);
168 }
169 
170 //---------------------------------------------------------------------------------------------------------------------
171 /**
172  * @brief GetGObject returns a point by id
173  * @param id id of point
174  * @return point
175  */
176 // cppcheck-suppress unusedFunction
GetGObject(quint32 id) const177 const QSharedPointer<VGObject> VContainer::GetGObject(quint32 id) const
178 {
179     if (d->calculationObjects.contains(id))
180     {
181         return d->calculationObjects.value(id);
182     }
183     else if (d->modelingObjects->contains(id))
184     {
185         return d->modelingObjects->value(id);
186     }
187     else
188     {
189         throw VExceptionBadId(tr("Can't find object"), id);
190     }
191 }
192 
193 //---------------------------------------------------------------------------------------------------------------------
GetFakeGObject(quint32 id)194 const QSharedPointer<VGObject> VContainer::GetFakeGObject(quint32 id)
195 {
196     VGObject *obj = new VGObject();
197     obj->setId(id);
198     QSharedPointer<VGObject> pointer(obj);
199     return pointer;
200 }
201 
202 //---------------------------------------------------------------------------------------------------------------------
GetPiece(quint32 id) const203 VPiece VContainer::GetPiece(quint32 id) const
204 {
205     if (d->pieces->contains(id))
206     {
207         return d->pieces->value(id);
208     }
209     else
210     {
211         throw VExceptionBadId(tr("Can't find object"), id);
212     }
213 }
214 
215 //---------------------------------------------------------------------------------------------------------------------
GetPiecePath(quint32 id) const216 VPiecePath VContainer::GetPiecePath(quint32 id) const
217 {
218     if (d->piecePaths->contains(id))
219     {
220         return d->piecePaths->value(id);
221     }
222     else
223     {
224         throw VExceptionBadId(tr("Can't find object"), id);
225     }
226 }
227 
228 //---------------------------------------------------------------------------------------------------------------------
GetPieceForPiecePath(quint32 id) const229 quint32 VContainer::GetPieceForPiecePath(quint32 id) const
230 {
231     auto i = d->pieces->constBegin();
232     while (i != d->pieces->constEnd())
233     {
234         if (i.value().GetInternalPaths().contains(id))
235         {
236             return i.key();
237         }
238         ++i;
239     }
240 
241     return NULL_ID;
242 }
243 
244 //---------------------------------------------------------------------------------------------------------------------
RegisterUniqueName(VGObject * obj) const245 void VContainer::RegisterUniqueName(VGObject *obj) const
246 {
247     SCASSERT(obj != nullptr)
248     QSharedPointer<VGObject> pointer(obj);
249     RegisterUniqueName(pointer);
250 }
251 
252 //---------------------------------------------------------------------------------------------------------------------
RegisterUniqueName(const QSharedPointer<VGObject> & obj) const253 void VContainer::RegisterUniqueName(const QSharedPointer<VGObject> &obj) const
254 {
255     SCASSERT(not obj.isNull())
256 
257     uniqueNames[d->nspace].insert(obj->name());
258 
259     if (not obj->GetAlias().isEmpty())
260     {
261         uniqueNames[d->nspace].insert(obj->GetAlias());
262     }
263 }
264 
265 //---------------------------------------------------------------------------------------------------------------------
266 /**
267  * @brief AddGObject add new GObject to container
268  * @param obj new object
269  * @return return id of new object in container
270  */
AddGObject(VGObject * obj)271 quint32 VContainer::AddGObject(VGObject *obj)
272 {
273     SCASSERT(obj != nullptr)
274     QSharedPointer<VGObject> pointer(obj);
275     return AddGObject(pointer);
276 }
277 
278 //---------------------------------------------------------------------------------------------------------------------
AddGObject(const QSharedPointer<VGObject> & obj)279 quint32 VContainer::AddGObject(const QSharedPointer<VGObject> &obj)
280 {
281     SCASSERT(not obj.isNull())
282 
283     if (obj->getMode() == Draw::Layout)
284     {
285         qWarning("Can't add an object with mode 'Layout'");
286         return NULL_ID;
287     }
288 
289     RegisterUniqueName(obj);
290 
291     const quint32 id = getNextId();
292     obj->setId(id);
293 
294     if (obj->getMode() == Draw::Calculation)
295     {
296         d->calculationObjects.insert(id, obj);
297     }
298     else if (obj->getMode() == Draw::Modeling)
299     {
300         d->modelingObjects->insert(id, obj);
301     }
302 
303     return id;
304 }
305 
306 //---------------------------------------------------------------------------------------------------------------------
AddPiece(const VPiece & detail)307 quint32 VContainer::AddPiece(const VPiece &detail)
308 {
309     const quint32 id = getNextId();
310     d->pieces->insert(id, detail);
311     return id;
312 }
313 
314 //---------------------------------------------------------------------------------------------------------------------
AddPiecePath(const VPiecePath & path)315 quint32 VContainer::AddPiecePath(const VPiecePath &path)
316 {
317     const quint32 id = getNextId();
318     d->piecePaths->insert(id, path);
319     return id;
320 }
321 
322 //---------------------------------------------------------------------------------------------------------------------
getId() const323 quint32 VContainer::getId() const
324 {
325     return _id.value(d->nspace);
326 }
327 
328 //---------------------------------------------------------------------------------------------------------------------
329 /**
330  * @brief getNextId generate next unique id
331  * @return next unique id
332  */
getNextId() const333 quint32 VContainer::getNextId() const
334 {
335     //TODO. Current count of ids are very big and allow us save time before someone will reach its max value.
336     //Better way, of cource, is to seek free ids inside the set of values and reuse them.
337     //But for now better to keep it as it is now.
338     if (_id.value(d->nspace) == UINT_MAX)
339     {
340         qCritical()<<(tr("Number of free id exhausted."));
341     }
342     _id[d->nspace]++;
343     return _id.value(d->nspace);
344 }
345 
346 //---------------------------------------------------------------------------------------------------------------------
UpdateId(quint32 newId,const QString & nspace)347 void VContainer::UpdateId(quint32 newId, const QString &nspace)
348 {
349     if (_id.contains(nspace))
350     {
351         if (newId > _id.value(nspace))
352         {
353            _id[nspace] = newId;
354         }
355     }
356     else
357     {
358         throw VException(QStringLiteral("Unknown namespace"));
359     }
360 }
361 
362 //---------------------------------------------------------------------------------------------------------------------
363 /**
364  * @brief UpdateId update id. If new id bigger when current save new like current.
365  * @param newId id
366  */
UpdateId(quint32 newId) const367 void VContainer::UpdateId(quint32 newId) const
368 {
369     VContainer::UpdateId(newId, d->nspace);
370 }
371 
372 //---------------------------------------------------------------------------------------------------------------------
373 /**
374  * @brief Clear clear data in container. Id will be 0.
375  */
Clear()376 void VContainer::Clear()
377 {
378     qCDebug(vCon, "Clearing container data.");
379     _id[d->nspace] = NULL_ID;
380 
381     d->pieces->clear();
382     d->piecePaths->clear();
383     ClearVariables();
384     ClearGObjects();
385     ClearUniqueNames();
386 }
387 
388 //---------------------------------------------------------------------------------------------------------------------
ClearForFullParse()389 void VContainer::ClearForFullParse()
390 {
391     qCDebug(vCon, "Clearing container data for full parse.");
392     _id[d->nspace] = NULL_ID;
393 
394     d->pieces->clear();
395     d->piecePaths->clear();
396     Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 9, "Check that you used all types");
397     ClearVariables(QVector<VarType>({VarType::Increment,
398                                      VarType::IncrementSeparator,
399                                      VarType::LineAngle,
400                                      VarType::LineLength,
401                                      VarType::CurveLength,
402                                      VarType::CurveCLength,
403                                      VarType::ArcRadius,
404                                      VarType::CurveAngle}));
405     ClearGObjects();
406     ClearUniqueNames();
407 }
408 
409 //---------------------------------------------------------------------------------------------------------------------
410 /**
411  * @brief ClearObject points, splines, arcs, spline paths will be cleared.
412  */
ClearGObjects()413 void VContainer::ClearGObjects()
414 {
415     d->calculationObjects.clear();
416     d->modelingObjects->clear();
417 }
418 
419 //---------------------------------------------------------------------------------------------------------------------
ClearCalculationGObjects()420 void VContainer::ClearCalculationGObjects()
421 {
422     d->calculationObjects.clear();
423 }
424 
425 //---------------------------------------------------------------------------------------------------------------------
ClearVariables(const VarType & type)426 void VContainer::ClearVariables(const VarType &type)
427 {
428     ClearVariables(QVector<VarType>({type}));
429 }
430 
431 //---------------------------------------------------------------------------------------------------------------------
ClearVariables(const QVector<VarType> & types)432 void VContainer::ClearVariables(const QVector<VarType> &types)
433 {
434     if (not d->variables.isEmpty()) //-V807
435     {
436         if (types.isEmpty() || types.contains(VarType::Unknown))
437         {
438             d->variables.clear();
439         }
440         else
441         {
442             QHash<QString, QSharedPointer<VInternalVariable> >::iterator i;
443             for (i = d->variables.begin(); i != d->variables.end();)
444             {
445                 if (types.contains(i.value()->GetType()))
446                 {
447                     i = d->variables.erase(i);
448                 }
449                 else
450                 {
451                     ++i;
452                 }
453             }
454         }
455     }
456 }
457 
458 //---------------------------------------------------------------------------------------------------------------------
459 /**
460  * @brief AddLine add line to container
461  * @param firstPointId id of first point of line
462  * @param secondPointId id of second point of line
463  */
AddLine(const quint32 & firstPointId,const quint32 & secondPointId)464 void VContainer::AddLine(const quint32 &firstPointId, const quint32 &secondPointId)
465 {
466     const QSharedPointer<VPointF> first = GeometricObject<VPointF>(firstPointId);
467     const QSharedPointer<VPointF> second = GeometricObject<VPointF>(secondPointId);
468 
469     AddVariable(new VLengthLine(first.data(), firstPointId, second.data(), secondPointId, *GetPatternUnit()));
470     AddVariable(new VLineAngle(first.data(), firstPointId, second.data(), secondPointId));
471 }
472 
473 //---------------------------------------------------------------------------------------------------------------------
AddArc(const QSharedPointer<VAbstractCurve> & arc,const quint32 & id,const quint32 & parentId)474 void VContainer::AddArc(const QSharedPointer<VAbstractCurve> &arc, const quint32 &id, const quint32 &parentId)
475 {
476     AddCurve(arc, id, parentId);
477 
478     if (arc->getType() == GOType::Arc)
479     {
480         const QSharedPointer<VArc> casted = arc.staticCast<VArc>();
481 
482         AddVariable(new VArcRadius(id, parentId, casted.data(), *GetPatternUnit()));
483     }
484     else if (arc->getType() == GOType::EllipticalArc)
485     {
486         const QSharedPointer<VEllipticalArc> casted = arc.staticCast<VEllipticalArc>();
487 
488         AddVariable(new VArcRadius(id, parentId, casted.data(), 1, *GetPatternUnit()));
489         AddVariable(new VArcRadius(id, parentId, casted.data(), 2, *GetPatternUnit()));
490         AddVariable(new VEllipticalArcRotation(id, parentId, casted.data()));
491     }
492 }
493 
494 //---------------------------------------------------------------------------------------------------------------------
AddCurve(const QSharedPointer<VAbstractCurve> & curve,const quint32 & id,quint32 parentId)495 void VContainer::AddCurve(const QSharedPointer<VAbstractCurve> &curve, const quint32 &id, quint32 parentId)
496 {
497     const GOType curveType = curve->getType();
498     if (curveType != GOType::Spline      && curveType != GOType::SplinePath &&
499         curveType != GOType::CubicBezier && curveType != GOType::CubicBezierPath &&
500         curveType != GOType::Arc         && curveType != GOType::EllipticalArc)
501     {
502         throw VException(tr("Can't create a curve with type '%1'").arg(static_cast<int>(curveType)));
503     }
504 
505     AddVariable(new VCurveLength(id, parentId, curve.data(), *GetPatternUnit()));
506     AddVariable(new VCurveAngle(id, parentId, curve.data(), CurveAngle::StartAngle));
507     AddVariable(new VCurveAngle(id, parentId, curve.data(), CurveAngle::EndAngle));
508 }
509 
510 //---------------------------------------------------------------------------------------------------------------------
AddSpline(const QSharedPointer<VAbstractBezier> & curve,quint32 id,quint32 parentId)511 void VContainer::AddSpline(const QSharedPointer<VAbstractBezier> &curve, quint32 id, quint32 parentId)
512 {
513     AddCurve(curve, id, parentId);
514     AddVariable(new VCurveCLength(id, parentId, curve.data(), CurveCLength::C1, *GetPatternUnit()));
515     AddVariable(new VCurveCLength(id, parentId, curve.data(), CurveCLength::C2, *GetPatternUnit()));
516 }
517 
518 //---------------------------------------------------------------------------------------------------------------------
AddCurveWithSegments(const QSharedPointer<VAbstractCubicBezierPath> & curve,const quint32 & id,quint32 parentId)519 void VContainer::AddCurveWithSegments(const QSharedPointer<VAbstractCubicBezierPath> &curve, const quint32 &id,
520                                       quint32 parentId)
521 {
522     AddSpline(curve, id, parentId);
523 
524     for (qint32 i = 1; i <= curve->CountSubSpl(); ++i)
525     {
526         const VSpline spl = curve->GetSpline(i);
527 
528         AddVariable(new VCurveLength(id, parentId, curve.data(), spl, *GetPatternUnit(), i));
529         AddVariable(new VCurveAngle(id, parentId, curve.data(), spl, CurveAngle::StartAngle, i));
530         AddVariable(new VCurveAngle(id, parentId, curve.data(), spl, CurveAngle::EndAngle, i));
531         AddVariable(new VCurveCLength(id, parentId, curve.data(), spl, CurveCLength::C1, *GetPatternUnit(), i));
532         AddVariable(new VCurveCLength(id, parentId, curve.data(), spl, CurveCLength::C2, *GetPatternUnit(), i));
533     }
534 }
535 
536 //---------------------------------------------------------------------------------------------------------------------
RemoveVariable(const QString & name)537 void VContainer::RemoveVariable(const QString &name)
538 {
539     d->variables.remove(name);
540 }
541 
542 //---------------------------------------------------------------------------------------------------------------------
RemovePiece(quint32 id)543 void VContainer::RemovePiece(quint32 id)
544 {
545     d->pieces->remove(id);
546 }
547 
548 //---------------------------------------------------------------------------------------------------------------------
UpdatePiece(quint32 id,const VPiece & detail)549 void VContainer::UpdatePiece(quint32 id, const VPiece &detail)
550 {
551     Q_ASSERT_X(id != NULL_ID, Q_FUNC_INFO, "id == 0"); //-V654 //-V712
552     d->pieces->insert(id, detail);
553     UpdateId(id);
554 }
555 
556 //---------------------------------------------------------------------------------------------------------------------
UpdatePiecePath(quint32 id,const VPiecePath & path)557 void VContainer::UpdatePiecePath(quint32 id, const VPiecePath &path)
558 {
559     Q_ASSERT_X(id != NULL_ID, Q_FUNC_INFO, "id == 0"); //-V654 //-V712
560     d->piecePaths->insert(id, path);
561     UpdateId(id);
562 }
563 
564 //---------------------------------------------------------------------------------------------------------------------
565 /**
566  * @brief RemoveIncrement remove increment by name from increment table
567  * @param name name of existing increment
568  */
RemoveIncrement(const QString & name)569 void VContainer::RemoveIncrement(const QString &name)
570 {
571     d->variables[name].clear();
572     d->variables.remove(name);
573 }
574 
575 //---------------------------------------------------------------------------------------------------------------------
DataMeasurements() const576 const QMap<QString, QSharedPointer<VMeasurement> > VContainer::DataMeasurements() const
577 {
578     return DataVar<VMeasurement>(VarType::Measurement);
579 }
580 
581 //---------------------------------------------------------------------------------------------------------------------
DataIncrements() const582 const QMap<QString, QSharedPointer<VIncrement> > VContainer::DataIncrements() const
583 {
584     return DataVar<VIncrement>(VarType::Increment);
585 }
586 
587 //---------------------------------------------------------------------------------------------------------------------
DataIncrementsWithSeparators() const588 const QMap<QString, QSharedPointer<VIncrement> > VContainer::DataIncrementsWithSeparators() const
589 {
590     QMap<QString, QSharedPointer<VIncrement> > increments = DataVar<VIncrement>(VarType::Increment);
591     QMap<QString, QSharedPointer<VIncrement> > separators = DataVar<VIncrement>(VarType::IncrementSeparator);
592 
593     QMap<QString, QSharedPointer<VIncrement>>::const_iterator i = separators.constBegin();
594     while (i != separators.constEnd())
595     {
596         increments.insert(i.key(), i.value());
597         ++i;
598     }
599 
600     return increments;
601 }
602 
603 //---------------------------------------------------------------------------------------------------------------------
DataLengthLines() const604 const QMap<QString, QSharedPointer<VLengthLine> > VContainer::DataLengthLines() const
605 {
606     return DataVar<VLengthLine>(VarType::LineLength);
607 }
608 
609 //---------------------------------------------------------------------------------------------------------------------
DataLengthCurves() const610 const QMap<QString, QSharedPointer<VCurveLength> > VContainer::DataLengthCurves() const
611 {
612     return DataVar<VCurveLength>(VarType::CurveLength);
613 }
614 
615 //---------------------------------------------------------------------------------------------------------------------
DataCurvesCLength() const616 const QMap<QString, QSharedPointer<VCurveCLength> > VContainer::DataCurvesCLength() const
617 {
618     return DataVar<VCurveCLength>(VarType::CurveCLength);
619 }
620 
621 //---------------------------------------------------------------------------------------------------------------------
DataAngleLines() const622 const QMap<QString, QSharedPointer<VLineAngle> > VContainer::DataAngleLines() const
623 {
624     return DataVar<VLineAngle>(VarType::LineAngle);
625 }
626 
627 //---------------------------------------------------------------------------------------------------------------------
DataRadiusesArcs() const628 const QMap<QString, QSharedPointer<VArcRadius> > VContainer::DataRadiusesArcs() const
629 {
630     return DataVar<VArcRadius>(VarType::ArcRadius);
631 }
632 
633 //---------------------------------------------------------------------------------------------------------------------
DataAnglesCurves() const634 const QMap<QString, QSharedPointer<VCurveAngle> > VContainer::DataAnglesCurves() const
635 {
636     return DataVar<VCurveAngle>(VarType::CurveAngle);
637 }
638 
639 //---------------------------------------------------------------------------------------------------------------------
IsUnique(const QString & name) const640 bool VContainer::IsUnique(const QString &name) const
641 {
642     return VContainer::IsUnique(name, d->nspace);
643 }
644 
645 //---------------------------------------------------------------------------------------------------------------------
IsUnique(const QString & name,const QString & nspace)646 bool VContainer::IsUnique(const QString &name, const QString &nspace)
647 {
648     if (uniqueNames.contains(nspace))
649     {
650         return (!uniqueNames.value(nspace).contains(name) && !builInFunctions.contains(name));
651     }
652     else
653     {
654         throw VException(QStringLiteral("Unknown namespace"));
655     }
656 }
657 
658 //---------------------------------------------------------------------------------------------------------------------
AllUniqueNames() const659 QStringList VContainer::AllUniqueNames() const
660 {
661     return AllUniqueNames(d->nspace);
662 }
663 
664 //---------------------------------------------------------------------------------------------------------------------
AllUniqueNames(const QString & nspace)665 QStringList VContainer::AllUniqueNames(const QString &nspace)
666 {
667     if (uniqueNames.contains(nspace))
668     {
669         QStringList names = builInFunctions;
670         names.append(uniqueNames.value(nspace).values());
671         return names;
672     }
673     else
674     {
675         throw VException(QStringLiteral("Unknown namespace"));
676     }
677 }
678 
679 //---------------------------------------------------------------------------------------------------------------------
GetPatternUnit() const680 const Unit *VContainer::GetPatternUnit() const
681 {
682     return d->patternUnit;
683 }
684 
685 //---------------------------------------------------------------------------------------------------------------------
GetTrVars() const686 const VTranslateVars *VContainer::GetTrVars() const
687 {
688     return d->trVars;
689 }
690 
691 //---------------------------------------------------------------------------------------------------------------------
692 template <typename T>
DataVar(const VarType & type) const693 const QMap<QString, QSharedPointer<T> > VContainer::DataVar(const VarType &type) const
694 {
695     QMap<QString, QSharedPointer<T> > map;
696     //Sorting QHash by id
697     QHash<QString, QSharedPointer<VInternalVariable> >::const_iterator i;
698     for (i = d->variables.constBegin(); i != d->variables.constEnd(); ++i)
699     {
700         if (i.value()->GetType() == type)
701         {
702             QSharedPointer<T> var = GetVariable<T>(i.key());
703             map.insert(d->trVars->VarToUser(i.key()), var);
704         }
705     }
706     return map;
707 }
708 
709 //---------------------------------------------------------------------------------------------------------------------
ClearUniqueNames() const710 void VContainer::ClearUniqueNames() const
711 {
712     uniqueNames[d->nspace].clear();
713 }
714 
715 //---------------------------------------------------------------------------------------------------------------------
ClearUniqueIncrementNames() const716 void VContainer::ClearUniqueIncrementNames() const
717 {
718     const QList<QString> list = uniqueNames.value(d->nspace).values();
719     ClearUniqueNames();
720 
721     for(auto &name : list)
722     {
723         if (not name.startsWith('#'))
724         {
725             uniqueNames[d->nspace].insert(name);
726         }
727     }
728 }
729 
730 //---------------------------------------------------------------------------------------------------------------------
ClearExceptUniqueIncrementNames() const731 void VContainer::ClearExceptUniqueIncrementNames() const
732 {
733     const QList<QString> list = uniqueNames.value(d->nspace).values();
734     ClearUniqueNames();
735 
736     for(auto &name : list)
737     {
738         if (name.startsWith('#'))
739         {
740             uniqueNames[d->nspace].insert(name);
741         }
742     }
743 }
744 
745 //---------------------------------------------------------------------------------------------------------------------
746 /**
747  * @brief data container with datagObjects return container of gObjects
748  * @return pointer on container of gObjects
749  */
CalculationGObjects() const750 const QHash<quint32, QSharedPointer<VGObject> > *VContainer::CalculationGObjects() const
751 {
752     return &d->calculationObjects;
753 }
754 
755 //---------------------------------------------------------------------------------------------------------------------
DataPieces() const756 const QHash<quint32, VPiece> *VContainer::DataPieces() const
757 {
758     return d->pieces.data();
759 }
760 
761 //---------------------------------------------------------------------------------------------------------------------
DataVariables() const762 const QHash<QString, QSharedPointer<VInternalVariable> > *VContainer::DataVariables() const
763 {
764     return &d->variables;
765 }
766 
767 //---------------------------------------------------------------------------------------------------------------------
~VContainerData()768 VContainerData::~VContainerData()
769 {
770 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
771     if (ref.loadRelaxed() == 0)
772 #else
773     if (ref.load() == 0)
774 #endif
775     {
776         --VContainer::copyCounter[nspace];
777     }
778 
779     if (VContainer::copyCounter.value(nspace) == 0)
780     {
781         VContainer::ClearNamespace(nspace);
782     }
783 }
784