From e7918649ba7a5a6eceb542e14df35b578c88ea29 Mon Sep 17 00:00:00 2001 From: sln Date: Tue, 23 Aug 2005 08:24:07 +0000 Subject: [PATCH] Methods for starting, suspending, aborting (etc) operation added. Now if operation has study it calls corresponding stydy method for these purposes. List of started operations added. --- src/SUIT/SUIT_Study.cxx | 250 ++++++++++++++++++++++++++++++++++------ src/SUIT/SUIT_Study.h | 35 +++--- 2 files changed, 233 insertions(+), 52 deletions(-) diff --git a/src/SUIT/SUIT_Study.cxx b/src/SUIT/SUIT_Study.cxx index a2679a5f5..9c2af0282 100755 --- a/src/SUIT/SUIT_Study.cxx +++ b/src/SUIT/SUIT_Study.cxx @@ -5,6 +5,7 @@ #include "SUIT_DataObject.h" #include "SUIT_MessageBox.h" #include "SUIT_Application.h" +#include /*!\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_Study::operations() const +{ + return myOperations; +} + + + + + + + + + + diff --git a/src/SUIT/SUIT_Study.h b/src/SUIT/SUIT_Study.h index 58d311eea..bd1f419c8 100755 --- a/src/SUIT/SUIT_Study.h +++ b/src/SUIT/SUIT_Study.h @@ -6,10 +6,11 @@ #include "SUIT_Operation.h" #include -#include +#include 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& 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 OperationsStack; - -protected: - OperationsStack myOperations; +private: + typedef QPtrList 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 -- 2.39.2