Salome HOME
Issue #1343 Improvement of Extrusion and Revolution operations: preview planes visual...
[modules/shaper.git] / src / PartSet / PartSet_WidgetSketchCreator.cpp
index 874d917b1bd4990d19aa6c678323e23297775b09..52e518297b1bf06b06740ddd4fda34113b59c68e 100644 (file)
@@ -7,6 +7,7 @@
 #include "PartSet_WidgetSketchCreator.h"
 #include "PartSet_Module.h"
 #include "PartSet_WidgetSketchLabel.h"
+#include "PartSet_PreviewPlanes.h"
 
 #include <Config_Keywords.h>
 
@@ -16,6 +17,8 @@
 #include <XGUI_SelectionMgr.h>
 #include <XGUI_OperationMgr.h>
 #include <XGUI_PropertyPanel.h>
+#include <XGUI_Tools.h>
+#include <XGUI_ViewerProxy.h>
 
 #include <GeomAPI_Face.h>
 
@@ -47,7 +50,7 @@ PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent,
                                                          PartSet_Module* theModule,
                                                          const Config_WidgetAPI* theData)
 : ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData),
-  myModule(theModule), myUseBody(true)
+  myModule(theModule)
 {
   myAttributeListID = theData->getProperty("attribute_list_id");
 
@@ -75,15 +78,12 @@ PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent,
 
   myLabel->setToolTip(aToolTip);
 
-  QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
-  if(!aUseBody.isEmpty()) {
-    myUseBody = QVariant(aUseBody).toBool();
-  }
-
   aLayout->addRow(myLabel, myTextLine);*/
 
   std::string aTypes = theData->getProperty("shape_types");
   myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
+
+  myPreviewPlanes = new PartSet_PreviewPlanes();
 }
 
 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
@@ -113,25 +113,10 @@ bool PartSet_WidgetSketchCreator::storeValueCustom() const
   return true;
 }
 
-void PartSet_WidgetSketchCreator::activateCustom()
-{
-  if (isSelectionMode()) {
-    ModuleBase_WidgetSelector::activateCustom();
-    //connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
-
-    //setVisibleSelectionControl(true);
-  }
-  //else {
-  //  setVisibleSelectionControl(false);
-  //  emit focusOutWidget(this);
-  //}
-}
-
 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
 {
   // hide current widget, activate the next widget
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
-  XGUI_Workshop* aWorkshop = aConnector->workshop();
+  XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
   XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
   const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
   foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
@@ -146,6 +131,19 @@ void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelec
         aWidget->setVisible(true);
     }
   }
+
+  if (theSelectionControl) {
+    bool aBodyIsVisualized = myPreviewPlanes->hasVisualizedBodies(myWorkshop);
+    if (!aBodyIsVisualized) {
+      // We have to select a plane before any operation
+      myPreviewPlanes->showPreviewPlanes(myWorkshop);
+    }
+  } else {
+    bool aHidePreview = myPreviewPlanes->isPreviewDisplayed();
+    myPreviewPlanes->showPreviewPlanes(myWorkshop);
+    if (aHidePreview)
+      aWorkshop->viewer()->update();
+  }
 }
 
 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
@@ -157,44 +155,39 @@ QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
   return aShapeTypes;
 }
 
-void PartSet_WidgetSketchCreator::deactivate()
+void PartSet_WidgetSketchCreator::setEditingMode(bool isEditing)
 {
-  if (isSelectionMode()) {
-    ModuleBase_WidgetSelector::activateCustom();
-  }
+  ModuleBase_ModelWidget::setEditingMode(isEditing);
+  if (isEditing)
+    setVisibleSelectionControl(false);
 }
 
 bool PartSet_WidgetSketchCreator::isSelectionMode() const
 {
-  //CompositeFeaturePtr aCompFeature =
-  //  std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
-  //bool aHasSub = aCompFeature->numberOfSubs() > 0;
-
   AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
   bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
 
-  return !aHasValueInList;//aHasSub || aHasValueInList;
+  return !aHasValueInList;
 }
 
 void PartSet_WidgetSketchCreator::onSelectionChanged()
 {
   QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
 
-  if (aSelected.size() == 1) { // plane or planar face of not sketch object
-    startSketchOperation(aSelected.front());
-  }
-  else if (aSelected.size() > 1) {
+  if (!startSketchOperation(aSelected)) {
     QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
-    bool aProcessed;
+    bool aProcessed = false;
     for (; anIt != aLast; anIt++) {
       ModuleBase_ViewerPrs aValue = *anIt;
       if (isValidInFilters(aValue))
-        aProcessed = setSelectionCustom(aValue);
+        aProcessed = setSelectionCustom(aValue) || aProcessed;
     }
     if (aProcessed) {
       emit valuesChanged();
       updateObject(myFeature);
       setVisibleSelectionControl(false);
+      // manually deactivation because the widget was not activated as has no focus acceptin controls
+      deactivate();
       emit focusOutWidget(this);
     }
   }
@@ -217,82 +210,64 @@ void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
     }
   }
 }
-void PartSet_WidgetSketchCreator::onStarted()
+
+bool PartSet_WidgetSketchCreator::startSketchOperation(const QList<ModuleBase_ViewerPrs>& theValues)
 {
-  disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted()));
+  bool aSketchStarted = false;
 
-  setVisibleSelectionControl(true);
-}
+  if (theValues.size() != 1)
+    return aSketchStarted;
 
-void PartSet_WidgetSketchCreator::startSketchOperation(const ModuleBase_ViewerPrs& theValue)
-{
-  // Check that model already has bodies
-  /*XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
-  XGUI_Workshop* aWorkshop = aConnector->workshop();
-  XGUI_Displayer* aDisp = aWorkshop->displayer();
-  QObjectPtrList aObjList = aDisp->displayedObjects();
-  bool aHasBody = !myUseBody;
-  ResultBodyPtr aBody;
-  if(!aHasBody) {
-    foreach(ObjectPtr aObj, aObjList) {
-      aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
-      if (aBody.get() != NULL) {
-        aHasBody = true;
-        break;
-      }
-    }
-  }*/
+  ModuleBase_ViewerPrs aValue = theValues.front();
+  if (!PartSet_WidgetSketchLabel::canFillSketch(aValue))
+    return aSketchStarted;
 
-  //if (aHasBody) {
-    // Launch Sketch operation
-    CompositeFeaturePtr aCompFeature = 
-      std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
+  aSketchStarted = true;
 
-    /// add sketch feature without current feature change.
-    /// it is important to do not change the current feature in order to
-    /// after sketch edition, the extrusion cut feature becomes current
-    SessionPtr aMgr = ModelAPI_Session::get();
-    DocumentPtr aDoc = aMgr->activeDocument();
-    FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
-    FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
-
-    PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(aSketch, theValue);
-
-    aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
-
-    // start edit operation for the sketch
-    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
-                                                             (myModule->createOperation("Sketch"));
-    if (aFOperation)
-      aFOperation->setFeature(aSketch);
-    myModule->sendOperation(aFOperation);
-    //connect(anOperation, SIGNAL(aborted()), aWorkshop->operationMgr(), SLOT(abortAllOperations()));
-  //}
-  /* else {
-    // Break current operation
-    std::string anOperationName = feature()->getKind();
-    QString aTitle = tr( anOperationName.c_str() );
-    QMessageBox::warning(this, aTitle,
-        tr("There are no bodies found. Operation aborted."), QMessageBox::Ok);
-    ModuleBase_Operation* aOp = myModule->workshop()->currentOperation();
-    aOp->abort();
-  }*/
+  // manually deactivation because the widget was not activated as has no focus acceptin controls
+  deactivate();
+  bool aHidePreview = myPreviewPlanes->isPreviewDisplayed();
+  myPreviewPlanes->erasePreviewPlanes(myWorkshop);
+
+  // Launch Sketch operation
+  CompositeFeaturePtr aCompFeature = 
+    std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
+
+  /// add sketch feature without current feature change.
+  /// it is important to do not change the current feature in order to
+  /// after sketch edition, the extrusion cut feature becomes current
+  SessionPtr aMgr = ModelAPI_Session::get();
+  DocumentPtr aDoc = aMgr->activeDocument();
+  FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
+  FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
+
+  PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(aSketch, aValue);
+
+  aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
+
+  // start edit operation for the sketch
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                            (myModule->createOperation("Sketch"));
+  if (aFOperation)
+    aFOperation->setFeature(aSketch);
+  myModule->sendOperation(aFOperation);
+
+  return aSketchStarted;
 }
 
 bool PartSet_WidgetSketchCreator::focusTo()
 {
   if (isSelectionMode()) {
-    //CompositeFeaturePtr aCompFeature = 
-    //   std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
-    // if (aCompFeature->numberOfSubs() == 0)
-    //   return ModuleBase_ModelWidget::focusTo(); 
-    connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
+    setVisibleSelectionControl(true);
+
     // we need to call activate here as the widget has no focus accepted controls
     // if these controls are added here, activate will happens automatically after focusIn()
-    activate();
+    activateCustom();
     return true;
   }
   else {
+    setVisibleSelectionControl(false);
+
     connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
     SessionPtr aMgr = ModelAPI_Session::get();
     // Open transaction that is general for the previous nested one: it will be closed on nested commit
@@ -313,8 +288,10 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
   CompositeFeaturePtr aSketchFeature = 
     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
   if (aSketchFeature->numberOfSubs() == 0) {
+    // do nothing, selection control should be shown
+
     // Abort operation
-    SessionPtr aMgr = ModelAPI_Session::get();
+    //SessionPtr aMgr = ModelAPI_Session::get();
     // Close transaction
     /*
     bool aIsOp = aMgr->isOperation();
@@ -323,8 +300,17 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
       aMgr->startOperation(aNestedOpID, true);
     }
     */
-    theOp->abort();
+    //theOp->abort();
   } else {
+    // Update value in attribute selection list
+    XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
+    XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
+    const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
+    foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
+      if (aWidget->attributeID() == myAttributeListID)
+        aWidget->restoreValue();
+    }
+
     // Hide sketcher result
     std::list<ResultPtr> aResults = aSketchFeature->results();
     std::list<ResultPtr>::const_iterator aIt;
@@ -333,36 +319,28 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
     }
     aSketchFeature->setDisplayed(false);
 
-    if(myUseBody) {
-      // Add Selected body were created the sketcher to list of selected objects
+    // restore value in the selection control
+
+
+    // Add Selected body were created the sketcher to list of selected objects
+    std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
+    AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
+    if (aSelList.get()) {
       DataPtr aData = aSketchFeature->data();
-      AttributeSelectionPtr aSelAttr = 
-        std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
-        (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
-      if (aSelAttr.get()) {
-        ResultPtr aRes = aSelAttr->context();
-        GeomShapePtr aShape = aSelAttr->value();
-        if (aRes.get()) {
-          std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
-          SessionPtr aMgr = ModelAPI_Session::get();
-          ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
-          AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
-          std::string aValidatorID, anError;
-          AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
-          aSelList->append(aRes, GeomShapePtr());
-          if (aFactory->validate(anAttribute, aValidatorID, anError))
-            updateObject(aCompFeature);
-          else
-            aSelList->clear();
-        }
+      AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
+                                    (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
+      ResultPtr aRes = aSelAttr.get() ? aSelAttr->context() : ResultPtr();
+      if (aRes.get()) {
+        SessionPtr aMgr = ModelAPI_Session::get();
+        ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+        AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
+        std::string aValidatorID, anError;
+        aSelList->append(aRes, GeomShapePtr());
+        if (aFactory->validate(anAttribute, aValidatorID, anError))
+          updateObject(aCompFeature);
+        else
+          aSelList->clear();
       }
     }
-    else {
-      // this is a workarount to display the feature results in the operation selection mode
-      // if this is absent, sketch point/line local selection is available on extrusion cut result
-      static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
-      ModelAPI_EventCreator::get()->sendUpdated(feature(), anUpdateEvent);
-      updateObject(feature());
-    }
   }
 }