]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Activation of operators fixed
authorsln <sln@opencascade.com>
Fri, 8 Jul 2005 05:25:48 +0000 (05:25 +0000)
committersln <sln@opencascade.com>
Fri, 8 Jul 2005 05:25:48 +0000 (05:25 +0000)
src/SUIT/SUIT_Operation.cxx
src/SUIT/SUIT_Operation.h
src/SUIT/SUIT_Study.cxx
src/SUIT/SUIT_Study.h

index f7f34a623718ab79330d7d40c8148d9bad484da1..65c8c27072d4538e70f9fac13cf41c97787c3df4 100755 (executable)
@@ -1,8 +1,26 @@
+/**
+*  SALOME SalomeApp
+*
+*  Copyright (C) 2005  CEA/DEN, EDF R&D
+*
+*
+*
+*  File   : SUIT_Operation.h
+*  Author : Unknown
+*  Module : SALOME
+*/
+
 #include "SUIT_Operation.h"
 
 #include "SUIT_Study.h"
 #include "SUIT_Application.h"
+#include "SUIT_MessageBox.h"
+#include "SUIT_Desktop.h"
 
+//=======================================================================
+// name    : SUIT_Operation
+// Purpose : Constructor
+//=======================================================================
 SUIT_Operation::SUIT_Operation( SUIT_Application* app )
 : QObject(),
 myApp( app ),
@@ -15,126 +33,292 @@ SUIT_Operation::~SUIT_Operation()
 {
 }
 
+//=======================================================================
+// name    : study
+// Purpose : Gets operation study (i.e. study which starts this operation )
+//=======================================================================
 SUIT_Study* SUIT_Operation::study() const
 {
   return myStudy;
 }
 
+//=======================================================================
+// name    : setStudy
+// Purpose : Sets operation study (i.e. study which starts this operation )
+//=======================================================================
+void SUIT_Operation::setStudy( SUIT_Study* theStudy )
+{
+  myStudy = theStudy;
+}
+
+//=======================================================================
+// name    : application
+// Purpose : Returns application
+//=======================================================================
 SUIT_Application* SUIT_Operation::application() const
 {
   return myApp;
 }
 
+//=======================================================================
+// name    : setApplication
+// Purpose : Sets application
+//=======================================================================
+void SUIT_Operation::setApplication( SUIT_Application* theApp )
+{
+  myApp = theApp;
+}
+
+//=======================================================================
+// name    : state
+// Purpose : Returns state of operation (see OperationState enumeration)
+//=======================================================================
 SUIT_Operation::OperationState SUIT_Operation::state() const
 {
   return myState;
 }
 
+//=======================================================================
+// name    : setState
+// Purpose : Sets state of operation (see OperationState enumeration)
+//=======================================================================
+void SUIT_Operation::setState( const SUIT_Operation::OperationState theState )
+{
+  myState = theState;
+}
+
+//=======================================================================
+// name    : start
+// Purpose : Verifies whether operation can be started and starts operation. This slot
+//           is not virtual and cannot be redefined. Redefine startOperation method
+//           to change behaviour of operation instead
+//=======================================================================
 void SUIT_Operation::start()
 {
-       myStudy = myApp->activeStudy();
-       if ( myStudy )
+  if ( study() )
+    study()->start( this );
+  else
   {
-               if ( myStudy->canStartOperation( this ) )
-    {
-      if ( !isReadyToStart() )
-      {
-        myStudy->stopOperation();
-        return;
-      }
-                       startOperation();
-                       myState = Running;
-
-                       emit started( this );
-               }
-       }
+    startOperation();
+    emit started( this );
+  }
 }
 
+//=======================================================================
+// name    : abort
+// Purpose : Aborts operation. This slot is not virtual and cannot be
+//           redefined. Redefine abortOperation method to change behaviour
+//           of operation instead
+//=======================================================================
 void SUIT_Operation::abort()
 {
-       abortOperation();
-       myStudy->stopOperation();
-       myState = Waiting;
-
-  emit aborted( this );
+  if ( study() )
+    study()->abort( this );
+  else
+  {
+    abortOperation();
+    myState = Waiting;
+    emit aborted( this );
+    emit stopped( this );
+  }
 }
 
+//=======================================================================
+// name    : commit
+// Purpose : Commits operation. This slot is not virtual and cannot be
+//           redefined. Redefine commitOperation method to change behaviour
+//           of operation instead
+//=======================================================================
 void SUIT_Operation::commit()
 {
-       commitOperation();
-       myStudy->stopOperation();
-       myState = Waiting;
-
-       emit commited( this );
-
-  myStudy->sendChangesNotification();
+  if ( study() )
+    study()->commit( this );
+  else
+  {
+    commitOperation();
+    myState = Waiting;
+    emit commited( this );
+    emit stopped( this );
+  }
 }
 
+//=======================================================================
+// name    : resume
+// Purpose : Resume operation. This slot is called when operation is
+//           resumed after previous suspending. This slot is not virtual
+//           and cannot be redefined. Redefine resumeOperation method
+//           to change behaviour of operation instead 
+//=======================================================================
 void SUIT_Operation::resume()
 {
-       resumeOperation();
-       myState = Running;
-
-       emit resumed( this );
+  if ( study() )
+    study()->resume( this );
+  else
+  {
+    resumeOperation();
+    myState = Running;
+    emit resumed( this );
+  }
 }
 
+//=======================================================================
+// name    : suspend
+// Purpose : Suspend operation. This slot is called when operation is
+//           suspended (for starting other one, for example). This slot is not
+//           virtual and cannot be redefined. Redefine suspendOperation
+//           method to change behaviour of operation instead
+//=======================================================================
 void SUIT_Operation::suspend()
 {
-       suspendOperation();
-       myState = Suspended;
-
-       emit suspended( this );
+  if ( study() )
+    study()->suspend( this );
+  else
+  {
+    suspendOperation();
+    myState = Suspended;
+    emit suspended( this );
+  }
 }
 
+//=======================================================================
+// name    : isReadyToStart
+// Purpose : Verify whether operator is ready to start. Default implementation
+//           returns true. Redefine this method to add own verifications 
+//=======================================================================
 bool SUIT_Operation::isReadyToStart()
 {
-       return true;
+  return true;
 }
 
+//=======================================================================
+// name    : startOperation
+// Purpose : Virtual method called when operation started (see start()
+//           method for more description)
+//=======================================================================
 void SUIT_Operation::startOperation()
 {
-       emit callSlot();
-
-       commit();
+  emit callSlot();
+  commit();
 }
 
+//=======================================================================
+// name    : abortOperation
+// Purpose : Virtual method called when operation aborted (see abort()
+//           method for more description)
+//=======================================================================
 void SUIT_Operation::abortOperation()
 {
 }
 
+//=======================================================================
+// name    : resumeOperation
+// Purpose : Virtual method called when operation resumed (see resume()
+//           method for more description)
+//=======================================================================
 void SUIT_Operation::resumeOperation()
 {
 }
 
+//=======================================================================
+// name    : suspendOperation
+// Purpose : Virtual method called when operation suspended (see suspend()
+//           method for more description)
+//=======================================================================
 void SUIT_Operation::suspendOperation()
 {
 }
 
+//=======================================================================
+// name    : commitOperation
+// Purpose : Virtual method called when operation commited (see commit()
+//           method for more description)
+//=======================================================================
 void SUIT_Operation::commitOperation()
 {
 }
 
+//=======================================================================
+// name    : setSlot
+// Purpose : Sets slot which is called when operation is started. There is no point in
+//           using this method. It would be better to inherit own operator from base
+//           one and redefine startOperation method.
+//=======================================================================
 bool SUIT_Operation::setSlot( const QObject* theReceiver, const char* theSlot )
 {
-       return connect( this, SIGNAL( callSlot() ), theReceiver, theSlot );
+  return connect( this, SIGNAL( callSlot() ), theReceiver, theSlot );
 }
 
+//=======================================================================
+// name    : isValid
+// Purpose : Returns TRUE if the given operator is valid for the current one
+//           (can be started "above")
+//=======================================================================
 bool SUIT_Operation::isValid( SUIT_Operation* ) const
 {
   return false;
 }
 
+//=======================================================================
+// name    : isGranted
+// Purpose : Returns TRUE if current operation must not be checked for
+//           ActiveOperation->IsValid(this).  Default implementation returns FALSE,
+//           so it is being checked for IsValid, but some operations may overload IsGranted()
+//           In this case they will always start, no matter what operation is running
+//=======================================================================
 bool SUIT_Operation::isGranted() const
 {
   return false;
 }
 
-void SUIT_Operation::setStudy( SUIT_Study* s )
+//=======================================================================
+// name    : isActive
+// Purpose : Verify whether operation is an active one
+//=======================================================================
+bool SUIT_Operation::isActive() const
+{
+  return state()==Running;
+}
+
+//=======================================================================
+// name    : start
+// Purpose : Start operator above this one
+//=======================================================================
+void SUIT_Operation::start( SUIT_Operation* op )
+{
+  if ( !op )
+    return;
+    
+  if ( study() )
+    study()->start( op, false );
+  else
+  {
+    connect( this, SIGNAL( stopped( SUIT_Operation* ) ), op, SLOT( abort() ) );
+    op->start();
+  }
+}
+
+//=======================================================================
+// name    : setExecStatus
+// Purpose : Sets myExecStatus to the given value
+//=======================================================================
+void SUIT_Operation::setExecStatus( const int theVal )
 {
-  myStudy = s;
+  myExecStatus = (ExecStatus)theVal;
 }
 
-void SUIT_Operation::setApplication( SUIT_Application* app )
+//=======================================================================
+// name    : execStatus
+// Purpose : Gets execution status
+//=======================================================================
+int SUIT_Operation::execStatus()
 {
-  myApp = app;
+  return myExecStatus;
 }
+
+
+
+
+
+
+
+
index 123ec37477a64b0a9749b271bdaa0a052127901c..2c729e07ad06b11915ee6ecc4a62ace4f7a19bde 100755 (executable)
+/**
+*  SALOME SalomeApp
+*
+*  Copyright (C) 2005  CEA/DEN, EDF R&D
+*
+*
+*
+*  File   : SUIT_Operation.h
+*  Author : Unknown
+*  Module : SALOME
+*/
+
 #ifndef SUIT_OPERATION_H
 #define SUIT_OPERATION_H
 
 #include <qobject.h>
-#include <qstring.h>
-#include <qiconset.h>
-#include <qkeysequence.h>
 
 #include "SUIT.h"
 
 class SUIT_Study;
 class SUIT_Application;
 
+//==============================================================================
+//! 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 alredy strated
+*  ones, commiting operations and so on. To create own operation it is reasonable to
+*  inherit it from this class and reddefines virtual methods to provide own behaviour
+*  Main virtual methods are
+*  - virtual bool      isReadyToStart();
+*  - virtual void      startOperation();
+*  - virtual void      abortOperation();
+*  - virtual void      commitOperation();
+*  - virtual void      resumeOperation();
+*  - virtual void      suspendOperation();
+*/
+//==============================================================================
 class SUIT_EXPORT SUIT_Operation : public QObject  
 {
-       Q_OBJECT
+  Q_OBJECT
 
 public:
-       enum OperationState { Waiting, Running, Suspended };
 
-public:
-       SUIT_Operation( SUIT_Application* );
-       virtual ~SUIT_Operation();
+  /*! Enum describes state of operation */
+  enum OperationState
+  {
+    Waiting,  /*!< Operation is not used (it is not runned or suspended) */
+    Running,  /*!< Operation is started */
+    Suspended /*!< Operation is started but suspended (other operation is performed above it) */
+  };
+
+  /*! Enum describes execution status of operation */
+  enum ExecStatus
+  {
+    Rejected, /*! Operation has not parformed any action (modificetion of data model for example) */
+    Accepted  /*! Operation has performed an actions and must be stopped */
+  };
 
-       OperationState    state() const;
-       SUIT_Study*       study() const;
-       SUIT_Application* application() const;
+public:
 
-       bool              setSlot( const QObject* theReceiver, const char* theSlot );
+  SUIT_Operation( SUIT_Application* );
+  //!< Constructor
+  
+  virtual ~SUIT_Operation();
+  //!< Destructor
+
+  bool              isActive() const;
+  //!< Verifies whether operation is an active one (state()==Running)
+  
+  OperationState    state() const;
+  //!< Returns state of operation (see OperationState enumeration)
+  void              setState( const OperationState );
+  //!< Sets state of operation (see OperationState enumeration)
+  
+  SUIT_Study*       study() const;
+  //!< Returns operation study (i.e. study which starts this operation )
+  virtual void      setStudy( SUIT_Study* );
+  //!< Sets operation study (i.e. study which starts this operation )
+  
+  SUIT_Application* application() const;
+  //!< Returns application
+  virtual void      setApplication( SUIT_Application* );
+  //!< Sets application
+  
+  bool              setSlot( const QObject* theReceiver, const char* theSlot );
+  //!< Sets slot which is called when operation is started
+  /*! Sets slot which is called when operation is started. There is no point in
+      using this method. It would be better to inherit own operator from base
+      one and redefine startOperation method. */
+
+  virtual bool      isValid( SUIT_Operation* ) const;
+  //! Returns TRUE if the given operator is valid for (can be started "above") the current one
+
+  virtual bool      isGranted() const;
+  //!< Returns TRUE if current operation must not be checked for ActiveOperation->IsValid(this)
+  /*!< Returns TRUE if current operation must not be checked for
+    ActiveOperation->IsValid(this).  Default implementation returns FALSE,
+    so it is being checked for IsValid, but some operations may overload IsGranted()
+    In this case they will always start, no matter what operation is running. */
 
 public slots:
-       void              start();
-       void              abort();
-       void              commit();
-       void              resume();
-       void              suspend();
 
+  void              start();
+  //!< Starts operation.
+  /*!< Verifies whether operation can be started and starts operation. This slot
+       is not virtual and cannot be redefined. Redefine startOperation method
+       to change behaviour of operation instead */
+       
+  void              abort();
+  //!< Aborts operation.
+  /*!< This slot is not virtual and cannot be redefined. Redefine abortOperation
+       method to change behaviour of operation instead */
+  
+  void              commit();
+  //!< Commits operation.
+  /*!< This slot is not virtual and cannot be redefined. Redefine commitOperation
+       method to change behaviour of operation instead */
+
+  void              suspend();
+  //!< Suspend operation.
+  /*!< This slot is called when operation is suspended (for starting other one, for example)
+       This slot is not virtual and cannot be redefined. Redefine suspendOperation
+       method to change behaviour of operation instead */
+
+  void              resume();
+  //!< Resume operation.
+  /*!< This slot is called when operation is resumed after previous suspending.
+       This slot is not virtual and cannot be redefined. Redefine resumeOperation
+       method to change behaviour of operation instead */
+  
 signals:
-       void              started( SUIT_Operation* );
-       void              aborted( SUIT_Operation* );
-       void              resumed( SUIT_Operation* );
-       void              commited( SUIT_Operation* );
-       void              suspended( SUIT_Operation* );
-       void              callSlot();
+
+  void              started( SUIT_Operation* );
+  //!< Signal emited from start method when operation started
+  void              aborted( SUIT_Operation* );
+  //!< Signal emited from abort method when operation aborted
+  void              resumed( SUIT_Operation* );
+  //!< Signal emited from resume method when operation resumed
+  void              commited( SUIT_Operation* );
+  //!< Signal emited from commite method when operation commited
+  void              suspended( SUIT_Operation* );
+  //!< Signal emited from suspend method when operation suspended
+  void              stopped( SUIT_Operation* );
+  //!< Signal emited from stop method when operation stopped
+  
+  void              callSlot();
+  //!< Signal emited from default implementation of startOperation method
+  /*!< See setSlot for more description */
 
 protected:
-       virtual bool      isReadyToStart();
-       virtual void      startOperation();
-       virtual void      abortOperation();
-       virtual void      commitOperation();
-       virtual void      resumeOperation();
-       virtual void      suspendOperation();
-
-  // Returns TRUE if the given operator is valid for (can be started "above") the current operator
-       virtual bool      isValid( SUIT_Operation* ) const;
-
-       /*!
-               Returns TRUE if current operation must not be checked for 
-               ActiveOperation->IsValid(this).  Default implementation returns FALSE, 
-               so it is being checked for IsValid, but some operations may overload IsGranted()
-               In this case they will always start, no matter what operation is running.
-       */
-       virtual bool      isGranted() const;
 
-  virtual void      setStudy( SUIT_Study* );
-  virtual void      setApplication( SUIT_Application* );
+  virtual bool      isReadyToStart();
+  //!< Verify whether operator is ready to start.
+  /*!< Default implementation returns true. Redefine this method to add own verifications */
+  
+  virtual void      startOperation();
+  //!< Virtual method called when operation started (see start() method for more description)
+  virtual void      abortOperation();
+  //!< Virtual method called when operation aborted (see abort() method for more description)
+  virtual void      commitOperation();
+  //!< Virtual method called when operation commited (see commit() method for more description)
+  virtual void      suspendOperation();
+  //!< Virtual method called when operation suspended (see suspend() method for more description)
+  virtual void      resumeOperation();
+  //!< Virtual method called when operation resumed (see resume() method for more description)
+  
+  void              setExecStatus( const int );
+  //!< Sets myExecStatus to the given value
+  int               execStatus();
+  //!< Gets execution status
+
+  void              start( SUIT_Operation* );
+  //!< Start operator above this one
 
 private:
-       SUIT_Application* myApp;
-       SUIT_Study*                 myStudy;
-       OperationState    myState;
 
-       friend class SUIT_Study;
+  SUIT_Application* myApp;
+  SUIT_Study*       myStudy;
+  OperationState    myState;
+  ExecStatus        myExecStatus;
+
+  friend class SUIT_Study;
 };
 
 #endif
index ea157b387a18515888e23409d0343e6f7c964232..243447ca2a92a818482ea349e1369b1c1ebaa072 100755 (executable)
@@ -11,7 +11,8 @@ SUIT_Study::SUIT_Study( SUIT_Application* app )
 myApp( app ),
 myIsSaved( false ),
 myIsModified( false ),
-myName( "" )
+myName( "" ),
+myBlockChangeState( false )
 {
   static int _id = 0;
 
@@ -19,6 +20,10 @@ myName( "" )
 
   myRoot = new SUIT_DataObject();
   myOperations.setAutoDelete( false );
+
+  connect( this, SIGNAL( changeOperationState( bool ) ), this, SLOT( onChangeOperationState( bool ) ) );
+
+  myOperations.setAutoDelete( false );
 }
 
 SUIT_Study::~SUIT_Study()
@@ -49,7 +54,13 @@ QString SUIT_Study::studyName() const
 
 SUIT_Operation* SUIT_Study::activeOperation() const
 {
-  return myOperations.current();
+  Operations::const_iterator anIt = myOperations.begin(),
+                             aLast = myOperations.end();
+  for( ; anIt!=aLast; anIt++ )
+    if( (*anIt)->isActive() )
+      return *anIt;
+  
+  return 0;
 }
 
 bool SUIT_Study::isSaved() const
@@ -97,12 +108,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();
 }
 
 void SUIT_Study::update()
@@ -138,39 +148,188 @@ void SUIT_Study::setStudyName( const QString& name )
   myName = name;
 }
 
-void SUIT_Study::stopOperation()
+bool SUIT_Study::canActivate( SUIT_Operation* op, SUIT_Operation** refusingOp ) const
 {
-  myOperations.pop();
-  if ( myOperations.current() )
-    myOperations.current()->resume();
-  myIsModified = true;
+  if( !op )
+  {
+    if( refusingOp )
+      *refusingOp = 0;      
+    return false;
+  }
+
+  if( op->isGranted() )
+    return true;
+
+  Operations::const_iterator anIt = myOperations.begin(),
+                             aLast = myOperations.end();
+  for( ; anIt!=aLast; anIt++ )
+    if( !(*anIt)->isValid( op ) )
+    {
+      if( refusingOp )
+        *refusingOp = *anIt;
+      return false;
+    }
+    
+  return true;
 }
 
-bool SUIT_Study::canStartOperation( SUIT_Operation* theOperation )
+void SUIT_Study::connectOperation( SUIT_Operation* op, const bool conn ) const
 {
-  SUIT_Operation* anActiveOperation = (SUIT_Operation*)activeOperation();
-  if ( anActiveOperation )
+  if( !op )
+    return;
+    
+  if( conn )
   {
-    if ( !theOperation->isGranted() )
+    connect( op, SIGNAL( started( SUIT_Operation* ) ), this, SLOT( onAddOperation( SUIT_Operation* ) ) );
+    connect( op, SIGNAL( stoped( SUIT_Operation* ) ), this, SLOT( onRemoveOperation( SUIT_Operation* ) ) );
+    connect( op, SIGNAL( resumed( SUIT_Operation* ) ), this, SLOT( onOperationResume( SUIT_Operation* ) ) );
+  }
+  else
+  {
+    disconnect( op, SIGNAL( started( SUIT_Operation* ) ), this, SLOT( onAddOperation( SUIT_Operation* ) ) );
+    disconnect( op, SIGNAL( stoped( SUIT_Operation* ) ), this, SLOT( onRemoveOperation( SUIT_Operation* ) ) );
+    disconnect( op, SIGNAL( resumed( SUIT_Operation* ) ), this, SLOT( onOperationResume( SUIT_Operation* ) ) );
+  }
+}
+
+void SUIT_Study::onAddOperation( SUIT_Operation* op )
+{
+  myOperations.append( op );
+}
+
+void SUIT_Study::onRemoveOperation( SUIT_Operation* op )
+{
+  myOperations.remove( op );
+}
+
+void SUIT_Study::onOperationResume( SUIT_Operation* op )
+{
+  Operations::const_iterator anIt = myOperations.begin(),
+                             aLast = myOperations.end();
+  for( ; anIt!=aLast; anIt++ )
+    if( *anIt!=op )
+      (*anIt)->suspend();
+}
+
+//=======================================================================
+// name    : start
+// Purpose : Starts operation.
+//=======================================================================
+void SUIT_Study::start( SUIT_Operation* op, const bool check )
+{
+  if ( !op || myOperations.find( op ) >= 0 )
+    return;
+    
+  op->setExecStatus( SUIT_Operation::Rejected );
+  op->setStudy( this );
+
+  if ( !op->isReadyToStart() )
+    return;
+
+  if ( check )
+  {
+    SUIT_Operation* refusingOperation = 0;
+    while( canActivate( op, &refusingOperation ) && refusingOperation )
     {
-      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 operation is not finished and will be aborted." ),
+                                           tr( "Continue" ), tr( "Cancel" ), 0, 1, 1 );
+      if( anAnsw == 1 )
+        return;  // user refuse to start this operation
+      else
+        refusingOperation->abort();
     }
-    anActiveOperation->suspend();
   }
-  myOperations.push( theOperation );
 
-  return true;
+  if ( activeOperation() )
+    activeOperation()->suspendOperation();
+
+  op->startOperation();
+  myOperations.append( op );
+  op->setState( SUIT_Operation::Running );
+  emit op->started( op );
 }
+
+//=======================================================================
+// name    : abort
+// Purpose : Aborts operation.
+//=======================================================================  
+void SUIT_Study::abort( SUIT_Operation* op )
+{
+  if ( !op || myOperations.find( op ) == -1 )
+    return;
+    
+  op->abortOperation();
+  emit op->aborted( op );
+  stop( op );
+}
+
+//=======================================================================
+// name    : commit
+// Purpose : Commits operation
+//=======================================================================
+void SUIT_Study::commit( SUIT_Operation* op )
+{
+  if ( !op || myOperations.find( op ) == -1 )
+    return;
+
+  op->commitOperation();
+  emit op->commited( op );
+  stop( op );
+  emit studyModified( this );
+}
+
+//=======================================================================
+// name    : suspend
+// Purpose : Suspends operation
+//=======================================================================  
+void SUIT_Study::suspend( SUIT_Operation* op )
+{
+  if ( !op || myOperations.find( op ) == -1 || op->state() == SUIT_Operation::Suspended )
+    return;
+
+  op->setState( SUIT_Operation::Suspended );
+  op->suspendOperation();
+  emit op->suspended( op );
+}
+
+
+//=======================================================================
+// name    : resume
+// Purpose : Resume operation
+//=======================================================================  
+void SUIT_Study::resume( SUIT_Operation* op )
+{
+  if ( !op || myOperations.find( op ) == -1 || op->state() == SUIT_Operation::Running )
+    return;
+
+  op->setState( SUIT_Operation::Running );
+  op->resumeOperation();
+  emit op->resumed( op );
+}
+
+//=======================================================================
+// name    : stop
+// Purpose : Stop operation. This method is called when operation is
+//           aborted or commited
+//=======================================================================  
+void SUIT_Study::stop( SUIT_Operation* op )
+{
+  op->setState( SUIT_Operation::Waiting );
+  myOperations.remove( op );
+  if ( myOperations.count() > 0 && myOperations.getLast() )
+    myOperations.getLast()->resumeOperation();
+    
+  emit op->stopped( op );
+}
+
+
+
+
+
+
+
+
+
+
+  
\ No newline at end of file
index 56582caf7e9afe7811ed48a40d405ac28e0a399c..6ab11d1f1fd22b22359f9b2e6b3e544bbe1329c6 100755 (executable)
@@ -6,7 +6,7 @@
 #include "SUIT_Operation.h"
 
 #include <qobject.h>
-#include <qptrstack.h>
+#include <qptrlist.h>
 
 class SUIT_DataObject;
 class SUIT_Application;
@@ -18,6 +18,7 @@ class SUIT_Application;
 class SUIT_EXPORT SUIT_Study : public QObject
 {
   Q_OBJECT
+  
 public:
   SUIT_Study( SUIT_Application* );
   virtual ~SUIT_Study();
@@ -27,7 +28,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 +39,27 @@ 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();
+  virtual bool      canActivate( SUIT_Operation*, SUIT_Operation** = 0 ) const;
+  virtual void      connectOperation( SUIT_Operation*, const bool ) const;
+
+  void              start( SUIT_Operation*, const bool check = true );
+  //!< Starts operation.
+  void              abort( SUIT_Operation* );
+  //!< Aborts operation.
+  void              commit( SUIT_Operation* );
+  //!< Commits operation.
+  void              suspend( SUIT_Operation* );
+  //!< Suspend operation.
+  void              resume( SUIT_Operation* );
+  //!< Resume operation.
+
 signals:
   void              studyModified( SUIT_Study* );
 
@@ -54,14 +69,14 @@ 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 slots:
+  void onAddOperation( SUIT_Operation* );
+  void onRemoveOperation( SUIT_Operation* );
+  void onOperationResume( SUIT_Operation* );
+  
+private:
+  typedef QPtrList<SUIT_Operation> Operations;
+  void              stop( SUIT_Operation* );
 
 private:
   int               myId;
@@ -70,8 +85,8 @@ private:
   QString           myName;
   bool              myIsSaved;
   bool              myIsModified;
-
-  friend class SUIT_Operation;
+  Operations        myOperations;
+  bool              myBlockChangeState;
 };
 
 #ifdef WIN32