Salome HOME
1. Correction for perfomance problem by Apply button state update: do not listen...
[modules/shaper.git] / src / PartSet / PartSet_SketcherMgr.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 2185f64..be2d63e
@@ -5,11 +5,14 @@
 // 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 "PartSet_ResultSketchPrs.h"
 
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Displayer.h>
@@ -21,6 +24,7 @@
 #include <XGUI_PropertyPanel.h>
 #include <XGUI_ViewerProxy.h>
 #include <XGUI_OperationMgr.h>
+#include <XGUI_Tools.h>
 
 #include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_ISelection.h>
@@ -32,6 +36,7 @@
 #include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_WidgetEditor.h>
+#include <ModuleBase_ViewerPrs.h>
 
 #include <GeomDataAPI_Point2D.h>
 
 #include <SketchPlugin_ConstraintFillet.h>
 #include <SketchPlugin_ConstraintMirror.h>
 #include <SketchPlugin_ConstraintAngle.h>
+#include <SketchPlugin_ConstraintCollinear.h>
+#include <SketchPlugin_ConstraintMiddle.h>
 #include <SketchPlugin_MultiRotation.h>
 #include <SketchPlugin_MultiTranslation.h>
+#include <SketchPlugin_IntersectionPoint.h>
 
 #include <SketcherPrs_Tools.h>
 
@@ -66,6 +74,7 @@
 
 //#include <AIS_DimensionSelectionMode.hxx>
 #include <AIS_Shape.hxx>
+#include <AIS_Dimension.hxx>
 
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Session.h>
 
 #include <QMouseEvent>
 #include <QApplication>
+#include <QCursor>
+#include <QMessageBox>
 
 //#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,
-                                       const QList<ModuleBase_ViewerPrs>& theList2)
+/*QList<ModuleBase_ViewerPrsPtr> getSumList(const QList<ModuleBase_ViewerPrsPtr>& theList1,
+                                       const QList<ModuleBase_ViewerPrsPtr>& theList2)
 {
-  QList<ModuleBase_ViewerPrs> aRes;
-  foreach (ModuleBase_ViewerPrs aPrs, theList1) {
+  QList<ModuleBase_ViewerPrsPtr> aRes;
+  foreach (ModuleBase_ViewerPrsPtr aPrs, theList1) {
     if (!aRes.contains(aPrs))
       aRes.append(aPrs);
   }
-  foreach (ModuleBase_ViewerPrs aPrs, theList2) {
+  foreach (ModuleBase_ViewerPrsPtr aPrs, theList2) {
     if (!aRes.contains(aPrs))
       aRes.append(aPrs);
   }
 // \param theSketch a sketch to project a vertex shape of a presentation to the plane
 // and find the corresponded attribute
 // \param theFeatureList  an output list of features
-void fillFeatureList(const QList<ModuleBase_ViewerPrs>& theList,
+void fillFeatureList(const QList<ModuleBase_ViewerPrsPtr>& theList,
                      const FeaturePtr theSketch,
                      QList<FeaturePtr>& theFeatureList)
 {
-  QList<ModuleBase_ViewerPrs> aRes;
+  QList<ModuleBase_ViewerPrsPtr> aRes;
 
-  QList<ModuleBase_ViewerPrs>::const_iterator anIt = theList.begin(),
+  QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = theList.begin(),
                                               aLast = theList.end();
   for (; anIt != aLast; anIt++)
   {
-    ModuleBase_ViewerPrs aPrs = *anIt;
-    FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object());
+    ModuleBase_ViewerPrsPtr aPrs = *anIt;
+    FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs->object());
     if (aFeature.get()  && !theFeatureList.contains(aFeature))
       theFeatureList.append(aFeature);
   }
@@ -152,14 +164,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)
+    myIsPopupMenuActive(false)
 {
   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*)));
@@ -176,6 +188,10 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
   XGUI_Workshop* aWorkshop = aConnector->workshop();
   connect(aWorkshop, SIGNAL(applicationStarted()), this, SLOT(onApplicationStarted()));
+
+  myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
+  myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
+  myIsConstraintsShown[PartSet_Tools::Expressions] = false;
 }
 
 PartSet_SketcherMgr::~PartSet_SketcherMgr()
@@ -191,22 +207,24 @@ 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;
 
-  QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));//QIcon(":pictures/button_plus.png").pixmap(20,20)));
   operationMgr()->onValidateOperation();
 
   // we need change displayed state of the current operation feature
@@ -229,27 +247,28 @@ void PartSet_SketcherMgr::onLeaveViewPort()
 {
   myIsMouseOverViewProcessed = false;
   myIsMouseOverWindow = 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("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;
 
-  QApplication::restoreOverrideCursor();
-
   // the method should be performed if the popup menu is called,
   // the reset of the current widget should not happen
   if (myIsPopupMenuActive)
     return;
 
+  // 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();
 
   // 2. if the mouse IS NOT over window, reset the active widget value and hide the presentation
@@ -259,13 +278,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
@@ -276,13 +291,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();
@@ -295,8 +312,11 @@ void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
 
 void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
 {
-  if (isNestedCreateOperation(getCurrentOperation()))
+  if (!isNestedEditOperation(getCurrentOperation()) ||
+      myModule->sketchReentranceMgr()->isInternalEditActive()) {
+    myModule->sketchReentranceMgr()->updateInternalEditActiveState();
     return;
+  }
   // it is necessary to restore current selection in order to restore it after the values are modified
   restoreSelection();
   myCurrentSelection.clear();
@@ -309,29 +329,16 @@ void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
   XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
   aDisplayer->enableUpdateViewer(myPreviousUpdateViewerEnabled);
   aDisplayer->updateViewer();
-}
 
-void PartSet_SketcherMgr::onValuesChangedInPropertyPanel()
-{
-  if (!isNestedCreateOperation(getCurrentOperation()))
-    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 (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent))
+    return;
+
+  //get2dPoint(theWnd, theEvent, myClickedPoint);
 
   if (!(theEvent->buttons() & Qt::LeftButton))
     return;
@@ -341,7 +348,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;
 
@@ -351,10 +357,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;
     }
   }
@@ -402,6 +407,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       myIsDragging = true;
       get2dPoint(theWnd, theEvent, myCurrentPoint);
       myDragDone = false;
+
+      myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
       launchEditing();
       if (aFeature.get() != NULL) {
         std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
@@ -422,8 +429,14 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       get2dPoint(theWnd, theEvent, myCurrentPoint);
       myDragDone = false;
 
+      myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
+
+      // this is temporary commented in order to avoid the following wrong case:
+      // Distance constraint is under edition, double click on the digit -> nothing happens
+      // because QApplication::processEvents() calls onMouseDoubleClick, which try to show editor
+      // but as the prev edit is commited an new one is not started, editor is not shown.
       // This is necessary in order to finalize previous operation
-      QApplication::processEvents();
+      //QApplication::processEvents();
       launchEditing();
     }
   }
@@ -431,6 +444,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,7 +454,7 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
   ModuleBase_Operation* aOp = getCurrentOperation();
   if (aOp) {
     if (isNestedSketchOperation(aOp)) {
-      get2dPoint(theWnd, theEvent, myClickedPoint);
+      //get2dPoint(theWnd, theEvent, myClickedPoint);
 
       // Only for sketcher operations
       if (myIsDragging) {
@@ -458,26 +474,28 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
       }
     }
   }
-  aWorkshop->viewer()->enableSelection(myPreviousSelectionEnabled);
+
+  aWorkshop->viewer()->enableDrawMode(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);
     }
@@ -491,15 +509,13 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     }
   }
 
-  myClickedPoint.clear();
+  //myClickedPoint.clear();
 
   if (myIsDragging) {
     // 1. the current selection is saved in the mouse press method in order to restore it after moving
     // 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);
 
     ModuleBase_Operation* aCurrentOperation = getCurrentOperation();
     if (!aCurrentOperation)
@@ -598,7 +614,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;
         }
       }
@@ -611,10 +629,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(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();
@@ -626,23 +651,23 @@ void PartSet_SketcherMgr::onApplicationStarted()
   connect(aContextMenuMgr, SIGNAL(afterContextMenu()), this, SLOT(onAfterContextMenu()));
 }
 
-void PartSet_SketcherMgr::onBeforeWidgetActivated(ModuleBase_ModelWidget* theWidget)
-{
-  if (!myClickedPoint.myIsInitialized)
-    return;
+//void PartSet_SketcherMgr::onBeforeWidgetActivated(ModuleBase_ModelWidget* theWidget)
+//{
+  //if (!myClickedPoint.myIsInitialized)
+  //  return;
 
-  ModuleBase_Operation* aOperation = getCurrentOperation();
+  //ModuleBase_Operation* aOperation = getCurrentOperation();
   // the distance constraint feature should not use the clickedd point
   // this is workaround in order to don't throw down the flyout point value,
   // set by execute() method of these type of features
-  if (isDistanceOperation(aOperation))
-    return;
+  //if (isDistanceOperation(aOperation))
+  //  return;
 
-  PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast<PartSet_WidgetPoint2D*>(theWidget);
-  if (aPnt2dWgt) {
-    aPnt2dWgt->setPoint(myClickedPoint.myCurX, myClickedPoint.myCurY);
-  }
-}
+  //PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast<PartSet_WidgetPoint2D*>(theWidget);
+  //if (aPnt2dWgt) {
+  //  aPnt2dWgt->setPoint(myClickedPoint.myCurX, myClickedPoint.myCurY);
+  //}
+//}
 
 void PartSet_SketcherMgr::onBeforeContextMenu()
 {
@@ -698,27 +723,15 @@ QString PartSet_SketcherMgr::getFeatureError(const FeaturePtr& theFeature)
     AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());
     anError = aAttributeString->value().c_str();
   }
-  else if (myIsResetCurrentValue) { // this flag do not allow commit of the current operation
-    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
-                                                                        (getCurrentOperation());
-    if (aFOperation) {
-      FeaturePtr aFeature = aFOperation->feature();
-      if (aFeature.get() && aFeature == theFeature && isNestedCreateOperation(aFOperation)) {
-        QString anAttributeName = "";
-        ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
-        ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();
-        if (anActiveWgt) {
-          AttributePtr anAttr = aFeature->attribute(anActiveWgt->attributeID());
-          if (anAttr.get())
-            anAttributeName = anAttr->id().c_str();
-        }
-        anError = "Attribute \"" + anAttributeName + "\" is not initialized.";
-      }
-    }
-  }
   return anError;
 }
 
+void PartSet_SketcherMgr::clearClickedFlags()
+{
+  //myClickedPoint.clear();
+  myCurrentPoint.clear();
+}
+
 const QStringList& PartSet_SketcherMgr::sketchOperationIdList()
 {
   static QStringList aIds;
@@ -728,6 +741,10 @@ const QStringList& PartSet_SketcherMgr::sketchOperationIdList()
     aIds << SketchPlugin_Arc::ID().c_str();
     aIds << SketchPlugin_Circle::ID().c_str();
     aIds << SketchPlugin_ConstraintFillet::ID().c_str();
+    aIds << SketchPlugin_IntersectionPoint::ID().c_str();
+    // TODO
+    // SketchRectangle is a python feature, so its ID is passed just as a string
+    aIds << "SketchRectangle";
     aIds.append(constraintsIdList());
   }
   return aIds;
@@ -752,6 +769,8 @@ const QStringList& PartSet_SketcherMgr::constraintsIdList()
     aIds << SketchPlugin_ConstraintAngle::ID().c_str();
     aIds << SketchPlugin_MultiRotation::ID().c_str();
     aIds << SketchPlugin_MultiTranslation::ID().c_str();
+    aIds << SketchPlugin_ConstraintCollinear::ID().c_str();
+    aIds << SketchPlugin_ConstraintMiddle::ID().c_str();
   }
   return aIds;
 }
@@ -767,6 +786,17 @@ void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes)
   theModes.append(TopAbs_EDGE);
 }
 
+Handle(AIS_InteractiveObject) PartSet_SketcherMgr::createPresentation(const ResultPtr& theResult)
+{
+  Handle(AIS_InteractiveObject) aPrs;
+
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theResult);
+  if (aFeature.get() && aFeature->getKind() == SketchPlugin_Sketch::ID()) {
+    aPrs = new PartSet_ResultSketchPrs(theResult);
+  }
+  return aPrs;
+}
+
 bool PartSet_SketcherMgr::isSketchOperation(ModuleBase_Operation* theOperation)
 {
   return theOperation && theOperation->id().toStdString() == SketchPlugin_Sketch::ID();
@@ -785,6 +815,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()) ||
@@ -795,12 +832,17 @@ bool PartSet_SketcherMgr::isEntity(const std::string& theId)
 
 bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation)
 {
-  std::string aId = theOperation ? theOperation->id().toStdString() : "";
+  std::string anId = theOperation ? theOperation->id().toStdString() : "";
 
-  return (aId == SketchPlugin_ConstraintLength::ID()) ||
-         (aId == SketchPlugin_ConstraintDistance::ID()) ||
-         (aId == SketchPlugin_ConstraintRadius::ID()) ||
-         (aId == SketchPlugin_ConstraintAngle::ID());
+  return isDistanceKind(anId);
+}
+
+bool PartSet_SketcherMgr::isDistanceKind(std::string& theKind)
+{
+  return (theKind == SketchPlugin_ConstraintLength::ID()) ||
+         (theKind == SketchPlugin_ConstraintDistance::ID()) ||
+         (theKind == SketchPlugin_ConstraintRadius::ID()) ||
+         (theKind == SketchPlugin_ConstraintAngle::ID());
 }
 
 void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
@@ -815,6 +857,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();
@@ -835,35 +878,35 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
     aFeature->setDisplayed(true);
   }
 
+  if(myCirclePointFilter.IsNull()) {
+    myCirclePointFilter = new PartSet_CirclePointFilter(myModule->workshop());
+  }
+
+  myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter);
+
   if (myPlaneFilter.IsNull()) 
     myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
 
   myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
-
   bool aHasPlane = false;
   std::shared_ptr<GeomAPI_Pln> aPln;
-  if (aFOperation->isEditOperation()) {
-    // If it is editing of sketch then it means that plane is already defined
-    aPln = PartSet_Tools::sketchPlane(myCurrentSketch);
-    if (aPln.get())
-      aHasPlane = true;
-  }
+  aPln = PartSet_Tools::sketchPlane(myCurrentSketch);
   myPlaneFilter->setPlane(aPln);
 
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-  // all sketch objects should be activated in the sketch selection modes by edit operation start
-  // in case of creation operation, there is an active widget, which activates own selection mode
-  if (aFOperation->isEditOperation() && aHasPlane)
+  // all displayed objects should be activated in current selection modes according to switched
+  // plane filter
+  if (aPln.get())
     aConnector->activateModuleSelectionModes();
 }
 
 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
+  myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
+  myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
+  myIsConstraintsShown[PartSet_Tools::Expressions] = false;
+
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
 
   DataPtr aData = myCurrentSketch->data();
@@ -871,6 +914,8 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
     XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
     // The sketch was aborted
     myCurrentSketch = CompositeFeaturePtr();
+    // TODO: move this outside of if-else
+    myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
 
     // Erase all sketcher objects
@@ -913,29 +958,40 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
       myCurrentSketch->setDisplayed(true);
     
     myCurrentSketch = CompositeFeaturePtr();
+
+    myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
 
     Events_Loop::loop()->flush(aDispEvent);
   }
   // 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 (isNestedCreateOperation(theOperation) && myIsMouseOverWindow)
-    QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));//QIcon(":pictures/button_plus.png").pixmap(20,20)));
+  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 (isNestedCreateOperation(theOp))
+  if (canChangeCursor(theOperation)) {
     QApplication::restoreOverrideCursor();
+#ifdef DEBUG_CURSOR
+    qDebug("stopNestedSketch() : None");
+#endif
+  }
 }
 
 void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
@@ -954,24 +1010,48 @@ void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
   }
 }
 
-bool PartSet_SketcherMgr::canUndo() const
+void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate)
 {
-  return isNestedCreateOperation(getCurrentOperation());
+  if (toActivate)
+    myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
+  else
+    myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
 }
 
-bool PartSet_SketcherMgr::canRedo() const
+bool PartSet_SketcherMgr::operationActivatedByPreselection()
 {
-  return isNestedCreateOperation(getCurrentOperation());
+  bool isOperationStopped = false;
+  ModuleBase_Operation* anOperation = getCurrentOperation();
+  if(anOperation && PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) {
+    // Set final definitions if they are necessary
+    //propertyPanelDefined(aOperation);
+    /// Commit sketcher operations automatically
+    /// distance operation are able to show popup editor to modify the distance value
+    /// after entering the value, the operation should be committed/aborted(by Esc key)
+    bool aCanCommitOperation = true;
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                            (anOperation);
+    if (aFOperation && PartSet_SketcherMgr::isDistanceOperation(aFOperation))
+      aCanCommitOperation = setDistanceValueByPreselection(anOperation, myModule->workshop());
+
+    if (aCanCommitOperation)
+      isOperationStopped = anOperation->commit();
+    else {
+      anOperation->abort();
+      isOperationStopped = true;
+    }
+  }
+  return isOperationStopped;
 }
 
-bool PartSet_SketcherMgr::canCommitOperation() const
+bool PartSet_SketcherMgr::canUndo() const
 {
-  bool aCanCommit = true;
-
-  if (isNestedCreateOperation(getCurrentOperation()) && myIsResetCurrentValue)
-    aCanCommit = false;
+  return isNestedCreateOperation(getCurrentOperation());
+}
 
-  return aCanCommit;
+bool PartSet_SketcherMgr::canRedo() const
+{
+  return isNestedCreateOperation(getCurrentOperation());
 }
 
 bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const
@@ -1041,39 +1121,185 @@ bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
       }
     }
   }
-  if (!isObjectFound) 
-    return aCanDisplay;
-  
-  // 4. For created nested feature operation do not display the created feature if
-  // the mouse curstor leaves the OCC window.
-  // The correction cases, which ignores this condition:
-  // a. the property panel values modification
-  // b. the popup menu activated
-  // 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;
-    // the active widget editor should not influence here. The presentation should be visible always
-    // when this widget is active.
-    if (!anEditorWdg && !myIsPopupMenuActive) {
-      // during a nested create operation, the feature is redisplayed only if the mouse over view
-      // of there was a value modified in the property panel after the mouse left the view
-      aCanDisplay = canDisplayCurrentCreatedFeature();
+  if (isObjectFound) {
+    // 4. For created nested feature operation do not display the created feature if
+    // the mouse curstor leaves the OCC window.
+    // The correction cases, which ignores this condition:
+    // a. the property panel values modification
+    // b. the popup menu activated
+    // c. widget editor control
+    #ifndef DEBUG_DO_NOT_BY_ENTER
+    if (aCanDisplay && isNestedCreateOperation(getCurrentOperation())) {
+      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) {
+        // during a nested create operation, the feature is redisplayed only if the mouse over view
+        // of there was a value modified in the property panel after the mouse left the view
+        aCanDisplay = canDisplayCurrentCreatedFeature();
+      }
     }
+    #endif
   }
-  #endif
+
+  // checks the sketcher constraints visibility according to active sketch check box states
+  if (aCanDisplay) {
+    bool aProcessed = false;
+    FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+    if (aFeature.get()) {
+      bool aConstraintDisplayed = canDisplayConstraint(aFeature, PartSet_Tools::Any, aProcessed);
+      if (aProcessed)
+        aCanDisplay = aConstraintDisplayed;
+    }
+  }
+
   return aCanDisplay;
 }
 
+bool PartSet_SketcherMgr::canDisplayConstraint(const FeaturePtr& theFeature,
+                                             const PartSet_Tools::ConstraintVisibleState& theState,
+                                             bool& isProcessed) const
+{
+  bool aSwitchedOn = true;
+
+  const QStringList& aConstrIds = constraintsIdList();
+
+  std::string aKind = theFeature->getKind();
+  if (aConstrIds.contains(QString(aKind.c_str()))) {
+    bool isTypedConstraint = false;
+
+    switch (theState) {
+      case PartSet_Tools::Dimensional: {
+        bool isDistance = isDistanceKind(aKind);
+        if (isDistance) {
+          isProcessed = true;
+          aSwitchedOn = myIsConstraintsShown[theState];
+        }
+      }
+      break;
+      case PartSet_Tools::Geometrical: {
+        bool isGeometrical = !isDistanceKind(aKind);
+        if (isGeometrical) {
+          isProcessed = true;
+          aSwitchedOn = myIsConstraintsShown[theState];
+        }
+      }
+      break;
+      case PartSet_Tools::Any: {
+        isProcessed = true;
+        bool isDistance = isDistanceKind(aKind);
+        if (isDistance)
+          aSwitchedOn = myIsConstraintsShown[PartSet_Tools::Dimensional];
+        else
+          aSwitchedOn = myIsConstraintsShown[PartSet_Tools::Geometrical];
+      }
+      break;
+    default:
+      break;
+    }
+  }
+  return aSwitchedOn;
+}
+
+void PartSet_SketcherMgr::processHiddenObject(const std::list<ObjectPtr>& theObjects)
+{
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                           (getCurrentOperation());
+  if (aFOperation && myCurrentSketch.get()) {
+    // find results of the current operation
+    // these results should not be proposed to be deleted
+    FeaturePtr anOperationFeature = aFOperation->feature();
+    std::list<ResultPtr> anOperationResultList = anOperationFeature->results();
+    std::set<ResultPtr> anOperationResults;
+    std::list<ResultPtr>::const_iterator aRIt = anOperationResultList.begin(),
+                                        aRLast = anOperationResultList.end();
+    for (; aRIt != aRLast; aRIt++)
+      anOperationResults.insert(*aRIt);
+
+    std::set<FeaturePtr> anObjectsToBeDeleted;
+    QStringList anObjectsToBeDeletedNames;
+    std::list<ObjectPtr>::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
+    for (; anIt != aLast; anIt++) {
+      ObjectPtr anObject = *anIt;
+      bool aCanErase = true;
+      // when the sketch operation is active, results of sketch sub-feature can not be hidden
+      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+      // the result is found between current feature results
+      if (anOperationResults.find(aResult) != anOperationResults.end())
+        continue;
+
+      if (aResult.get()) {
+        // Display sketcher objects
+        for (int i = 0; i < myCurrentSketch->numberOfSubs() && aCanErase; i++) {
+          FeaturePtr aFeature = myCurrentSketch->subFeature(i);
+          std::list<ResultPtr> aResults = aFeature->results();
+          std::list<ResultPtr>::const_iterator anIt;
+          for (anIt = aResults.begin(); anIt != aResults.end() && aCanErase; ++anIt) {
+            aCanErase = *anIt != aResult;
+          }
+        }
+      }
+      if (!aCanErase) {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+        if (aFeature.get() && anObjectsToBeDeleted.find(aFeature) == anObjectsToBeDeleted.end()) {
+          anObjectsToBeDeleted.insert(aFeature);
+          anObjectsToBeDeletedNames.append(aFeature->name().c_str());
+        }
+      }
+    }
+    if (!anObjectsToBeDeleted.empty()) {
+      QString aFeatureNames = anObjectsToBeDeletedNames.join(", ");
+      QString aMessage = tr("The following features have incorrect presentation and \
+will be hidden: %1. Would you like to delete them?")
+                         .arg(aFeatureNames);
+      int anAnswer = QMessageBox::question(qApp->activeWindow(), tr("Features hide"),
+                                           aMessage, QMessageBox::Ok | QMessageBox::Cancel,
+                                           QMessageBox::Cancel);
+      if (anAnswer == QMessageBox::Ok) {
+        QObjectPtrList anObjects;
+        std::set<FeaturePtr>::const_iterator anIt = anObjectsToBeDeleted.begin(),
+                                             aLast = anObjectsToBeDeleted.end();
+        for (; anIt != aLast; anIt++)
+          anObjects.append(*anIt);
+        SessionPtr aMgr = ModelAPI_Session::get();
+        DocumentPtr aDoc = aMgr->activeDocument();
+        bool aIsOp = aMgr->isOperation();
+        if (!aIsOp)
+          aMgr->startOperation();
+        workshop()->deleteFeatures(anObjects);
+        //static Events_ID aDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
+        //static Events_ID aRedispEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
+        //Events_Loop::loop()->flush(aDeletedEvent);
+        //Events_Loop::loop()->flush(aRedispEvent);
+
+        if (!aIsOp)
+          aMgr->finishOperation();
+      }
+    }
+  }
+}
+
 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();
+}
+
+const QMap<PartSet_Tools::ConstraintVisibleState, bool>& PartSet_SketcherMgr::showConstraintStates()
+{
+  return myIsConstraintsShown;
 }
 
 bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const
@@ -1099,6 +1325,79 @@ void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& th
   myPlaneFilter->setPlane(thePln);
 }
 
+bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* theOperation,
+                                                         ModuleBase_IWorkshop* theWorkshop)
+{
+  bool isValueAccepted = false;
+
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                              (theOperation);
+  FeaturePtr aFeature = aFOperation->feature();
+  // editor is shown only if all attribute references are filled by preseletion
+  bool anAllRefAttrInitialized = true;
+
+  std::list<AttributePtr> aRefAttrs = aFeature->data()->attributes(
+                                              ModelAPI_AttributeRefAttr::typeId());
+  std::list<AttributePtr>::const_iterator anIt = aRefAttrs.begin(), aLast = aRefAttrs.end();
+  for (; anIt != aLast && anAllRefAttrInitialized; anIt++) {
+    anAllRefAttrInitialized = (*anIt)->isInitialized();
+  }
+  if (anAllRefAttrInitialized) {
+    // Activate dimension value editing on double click
+    ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
+    QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
+    // Find corresponded widget to activate value editing
+    foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
+      if (aWgt->attributeID() == "ConstraintValue") {
+        // the featue should be displayed in order to find the AIS text position,
+        // the place where the editor will be shown
+        aFeature->setDisplayed(true);
+        /// the execute is necessary to perform in the feature compute for flyout position
+        aFeature->execute();
+
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+
+        PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
+        if (anEditor) {
+          int aX = 0, anY = 0;
+
+          XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(theWorkshop);
+          XGUI_Displayer* aDisplayer = aWorkshop->displayer();
+          AISObjectPtr anAIS = aDisplayer->getAISObject(aFeature);
+          Handle(AIS_InteractiveObject) anAISIO;
+          if (anAIS.get() != NULL) {
+            anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+          }
+          if (anAIS.get() != NULL) {
+            Handle(AIS_InteractiveObject) anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+
+            if (!anAISIO.IsNull()) {
+              Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(anAISIO);
+              if (!aDim.IsNull()) {
+                gp_Pnt aPosition = aDim->GetTextPosition();
+
+                ModuleBase_IViewer* aViewer = aWorkshop->viewer();
+                Handle(V3d_View) aView = aViewer->activeView();
+                int aCX, aCY;
+                aView->Convert(aPosition.X(), aPosition.Y(), aPosition.Z(), aCX, aCY);
+
+                QWidget* aViewPort = aViewer->activeViewPort();
+                QPoint aGlPoint = aViewPort->mapToGlobal(QPoint(aCX, aCY));
+                aX = aGlPoint.x();
+                anY = aGlPoint.y();
+              }
+            }
+            anEditor->setCursorPosition(aX, anY);
+            isValueAccepted = anEditor->showPopupEditor(false);
+          }
+        }
+      }
+    }
+  }
+  return isValueAccepted;
+}
+
 void PartSet_SketcherMgr::getCurrentSelection(const FeaturePtr& theFeature,
                                               const FeaturePtr& theSketch,
                                               ModuleBase_IWorkshop* theWorkshop,
@@ -1215,38 +1514,63 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
   }
 }
 
-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));
     }
   }
 }
 
+void PartSet_SketcherMgr::customizePresentation(const ObjectPtr& theObject)
+{
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                           (getCurrentOperation());
+  if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||
+                      PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)))
+    SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]);
+}
+
 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,
@@ -1287,9 +1611,12 @@ void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature,
 
 void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
 {
+  if (!myCurrentSketch.get())
+    return;
+
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   ModuleBase_ISelection* aSelect = aWorkshop->selection();
-  QList<ModuleBase_ViewerPrs> aHighlighted = aSelect->getHighlighted();
+  QList<ModuleBase_ViewerPrsPtr> aHighlighted = aSelect->getHighlighted();
 
   QList<FeaturePtr> aFeatureList;
   if (theHighlightedOnly) {
@@ -1298,7 +1625,7 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
   else {
     fillFeatureList(aHighlighted, myCurrentSketch, aFeatureList);
 
-    QList<ModuleBase_ViewerPrs> aSelected = aSelect->getSelected(ModuleBase_ISelection::AllControls);
+    QList<ModuleBase_ViewerPrsPtr> aSelected = aSelect->getSelected(ModuleBase_ISelection::AllControls);
     fillFeatureList(aSelected, myCurrentSketch, aFeatureList);
   }
 
@@ -1313,6 +1640,9 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
 
 void PartSet_SketcherMgr::restoreSelection()
 {
+  if (!myCurrentSketch.get())
+    return;
+
   //qDebug(QString("restoreSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str());
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
@@ -1327,42 +1657,59 @@ void PartSet_SketcherMgr::restoreSelection()
   }
 }
 
-void PartSet_SketcherMgr::onShowConstraintsToggle(bool theOn)
+void PartSet_SketcherMgr::onShowConstraintsToggle(int theType, bool theState)
 {
-  if (myIsConstraintsShown == theOn)
-    return;
-  if (myCurrentSketch.get() == NULL)
-    return;
+  PartSet_Tools::ConstraintVisibleState aType = (PartSet_Tools::ConstraintVisibleState)theType;
 
-  myIsConstraintsShown = theOn;
+  updateBySketchParameters(aType, theState);
+}
 
-  ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+void PartSet_SketcherMgr::updateBySketchParameters(
+                                   const PartSet_Tools::ConstraintVisibleState& theType,
+                                   bool theState)
+{
+  if (myCurrentSketch.get() == NULL)
+    return;
 
-  const QStringList& aConstrIds = constraintsIdList();
-  for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
-    FeaturePtr aSubFeature = myCurrentSketch->subFeature(i);
-    if (aConstrIds.contains(QString(aSubFeature->getKind().c_str()))) {
-      if (myIsConstraintsShown) 
-        aSubFeature->setDisplayed(true);
-      else
-        aSubFeature->setDisplayed(false);
+  bool aPrevState = myIsConstraintsShown[theType];
+  myIsConstraintsShown[theType] = theState;
+
+  switch (theType) {
+    case PartSet_Tools::Geometrical:
+    case PartSet_Tools::Dimensional: {
+      if (aPrevState != theState) {
+        ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+        XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+        for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+          FeaturePtr aSubFeature = myCurrentSketch->subFeature(i);
+          bool aProcessed = false;
+          bool aConstraintDisplayed = canDisplayConstraint(aSubFeature, theType, aProcessed);
+          if (aProcessed)
+            aSubFeature->setDisplayed(aConstraintDisplayed);
+        }
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+      }
+    }
+    break;
+    case PartSet_Tools::Expressions: {
+      /// call all sketch features redisplay, the expression state will be corrected in customize
+      /// of distance presentation
+      Events_ID anEventId = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+      PartSet_Tools::sendSubFeaturesEvent(myCurrentSketch, anEventId);
     }
+    break;
   }
-  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
 }
 
-QString PartSet_SketcherMgr::mouseOverWindowFlagsInfo() const
+XGUI_Workshop* PartSet_SketcherMgr::workshop() const
 {
-  return QString("myIsResetCurrentValue = %1,    myIsMouseOverWindow = %2")
-     .arg(myIsResetCurrentValue).arg(myIsMouseOverWindow);
+  ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
+  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
+  return aConnector->workshop();
 }
 
 XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const
 {
-  ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
-  XGUI_Workshop* aWorkshop = aConnector->workshop();
-
-  return aWorkshop->operationMgr();
+  return workshop()->operationMgr();
 }
+