Salome HOME
Providing Action class to have a common approach to start/finish/abort model transact...
authornds <nds@opencascade.com>
Wed, 26 Aug 2015 09:08:43 +0000 (12:08 +0300)
committernds <nds@opencascade.com>
Wed, 26 Aug 2015 09:09:08 +0000 (12:09 +0300)
The common functionality:
1.On the start of the action, the message about aborting the previous operation should be shown.
2. On commit, ApplyAll button[sketch operation] enable state should be updated, SetModified[sketch operation] of the parent operation update[in order to have a message about aborting transaction].
In the current integration, ModuleBase_Operation is separated to ModuleBase_OperationFeature and ModuleBase_OperationAction.

18 files changed:
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_Operation.cpp
src/ModuleBase/ModuleBase_Operation.h
src/ModuleBase/ModuleBase_OperationAction.cpp [new file with mode: 0755]
src/ModuleBase/ModuleBase_OperationAction.h [new file with mode: 0755]
src/ModuleBase/ModuleBase_OperationFeature.cpp [new file with mode: 0755]
src/ModuleBase/ModuleBase_OperationFeature.h [new file with mode: 0755]
src/PartSet/PartSet_MenuMgr.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_WidgetSketchCreator.cpp
src/XGUI/XGUI_ActionsMgr.cpp
src/XGUI/XGUI_ErrorMgr.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_WorkshopListener.cpp

index fd928e6ef0038c7538f37f9d4dbd491db523e08d..935f742e84e0b40f8191d3bdd0bef9018ac20c4a 100644 (file)
@@ -22,7 +22,9 @@ SET(PROJECT_HEADERS
   ModuleBase_IWorkshop.h
   ModuleBase_ModelWidget.h
   ModuleBase_Operation.h
+  ModuleBase_OperationAction.h
   ModuleBase_OperationDescription.h    
+  ModuleBase_OperationFeature.h
   ModuleBase_PageBase.h
   ModuleBase_PageGroupBox.h
   ModuleBase_PageWidget.h      
@@ -71,7 +73,9 @@ SET(PROJECT_SOURCES
   ModuleBase_IWorkshop.cpp
   ModuleBase_ModelWidget.cpp
   ModuleBase_Operation.cpp
-  ModuleBase_OperationDescription.cpp
+  ModuleBase_OperationAction.cpp
+  ModuleBase_OperationDescription.cpp  
+  ModuleBase_OperationFeature.cpp
   ModuleBase_PageBase.cpp
   ModuleBase_PageGroupBox.cpp
   ModuleBase_PageWidget.cpp
index 1c69f04710ee9e69b304a29dbbfa70e28fab35ed..3fe2524f3f512002f407eb42ca281702702635e9 100644 (file)
@@ -7,6 +7,7 @@
 #include "ModuleBase_Operation.h"
 #include "ModuleBase_ISelection.h"
 #include "ModuleBase_OperationDescription.h"
+#include "ModuleBase_OperationFeature.h"
 
 #include <Events_Loop.h>
 
@@ -43,11 +44,14 @@ void ModuleBase_IModule::launchOperation(const QString& theCmdId)
   if (!myWorkshop->canStartOperation(theCmdId))
     return;
 
-  ModuleBase_Operation* anOperation = createOperation(theCmdId.toStdString());
-  ModuleBase_ISelection* aSelection = myWorkshop->selection();
-  // Initialise operation with preliminary selection
-  anOperation->initSelection(aSelection, myWorkshop->viewer());
-  sendOperation(anOperation);
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                             (createOperation(theCmdId.toStdString()));
+  if (aFOperation) {
+    ModuleBase_ISelection* aSelection = myWorkshop->selection();
+    // Initialise operation with preliminary selection
+    aFOperation->initSelection(aSelection, myWorkshop->viewer());
+    sendOperation(aFOperation);
+  }
 }
 
 
@@ -62,22 +66,23 @@ void ModuleBase_IModule::sendOperation(ModuleBase_Operation* theOperation)
 
 ModuleBase_Operation* ModuleBase_IModule::getNewOperation(const std::string& theFeatureId)
 {
-  return new ModuleBase_Operation(theFeatureId.c_str(), this);
+  return new ModuleBase_OperationFeature(theFeatureId.c_str(), this);
 }
 
 ModuleBase_Operation* ModuleBase_IModule::createOperation(const std::string& theFeatureId)
 {
-  ModuleBase_Operation* anOperation = getNewOperation(theFeatureId);
-
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                          (getNewOperation(theFeatureId));
   // If the operation is launched as sub-operation of another then we have to initialise
   // parent feature
-  ModuleBase_Operation* aCurOperation = myWorkshop->currentOperation();
+  ModuleBase_OperationFeature* aCurOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                         (myWorkshop->currentOperation());
   if (aCurOperation) {
     FeaturePtr aFeature = aCurOperation->feature();
     CompositeFeaturePtr aCompFeature =
         std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
     if (aCompFeature) {
-      anOperation->setParentFeature(aCompFeature);
+      aFOperation->setParentFeature(aCompFeature);
     }
   }
 
@@ -87,10 +92,10 @@ ModuleBase_Operation* ModuleBase_IModule::createOperation(const std::string& the
   std::string aXmlCfg = aWdgReader.featureWidgetCfg(theFeatureId);
   std::string aDescription = aWdgReader.featureDescription(theFeatureId);
 
-  anOperation->getDescription()->setDescription(QString::fromStdString(aDescription));
-  anOperation->getDescription()->setXmlRepresentation(QString::fromStdString(aXmlCfg));
+  aFOperation->getDescription()->setDescription(QString::fromStdString(aDescription));
+  aFOperation->getDescription()->setXmlRepresentation(QString::fromStdString(aXmlCfg));
 
-  return anOperation;
+  return aFOperation;
 }
 
 void ModuleBase_IModule::createFeatures()
@@ -156,15 +161,19 @@ void ModuleBase_IModule::editFeature(FeaturePtr theFeature)
   if (!myWorkshop->canStartOperation(aFeatureId.c_str()))
     return;
 
-  ModuleBase_Operation* anOperation = createOperation(aFeatureId);
-  anOperation->setFeature(theFeature);
-  sendOperation(anOperation);
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                         (createOperation(aFeatureId));
+  if (aFOperation) {
+    aFOperation->setFeature(theFeature);
+    sendOperation(aFOperation);
+  }
 }
 
 bool ModuleBase_IModule::canActivateSelection(const ObjectPtr& theObject) const
 {
-  ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
-  return !aOperation || !aOperation->hasObject(theObject);
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                     (myWorkshop->currentOperation());
+  return !aFOperation || !aFOperation->hasObject(theObject);
 }
 
 void ModuleBase_IModule::onOperationResumed(ModuleBase_Operation* theOperation) 
index 701b6a0cce5e7eed85be957a3507d9e0c4c9b12d..4d54780f9941acda1717d3030d28b48f4efad6b7 100644 (file)
@@ -39,7 +39,6 @@
 
 ModuleBase_Operation::ModuleBase_Operation(const QString& theId, QObject* theParent)
     : QObject(theParent),
-      myIsEditing(false),
       myIsModified(false),
       myPropertyPanel(NULL)
 {
@@ -49,7 +48,6 @@ ModuleBase_Operation::ModuleBase_Operation(const QString& theId, QObject* thePar
 ModuleBase_Operation::~ModuleBase_Operation()
 {
   delete myDescription;
-  clearPreselection();
 }
 
 QString ModuleBase_Operation::id() const
@@ -57,86 +55,21 @@ QString ModuleBase_Operation::id() const
   return getDescription()->operationId();
 }
 
-FeaturePtr ModuleBase_Operation::feature() const
-{
-  return myFeature;
-}
-
 bool ModuleBase_Operation::isValid() const
 {
-  if (!myFeature || !myFeature->data()->isValid())
-    return true; // rename operation
-  if (myFeature->isAction())
-    return true;
-  //Get validators for the Id
-  SessionPtr aMgr = ModelAPI_Session::get();
-  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
-  bool aValid = aFactory->validate(myFeature);
-
-  // the feature exec state should be checked in order to do not apply features, which result can not
-  // be built. E.g. extrusion on sketch, where the "to" is a perpendicular plane to the sketch
-  bool isDone = ( myFeature->data()->execState() == ModelAPI_StateDone
-               || myFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
-
-  return aValid && isDone;
+  return true;
 }
 
-
 bool ModuleBase_Operation::canBeCommitted() const
 {
   return isValid();
 }
 
-FeaturePtr ModuleBase_Operation::createFeature(const bool theFlushMessage)
-{
-  if (myParentFeature.get()) {
-    myFeature = myParentFeature->addFeature(getDescription()->operationId().toStdString());
-  } else {
-    std::shared_ptr<ModelAPI_Document> aDoc = ModelAPI_Session::get()->activeDocument();
-    myFeature = aDoc->addFeature(getDescription()->operationId().toStdString());
-  }
-  if (myFeature) {  // TODO: generate an error if feature was not created
-    myIsModified = true;
-    // Model update should call "execute" of a feature.
-    //myFeature->execute();
-    // Init default values
-    /*QList<ModuleBase_ModelWidget*> aWidgets = getDescription()->modelWidgets();
-     QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end();
-     for (; anIt != aLast; anIt++) {
-     (*anIt)->storeValue(aFeature);
-     }*/
-  }
-
-  if (theFlushMessage)
-    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
-  return myFeature;
-}
-
-void ModuleBase_Operation::setFeature(FeaturePtr theFeature)
-{
-  myFeature = theFeature;
-  myIsEditing = true;
-}
-
-bool ModuleBase_Operation::hasObject(ObjectPtr theObj) const
-{
-  FeaturePtr aFeature = feature();
-  if (aFeature) {
-    if (aFeature == theObj)
-      return true;
-    std::list<ResultPtr> aResults = aFeature->results();
-    std::list<ResultPtr>::const_iterator aIt;
-    for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-      if (theObj == (*aIt))
-        return true;
-    }
-  }
-  return false;
-}
 
 void ModuleBase_Operation::start()
 {
   myIsModified = false;
+  /*
   QString anId = getDescription()->operationId();
   if (myIsEditing) {
     anId = anId.append(EditSuffix());
@@ -164,7 +97,7 @@ void ModuleBase_Operation::start()
 
   startOperation();
   emit started();
-
+*/
 }
 
 void ModuleBase_Operation::postpone()
@@ -181,6 +114,7 @@ void ModuleBase_Operation::resume()
 
 void ModuleBase_Operation::abort()
 {
+/*
   // the viewer update should be blocked in order to avoid the features blinking before they are
   // hidden
   std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
@@ -223,11 +157,12 @@ void ModuleBase_Operation::abort()
   Events_Loop::loop()->send(aMsg);
 
   emit aborted();
+*/
 }
 
 bool ModuleBase_Operation::commit()
 {
-  if (canBeCommitted()) {
+/*  if (canBeCommitted()) {
     // the widgets of property panel should not process any events come from data mode
     // after commit clicked. Some signal such as redisplay/create influence on content
     // of the object browser and viewer context. Therefore it influence to the current
@@ -258,6 +193,7 @@ bool ModuleBase_Operation::commit()
     afterCommitOperation();
     return true;
   }
+*/
   return false;
 }
 
@@ -266,143 +202,12 @@ void ModuleBase_Operation::onValuesChanged()
   myIsModified = true;
 }
 
-void ModuleBase_Operation::commitOperation()
-{
-  if(!myPropertyPanel) {
-    return;
-  }
-}
-
-void ModuleBase_Operation::activateByPreselection()
-{
-  if (myPreSelection.empty())
-    return;
-
-  ModuleBase_ModelWidget* aFilledWgt = 0;
-  if (myPropertyPanel) {
-    const QList<ModuleBase_ModelWidget*>& aWidgets = myPropertyPanel->modelWidgets();
-    if (!aWidgets.empty()) {
-      ModuleBase_ModelWidget* aWgt = 0;
-      QList<ModuleBase_ModelWidget*>::const_iterator aWIt;
-      bool isSet = false;
-      // 1. apply the selection to controls
-      for (aWIt = aWidgets.constBegin(); aWIt != aWidgets.constEnd(); ++aWIt) {
-        aWgt = (*aWIt);
-        if (!aWgt->canSetValue())
-          continue;
-        myPropertyPanel->setPreselectionWidget(aWgt);
-        if (!aWgt->setSelection(myPreSelection, true)) {
-          isSet = false;
-          break;
-        } else {
-          isSet = true;
-          aFilledWgt = aWgt;
-        }
-      }
-      myPropertyPanel->setPreselectionWidget(NULL);
-      // in order to redisplay object in the viewer, the update/redisplay signals should be flushed
-      // it is better to perform it not in setSelection of each widget, but do it here,
-      // after the preselection is processed
-      ModuleBase_ModelWidget::updateObject(myFeature);
-
-      // 3. a signal should be emitted before the next widget activation
-      // because, the activation of the next widget will give a focus to the widget. As a result
-      // the value of the widget is initialized. And commit may happens until the value is entered.
-      if (aFilledWgt)
-        emit activatedByPreselection();
-    }
-    // 4. activate the next obligatory widget
-    myPropertyPanel->activateNextWidget(aFilledWgt);
-  }
-
-  clearPreselection();
-}
-
-void ModuleBase_Operation::setParentFeature(CompositeFeaturePtr theParent)
-{
-  myParentFeature = theParent;
-}
-
-CompositeFeaturePtr ModuleBase_Operation::parentFeature() const
-{
-  return myParentFeature;
-}
-
-void ModuleBase_Operation::initSelection(ModuleBase_ISelection* theSelection,
-                                         ModuleBase_IViewer* theViewer)
-{
-  clearPreselection();
-
-  QList<ModuleBase_ViewerPrs> aPreSelected;
-  // Check that the selected result are not results of operation feature
-  FeaturePtr aFeature = feature();
-  if (aFeature) {
-    QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected(ModuleBase_ISelection::AllControls);
-
-    std::list<ResultPtr> aResults = aFeature->results();
-    QObjectPtrList aResList;
-    std::list<ResultPtr>::const_iterator aIt;
-    for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)
-      aResList.append(*aIt);
-
-    foreach (ModuleBase_ViewerPrs aPrs, aSelected) {
-      if ((!aResList.contains(aPrs.object())) && (aPrs.object() != aFeature))
-        aPreSelected.append(aPrs);
-    }
-  } else
-    aPreSelected = theSelection->getSelected(ModuleBase_ISelection::AllControls);
-
-  // convert the selection values to the values, which are set to the operation widgets
-
-  //Handle(V3d_View) aView = theViewer->activeView();
-  //foreach (ModuleBase_ViewerPrs aPrs, aPreSelected) {
-  //  ModuleBase_WidgetValueFeature* aValue = new ModuleBase_WidgetValueFeature();
-  //  aValue->setObject(aPrs.object());
-
-  //  double aX, anY;
-  //  if (getViewerPoint(aPrs, theViewer, aX, anY))
-  //    aValue->setPoint(std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, anY)));
-  //  myPreSelection.append(aValue);
-  //}
-  myPreSelection = aPreSelected;
-}
-
-
-bool ModuleBase_Operation::getViewerPoint(ModuleBase_ViewerPrs thePrs,
-                                               ModuleBase_IViewer* theViewer,
-                                               double& theX, double& theY)
-{
-  return false;
-}
-
-void ModuleBase_Operation::clearPreselection()
-{
-  myPreSelection.clear();
-}
-
 void ModuleBase_Operation::setPropertyPanel(ModuleBase_IPropertyPanel* theProp) 
 { 
   myPropertyPanel = theProp; 
-  myPropertyPanel->setEditingMode(isEditOperation());
-
-  if (myPropertyPanel) {
-    const QList<ModuleBase_ModelWidget*>& aWidgets = myPropertyPanel->modelWidgets();
-    QList<ModuleBase_ModelWidget*>::const_iterator aWIt;
-    for (aWIt = aWidgets.constBegin(); aWIt != aWidgets.constEnd(); ++aWIt) {
-      ModuleBase_ModelWidget* aWgt = (*aWIt);
-      connect(aWgt, SIGNAL(valuesChanged()), this, SLOT(onValuesChanged()));
-    }
-  }
-
-  // Do not activate widgets by default if the current operation is editing operation
-  // Because we don't know which widget is going to be edited. 
-  if (!isEditOperation()) {
-    // 4. activate the first obligatory widget
-    myPropertyPanel->activateNextWidget(NULL);
-  }
 }
 
 bool ModuleBase_Operation::isGranted(QString theId) const
 {
-  return myNestedFeatures.contains(theId);
+  return false;
 }
index ec6cc4f49ad91228d0352b8ed106773b932da00c..09b6257786cd4c10dcb9d1d5b1f4bcbc1047759a 100644 (file)
 #define ModuleBase_Operation_H
 
 #include <ModuleBase.h>
-#include <ModuleBase_ViewerPrs.h>
-
-#include <ModelAPI_CompositeFeature.h>
-#include <ModelAPI_Document.h>
 
 #include <QObject>
 #include <QString>
@@ -23,8 +19,6 @@
 class ModuleBase_ModelWidget;
 class ModuleBase_OperationDescription;
 class ModuleBase_IPropertyPanel;
-class ModuleBase_ISelection;
-class ModuleBase_IViewer;
 
 class QKeyEvent;
 
@@ -50,13 +44,11 @@ class MODULEBASE_EXPORT ModuleBase_Operation : public QObject
 Q_OBJECT
 
  public:
-
-  /// Appends to operation's history id, if it is an "edit" operation (myIsEditing == true)
-  static QString EditSuffix() { return "_E"; }
   /// Constructor
   /// \param theId the operation identifier
   /// \param theParent the QObject parent
   ModuleBase_Operation(const QString& theId = "", QObject* theParent = 0);
+
   /// Destructor
   virtual ~ModuleBase_Operation();
 
@@ -64,56 +56,25 @@ Q_OBJECT
   /// /returns the instance of the description class
   ModuleBase_OperationDescription* getDescription() const { return myDescription; }
 
-  /**
-  * Must return true if this operation can be launched as nested for any current operation
-  * and it is not necessary to check this operation on validity. By default 
-  * the operation is not granted.
-  * The method has to be redefined for granted operations.
-  */
+  /// Must return true if this operation can be launched as nested for any current operation
+  /// and it is not necessary to check this operation on validity. By default 
+  /// the operation is not granted.
+  /// The method has to be redefined for granted operations.
   virtual bool isGranted(QString theId) const;
 
-
   /// Returns True if data of its feature was modified during operation
   virtual bool isModified() const { return myIsModified; }
 
   /// Change the modified state of the operation
   void setIsModified(const bool theIsModified) { myIsModified = theIsModified;  }
 
-  /// Returns True id the current operation is launched in editing mode
-  bool isEditOperation() const { return myIsEditing; }
-
-  /// Returns list of nested features
-  QStringList nestedFeatures() const { return myNestedFeatures; }
-
-  /// Sets list of nested features
-  void setNestedFeatures(const QStringList& theList) { myNestedFeatures = theList; }
-
-
   /// Returns operations Id from it's description
   QString id() const;
 
-  /// Returns the operation feature
-  /// \return the feature
-  FeaturePtr feature() const;
-
-  /**
-  * Must return True if the operation's feature is valid.
-  * Since IOperation does not have any feature returns false.
-  */
+  /// Must return True if the operation's feature is valid.
+  /// Since IOperation does not have any feature returns false.
   virtual bool isValid() const;
 
-  /// Sets the operation feature
-  void setFeature(FeaturePtr theFeature);
-
-  /// Returns True if the current operation works with the given object (feature or result)
-  virtual bool hasObject(ObjectPtr theObj) const;
-
-  /// Initialisation of operation with preliminary selection
-  /// \param theSelection an instance of Selection class
-  /// \param theViewer a viewer to have the viewer the eye position
-  virtual void initSelection(ModuleBase_ISelection* theSelection,
-                             ModuleBase_IViewer* theViewer);
-
   /// \brief Set property pane to the operation
   /// \param theProp a property panel instance
   virtual void setPropertyPanel(ModuleBase_IPropertyPanel* theProp);
@@ -121,38 +82,24 @@ Q_OBJECT
   /// \return Currently installed property panel
   ModuleBase_IPropertyPanel* propertyPanel() const { return myPropertyPanel; }
 
-  /// Activates widgets by preselection if it is accepted. Emits signal if the activation is correct
-  virtual void activateByPreselection();
-
-  /// If the operation works with feature which is sub-feature of another one
-  /// then this variable has to be initialised by parent feature 
-  /// before operation feature creating
-  void setParentFeature(CompositeFeaturePtr theParent);
-
-  /// \return Installed parent feature (can be NULL)
-  CompositeFeaturePtr parentFeature() const;
-
 signals:
   /// The operation is started
-  void started();  
+  void started();
 
   /// The operation is aborted
-  void aborted();  
+  void aborted();
 
   /// The operation is committed
-  void committed();  
+  void committed();
 
   /// The operation is aborted or committed
-  void stopped();  
+  void stopped();
 
   /// The operation is resumed
-  void resumed();  
+  void resumed();
 
   /// The operation is postponed
-  void postponed();  
-
-  /// The operation is filled with existing preselection
-  void activatedByPreselection(); 
+  void postponed();
 
  public slots:
   /// Starts operation
@@ -161,10 +108,10 @@ signals:
   /// to change behavior of operation. There is no point in using this method. It would
   /// be better to inherit own operator from base one and redefine startOperation method
   /// instead.
-  void start();
+  virtual void start();
 
   /// Deactivates current operation which can be resumed later.
-  void postpone();
+  virtual void postpone();
 
   /// Resumes operation
   /// Public slot. Verifies whether operation can be started and starts operation.
@@ -172,17 +119,17 @@ signals:
   /// to change behavior of operation. There is no point in using this method. It would
   /// be better to inherit own operator from base one and redefine startOperation method
   /// instead.
-  void resume();
+  virtual void resume();
 
   /// Aborts operation
   /// Public slot. Aborts operation. This slot is not virtual and cannot be redefined.
   /// Redefine abortOperation method to change behavior of operation instead
-  void abort();
+  virtual void abort();
 
   /// Commits operation
   /// Public slot. Commits operation. This slot is not virtual and cannot be redefined.
   /// Redefine commitOperation method to change behavior of operation instead
-  bool commit();
+  virtual bool commit();
 
   /// Changes the modified flag of the operation
   void onValuesChanged();
@@ -202,7 +149,7 @@ signals:
   virtual void abortOperation() {}
 
   /// Virtual method called when operation committed (see commit() method for more description)
-  virtual void commitOperation();
+  virtual void commitOperation() {};
 
   /// Virtual method called after operation committed (see commit() method for more description)
   virtual void afterCommitOperation() {}
@@ -210,58 +157,19 @@ signals:
   /// Virtual method called after operation resume (see resume() method for more description)
   virtual void resumeOperation() {}
 
-  /// Creates an operation new feature
-  /// \param theFlushMessage the flag whether the create message should be flushed
-  /// \returns the created feature
-  virtual FeaturePtr createFeature(const bool theFlushMessage = true);
-
   /// Verifies whether this operator can be commited.
   /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled
   virtual bool canBeCommitted() const;
 
-  /// Return a widget value point by the selection and the viewer position
-  /// The default realization returns false
-  /// \param thePrs the presentation
-  /// \param theViewer a viewer to have the viewer the eye position
-  /// \param theX the horizontal coordinate
-  /// \param theY the vertical coordinate
-  /// \return true if the point exits in the selection
-  virtual bool getViewerPoint(ModuleBase_ViewerPrs thePrs,
-                                   ModuleBase_IViewer* theViewer,
-                                   double& theX, double& theY);
-
-  /// Removes the preselection information and clears the map of preselection
-  void clearPreselection();
-
- protected:
-   /// The operation feature to be handled
-  FeaturePtr myFeature;  
-
+private:
   /// the container to have the operation description
-  ModuleBase_OperationDescription* myDescription;  
-
-  /// Editing feature flag
-  bool myIsEditing;
+  ModuleBase_OperationDescription* myDescription;
 
   /// Modified feature flag
   bool myIsModified;
 
-  /// List of nested operations IDs
-  QStringList myNestedFeatures;
-
-  /// List of pre-selected object 
-  QList<ModuleBase_ViewerPrs> myPreSelection;
-
   /// Access to property panel
   ModuleBase_IPropertyPanel* myPropertyPanel;
-
-  /// If the operation works with feature which is sub-feature of another one
-  /// then this variable has to be initialised by parent feature 
-  /// before operation feature creating
-  CompositeFeaturePtr myParentFeature;  
-
-  /// Last current feature before editing operation
-  FeaturePtr myCurrentFeature;
 };
 
 #endif
diff --git a/src/ModuleBase/ModuleBase_OperationAction.cpp b/src/ModuleBase/ModuleBase_OperationAction.cpp
new file mode 100755 (executable)
index 0000000..cabc64c
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_OperationAction.cpp
+ *
+ *  Created on: Apr 2, 2014
+ *      Author: sbh
+ */
+
+#include "ModuleBase_OperationAction.h"
+
+ModuleBase_OperationAction::ModuleBase_OperationAction(const QString& theId, QObject* theParent)
+ : ModuleBase_Operation(theId, theParent)
+{
+}
+
+ModuleBase_OperationAction::~ModuleBase_OperationAction()
+{
+}
diff --git a/src/ModuleBase/ModuleBase_OperationAction.h b/src/ModuleBase/ModuleBase_OperationAction.h
new file mode 100755 (executable)
index 0000000..4667840
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_OperationAction.h
+ *
+ *  Created on: Apr 2, 2014
+ *      Author: sbh
+ */
+
+#ifndef ModuleBase_OperationAction_H
+#define ModuleBase_OperationAction_H
+
+#include <ModuleBase.h>
+
+#include <ModuleBase_Operation.h>
+
+/*!
+ * \class ModuleBase_OperationAction
+ * \ingroup GUI
+ * \brief Base class for all operations
+ *
+ *  Base class for all operations. If you perform an action it is reasonable to create
+ *  operation intended for this. This is a base class for all operations which provides
+ *  mechanism for correct starting operations, starting operations above already started
+ *  ones, committing operations and so on. To create own operation it is reasonable to
+ *  inherit it from this class and redefines virtual methods to provide own behavior
+ */
+
+class MODULEBASE_EXPORT ModuleBase_OperationAction : public ModuleBase_Operation
+{
+Q_OBJECT
+
+ public:
+
+  /// Constructor
+  /// \param theId the operation identifier
+  /// \param theParent the QObject parent
+  ModuleBase_OperationAction(const QString& theId = "", QObject* theParent = 0);
+  /// Destructor
+  virtual ~ModuleBase_OperationAction();
+};
+
+#endif
diff --git a/src/ModuleBase/ModuleBase_OperationFeature.cpp b/src/ModuleBase/ModuleBase_OperationFeature.cpp
new file mode 100755 (executable)
index 0000000..ff49f71
--- /dev/null
@@ -0,0 +1,355 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_OperationFeature.cpp
+ *
+ *  Created on: Apr 2, 2014
+ *      Author: sbh
+ */
+
+#include "ModuleBase_OperationFeature.h"
+
+#include "ModuleBase_OperationDescription.h"
+#include "ModuleBase_ModelWidget.h"
+#include "ModuleBase_ViewerPrs.h"
+#include "ModuleBase_IPropertyPanel.h"
+#include "ModuleBase_ISelection.h"
+#include "ModuleBase_IViewer.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Result.h>
+#include <ModelAPI_Object.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_Session.h>
+
+#include <GeomAPI_Pnt2d.h>
+
+#include <Events_Loop.h>
+
+#include <QTimer>
+
+#ifdef _DEBUG
+#include <QDebug>
+#endif
+
+ModuleBase_OperationFeature::ModuleBase_OperationFeature(const QString& theId, QObject* theParent)
+: ModuleBase_Operation(theId, theParent),
+  myIsEditing(false)
+{
+}
+
+ModuleBase_OperationFeature::~ModuleBase_OperationFeature()
+{
+  clearPreselection();
+}
+
+FeaturePtr ModuleBase_OperationFeature::feature() const
+{
+  return myFeature;
+}
+
+bool ModuleBase_OperationFeature::isValid() const
+{
+  if (!myFeature || !myFeature->data()->isValid())
+    return true; // rename operation
+  if (myFeature->isAction())
+    return true;
+  //Get validators for the Id
+  SessionPtr aMgr = ModelAPI_Session::get();
+  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+  bool aValid = aFactory->validate(myFeature);
+
+  // the feature exec state should be checked in order to do not apply features, which result can not
+  // be built. E.g. extrusion on sketch, where the "to" is a perpendicular plane to the sketch
+  bool isDone = ( myFeature->data()->execState() == ModelAPI_StateDone
+               || myFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
+
+  return aValid && isDone;
+}
+
+FeaturePtr ModuleBase_OperationFeature::createFeature(const bool theFlushMessage)
+{
+  if (myParentFeature.get()) {
+    myFeature = myParentFeature->addFeature(getDescription()->operationId().toStdString());
+  } else {
+    std::shared_ptr<ModelAPI_Document> aDoc = ModelAPI_Session::get()->activeDocument();
+    myFeature = aDoc->addFeature(getDescription()->operationId().toStdString());
+  }
+  if (myFeature) {  // TODO: generate an error if feature was not created
+    setIsModified(true);
+    // Model update should call "execute" of a feature.
+    //myFeature->execute();
+    // Init default values
+    /*QList<ModuleBase_ModelWidget*> aWidgets = getDescription()->modelWidgets();
+     QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end();
+     for (; anIt != aLast; anIt++) {
+     (*anIt)->storeValue(aFeature);
+     }*/
+  }
+
+  if (theFlushMessage)
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+  return myFeature;
+}
+
+void ModuleBase_OperationFeature::setFeature(FeaturePtr theFeature)
+{
+  myFeature = theFeature;
+  myIsEditing = true;
+}
+
+bool ModuleBase_OperationFeature::hasObject(ObjectPtr theObj) const
+{
+  FeaturePtr aFeature = feature();
+  if (aFeature) {
+    if (aFeature == theObj)
+      return true;
+    std::list<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr>::const_iterator aIt;
+    for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
+      if (theObj == (*aIt))
+        return true;
+    }
+  }
+  return false;
+}
+
+void ModuleBase_OperationFeature::start()
+{
+  setIsModified(false);
+  QString anId = getDescription()->operationId();
+  if (myIsEditing) {
+    anId = anId.append(EditSuffix());
+  }
+  ModelAPI_Session::get()->startOperation(anId.toStdString());
+
+  startOperation();
+
+  if (!myIsEditing) {
+    FeaturePtr aFeature = createFeature();
+    // if the feature is not created, there is no sense to start the operation
+    if (aFeature.get() == NULL) {
+      // it is necessary to abor the operation in the session and emit the aborted signal
+      // in order to update commands status in the workshop, to be exact the feature action
+      // to be unchecked
+      abort();
+      return;
+    }
+  }
+  /// Set current feature and remeber old current feature
+  if (myIsEditing) {
+    SessionPtr aMgr = ModelAPI_Session::get();
+    DocumentPtr aDoc = aMgr->activeDocument();
+    myCurrentFeature = aDoc->currentFeature(true);
+    aDoc->setCurrentFeature(feature(), false);
+  }
+
+  startOperation();
+  emit started();
+
+}
+
+void ModuleBase_OperationFeature::abort()
+{
+  // the viewer update should be blocked in order to avoid the features blinking before they are
+  // hidden
+  std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
+      new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
+  Events_Loop::loop()->send(aMsg);
+
+  // the widgets of property panel should not process any events come from data mode
+  // after abort clicked. Some signal such as redisplay/create influence on content
+  // of the object browser and viewer context. Therefore it influence to the current
+  // selection and if the active widget listens it, the attribute value is errnoneous
+  // changed.
+  ModuleBase_IPropertyPanel* aPropertyPanel = propertyPanel();
+  if (aPropertyPanel)
+    aPropertyPanel->cleanContent();
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  if (myIsEditing) {
+    DocumentPtr aDoc = aMgr->activeDocument();
+    bool aIsOp = aMgr->isOperation();
+    if (!aIsOp)
+      aMgr->startOperation();
+    aDoc->setCurrentFeature(myCurrentFeature, true);
+    if (!aIsOp)
+      aMgr->finishOperation();
+    myCurrentFeature = FeaturePtr();
+  }
+  abortOperation();
+
+  stopOperation();
+  // is is necessary to deactivate current widgets before the model operation is aborted
+  // because abort removes the feature and activated filters should not check it
+  propertyPanel()->cleanContent();
+
+  aMgr->abortOperation();
+  emit stopped();
+  // the viewer update should be unblocked in order to avoid the features blinking before they are
+  // hidden
+  aMsg = std::shared_ptr<Events_Message>(
+                new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
+
+  Events_Loop::loop()->send(aMsg);
+
+  emit aborted();
+}
+
+bool ModuleBase_OperationFeature::commit()
+{
+  if (canBeCommitted()) {
+    // the widgets of property panel should not process any events come from data mode
+    // after commit clicked. Some signal such as redisplay/create influence on content
+    // of the object browser and viewer context. Therefore it influence to the current
+    // selection and if the active widget listens it, the attribute value is errnoneous
+    // changed.
+    ModuleBase_IPropertyPanel* aPropertyPanel = propertyPanel();
+    if (aPropertyPanel)
+      aPropertyPanel->cleanContent();
+
+    SessionPtr aMgr = ModelAPI_Session::get();
+    /// Set current feature and remeber old current feature
+    if (myIsEditing) {
+      DocumentPtr aDoc = aMgr->activeDocument();
+      bool aIsOp = aMgr->isOperation();
+      if (!aIsOp)
+        aMgr->startOperation();
+      aDoc->setCurrentFeature(myCurrentFeature, true);
+      if (!aIsOp)
+        aMgr->finishOperation();
+      myCurrentFeature = FeaturePtr();
+    }
+    commitOperation();
+    aMgr->finishOperation();
+
+    stopOperation();
+    emit stopped();
+    emit committed();
+
+    afterCommitOperation();
+    return true;
+  }
+  return false;
+}
+
+void ModuleBase_OperationFeature::activateByPreselection()
+{
+  if (myPreSelection.empty())
+    return;
+
+  ModuleBase_ModelWidget* aFilledWgt = 0;
+  ModuleBase_IPropertyPanel* aPropertyPanel = propertyPanel();
+  if (aPropertyPanel) {
+    const QList<ModuleBase_ModelWidget*>& aWidgets = aPropertyPanel->modelWidgets();
+    if (!aWidgets.empty()) {
+      ModuleBase_ModelWidget* aWgt = 0;
+      QList<ModuleBase_ModelWidget*>::const_iterator aWIt;
+      bool isSet = false;
+      // 1. apply the selection to controls
+      for (aWIt = aWidgets.constBegin(); aWIt != aWidgets.constEnd(); ++aWIt) {
+        aWgt = (*aWIt);
+        if (!aWgt->canSetValue())
+          continue;
+        aPropertyPanel->setPreselectionWidget(aWgt);
+        if (!aWgt->setSelection(myPreSelection, true)) {
+          isSet = false;
+          break;
+        } else {
+          isSet = true;
+          aFilledWgt = aWgt;
+        }
+      }
+      aPropertyPanel->setPreselectionWidget(NULL);
+      // in order to redisplay object in the viewer, the update/redisplay signals should be flushed
+      // it is better to perform it not in setSelection of each widget, but do it here,
+      // after the preselection is processed
+      ModuleBase_ModelWidget::updateObject(myFeature);
+
+      // 3. a signal should be emitted before the next widget activation
+      // because, the activation of the next widget will give a focus to the widget. As a result
+      // the value of the widget is initialized. And commit may happens until the value is entered.
+      if (aFilledWgt)
+        emit activatedByPreselection();
+    }
+    // 4. activate the next obligatory widget
+    aPropertyPanel->activateNextWidget(aFilledWgt);
+  }
+
+  clearPreselection();
+}
+
+void ModuleBase_OperationFeature::setParentFeature(CompositeFeaturePtr theParent)
+{
+  myParentFeature = theParent;
+}
+
+CompositeFeaturePtr ModuleBase_OperationFeature::parentFeature() const
+{
+  return myParentFeature;
+}
+
+void ModuleBase_OperationFeature::initSelection(ModuleBase_ISelection* theSelection,
+                                         ModuleBase_IViewer* theViewer)
+{
+  clearPreselection();
+
+  QList<ModuleBase_ViewerPrs> aPreSelected;
+  // Check that the selected result are not results of operation feature
+  FeaturePtr aFeature = feature();
+  if (aFeature) {
+    QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected(ModuleBase_ISelection::AllControls);
+
+    std::list<ResultPtr> aResults = aFeature->results();
+    QObjectPtrList aResList;
+    std::list<ResultPtr>::const_iterator aIt;
+    for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)
+      aResList.append(*aIt);
+
+    foreach (ModuleBase_ViewerPrs aPrs, aSelected) {
+      if ((!aResList.contains(aPrs.object())) && (aPrs.object() != aFeature))
+        aPreSelected.append(aPrs);
+    }
+  } else
+    aPreSelected = theSelection->getSelected(ModuleBase_ISelection::AllControls);
+
+  myPreSelection = aPreSelected;
+}
+
+void ModuleBase_OperationFeature::clearPreselection()
+{
+  myPreSelection.clear();
+}
+
+void ModuleBase_OperationFeature::setPropertyPanel(ModuleBase_IPropertyPanel* theProp) 
+{
+  ModuleBase_Operation::setPropertyPanel(theProp);
+
+  theProp->setEditingMode(isEditOperation());
+
+  if (theProp) {
+    const QList<ModuleBase_ModelWidget*>& aWidgets = theProp->modelWidgets();
+    QList<ModuleBase_ModelWidget*>::const_iterator aWIt;
+    for (aWIt = aWidgets.constBegin(); aWIt != aWidgets.constEnd(); ++aWIt) {
+      ModuleBase_ModelWidget* aWgt = (*aWIt);
+      connect(aWgt, SIGNAL(valuesChanged()), this, SLOT(onValuesChanged()));
+    }
+  }
+
+  // Do not activate widgets by default if the current operation is editing operation
+  // Because we don't know which widget is going to be edited. 
+  if (!isEditOperation()) {
+    // 4. activate the first obligatory widget
+    theProp->activateNextWidget(NULL);
+  }
+}
+
+bool ModuleBase_OperationFeature::isGranted(QString theId) const
+{
+  return myNestedFeatures.contains(theId);
+}
diff --git a/src/ModuleBase/ModuleBase_OperationFeature.h b/src/ModuleBase/ModuleBase_OperationFeature.h
new file mode 100755 (executable)
index 0000000..cc937e1
--- /dev/null
@@ -0,0 +1,172 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_OperationFeature.h
+ *
+ *  Created on: Apr 2, 2014
+ *      Author: sbh
+ */
+
+#ifndef ModuleBase_OperationFeature_H
+#define ModuleBase_OperationFeature_H
+
+#include <ModuleBase.h>
+#include <ModuleBase_Operation.h>
+#include <ModuleBase_ViewerPrs.h>
+
+#include <ModelAPI_CompositeFeature.h>
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+
+class ModuleBase_ModelWidget;
+class ModuleBase_ISelection;
+class ModuleBase_IViewer;
+
+class QKeyEvent;
+
+/*!
+ * \class ModuleBase_OperationFeature
+ * \ingroup GUI
+ * \brief Base class for all operations
+ *
+ *  Base class for all operations. If you perform an action it is reasonable to create
+ *  operation intended for this. This is a base class for all operations which provides
+ *  mechanism for correct starting operations, starting operations above already started
+ *  ones, committing operations and so on. To create own operation it is reasonable to
+ *  inherit it from this class and redefines virtual methods to provide own behavior
+ *  Main virtual methods are
+ *  - virtual bool      isReadyToStart();
+ *  - virtual void      startOperation();
+ *  - virtual void      abortOperation();
+ *  - virtual void      commitOperation();
+ */
+
+class MODULEBASE_EXPORT ModuleBase_OperationFeature : public ModuleBase_Operation
+{
+Q_OBJECT
+
+ public:
+
+  /// Appends to operation's history id, if it is an "edit" operation (myIsEditing == true)
+  static QString EditSuffix() { return "_E"; }
+  /// Constructor
+  /// \param theId the operation identifier
+  /// \param theParent the QObject parent
+  ModuleBase_OperationFeature(const QString& theId = "", QObject* theParent = 0);
+  /// Destructor
+  virtual ~ModuleBase_OperationFeature();
+
+  /**
+  * Must return true if this operation can be launched as nested for any current operation
+  * and it is not necessary to check this operation on validity. By default 
+  * the operation is not granted.
+  * The method has to be redefined for granted operations.
+  */
+  virtual bool isGranted(QString theId) const;
+
+  /// Returns True id the current operation is launched in editing mode
+  bool isEditOperation() const { return myIsEditing; }
+
+  /// Returns list of nested features
+  QStringList nestedFeatures() const { return myNestedFeatures; }
+
+  /// Sets list of nested features
+  void setNestedFeatures(const QStringList& theList) { myNestedFeatures = theList; }
+
+  /// Returns the operation feature
+  /// \return the feature
+  FeaturePtr feature() const;
+
+  /**
+  * Must return True if the operation's feature is valid.
+  * Since IOperation does not have any feature returns false.
+  */
+  virtual bool isValid() const;
+
+  /// Sets the operation feature
+  void setFeature(FeaturePtr theFeature);
+
+  /// Returns True if the current operation works with the given object (feature or result)
+  virtual bool hasObject(ObjectPtr theObj) const;
+
+  /// Initialisation of operation with preliminary selection
+  /// \param theSelection an instance of Selection class
+  /// \param theViewer a viewer to have the viewer the eye position
+  virtual void initSelection(ModuleBase_ISelection* theSelection,
+                             ModuleBase_IViewer* theViewer);
+
+  /// \brief Set property pane to the operation
+  /// \param theProp a property panel instance
+  virtual void setPropertyPanel(ModuleBase_IPropertyPanel* theProp);
+
+  /// \return Currently installed property panel
+  //ModuleBase_IPropertyPanel* propertyPanel() const { return myPropertyPanel; }
+
+  /// Activates widgets by preselection if it is accepted. Emits signal if the activation is correct
+  virtual void activateByPreselection();
+
+  /// If the operation works with feature which is sub-feature of another one
+  /// then this variable has to be initialised by parent feature 
+  /// before operation feature creating
+  void setParentFeature(CompositeFeaturePtr theParent);
+
+  /// \return Installed parent feature (can be NULL)
+  CompositeFeaturePtr parentFeature() const;
+
+signals:
+  /// The operation is filled with existing preselection
+  void activatedByPreselection(); 
+
+ public slots:
+  /// Starts operation
+  /// Public slot. Verifies whether operation can be started and starts operation.
+  /// This slot is not virtual and cannot be redefined. Redefine startOperation method
+  /// to change behavior of operation. There is no point in using this method. It would
+  /// be better to inherit own operator from base one and redefine startOperation method
+  /// instead.
+  void start();
+
+  /// Aborts operation
+  /// Public slot. Aborts operation. This slot is not virtual and cannot be redefined.
+  /// Redefine abortOperation method to change behavior of operation instead
+  void abort();
+
+  /// Commits operation
+  /// Public slot. Commits operation. This slot is not virtual and cannot be redefined.
+  /// Redefine commitOperation method to change behavior of operation instead
+  bool commit();
+
+ protected:
+  /// Creates an operation new feature
+  /// \param theFlushMessage the flag whether the create message should be flushed
+  /// \returns the created feature
+  virtual FeaturePtr createFeature(const bool theFlushMessage = true);
+
+  /// Removes the preselection information and clears the map of preselection
+  void clearPreselection();
+
+ protected:
+   /// The operation feature to be handled
+  FeaturePtr myFeature;
+
+  /// Editing feature flag
+  bool myIsEditing;
+
+  /// List of nested operations IDs
+  QStringList myNestedFeatures;
+
+  /// List of pre-selected object 
+  QList<ModuleBase_ViewerPrs> myPreSelection;
+
+  /// If the operation works with feature which is sub-feature of another one
+  /// then this variable has to be initialised by parent feature 
+  /// before operation feature creating
+  CompositeFeaturePtr myParentFeature;  
+
+  /// Last current feature before editing operation
+  FeaturePtr myCurrentFeature;
+};
+
+#endif
index 0d8c0cc9a5f1cec77ec2e3f3772e9e8bedce9530..d6bd2879eb950d2d42d655a1b39d90b562f0daac 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_Operation.h>
+#include <ModuleBase_OperationFeature.h>
 
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Workshop.h>
@@ -343,8 +344,11 @@ void PartSet_MenuMgr::setAuxiliary(const bool isChecked)
   bool isUseTransaction = false;
   // 1. change auxiliary type of a created feature
   if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation) &&
-    PartSet_SketcherMgr::isEntity(anOperation->id().toStdString()) ) {
-    anObjects.append(anOperation->feature());
+      PartSet_SketcherMgr::isEntity(anOperation->id().toStdString()) ) {
+      ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                               (anOperation);
+      if (aFOperation)
+        anObjects.append(aFOperation->feature());
   }
   else {
     isUseTransaction = true;
@@ -405,7 +409,9 @@ bool PartSet_MenuMgr::canSetAuxiliary(bool& theValue) const
   // 1. change auxiliary type of a created feature
   if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation) &&
     PartSet_SketcherMgr::isEntity(anOperation->id().toStdString()) ) {
-    anObjects.append(anOperation->feature());
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(anOperation);
+    if (aFOperation)
+      anObjects.append(aFOperation->feature());
   }
   else {
     /// The operation should not be aborted here, because the method does not changed
index c23c23beb914c0bccacf95ad71b3045f61caa111..54b88f25dabd3f1b09a47971950c32c531a479b1 100755 (executable)
@@ -32,8 +32,9 @@
 #include <ModuleBase_WidgetValidated.h>
 #include <ModuleBase_FilterFactory.h>
 #include <ModuleBase_Tools.h>
-#include <GeomValidators_ShapeType.h>
+#include <ModuleBase_OperationFeature.h>
 
+#include <GeomValidators_ShapeType.h>
 #include <GeomValidators_Face.h>
 #include <GeomValidators_ConstructionComposite.h>
 #include <GeomValidators_ZeroOffset.h>
@@ -246,7 +247,8 @@ void PartSet_Module::onOperationCommitted(ModuleBase_Operation* theOperation)
     mySketchMgr->commitNestedSketch(theOperation);
   }
 
-  if (theOperation->isEditOperation())
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if (!aFOperation || aFOperation->isEditOperation())
     return;
   // the selection is cleared after commit the create operation
   // in order to do not use the same selected objects in the restarted operation
@@ -256,13 +258,13 @@ void PartSet_Module::onOperationCommitted(ModuleBase_Operation* theOperation)
   aWorkshop->selector()->clearSelection();
 
   /// Restart sketcher operations automatically
-  FeaturePtr aFeature = theOperation->feature();
+  FeaturePtr aFeature = aFOperation->feature();
   std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
             std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
   if (aSPFeature && (myRestartingMode == RM_LastFeatureUsed ||
                      myRestartingMode == RM_EmptyFeatureUsed)) {
-    myLastOperationId = theOperation->id();
-    myLastFeature = myRestartingMode == RM_LastFeatureUsed ? theOperation->feature() : FeaturePtr();
+    myLastOperationId = aFOperation->id();
+    myLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature() : FeaturePtr();
     
     launchOperation(myLastOperationId);
   }
@@ -290,7 +292,9 @@ void PartSet_Module::onOperationStarted(ModuleBase_Operation* theOperation)
     mySketchMgr->startNestedSketch(theOperation);
   }
 
-  myCustomPrs->activate(theOperation->feature());
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if (aFOperation)
+    myCustomPrs->activate(aFOperation->feature());
 }
 
 void PartSet_Module::onOperationStopped(ModuleBase_Operation* theOperation)
@@ -371,7 +375,8 @@ bool PartSet_Module::canActivateSelection(const ObjectPtr& theObject) const
   if (isSketchOp || isNestedOp) {
     // in active sketch operation it is possible to activate operation object in selection
     // in the edit operation, e.g. points of the line can be moved when the line is edited
-    aCanActivate = aCanActivate || anOperation->isEditOperation();
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(anOperation);
+    aCanActivate = aCanActivate || (aFOperation && aFOperation->isEditOperation());
   }
   return aCanActivate;
 }
@@ -401,17 +406,21 @@ bool PartSet_Module::isMouseOverWindow()
 
 void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation)
 {
-  ModuleBase_IPropertyPanel* aPanel = theOperation->propertyPanel();
-  if (PartSet_SketcherMgr::isSketchOperation(theOperation) &&  (theOperation->isEditOperation())) {
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if (!aFOperation)
+    return;
+
+  ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
+  if (PartSet_SketcherMgr::isSketchOperation(aFOperation) &&  (aFOperation->isEditOperation())) {
     // we have to manually activate the sketch label in edit mode
       aPanel->activateWidget(aPanel->modelWidgets().first());
       return;
   }
 
   // Restart last operation type 
-  if ((theOperation->id() == myLastOperationId) && myLastFeature) {
+  if ((aFOperation->id() == myLastOperationId) && myLastFeature) {
     ModuleBase_ModelWidget* aWgt = aPanel->activeWidget();
-    if (theOperation->id().toStdString() == SketchPlugin_Line::ID()) {
+    if (aFOperation->id().toStdString() == SketchPlugin_Line::ID()) {
       // Initialise new line with first point equal to end of previous
       PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast<PartSet_WidgetPoint2D*>(aWgt);
       if (aPnt2dWgt) {
@@ -420,7 +429,7 @@ void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation)
           std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::END_ID()));
         if (aPoint) {
           aPnt2dWgt->setPoint(aPoint->x(), aPoint->y());
-          PartSet_Tools::setConstraints(mySketchMgr->activeSketch(), theOperation->feature(), 
+          PartSet_Tools::setConstraints(mySketchMgr->activeSketch(), aFOperation->feature(), 
             aWgt->attributeID(), aPoint->x(), aPoint->y());
           aPanel->activateNextWidget(aPnt2dWgt);
         }
index 3840be472092176c6f2292deb2c92c32a67ee50e..0bea2148a29ec20002f796e62c54e3d36e8b3332 100644 (file)
@@ -29,6 +29,7 @@
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_IViewWindow.h>
 #include <ModuleBase_Operation.h>
+#include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_Operation.h>
@@ -207,11 +208,13 @@ void PartSet_SketcherMgr::onEnterViewPort()
   // not accept a signal about the result created. Nothing is shown until mouse is moved out/in view
   // port. If the isDisplayed flag is true, the presentable feature is displayed as soon as the
   // presentation becomes valid and redisplay happens
-  ModuleBase_Operation* aOperation = getCurrentOperation();
-  if (aOperation) {
-    FeaturePtr aFeature = aOperation->feature();
+  //ModuleBase_Operation* aOperation = getCurrentOperation();
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                           (getCurrentOperation());
+  if (aFOperation) {
+    FeaturePtr aFeature = aFOperation->feature();
     if (aFeature.get() && aFeature->data()->isValid()) {
-      visualizeFeature(aOperation, canDisplayObject(aFeature), false);
+      visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature), false);
     }
   }
 }
@@ -254,8 +257,12 @@ void PartSet_SketcherMgr::onLeaveViewPort()
   // hides the presentation of the current operation feature
   // 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)
-  FeaturePtr aFeature = getCurrentOperation()->feature();
-  visualizeFeature(aOperation, canDisplayObject(aFeature));
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                           (getCurrentOperation());
+  if (aFOperation) {
+    FeaturePtr aFeature = aFOperation->feature();
+    visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
+  }
 }
 
 void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
@@ -297,11 +304,14 @@ void PartSet_SketcherMgr::onValuesChangedInPropertyPanel()
   // visualize the current operation feature
   myIsResetCurrentValue = false;
   operationMgr()->onValidateOperation();
-  ModuleBase_Operation* aOperation = getCurrentOperation();
   // 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)
-  FeaturePtr aFeature = getCurrentOperation()->feature();
-  visualizeFeature(aOperation, canDisplayObject(aFeature));
+  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)
@@ -320,9 +330,13 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
   if (!aViewer->canDragByMouse())
     return;
 
-  ModuleBase_Operation* aOperation = getCurrentOperation();
-  if (aOperation && aOperation->isEditOperation()) {
-    ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                               (getCurrentOperation());
+  if (!aFOperation)
+    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()) {
@@ -331,18 +345,18 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
   }
 
   // Use only for sketch operations
-  if (aOperation && myCurrentSketch) {
+  if (myCurrentSketch) {
     if (!PartSet_Tools::sketchPlane(myCurrentSketch))
       return;
 
-    bool isSketcher = isSketchOperation(aOperation);
-    bool isSketchOpe = isNestedSketchOperation(aOperation);
+    bool isSketcher = isSketchOperation(aFOperation);
+    bool isSketchOpe = isNestedSketchOperation(aFOperation);
 
     // Avoid non-sketch operations
     if ((!isSketchOpe) && (!isSketcher))
       return;
 
-    bool isEditing = aOperation->isEditOperation();
+    bool isEditing = aFOperation->isEditOperation();
 
     // Ignore creation sketch operation
     if ((!isSketcher) && (!isEditing))
@@ -360,8 +374,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
     if (myCurrentSelection.empty()) {
       if (isSketchOpe && (!isSketcher))
         // commit previous operation
-        if (!aOperation->commit())
-          aOperation->abort();
+        if (!aFOperation->commit())
+          aFOperation->abort();
       return;
     }
     // Init flyout point for radius rotation
@@ -385,7 +399,7 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       }
     } else if (isSketchOpe && isEditing) {
       // If selected another object commit current result
-      aOperation->commit();
+      aFOperation->commit();
 
       myIsDragging = true;
       get2dPoint(theWnd, theEvent, myCurrentPoint);
@@ -450,8 +464,12 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     }
     // 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)
-    FeaturePtr aFeature = getCurrentOperation()->feature();
-    visualizeFeature(aOperation, canDisplayObject(aFeature));
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                             (getCurrentOperation());
+    if (aFOperation) {
+      FeaturePtr aFeature = aFOperation->feature();
+      visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
+    }
   }
 
   myClickedPoint.clear();
@@ -549,13 +567,14 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
 
 void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
 {
-  ModuleBase_Operation* aOperation = getCurrentOperation();
-  if (aOperation && aOperation->isEditOperation()) {
-    std::string aId = aOperation->id().toStdString();
-    if (isDistanceOperation(aOperation))
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                               (getCurrentOperation());
+  if (aFOperation && aFOperation->isEditOperation()) {
+    std::string aId = aFOperation->id().toStdString();
+    if (isDistanceOperation(aFOperation))
     {
       // Activate dimension value editing on double click
-      ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+      ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
       QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
       // Find corresponded widget to activate value editing
       foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
@@ -700,7 +719,9 @@ bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOpera
 
 bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation)
 {
-  return theOperation && !theOperation->isEditOperation() && isNestedSketchOperation(theOperation);
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                               (theOperation);
+  return aFOperation && !aFOperation->isEditOperation() && isNestedSketchOperation(aFOperation);
 }
 
 bool PartSet_SketcherMgr::isEntity(const std::string& theId)
@@ -723,10 +744,15 @@ bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation
 
 void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
 {
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                               (getCurrentOperation());
+  if (!aFOperation)
+    return;
+
   myModule->onViewTransformed();
 
   // Display all sketcher sub-Objects
-  myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theOperation->feature());
+  myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
 
   // Hide sketcher result
@@ -755,7 +781,7 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
 
   bool aHasPlane = false;
   std::shared_ptr<GeomAPI_Pln> aPln;
-  if (theOperation->isEditOperation()) {
+  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())
@@ -766,11 +792,11 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
   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 (theOperation->isEditOperation() && aHasPlane)
+  if (aFOperation->isEditOperation() && aHasPlane)
     aConnector->activateModuleSelectionModes();
 }
 
-void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
+void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation*/* theOperation*/)
 {
   myIsMouseOverWindow = false;
   myIsConstraintsShown = true;
@@ -848,11 +874,15 @@ void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOp)
 void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
 {
   if (isNestedCreateOperation(theOperation)) {
-    FeaturePtr aFeature = theOperation->feature();
-    // it is necessary to check the the feature data validity because
-    // some kind of features are removed by an operation commit(the macro state of a feature)
-    if (aFeature.get() && aFeature->data()->isValid()) {
-      visualizeFeature(theOperation, true);
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                             (theOperation);
+    if (aFOperation) {
+      FeaturePtr aFeature = aFOperation->feature();
+      // it is necessary to check the the feature data validity because
+      // some kind of features are removed by an operation commit(the macro state of a feature)
+      if (aFeature.get() && aFeature->data()->isValid()) {
+        visualizeFeature(aFeature, aFOperation->isEditOperation(), true);
+      }
     }
   }
 }
@@ -906,9 +936,10 @@ bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
   // 3. the method should not filter the objects, which are not related to the current operation.
   // The object is filtered just if it is a current operation feature or this feature result
   bool isObjectFound = false;
-  ModuleBase_Operation* anOperation = getCurrentOperation();
-  if (anOperation) {
-    FeaturePtr aFeature = anOperation->feature();
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                               (getCurrentOperation());
+  if (aFOperation) {
+    FeaturePtr aFeature = aFOperation->feature();
     if (aFeature.get()) {
       std::list<ResultPtr> aResults = aFeature->results();
       if (theObject == aFeature)
@@ -1125,7 +1156,8 @@ ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const
   return myModule->workshop()->currentOperation();
 }
 
-void PartSet_SketcherMgr::visualizeFeature(ModuleBase_Operation* theOperation,
+void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature,
+                                           const bool isEditOperation,
                                            const bool isToDisplay,
                                            const bool isFlushRedisplay)
 {
@@ -1133,7 +1165,7 @@ void PartSet_SketcherMgr::visualizeFeature(ModuleBase_Operation* theOperation,
   return;
   #endif
 
-  if (!theOperation || theOperation->isEditOperation())
+  if (isEditOperation || !theFeature.get())
     return;
 
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
@@ -1141,12 +1173,12 @@ void PartSet_SketcherMgr::visualizeFeature(ModuleBase_Operation* theOperation,
 
   // 1. change visibility of the object itself, here the presentable object is processed,
   // e.g. constraints features
-  FeaturePtr aFeature = theOperation->feature();
-  std::list<ResultPtr> aResults = aFeature->results();
+  //FeaturePtr aFeature = aFOperation->feature();
+  std::list<ResultPtr> aResults = theFeature->results();
   if (isToDisplay)
-    aFeature->setDisplayed(true);
+    theFeature->setDisplayed(true);
   else
-    aFeature->setDisplayed(false);
+    theFeature->setDisplayed(false);
 
   // change visibility of the object results, e.g. non-constraint features
   std::list<ResultPtr>::const_iterator aIt;
index fea62f8e8978c8a9976dd6c29b3cc61da5f1e091..e108ff9997c949eafbed24ed28ff3139ffc97bd5 100644 (file)
@@ -265,8 +265,8 @@ private:
   /// a current value is changed by property panel, the feature is displayed otherwise it is hidden
   /// \param theOperation an operation which feature is to be displayed, it is nested create operation
   /// \param isToDisplay a flag about the display or erase the feature
-  void visualizeFeature(ModuleBase_Operation* theOperation, const bool isToDisplay,
-                        const bool isFlushRedisplay = true);
+  void visualizeFeature(const FeaturePtr& theFeature, const bool isEditOperation,
+                        const bool isToDisplay, const bool isFlushRedisplay = true);
 private:
   /// Gives a debug information about internal flags myIsMouseOverWindow and myIsResetCurrentValue
   /// \return a string value
index 20d602a3a69c37500683591fc5e08a04de078038..9781f9cf8ca1aabbc1c890ac32a006856162793d 100644 (file)
@@ -26,6 +26,7 @@
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_OperationFeature.h>
 #include <Config_WidgetAPI.h>
 
 #include <QLabel>
@@ -118,9 +119,11 @@ void PartSet_WidgetSketchCreator::onStarted()
       std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
     FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
 
-    ModuleBase_Operation* anOperation = myModule->createOperation("Sketch");
-    anOperation->setFeature(aSketch);
-    myModule->sendOperation(anOperation);
+    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
index fd872f417f40943bbbddddd99ee8948127f39328..542e1b5e4979febf30f10433af2c16026c7eb5ec 100644 (file)
@@ -20,6 +20,7 @@
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Validator.h>
 #include <ModuleBase_Operation.h>
+#include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_SelectionValidator.h>
 
 
@@ -95,15 +96,16 @@ bool XGUI_ActionsMgr::isNested(const QString& theId) const
 void XGUI_ActionsMgr::update()
 {
   FeaturePtr anActiveFeature = FeaturePtr();
-  if (myOperationMgr->hasOperation()) {
-    ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
-    anActiveFeature = anOperation->feature();
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                         (myOperationMgr->currentOperation());
+  if (aFOperation) {
+    anActiveFeature = aFOperation->feature();
     if(anActiveFeature.get()) {
       setAllEnabled(false);
       QString aFeatureId = QString::fromStdString(anActiveFeature->getKind());
       setActionEnabled(aFeatureId, true);
     }
-    setNestedStackEnabled(anOperation);
+    setNestedStackEnabled(aFOperation);
   } else {
     setAllEnabled(true);
     setNestedCommandsEnabled(false);
@@ -315,9 +317,10 @@ void XGUI_ActionsMgr::setNestedCommandsEnabled(bool theEnabled, const QString& t
 
 void XGUI_ActionsMgr::setNestedStackEnabled(ModuleBase_Operation* theOperation)
 {
-  if(!theOperation || !theOperation->feature())
+  ModuleBase_OperationFeature* anOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if(!anOperation || !anOperation->feature())
     return;
-  FeaturePtr aFeature = theOperation->feature();
+  FeaturePtr aFeature = anOperation->feature();
   QString aFeatureId = QString::fromStdString(aFeature->getKind());
   setActionEnabled(aFeatureId, true);
   setNestedCommandsEnabled(true, aFeatureId);
index 9dda1abbb0ed1f23d7eaa6c83ce2a42eac9b1ebc..500452a44d0ebdb8921d756ec7210cb497bffd95 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_ModelWidget.h>
+#include <ModuleBase_OperationFeature.h>
 
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_Session.h>
@@ -45,14 +46,15 @@ const char* toString(ModelAPI_ExecState theExecState)
 void XGUI_ErrorMgr::onValidationStateChanged()
 {
   XGUI_OperationMgr* anOperationMgr = dynamic_cast<XGUI_OperationMgr*>(sender());
-  if (!anOperationMgr || !anOperationMgr->currentOperation())
+  if (!anOperationMgr)
     return;
-
-  if (!myPropertyPanel)
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                  (anOperationMgr->currentOperation());
+  if (!myPropertyPanel || !aFOperation)
     return;
 
   // get feature
-  FeaturePtr aFeature = anOperationMgr->currentOperation()->feature();
+  FeaturePtr aFeature = aFOperation->feature();
   if (!aFeature.get() || !aFeature->data()->isValid())
     return;
 
index fe2b72830ae95b4697dcf0850139e3788beb8bdc..52826dc65b0f20801353c2328c4055d229bb05bd 100644 (file)
@@ -10,6 +10,7 @@
 #include "ModuleBase_IWorkshop.h"
 #include "ModuleBase_IModule.h"
 #include "ModuleBase_OperationDescription.h"
+#include "ModuleBase_OperationFeature.h"
 
 #include "ModelAPI_CompositeFeature.h"
 #include "ModelAPI_Session.h"
@@ -74,9 +75,12 @@ QStringList XGUI_OperationMgr::operationList() const
 {
   QStringList result;
   foreach(ModuleBase_Operation* eachOperation, myOperations) {
-    FeaturePtr aFeature = eachOperation->feature();
-    if(aFeature) {
-      result << QString::fromStdString(aFeature->getKind());
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(eachOperation);
+    if (aFOperation) {
+      FeaturePtr aFeature = aFOperation->feature();
+      if(aFeature) {
+        result << QString::fromStdString(aFeature->getKind());
+      }
     }
   }
   return result;
@@ -158,12 +162,16 @@ bool XGUI_OperationMgr::commitAllOperations()
     } else {
       abortOperation(anOperation);
     }
-    FeaturePtr aFeature = anOperation->feature();
-    CompositeFeaturePtr aComposite = 
-        std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
-    isCompositeCommitted = aComposite.get();
-    if (isCompositeCommitted)
-      break;
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                            (anOperation);
+    if (aFOperation) {
+      FeaturePtr aFeature = aFOperation->feature();
+      CompositeFeaturePtr aComposite = 
+          std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+      isCompositeCommitted = aComposite.get();
+      if (isCompositeCommitted)
+        break;
+    }
   }
   return true;
 }
index a66f445985eee738a49c90c4f3aa82fdfa00345f..fc0a66630fd19017f50570052b5cf7af93a00143 100644 (file)
@@ -62,6 +62,7 @@
 #include <ModuleBase_SelectionValidator.h>
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_WidgetFactory.h>
+#include <ModuleBase_OperationFeature.h>
 
 #include <Config_Common.h>
 #include <Config_FeatureMessage.h>
@@ -376,24 +377,29 @@ void XGUI_Workshop::onOperationStarted(ModuleBase_Operation* theOperation)
 {
   setNestedFeatures(theOperation);
 
-  if (theOperation->getDescription()->hasXmlRepresentation()) {  //!< No need for property panel
-    setPropertyPanel(theOperation);
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                               (theOperation);
+  if (!aFOperation)
+    return;
+
+  if (aFOperation->getDescription()->hasXmlRepresentation()) {  //!< No need for property panel
+    setPropertyPanel(aFOperation);
     // filling the operation values by the current selection
     // if the operation can be commited after the controls filling, the method perform should
     // be stopped. Otherwise unnecessary presentations can be shown(e.g. operation prs in sketch)
-    if (!theOperation->isEditOperation()) {
-      theOperation->activateByPreselection();
-      if (operationMgr()->currentOperation() != theOperation)
+    if (!aFOperation->isEditOperation()) {
+      aFOperation->activateByPreselection();
+      if (operationMgr()->currentOperation() != aFOperation)
         return;
     }
   }
   updateCommandStatus();
 
-  myModule->onOperationStarted(theOperation);
+  myModule->onOperationStarted(aFOperation);
 
   // the objects of the current operation should be deactivated
   QObjectPtrList anObjects;
-  FeaturePtr aFeature = theOperation->feature();
+  FeaturePtr aFeature = aFOperation->feature();
   anObjects.append(aFeature);
   std::list<ResultPtr> aResults = aFeature->results();
   std::list<ResultPtr>::const_iterator aIt;
@@ -424,6 +430,11 @@ void XGUI_Workshop::onOperationResumed(ModuleBase_Operation* theOperation)
 //******************************************************
 void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
 {
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                        (theOperation);
+  if (!aFOperation)
+    return;
+
   ModuleBase_ISelection* aSel = mySelector->selection();
   QObjectPtrList aObj = aSel->selectedPresentations();
   //!< No need for property panel
@@ -431,12 +442,12 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
   hidePropertyPanel();
   myPropertyPanel->cleanContent();
 
-  myModule->onOperationStopped(theOperation);
+  myModule->onOperationStopped(aFOperation);
 
   // the deactivated objects of the current operation should be activated back.
   // They were deactivated on operation start or an object redisplay
   QObjectPtrList anObjects;
-  FeaturePtr aFeature = theOperation->feature();
+  FeaturePtr aFeature = aFOperation->feature();
   if (myDisplayer->isVisible(aFeature) && !myDisplayer->isActive(aFeature))
     anObjects.append(aFeature);
   std::list<ResultPtr> aResults = aFeature->results();
@@ -465,16 +476,24 @@ void XGUI_Workshop::onOperationAborted(ModuleBase_Operation* theOperation)
 
 void XGUI_Workshop::setNestedFeatures(ModuleBase_Operation* theOperation)
 {
-  if (this->isSalomeMode()) 
-    theOperation->setNestedFeatures(mySalomeConnector->nestedActions(theOperation->id()));
-  else 
-    theOperation->setNestedFeatures(myActionsMgr->nestedCommands(theOperation->id()));
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if (!aFOperation)
+    return;
+
+  if (isSalomeMode()) 
+    aFOperation->setNestedFeatures(mySalomeConnector->nestedActions(theOperation->id()));
+  else
+    aFOperation->setNestedFeatures(myActionsMgr->nestedCommands(theOperation->id()));
 }
 
 void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
 {
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if (!aFOperation)
+    return;
+
   showPropertyPanel();
-  QString aXmlRepr = theOperation->getDescription()->xmlRepresentation();
+  QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation();
   ModuleBase_WidgetFactory aFactory = ModuleBase_WidgetFactory(aXmlRepr.toStdString(),
                                                                 myModuleConnector);
 
@@ -483,15 +502,15 @@ void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
 
   QList<ModuleBase_ModelWidget*> aWidgets = aFactory.getModelWidgets();
   foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
-    bool isStoreValue = !theOperation->isEditOperation() &&
+    bool isStoreValue = !aFOperation->isEditOperation() &&
                         !aWidget->getDefaultValue().empty() &&
                         !aWidget->isComputedDefault();
-    aWidget->setFeature(theOperation->feature(), isStoreValue);
+    aWidget->setFeature(aFOperation->feature(), isStoreValue);
     aWidget->enableFocusProcessing();
   }
   
   myPropertyPanel->setModelWidgets(aWidgets);
-  theOperation->setPropertyPanel(myPropertyPanel);
+  aFOperation->setPropertyPanel(myPropertyPanel);
 
   myModule->propertyPanelDefined(theOperation);
 
@@ -1530,9 +1549,9 @@ QList<ActionInfo> XGUI_Workshop::processHistoryList(const std::list<std::string>
   std::list<std::string>::const_iterator it = theList.cbegin();
   for (; it != theList.cend(); it++) {
     QString anId = QString::fromStdString(*it);
-    bool isEditing = anId.endsWith(ModuleBase_Operation::EditSuffix());
+    bool isEditing = anId.endsWith(ModuleBase_OperationFeature::EditSuffix());
     if (isEditing) {
-      anId.chop(ModuleBase_Operation::EditSuffix().size());
+      anId.chop(ModuleBase_OperationFeature::EditSuffix().size());
     }
     ActionInfo anInfo;
     QAction* aContextMenuAct = myContextMenuMgr->actionByName(anId);
index b55879faef8597bb03611983a10cfa6cb7942ee6..be913ac98bcff86a0de81f28ff9c4a8a842dd979 100755 (executable)
@@ -37,6 +37,7 @@
 
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_OperationDescription.h>
+#include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_IViewer.h>
 #include <ModuleBase_FilterFactory.h>
@@ -154,7 +155,9 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr<Events_Message>&
     XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
 
     if (anOperationMgr->startOperation(anOperation)) {
-      workshop()->propertyPanel()->updateContentWidget(anOperation->feature());
+      ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(anOperation);
+      if (aFOperation)
+        workshop()->propertyPanel()->updateContentWidget(aFOperation->feature());
       if (!anOperation->getDescription()->hasXmlRepresentation()) {
         if (anOperation->commit())
           workshop()->updateCommandStatus();
@@ -196,18 +199,23 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr<Events_Message>&
 }
 
 //******************************************************
-void XGUI_WorkshopListener::onFeatureUpdatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
+void XGUI_WorkshopListener::onFeatureUpdatedMsg(
+                                     const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
 {
   std::set<ObjectPtr> aFeatures = theMsg->objects();
   XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
   if (anOperationMgr->hasOperation()) {
-    FeaturePtr aCurrentFeature = anOperationMgr->currentOperation()->feature();
-    std::set<ObjectPtr>::const_iterator aIt;
-    for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) {
-      ObjectPtr aNewFeature = (*aIt);
-      if (aNewFeature == aCurrentFeature) {
-        workshop()->propertyPanel()->updateContentWidget(aCurrentFeature);
-        break;
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                      (anOperationMgr->currentOperation());
+    if (aFOperation) {
+      FeaturePtr aCurrentFeature = aFOperation->feature();
+      std::set<ObjectPtr>::const_iterator aIt;
+      for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) {
+        ObjectPtr aNewFeature = (*aIt);
+        if (aNewFeature == aCurrentFeature) {
+          workshop()->propertyPanel()->updateContentWidget(aCurrentFeature);
+          break;
+        }
       }
     }
   }