Salome HOME
Issues #2027, #2024, #2063, #2067: reentrant message to fill new operation by result...
authornds <nds@opencascade.com>
Mon, 3 Apr 2017 05:59:04 +0000 (08:59 +0300)
committernds <nds@opencascade.com>
Mon, 3 Apr 2017 05:59:04 +0000 (08:59 +0300)
39 files changed:
src/ModelAPI/CMakeLists.txt
src/ModelAPI/ModelAPI_EventReentrantMessage.cpp [new file with mode: 0644]
src/ModelAPI/ModelAPI_EventReentrantMessage.h [new file with mode: 0644]
src/ModelAPI/ModelAPI_IReentrant.cpp [new file with mode: 0644]
src/ModelAPI/ModelAPI_IReentrant.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_IErrorMgr.h
src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_IModule.h
src/ModuleBase/ModuleBase_IPropertyPanel.cpp
src/ModuleBase/ModuleBase_IPropertyPanel.h
src/ModuleBase/ModuleBase_IWorkshop.h
src/ModuleBase/ModuleBase_ModelWidget.cpp
src/ModuleBase/ModuleBase_ModelWidget.h
src/PartSet/PartSet_CustomPrs.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_OperationPrs.cpp
src/PartSet/PartSet_OperationPrs.h
src/PartSet/PartSet_OverconstraintListener.cpp
src/PartSet/PartSet_SketcherReentrantMgr.cpp
src/PartSet/PartSet_SketcherReentrantMgr.h
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h
src/PartSet/PartSet_WidgetFeaturePointSelector.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_Line.h
src/SketchPlugin/SketchPlugin_MacroArc.cpp
src/SketchPlugin/SketchPlugin_MacroArc.h
src/SketchPlugin/SketchPlugin_MacroArcReentrantMessage.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_MacroCircle.cpp
src/SketchPlugin/SketchPlugin_MacroCircle.h
src/SketchPlugin/SketchPlugin_Trim.cpp
src/SketchPlugin/SketchPlugin_Trim.h
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/plugin-Sketch.xml
src/XGUI/XGUI_ErrorMgr.h
src/XGUI/XGUI_ModuleConnector.cpp
src/XGUI/XGUI_ModuleConnector.h

index e227fdeab8cc997ed36f174bf68b86fa0830cfc4..fea8bb975fb63c4dab94419929f8d086683c4ca9 100644 (file)
@@ -28,10 +28,12 @@ SET(PROJECT_HEADERS
     ModelAPI_CompositeFeature.h
     ModelAPI_Data.h
     ModelAPI_Document.h
+    ModelAPI_EventReentrantMessage.h
     ModelAPI_Events.h
     ModelAPI_Expression.h
     ModelAPI_Feature.h
     ModelAPI_FeatureValidator.h
+    ModelAPI_IReentrant.h
     ModelAPI_Object.h
     ModelAPI_Plugin.h
     ModelAPI_Result.h
@@ -69,10 +71,12 @@ SET(PROJECT_SOURCES
     ModelAPI_CompositeFeature.cpp
     ModelAPI_Data.cpp
     ModelAPI_Document.cpp
+    ModelAPI_EventReentrantMessage.cpp
     ModelAPI_Events.cpp
     ModelAPI_Expression.cpp
     ModelAPI_Feature.cpp
     ModelAPI_FeatureValidator.cpp
+    ModelAPI_IReentrant.cpp
     ModelAPI_Object.cpp
     ModelAPI_Plugin.cpp
     ModelAPI_Result.cpp
diff --git a/src/ModelAPI/ModelAPI_EventReentrantMessage.cpp b/src/ModelAPI/ModelAPI_EventReentrantMessage.cpp
new file mode 100644 (file)
index 0000000..b527e70
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    ModelAPI_EventReentrantMessage.cpp
+// Created: 30 Mar 2017
+// Author:  Natalia ERMOLAEVA
+
+#include <ModelAPI_EventReentrantMessage.h>
+
+ModelAPI_EventReentrantMessage::ModelAPI_EventReentrantMessage(
+                                                 const Events_ID theID,
+                                                 const void* theSender)
+: Events_Message(theID, theSender)
+{
+}
diff --git a/src/ModelAPI/ModelAPI_EventReentrantMessage.h b/src/ModelAPI/ModelAPI_EventReentrantMessage.h
new file mode 100644 (file)
index 0000000..ded9c8b
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    ModelAPI_EventReentrantMessage.h
+// Created: 30 Mar 2017
+// Author:  Natalia ERMOLAEVA
+
+#ifndef ModelAPI_EventReentrantMessage_H_
+#define ModelAPI_EventReentrantMessage_H_
+
+#include <Events_Message.h>
+#include <Events_Loop.h>
+
+#include <ModelAPI.h>
+
+#include <memory>
+
+class ModelAPI_Object;
+class ModelAPI_Feature;
+class ModelAPI_Attribute;
+class GeomAPI_Pnt2d;
+
+/// Message that style of visualization of parameter is changed.
+/// It will be shown as expression or value
+class ModelAPI_EventReentrantMessage : public Events_Message
+{
+public:
+  /// Creates an empty message
+  MODELAPI_EXPORT ModelAPI_EventReentrantMessage(const Events_ID theID,
+                                                 const void* theSender = 0);
+  /// The virtual destructor
+  MODELAPI_EXPORT virtual ~ModelAPI_EventReentrantMessage() {}
+  /// Static. Returns EventID of the message.
+  MODELAPI_EXPORT static Events_ID eventId()
+  {
+    static const char * MY_EVENT_REENTRANT_MESSAGE_ID("EventReentrantMessage");
+    return Events_Loop::eventByName(MY_EVENT_REENTRANT_MESSAGE_ID);
+  }
+
+  /// Fills previous feature parameter
+  MODELAPI_EXPORT void setCreatedFeature(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+  { myCreatedFeature = theFeature; }
+
+  /// Returns previous feature parameter
+  MODELAPI_EXPORT const std::shared_ptr<ModelAPI_Feature>& createdFeature() const
+  { return myCreatedFeature; }
+
+  /// Fills selected object parameter
+  /// \theObject a feature or result
+  MODELAPI_EXPORT void setSelectedObject(const std::shared_ptr<ModelAPI_Object>& theObject)
+  { mySelectedObject = theObject; }
+
+  /// Returns selected object parameter
+  MODELAPI_EXPORT const std::shared_ptr<ModelAPI_Object>& selectedObject() const
+  { return mySelectedObject; }
+
+  /// Fills selected attribute parameter
+  /// \theAttribute
+  MODELAPI_EXPORT void setSelectedAttribute
+                                  (const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
+  { mySelectedAttribute = theAttribute; }
+
+  /// Returns selected attribute parameter
+  MODELAPI_EXPORT const std::shared_ptr<ModelAPI_Attribute>& selectedAttribute()
+  { return mySelectedAttribute; }
+
+  /// Fills clicked point
+  /// \thePoint
+  MODELAPI_EXPORT void setClickedPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+  { myClickedPoint = thePoint; }
+
+  /// Returns clicked point
+  MODELAPI_EXPORT const std::shared_ptr<GeomAPI_Pnt2d>& clickedPoint()
+  { return myClickedPoint; }
+
+private:
+  std::shared_ptr<ModelAPI_Feature> myCreatedFeature; ///< previous object
+  std::shared_ptr<ModelAPI_Object> mySelectedObject; ///< selected object
+  std::shared_ptr<ModelAPI_Attribute> mySelectedAttribute; ///< selected attribute
+  std::shared_ptr<GeomAPI_Pnt2d> myClickedPoint; ///< clicked point
+};
+
+typedef std::shared_ptr<ModelAPI_EventReentrantMessage> ReentrantMessagePtr;
+
+
+#endif
diff --git a/src/ModelAPI/ModelAPI_IReentrant.cpp b/src/ModelAPI/ModelAPI_IReentrant.cpp
new file mode 100644 (file)
index 0000000..53697f9
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModelAPI_IReentrant.cpp
+// Created:     30 Mar 2017
+// Author:      Natalia ERMOLAEVA
+
+#include <ModelAPI_IReentrant.h>
+
+ModelAPI_IReentrant::~ModelAPI_IReentrant()
+{
+}
diff --git a/src/ModelAPI/ModelAPI_IReentrant.h b/src/ModelAPI/ModelAPI_IReentrant.h
new file mode 100644 (file)
index 0000000..b556193
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModelAPI_IReentrant.hxx
+// Created:     30 Mar 2017
+// Author:      Natalia ERMOLAEVA
+
+#ifndef ModelAPI_IReentrant_H
+#define ModelAPI_IReentrant_H
+
+#include "ModelAPI.h"
+
+#include <vector>
+#include <memory>
+
+class Events_Message;
+
+/** \class ModelAPI_IReentrant
+ *  \ingroup DataModel
+ *  \brief Interface of a class which can process specific messages
+ */
+class ModelAPI_IReentrant
+{
+public:
+  MODELAPI_EXPORT virtual ~ModelAPI_IReentrant();
+
+  /// Apply information of the message to current object.
+  /// \param theMessage a container of information
+  /// \return a next active attribute name
+  virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage) = 0;
+};
+
+typedef std::shared_ptr<ModelAPI_IReentrant> ModelReentrantPtr;
+
+#endif
index 9f595fdbbf7bb5e5fa97c9467694d7d1cd882f1c..c41b0b5238233ff14c9b076196a6779037811392 100644 (file)
@@ -8,9 +8,13 @@
 #define ModuleBase_IErrorMgr_H
 
 #include "ModuleBase.h"
+
 #include <QObject>
 
+#include <memory>
+
 class ModuleBase_IPropertyPanel;
+class ModelAPI_Feature;
 
 /**
  * \class ModuleBase_IErrorMgr
@@ -34,6 +38,10 @@ public:
   /// \return Currently installed property panel
   ModuleBase_IPropertyPanel* propertyPanel() const { return myPropertyPanel; }
 
+  /// Update actions for the given feature
+  /// \param theFeature a feature
+  virtual void updateActions(const std::shared_ptr<ModelAPI_Feature>& theFeature) = 0;
+
 protected slots:
   /// Process values changed event for processing feature attribute validation errors.
   virtual void onWidgetChanged() = 0;
index 3a5aebb6a90e49f14dc750114f84b0c3c20a0ab4..7dc2d8f82e28c7b550a6c4919cb2151340858b92 100644 (file)
@@ -1,10 +1,13 @@
 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 
+#include "ModelAPI_IReentrant.h"
+#include "ModelAPI_EventReentrantMessage.h"
 
 #include "ModuleBase_IModule.h"
 #include "ModuleBase_IViewer.h"
 #include "ModuleBase_ViewerPrs.h"
 #include "ModuleBase_Operation.h"
+#include "ModuleBase_IPropertyPanel.h"
 #include "ModuleBase_ISelection.h"
 #include "ModuleBase_OperationDescription.h"
 #include "ModuleBase_OperationFeature.h"
 #include "ModuleBase_WidgetFactory.h"
 #include "ModuleBase_PageWidget.h"
 #include "ModuleBase_Dialog.h"
+#include "ModuleBase_IErrorMgr.h"
 
 #include <Events_Loop.h>
+#include <Events_Message.h>
 
 #include <ModelAPI_Events.h>
 #include <ModelAPI_CompositeFeature.h>
@@ -85,9 +90,30 @@ void ModuleBase_IModule::launchOperation(const QString& theCmdId)
   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
                                              (createOperation(theCmdId.toStdString()));
   if (aFOperation) {
-    aFOperation->initSelection(aPreSelected);
+    std::shared_ptr<Events_Message> aMessage = reentrantMessage();
+    if (aMessage.get()) {
+      setReentrantPreSelection(aMessage);
+    }
+    else
+      aFOperation->initSelection(aPreSelected);
 
     workshop()->processLaunchOperation(aFOperation);
+
+    if (aFOperation) {
+      FeaturePtr aFeature = aFOperation->feature();
+      ModelReentrantPtr aReentrantFeature =
+                                      std::dynamic_pointer_cast<ModelAPI_IReentrant>(aFeature);
+      if (aReentrantFeature.get()) {
+        if (aMessage.get()) {
+          ModuleBase_IPropertyPanel* aPanel = workshop()->propertyPanel();
+          std::string aPrevAttribute = aReentrantFeature->processEvent(aMessage);
+          workshop()->errorMgr()->updateActions(aFeature);
+
+          ModuleBase_ModelWidget* aPrevWidget = aPanel->modelWidget(aPrevAttribute);
+          aPanel->activateNextWidget(aPrevWidget);
+        }
+      }
+    }
   }
 }
 
index f72ad02fd16dd3045131755395562651570ea0e3..62b746eabb821cd8fe4c368bbece1eb705162d6c 100755 (executable)
@@ -28,8 +28,11 @@ class QMenu;
 class Config_WidgetAPI;
 class ModuleBase_ModelWidget;
 class ModuleBase_Operation;
+class ModuleBase_ViewerPrs;
+
 class ModuleBase_IWorkshop;
 class ModelAPI_Result;
+class Events_Message;
 
 class AIS_InteractiveObject;
 
@@ -317,6 +320,13 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
   virtual AttributePtr findAttribute(const ObjectPtr& theObject,
                                      const GeomShapePtr& theGeomShape) = 0;
 
+  /// Returns reentrant message if it was accepted
+  virtual std::shared_ptr<Events_Message> reentrantMessage() = 0;
+
+  /// Put current selection into reentrant message
+  /// \param theMessage a message of reentrant operation
+  virtual void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage) = 0;
+
   /// Returns XML information by the feature index
   /// \param theFeatureId a feature id
   /// \param theXmlCfg XML configuration
index bb6d2276a9fe1736a4a2d1773d9498a60d973d4f..37230d33de11acb989ba8d4ffec92f417fbf826e 100644 (file)
 ModuleBase_IPropertyPanel::ModuleBase_IPropertyPanel(QWidget* theParent)
  : QDockWidget(theParent), myIsEditing(false)
 {
+}
+
+ModuleBase_ModelWidget* ModuleBase_IPropertyPanel::modelWidget(
+                                          const std::string& theAttributeId) const
+{
+  ModuleBase_ModelWidget* aWidget = 0;
+  QList<ModuleBase_ModelWidget*> aWidgets = modelWidgets();
+  ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+  for (QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin();
+    anIt != aWidgets.end() && !aWidget; anIt++) {
+    ModuleBase_ModelWidget* aCurrentWidget = *anIt;
+    if (aCurrentWidget->attributeID() == theAttributeId &&
+        aCurrentWidget->canAcceptFocus() &&
+        aValidators->isCase(aCurrentWidget->feature(), aCurrentWidget->attributeID()))
+      aWidget = aCurrentWidget;
+  }
 
+  return aWidget;
 }
 
 ModuleBase_ModelWidget* ModuleBase_IPropertyPanel::findFirstAcceptingValueWidget()
index 58683af4178d1b6233eb92ab437acf469f182f6b..123e5084e234f39398883babfd465cbaafa6acfc 100644 (file)
@@ -38,6 +38,10 @@ public:
   /// Returns all property panel's widget created by WidgetFactory
   virtual const QList<ModuleBase_ModelWidget*>& modelWidgets() const = 0;
 
+  /// Returns widget, that has the given attribute index
+  /// \param theAttributeId an attribute from XML
+  virtual ModuleBase_ModelWidget* modelWidget(const std::string& theAttributeId) const;
+
   /// Removes all widgets in the widget area of the property panel
   virtual void cleanContent() = 0;
 
index 8c5695aa8f3106da72a5f562cbb6478612dec100..a9c66405d9a8836758299ebe1ceee3920f6c2fd5 100644 (file)
@@ -21,6 +21,7 @@ class ModuleBase_IModule;
 class ModuleBase_ISelection;
 class ModuleBase_IViewer;
 class ModuleBase_IPropertyPanel;
+class ModuleBase_IErrorMgr;
 class ModuleBase_Operation;
 class ModuleBase_ViewerPrs;
 class QMainWindow;
@@ -62,6 +63,9 @@ Q_OBJECT
   //! Returns property panel
   virtual ModuleBase_IPropertyPanel* propertyPanel() const = 0;
 
+  //! Returns error manager
+  virtual ModuleBase_IErrorMgr* errorMgr() const = 0;
+
   /// A filter to process an attribute validators
   /// \return a filter
   Handle(ModuleBase_FilterValidated) validatorFilter();
index aa0470f7a6c2faca5ef62048f679b1df740ff546..f0be4ae9e58002dba8ddb0082c929506c0d2b1a0 100644 (file)
@@ -51,7 +51,7 @@ ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent,
 
   myIsInternal = theData->getBooleanAttribute(ATTR_INTERNAL, false);
 
-  myIsModifiedInEdit = theData->getBooleanAttribute(ATTR_MODIFIED_IN_EDIT, true);
+  myIsModifiedInEdit = theData->getProperty(ATTR_MODIFIED_IN_EDIT);
 
   myDefaultValue = theData->getProperty(ATTR_DEFAULT);
   myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);
@@ -315,8 +315,18 @@ bool ModuleBase_ModelWidget::storeValue()
   bool isDone = false;
   // value is stored only in creation mode and in edition if there is not
   // XML flag prohibited modification in edit mode(macro feature circle/arc)
-  if (!isEditingMode() || isModifiedInEdit())
+  if (!isEditingMode() || isModifiedInEdit().empty())
     isDone = storeValueCustom();
+  else {
+    /// store value in an alternative attribute if possible(attribute has the same type)
+    std::string aWidgetAttribute = attributeID();
+    myAttributeID = isModifiedInEdit();
+    storeValueCustom();
+    myAttributeID = aWidgetAttribute;
+    // operation will be restarted but if isDone == true, PagedContainer will try to set focus
+    // to the current widget, but will be already deleted
+    isDone = false;
+  }
 
   emit afterValuesChanged();
 
index fcd2ad508b81e1218ea686d5031162f8c49cbee6..0b409e6feedb9ce02cd32e60c6224b8e84a938e1 100644 (file)
@@ -95,7 +95,7 @@ Q_OBJECT
 
   /// Returns this parameter value in the xml file
   /// \return the boolean result
-  bool isModifiedInEdit() const { return myIsModifiedInEdit; }
+  std::string isModifiedInEdit() const { return myIsModifiedInEdit; }
 
   /// Returns this widget value state
   /// \return the enumeration result
@@ -364,7 +364,7 @@ private:
   bool myIsInternal;
 
   // an XML state, the value is not stored into model if the widget is in edit mode
-  bool myIsModifiedInEdit;
+  std::string myIsModifiedInEdit;
 
   /// the reset state. If it is false, the reset method of the widget is not performed
   bool myUseReset;
index cc52284cca9e8e51c1452c7cadf4bd56adfa6603..ded37014d7baef9c394fe685f1364105adc7d866 100755 (executable)
@@ -96,6 +96,7 @@ bool PartSet_CustomPrs::displayPresentation(
       break;
     case ModuleBase_IModule::CustomizeResults:
       PartSet_OperationPrs::getResultShapes(myFeature, myWorkshop, aFeatureShapes);
+      PartSet_OperationPrs::getPresentationShapes(myFeature, myWorkshop, aFeatureShapes);
       break;
     case ModuleBase_IModule::CustomizeHighlightedObjects:
       PartSet_OperationPrs::getHighlightedShapes(myWorkshop, aFeatureShapes);
index 4382fca68cb83d42f93e640f775004b734061e97..41c2d3b04db528cb807b85e8bab3ff3fd3310732 100755 (executable)
@@ -552,6 +552,17 @@ void PartSet_Module::customSubShapesSelectionModes(QIntList& theTypes)
     theTypes.append(SketcherPrs_Tools::Sel_Sketch_Wire);
 }
 
+void PartSet_Module::getGeomSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theSelected,
+                                      ObjectPtr& theObject, AttributePtr& theAttribute)
+{
+  ObjectPtr anObject = theSelected->object();
+  GeomShapePtr aShape = theSelected->shape();
+
+  theAttribute = findAttribute(anObject, aShape);
+  // TODO: try to create result if object is an external object
+  theObject = anObject;
+}
+
 bool PartSet_Module::isMouseOverWindow()
 {
   return mySketchMgr->isMouseOverWindow();
@@ -1424,6 +1435,18 @@ AttributePtr PartSet_Module::findAttribute(const ObjectPtr& theObject,
   return anAttribute;
 }
 
+//******************************************************
+std::shared_ptr<Events_Message> PartSet_Module::reentrantMessage()
+{
+  return sketchReentranceMgr()->reentrantMessage();
+}
+
+//******************************************************
+void PartSet_Module::setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage)
+{
+  sketchReentranceMgr()->setReentrantPreSelection(theMessage);
+}
+
 //******************************************************
 void PartSet_Module::onChoiceChanged(ModuleBase_ModelWidget* theWidget,
                                      int theIndex)
index 2795d2965721b88786a05d76003b061389f192b0..7292bb30ad20c54e0ffc28aa478573394d6e782a 100755 (executable)
@@ -30,6 +30,8 @@
 
 class ModuleBase_Operation;
 class ModuleBase_IViewWindow;
+class ModuleBase_ViewerPrs;
+
 class XGUI_Workshop;
 class PartSet_MenuMgr;
 class PartSet_CustomPrs;
@@ -205,6 +207,13 @@ public:
   /// Returns sketch reentrant manager
   PartSet_SketcherReentrantMgr* sketchReentranceMgr() const { return mySketchReentrantMgr; }
 
+  /// Find object and attribute(if selected) for the given viewer selection
+  /// \param theSelected a viewer selection
+  /// \param theObject a selected model object
+  /// \param theAttribute a selected model attribute
+  virtual void getGeomSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theSelected,
+                                ObjectPtr& theObject, AttributePtr& theAttribute);
+
   /// Returns listener of overconstraint signal
   /// \return the listener
   PartSet_OverconstraintListener* overconstraintListener() { return myOverconstraintListener; }
@@ -329,6 +338,13 @@ public:
   /// \return theAttribute
   virtual AttributePtr findAttribute(const ObjectPtr& theObject, const GeomShapePtr& theGeomShape);
 
+  /// Returns reentrant message if it was accepted
+  virtual std::shared_ptr<Events_Message> reentrantMessage();
+
+  /// Put current selection into reentrant message
+  /// \param theMessage a message of reentrant operation
+  virtual void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage);
+
   /// Returns the workshop
   XGUI_Workshop* getWorkshop() const;
 
index 31efa6041197b8ece3291807446e71b0db9c12fd..7068063188130db566b6264cad07d91c1967c2b3 100755 (executable)
@@ -348,6 +348,41 @@ void PartSet_OperationPrs::getResultShapes(const FeaturePtr& theFeature,
   }
 }
 
+void PartSet_OperationPrs::getPresentationShapes(const FeaturePtr& theFeature,
+                                           ModuleBase_IWorkshop* theWorkshop,
+                                           QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes,
+                                           const bool theListShouldBeCleared)
+{
+  if (theListShouldBeCleared)
+    theObjectShapes.clear();
+
+  if (!theFeature.get() || !theFeature->data()->isValid()) // if feature is already removed
+    return;
+
+  XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer();
+
+  GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theFeature);
+  if (!aPrs.get())
+    return;
+
+  AISObjectPtr anAIS = aPrs->getAISObject(aDisplayer->getAISObject(theFeature));
+  if (!anAIS.get())
+    return;
+
+  Handle(AIS_InteractiveObject) anAISPrs = anAIS->impl<Handle(AIS_InteractiveObject)>();
+  if (!anAISPrs.IsNull()) {
+    Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(anAISPrs);
+    if (!aShapePrs.IsNull()) {
+      TopoDS_Shape aShape = aShapePrs->Shape();
+      if (!aShape.IsNull()) {
+        std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
+        aGeomShape->setImpl(new TopoDS_Shape(aShape));
+        appendShapeIfVisible(theWorkshop, theFeature, aGeomShape, theObjectShapes);
+      }
+    }
+  }
+}
+
 void PartSet_OperationPrs::getHighlightedShapes(ModuleBase_IWorkshop* theWorkshop,
                                                 QMap<ObjectPtr,
                                                 QList<GeomShapePtr> >& theObjectShapes)
index 95ce374efa159fddc39855bcaf403cb3a47d188c..7e871fc5dd7377f1ff922e3a38373125a7386e9a 100755 (executable)
@@ -100,6 +100,16 @@ private:
                               QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes,
                               const bool theListShouldBeCleared = true);
 
+  /// Fills the map by the feature presentation if the feature is presentable
+  /// \param theFeature a current feature
+  /// \param theWorkshop a current workshop
+  /// \param theObjectShapes an output map
+  /// \param theObjectShape an output map of objects
+  static void getPresentationShapes(const FeaturePtr& theFeature,
+                              ModuleBase_IWorkshop* theWorkshop,
+                              QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes,
+                              const bool theListShouldBeCleared = true);
+
   /// Fills the map by the feature object and shapes, which should be visuaziled
   /// Gets the active widget, obtain the highlighted presentations if it has such and
   /// fill map by object and shapes
index 41ee6b2a22905cea2c9cb0e237de0c2f5dc87dab..768dff3c75c28107d59f18bc9839098e5d5878fe 100755 (executable)
 
 #include "SketcherPrs_SymbolPrs.h"
 #include "SketchPlugin_SketchEntity.h"
+#include "SketchPlugin_MacroArcReentrantMessage.h"
 
 #include "Events_Loop.h"
 
 #include <GeomAPI_IPresentable.h>
 #include <ModelAPI_Events.h>
+#include <ModelAPI_EventReentrantMessage.h>
 #include <ModuleBase_Tools.h>
 
 #include <QString>
@@ -39,7 +41,8 @@ PartSet_OverconstraintListener::PartSet_OverconstraintListener(ModuleBase_IWorks
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_UNDER_CONSTRAINED));
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_FULLY_CONSTRAINED));
 
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+  aLoop->registerListener(this, ModelAPI_EventReentrantMessage::eventId());
+  aLoop->registerListener(this, SketchPlugin_MacroArcReentrantMessage::eventId());
 }
 
 void PartSet_OverconstraintListener::getCustomColor(const ObjectPtr& theObject,
@@ -123,16 +126,13 @@ void PartSet_OverconstraintListener::processEvent(
       }
     }
   }
-  else if (anEventID == Events_Loop::eventByName(EVENT_OBJECT_CREATED)) {
+  else if (anEventID == ModelAPI_EventReentrantMessage::eventId() ||
+           anEventID == SketchPlugin_MacroArcReentrantMessage::eventId()) {
     PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
     PartSet_SketcherReentrantMgr* aReentrantMgr = aModule->sketchReentranceMgr();
-    if (aReentrantMgr->isInternalEditActive()) {
-      std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
-            std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
-      std::set<ObjectPtr> anObjects = aUpdMsg->objects();
-      aReentrantMgr->appendCreatedObjects(anObjects);
-    }
+    aReentrantMgr->setReentrantMessage(theMessage);
   }
+
 #ifdef DEBUG_FEATURE_OVERCONSTRAINT_LISTENER
   aCurrentInfoStr = getObjectsInfo(myConflictingObjects);
   qDebug(QString("RESULT: current objects count = %1:%2\n")
index dc1ec367868791b6d57a239eb45332d102b6ce57..8af09b3fab92f07e1a87d68dd96f8ba3cc7f26e3 100644 (file)
@@ -8,6 +8,7 @@
 #include "ModelAPI_Session.h"
 #include "ModelAPI_AttributeString.h"
 #include "ModelAPI_AttributeRefAttr.h"
+#include "ModelAPI_EventReentrantMessage.h"
 
 #include "GeomDataAPI_Point2D.h"
 
@@ -28,6 +29,7 @@
 #include <SketchPlugin_MacroArc.h>
 #include <SketchPlugin_MacroCircle.h>
 #include <SketchPlugin_Point.h>
+#include <SketchPlugin_Trim.h>
 
 #include <XGUI_Workshop.h>
 #include <XGUI_ModuleConnector.h>
 
 #include <QToolButton>
 
+//#define DEBUG_RESTART
+
 PartSet_SketcherReentrantMgr::PartSet_SketcherReentrantMgr(ModuleBase_IWorkshop* theWorkshop)
 : QObject(theWorkshop),
   myWorkshop(theWorkshop),
   myRestartingMode(RM_None),
   myIsFlagsBlocked(false),
   myIsInternalEditOperation(false),
-  myIsValueChangedBlocked(false),
   myInternalActiveWidget(0),
   myNoMoreWidgetsAttribute("")
 {
@@ -118,7 +121,8 @@ void PartSet_SketcherReentrantMgr::operationStarted(ModuleBase_Operation* theOpe
     ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast<ModuleBase_OperationFeature*>(
                                                                 myWorkshop->currentOperation());
     CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
-    copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch);
+    if (myPreviousFeature.get() && myPreviousFeature->data()->isValid()) // it is not removed
+      copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch);
   }
   resetFlags();
 }
@@ -194,8 +198,8 @@ bool PartSet_SketcherReentrantMgr::processMousePressed(ModuleBase_IViewWindow* /
   return isActiveMgr() && myIsInternalEditOperation;
 }
 
-bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* theWnd,
-                                                         QMouseEvent* theEvent)
+bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* theWindow,
+                                                        QMouseEvent* theEvent)
 {
   bool aProcessed = false;
   if (!isActiveMgr())
@@ -228,7 +232,16 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow*
       QList<ModuleBase_ViewerPrsPtr> aPreSelected =
         aSelection->getSelected(ModuleBase_ISelection::AllControls);
 
+      myClickedSketchPoint = PartSet_Tools::getPnt2d(theEvent, theWindow,
+                                                     module()->sketchMgr()->activeSketch());
+      if (!aPreSelected.empty())
+        module()->getGeomSelection(aPreSelected.first(), mySelectedObject, mySelectedAttribute);
+
       restartOperation();
+      myClickedSketchPoint = std::shared_ptr<GeomAPI_Pnt2d>();
+      mySelectedObject = ObjectPtr();
+      mySelectedAttribute = AttributePtr();
+
       myPreviousFeature = FeaturePtr();
       aProcessed = true;
 
@@ -252,8 +265,8 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow*
           // there are created objects to replace the object depending on created feature kind
           aSelectedPrs = generatePreSelection();
         }
-        aMouseProcessor->setPreSelection(aSelectedPrs, theWnd, theEvent);
-        //aPoint2DWdg->mouseReleased(theWnd, theEvent);
+        aMouseProcessor->setPreSelection(aSelectedPrs, theWindow, theEvent);
+        //aPoint2DWdg->mouseReleased(theWindow, theEvent);
         //if (!aPreSelected.empty())
         //  aPoint2DWdg->setPreSelection(ModuleBase_ViewerPrsPtr());
       }
@@ -264,6 +277,20 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow*
   return aProcessed;
 }
 
+//******************************************************
+void PartSet_SketcherReentrantMgr::setReentrantPreSelection(
+                                       const std::shared_ptr<Events_Message>& theMessage)
+{
+  ReentrantMessagePtr aReentrantMessage =
+                      std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
+  if (!aReentrantMessage.get())
+    return;
+
+  aReentrantMessage->setSelectedObject(mySelectedObject);
+  aReentrantMessage->setSelectedAttribute(mySelectedAttribute);
+  aReentrantMessage->setClickedPoint(myClickedSketchPoint);
+}
+
 void PartSet_SketcherReentrantMgr::onWidgetActivated()
 {
   if (!isActiveMgr())
@@ -283,6 +310,10 @@ void PartSet_SketcherReentrantMgr::onWidgetActivated()
 
 void PartSet_SketcherReentrantMgr::onNoMoreWidgets(const std::string& thePreviousAttributeID)
 {
+#ifdef DEBUG_RESTART
+  std::cout << "PartSet_SketcherReentrantMgr::onNoMoreWidgets" << std::endl;
+#endif
+
   if (!isActiveMgr())
     return;
 
@@ -369,14 +400,12 @@ void PartSet_SketcherReentrantMgr::onVertexSelected()
 
 void PartSet_SketcherReentrantMgr::onAfterValuesChangedInPropertyPanel()
 {
-  // blocked flag in order to avoid circling when storeValue will be applied in
-  // this method to cached widget
-  if (myIsValueChangedBlocked)
-    return;
 
   if (isInternalEditActive()) {
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                       (myWorkshop->currentOperation());
     ModuleBase_ModelWidget* aWidget = (ModuleBase_ModelWidget*)sender();
-    if (!aWidget->isModifiedInEdit())
+    if (!aWidget->isModifiedInEdit().empty())
       restartOperation();
   }
 }
@@ -394,28 +423,6 @@ bool PartSet_SketcherReentrantMgr::canBeCommittedByPreselection()
   return !isActiveMgr() || myRestartingMode == RM_None;
 }
 
-void PartSet_SketcherReentrantMgr::appendCreatedObjects(const std::set<ObjectPtr>& theObjects)
-{
-  if (!myIsFlagsBlocked) // we need to collect objects only when launch operation is called
-    return;
-
-  FeaturePtr aCurrentFeature;
-  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
-                                                       (myWorkshop->currentOperation());
-  if (aFOperation)
-    aCurrentFeature = aFOperation->feature();
-
-
-  for (std::set<ObjectPtr>::const_iterator anIt = theObjects.begin();
-       anIt != theObjects.end(); ++anIt) {
-    FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
-    if (aFeature == aCurrentFeature)
-      continue;
-    if (myCreatedFeatures.find(aFeature) == myCreatedFeatures.end())
-      myCreatedFeatures.insert(aFeature);
-  }
-}
-
 bool PartSet_SketcherReentrantMgr::isActiveMgr() const
 {
   ModuleBase_Operation* aCurrentOperation = myWorkshop->currentOperation();
@@ -435,6 +442,10 @@ bool PartSet_SketcherReentrantMgr::isActiveMgr() const
 
 bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePreviousAttributeID)
 {
+#ifdef DEBUG_RESTART
+  std::cout << "PartSet_SketcherReentrantMgr::startInternalEdit" << std::endl;
+#endif
+
   bool isDone = false;
   /// this is workaround for ModuleBase_WidgetEditor, used in SALOME mode. Sometimes key enter
   /// event comes two times, so we should not start another internal edit operation
@@ -520,32 +531,30 @@ void PartSet_SketcherReentrantMgr::beforeStopInternalEdit()
 
 void PartSet_SketcherReentrantMgr::restartOperation()
 {
+#ifdef DEBUG_RESTART
+  std::cout << "PartSet_SketcherReentrantMgr::restartOperation" << std::endl;
+#endif
+
   if (myIsInternalEditOperation) {
     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(
                                                                   myWorkshop->currentOperation());
     if (aFOperation) {
-      // obtain widgets(attributes) which content should be applied to attributes of new feature
-      ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
-      ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
-      const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
-      QList<ModuleBase_ModelWidget*> aValueWidgets;
-      for (int i = 0, aSize = aWidgets.size(); i < aSize; i++) {
-        ModuleBase_ModelWidget* aWidget = aWidgets[i];
-        if (!aWidget->isModifiedInEdit()) {
-          aValueWidgets.append(aWidget);
-          // the widget is cashed to fill feature of new operation by the current widget value
-          // we set empty parent to the widget in order to remove it ourselves. Reason: restart
-          // operation will clear property panel and delete all widgets. This widget should be
-          // removed only after applying value of the widget to new created feature.
-          aWidget->setParent(0);
-        }
-      }
+      ModuleBase_ISelection* aSelection = myWorkshop->selection();
+      QList<ModuleBase_ViewerPrsPtr> aPreSelected =
+        aSelection->getSelected(ModuleBase_ISelection::AllControls);
+
+
+
+      if (myInternalFeature.get())
+        copyReetntrantAttributes(myInternalFeature, aFOperation->feature(),
+                                  module()->sketchMgr()->activeSketch());
 
       myNoMoreWidgetsAttribute = "";
       myIsFlagsBlocked = true;
       module()->launchOperation(aFOperation->id());
       myIsFlagsBlocked = false;
       resetFlags();
+
       // we should avoid processing of the signal about no more widgets attributes and
       // do this after the restart operaion is finished if it was called
       // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute
@@ -554,21 +563,6 @@ void PartSet_SketcherReentrantMgr::restartOperation()
         onNoMoreWidgets(myNoMoreWidgetsAttribute);
         myNoMoreWidgetsAttribute = "";
       }
-
-      // filling new feature by the previous value of active widget
-      // (e.g. circle_type in macro Circle)
-      ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(
-                                                                myWorkshop->currentOperation());
-      myIsValueChangedBlocked = true; // flag to avoid onAfterValuesChangedInPropertyPanel slot
-      for (int i = 0, aSize = aValueWidgets.size(); i < aSize; i++) {
-        ModuleBase_ModelWidget* aWidget = aValueWidgets[i];
-        aWidget->setEditingMode(false);
-        aWidget->setFeature(aFOperation->feature());
-        aWidget->storeValue();
-        // we must delete this widget
-        delete aWidget;
-      }
-      myIsValueChangedBlocked = false;
     }
   }
 }
@@ -584,6 +578,11 @@ void PartSet_SketcherReentrantMgr::createInternalFeature()
     CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
     myInternalFeature = aSketch->addFeature(anOperationFeature->getKind());
 
+#ifdef DEBUG_RESTART
+    std::cout << "PartSet_SketcherReentrantMgr::createInternalFeature: "
+              << myInternalFeature->data()->name() << std::endl;
+#endif
+
     bool isFeatureChanged = copyReetntrantAttributes(anOperationFeature, myInternalFeature,
                                                      aSketch, false);
     XGUI_PropertyPanel* aPropertyPanel = dynamic_cast<XGUI_PropertyPanel*>
@@ -618,6 +617,10 @@ void PartSet_SketcherReentrantMgr::createInternalFeature()
 
 void PartSet_SketcherReentrantMgr::deleteInternalFeature()
 {
+#ifdef DEBUG_RESTART
+  std::cout << "PartSet_SketcherReentrantMgr::deleteInternalFeature: "
+            << myInternalFeature->data()->name() << std::endl;
+#endif
   if (myInternalActiveWidget) {
     ModuleBase_WidgetSelector* aWSelector =
       dynamic_cast<ModuleBase_WidgetSelector*>(myInternalActiveWidget);
@@ -640,22 +643,28 @@ void PartSet_SketcherReentrantMgr::resetFlags()
     myIsInternalEditOperation = false;
     updateAcceptAllAction();
     myRestartingMode = RM_None;
-    myCreatedFeatures.clear();
+    myReentrantMessage = std::shared_ptr<Events_Message>();
   }
 }
 
 bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& theSourceFeature,
                                                              const FeaturePtr& theNewFeature,
                                                              const CompositeFeaturePtr& theSketch,
-                                                             const bool isTemporary)
+                                                             const bool /*isTemporary*/)
 {
   bool aChanged = false;
   if (!theSourceFeature.get() || !theSourceFeature->data().get() ||
       !theSourceFeature->data()->isValid())
     return aChanged;
 
+#ifdef DEBUG_RESTART
+  std::cout << "PartSet_SketcherReentrantMgr::copyReetntrantAttributes from '"
+            << theSourceFeature->data()->name() << "' to '" << theNewFeature->data()->name()
+            << "'" << std::endl;
+#endif
+
   std::string aFeatureKind = theSourceFeature->getKind();
-  if (aFeatureKind == SketchPlugin_Line::ID()) {
+  /*if (aFeatureKind == SketchPlugin_Line::ID()) {
     // Initialize new line with first point equal to end of previous
     std::shared_ptr<ModelAPI_Data> aSFData = theSourceFeature->data();
     std::shared_ptr<GeomDataAPI_Point2D> aSPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
@@ -670,22 +679,23 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th
                                                  aSFData->attribute(SketchPlugin_Line::END_ID()));
     aNPoint->setValue(aSPoint->x(), aSPoint->y());
   }
-  else if (aFeatureKind == SketchPlugin_MacroCircle::ID()) {
+  else*/ if (aFeatureKind == SketchPlugin_MacroCircle::ID()) {
     // set circle type
-    std::string aTypeAttributeId = SketchPlugin_MacroCircle::CIRCLE_TYPE();
+    /*std::string aTypeAttributeId = SketchPlugin_MacroCircle::CIRCLE_TYPE();
     AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
     AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
-    aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
+    if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes
+      aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
     //ModuleBase_Tools::flushUpdated(theNewFeature);
-    aChanged = true;
+    aChanged = true;*/
   }
   else if (aFeatureKind == SketchPlugin_MacroArc::ID()) {
     // set arc type
     std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE();
     AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
     AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
-    aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
-
+    if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes
+      aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
     //// if the arc is tangent, set coincidence to end point of the previous arc
     //std::string anArcType = aSourceFeatureTypeAttr->value();
     //if (anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT()) {
@@ -708,6 +718,41 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th
     //ModuleBase_Tools::flushUpdated(theNewFeature);
     aChanged = true;
   }
+  else if (aFeatureKind == SketchPlugin_Trim::ID()) {
+    /*std::shared_ptr<ModelAPI_AttributeReference> aRefSelectedAttr =
+                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                            theSourceFeature->data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
+    std::shared_ptr<ModelAPI_AttributeReference> aNRefSelectedAttr =
+                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                            theNewFeature->data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
+    aNRefSelectedAttr->setValue(aRefSelectedAttr->value());*/
+
+    std::shared_ptr<ModelAPI_AttributeReference> aRefPreviewAttr =
+                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                            theSourceFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+    std::shared_ptr<ModelAPI_AttributeReference> aNRefPreviewAttr =
+                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                            theNewFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+    aNRefPreviewAttr->setValue(aRefPreviewAttr->value());
+
+    /*std::shared_ptr<GeomDataAPI_Point2D> aPointSelectedAttr =
+                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                            theSourceFeature->data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
+    std::shared_ptr<GeomDataAPI_Point2D> aNPointSelectedAttr =
+                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                            theNewFeature->data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
+    aNPointSelectedAttr->setValue(aPointSelectedAttr->x(), aPointSelectedAttr->y());
+    */
+    std::shared_ptr<GeomDataAPI_Point2D> aPointPreviewAttr =
+                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                            theSourceFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
+    std::shared_ptr<GeomDataAPI_Point2D> aNPointPreviewAttr =
+                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                            theNewFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
+    aNPointPreviewAttr->setValue(aPointPreviewAttr->x(), aPointPreviewAttr->y());
+
+    aChanged = true;
+  }
   return aChanged;
 }
 
index 96ff877538642fcf6c77b8c30da2969b8a20412f..3fc5c22469eb820acbbff38bb63648e2a0060565 100644 (file)
@@ -8,6 +8,7 @@
 #include <ModelAPI_Feature.h>
 
 #include <string>
+#include <memory>
 
 #include <QObject>
 
@@ -23,6 +24,9 @@ class QMouseEvent;
 class XGUI_Workshop;
 class PartSet_Module;
 class ModuleBase_ViewerPrs;
+class Events_Message;
+class ModelAPI_Attribute;
+class GeomAPI_Pnt2d;
 
 /// \ingroup PartSet_SketcherReentrantMgr
 /// It provides reentrant create operations in sketch, that is when all inputs are valid,
@@ -102,10 +106,17 @@ public:
   /// Returns false if the reentrant mode of the operation is not empty.
   bool canBeCommittedByPreselection();
 
-  /// Put information about created objects into a cash. It will be processed in
-  /// restart operation.
-  /// \param theObjects a list of created objects
-  void appendCreatedObjects(const std::set<ObjectPtr>& theObjects);
+  /// Fills reentrant message during restarting operation
+  /// \param theMessage reentrant message
+  void setReentrantMessage(const std::shared_ptr<Events_Message>& theMessage)
+  { myReentrantMessage = theMessage; }
+
+  /// Returnss reentrant message
+  std::shared_ptr<Events_Message> reentrantMessage() const { return myReentrantMessage; }
+
+  /// Put current selection into reentrant message
+  /// \param theMessage a message of reentrant operation
+  void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage);
 
 private slots:
   /// SLOT, that is called by a widget activating in the property panel
@@ -195,14 +206,17 @@ private:
   RestartingMode myRestartingMode;  /// automatical restarting mode flag
   bool myIsFlagsBlocked; /// true when reset of flags should not be perfromed
   bool myIsInternalEditOperation; /// true when the 'internal' edit is started
-  bool myIsValueChangedBlocked; /// blocked flag to avoid circling by value changed
 
   FeaturePtr myPreviousFeature; /// feature of the previous operation, which is restarted
-  std::set<FeaturePtr> myCreatedFeatures; /// list of created features by restart operation
   FeaturePtr myInternalFeature;
   QWidget* myInternalWidget;
   ModuleBase_ModelWidget* myInternalActiveWidget;
   std::string myNoMoreWidgetsAttribute;
+
+  std::shared_ptr<Events_Message> myReentrantMessage; /// message obtained by operation restart
+  ObjectPtr mySelectedObject; /// cashed selected object
+  std::shared_ptr<ModelAPI_Attribute> mySelectedAttribute; /// cashed selected attribute
+  std::shared_ptr<GeomAPI_Pnt2d> myClickedSketchPoint; /// cashed clicked point
 };
 
 #endif
index 37cee3d6771e9b9e6eea108280de8353a0fd1a13..0976d01ced0d523ec3a576ff3bc7ee4a8d714fbe 100755 (executable)
@@ -17,6 +17,8 @@
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Validator.h>
 
+#include <ModuleBase_IViewWindow.h>
+
 #include <ModelGeomAlgo_Point2D.h>
 
 #include <Events_Loop.h>
@@ -73,6 +75,8 @@
 #include <StdSelect_BRepOwner.hxx>
 #include <SelectMgr_IndexedMapOfOwner.hxx>
 
+#include <QMouseEvent>
+
 #ifdef _DEBUG
 #include <QDebug>
 #endif
@@ -643,6 +647,18 @@ std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::getPoint(
   return std::shared_ptr<GeomAPI_Pnt2d>();
 }
 
+std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::getPnt2d(QMouseEvent* theEvent,
+                                                ModuleBase_IViewWindow* theWindow,
+                                                const FeaturePtr& theSketch)
+{
+  gp_Pnt aPnt = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
+  double aX, anY;
+  Handle(V3d_View) aView = theWindow->v3dView();
+  PartSet_Tools::convertTo2D(aPnt, theSketch, aView, aX, anY);
+
+  return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, anY));
+}
+
 FeaturePtr findFirstCoincidenceByData(const DataPtr& theData,
                                       std::shared_ptr<GeomAPI_Pnt2d> thePoint)
 {
index 1b9937dd1e29c12d32336782dd88128a4c5f82df..1429f9d29cfdfb853b1e38a93487f8ce2202967e 100755 (executable)
@@ -25,6 +25,7 @@
 #include <memory>
 
 class V3d_View;
+class ModuleBase_IViewWindow;
 class ModuleBase_ViewerPrs;
 class ModuleBase_IWorkshop;
 class GeomDataAPI_Point2D;
@@ -36,6 +37,8 @@ class GeomAPI_Edge;
 class GeomAPI_Vertex;
 class ModelAPI_Result;
 
+class QMouseEvent;
+
 /*!
  * \class PartSet_Tools
  * \ingroup Modules
@@ -214,6 +217,16 @@ public:
   static std::shared_ptr<GeomAPI_Pnt2d> getPoint(std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                  const std::string& theAttribute);
 
+  /**
+  * Convertes parameters into a geom point
+  * \theEvent a Qt event to find mouse position
+  * \param theWindow view window to define eye of view
+  * \param theSketch to convert 3D point coordinates into coorditates of the sketch plane
+  */
+  static std::shared_ptr<GeomAPI_Pnt2d> getPnt2d(QMouseEvent* theEvent,
+                                                 ModuleBase_IViewWindow* theWindow,
+                                                 const FeaturePtr& theSketch);
+
   /**
   * Gets all references to the feature, take coincidence constraint features, get point 2d attributes
   * and compare the point value to be equal with the given. Returns the first feature, which has
index e8c4abf8c71a1f949d7d5bca8e6ace9640e30e1a..0fecb7ed7855e535d11dfc007a7ffe30e5565f84 100644 (file)
@@ -170,11 +170,6 @@ bool PartSet_WidgetFeaturePointSelector::fillFeature(
   if (!anObject.get())
     return aFilled;
 
-  gp_Pnt aPnt = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
-  double aX, anY;
-  Handle(V3d_View) aView = theWindow->v3dView();
-  PartSet_Tools::convertTo2D(aPnt, mySketch, aView, aX, anY);
-
   std::shared_ptr<ModelAPI_AttributeReference> aRef =
                           std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
                           feature()->data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
@@ -183,7 +178,8 @@ bool PartSet_WidgetFeaturePointSelector::fillFeature(
   std::shared_ptr<GeomDataAPI_Point2D> anAttributePoint =
                   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
                   feature()->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
-  anAttributePoint->setValue(aX, anY);
+  std::shared_ptr<GeomAPI_Pnt2d> aPoint = PartSet_Tools::getPnt2d(theEvent, theWindow, mySketch);
+  anAttributePoint->setValue(aPoint);
   // redisplay AIS presentation in viewer
 #ifndef HIGHLIGHT_STAYS_PROBLEM
   // an attempt to clear highlighted item in the viewer: but of OCCT
index 8ac8414eef33291978f8c44b9494faada2b5ae43..96e7591c95559ced89aec8c2bf7a22df443aecd3 100644 (file)
@@ -31,6 +31,7 @@ SET(PROJECT_HEADERS
     SketchPlugin_IntersectionPoint.h
     SketchPlugin_Line.h
     SketchPlugin_MacroArc.h
+    SketchPlugin_MacroArcReentrantMessage.h
     SketchPlugin_MacroCircle.h
     SketchPlugin_MultiRotation.h
     SketchPlugin_MultiTranslation.h
index 10e1ed235e937aa2d04f45d5b2aa19cb2e6d0d3b..025a98b432fdd88f377eccd1ce3a02f7cab79e96 100644 (file)
@@ -6,7 +6,10 @@
 
 #include "SketchPlugin_Line.h"
 #include "SketchPlugin_Sketch.h"
+#include "SketchPlugin_ConstraintCoincidence.h"
+
 #include <ModelAPI_Data.h>
+#include <ModelAPI_EventReentrantMessage.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeBoolean.h>
@@ -64,6 +67,14 @@ void SketchPlugin_Line::execute()
       aConstr->setShape(anEdge);
       aConstr->setIsInHistory(false);
       setResult(aConstr);
+
+      static Events_ID anId = ModelAPI_EventReentrantMessage::eventId();
+      std::shared_ptr<ModelAPI_EventReentrantMessage> aMessage = std::shared_ptr
+          <ModelAPI_EventReentrantMessage>(new ModelAPI_EventReentrantMessage(anId, 0));
+      aMessage->setCreatedFeature(ModelAPI_Feature::feature(
+                                  data()->attribute(START_ID())->owner()));
+      Events_Loop::loop()->send(aMessage);
+      Events_Loop::loop()->flush(anId);
     }
   }
 }
@@ -83,6 +94,33 @@ void SketchPlugin_Line::move(double theDeltaX, double theDeltaY)
   aPoint2->move(theDeltaX, theDeltaY);
 }
 
+std::string SketchPlugin_Line::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+  std::string aFilledAttributeName;
+
+  std::shared_ptr<ModelAPI_EventReentrantMessage> aReentrantMessage =
+        std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
+  if (aReentrantMessage.get()) {
+    FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+
+    // Initialize new line with first point equal to end of previous
+    std::shared_ptr<ModelAPI_Data> aSFData = aCreatedFeature->data();
+    std::shared_ptr<GeomDataAPI_Point2D> aSPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                                 aSFData->attribute(SketchPlugin_Line::END_ID()));
+    std::shared_ptr<ModelAPI_Data> aNFData = data();
+    std::shared_ptr<GeomDataAPI_Point2D> aNPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                                 aNFData->attribute(SketchPlugin_Line::START_ID()));
+    aNPoint->setValue(aSPoint->x(), aSPoint->y());
+    SketchPlugin_ConstraintCoincidence::createCoincidenceFeature(sketch(), aSPoint, aNPoint);
+
+    aNPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                                 aSFData->attribute(SketchPlugin_Line::END_ID()));
+    aNPoint->setValue(aSPoint->x(), aSPoint->y());
+
+  }
+  return aFilledAttributeName;
+}
+
 double SketchPlugin_Line::distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
 {
   double aDelta = 0;
index e24e90e5444c0f52762a57e99e576f89258db299..173c2c3564570554418ba6f8db38be6381b98239 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef SketchPlugin_Line_H_
 #define SketchPlugin_Line_H_
 
+#include <ModelAPI_IReentrant.h>
+
 #include "SketchPlugin.h"
 #include <SketchPlugin_SketchEntity.h>
 #include <SketchPlugin_Sketch.h>
@@ -18,7 +20,8 @@ class GeomAPI_Pnt2d;
  * \ingroup Plugins
  * \brief Feature for creation of the new part in PartSet.
  */
-class SketchPlugin_Line : public SketchPlugin_SketchEntity
+class SketchPlugin_Line : public SketchPlugin_SketchEntity,
+                          public ModelAPI_IReentrant
 {
  public:
   /// Arc feature kind
@@ -64,6 +67,11 @@ class SketchPlugin_Line : public SketchPlugin_SketchEntity
   /// \param theDeltaY the delta for Y coordinate is moved
   SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY);
 
+  /// Apply information of the message to current object. It fills start attribute of
+  /// the currrent feature by last attribute of the message feature, build coincidence
+  /// if message has selected object
+  virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
   /// Return the distance between the feature and the point
   /// \param thePoint the point
   double distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
index cd199d936b612c853c93aad8ad4d686bfe7cdbe5..6a0fff2dc33a10d86129989de9aaf5db89e888d3 100644 (file)
 #include "SketchPlugin_ConstraintTangent.h"
 #include "SketchPlugin_Sketch.h"
 #include "SketchPlugin_Tools.h"
+#include "SketchPlugin_MacroArcReentrantMessage.h"
 
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Events.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 
@@ -82,12 +84,16 @@ void SketchPlugin_MacroArc::initAttributes()
   data()->addAttribute(END_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
   data()->addAttribute(PASSED_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
 
+  data()->addAttribute(EDIT_ARC_TYPE_ID(), ModelAPI_AttributeString::typeId());
+
   boolean(REVERSED_ID())->setValue(false);
+  string(EDIT_ARC_TYPE_ID())->setValue("");
 
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_POINT_REF_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), START_POINT_REF_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), END_POINT_REF_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PASSED_POINT_REF_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_ARC_TYPE_ID());
 }
 
 void SketchPlugin_MacroArc::attributeChanged(const std::string& theID)
@@ -268,6 +274,81 @@ void SketchPlugin_MacroArc::execute()
                                          ObjectPtr(),
                                          false);
   }
+
+  // message to init reentrant operation
+  static Events_ID anId = SketchPlugin_MacroArcReentrantMessage::eventId();
+  std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aMessage = std::shared_ptr
+    <SketchPlugin_MacroArcReentrantMessage>(new SketchPlugin_MacroArcReentrantMessage(anId, 0));
+
+  std::string anEditArcType = string(EDIT_ARC_TYPE_ID())->value();
+  aMessage->setTypeOfCreation(!anEditArcType.empty() ? anEditArcType : anArcType);
+  aMessage->setCreatedFeature(anArcFeature);
+  Events_Loop::loop()->send(aMessage);
+  Events_Loop::loop()->flush(anId);
+}
+
+std::string SketchPlugin_MacroArc::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+  std::string aFilledAttributeName;
+  std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aReentrantMessage =
+        std::dynamic_pointer_cast<SketchPlugin_MacroArcReentrantMessage>(theMessage);
+  if (aReentrantMessage.get()) {
+    FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+    std::string anArcType = aReentrantMessage->typeOfCreation();
+
+    string(ARC_TYPE())->setValue(anArcType);
+
+    aFilledAttributeName = ARC_TYPE();
+    if(anArcType == ARC_TYPE_BY_TANGENT_EDGE()) {
+      aFilledAttributeName = TANGENT_POINT_ID();
+      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                                        attribute(aFilledAttributeName));
+      FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+      aRefAttr->setAttr(aCreatedFeature->attribute(SketchPlugin_Arc::END_ID()));
+    }
+    else {
+      ObjectPtr anObject = aReentrantMessage->selectedObject();
+      AttributePtr anAttribute = aReentrantMessage->selectedAttribute();
+      std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = aReentrantMessage->clickedPoint();
+
+      if (aClickedPoint.get() && (anObject.get() || anAttribute.get())) {
+        if (anArcType == ARC_TYPE_BY_CENTER_AND_POINTS() ||
+            anArcType == ARC_TYPE_BY_THREE_POINTS()) {
+          std::string aReferenceAttributeName;
+          if (anArcType == ARC_TYPE_BY_CENTER_AND_POINTS()) {
+            aFilledAttributeName = CENTER_POINT_ID();
+            aReferenceAttributeName = CENTER_POINT_REF_ID();
+          }
+          else {
+            aFilledAttributeName = START_POINT_2_ID();
+            aReferenceAttributeName = START_POINT_REF_ID();
+          }
+          // fill 2d point attribute
+          AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                                            attribute(aFilledAttributeName));
+          aPointAttr->setValue(aClickedPoint);
+          // fill reference attribute
+          AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                                            attribute(aReferenceAttributeName));
+          if (aRefAttr.get()) {
+            if (anAttribute.get())
+              aRefAttr->setAttr(anAttribute);
+            else if (anObject.get()) {
+              // if presentation of previous reentrant macro arc is used, the object is invalid,
+              // we should use result of previous feature of the message(Arc)
+              if (!anObject->data()->isValid()) {
+                FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+                anObject = aCreatedFeature->lastResult();
+              }
+              aRefAttr->setObject(anObject);
+            }
+          }
+        }
+      }
+    }
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  }
+  return aFilledAttributeName;
 }
 
 FeaturePtr SketchPlugin_MacroArc::createArcFeature()
index cc49b0e0233db56c82a7bc39934d337b33b95adc..81297838169f9353daa124d3abfb99ad70f31a47 100644 (file)
@@ -7,8 +7,9 @@
 #ifndef SketchPlugin_MacroArc_H_
 #define SketchPlugin_MacroArc_H_
 
-#include "SketchPlugin.h"
+#include <ModelAPI_IReentrant.h>
 
+#include "SketchPlugin.h"
 #include "SketchPlugin_SketchEntity.h"
 
 #include <GeomAPI_IPresentable.h>
@@ -24,7 +25,8 @@ class GeomAPI_Pnt2d;
  * it is calculated if all attributes are initialized.
  */
 class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity,
-                             public GeomAPI_IPresentable
+                             public GeomAPI_IPresentable,
+                             public ModelAPI_IReentrant
 {
  public:
   /// Arc feature kind
@@ -157,6 +159,13 @@ class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity,
     return ID;
   }
 
+  /// Arc angle.
+  static const std::string& EDIT_ARC_TYPE_ID()
+  {
+    static const std::string ID("edit_arc_type");
+    return ID;
+  }
+
   /// Returns the kind of a feature
   SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
   {
@@ -189,6 +198,10 @@ class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity,
 
   SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;};
 
+  /// Apply information of the message to current object. It fills reference object,
+  /// tangent type and tangent point refence in case of tangent arc
+  virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
   /// Use plugin manager for features creation.
   SketchPlugin_MacroArc();
 
diff --git a/src/SketchPlugin/SketchPlugin_MacroArcReentrantMessage.h b/src/SketchPlugin/SketchPlugin_MacroArcReentrantMessage.h
new file mode 100644 (file)
index 0000000..5ad9a8c
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    SketchPlugin_MacroArcReentrantMessage.h
+// Created: 01 Apr 2017
+// Author:  Natalia ERMOLAEVA
+
+#ifndef SketchPlugin_MacroArcReentrantMessage_H_
+#define SketchPlugin_MacroArcReentrantMessage_H_
+
+#include <ModelAPI_EventReentrantMessage.h>
+#include <Events_Loop.h>
+
+#include <SketchPlugin.h>
+
+#include <memory>
+
+/// Message that style of visualization of parameter is changed.
+/// It will be shown as expression or value
+class SketchPlugin_MacroArcReentrantMessage : public ModelAPI_EventReentrantMessage
+{
+public:
+  /// Creates an empty message
+  SKETCHPLUGIN_EXPORT SketchPlugin_MacroArcReentrantMessage(const Events_ID theID,
+                                                            const void* theSender = 0)
+  : ModelAPI_EventReentrantMessage(theID, theSender) {}
+  /// The virtual destructor
+  SKETCHPLUGIN_EXPORT virtual ~SketchPlugin_MacroArcReentrantMessage() {}
+  /// Static. Returns EventID of the message.
+
+  inline static Events_ID eventId()
+  {
+    static const char * MY_EVENT_MACRO_ARC_MESSAGE_ID("MacroArcReentrantMessage");
+    return Events_Loop::eventByName(MY_EVENT_MACRO_ARC_MESSAGE_ID);
+  }
+
+  /// Stores type of creation
+  /// \param the type
+  SKETCHPLUGIN_EXPORT void setTypeOfCreation(const std::string& theType)
+  { myTypeOfCreation = theType; }
+
+  /// Returns type of creation
+  /// \return the type
+  SKETCHPLUGIN_EXPORT std::string typeOfCreation() const { return myTypeOfCreation; }
+
+private:
+  std::string myTypeOfCreation; ///< to know what parameters of new feature should be filled
+};
+
+
+#endif
index da9625e23f5b066ae1c664b0ec196b594dcd318e..b865ec374d61420e52b206ee2984e08d2e79c00d 100644 (file)
@@ -9,12 +9,14 @@
 #include "SketchPlugin_Circle.h"
 #include "SketchPlugin_Point.h"
 #include "SketchPlugin_Tools.h"
+#include "SketchPlugin_MacroArcReentrantMessage.h"
 
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
+#include <ModelAPI_Events.h>
 
 #include <GeomDataAPI_Dir.h>
 #include <GeomDataAPI_Point2D.h>
@@ -54,6 +56,7 @@ SketchPlugin_MacroCircle::SketchPlugin_MacroCircle()
 void SketchPlugin_MacroCircle::initAttributes()
 {
   data()->addAttribute(CIRCLE_TYPE(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(EDIT_CIRCLE_TYPE(), ModelAPI_AttributeString::typeId());
 
   data()->addAttribute(CENTER_POINT_ID(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(CENTER_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
@@ -70,11 +73,14 @@ void SketchPlugin_MacroCircle::initAttributes()
   data()->addAttribute(CIRCLE_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
   data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
 
+  string(EDIT_CIRCLE_TYPE())->setValue("");
+
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_POINT_REF_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PASSED_POINT_REF_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FIRST_POINT_REF_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SECOND_POINT_REF_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), THIRD_POINT_REF_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_CIRCLE_TYPE());
 }
 
 void SketchPlugin_MacroCircle::execute()
@@ -86,6 +92,69 @@ void SketchPlugin_MacroCircle::execute()
     constraintsForCircleByCenterAndPassed(aCircle);
   else if (aType == CIRCLE_TYPE_BY_THREE_POINTS())
     constraintsForCircleByThreePoints(aCircle);
+
+  // message to init reentrant operation
+  static Events_ID anId = SketchPlugin_MacroArcReentrantMessage::eventId();
+  std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aMessage = std::shared_ptr
+    <SketchPlugin_MacroArcReentrantMessage>(new SketchPlugin_MacroArcReentrantMessage(anId, 0));
+
+  std::string anEditType = string(EDIT_CIRCLE_TYPE())->value();
+  aMessage->setTypeOfCreation(!anEditType.empty() ? anEditType : aType);
+  aMessage->setCreatedFeature(aCircle);
+  Events_Loop::loop()->send(aMessage);
+  Events_Loop::loop()->flush(anId);
+}
+
+std::string SketchPlugin_MacroCircle::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+  std::string aFilledAttributeName;
+  std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aReentrantMessage =
+        std::dynamic_pointer_cast<SketchPlugin_MacroArcReentrantMessage>(theMessage);
+  if (aReentrantMessage.get()) {
+    FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+    std::string aCircleType = aReentrantMessage->typeOfCreation();
+
+    string(CIRCLE_TYPE())->setValue(aCircleType);
+
+    aFilledAttributeName = CIRCLE_TYPE();
+    ObjectPtr anObject = aReentrantMessage->selectedObject();
+    AttributePtr anAttribute = aReentrantMessage->selectedAttribute();
+    std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = aReentrantMessage->clickedPoint();
+
+    if (aClickedPoint.get() && (anObject.get() || anAttribute.get())) {
+      std::string aReferenceAttributeName;
+      if (aCircleType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()) {
+        aFilledAttributeName = CENTER_POINT_ID();
+        aReferenceAttributeName = CENTER_POINT_REF_ID();
+      }
+      else {
+        aFilledAttributeName = FIRST_POINT_ID();
+        aReferenceAttributeName = FIRST_POINT_REF_ID();
+      }
+      // fill 2d point attribute
+      AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                                        attribute(aFilledAttributeName));
+      aPointAttr->setValue(aClickedPoint);
+      // fill reference attribute
+      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                                        attribute(aReferenceAttributeName));
+      if (aRefAttr.get()) {
+        if (anAttribute.get())
+          aRefAttr->setAttr(anAttribute);
+        else if (anObject.get()) {
+          // if presentation of previous reentrant macro arc is used, the object is invalid,
+          // we should use result of previous feature of the message(Arc)
+          if (!anObject->data()->isValid()) {
+            FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+            anObject = aCreatedFeature->lastResult();
+          }
+          aRefAttr->setObject(anObject);
+        }
+      }
+    }
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  }
+  return aFilledAttributeName;
 }
 
 void SketchPlugin_MacroCircle::constraintsForCircleByCenterAndPassed(FeaturePtr theCircleFeature)
index 6bf46f36ca2afba24ec6cd7be89ee432a1f3e7a8..4e1bfeb22e049df6f5d63c5efa375095abccd5ab 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef SketchPlugin_MacroCircle_H_
 #define SketchPlugin_MacroCircle_H_
 
+#include <ModelAPI_IReentrant.h>
+
 #include "SketchPlugin.h"
 
 #include "SketchPlugin_SketchEntity.h"
@@ -21,7 +23,8 @@ class GeomAPI_Pnt2d;
  * \brief Feature for creation of the new circle in Sketch.
  */
 class SketchPlugin_MacroCircle: public SketchPlugin_SketchEntity,
-                                public GeomAPI_IPresentable
+                                public GeomAPI_IPresentable,
+                                public ModelAPI_IReentrant
 {
  public:
   /// Circle feature kind
@@ -37,6 +40,12 @@ class SketchPlugin_MacroCircle: public SketchPlugin_SketchEntity,
     return ID;
   }
 
+  inline static const std::string& EDIT_CIRCLE_TYPE()
+  {
+    static const std::string ID("edit_circle_type");
+    return ID;
+  }
+
   /// Creation method by center and passed point.
   inline static const std::string& CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()
   {
@@ -159,6 +168,10 @@ class SketchPlugin_MacroCircle: public SketchPlugin_SketchEntity,
 
   SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;};
 
+  /// Apply information of the message to current object. It fills reference object,
+  /// tangent type and tangent point refence in case of tangent arc
+  virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
   /// Use plugin manager for features creation
   SketchPlugin_MacroCircle();
 
index 46b01dee111b80214a810185788aa4d61d2be937..e94f4b10cbd40a07eae3c960fbaa1a0166ba5729 100644 (file)
@@ -41,6 +41,8 @@
 #include <SketchPlugin_MultiTranslation.h>
 #include <SketchPlugin_Point.h>
 
+#include <ModelAPI_EventReentrantMessage.h>
+
 #include <ModelAPI_Events.h>
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Arc.h>
 
 #include <cmath>
 
-#define DEBUG_TRIM
+//#define DEBUG_TRIM_METHODS
+//#define DEBUG_TRIM
+
 #ifdef DEBUG_TRIM
 #include <iostream>
 #endif
 
+#ifdef DEBUG_TRIM_METHODS
+#include <iostream>
+#endif
+
 static const double PI = 3.141592653589793238463;
 
 static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; }
@@ -174,8 +182,8 @@ std::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Trim::convertPoint(
 
 void SketchPlugin_Trim::execute()
 {
-#ifdef DEBUG_TRIM
-  std::cout << "SketchPlugin_Trim::execute" << std::endl;
+#ifdef DEBUG_TRIM_METHODS
+  std::cout << "SketchPlugin_Trim::execute: " << data()->name() << std::endl;
 #endif
 
   SketchPlugin_Sketch* aSketch = sketch();
@@ -199,8 +207,16 @@ void SketchPlugin_Trim::execute()
   AttributeReferencePtr aPreviewObjectAttr =
                      std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
                      data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+
+  ObjectPtr aPreviewObject = aPreviewObjectAttr->value();
+  AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                           data()->attribute(PREVIEW_POINT()));
+  std::shared_ptr<GeomAPI_Pnt2d> aPreviewPnt2d = aPoint->pnt();
+  // nullify pointer of preview attribute
   aPreviewObjectAttr->setValue(ResultPtr());
 
+  bool anIsEqualPreviewAndSelected = aPreviewObject == aBaseObject;
+
   /// points of trim
   std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
 #ifdef DEBUG_TRIM
@@ -269,7 +285,7 @@ void SketchPlugin_Trim::execute()
   std::set<AttributePoint2DPtr> aFurtherCoincidences;
   std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
   const std::string& aKind = aBaseFeature->getKind();
-  FeaturePtr aReplacingFeature;
+  FeaturePtr aReplacingFeature, aNewFeature;
   if (aKind == SketchPlugin_Circle::ID()) {
     aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d,
                aFurtherCoincidences, aModifiedAttributes);
@@ -281,12 +297,12 @@ void SketchPlugin_Trim::execute()
     aBaseObjectAttr->setObject(ResultPtr());
   }
   else if (aKind == SketchPlugin_Line::ID()) {
-    trimLine(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
-             aFurtherCoincidences, aModifiedAttributes);
+    aNewFeature = trimLine(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
+                           aFurtherCoincidences, aModifiedAttributes);
   }
   else if (aKind == SketchPlugin_Arc::ID()) {
-    trimArc(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
-            aFurtherCoincidences, aModifiedAttributes);
+    aNewFeature = trimArc(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
+                          aFurtherCoincidences, aModifiedAttributes);
   }
 
   // constraints to end points of trim feature
@@ -398,11 +414,116 @@ void SketchPlugin_Trim::execute()
     Events_Loop::loop()->setFlushed(anUpdateEvent, true);
   }
 
+  if (anIsEqualPreviewAndSelected) {
+    // equal preview and selected objects
+    // nothing to do if the preview and selected objects are different
+    if (aReplacingResult.get()) { // base object was removed
+      aPreviewObject = aReplacingResult;
+      //aMessage->setSelectedObject(aReplacingResult);
+
+      GeomShapePtr aSelectedShape = aReplacingResult->shape();
+      std::shared_ptr<GeomAPI_Pnt> aPreviewPnt = sketch()->to3D(aPreviewPnt2d->x(),
+                                                                aPreviewPnt2d->y());
+      std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+      if (ModelGeomAlgo_Point2D::isPointOnEdge(aSelectedShape, aPreviewPnt, aProjectedPoint)) {
+        bool aValue = true;
+      }
+      //aBaseShape = aShape;
+
+#ifdef DEBUG_TRIM_METHODS
+      if (!aSelectedShape.get())
+        std::cout << "Set empty selected object" << std::endl;
+      else
+        std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl;
+#endif
+      bool aValue = true;
+    }
+    else {
+      aPreviewObject = ObjectPtr();
+
+      aBaseFeature->execute(); // should recompute shapes of result to do not check obsolete one
+      aBaseObject = getFeatureResult(aBaseFeature);
+      std::shared_ptr<GeomAPI_Pnt> aPreviewPnt = sketch()->to3D(aPreviewPnt2d->x(),
+                                                                aPreviewPnt2d->y());
+      ResultPtr aBaseResult = std::dynamic_pointer_cast<ModelAPI_Result>(aBaseObject);
+      if (aBaseResult) {
+        GeomShapePtr aShape = aBaseResult->shape();
+        std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+        if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPreviewPnt, aProjectedPoint))
+          aPreviewObject = aBaseResult;
+      }
+      if (!aPreviewObject.get() && aNewFeature.get()) {
+        ResultPtr aNewFeatureResult = getFeatureResult(aNewFeature);
+        if (aNewFeatureResult.get()) {
+          GeomShapePtr aShape = aNewFeatureResult->shape();
+          std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+          if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPreviewPnt, aProjectedPoint))
+            aPreviewObject = aNewFeatureResult;
+        }
+      }
+    }
+  }
+  if (aPreviewObject.get()) {
+    static Events_ID anId = ModelAPI_EventReentrantMessage::eventId();
+    std::shared_ptr<ModelAPI_EventReentrantMessage> aMessage = std::shared_ptr
+      <ModelAPI_EventReentrantMessage>(new ModelAPI_EventReentrantMessage(anId, 0));
+    aMessage->setSelectedObject(aPreviewObject);
+    Events_Loop::loop()->send(aMessage);
+    Events_Loop::loop()->flush(anId);
+  }
 #ifdef DEBUG_TRIM
   std::cout << "SketchPlugin_Trim::done" << std::endl;
 #endif
 }
 
+std::string SketchPlugin_Trim::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+#ifdef DEBUG_TRIM_METHODS
+  std::cout << "SketchPlugin_Trim::processEvent:" << data()->name() << std::endl;
+#endif
+
+  std::string aFilledAttributeName;
+
+  std::shared_ptr<ModelAPI_EventReentrantMessage> aMessage =
+        std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
+  if (aMessage.get()) {
+    ObjectPtr anObject = aMessage->selectedObject();
+    std::shared_ptr<GeomAPI_Pnt2d> aPoint = aMessage->clickedPoint();
+
+    if (anObject.get() && aPoint.get()) {
+      std::shared_ptr<ModelAPI_AttributeReference> aRefSelectedAttr =
+                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                            data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
+      std::shared_ptr<ModelAPI_AttributeReference> aRefPreviewAttr =
+                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                            data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+      aRefSelectedAttr->setValue(anObject);
+      aRefPreviewAttr->setValue(anObject);
+
+      std::shared_ptr<GeomDataAPI_Point2D> aPointSelectedAttr =
+                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                            data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
+      std::shared_ptr<GeomDataAPI_Point2D> aPointPreviewAttr =
+                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                            data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
+      aPointSelectedAttr->setValue(aPoint);
+      aPointPreviewAttr->setValue(aPoint);
+
+      Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+
+      GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT());
+#ifdef DEBUG_TRIM_METHODS
+      if (!aSelectedShape.get())
+        std::cout << "Set empty selected object" << std::endl;
+      else
+        std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl;
+#endif
+      aFilledAttributeName = SketchPlugin_Trim::SELECTED_OBJECT();
+    }
+  }
+  return aFilledAttributeName;
+}
+
 bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute,
                                 const std::set<AttributePoint2DPtr>& theFurtherCoincidences)
 {
@@ -470,6 +591,10 @@ bool SketchPlugin_Trim::isMacro() const
 
 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 {
+#ifdef DEBUG_TRIM_METHODS
+  std::cout << "SketchPlugin_Trim::getAISObject: " << data()->name() << std::endl;
+#endif
+
   AISObjectPtr anAIS = thePrevious;
 
   std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
@@ -744,12 +869,14 @@ void SketchPlugin_Trim::removeReferencesToAttribute(const AttributePtr& theAttri
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
 }
 
-void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+FeaturePtr SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
                   const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
                   std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
                   std::set<AttributePoint2DPtr>& thePoints,
                   std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
 {
+  FeaturePtr anNewFeature;
+
   // Check the base objects are initialized.
   AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
                                         data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
@@ -809,7 +936,7 @@ void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartS
     // result is two lines: start line point - start shape point,
     // last shape point - last line point
     // create second line
-    FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
+    anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
     thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
                                (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
 
@@ -830,14 +957,16 @@ void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartS
                                getFeatureResult(anNewFeature));
 
   }
+  return anNewFeature;
 }
 
-void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+FeaturePtr SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
                  const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
                  std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
                  std::set<AttributePoint2DPtr>& thePoints,
                  std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
 {
+  FeaturePtr anNewFeature;
   // Check the base objects are initialized.
   AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
                                         data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
@@ -892,14 +1021,14 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartSh
   else {
     // result is two arcs: start arc point - start shape point, last shape point - last arc point
     // create second arc
-    FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
+    anNewFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
     thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
-                               (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
+                               (anNewFeature->attribute(SketchPlugin_Arc::START_ID())));
 
     std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
     theModifiedAttributes.insert(
       std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
-                                   anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
+                                   anNewFeature->attribute(SketchPlugin_Arc::END_ID())));
 
     // modify base arc
     fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
@@ -908,20 +1037,22 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartSh
                                (aBaseFeature->attribute(aModifiedAttribute)));
 
     // equal Radius constraint for arcs
-    anArcFeature->execute(); // we need the created arc result to set equal constraint
+    anNewFeature->execute(); // we need the created arc result to set equal constraint
     createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
                                getFeatureResult(aBaseFeature),
-                               getFeatureResult(anArcFeature));
+                               getFeatureResult(anNewFeature));
     // coincident centers constraint
     createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
                      aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
-                     anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
+                     anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
 
+#ifdef DEBUG_TRIM
     std::cout << "Created arc on points:" << std::endl;
     std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " <<
                                            aStartShapePoint->y() << "]" << std::endl;
-
+#endif
   }
+  return anNewFeature;
 }
 
 FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
@@ -940,20 +1071,20 @@ FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& t
   //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
 
   /// trim feature
-  FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
+  FeaturePtr anNewFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
   // arc created by trim of circle is always correct, that means that it is not inversed
-  anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false);
+  anNewFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false);
 
   theModifiedAttributes.insert(
     std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
-                   anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
+                   anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
 
   thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
-                             (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
+                             (anNewFeature->attribute(SketchPlugin_Arc::START_ID())));
   thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
-                             (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
+                             (anNewFeature->attribute(SketchPlugin_Arc::END_ID())));
 
-  return anArcFeature;
+  return anNewFeature;
 }
 
 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
index 532731b394bc95cbbb0d23c4f047560574d6a7b0..5791ff690c450125bc1588654bb7bd0cade6ada8 100644 (file)
@@ -7,9 +7,11 @@
 #ifndef SketchPlugin_Trim_H_
 #define SketchPlugin_Trim_H_
 
+#include <ModelAPI_IReentrant.h>
+
 #include "SketchPlugin.h"
-#include <SketchPlugin_Sketch.h>
 #include "SketchPlugin_ConstraintBase.h"
+#include <SketchPlugin_Sketch.h>
 
 class GeomDataAPI_Point2D;
 class ModelAPI_Feature;
@@ -22,7 +24,8 @@ typedef std::pair<std::string, std::shared_ptr<GeomDataAPI_Point2D> > IdToPointP
  *  \ingroup Plugins
  *  \brief Feature for creation of a new constraint trimming object. Entities for split:
  */
-class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentable
+class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentable,
+                          public ModelAPI_IReentrant
 {
  public:
   /// Split constraint kind
@@ -89,11 +92,8 @@ class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentab
   /// Moves the feature : Empty
   SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY) {};
 
-  bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
-            const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
-
-  bool replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
-            const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
+  /// Apply information of the message to current object. It fills selected point and object
+  virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
 
   typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
                    std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
@@ -105,6 +105,12 @@ class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentab
     std::map<std::shared_ptr<ModelAPI_Object>, PointToRefsMap>& theObjectToPoints);
 
 private:
+  bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
+            const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
+
+  bool replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
+            const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
+
   GeomShapePtr getSubShape(const std::string& theObjectAttributeId,
                            const std::string& thePointAttributeId);
 
@@ -160,7 +166,8 @@ private:
   /// \param thePoints a list of points where coincidences will be build
   /// \param theModifiedAttributes a container of attribute on base
   /// feature to attribute on new feature
-  void trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+  /// \return new line if it was created
+  FeaturePtr trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
                 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
                 std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
                 std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
@@ -168,7 +175,8 @@ private:
 
   /// Make the base object is splitted by the point attributes
   /// \param thePoints a list of points where coincidences will be build
-  void trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+  /// \return new line if it was created
+  FeaturePtr trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
                const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
                std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
                std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
index 7dadf303c8c9c48b07a3cc52dd48b09cfa7ae326..2bf0fa121e48400d1f10980d1cc4e84a1569f121 100755 (executable)
@@ -877,14 +877,17 @@ bool SketchPlugin_TrimValidator::isValid(const AttributePtr& theAttribute,
     AttributePtr aPreviewAttr = aTrimFeature->attribute(SketchPlugin_Trim::PREVIEW_OBJECT());
     aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(aPreviewAttr);
     aBaseObject = aBaseObjectAttr->value();
-
-    //return aValid;
   }
 
   FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject);
   if (!aBaseFeature)
     return aValid;
 
+  std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+                                 std::dynamic_pointer_cast<SketchPlugin_Feature>(aBaseFeature);
+  if (!aSketchFeature.get() || aSketchFeature->isCopy())
+    return aValid;
+
   std::string aKind = aBaseFeature->getKind();
   if (aKind != SketchPlugin_Line::ID() &&
       aKind != SketchPlugin_Arc::ID() &&
index e1908173910b0768c235a651ce4d1cbe37468359..57d57f82e1b32f2dd299ed30c7e7fabd9f209c4a 100644 (file)
@@ -76,7 +76,7 @@
                icon="icons/Sketch/circle.png"
                title="Circle"
                tooltip="Create circle">
-        <toolbox id="circle_type" modified_in_edit="false">
+        <toolbox id="circle_type" modified_in_edit="edit_circle_type">
           <box id="circle_type_by_center_and_passed_points"
                icon="icons/Sketch/circle_pt_rad_32x32.png"
                title="Center and passed points">
         title="Arc"
         tooltip="Create arc"
         icon="icons/Sketch/arc.png">
-        <toolbox id="arc_type" modified_in_edit="false">
+        <toolbox id="arc_type" modified_in_edit="edit_arc_type">
           <box id="by_center_and_points"
                icon="icons/Sketch/arc_base_32x32.png"
                title="Center and two points">
index 3a320c4b0e807877a5c53b532230a6a78f504ca8..f9ad34c09fff0e3d0b39a3d309c22606ddeeb069 100644 (file)
@@ -38,7 +38,7 @@ public:
 
   /// Update actions for the given feature
   /// \param theFeature a feature
-  void updateActions(const FeaturePtr& theFeature);
+  virtual void updateActions(const FeaturePtr& theFeature);
 
   /// Update enable state of AcceptAll action if the feature uses it
   /// \param theFeature a feature
index 7231a1b28c33b8e790775019ebcbffb6ae3befcb..e6b6cf73fe249565817b83988643a47659e149df 100644 (file)
@@ -13,6 +13,7 @@
 #include "XGUI_Displayer.h"
 #include "XGUI_PropertyPanel.h"
 #include "XGUI_ActionsMgr.h"
+#include "XGUI_ErrorMgr.h"
 
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_ViewerPrs.h>
@@ -58,6 +59,11 @@ ModuleBase_IPropertyPanel* XGUI_ModuleConnector::propertyPanel() const
   return myWorkshop->propertyPanel();
 }
 
+ModuleBase_IErrorMgr* XGUI_ModuleConnector::errorMgr() const
+{
+  return myWorkshop->errorMgr();
+}
+
 ModuleBase_Operation* XGUI_ModuleConnector::currentOperation() const
 {
   return myWorkshop->operationMgr()->currentOperation();
index b86c0ef8ba2277515b1536837e83ce0e74421613..eb4c37c4f27de2caeda07fe73b2ef6b94c45e589 100644 (file)
@@ -50,6 +50,9 @@ Q_OBJECT
   //! Returns property panel
   virtual ModuleBase_IPropertyPanel* propertyPanel() const;
 
+  //! Returns error manager
+  virtual ModuleBase_IErrorMgr* errorMgr() const;
+
   //! Returns currently active operation
   virtual ModuleBase_Operation* currentOperation() const;