Salome HOME
Providing Action class to have a common approach to start/finish/abort model transact...
authornds <nds@opencascade.com>
Wed, 26 Aug 2015 18:38:55 +0000 (21:38 +0300)
committernds <nds@opencascade.com>
Wed, 26 Aug 2015 18:38:55 +0000 (21:38 +0300)
An action instance is used for Delete operation of sketch sub-entities.

12 files changed:
src/ModuleBase/ModuleBase_Operation.cpp
src/ModuleBase/ModuleBase_Operation.h
src/ModuleBase/ModuleBase_OperationAction.cpp
src/ModuleBase/ModuleBase_OperationAction.h
src/ModuleBase/ModuleBase_OperationFeature.cpp
src/ModuleBase/ModuleBase_OperationFeature.h
src/PartSet/PartSet_Module.cpp
src/XGUI/XGUI_ActionsMgr.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_WorkshopListener.cpp

index 4d54780f9941acda1717d3030d28b48f4efad6b7..009502dcb6f525c7076369ec593aff5780cfed70 100644 (file)
@@ -50,6 +50,26 @@ ModuleBase_Operation::~ModuleBase_Operation()
   delete myDescription;
 }
 
+const QStringList& ModuleBase_Operation::grantedOperationIds() const
+{
+  return myGrantedIds;
+}
+
+void ModuleBase_Operation::setGrantedOperationIds(const QStringList& theList)
+{
+  myGrantedIds = theList;
+}
+
+void ModuleBase_Operation::addGrantedOperationId(const QString& theId)
+{
+  myGrantedIds.append(theId);
+}
+
+void ModuleBase_Operation::removeGrantedOperationId(const QString& theId)
+{
+  myGrantedIds.removeAll(theId);
+}
+
 QString ModuleBase_Operation::id() const
 {
   return getDescription()->operationId();
@@ -65,39 +85,14 @@ bool ModuleBase_Operation::canBeCommitted() const
   return isValid();
 }
 
-
 void ModuleBase_Operation::start()
 {
   myIsModified = false;
-  /*
-  QString anId = getDescription()->operationId();
-  if (myIsEditing) {
-    anId = anId.append(EditSuffix());
-  }
-  ModelAPI_Session::get()->startOperation(anId.toStdString());
-
-  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);
-  }
+
+  ModelAPI_Session::get()->startOperation(id().toStdString());
 
   startOperation();
   emit started();
-*/
 }
 
 void ModuleBase_Operation::postpone()
@@ -114,75 +109,29 @@ 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>(
-      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.
-  if (myPropertyPanel)
-    myPropertyPanel->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();
+  //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);
 
-  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();
+  ModelAPI_Session::get()->abortOperation();
 
-  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);
+  //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_Operation::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.
-    if (myPropertyPanel)
-      myPropertyPanel->cleanContent();
-
+  if (canBeCommitted()) {
     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();
 
@@ -193,7 +142,6 @@ bool ModuleBase_Operation::commit()
     afterCommitOperation();
     return true;
   }
-*/
   return false;
 }
 
@@ -209,5 +157,5 @@ void ModuleBase_Operation::setPropertyPanel(ModuleBase_IPropertyPanel* theProp)
 
 bool ModuleBase_Operation::isGranted(QString theId) const
 {
-  return false;
+  return myGrantedIds.contains(theId);
 }
index 09b6257786cd4c10dcb9d1d5b1f4bcbc1047759a..01a351d1ddc19ed1ea0821057c22c2e242847b7c 100644 (file)
@@ -56,6 +56,21 @@ Q_OBJECT
   /// /returns the instance of the description class
   ModuleBase_OperationDescription* getDescription() const { return myDescription; }
 
+  /// Returns list of granted operation indices
+  const QStringList& grantedOperationIds() const;
+
+  /// Sets list of operation indices, which can be started without the current operation stop
+  /// \param theList an ids
+  void setGrantedOperationIds(const QStringList& theList);
+
+  /// Appends an operation index to be granted
+  /// \param theId an index
+  void addGrantedOperationId(const QString& theId);
+
+  /// Removes an operation index from the granted
+  /// \param theId an index
+  void removeGrantedOperationId(const QString& theId);
+
   /// 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.
@@ -168,6 +183,9 @@ private:
   /// Modified feature flag
   bool myIsModified;
 
+  /// List of operations IDs which are granted of the current operation
+  QStringList myGrantedIds;
+
   /// Access to property panel
   ModuleBase_IPropertyPanel* myPropertyPanel;
 };
index cabc64c79b5868272fbacd7eddc992aa5b33360a..19dda8a73709c9933637d173a18a06ff4b883c33 100755 (executable)
@@ -17,3 +17,11 @@ ModuleBase_OperationAction::ModuleBase_OperationAction(const QString& theId, QOb
 ModuleBase_OperationAction::~ModuleBase_OperationAction()
 {
 }
+
+bool ModuleBase_OperationAction::commit()
+{
+  // the action is supposed to perform a single modification, so the operation returns modified state
+  setIsModified(true);
+
+  return ModuleBase_Operation::commit();
+}
index 4667840b0e076436131a395e486fb8766ea390b2..3e9c283a956e4abb0d2f68f256dab783bc60586f 100755 (executable)
 /*!
  * \class ModuleBase_OperationAction
  * \ingroup GUI
- * \brief Base class for all operations
+ * \brief Base class for action 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
+ *  This is an action-like operation, which modifies the structure of data through
+ *  starting/comitting transactions in the document. This operations are single stepped,
+ *  and have no filled property panel, like Delete/Detach.
  */
 
 class MODULEBASE_EXPORT ModuleBase_OperationAction : public ModuleBase_Operation
@@ -31,13 +29,17 @@ 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();
+
+ public slots:
+  /// Commits the operation. Change is modified state to true value.
+  /// \return the result of commit
+  virtual bool commit();
 };
 
 #endif
index ff49f71454cfc80d42835df98295220ff4ca8d28..2c00e35430b5ae8278fd6df69a0ec090ecc03d95 100755 (executable)
@@ -348,8 +348,3 @@ void ModuleBase_OperationFeature::setPropertyPanel(ModuleBase_IPropertyPanel* th
     theProp->activateNextWidget(NULL);
   }
 }
-
-bool ModuleBase_OperationFeature::isGranted(QString theId) const
-{
-  return myNestedFeatures.contains(theId);
-}
index cc937e1a41017dc0a5f1cf4c7dbcee628920641a..dedbb6a16dd1683f9c898d564a4e966aded8829f 100755 (executable)
@@ -58,31 +58,15 @@ Q_OBJECT
   /// 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.
-  */
+  /// 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
@@ -154,9 +138,6 @@ signals:
   /// Editing feature flag
   bool myIsEditing;
 
-  /// List of nested operations IDs
-  QStringList myNestedFeatures;
-
   /// List of pre-selected object 
   QList<ModuleBase_ViewerPrs> myPreSelection;
 
index 54b88f25dabd3f1b09a47971950c32c531a479b1..23741dfbdc94ab6996f10fa8ddfdbb555ba5cf8d 100755 (executable)
@@ -25,6 +25,7 @@
 #include <PartSetPlugin_Duplicate.h>
 
 #include <ModuleBase_Operation.h>
+#include <ModuleBase_OperationAction.h>
 #include <ModuleBase_IViewer.h>
 #include <ModuleBase_IViewWindow.h>
 #include <ModuleBase_IPropertyPanel.h>
@@ -621,23 +622,26 @@ bool PartSet_Module::deleteObjects()
     if (aSketchObjects.size() == 0)
       return true;
 
-    // the active nested sketch operation should be aborted unconditionally
-    if (isNestedOp)
-      anOperation->abort();
-
     // 3. start operation
     QString aDescription = aWorkshop->contextMenuMgr()->action("DELETE_CMD")->text();
-    aMgr->startOperation(aDescription.toStdString());
+    ModuleBase_OperationAction* anAction = new ModuleBase_OperationAction(aDescription, this);
 
+    XGUI_OperationMgr* anOpMgr = aConnector->workshop()->operationMgr();
+    // the active nested sketch operation should be aborted unconditionally
+    if (isSketchOp)
+      anOperation->addGrantedOperationId(anAction->id());
+    if (!anOpMgr->canStartOperation(anAction->id()))
+      return true; // the objects are processed but can not be deleted
+    if (isSketchOp)
+      anOperation->removeGrantedOperationId(anAction->id());
+
+    anOpMgr->startOperation(anAction);
     // 4. delete features
     // sketch feature should be skipped, only sub-features can be removed
     // when sketch operation is active
     aWorkshop->deleteFeatures(aSketchObjects);
     // 5. stop operation
-    aWorkshop->displayer()->updateViewer();
-    aMgr->finishOperation();
-    XGUI_OperationMgr* anOpMgr = aConnector->workshop()->operationMgr();
-    anOpMgr->updateApplyOfOperations();
+    anOpMgr->commitOperation();
   } else {
     bool isPartRemoved = false;
     // Delete part with help of PartSet plugin
index 542e1b5e4979febf30f10433af2c16026c7eb5ec..32f7e4af556fdd5b49a985298734a12de3336b92 100644 (file)
@@ -271,7 +271,7 @@ QAction* XGUI_ActionsMgr::operationStateAction(OperationStateActionId theId, QOb
 
 QAction* XGUI_ActionsMgr::action(const QString& theId)
 {
-  QAction* anAction;
+  QAction* anAction = 0;
   if(myActions.contains(theId)) {
     anAction = myActions.value(theId);
   }
index 52826dc65b0f20801353c2328c4055d229bb05bd..259d3411d4aac5f85da5bcc76dc4cec6131f7ad1 100644 (file)
@@ -117,9 +117,11 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
   connect(theOperation, SIGNAL(committed()), SLOT(onOperationCommitted()));
   connect(theOperation, SIGNAL(stopped()), SLOT(onOperationStopped()));
   connect(theOperation, SIGNAL(resumed()), SLOT(onOperationResumed()));
-  connect(theOperation, SIGNAL(triggered(bool)), SLOT(onOperationTriggered(bool)));
-  connect(theOperation, SIGNAL(activatedByPreselection()),
-          SIGNAL(operationActivatedByPreselection()));
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                        (theOperation);
+  if (aFOperation)
+    connect(aFOperation, SIGNAL(activatedByPreselection()),
+            SIGNAL(operationActivatedByPreselection()));
 
   theOperation->start();
   onValidateOperation();
@@ -273,7 +275,7 @@ bool XGUI_OperationMgr::canStartOperation(QString theId)
   if (aCurrentOp) {
     if (!aCurrentOp->isGranted(theId)) {
       if (canStopOperation()) {
-        if (myIsApplyEnabled)
+        if (myIsApplyEnabled && aCurrentOp->isModified())
           aCurrentOp->commit();
         else
           abortOperation(aCurrentOp);
index 4c4514981cd20ac991ee9b02764e576bd9e8283e..48b6a7ea2927b4c54be8715cbda86274fd672d3d 100644 (file)
@@ -159,10 +159,10 @@ public: // TEMPORARY, it should be protected and be performed automatically
   /// \param theOperation the sent operation. If it is NULL, all operations in the stack are sent.
   void updateApplyOfOperations(ModuleBase_Operation* theOperation = 0);
 
-protected: // TEMPORARY
   /// Commits the current operatin if it is valid
   bool commitOperation();
 
+protected: // TEMPORARY
   /// Sets the current operation or NULL
   /// \param theOperation the started operation
   void resumeOperation(ModuleBase_Operation* theOperation);
index fc0a66630fd19017f50570052b5cf7af93a00143..facd2e4286158d34e5188b90cf52cc7e5b396f46 100644 (file)
@@ -480,10 +480,10 @@ void XGUI_Workshop::setNestedFeatures(ModuleBase_Operation* theOperation)
   if (!aFOperation)
     return;
 
-  if (isSalomeMode()) 
-    aFOperation->setNestedFeatures(mySalomeConnector->nestedActions(theOperation->id()));
+  if (isSalomeMode())
+    aFOperation->setGrantedOperationIds(mySalomeConnector->nestedActions(theOperation->id()));
   else
-    aFOperation->setNestedFeatures(myActionsMgr->nestedCommands(theOperation->id()));
+    aFOperation->setGrantedOperationIds(myActionsMgr->nestedCommands(theOperation->id()));
 }
 
 void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
index be913ac98bcff86a0de81f28ff9c4a8a842dd979..fcc927c3edcc1d758fc18309c4a96de9a29d3993 100755 (executable)
@@ -65,6 +65,9 @@ XGUI_WorkshopListener::XGUI_WorkshopListener(ModuleBase_IWorkshop* theWorkshop)
   : myWorkshop(theWorkshop),
     myUpdatePrefs(false)
 {
+  XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
+  connect(anOperationMgr, SIGNAL(nestedStateChanged(const std::string&, const bool)),
+          this, SLOT(onNestedStateChanged(const std::string&, const bool)));
 }
 
 //******************************************************
@@ -378,7 +381,8 @@ void XGUI_WorkshopListener::onNestedStateChanged(const std::string& theFeatureId
       anAcceptAllAction->setEnabled(theState);
   } else {
     AppElements_MainMenu* aMenuBar = aWorkshop->mainWindow()->menuObject();
-    if (aMenuBar->feature(theFeatureId.c_str())->button()->additionalButtonWidget())
+    AppElements_Command* aCommand = aMenuBar->feature(theFeatureId.c_str());
+    if (aCommand && aCommand->button()->additionalButtonWidget())
       anAcceptAllAction->setEnabled(theState);
   }
 }
@@ -475,9 +479,6 @@ void XGUI_WorkshopListener::addFeature(const std::shared_ptr<Config_FeatureMessa
     aWorkshop->actionsMgr()->addCommand(aCommand);
     aWorkshop->module()->actionCreated(aCommand);
   }
-  XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
-  connect(anOperationMgr, SIGNAL(nestedStateChanged(const std::string&, const bool)),
-          this, SLOT(onNestedStateChanged(const std::string&, const bool)));
 }