X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeRefList.cpp;h=9d6f25ff36d448b2f70d7b97a68b77eb3e4b2935;hb=b5eaf6f6971771b1e39f55ba5fc484e2f150ffb8;hp=01e288ab9204a435353b046fec5ccc3e5c2705da;hpb=dc50f2f6b509a5dd5de0be397a3fe4564cb8d98d;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeRefList.cpp b/src/Model/Model_AttributeRefList.cpp index 01e288ab9..9d6f25ff3 100644 --- a/src/Model/Model_AttributeRefList.cpp +++ b/src/Model/Model_AttributeRefList.cpp @@ -10,27 +10,80 @@ #include "Model_Objects.h" #include #include +#include +#include using namespace std; void Model_AttributeRefList::append(ObjectPtr theObject) { - std::shared_ptr aData = std::dynamic_pointer_cast(theObject->data()); - myRef->Append(aData->label().Father()); // store label of the object + if (owner()->document() == theObject->document()) { + std::shared_ptr aData = std::dynamic_pointer_cast(theObject->data()); + myRef->Append(aData->label().Father()); // store label of the object + } else if (theObject.get() && theObject->data()->isValid()) { // reference to the other document + myRef->Append(myRef->Label()); + // if these attributes exist, the link is external: keep reference to access the label + std::ostringstream anIdString; // string with document Id + anIdString<document()->id(); + myExtDocRef->Append(anIdString.str().c_str()); + std::shared_ptr aData = std::dynamic_pointer_cast(theObject->data()); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(aData->label().Father(), anEntry); + myExtDocRef->Append(anEntry); + } else return; // something is wrong + // do it before the transaction finish to make just created/removed objects know dependencies // and reference from composite feature is removed automatically ADD_BACK_REF(theObject); - owner()->data()->sendAttributeUpdated(this); } void Model_AttributeRefList::remove(ObjectPtr theObject) { - std::shared_ptr aData; if (theObject.get() != NULL) { - aData = std::dynamic_pointer_cast(theObject->data()); - myRef->Remove(aData->label().Father()); - REMOVE_BACK_REF(theObject); + if (owner()->document() == theObject->document()) { + std::shared_ptr aData; + aData = std::dynamic_pointer_cast(theObject->data()); + myRef->Remove(aData->label().Father()); + REMOVE_BACK_REF(theObject); + owner()->data()->sendAttributeUpdated(this); + } else { + // create new lists because for the current moment remove one of the duplicated elements + // from the list is buggy + TDF_LabelList anOldList = myRef->List(); + myRef->Clear(); + TDataStd_ListOfExtendedString anOldExts = myExtDocRef->List(); + myExtDocRef->Clear(); + + std::ostringstream anIdString; // string with document Id + anIdString<document()->id(); + std::shared_ptr aData = std::dynamic_pointer_cast(theObject->data()); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(aData->label().Father(), anEntry); + bool aFound = false; + TDataStd_ListIteratorOfListOfExtendedString anExtIter(anOldExts); + for (TDF_ListIteratorOfLabelList aLIter(anOldList); aLIter.More(); aLIter.Next()) { + if (aLIter.Value() == myRef->Label()) { + if (anExtIter.Value() == anIdString.str().c_str()) { + TDataStd_ListIteratorOfListOfExtendedString anExtIter2 = anExtIter; + anExtIter2.Next(); + if (anExtIter2.Value() == anEntry) { // fully maches, so, remove(don't copy) + aFound = true; + continue; + } + } + myExtDocRef->Append(anExtIter.Value()); + anExtIter.Next(); + myExtDocRef->Append(anExtIter.Value()); + anExtIter.Next(); + } + myRef->Append(aLIter.Value()); + } + if (aFound) { + REMOVE_BACK_REF(theObject); + owner()->data()->sendAttributeUpdated(this); + } + } } else { // in case of empty object remove, the first empty object is removed from the list std::shared_ptr aDoc = std::dynamic_pointer_cast( @@ -42,12 +95,12 @@ void Model_AttributeRefList::remove(ObjectPtr theObject) if (anObj.get() == NULL) { myRef->Remove(aLIter.Value()); REMOVE_BACK_REF(theObject); + owner()->data()->sendAttributeUpdated(this); break; } } } } - owner()->data()->sendAttributeUpdated(this); } void Model_AttributeRefList::clear() @@ -58,6 +111,8 @@ void Model_AttributeRefList::clear() for(; anOldIter != anOldList.end(); anOldIter++) { REMOVE_BACK_REF((*anOldIter)); } + myExtDocRef->Clear(); + owner()->data()->sendAttributeUpdated(this); } int Model_AttributeRefList::size(const bool theWithEmpty) const @@ -67,19 +122,46 @@ int Model_AttributeRefList::size(const bool theWithEmpty) const int aResult = 0; const TDF_LabelList& aList = myRef->List(); for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { - if (!aLIter.Value().IsNull()) aResult++; + if (!aLIter.Value().IsNull() && !aLIter.Value().IsRoot()) aResult++; } return aResult; } bool Model_AttributeRefList::isInitialized() { - if (size() == 0) { // empty list is not initialized list: sketch will be not valid after add/undo + if (size(false) == 0) { // empty list is not initialized list: sketch will be not valid after add/undo return false; } return ModelAPI_AttributeRefList::isInitialized(); } +ObjectPtr Model_AttributeRefList::iteratedObject(TDF_ListIteratorOfLabelList& theLIter, + TDataStd_ListIteratorOfListOfExtendedString& theExtIter, + std::shared_ptr theDoc) const +{ + ObjectPtr anObj; + if (!theLIter.Value().IsNull() && !theLIter.Value().IsRoot()) { + if (theLIter.Value() == myRef->Label()) { // external document object + int anID = atoi(TCollection_AsciiString(theExtIter.Value()).ToCString()); + theExtIter.Next(); + DocumentPtr aRefDoc = Model_Application::getApplication()->document(anID); + if (aRefDoc.get()) { + std::shared_ptr aDR = std::dynamic_pointer_cast(aRefDoc); + TDF_Label aRefLab; + TDF_Tool::Label(aDR->objects()->featuresLabel().Data(), + TCollection_AsciiString(theExtIter.Value()).ToCString(), aRefLab); + if (!aRefLab.IsNull()) { + anObj = aDR->objects()->object(aRefLab); + } + } + theExtIter.Next(); + } else { // internal document object + anObj = theDoc->objects()->object(theLIter.Value()); + } + } + return anObj; +} + list Model_AttributeRefList::list() { std::list aResult; @@ -87,11 +169,9 @@ list Model_AttributeRefList::list() owner()->document()); if (aDoc) { const TDF_LabelList& aList = myRef->List(); + TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List()); for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { - ObjectPtr anObj; - if (!aLIter.Value().IsNull()) - anObj = aDoc->objects()->object(aLIter.Value()); - aResult.push_back(anObj); + aResult.push_back(iteratedObject(aLIter, anExtIter, aDoc)); } } return aResult; @@ -99,18 +179,42 @@ list Model_AttributeRefList::list() bool Model_AttributeRefList::isInList(const ObjectPtr& theObj) { - std::list aResult; - std::shared_ptr aDoc = std::dynamic_pointer_cast( - owner()->document()); - if (aDoc) { + if(!theObj.get()) { + return false; + } + if (theObj->document() == owner()->document()) { // this document object + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + std::shared_ptr aData = std::dynamic_pointer_cast(theObj->data()); + if (aData.get() && aData->isValid()) { + TDF_Label anObjLab = aData->label().Father(); + const TDF_LabelList& aList = myRef->List(); + for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { + if (aLIter.Value().IsEqual(anObjLab)) { + return true; + } + } + } + } + } else { // external document object + // create new lists because for the current moment remove one of the duplicated elements + // from the list is buggy + std::ostringstream anIdString; // string with document Id + anIdString<document()->id(); std::shared_ptr aData = std::dynamic_pointer_cast(theObj->data()); - if (aData.get() && aData->isValid()) { - TDF_Label anObjLab = aData->label().Father(); - const TDF_LabelList& aList = myRef->List(); - for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { - if (aLIter.Value().IsEqual(anObjLab)) { + TCollection_AsciiString anEntry; + TDF_Tool::Entry(aData->label().Father(), anEntry); + bool aFound = false; + TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List()); + for (; anExtIter.More(); anExtIter.Next()) { + if (anExtIter.Value() == anIdString.str().c_str()) { + anExtIter.Next(); + if (anExtIter.Value() == anEntry) { // fully maches return true; } + } else { + anExtIter.Next(); } } } @@ -119,16 +223,21 @@ bool Model_AttributeRefList::isInList(const ObjectPtr& theObj) ObjectPtr Model_AttributeRefList::object(const int theIndex, const bool theWithEmpty) const { - std::shared_ptr aDoc = std::dynamic_pointer_cast( - owner()->document()); + std::shared_ptr aDoc = + std::dynamic_pointer_cast(owner()->document()); if (aDoc) { - const TDF_LabelList& aList = myRef->List(); int anIndex = -1; - for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { - if (theWithEmpty || !aLIter.Value().IsNull()) + TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List()); + for (TDF_ListIteratorOfLabelList aLIter(myRef->List()); aLIter.More(); aLIter.Next()) { + if (theWithEmpty || (!aLIter.Value().IsNull() && !aLIter.Value().IsRoot())) anIndex++; - if (anIndex == theIndex) - return aDoc->objects()->object(aLIter.Value()); + if (anIndex == theIndex) { + return iteratedObject(aLIter, anExtIter, aDoc); + } + if (aLIter.Value() == myRef->Label()) { + anExtIter.Next(); + anExtIter.Next(); + } } } return ObjectPtr(); @@ -147,6 +256,8 @@ void Model_AttributeRefList::substitute(const ObjectPtr& theCurrent, const Objec std::shared_ptr aNewData = std::dynamic_pointer_cast(theNew->data()); aNewLab = aNewData->label().Father(); + } else { + aNewLab = aCurrentLab.Root(); // root means null object } // do the substitution ADD_BACK_REF(theNew); @@ -159,6 +270,37 @@ void Model_AttributeRefList::substitute(const ObjectPtr& theCurrent, const Objec } } +void Model_AttributeRefList::exchange(const ObjectPtr& theObject1, const ObjectPtr& theObject2) +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + std::shared_ptr aData1 = std::dynamic_pointer_cast(theObject1->data()); + if (aData1.get() && aData1->isValid()) { + TDF_Label aLab1 = aData1->label().Father(); + if (theObject2.get() && theObject2->data()->isValid()) { // the new may be null + std::shared_ptr aData2 = + std::dynamic_pointer_cast(theObject2->data()); + if (aData2.get() && aData2->isValid()) { + TDF_Label aLab2 = aData2->label().Father(); + // do the substitution: use the temporary label, as usually in exchange + TDF_Label aTmpLab = aLab1.Root(); + if (myRef->InsertAfter(aTmpLab, aLab1)) { + myRef->Remove(aLab1); + } + if (myRef->InsertAfter(aLab1, aLab2)) { + myRef->Remove(aLab2); + } + if (myRef->InsertAfter(aLab2, aTmpLab)) { + myRef->Remove(aTmpLab); + } + owner()->data()->sendAttributeUpdated(this); + } + } + } + } +} + void Model_AttributeRefList::removeLast() { std::shared_ptr aDoc = std::dynamic_pointer_cast( @@ -173,10 +315,45 @@ void Model_AttributeRefList::removeLast() } } +void Model_AttributeRefList::remove(const std::set& theIndices) +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc && !myRef->IsEmpty()) { + // collet labels that will be removed + TDF_LabelList aLabelsToRemove; + TDF_ListIteratorOfLabelList aLabIter(myRef->List()); + for(int aCurrent = 0; aLabIter.More(); aLabIter.Next(), aCurrent++) { + if (theIndices.find(aCurrent) != theIndices.end()) + aLabelsToRemove.Append(aLabIter.Value()); + } + // remove labels + for(aLabIter.Initialize(aLabelsToRemove); aLabIter.More(); aLabIter.Next()) { + ObjectPtr anObj = aDoc->objects()->object(aLabIter.Value()); + if (anObj.get()) { + myRef->Remove(aLabIter.Value()); + REMOVE_BACK_REF(anObj); + } + } + if (!aLabelsToRemove.IsEmpty()) { + owner()->data()->sendAttributeUpdated(this); + } + } +} + Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel) { - myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True; + myLab = theLabel; + reinit(); +} + +void Model_AttributeRefList::reinit() +{ + myIsInitialized = myLab.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True; if (!myIsInitialized) { - myRef = TDataStd_ReferenceList::Set(theLabel); + myRef = TDataStd_ReferenceList::Set(myLab); + } + if (!myLab.FindAttribute(TDataStd_ExtStringList::GetID(), myExtDocRef)) { + myExtDocRef = TDataStd_ExtStringList::Set(myLab); } }