Salome HOME
Issue #1343 Improvement of Extrusion and Revolution operations: sketch is filled...
[modules/shaper.git] / src / PartSet / PartSet_WidgetSketchCreator.cpp
index f7a52416e4597dfd8c20d04e28b7ab0743378680..874d917b1bd4990d19aa6c678323e23297775b09 100644 (file)
@@ -6,12 +6,16 @@
 
 #include "PartSet_WidgetSketchCreator.h"
 #include "PartSet_Module.h"
+#include "PartSet_WidgetSketchLabel.h"
+
+#include <Config_Keywords.h>
 
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Workshop.h>
 #include <XGUI_Displayer.h>
 #include <XGUI_SelectionMgr.h>
 #include <XGUI_OperationMgr.h>
+#include <XGUI_PropertyPanel.h>
 
 #include <GeomAPI_Face.h>
 
@@ -20,6 +24,7 @@
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_Validator.h>
+#include <ModelAPI_Events.h>
 
 #include <SketchPlugin_SketchEntity.h>
 #include <FeaturesPlugin_CompositeBoolean.h>
 #include <ModuleBase_OperationFeature.h>
 #include <Config_WidgetAPI.h>
 
+#include <Events_Loop.h>
+
 #include <QLabel>
 #include <QLineEdit>
-#include <QFormLayout>
+//#include <QFormLayout>
+#include <QVBoxLayout>
 #include <QMessageBox>
 
 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, 
                                                          PartSet_Module* theModule,
-                                                         const Config_WidgetAPI* theData,
-                                                         const std::string& theParentId)
-: ModuleBase_ModelWidget(theParent, theData, theParentId), myModule(theModule)
+                                                         const Config_WidgetAPI* theData)
+: ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData),
+  myModule(theModule), myUseBody(true)
 {
-  QFormLayout* aLayout = new QFormLayout(this);
+  myAttributeListID = theData->getProperty("attribute_list_id");
+
+  //QFormLayout* aLayout = new QFormLayout(this);
+  QVBoxLayout* aLayout = new QVBoxLayout(this);
+  ModuleBase_Tools::zeroMargins(aLayout);
+
   ModuleBase_Tools::adjustMargins(aLayout);
 
   QString aLabelText = QString::fromStdString(theData->widgetLabel());
   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
+
   myLabel = new QLabel(aLabelText, this);
-  if (!aLabelIcon.isEmpty())
+  myLabel->setWordWrap(true);
+  aLayout->addWidget(myLabel);
+  /*if (!aLabelIcon.isEmpty())
     myLabel->setPixmap(QPixmap(aLabelIcon));
 
 
@@ -57,7 +73,17 @@ PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent,
   myTextLine->setToolTip(aToolTip);
   myTextLine->installEventFilter(this);
 
-  aLayout->addRow(myLabel, myTextLine);
+  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);
 }
 
 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
@@ -67,18 +93,18 @@ PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
 {
   QList<QWidget*> aControls;
-  aControls.append(myTextLine);
+  aControls.append(myLabel);
   return aControls;
 }
 
 bool PartSet_WidgetSketchCreator::restoreValueCustom()
 {
-  CompositeFeaturePtr aCompFeature = 
+  /*CompositeFeaturePtr aCompFeature = 
     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
   if (aCompFeature->numberOfSubs() > 0) {
     FeaturePtr aSubFeature = aCompFeature->subFeature(0);
     myTextLine->setText(QString::fromStdString(aSubFeature->data()->name()));
-  }
+  }*/
   return true;
 }
 
@@ -89,44 +115,160 @@ bool PartSet_WidgetSketchCreator::storeValueCustom() const
 
 void PartSet_WidgetSketchCreator::activateCustom()
 {
-  CompositeFeaturePtr aCompFeature = 
-    std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
-  if (aCompFeature->numberOfSubs() == 0)
-    connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
+  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_PropertyPanel* aPanel = aWorkshop->propertyPanel();
+  const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
+  foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
+    if (theSelectionControl) { // hide other controls
+      if (aWidget != this)
+        aWidget->setVisible(false);
+    }
+    else { // hide current control
+      if (aWidget == this)
+        aWidget->setVisible(false);
+      else
+        aWidget->setVisible(true);
+    }
+  }
+}
+
+QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
+{
+  QIntList aShapeTypes;
+  foreach(QString aType, myShapeTypes) {
+    aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
+  }
+  return aShapeTypes;
+}
+
+void PartSet_WidgetSketchCreator::deactivate()
+{
+  if (isSelectionMode()) {
+    ModuleBase_WidgetSelector::activateCustom();
+  }
 }
 
+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;
+}
+
+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) {
+    QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
+    bool aProcessed;
+    for (; anIt != aLast; anIt++) {
+      ModuleBase_ViewerPrs aValue = *anIt;
+      if (isValidInFilters(aValue))
+        aProcessed = setSelectionCustom(aValue);
+    }
+    if (aProcessed) {
+      emit valuesChanged();
+      updateObject(myFeature);
+      setVisibleSelectionControl(false);
+      emit focusOutWidget(this);
+    }
+  }
+}
+
+//********************************************************************
+void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
+                                            GeomShapePtr theShape)
+{
+  std::string anAttributeId = myAttributeListID;
+  DataPtr aData = myFeature->data();
+  AttributePtr anAttribute = aData->attribute(anAttributeId);
+  if (anAttribute.get()) {
+    std::string aType = anAttribute->attributeType();
+    if (aType == ModelAPI_AttributeSelectionList::typeId()) {
+      AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(anAttributeId);
+      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
+      if (!aSelectionListAttr->isInList(aResult, theShape, myIsInValidate))
+        aSelectionListAttr->append(aResult, theShape, myIsInValidate);
+    }
+  }
+}
 void PartSet_WidgetSketchCreator::onStarted()
 {
   disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted()));
 
+  setVisibleSelectionControl(true);
+}
+
+void PartSet_WidgetSketchCreator::startSketchOperation(const ModuleBase_ViewerPrs& theValue)
+{
   // Check that model already has bodies
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
+  /*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 = false;
+  bool aHasBody = !myUseBody;
   ResultBodyPtr aBody;
-  foreach(ObjectPtr aObj, aObjList) {
-    aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
-    if (aBody.get() != NULL) {
-      aHasBody = true;
-      break;
+  if(!aHasBody) {
+    foreach(ObjectPtr aObj, aObjList) {
+      aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
+      if (aBody.get() != NULL) {
+        aHasBody = true;
+        break;
+      }
     }
-  }
+  }*/
 
-  if (aHasBody) {
+  //if (aHasBody) {
     // 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, 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 {
+  //}
+  /* else {
     // Break current operation
     std::string anOperationName = feature()->getKind();
     QString aTitle = tr( anOperationName.c_str() );
@@ -134,26 +276,33 @@ void PartSet_WidgetSketchCreator::onStarted()
         tr("There are no bodies found. Operation aborted."), QMessageBox::Ok);
     ModuleBase_Operation* aOp = myModule->workshop()->currentOperation();
     aOp->abort();
-  }
+  }*/
 }
 
 bool PartSet_WidgetSketchCreator::focusTo()
 {
-  CompositeFeaturePtr aCompFeature = 
-    std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
-  if (aCompFeature->numberOfSubs() == 0)
-    return ModuleBase_ModelWidget::focusTo(); 
-
-  connect(myModule, SIGNAL(operationResumed(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
-  bool aIsOp = aMgr->isOperation();
-  if (!aIsOp) {
-    const static std::string aNestedOpID("Parameters modification");
-    aMgr->startOperation(aNestedOpID, true);
+  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()));
+    // 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();
+    return true;
+  }
+  else {
+    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
+    bool aIsOp = aMgr->isOperation();
+    if (!aIsOp) {
+      const static std::string aNestedOpID("Parameters modification");
+      aMgr->startOperation(aNestedOpID, true);
+    }
+    restoreValue();
   }
-
-  restoreValue();
   return false;
 }
 
@@ -184,27 +333,36 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
     }
     aSketchFeature->setDisplayed(false);
 
-    // Add Selected body were created the sketcher to list of selected objects
-    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();
+    if(myUseBody) {
+      // Add Selected body were created the sketcher to list of selected objects
+      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();
+        }
       }
     }
+    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());
+    }
   }
 }