Salome HOME
Methods for starting, suspending, aborting (etc) operation added. Now if operation...
authorsln <sln@opencascade.com>
Tue, 23 Aug 2005 08:24:07 +0000 (08:24 +0000)
committersln <sln@opencascade.com>
Tue, 23 Aug 2005 08:24:07 +0000 (08:24 +0000)
src/SUIT/SUIT_Study.cxx
src/SUIT/SUIT_Study.h

index a2679a5f5c4e2e02cb7d3747250cca6e6add7a15..9c2af0282d394045b990ba003b537826bd85eecb 100755 (executable)
@@ -5,6 +5,7 @@
 #include "SUIT_DataObject.h"
 #include "SUIT_MessageBox.h"
 #include "SUIT_Application.h"
+#include <qvaluevector.h>
 
 /*!\class SUIT_Study
  * Support study management. Object management. Operation management.
@@ -16,7 +17,8 @@ SUIT_Study::SUIT_Study( SUIT_Application* app )
 myApp( app ),
 myIsSaved( false ),
 myIsModified( false ),
-myName( "" )
+myName( "" ),
+myBlockChangeState( false )
 {
   static int _id = 0;
 
@@ -24,6 +26,10 @@ myName( "" )
 
   myRoot = new SUIT_DataObject();
   myOperations.setAutoDelete( false );
+
+  connect( this, SIGNAL( changeOperationState( bool ) ), this, SLOT( onChangeOperationState( bool ) ) );
+
+  myOperations.setAutoDelete( false );
 }
 
 /*!Destructor.*/
@@ -70,7 +76,7 @@ QString SUIT_Study::studyName() const
  */
 SUIT_Operation* SUIT_Study::activeOperation() const
 {
-  return myOperations.current();
+  return myOperations.count() > 0 ? myOperations.getLast() : 0;
 }
 
 /*!
@@ -140,12 +146,11 @@ bool SUIT_Study::saveDocument()
  */
 void SUIT_Study::abortAllOperations()
 {
-  SUIT_Operation* aOperation = 0;
-  while ( aOperation = myOperations.current() )
-  {
-    aOperation->abort();
-    myOperations.pop();
-  }
+  myBlockChangeState = true;
+  for( SUIT_Operation* op = myOperations.first(); op; op = myOperations.next() )
+    op->abort();
+  myBlockChangeState = false;
+  myOperations.clear();
 }
 
 /*!
@@ -200,45 +205,214 @@ void SUIT_Study::setStudyName( const QString& name )
 }
 
 /*!
-  Stop operation.
- */
-void SUIT_Study::stopOperation()
+ * \brief Verifies whether operation can be activated above already started ones
+  * \param theOp - operation to be checked
+  * \return NULL if operation can be activated, pointer to operation which denies
+  * starting tested operation
+*
+* Verifies whether operation can be activated above already started ones. This method
+* is called from SUIT_Study::start() and SUIT_Study::resume() methods.
+*/
+SUIT_Operation* SUIT_Study::blockingOperation( SUIT_Operation* theOp ) const
 {
-  myOperations.pop();
-  if ( myOperations.current() )
-    myOperations.current()->resume();
-  myIsModified = true;
+  if( theOp->isGranted() )
+    return 0;
+
+  Operations tmpOps( myOperations );
+  SUIT_Operation* anOp = 0;
+  for ( anOp = tmpOps.last(); anOp; anOp = tmpOps.prev() )
+  {
+    if ( anOp != 0 && anOp!= theOp && !anOp->isValid( theOp ) )
+      return anOp;
+  }
+
+  return 0;
 }
 
 /*!
- * Set can start operation \a theOperation.
- *\retval FALSE - if can't start.
- */
-bool SUIT_Study::canStartOperation( SUIT_Operation* theOperation )
+ * \brief Starts operation
+  * \param theOp - operation to be started
+  * \param toCheck - if parameters is equal TRUE then checking performed whether
+  * all already started operations allow to start this operation above them (default
+  * value is TRUE
+  * \return TRUE if operation is started, FALSE otherwise
+*
+* Verifies whether theOp operation can be started above already started ones (if toCheck
+* parameter is equal TRUE) and starts it
+*/
+bool SUIT_Study::start( SUIT_Operation* theOp, const bool toCheck )
 {
-  SUIT_Operation* anActiveOperation = (SUIT_Operation*)activeOperation();
-  if ( anActiveOperation )
+  if ( !theOp || myOperations.find( theOp ) >= 0 )
+    return false;
+
+  theOp->setExecStatus( SUIT_Operation::Rejected );
+  theOp->setStudy( this );
+
+  if ( !theOp->isReadyToStart() )
+    return false;
+
+  if ( toCheck )
   {
-    if ( !theOperation->isGranted() )
+    while( SUIT_Operation* anOp = blockingOperation( theOp ) )
     {
-      if ( !anActiveOperation->isValid( theOperation ) )
-      {
-        // Ask user about existing operation
-        int anAnsw = SUIT_MessageBox::warn2( application()->desktop(), tr( "Operation launch" ), 
-                                             tr( "Previous operation is not finished and will be aborted." ),
-                                             tr( "Continue" ), tr( "Cancel" ), 0, 1, 1 );
-        if ( anAnsw == 1 )
-          return false;
-
-        anActiveOperation->abort();
-        myOperations.pop();
-        myOperations.push( theOperation );
-        return true;
-      }
+      int anAnsw = SUIT_MessageBox::warn2( application()->desktop(),
+         tr( "OPERATION_LAUNCH" ), tr( "PREVIOUS_NOT_FINISHED" ),
+         tr( "CONTINUE" ), tr( "CANCEL" ), 0, 1, 1 );
+
+      if( anAnsw == 1 )
+        return false;
+      else
+        anOp->abort();
     }
-    anActiveOperation->suspend();
   }
-  myOperations.push( theOperation );
 
+  SUIT_Operation* anOp = activeOperation();
+  if ( anOp )
+  {
+    activeOperation()->suspendOperation();
+    anOp->setState( SUIT_Operation::Suspended );
+  }
+
+  theOp->setState( SUIT_Operation::Running );
+  myOperations.append( theOp );
+  emit theOp->started( theOp );
+  theOp->startOperation();
+  
+  return true;
+}
+
+/*!
+ * \brief Aborts operation
+  * \param theOp - operation to be aborted
+  * \return TRUE if operation is aborted successfully
+*
+* Verifies whether operation already started and aborts it in this case (sets execution
+* status to Rejected and stops operation)
+*/
+bool SUIT_Study::abort( SUIT_Operation* theOp )
+{
+  if ( !theOp || myOperations.find( theOp ) == -1 )
+    return false;
+
+  theOp->abortOperation();
+  theOp->setExecStatus( SUIT_Operation::Rejected );
+  emit theOp->aborted( theOp );
+  stop( theOp );
+  return true;
+}
+
+/*!
+ * \brief Commits operation
+  * \param theOp - operation to be committed
+  * \return TRUE if operation is committed successfully
+*
+* Verifies whether operation already started and commits it in this case (sets execution
+* status to Accepted and stops operation)
+*/
+bool SUIT_Study::commit( SUIT_Operation* theOp )
+{
+  if ( !theOp || myOperations.find( theOp ) == -1 )
+    return false;
+
+  theOp->commitOperation();
+  theOp->setExecStatus( SUIT_Operation::Accepted );
+  emit theOp->committed( theOp );
+  stop( theOp );
+  emit studyModified( this );
+  return true;
+}
+
+/*!
+ * \brief Commits operation
+  * \param theOp - operation to be committed
+  * \return TRUE if operation is suspended successfully
+*
+* Verifies whether operation already started and suspends it in this case. Operations
+* ususlly are suspended to start other one above them.
+*/
+bool SUIT_Study::suspend( SUIT_Operation* theOp )
+{
+  if ( !theOp || myOperations.find( theOp ) == -1 || theOp->state() == SUIT_Operation::Suspended )
+    return false;
+
+  theOp->setState( SUIT_Operation::Suspended );
+  theOp->suspendOperation();
+  emit theOp->suspended( theOp );
   return true;
 }
+
+
+/*!
+ * \brief Resumes operation
+  * \param theOp - operation to be resumed
+  * \return TRUE if operation is aborted successfully
+*
+* Verifies whether operation already started but suspended and resumesit in this case.
+*/
+bool SUIT_Study::resume( SUIT_Operation* theOp )
+{
+  if ( !theOp || myOperations.find( theOp ) == -1 ||
+       theOp->state() == SUIT_Operation::Running ||
+       blockingOperation( theOp ) != 0 )
+    return false;
+
+  if ( myOperations.count() > 0 )
+    suspend( myOperations.last() );
+
+  theOp->setState( SUIT_Operation::Running );
+  theOp->resumeOperation();
+
+  // Move operation at the end of list in order to sort it in the order of activation.
+  // As result active operation is a last operation of list, operation which was active
+  // before currently active operation is located before it and so on
+  myOperations.remove( theOp );
+  myOperations.append( theOp );
+
+  emit theOp->resumed( theOp );
+  return true;
+}
+
+/*!
+ * \brief Stops operation
+  * \param theOp - operation to be stopped
+*
+* Stops operation. This private method is called from abort() and commit() ones to perform
+* common actions when operation is stopped
+*/
+void SUIT_Study::stop( SUIT_Operation* theOp )
+{
+  theOp->setState( SUIT_Operation::Waiting );
+  myOperations.remove( theOp );
+
+  // get last operation which can be resumed
+  SUIT_Operation* anOp, *aResultOp = 0;
+  for( anOp = myOperations.last(); anOp; anOp = myOperations.prev() )
+    if ( anOp && anOp != theOp && blockingOperation( anOp ) == 0 )
+    {
+      aResultOp = anOp;
+      break;
+    }
+
+  emit theOp->stopped( theOp );
+  if ( aResultOp )
+    resume( aResultOp );
+}
+
+/*!
+ * \brief Get all started operations
+  * \return List of all started operations
+*/
+const QPtrList<SUIT_Operation>& SUIT_Study::operations() const
+{
+  return myOperations;
+}
+
+
+
+
+
+
+
+
+
+
index 58d311eea6bdaaf57bed2d42dc5d6b7ab03a61f7..bd1f419c8b2337b1844d22b03df8b5adcd6fba37 100755 (executable)
@@ -6,10 +6,11 @@
 #include "SUIT_Operation.h"
 
 #include <qobject.h>
-#include <qptrstack.h>
+#include <qptrlist.h>
 
 class SUIT_DataObject;
 class SUIT_Application;
+class QDialog;
 
 #ifdef WIN32
 #pragma warning( disable:4251 )
@@ -18,6 +19,7 @@ class SUIT_Application;
 class SUIT_EXPORT SUIT_Study : public QObject
 {
   Q_OBJECT
+  
 public:
   SUIT_Study( SUIT_Application* );
   virtual ~SUIT_Study();
@@ -27,7 +29,6 @@ public:
   SUIT_DataObject*  root() const;
   QString           studyName() const;
   SUIT_Application* application() const;
-  SUIT_Operation*   activeOperation() const;
 
   virtual bool      isSaved()  const;
   virtual bool      isModified() const;
@@ -39,12 +40,23 @@ public:
   bool              saveDocument();
   virtual bool      saveDocumentAs( const QString& );
 
-  virtual void      abortAllOperations();
-
   virtual void      update();
 
   virtual void      sendChangesNotification();
 
+  // Operation management
+  SUIT_Operation*   activeOperation() const;
+  virtual void      abortAllOperations();
+  const QPtrList<SUIT_Operation>& operations() const;
+  
+  virtual SUIT_Operation* blockingOperation( SUIT_Operation* ) const;
+
+  bool              start( SUIT_Operation*, const bool check = true );
+  bool              abort( SUIT_Operation* );
+  bool              commit( SUIT_Operation* );
+  bool              suspend( SUIT_Operation* );
+  bool              resume( SUIT_Operation* );
+
 signals:
   void              studyModified( SUIT_Study* );
 
@@ -54,14 +66,9 @@ protected:
   virtual void      setRoot( SUIT_DataObject* );
   virtual void      setStudyName( const QString& );
 
-  void              stopOperation();
-  bool              canStartOperation( SUIT_Operation* );
-
-protected:
-  typedef QPtrStack<SUIT_Operation> OperationsStack;
-
-protected:
-  OperationsStack   myOperations;
+private:
+  typedef QPtrList<SUIT_Operation> Operations;
+  void              stop( SUIT_Operation* );
 
 private:
   int               myId;
@@ -70,8 +77,8 @@ private:
   QString           myName;
   bool              myIsSaved;
   bool              myIsModified;
-
-  friend class SUIT_Operation;
+  Operations        myOperations;
+  bool              myBlockChangeState;
 };
 
 #ifdef WIN32