Salome HOME
Edit operation correction.
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetFeatureOrAttribute.cpp
index 633adbc439e22e36df7a632acd878b5fd734b47d..cea8d1ec49bc7c75adcb7dacc1131ceaec1d6580 100644 (file)
@@ -7,6 +7,9 @@
 #include <ModuleBase_WidgetValueFeature.h>
 #include <ModuleBase_WidgetValue.h>
 
+#include <ModelAPI_RefAttrValidator.h>
+#include <ModelAPI_Session.h>
+
 #include <Config_Keywords.h>
 #include <Config_WidgetAPI.h>
 
@@ -17,6 +20,8 @@
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Object.h>
 #include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_Validator.h>
+
 #include <GeomAPI_Pnt2d.h>
 
 #include <GeomDataAPI_Point2D.h>
 #include <QHBoxLayout>
 #include <QLabel>
 
-ModuleBase_WidgetFeatureOrAttribute::ModuleBase_WidgetFeatureOrAttribute(QWidget* theParent,
-                                                   const Config_WidgetAPI* theData, 
-                                                   const std::string& theParentId)
-: ModuleBase_WidgetFeature(theParent, theData, theParentId)
+ModuleBase_WidgetFeatureOrAttribute::ModuleBase_WidgetFeatureOrAttribute(QWidget* theParent, 
+                                                                         const Config_WidgetAPI* theData, 
+                                                                         const std::string& theParentId)
+    : ModuleBase_WidgetFeature(theParent, theData, theParentId)
 {
 }
 
@@ -44,68 +49,63 @@ bool ModuleBase_WidgetFeatureOrAttribute::setValue(ModuleBase_WidgetValue* theVa
   bool isDone = false;
 
   if (theValue) {
-    ModuleBase_WidgetValueFeature* aFeatureValue = 
-                         dynamic_cast<ModuleBase_WidgetValueFeature*>(theValue);
+    ModuleBase_WidgetValueFeature* aFeatureValue =
+        dynamic_cast<ModuleBase_WidgetValueFeature*>(theValue);
     if (aFeatureValue) {
-      boost::shared_ptr<GeomAPI_Pnt2d> aValuePoint = aFeatureValue->point();
-      ObjectPtr aValueFeature = aFeatureValue->object();
-      if (aValueFeature) {
-        isDone = setObject(aValueFeature);
+      ObjectPtr aObject = aFeatureValue->object();
+
+      boost::shared_ptr<ModelAPI_Attribute> anAttribute = findAttribute(aFeatureValue);
+      if (anAttribute) {
+        isDone = setAttribute(anAttribute, false);
       }
-      if (!isDone && aValuePoint) {
-        // find the given point in the feature attributes
-        std::list<boost::shared_ptr<ModelAPI_Attribute> > anAttiributes =
-                                      aValueFeature->data()->attributes(GeomDataAPI_Point2D::type());
-        std::list<boost::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
-                                                                          aLast = anAttiributes.end();
-        boost::shared_ptr<GeomDataAPI_Point2D> aFPoint;
-        for (;anIt!=aLast && !aFPoint; anIt++) {
-          boost::shared_ptr<GeomDataAPI_Point2D> aCurPoint =
-                                              boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
-          if (aCurPoint && aCurPoint->pnt()->distance(aValuePoint) < Precision::Confusion())
-            aFPoint = aCurPoint;
-        }
-        if (aFPoint)
-          isDone = setAttribute(aFPoint);
+      else if (aObject) {
+        isDone = setObject(aObject, false);
       }
+
+      if (isDone)
+        emit valuesChanged();
     }
   }
   return isDone;
 }
 
-bool ModuleBase_WidgetFeatureOrAttribute::storeValue(FeaturePtr theFeature) const
+bool ModuleBase_WidgetFeatureOrAttribute::storeValue() const
 {
-  boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
-          boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(attributeID()));
-
-  ModuleBase_WidgetFeatureOrAttribute* that = (ModuleBase_WidgetFeatureOrAttribute*) this;
-  if (object())
-    aRef->setObject(object());
-  else if (myAttribute)
+  //FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(theFeature);
+  //if (!aFeature)
+  //  return false;
+
+  boost::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+  boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef = boost::dynamic_pointer_cast<
+      ModelAPI_AttributeRefAttr>(aData->attribute(attributeID()));
+
+  if (myObject)
+    aRef->setObject(myObject);
+  if (myAttribute)
     aRef->setAttr(myAttribute);
 
-  theFeature->execute();
-  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  myFeature->execute();
+  updateObject(myFeature);
 
   return true;
 }
 
-bool ModuleBase_WidgetFeatureOrAttribute::restoreValue(FeaturePtr theFeature)
+bool ModuleBase_WidgetFeatureOrAttribute::restoreValue()
 {
-  boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
-          boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(attributeID()));
+  boost::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+  boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef = boost::dynamic_pointer_cast<
+      ModelAPI_AttributeRefAttr>(aData->attribute(attributeID()));
 
-  FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(aRef->object());
+  ObjectPtr aObj = aRef->object();
+  FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
   if (aFeature) {
-    setObject(aFeature);
+    myObject = aFeature;
     myAttribute = aRef->attr();
 
     std::string aText = "";
     if (aFeature)
       aText = aFeature->data()->name().c_str();
-    else if (myAttribute)
+    if (myAttribute)
       aText = myAttribute->attributeType().c_str();
 
     editor()->setText(aText.c_str());
@@ -114,14 +114,66 @@ bool ModuleBase_WidgetFeatureOrAttribute::restoreValue(FeaturePtr theFeature)
   return false;
 }
 
-bool ModuleBase_WidgetFeatureOrAttribute::setAttribute(const boost::shared_ptr<ModelAPI_Attribute>& theAttribute)
+boost::shared_ptr<ModelAPI_Attribute> ModuleBase_WidgetFeatureOrAttribute::findAttribute(
+                                                        ModuleBase_WidgetValue* theValue)
+{
+  boost::shared_ptr<ModelAPI_Attribute> anAttribute;
+  ModuleBase_WidgetValueFeature* aFeatureValue =
+                                  dynamic_cast<ModuleBase_WidgetValueFeature*>(theValue);
+  if (!aFeatureValue)
+    return anAttribute;
+
+  boost::shared_ptr<GeomAPI_Pnt2d> aValuePoint = aFeatureValue->point();
+  if (aValuePoint) {
+    ObjectPtr aObject = aFeatureValue->object();
+    FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
+    if (aFeature) {
+      // find the given point in the feature attributes
+      std::list<boost::shared_ptr<ModelAPI_Attribute> > anAttiributes = aFeature->data()
+          ->attributes(GeomDataAPI_Point2D::type());
+      std::list<boost::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes
+          .begin(), aLast = anAttiributes.end();
+      for (; anIt != aLast && !anAttribute; anIt++) {
+        boost::shared_ptr<GeomDataAPI_Point2D> aCurPoint = boost::dynamic_pointer_cast<
+            GeomDataAPI_Point2D>(*anIt);
+        if (aCurPoint && aCurPoint->pnt()->distance(aValuePoint) < Precision::Confusion())
+          anAttribute = aCurPoint;
+      }
+    }
+  }
+  return anAttribute;
+}
+
+bool ModuleBase_WidgetFeatureOrAttribute::setAttribute(
+    const boost::shared_ptr<ModelAPI_Attribute>& theAttribute, bool theSendEvent)
 {
-  if (!theAttribute || !featureKinds().contains(theAttribute->attributeType().c_str()))
+  if (!theAttribute)  // || !featureKinds().contains(theAttribute->attributeType().c_str()))
     return false;
 
+  SessionPtr aMgr = ModelAPI_Session::get();
+  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+  std::list<ModelAPI_Validator*> aValidators;
+  std::list<std::list<std::string> > anArguments;
+  aFactory->validators(parentID(), attributeID(), aValidators, anArguments);
+
+  // Check the acceptability of the attribute
+  std::list<ModelAPI_Validator*>::iterator aValidator = aValidators.begin();
+  int aSize = aValidators.size();
+  std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
+  for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
+    const ModelAPI_RefAttrValidator* aAttrValidator =
+        dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
+    if (aAttrValidator) {
+      if (!aAttrValidator->isValid(myFeature, *aArgs, theAttribute)) {
+        return false;
+      }
+    }
+  }
+
   myAttribute = theAttribute;
   editor()->setText(theAttribute ? theAttribute->attributeType().c_str() : "");
-  emit valuesChanged();
+  if (theSendEvent)
+    emit valuesChanged();
   return true;
 }