Salome HOME
Merge branch 'occ/shaper2smesh'
[modules/shaper.git] / src / PartSet / PartSet_SketcherMgr.cpp
index e8257714569d0363873ca9a0db1b851984a35787..bcf6db4be9bedf1554dc90a14d4d49f0b548d4ee 100644 (file)
@@ -60,6 +60,7 @@
 #include <ModuleBase_ViewerFilters.h>
 
 #include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
 
 #include <GeomAPI_Shape.h>
 
 void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner,
                             const FeaturePtr& theFeature, const FeaturePtr& theSketch,
                             const ResultPtr& theResult,
-                            std::set<AttributePtr>& theSelectedAttributes,
+                            std::map<AttributePtr, int>& theSelectedAttributes,
                             std::set<ResultPtr>& theSelectedResults,
                             TopTools_MapOfShape& theShapes)
 {
@@ -156,10 +157,10 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner,
     theShapes.Add(aShape);
     TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
     if (aShapeType == TopAbs_VERTEX) {
-      AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature,
-                                                                    aShape, theSketch);
-      if (aPntAttr.get() != NULL)
-        theSelectedAttributes.insert(aPntAttr);
+      std::pair<AttributePtr, int> aPntAttrIndex =
+          PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch);
+      if (aPntAttrIndex.first.get() != NULL)
+        theSelectedAttributes[aPntAttrIndex.first] = aPntAttrIndex.second;
     }
     else if (aShapeType == TopAbs_EDGE &&
              theSelectedResults.find(theResult) == theSelectedResults.end()) {
@@ -226,15 +227,15 @@ void PartSet_SketcherMgr::onEnterViewPort()
 
   // It is switched off because of
   // Task #3067: 5.2.2 Drawing in the sketcher: change the mouse cursor arrow
-  //  if (canChangeCursor(getCurrentOperation())) {
-  //    QCursor* aCurrentCursor = QApplication::overrideCursor();
-  //    if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
-  //      QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
+    if (canChangeCursor(getCurrentOperation())) {
+      QCursor* aCurrentCursor = QApplication::overrideCursor();
+      if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
+        QApplication::setOverrideCursor(PartSet_Tools::getOperationCursor());
   //#ifdef DEBUG_CURSOR
   //      qDebug("onEnterViewPort() : Qt::CrossCursor");
   //#endif
-  //    }
-  //  }
+      }
+    }
 
   if (!isNestedCreateOperation(getCurrentOperation(), activeSketch()))
     return;
@@ -266,12 +267,12 @@ void PartSet_SketcherMgr::onLeaveViewPort()
   return;
   #endif
 
-//  if (canChangeCursor(getCurrentOperation())) {
-//    QApplication::restoreOverrideCursor();
+  if (canChangeCursor(getCurrentOperation())) {
+    QApplication::restoreOverrideCursor();
 //#ifdef DEBUG_CURSOR
 //    qDebug("onLeaveViewPort() : None");
 //#endif
-//  }
+  }
 
   if (!isNestedCreateOperation(getCurrentOperation(), activeSketch()))
     return;
@@ -348,11 +349,35 @@ void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
 }
 */
 
+bool PartSet_SketcherMgr::isDragModeCreation() const
+{
+  ModuleBase_Operation* aOp = getCurrentOperation();
+  if (!aOp)
+    return false;
+  bool aUserPref = Config_PropManager::boolean(SKETCH_TAB_NAME, "create_by_dragging");
+  if (!aUserPref)
+    return false;
+  QString aId = aOp->id();
+  // Acceptable features;
+  QStringList aList;
+  aList << "SketchLine" << "SketchMacroCircle" << "SketchMacroArc" <<
+    "SketchMacroEllipse" << "SketchMacroEllipticArc" << "SketchRectangle";
+  return aList.contains(aId);
+}
+
+static bool MyModeByDrag = false;
+static bool MyMultiselectionState = true;
+
 void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
 {
+  MyModeByDrag = isDragModeCreation();
+
   // Clear dragging mode
   myIsDragging = false;
 
+  myMousePoint.setX(theEvent->x());
+  myMousePoint.setY(theEvent->y());
+
   if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent))
     return;
   //get2dPoint(theWnd, theEvent, myClickedPoint);
@@ -398,9 +423,24 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       return;
 
     // Ignore creation sketch operation
-    if ((!isSketcher) && (!isEditing))
+    if ((!isSketcher) && (!isEditing)) {
+      if (MyModeByDrag) {
+        ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+        PartSet_MouseProcessor* aProcessor = dynamic_cast<PartSet_MouseProcessor*>(anActiveWidget);
+        if (aProcessor) {
+          MyMultiselectionState = aViewer->isMultiSelectionEnabled();
+          aViewer->enableMultiselection(false);
+          myIsDragging = true;
+          ModuleBase_ISelection* aSelection = aWorkshop->selection();
+          QList<ModuleBase_ViewerPrsPtr> aPreSelected = aSelection->getHighlighted();
+          if (!aPreSelected.empty())
+            aProcessor->setPreSelection(aPreSelected.first(), theWnd, theEvent);
+          else
+            aProcessor->mouseReleased(theWnd, theEvent);
+        }
+      }
       return;
-
+    }
     bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
     storeSelection(aHasShift ? ST_SelectAndHighlightType : ST_HighlightType, myCurrentSelection);
 
@@ -456,9 +496,10 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
           }
         }
       }
-      else
-        isRelaunchEditing = !myCurrentSelection.contains(aSPFeature);
-
+      else {
+        if (myCurrentSelection.size() > 1)
+          isRelaunchEditing = !myCurrentSelection.contains(aSPFeature);
+      }
       if (isRelaunchEditing)
         aFOperation->commit();
 
@@ -504,12 +545,13 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
   if (!myIsMouseOverViewProcessed) {
     return;
   }
-  //if (!aViewer->canDragByMouse())
-  //  return;
+
   ModuleBase_OperationFeature* aOp =
     dynamic_cast<ModuleBase_OperationFeature*>(getCurrentOperation());
+  bool isEditing = false;
   if (aOp) {
-    bool aStartNoDragOperation = !aViewer->canDragByMouse() && aOp->isEditOperation();
+    isEditing = aOp->isEditOperation();
+    bool aStartNoDragOperation = !aViewer->canDragByMouse() && isEditing;
     if (aStartNoDragOperation || myNoDragMoving) {
       // Process edit operation without dragging
       if (myCurrentSelection.size() > 0)
@@ -539,11 +581,31 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
     }
   }
 
-
   ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
   PartSet_MouseProcessor* aProcessor = dynamic_cast<PartSet_MouseProcessor*>(anActiveWidget);
-  if (aProcessor)
-    aProcessor->mouseReleased(theWnd, theEvent);
+  if (aProcessor) {
+    ModuleBase_ISelection* aSelection = aWorkshop->selection();
+    QList<ModuleBase_ViewerPrsPtr> aPreSelected = aSelection->getHighlighted();
+    if (MyModeByDrag && !aPreSelected.empty() && !isEditing)
+      aProcessor->setPreSelection(aPreSelected.first(), theWnd, theEvent);
+    else
+      aProcessor->mouseReleased(theWnd, theEvent);
+  }
+  if (MyModeByDrag && aOp) {
+    QString aOpId = aOp->id();
+    if (aOpId == "Sketch")
+      return;
+    QPoint aPnt(theEvent->x(), theEvent->y());
+    anActiveWidget = getActiveWidget();
+    if ((aPnt == myMousePoint) && anActiveWidget) {
+      aOp->abort();
+      return;
+    }
+    bool aCanRestart = !anActiveWidget && !isEditing;
+    if (aCanRestart) {
+      module()->launchOperation(aOpId, true);
+    }
+  }
 }
 
 void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
@@ -561,6 +623,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     qDebug(QString("%1").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str());
   }
 #endif
+
   if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent))
     return;
 
@@ -640,26 +703,26 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     for (; anIt != aLast; anIt++) {
       FeaturePtr aFeature = anIt.key();
 
-      std::set<AttributePtr> anAttributes = anIt.value().myAttributes;
+      std::map<AttributePtr, int> anAttributes = anIt.value().myAttributes;
       // Process selection by attribute: the priority to the attribute
       if (!anAttributes.empty()) {
-        std::set<AttributePtr>::const_iterator anAttIt = anAttributes.begin(),
+        std::map<AttributePtr, int>::const_iterator anAttIt = anAttributes.begin(),
           anAttLast = anAttributes.end();
         for (; anAttIt != anAttLast; anAttIt++) {
-          AttributePtr anAttr = *anAttIt;
+          AttributePtr anAttr = anAttIt->first;
           if (anAttr.get() == NULL)
             continue;
           std::string aAttrId = anAttr->id();
           DataPtr aData = aFeature->data();
           if (aData->isValid()) {
-            std::shared_ptr<GeomDataAPI_Point2D> aPoint =
-              std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(aAttrId));
-            if (aPoint.get() != NULL) {
+            AttributePtr aPoint = aData->attribute(aAttrId);
+            if (aPoint->attributeType() == GeomDataAPI_Point2D::typeId() ||
+                aPoint->attributeType() == GeomDataAPI_Point2DArray::typeId()) {
               bool isImmutable = aPoint->setImmutable(true);
 
               std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage = std::shared_ptr
                 <ModelAPI_ObjectMovedMessage>(new ModelAPI_ObjectMovedMessage(this));
-              aMessage->setMovedAttribute(aPoint);
+              aMessage->setMovedAttribute(aPoint, anAttIt->second);
               aMessage->setOriginalPosition(anOriginalPosition);
               aMessage->setCurrentPosition(aCurrentPosition);
               Events_Loop::loop()->send(aMessage);
@@ -1216,30 +1279,30 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
   workshop()->viewer()->set2dMode(false);
 }
 
-//void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
-//{
-//  if (canChangeCursor(theOperation) && myIsMouseOverWindow) {
-//    QCursor* aCurrentCursor = QApplication::overrideCursor();
-//    if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
-//      QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
+void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
+{
+  if (canChangeCursor(theOperation) && myIsMouseOverWindow) {
+    QCursor* aCurrentCursor = QApplication::overrideCursor();
+    if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
+      QApplication::setOverrideCursor(PartSet_Tools::getOperationCursor());
 //#ifdef DEBUG_CURSOR
 //      qDebug("startNestedSketch() : Qt::CrossCursor");
 //#endif
-//    }
-//  }
-//}
+    }
+  }
+}
 
 void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)
 {
   myIsMouseOverViewProcessed = true;
   operationMgr()->onValidateOperation();
   // when sketch nested operation is stopped the cursor should be restored unconditionally
-  //if (canChangeCursor(theOperation)) {
-    //QApplication::restoreOverrideCursor();
+  if (canChangeCursor(theOperation)) {
+    QApplication::restoreOverrideCursor();
 #ifdef DEBUG_CURSOR
     qDebug("stopNestedSketch() : None");
 #endif
-  //}
+  }
   /// improvement to deselect automatically all eventual selected objects, when
   // returning to the neutral point of the Sketcher
   bool isClearSelectionPossible = true;
@@ -1685,7 +1748,7 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
 
   FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature);
   SelectionInfo anInfo = anIt.value();
-  std::set<AttributePtr> aSelectedAttributes = anInfo.myAttributes;
+  std::map<AttributePtr, int> aSelectedAttributes = anInfo.myAttributes;
   std::set<ResultPtr> aSelectedResults = anInfo.myResults;
 
   ModuleBase_IViewer* aViewer = theWorkshop->viewer();
@@ -1737,10 +1800,10 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
       const TopoDS_Shape& aShape = anOwner->Shape();
       TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
       if (aShapeType == TopAbs_VERTEX) {
-        AttributePtr aPntAttr =
+        std::pair<AttributePtr, int> aPntAttrIndex =
           PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch);
-        if (aPntAttr.get() != NULL &&
-            aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end())
+        if (aPntAttrIndex.first.get() != NULL &&
+            aSelectedAttributes.find(aPntAttrIndex.first) != aSelectedAttributes.end())
           theOwnersToSelect.Add(anOwner);
         else if (isSameShape && anInfo.myLocalSelectedShapes.Contains(aShape)) {
           theOwnersToSelect.Add(anOwner);
@@ -2019,8 +2082,9 @@ void PartSet_SketcherMgr::updateBySketchParameters(
       if (aPrevState != theState) {
         /// call all sketch features redisplay, the expression state will be corrected in customize
         /// of distance presentation
-        SketcherPrs_Tools::
-          sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]);
+        SketcherPrs_Tools::ParameterStyle aStyle = myIsConstraintsShown[PartSet_Tools::Expressions]
+          ? SketcherPrs_Tools::ParameterText : SketcherPrs_Tools::ParameterValue;
+        SketcherPrs_Tools::setParameterStyle(aStyle);
         Events_ID anEventId = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
         PartSet_Tools::sendSubFeaturesEvent(myCurrentSketch, anEventId);
       }
@@ -2269,8 +2333,9 @@ void PartSet_SketcherMgr::customizeSketchPresentation(const ObjectPtr& theObject
   if (aShapeType != 6/*an edge*/ && aShapeType != 7/*a vertex*/ && aShapeType != 0/*compound*/)
     return;
 
+  int aWidth = Config_PropManager::integer("Visualization", "sketch_line_width");
   if (isExternal(aFeature)) {
-    thePrs->setWidth(1);
+    thePrs->setWidth(isIncludeToResult(aFeature)? aWidth : 1);
     return;
   }
   std::string aKind = aFeature->getKind();
@@ -2284,7 +2349,6 @@ void PartSet_SketcherMgr::customizeSketchPresentation(const ObjectPtr& theObject
       thePrs->setLineStyle(SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY());
     }
     else {
-      int aWidth = Config_PropManager::integer("Visualization", "sketch_line_width");
       thePrs->setWidth(aWidth);
       thePrs->setLineStyle(SketchPlugin_SketchEntity::SKETCH_LINE_STYLE());
     }