Salome HOME
Added the removeLast method into AttributeRefList
[modules/shaper.git] / src / Model / Model_AttributeRefList.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModelAPI_AttributeRefList.cxx
4 // Created:     8 May 2014
5 // Author:      Mikhail PONIKAROV
6
7 #include "Model_AttributeRefList.h"
8 #include "Model_Application.h"
9 #include "Model_Data.h"
10 #include "Model_Objects.h"
11 #include <ModelAPI_Feature.h>
12 #include <TDF_ListIteratorOfLabelList.hxx>
13
14 using namespace std;
15
16 void Model_AttributeRefList::append(ObjectPtr theObject)
17 {
18   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
19   myRef->Append(aData->label().Father());  // store label of the object
20   // do it before the transaction finish to make just created/removed objects know dependencies
21   // and reference from composite feature is removed automatically
22   ADD_BACK_REF(theObject);
23
24   owner()->data()->sendAttributeUpdated(this);
25 }
26
27 void Model_AttributeRefList::remove(ObjectPtr theObject)
28 {
29   std::shared_ptr<Model_Data> aData;
30   if (theObject.get() != NULL) {
31     aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
32     myRef->Remove(aData->label().Father());
33     REMOVE_BACK_REF(theObject);
34   }
35   else { // in case of empty object remove, the first empty object is removed from the list
36     std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
37         owner()->document());
38     if (aDoc) {
39       const TDF_LabelList& aList = myRef->List();
40       for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
41         ObjectPtr anObj = aDoc->objects()->object(aLIter.Value());
42         if (anObj.get() == NULL) {
43           myRef->Remove(aLIter.Value());
44           REMOVE_BACK_REF(theObject);
45           break;
46         }
47       }
48     }
49   }
50   owner()->data()->sendAttributeUpdated(this);
51 }
52
53 void Model_AttributeRefList::clear()
54 {
55   std::list<ObjectPtr> anOldList = list();
56   myRef->Clear();
57   std::list<ObjectPtr>::iterator anOldIter = anOldList.begin();
58   for(; anOldIter != anOldList.end(); anOldIter++) {
59     REMOVE_BACK_REF((*anOldIter));
60   }
61 }
62
63 int Model_AttributeRefList::size(const bool theWithEmpty) const
64 {
65   if (theWithEmpty)
66     return myRef->Extent();
67   int aResult = 0;
68   const TDF_LabelList& aList = myRef->List();
69   for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
70     if (!aLIter.Value().IsNull()) aResult++;
71   }
72   return aResult;
73 }
74
75 bool Model_AttributeRefList::isInitialized()
76 {
77   if (size() == 0) { // empty list is not initialized list: sketch will be not valid after add/undo
78     return false;
79   }
80   return ModelAPI_AttributeRefList::isInitialized();
81 }
82
83 list<ObjectPtr> Model_AttributeRefList::list()
84 {
85   std::list<ObjectPtr> aResult;
86   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
87       owner()->document());
88   if (aDoc) {
89     const TDF_LabelList& aList = myRef->List();
90     for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
91       ObjectPtr anObj;
92       if (!aLIter.Value().IsNull())
93         anObj = aDoc->objects()->object(aLIter.Value());
94       aResult.push_back(anObj);
95     }
96   }
97   return aResult;
98 }
99
100 bool Model_AttributeRefList::isInList(const ObjectPtr& theObj)
101 {
102   std::list<ObjectPtr> aResult;
103   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
104       owner()->document());
105   if (aDoc) {
106     std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObj->data());
107     if (aData.get() && aData->isValid()) {
108       TDF_Label anObjLab = aData->label().Father();
109       const TDF_LabelList& aList = myRef->List();
110       for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
111         if (aLIter.Value().IsEqual(anObjLab)) {
112           return true;
113         }
114       }
115     }
116   }
117   return false;
118 }
119
120 ObjectPtr Model_AttributeRefList::object(const int theIndex, const bool theWithEmpty) const
121 {
122   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
123       owner()->document());
124   if (aDoc) {
125     const TDF_LabelList& aList = myRef->List();
126     int anIndex = -1;
127     for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
128       if (theWithEmpty || !aLIter.Value().IsNull())
129         anIndex++;
130       if (anIndex == theIndex)
131         return aDoc->objects()->object(aLIter.Value());
132     }
133   }
134   return ObjectPtr();
135 }
136
137 void Model_AttributeRefList::substitute(const ObjectPtr& theCurrent, const ObjectPtr& theNew)
138 {
139   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
140       owner()->document());
141   if (aDoc) {
142     std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theCurrent->data());
143     if (aData.get() && aData->isValid()) {
144       TDF_Label aCurrentLab = aData->label().Father();
145       TDF_Label aNewLab;
146       if (theNew.get() && theNew->data()->isValid()) { // the new may be null
147         std::shared_ptr<Model_Data> aNewData = 
148           std::dynamic_pointer_cast<Model_Data>(theNew->data());
149         aNewLab = aNewData->label().Father();
150       }
151       // do the substitution
152       ADD_BACK_REF(theNew);
153       if (myRef->InsertAfter(aNewLab, aCurrentLab)) {
154         myRef->Remove(aCurrentLab);
155         REMOVE_BACK_REF(theCurrent);
156       }
157       owner()->data()->sendAttributeUpdated(this);
158     }
159   }
160 }
161
162 void Model_AttributeRefList::removeLast()
163 {
164   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
165       owner()->document());
166   if (aDoc && !myRef->IsEmpty()) {
167     ObjectPtr anObj = aDoc->objects()->object(myRef->Last());
168     if (anObj.get()) {
169       myRef->Remove(myRef->Last());
170       REMOVE_BACK_REF(anObj);
171       owner()->data()->sendAttributeUpdated(this);
172     }
173   }
174 }
175
176 Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel)
177 {
178   myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True;
179   if (!myIsInitialized) {
180     myRef = TDataStd_ReferenceList::Set(theLabel);
181   }
182 }