1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "Model_AttributeRefAttrList.h"
22 #include "Model_Application.h"
23 #include "Model_Data.h"
24 #include "Model_Objects.h"
25 #include <ModelAPI_Feature.h>
26 #include <TDF_ListIteratorOfLabelList.hxx>
27 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
29 void Model_AttributeRefAttrList::append(ObjectPtr theObject)
31 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
32 myRef->Append(aData->label().Father()); // store label of the object
33 myIDs->Append(""); // for the object store an empty string
34 // do it before the transaction finish to make just created/removed objects know dependencies
35 // and reference from composite feature is removed automatically
36 ADD_BACK_REF(theObject);
38 owner()->data()->sendAttributeUpdated(this);
41 void Model_AttributeRefAttrList::append(AttributePtr theAttr)
43 std::shared_ptr<Model_Data> aData =
44 std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
45 myRef->Append(aData->label().Father()); // store label of the object
46 myIDs->Append(theAttr->id().c_str()); // store the ID of the referenced attribute
47 // do it before the transaction finish to make just created/removed objects know dependencies
48 // and reference from composite feature is removed automatically
49 ADD_BACK_REF(theAttr->owner());
51 owner()->data()->sendAttributeUpdated(this);
54 void Model_AttributeRefAttrList::remove(ObjectPtr theObject)
57 if (theObject.get() != NULL) {
58 aTheObjLab = std::dynamic_pointer_cast<Model_Data>(theObject->data())->label().Father();
60 std::shared_ptr<Model_Document> aDoc =
61 std::dynamic_pointer_cast<Model_Document>(owner()->document());
62 // remove from the both lists by clearing the list and then appending one by one
63 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
64 TDF_LabelList aRefList = myRef->List();
66 TDataStd_ListOfExtendedString anIDList = myIDs->List();
68 bool aOneisDeleted = false;
69 TDF_ListIteratorOfLabelList aRefIter(aRefList);
70 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
71 for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) {
72 // append now only not removed
73 if (aOneisDeleted || aRefIter.Value() != aTheObjLab || !anIDIter.Value().IsEmpty() ||
74 (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) {
75 myRef->Append(aRefIter.Value());
76 myIDs->Append(anIDIter.Value());
77 } else if (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL) {
82 REMOVE_BACK_REF(theObject);
83 owner()->data()->sendAttributeUpdated(this);
87 void Model_AttributeRefAttrList::remove(AttributePtr theAttr)
90 if (theAttr->owner().get() != NULL) {
91 aTheObjLab = std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data())->label().Father();
93 std::shared_ptr<Model_Document> aDoc =
94 std::dynamic_pointer_cast<Model_Document>(owner()->document());
95 // remove from the both lists by clearing the list and then appending one by one
96 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
97 TDF_LabelList aRefList = myRef->List();
99 TDataStd_ListOfExtendedString anIDList = myIDs->List();
101 bool aOneisDeleted = false;
102 TDF_ListIteratorOfLabelList aRefIter(aRefList);
103 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
104 for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) {
105 if (aOneisDeleted || anIDIter.Value() != theAttr->id().c_str() ||
106 // append now only not removed
107 aRefIter.Value() != aTheObjLab || // append now only not removed
108 (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) {
109 myRef->Append(aRefIter.Value());
110 myIDs->Append(anIDIter.Value());
112 aOneisDeleted = true;
116 REMOVE_BACK_REF(theAttr->owner());
117 owner()->data()->sendAttributeUpdated(this);
121 void Model_AttributeRefAttrList::clear()
123 std::list<std::pair<ObjectPtr, AttributePtr> > anOldList = list();
126 std::list<std::pair<ObjectPtr, AttributePtr> >::iterator anOldIter = anOldList.begin();
127 for(; anOldIter != anOldList.end(); anOldIter++) {
128 REMOVE_BACK_REF((anOldIter->first));
130 owner()->data()->sendAttributeUpdated(this);
133 int Model_AttributeRefAttrList::size() const
135 return myRef->Extent();
138 bool Model_AttributeRefAttrList::isInitialized()
140 if (size() == 0) { // empty list is not initialized list: sketch will be not valid after add/undo
143 return ModelAPI_AttributeRefAttrList::isInitialized();
146 std::list<std::pair<ObjectPtr, AttributePtr> > Model_AttributeRefAttrList::list()
148 std::list<std::pair<ObjectPtr, AttributePtr> > aResult;
149 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
150 owner()->document());
152 const TDF_LabelList& aList = myRef->List();
153 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
154 TDF_ListIteratorOfLabelList aLIter(aList);
155 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
156 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
158 if (!aLIter.Value().IsNull()) {
159 anObj = aDoc->objects()->object(aLIter.Value());
160 aResult.push_back(std::pair<ObjectPtr, AttributePtr>(anObj,
161 anObj->data()->attribute(TCollection_AsciiString(anIDIter.Value()).ToCString())));
163 aResult.push_back(std::pair<ObjectPtr, AttributePtr>(ObjectPtr(), AttributePtr()));
170 bool Model_AttributeRefAttrList::isInList(const ObjectPtr& theObj)
175 std::list<ObjectPtr> aResult;
176 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
177 owner()->document());
179 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObj->data());
180 if (aData.get() && aData->isValid()) {
181 TDF_Label anObjLab = aData->label().Father();
182 const TDF_LabelList& aList = myRef->List();
183 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
184 TDF_ListIteratorOfLabelList aLIter(aList);
185 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
186 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
187 if (anIDIter.Value().IsEmpty() && aLIter.Value().IsEqual(anObjLab)) {
196 bool Model_AttributeRefAttrList::isInList(const AttributePtr& theAttr)
198 if (!theAttr->owner().get()) {
201 std::list<ObjectPtr> aResult;
202 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
203 owner()->document());
205 std::shared_ptr<Model_Data> aData =
206 std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
207 if (aData.get() && aData->isValid()) {
208 TDF_Label anObjLab = aData->label().Father();
209 const TDF_LabelList& aList = myRef->List();
210 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
211 TDF_ListIteratorOfLabelList aLIter(aList);
212 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
213 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
214 if (anIDIter.Value() == theAttr->id().c_str() && aLIter.Value().IsEqual(anObjLab)) {
223 bool Model_AttributeRefAttrList::isAttribute(const int theIndex) const
225 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
226 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
228 for (; anIDIter.More(); anIDIter.Next()) {
230 if (anIndex == theIndex) {
231 return !anIDIter.Value().IsEmpty();
237 ObjectPtr Model_AttributeRefAttrList::object(const int theIndex) const
239 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
240 owner()->document());
242 const TDF_LabelList& aList = myRef->List();
244 for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
246 if (anIndex == theIndex) {
247 if (aLIter.Value().IsNull()) { // null label => null sub
250 return aDoc->objects()->object(aLIter.Value());
257 AttributePtr Model_AttributeRefAttrList::attribute(const int theIndex) const
259 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
260 owner()->document());
263 const TDF_LabelList& aList = myRef->List();
264 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
265 TDF_ListIteratorOfLabelList aLIter(aList);
266 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
267 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
269 if (anIndex == theIndex) {
270 if (aLIter.Value().IsNull()) { // null label => null sub
271 return AttributePtr();
273 return aDoc->objects()->object(aLIter.Value())->data()->
274 attribute(TCollection_AsciiString(anIDIter.Value().ToExtString()).ToCString());
278 return AttributePtr();
281 void Model_AttributeRefAttrList::removeLast()
283 // remove from the both lists by clearing the list and then appending one by one
284 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
285 std::set<int> aLastSet;
286 aLastSet.insert(size() - 1);
290 void Model_AttributeRefAttrList::remove(const std::set<int>& theIndices)
292 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
293 owner()->document());
294 if (aDoc && !myRef->IsEmpty()) {
295 // remove from the both lists by clearing the list and then appending one by one
296 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
297 TDF_LabelList aRefList = myRef->List();
299 TDataStd_ListOfExtendedString anIDList = myIDs->List();
301 bool aOneisDeleted = false;
302 TDF_ListIteratorOfLabelList aRefIter(aRefList);
303 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
304 for (int anIndex = 0; aRefIter.More(); aRefIter.Next(), anIDIter.Next(), anIndex++) {
305 if (theIndices.find(anIndex) == theIndices.end()) { // not found
306 myRef->Append(aRefIter.Value());
307 myIDs->Append(anIDIter.Value());
308 } else { // found, so need to update the dependencies
309 aOneisDeleted = true;
310 ObjectPtr anObj = aDoc->objects()->object(aRefIter.Value());
312 REMOVE_BACK_REF(anObj);
317 owner()->data()->sendAttributeUpdated(this);
322 Model_AttributeRefAttrList::Model_AttributeRefAttrList(TDF_Label& theLabel)
328 void Model_AttributeRefAttrList::reinit()
330 myIsInitialized = myLab.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True;
331 if (!myIsInitialized) {
332 myRef = TDataStd_ReferenceList::Set(myLab);
333 myIDs = TDataStd_ExtStringList::Set(myLab);
335 myLab.FindAttribute(TDataStd_ExtStringList::GetID(), myIDs);