Salome HOME
Architecture changes
[modules/shaper.git] / src / PartSet / PartSet_SketcherMgr.cpp
old mode 100644 (file)
new mode 100755 (executable)
index ae21818..eddf4b0
@@ -5,11 +5,13 @@
 // Author:      Vitaly SMETANNIKOV
 
 #include "PartSet_SketcherMgr.h"
+#include "PartSet_SketcherReetntrantMgr.h"
 #include "PartSet_Module.h"
 #include "PartSet_WidgetPoint2d.h"
 #include "PartSet_WidgetPoint2dDistance.h"
 #include "PartSet_Tools.h"
 #include "PartSet_WidgetSketchLabel.h"
+#include "PartSet_WidgetEditor.h"
 
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Displayer.h>
 
 #include <QMouseEvent>
 #include <QApplication>
+#include <QCursor>
 
 //#define DEBUG_DO_NOT_BY_ENTER
-//#define DEBUG_MOUSE_OVER_WINDOW_FLAGS
+
+//#define DEBUG_CURSOR
 
 /// Returns list of unique objects by sum of objects from List1 and List2
 /*QList<ModuleBase_ViewerPrs> getSumList(const QList<ModuleBase_ViewerPrs>& theList1,
@@ -152,14 +156,14 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner,
 
 PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
   : QObject(theModule), myModule(theModule), myIsDragging(false), myDragDone(false),
-    myIsResetCurrentValue(false), myIsMouseOverWindow(false),
+    myIsMouseOverWindow(false),
     myIsMouseOverViewProcessed(true), myPreviousUpdateViewerEnabled(true),
     myIsPopupMenuActive(false), myIsConstraintsShown(true)
 {
   ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
   ModuleBase_IViewer* aViewer = anIWorkshop->viewer();
 
-  myPreviousSelectionEnabled = true;//aViewer->isSelectionEnabled();
+  myPreviousDrawModeEnabled = true;//aViewer->isSelectionEnabled();
 
   connect(aViewer, SIGNAL(mousePress(ModuleBase_IViewWindow*, QMouseEvent*)),
           this, SLOT(onMousePressed(ModuleBase_IViewWindow*, QMouseEvent*)));
@@ -191,21 +195,25 @@ void PartSet_SketcherMgr::onEnterViewPort()
   // the mouse move and use the cursor position to update own values. If the presentaion is
   // redisplayed before this update, the feature presentation jumps from reset value to current.
   myIsMouseOverWindow = true;
-  myIsResetCurrentValue = false;
-  // it is important to validate operation here only if sketch entity create operation is active
-  // because at this operation we reacts to the mouse leave/enter view port
-  //operationMgr()->onValidateOperation();
-#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS
-  qDebug(QString("onEnterViewPort: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str());
-#endif
 
   #ifdef DEBUG_DO_NOT_BY_ENTER
   return;
   #endif
 
+  if (canChangeCursor(getCurrentOperation())) {
+    QCursor* aCurrentCursor = QApplication::overrideCursor();
+    if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
+      QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
+#ifdef DEBUG_CURSOR
+      qDebug("onEnterViewPort() : Qt::CrossCursor");
+#endif
+    }
+  }
+
   if (!isNestedCreateOperation(getCurrentOperation()))
     return;
-    operationMgr()->onValidateOperation();
+
+  operationMgr()->onValidateOperation();
 
   // we need change displayed state of the current operation feature
   // if the feature is presentable, e.g. distance construction. It has no results, so workshop does
@@ -230,16 +238,21 @@ void PartSet_SketcherMgr::onLeaveViewPort()
   // it is important to validate operation here only if sketch entity create operation is active
   // because at this operation we reacts to the mouse leave/enter view port
   //operationMgr()->onValidateOperation();
-#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS
-  qDebug(QString("onLeaveViewPort: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str());
-#endif
 
   #ifdef DEBUG_DO_NOT_BY_ENTER
   return;
   #endif
 
+  if (canChangeCursor(getCurrentOperation())) {
+    QApplication::restoreOverrideCursor();
+#ifdef DEBUG_CURSOR
+    qDebug("onLeaveViewPort() : None");
+#endif
+  }
+
   if (!isNestedCreateOperation(getCurrentOperation()))
     return;
+
   // the method should be performed if the popup menu is called,
   // the reset of the current widget should not happen
   if (myIsPopupMenuActive)
@@ -254,13 +267,9 @@ void PartSet_SketcherMgr::onLeaveViewPort()
   // disable the viewer update in order to avoid visualization of redisplayed feature in viewer
   // obtained after reset value
   bool isEnableUpdateViewer = aDisplayer->enableUpdateViewer(false);
-  ModuleBase_Operation* aOperation = getCurrentOperation();
-  ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
-  ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget();
-  if (aActiveWgt && aActiveWgt->reset()) {
-    myIsResetCurrentValue = true;
-  }
-  aDisplayer->enableUpdateViewer(isEnableUpdateViewer);
+  ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+  if (anActiveWidget)
+    anActiveWidget->reset();
 
   // hides the presentation of the current operation feature
   // the feature is to be erased here, but it is correct to call canDisplayObject because
@@ -271,13 +280,15 @@ void PartSet_SketcherMgr::onLeaveViewPort()
     FeaturePtr aFeature = aFOperation->feature();
     visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
   }
+  // we should update viewer after the presentation are hidden in the viewer
+  // otherwise the reset presentation(line) appears in the viewer(by quick move from viewer to PP)
+  aDisplayer->enableUpdateViewer(isEnableUpdateViewer);
 }
 
 void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
 {
-  myIsResetCurrentValue = false;
-
-  if (isNestedCreateOperation(getCurrentOperation()))
+  if (!isNestedEditOperation(getCurrentOperation()) ||
+      myModule->sketchReentranceMgr()->isInternalEditActive())
     return;
   // it is necessary to save current selection in order to restore it after the values are modifed
   storeSelection();
@@ -290,7 +301,8 @@ void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
 
 void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
 {
-  if (isNestedCreateOperation(getCurrentOperation()))
+  if (!isNestedEditOperation(getCurrentOperation()) ||
+      myModule->sketchReentranceMgr()->isInternalEditActive())
     return;
   // it is necessary to restore current selection in order to restore it after the values are modified
   restoreSelection();
@@ -306,26 +318,11 @@ void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
   aDisplayer->updateViewer();
 }
 
-void PartSet_SketcherMgr::onValuesChangedInPropertyPanel()
+void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
 {
-  if (!isNestedCreateOperation(getCurrentOperation()))
+  if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent))
     return;
 
-  // visualize the current operation feature
-  //myIsResetCurrentValue = false;
-  operationMgr()->onValidateOperation();
-  // the feature is to be erased here, but it is correct to call canDisplayObject because
-  // there can be additional check (e.g. editor widget in distance constraint)
-  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
-                                                                           (getCurrentOperation());
-  if (aFOperation) {
-    FeaturePtr aFeature = aFOperation->feature();
-    visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
-  }
-}
-
-void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
-{
   get2dPoint(theWnd, theEvent, myClickedPoint);
 
   if (!(theEvent->buttons() & Qt::LeftButton))
@@ -336,7 +333,6 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
 
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   ModuleBase_IViewer* aViewer = aWorkshop->viewer();
-  myPreviousSelectionEnabled = aViewer->isSelectionEnabled();
   if (!aViewer->canDragByMouse())
     return;
 
@@ -346,10 +342,9 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
     return;
 
   if (aFOperation->isEditOperation()) {
-    ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
-    ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget();
     // If the current widget is a selector, do nothing, it processes the mouse press
-    if(aActiveWgt && aActiveWgt->isViewerSelector()) {
+    ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+    if(anActiveWidget && anActiveWidget->isViewerSelector()) {
       return;
     }
   }
@@ -372,9 +367,11 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
     if ((!isSketcher) && (!isEditing))
       return;
 
-    // MoveTo in order to highlight current object
-    aViewer->AISContext()->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView());
-
+    Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
+    if (!aContext.IsNull()) {
+      // MoveTo in order to highlight current object
+      aContext->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView());
+    }
     // Remember highlighted objects for editing
     ModuleBase_ISelection* aSelect = aWorkshop->selection();
 
@@ -395,6 +392,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       myIsDragging = true;
       get2dPoint(theWnd, theEvent, myCurrentPoint);
       myDragDone = false;
+      // TODO: Has to be uncommented when SALOME patch on draw mode become avialable
+      myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
       launchEditing();
       if (aFeature.get() != NULL) {
         std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
@@ -414,6 +413,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       myIsDragging = true;
       get2dPoint(theWnd, theEvent, myCurrentPoint);
       myDragDone = false;
+      // TODO: Has to be uncommented when SALOME patch on draw mode become avialable
+      myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
 
       // This is necessary in order to finalize previous operation
       QApplication::processEvents();
@@ -424,6 +425,9 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
 
 void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
 {
+  if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent))
+    return;
+
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   ModuleBase_IViewer* aViewer = aWorkshop->viewer();
   if (!aViewer->canDragByMouse())
@@ -438,37 +442,42 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
         if (myDragDone) {
           //aOp->commit();
           myCurrentSelection.clear();
+          /*Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
+          if (!aContext.IsNull()) {
           // Reselect edited object
-          /*aViewer->AISContext()->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView());
+          aContext->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView());
           if (theEvent->modifiers() & Qt::ShiftModifier)
-            aViewer->AISContext()->ShiftSelect();
+            aContext->ShiftSelect();
           else
-            aViewer->AISContext()->Select();
-            */
+            aContext->Select();
+          */
         }
       }
     }
   }
-  aWorkshop->viewer()->enableSelection(myPreviousSelectionEnabled);
+      // TODO: Has to be uncommented when SALOME patch on draw mode become avialable
+  aWorkshop->viewer()->enableDrawMode(myPreviousDrawModeEnabled);
+  //aWorkshop->viewer()->enableSelection(myPreviousDrawModeEnabled);
   myIsDragging = false;
 }
 
 void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
 {
+  if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent))
+    return;
+
   if (isNestedCreateOperation(getCurrentOperation()) && !myIsMouseOverViewProcessed) {
     myIsMouseOverViewProcessed = true;
     // 1. perform the widget mouse move functionality and display the presentation
-    ModuleBase_Operation* aOperation = getCurrentOperation();
-    ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
-    ModuleBase_ModelWidget* anActiveWdg = aPanel->activeWidget();
     // the mouse move should be processed in the widget, if it can in order to visualize correct
     // presentation. These widgets correct the feature attribute according to the mouse position
-    PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(anActiveWdg);
+    ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+    PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(anActiveWidget);
     if (aPoint2DWdg) {
       aPoint2DWdg->onMouseMove(theWnd, theEvent);
     }
     PartSet_WidgetPoint2dDistance* aDistanceWdg = dynamic_cast<PartSet_WidgetPoint2dDistance*>
-                                                                (anActiveWdg);
+                                                                (anActiveWidget);
     if (aDistanceWdg) {
       aDistanceWdg->onMouseMove(theWnd, theEvent);
     }
@@ -489,8 +498,10 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     // 2. the enable selection in the viewer should be temporary switched off in order to ignore
     // mouse press signal in the viewer(it call Select for AIS context and the dragged objects are
     // deselected). This flag should be restored in the slot, processed the mouse release signal.
-    ModuleBase_IViewer* aViewer = myModule->workshop()->viewer();
-    aViewer->enableSelection(false);
+
+    // TODO: Has to be commented out when SALOME patch on draw mode become avialable
+    //ModuleBase_IViewer* aViewer = myModule->workshop()->viewer();
+    //aViewer->enableSelection(false);
 
     ModuleBase_Operation* aCurrentOperation = getCurrentOperation();
     if (!aCurrentOperation)
@@ -589,7 +600,9 @@ void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMo
       // Find corresponded widget to activate value editing
       foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
         if (aWgt->attributeID() == "ConstraintValue") {
-          aWgt->focusTo();
+          PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
+          if (anEditor)
+            anEditor->showPopupEditor();
           return;
         }
       }
@@ -602,10 +615,17 @@ void PartSet_SketcherMgr::onApplicationStarted()
   ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
   XGUI_Workshop* aWorkshop = aConnector->workshop();
+  PartSet_SketcherReetntrantMgr* aReentranceMgr = myModule->sketchReentranceMgr();
+
   XGUI_PropertyPanel* aPropertyPanel = aWorkshop->propertyPanel();
   if (aPropertyPanel) {
     connect(aPropertyPanel, SIGNAL(beforeWidgetActivated(ModuleBase_ModelWidget*)),
             this, SLOT(onBeforeWidgetActivated(ModuleBase_ModelWidget*)));
+
+    connect(aPropertyPanel, SIGNAL(noMoreWidgets(const std::string&)),
+            aReentranceMgr, SLOT(onNoMoreWidgets(const std::string&)));
+    connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)),
+            aReentranceMgr, SLOT(onWidgetActivated()));
   }
 
   XGUI_ViewerProxy* aViewerProxy = aWorkshop->viewer();
@@ -678,6 +698,26 @@ bool PartSet_SketcherMgr::sketchSolverError()
   return anError;
 }
 
+QString PartSet_SketcherMgr::getFeatureError(const FeaturePtr& theFeature)
+{
+  QString anError = "";
+  if (!theFeature.get() || !theFeature->data()->isValid())
+    return anError;
+
+  CompositeFeaturePtr aSketch = activeSketch();
+  if (aSketch.get() && aSketch == theFeature) {
+    AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());
+    anError = aAttributeString->value().c_str();
+  }
+  return anError;
+}
+
+void PartSet_SketcherMgr::clearClickedFlags()
+{
+  return;
+  myClickedPoint.clear();
+  myCurrentPoint.clear();
+}
 
 const QStringList& PartSet_SketcherMgr::sketchOperationIdList()
 {
@@ -745,6 +785,13 @@ bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOpera
   return aFOperation && !aFOperation->isEditOperation() && isNestedSketchOperation(aFOperation);
 }
 
+bool PartSet_SketcherMgr::isNestedEditOperation(ModuleBase_Operation* theOperation)
+{
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                               (theOperation);
+  return aFOperation && aFOperation->isEditOperation() && isNestedSketchOperation(aFOperation);
+}
+
 bool PartSet_SketcherMgr::isEntity(const std::string& theId)
 {
   return (theId == SketchPlugin_Line::ID()) ||
@@ -775,6 +822,7 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
   // Display all sketcher sub-Objects
   myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
+  aConnector->workshop()->displayer()->activateTrihedron(true);
 
   // Hide sketcher result
   std::list<ResultPtr> aResults = myCurrentSketch->results();
@@ -817,13 +865,11 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
     aConnector->activateModuleSelectionModes();
 }
 
-void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* /* theOperation*/)
+void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
 {
   myIsMouseOverWindow = false;
   myIsConstraintsShown = true;
-#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS
-  qDebug(QString("stopSketch: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str());
-#endif
+
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
 
   DataPtr aData = myCurrentSketch->data();
@@ -858,13 +904,19 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* /* theOperation*/)
     std::list<ResultPtr>::const_iterator aIt;
     Events_Loop* aLoop = Events_Loop::loop();
     static Events_ID aDispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                           (theOperation);
     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
-      (*aIt)->setDisplayed(true);
-      // this display event is needed because sketch already may have "displayed" state,
-      // but not displayed while it is still active (issue 613, abort of existing sketch)
-      ModelAPI_EventCreator::get()->sendUpdated(*aIt, aDispEvent);
+      if (!aFOperation->isDisplayedOnStart(*aIt)) {
+        (*aIt)->setDisplayed(true);
+        // this display event is needed because sketch already may have "displayed" state,
+        // but not displayed while it is still active (issue 613, abort of existing sketch)
+        ModelAPI_EventCreator::get()->sendUpdated(*aIt, aDispEvent);
+      }
     }
-    myCurrentSketch->setDisplayed(true);
+    if (!aFOperation->isDisplayedOnStart(myCurrentSketch))
+      myCurrentSketch->setDisplayed(true);
     
     myCurrentSketch = CompositeFeaturePtr();
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
@@ -873,19 +925,32 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* /* theOperation*/)
   }
   // restore the module selection modes, which were changed on startSketch
   aConnector->activateModuleSelectionModes();
+  aConnector->workshop()->displayer()->activateTrihedron(false);
 }
 
 void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
 {
-  connectToPropertyPanel(true);
+  if (canChangeCursor(theOperation) && myIsMouseOverWindow) {
+    QCursor* aCurrentCursor = QApplication::overrideCursor();
+    if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
+      QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
+#ifdef DEBUG_CURSOR
+      qDebug("startNestedSketch() : Qt::CrossCursor");
+#endif
+    }
+  }
 }
 
-void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOp)
+void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)
 {
-  connectToPropertyPanel(false);
-  myIsResetCurrentValue = false;
   myIsMouseOverViewProcessed = true;
   operationMgr()->onValidateOperation();
+  if (canChangeCursor(theOperation)) {
+    QApplication::restoreOverrideCursor();
+#ifdef DEBUG_CURSOR
+    qDebug("stopNestedSketch() : None");
+#endif
+  }
 }
 
 void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
@@ -914,16 +979,6 @@ bool PartSet_SketcherMgr::canRedo() const
   return isNestedCreateOperation(getCurrentOperation());
 }
 
-bool PartSet_SketcherMgr::canCommitOperation() const
-{
-  bool aCanCommit = true;
-
-  if (isNestedCreateOperation(getCurrentOperation()) && myIsResetCurrentValue)
-    aCanCommit = false;
-
-  return aCanCommit;
-}
-
 bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const
 {
   bool aCanErase = true;
@@ -985,7 +1040,7 @@ bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
         isObjectFound = true;
       else {
         std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLast = aResults.end();
-        for (; anIt != aLast; anIt++) {
+        for (; anIt != aLast && !isObjectFound; anIt++) {
           isObjectFound = *anIt == theObject;
         }
       }
@@ -1002,10 +1057,8 @@ bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
   // c. widget editor control
   #ifndef DEBUG_DO_NOT_BY_ENTER
   if (aCanDisplay && isNestedCreateOperation(getCurrentOperation())) {
-    ModuleBase_Operation* aOperation = getCurrentOperation();
-    ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
-    ModuleBase_ModelWidget* anActiveWdg = aPanel ? aPanel->activeWidget() : 0;
-    ModuleBase_WidgetEditor* anEditorWdg = anActiveWdg ? dynamic_cast<ModuleBase_WidgetEditor*>(anActiveWdg) : 0;
+    ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+    ModuleBase_WidgetEditor* anEditorWdg = anActiveWidget ? dynamic_cast<ModuleBase_WidgetEditor*>(anActiveWidget) : 0;
     // the active widget editor should not influence here. The presentation should be visible always
     // when this widget is active.
     if (!anEditorWdg && !myIsPopupMenuActive) {
@@ -1020,10 +1073,19 @@ bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
 
 bool PartSet_SketcherMgr::canDisplayCurrentCreatedFeature() const
 {
-  return myIsMouseOverWindow || !myIsResetCurrentValue;
-#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS
-  qDebug(QString("canDisplayCurrentCreatedFeature: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str());
-#endif
+  bool aCanDisplay = myIsMouseOverWindow;
+  if (!aCanDisplay) {
+    ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+    if (anActiveWidget)
+      aCanDisplay = anActiveWidget->getValueState() == ModuleBase_ModelWidget::Stored;
+  }
+  return aCanDisplay;
+}
+
+bool PartSet_SketcherMgr::canChangeCursor(ModuleBase_Operation* theOperation) const
+{
+  return isNestedCreateOperation(theOperation) ||
+         myModule->sketchReentranceMgr()->isInternalEditActive();
 }
 
 bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const
@@ -1062,34 +1124,36 @@ void PartSet_SketcherMgr::getCurrentSelection(const FeaturePtr& theFeature,
 
   ModuleBase_IViewer* aViewer = theWorkshop->viewer();
   Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
-  XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+  if (!aContext.IsNull()) {
+    XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
+    XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
 
-  std::list<ResultPtr> aResults = theFeature->results();
-  std::list<ResultPtr>::const_iterator aIt;
-  for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)
-  {
-    ResultPtr aResult = *aIt;
-    AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult);
-    if (aAISObj.get() == NULL)
-      continue;
-    Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
-    for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
+    std::list<ResultPtr> aResults = theFeature->results();
+    std::list<ResultPtr>::const_iterator aIt;
+    for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)
     {
-      Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
-      if (anOwner->Selectable() != anAISIO)
-        continue;
-      getAttributesOrResults(anOwner, theFeature, theSketch, aResult,
-                             aSelectedAttributes, aSelectedResults);
-    }
-    for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) {
-      Handle(SelectMgr_EntityOwner) anOwner = aContext->DetectedOwner();
-      if (anOwner.IsNull())
+      ResultPtr aResult = *aIt;
+      AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult);
+      if (aAISObj.get() == NULL)
         continue;
-      if (anOwner->Selectable() != anAISIO)
-        continue;
-      getAttributesOrResults(anOwner, theFeature, theSketch, aResult,
-                             aSelectedAttributes, aSelectedResults);
+      Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+      for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
+      {
+        Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
+        if (anOwner->Selectable() != anAISIO)
+          continue;
+        getAttributesOrResults(anOwner, theFeature, theSketch, aResult,
+                               aSelectedAttributes, aSelectedResults);
+      }
+      for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) {
+        Handle(SelectMgr_EntityOwner) anOwner = aContext->DetectedOwner();
+        if (anOwner.IsNull())
+          continue;
+        if (anOwner->Selectable() != anAISIO)
+          continue;
+        getAttributesOrResults(anOwner, theFeature, theSketch, aResult,
+                               aSelectedAttributes, aSelectedResults);
+      }
     }
   }
   theSelection[theFeature] = std::make_pair(aSelectedAttributes, aSelectedResults);
@@ -1099,7 +1163,7 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
                                              const FeaturePtr& theSketch,
                                              ModuleBase_IWorkshop* theWorkshop,
                                              const FeatureToSelectionMap& theSelection,
-                                             SelectMgr_IndexedMapOfOwner& anOwnersToSelect)
+                                             SelectMgr_IndexedMapOfOwner& theOwnersToSelect)
 {
   if (theFeature.get() == NULL)
     return;
@@ -1109,7 +1173,7 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
   std::set<ResultPtr> aSelectedResults = anIt.value().second;
 
   ModuleBase_IViewer* aViewer = theWorkshop->viewer();
-  Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
+
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
   XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
 
@@ -1123,7 +1187,7 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
     for  (Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++) {
       Handle(SelectMgr_EntityOwner) anOwner = aSelectedOwners(i);
       if (!anOwner.IsNull())
-        anOwnersToSelect.Add(anOwner);
+        theOwnersToSelect.Add(anOwner);
     }
   }
 
@@ -1150,42 +1214,45 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
         AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch);
         if (aPntAttr.get() != NULL &&
             aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) {
-          anOwnersToSelect.Add(anOwner);
+          theOwnersToSelect.Add(anOwner);
         }
       }
       else if (aShapeType == TopAbs_EDGE) {
         bool aFound = aSelectedResults.find(aResult) != aSelectedResults.end();
         if (aSelectedResults.find(aResult) != aSelectedResults.end() &&
-            anOwnersToSelect.FindIndex(anOwner) <= 0)
-          anOwnersToSelect.Add(anOwner);
+            theOwnersToSelect.FindIndex(anOwner) <= 0)
+          theOwnersToSelect.Add(anOwner);
       }
     }
   }
 }
 
-void PartSet_SketcherMgr::connectToPropertyPanel(const bool isToConnect)
+void PartSet_SketcherMgr::connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect)
 {
-  ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
-  XGUI_Workshop* aWorkshop = aConnector->workshop();
-  XGUI_PropertyPanel* aPropertyPanel = aWorkshop->propertyPanel();
-  if (aPropertyPanel) {
-    const QList<ModuleBase_ModelWidget*>& aWidgets = aPropertyPanel->modelWidgets();
-    foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
-      if (isToConnect) {
-        connect(aWidget, SIGNAL(beforeValuesChanged()),
+  if (isToConnect) {
+    connect(theWidget, SIGNAL(beforeValuesChanged()),
+            this, SLOT(onBeforeValuesChangedInPropertyPanel()));
+    connect(theWidget, SIGNAL(afterValuesChanged()),
+            this, SLOT(onAfterValuesChangedInPropertyPanel()));
+  }
+  else {
+    disconnect(theWidget, SIGNAL(beforeValuesChanged()),
                 this, SLOT(onBeforeValuesChangedInPropertyPanel()));
-        connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onValuesChangedInPropertyPanel()));
-        connect(aWidget, SIGNAL(afterValuesChanged()),
+    disconnect(theWidget, SIGNAL(afterValuesChanged()),
                 this, SLOT(onAfterValuesChangedInPropertyPanel()));
-      }
-      else {
-        disconnect(aWidget, SIGNAL(beforeValuesChanged()),
-                   this, SLOT(onBeforeValuesChangedInPropertyPanel()));
-        disconnect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onValuesChangedInPropertyPanel()));
-        disconnect(aWidget, SIGNAL(afterValuesChanged()),
-                   this, SLOT(onAfterValuesChangedInPropertyPanel()));
-      }
+  }
+}
+
+void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState)
+{
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                           (getCurrentOperation());
+  if (aFOperation) {
+    if (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||
+        PartSet_SketcherMgr::isNestedSketchOperation(aFOperation) &&
+        thePreviousState == ModuleBase_ModelWidget::ModifiedInPP) {
+      FeaturePtr aFeature = aFOperation->feature();
+      visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
     }
   }
 }
@@ -1195,6 +1262,19 @@ ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const
   return myModule->workshop()->currentOperation();
 }
 
+//**************************************************************
+ModuleBase_ModelWidget* PartSet_SketcherMgr::getActiveWidget() const
+{
+  ModuleBase_ModelWidget* aWidget = 0;
+  ModuleBase_Operation* anOperation = getCurrentOperation();
+  if (anOperation) {
+    ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+    if (aPanel)
+      aWidget = aPanel->activeWidget();
+  }
+  return aWidget;
+}
+
 void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature,
                                            const bool isEditOperation,
                                            const bool isToDisplay,
@@ -1300,12 +1380,6 @@ void PartSet_SketcherMgr::onShowConstraintsToggle(bool theOn)
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
 }
 
-QString PartSet_SketcherMgr::mouseOverWindowFlagsInfo() const
-{
-  return QString("myIsResetCurrentValue = %1,    myIsMouseOverWindow = %2")
-     .arg(myIsResetCurrentValue).arg(myIsMouseOverWindow);
-}
-
 XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const
 {
   ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
@@ -1314,3 +1388,4 @@ XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const
 
   return aWorkshop->operationMgr();
 }
+