]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Implementation of remove of elements from the list by indexes
authormpv <mpv@opencascade.com>
Mon, 11 Jan 2016 17:04:21 +0000 (20:04 +0300)
committerdbv <dbv@opencascade.com>
Tue, 16 Feb 2016 14:03:01 +0000 (17:03 +0300)
src/Model/Model_AttributeRefList.cpp
src/Model/Model_AttributeSelectionList.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp

index 200807984d374405683e8c42e44b0d7063a18f1a..a1e0aeb666779046950ce637308c46a517661ec3 100644 (file)
@@ -214,6 +214,28 @@ void Model_AttributeRefList::removeLast()
 
 void Model_AttributeRefList::remove(const std::set<int>& theIndices)
 {
+  std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
+      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)
index 677d14d78760e552a6ee12fc9c7639fd488bcba8..b44767750922a7ace3dc5ff37bdf1c35ece593ed 100644 (file)
@@ -10,7 +10,9 @@
 #include "Model_Events.h"
 #include "Model_Data.h"
 
+#include <TDF_AttributeIterator.hxx>
 #include <TDF_ChildIterator.hxx>
+#include <TDF_RelocationTable.hxx>
 #include <TopAbs_ShapeEnum.hxx>
 
 #include <TopoDS.hxx>
@@ -83,8 +85,55 @@ void Model_AttributeSelectionList::removeLast()
   }
 }
 
+/// makes copy of all attributes on the given label and all sub-labels
+static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) {
+  TDF_AttributeIterator anAttrIter(theSource);
+  for(; anAttrIter.More(); anAttrIter.Next()) {
+    Handle(TDF_Attribute) aTargetAttr;
+    if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
+      // create a new attribute if not yet exists in the destination
+           aTargetAttr = anAttrIter.Value()->NewEmpty();
+      theDestination.AddAttribute(aTargetAttr);
+    }
+    Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(); // no relocation, empty map
+    anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
+  }
+  // copy the sub-labels content
+  TDF_ChildIterator aSubLabsIter(theSource);
+  for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
+    copyAttrs(aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()));
+  }
+}
+
 void Model_AttributeSelectionList::remove(const std::set<int>& theIndices)
 {
+  int anOldSize = mySize->Get();
+  int aRemoved = 0;
+  // iterate one by one and shifting the removed indicies
+  for(int aCurrent = 0; aCurrent < anOldSize; aCurrent++) {
+    if (theIndices.find(aCurrent) == theIndices.end()) { // not removed
+      if (aRemoved) { // but must be shifted to the removed position
+        TDF_Label aSource = mySize->Label().FindChild(aCurrent + 1);
+        TDF_Label aDest = mySize->Label().FindChild(aCurrent + 1 - aRemoved);
+        copyAttrs(aSource, aDest);
+        // remove the moved source
+        aSource.ForgetAllAttributes(Standard_True);
+      }
+    } else { // this is removed, so remove everything from this label
+      TDF_Label aLab = mySize->Label().FindChild(aCurrent + 1);
+      std::shared_ptr<Model_AttributeSelection> aOldAttr = 
+        std::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aLab));
+      aOldAttr->setObject(owner());
+      REMOVE_BACK_REF(aOldAttr->context());
+      aLab.ForgetAllAttributes(Standard_True);
+      myTmpAttr.reset();
+      aRemoved++;
+    }
+  }
+  if (aRemoved) { // remove was performed, so, update the size and this attribute
+    mySize->Set(anOldSize - aRemoved);
+    owner()->data()->sendAttributeUpdated(this);
+  }
 }
 
 int Model_AttributeSelectionList::size()
index 73ee5e4629d3a0bec8ca1b325b4e905e1287fe63..6328648a3ac0daaa33436c32813fd77701917872 100755 (executable)
@@ -506,19 +506,13 @@ void ModuleBase_WidgetMultiSelector::onDeleteItem()
   AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
   if (aSelectionListAttr.get()) {
     aDone = !anAttributeIds.empty();
-    //aSelectionListAttr->remove(anAttributeIds);
-    std::set<int>::const_iterator anIt = anAttributeIds.begin(), aLast = anAttributeIds.end();
-    for (; anIt != aLast; anIt++)
-      aSelectionListAttr->removeLast();
+    aSelectionListAttr->remove(anAttributeIds);
   }
   else {
     AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID());
     if (aRefListAttr.get()) {
       aDone = !anAttributeIds.empty();
-      //aRefListAttr->remove(anAttributeIds);
-      std::set<int>::const_iterator anIt = anAttributeIds.begin(), aLast = anAttributeIds.end();
-      for (; anIt != aLast; anIt++)
-        aRefListAttr->removeLast();
+      aRefListAttr->remove(anAttributeIds);
     }
   }
   if (aDone) {