From f16039b1923ca92906d4112a3bb0dbd431192807 Mon Sep 17 00:00:00 2001 From: stv Date: Tue, 22 Nov 2005 10:57:56 +0000 Subject: [PATCH] Transaction management in operations modifed. --- src/CAF/CAF_Operation.cxx | 52 +--------------- src/CAF/CAF_Operation.h | 42 +++---------- src/CAF/CAF_Study.cxx | 34 ++++++---- src/CAF/CAF_Study.h | 11 ++-- src/SUIT/SUIT_Operation.cxx | 120 +++++++++++++++++++++++++++++++++--- src/SUIT/SUIT_Operation.h | 56 +++++++++++------ src/SUIT/SUIT_Study.cxx | 91 ++++++++++++++++++++++++--- src/SUIT/SUIT_Study.h | 14 ++++- 8 files changed, 284 insertions(+), 136 deletions(-) diff --git a/src/CAF/CAF_Operation.cxx b/src/CAF/CAF_Operation.cxx index bb83610a3..f5a1e51cc 100755 --- a/src/CAF/CAF_Operation.cxx +++ b/src/CAF/CAF_Operation.cxx @@ -1,11 +1,7 @@ -// CAF_Operation.cxx: implementation of the CAF_Operation class. -// -////////////////////////////////////////////////////////////////////// - #include "CAF_Operation.h" -#include "CAF_Application.h" -#include "CAF_Study.h" +#include "CAF_Study.h" +#include "CAF_Application.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction @@ -19,47 +15,3 @@ CAF_Operation::CAF_Operation(SUIT_Application* theApp) CAF_Operation::~CAF_Operation() { } - -/*! - Sets the name of this operation. - This name is displayed in 'Undo'/'Redo' list. [ public ] -*/ -void CAF_Operation::setName( const QString& name ) -{ - myName = name; -} - -/*! - Returns the name of this operation. - This name is displayed in 'Undo'/'Redo' list. [ public ] -*/ -const QString& CAF_Operation::getName() const -{ - return myName; -} - -void CAF_Operation::startOperation() -{ - myIsDataChanged = true; - CAF_Study* cafStudy = dynamic_cast( study() ); - if ( cafStudy ) - cafStudy->startOperation(); -} - -void CAF_Operation::abortOperation() -{ - CAF_Study* cafStudy = dynamic_cast( study() ); - if ( cafStudy ) - cafStudy->abortOperation(); -} - -void CAF_Operation::commitOperation() -{ - CAF_Study* cafStudy = dynamic_cast( study() ); - if ( cafStudy ) - { - cafStudy->commitOperation(); - if ( myIsDataChanged ) - cafStudy->doModified(); - } -} diff --git a/src/CAF/CAF_Operation.h b/src/CAF/CAF_Operation.h index d60e1bb4d..b9715c41a 100755 --- a/src/CAF/CAF_Operation.h +++ b/src/CAF/CAF_Operation.h @@ -1,50 +1,22 @@ -// CAF_Operation.h: interface for the CAF_Operation class. -// -////////////////////////////////////////////////////////////////////// +#ifndef CAF_OPERATION_H +#define CAF_OPERATION_H -#if !defined(AFX_CAF_OPERATION_H__87D24897_EA69_4A5A_B81F_39E25ABC254B__INCLUDED_) -#define AFX_CAF_OPERATION_H__87D24897_EA69_4A5A_B81F_39E25ABC254B__INCLUDED_ +#include "CAF.h" -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 +#include "SUIT_Operation.h" #include #include -#include -#include - -#include "CAF.h" - -#include "SUIT_Operation.h" class CAF_Study; class CAF_EXPORT CAF_Operation : public SUIT_Operation { Q_OBJECT + public: - CAF_Operation(SUIT_Application* theApp); + CAF_Operation( SUIT_Application* ); virtual ~CAF_Operation(); - - void setName( const QString& name ); - const QString& getName() const; - -protected: - bool myIsDataChanged; - // All operations-successors must set this field to true in order - // to indicates that data are changed or false if aren't changed. - // By default, in startOperation method this field is set to true. - -protected: - virtual void startOperation(); - virtual void abortOperation(); - virtual void commitOperation(); - -private: - QString myName; - - friend class SUIT_Study; }; -#endif // !defined(AFX_SUIT_OPERATION_H__87D24897_EA69_4A5A_B81F_39E25ABC254B__INCLUDED_) +#endif diff --git a/src/CAF/CAF_Study.cxx b/src/CAF/CAF_Study.cxx index 5ddc2fe7d..c69305e3a 100755 --- a/src/CAF/CAF_Study.cxx +++ b/src/CAF/CAF_Study.cxx @@ -13,6 +13,8 @@ #include #include +#include + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -123,7 +125,7 @@ bool CAF_Study::saveDocumentAs( const QString& fname ) return status && SUIT_Study::saveDocumentAs( fname ); } -bool CAF_Study::startOperation() +bool CAF_Study::openTransaction() { if ( myStdDoc.IsNull() ) return false; @@ -142,40 +144,50 @@ bool CAF_Study::startOperation() return res; } -void CAF_Study::abortOperation() +bool CAF_Study::abortTransaction() { if ( myStdDoc.IsNull() ) - return; + return false; + bool res = true; try { myStdDoc->AbortCommand(); update(); } catch ( Standard_Failure ) { + res = false; } + return res; } -void CAF_Study::commitOperation() +bool CAF_Study::commitTransaction( const QString& name ) { if ( myStdDoc.IsNull() ) - return; + return false; + bool res = true; try { myStdDoc->CommitCommand(); if ( canUndo() ) { - CAF_Operation* cafOp = 0; - if ( activeOperation() && activeOperation()->inherits( "CAF_Operation" ) ) - cafOp = (CAF_Operation*)activeOperation(); - Handle(TDF_Delta) d = myStdDoc->GetUndos().Last(); - if ( cafOp && !d.IsNull() ) - d->SetName( CAF_Tools::toExtString( cafOp->getName() ) ); + if ( !d.IsNull() ) + d->SetName( CAF_Tools::toExtString( name ) ); } } catch ( Standard_Failure ) { + res = false; } + return res; +} + +bool CAF_Study::hasTransaction() const +{ + if ( myStdDoc.IsNull() ) + return false; + + return myStdDoc->HasOpenCommand(); } /*! diff --git a/src/CAF/CAF_Study.h b/src/CAF/CAF_Study.h index 88ae24cba..58119e0e6 100755 --- a/src/CAF/CAF_Study.h +++ b/src/CAF/CAF_Study.h @@ -31,11 +31,7 @@ public: virtual bool saveDocumentAs( const QString& ); - virtual bool startOperation(); - virtual void abortOperation(); - virtual void commitOperation(); - - bool isSaved() const; + bool isSaved() const; bool isModified() const; void doModified( bool = true ); void undoModified(); @@ -54,6 +50,11 @@ protected: Handle(TDocStd_Application) stdApp() const; CAF_Application* cafApplication() const; + virtual bool openTransaction(); + virtual bool abortTransaction(); + virtual bool hasTransaction() const; + virtual bool commitTransaction( const QString& = QString::null ); + virtual void setStdDoc( Handle(TDocStd_Document)& ); private: diff --git a/src/SUIT/SUIT_Operation.cxx b/src/SUIT/SUIT_Operation.cxx index cfaf3d431..60250b389 100755 --- a/src/SUIT/SUIT_Operation.cxx +++ b/src/SUIT/SUIT_Operation.cxx @@ -13,9 +13,9 @@ #include "SUIT_Operation.h" #include "SUIT_Study.h" -#include "SUIT_Application.h" -#include "SUIT_MessageBox.h" #include "SUIT_Desktop.h" +#include "SUIT_MessageBox.h" +#include "SUIT_Application.h" /*! * \brief Constructor @@ -30,7 +30,8 @@ SUIT_Operation::SUIT_Operation( SUIT_Application* app ) : QObject(), myApp( app ), myStudy( 0 ), -myState( Waiting ) +myState( Waiting ), +myFlags( Transaction ) { } @@ -107,6 +108,50 @@ void SUIT_Operation::setState( const SUIT_Operation::OperationState theState ) myState = theState; } +/*! + * \brief Sets the flags of operation + * \param f - flags of operation to be set +* +* Sets flags of operation (see Flags enumeration) +*/ +void SUIT_Operation::setFlags( const int f ) +{ + myFlags = myFlags | f; +} + +/*! + * \brief Clears the flags of operation + * \param f - flags of operation to be cleared +* +* Clears flags of operation (see Flags enumeration) +*/ +void SUIT_Operation::clearFlags( const int f ) +{ + myFlags = myFlags & ~f; +} + +/*! + * \brief Test the flags of operation + * \param f - flags of operation to be tested +* +* Returns TRUE if the specified flags setted in the operation (see Flags enumeration) +*/ +bool SUIT_Operation::testFlags( const int f ) const +{ + return ( myFlags & f ) == f; +} + +/*! + * \brief Name of the operation +* +* Returns string name of the operation. This name will be used for +* automatically commited transaction. +*/ +QString SUIT_Operation::operationName() const +{ + return QString::null; +} + /*! * \brief Starts operation * @@ -142,6 +187,8 @@ void SUIT_Operation::abort() abortOperation(); myState = Waiting; emit aborted( this ); + + stopOperation(); emit stopped( this ); } } @@ -161,6 +208,8 @@ void SUIT_Operation::commit() commitOperation(); myState = Waiting; emit committed( this ); + + stopOperation(); emit stopped( this ); } } @@ -225,6 +274,15 @@ void SUIT_Operation::startOperation() commit(); } +/*! + * \brief Virtual method called when operation is started +* +* Virtual method called when operation stopped - comitted or aborted. +*/ +void SUIT_Operation::stopOperation() +{ +} + /*! * \brief Virtual method called when operation aborted * @@ -304,15 +362,27 @@ bool SUIT_Operation::isGranted() const } /*! - * \brief Verifies whether operation is an active one (state()==Running) + * \brief Verifies whether operation is an runned one (state()==Running) * \return TRUE if operation is active, FALSE otherwise * -* Verifies whether operation is an active on. Returns TRUE if state of operator +* Verifies whether operation is an running. Returns TRUE if state of operator * is Running */ +bool SUIT_Operation::isRunning() const +{ + return state() == Running; +} + +/*! + * \brief Verifies whether operation is an active for study. + * \return TRUE if operation is active, FALSE otherwise +* +* Verifies whether operation is an active on. Returns TRUE if this operator +* is active for study +*/ bool SUIT_Operation::isActive() const { - return state()==Running; + return study() ? study()->activeOperation() == this : false; } /*! @@ -322,7 +392,7 @@ bool SUIT_Operation::isActive() const * Start operator above this one. Use this method if you want to call other operator * from this one */ -void SUIT_Operation::start( SUIT_Operation* op ) +void SUIT_Operation::start( SUIT_Operation* op, const bool check ) { if ( !op ) return; @@ -358,10 +428,46 @@ int SUIT_Operation::execStatus() const return myExecStatus; } +/*! + * \brief Opens transaction for data modifications. +*/ +bool SUIT_Operation::openTransaction() +{ + if ( !study() ) + return false; + return study()->openTransaction(); +} +/*! + * \brief Aborts transaction and all performed data modifications. +*/ +bool SUIT_Operation::abortTransaction() +{ + if ( !study() ) + return false; + return study()->abortTransaction(); +} +/*! + * \brief Commits transaction and all performed data modifications. +*/ +bool SUIT_Operation::commitTransaction( const QString& name ) +{ + if ( !study() ) + return false; + return study()->commitTransaction( name ); +} +/*! + * \brief Returns TRUE if transaction is opened. +*/ +bool SUIT_Operation::hasTransaction() const +{ + if ( !study() ) + return false; + return study()->hasTransaction(); +} diff --git a/src/SUIT/SUIT_Operation.h b/src/SUIT/SUIT_Operation.h index 7af280e8c..6f60680bf 100755 --- a/src/SUIT/SUIT_Operation.h +++ b/src/SUIT/SUIT_Operation.h @@ -41,7 +41,6 @@ class SUIT_EXPORT SUIT_Operation : public QObject Q_OBJECT public: - /*! Enum describes state of operation */ enum OperationState { @@ -61,13 +60,22 @@ public: Accepted //!< Operation has performed an actions and must be stopped }; -public: + /*! + * Enum describes setting of the operation. + */ + enum Flags + { + None = 0x00, //!< None options + Transaction = 0x01 //!< Automatically open (commit/abort) transaction during start (commit/abort). + }; +public: SUIT_Operation( SUIT_Application* ); virtual ~SUIT_Operation(); OperationState state() const; bool isActive() const; + bool isRunning() const; SUIT_Study* study() const; virtual void setStudy( SUIT_Study* theStudy ); @@ -80,45 +88,55 @@ public: bool setSlot( const QObject* theReceiver, const char* theSlot ); -public slots: + void setFlags( const int ); + void clearFlags( const int ); + bool testFlags( const int ) const; - void start(); - void abort(); - void commit(); - void suspend(); - void resume(); + virtual QString operationName() const; signals: - void started( SUIT_Operation* ); void aborted( SUIT_Operation* ); - void resumed( SUIT_Operation* ); void committed( SUIT_Operation* ); - void suspended( SUIT_Operation* ); + void stopped( SUIT_Operation* ); - + void resumed( SUIT_Operation* ); + void suspended( SUIT_Operation* ); + void callSlot(); -protected: +public slots: + void start(); + void abort(); + void commit(); + void resume(); + void suspend(); +protected: virtual bool isReadyToStart() const; - + + virtual void stopOperation(); virtual void startOperation(); virtual void abortOperation(); virtual void commitOperation(); - virtual void suspendOperation(); virtual void resumeOperation(); + virtual void suspendOperation(); + + virtual bool openTransaction(); + virtual bool abortTransaction(); + virtual bool hasTransaction() const; + virtual bool commitTransaction( const QString& = QString::null ); - void setExecStatus( const int theStatus ); int execStatus() const; + void setExecStatus( const int ); - void setState( const OperationState theState ); + void setState( const OperationState ); - void start( SUIT_Operation* theOp ); + void start( SUIT_Operation*, const bool = false ); private: - SUIT_Application* myApp; //!< application for this operation + int myFlags; //!< operation flags SUIT_Study* myStudy; //!< study for this operation OperationState myState; //!< Operation state ExecStatus myExecStatus; //!< Execution status diff --git a/src/SUIT/SUIT_Study.cxx b/src/SUIT/SUIT_Study.cxx index d99233382..3fb151902 100755 --- a/src/SUIT/SUIT_Study.cxx +++ b/src/SUIT/SUIT_Study.cxx @@ -257,10 +257,10 @@ bool SUIT_Study::start( SUIT_Operation* theOp, const bool toCheck ) while( SUIT_Operation* anOp = blockingOperation( theOp ) ) { int anAnsw = SUIT_MessageBox::warn2( application()->desktop(), - tr( "OPERATION_LAUNCH" ), tr( "PREVIOUS_NOT_FINISHED" ), - tr( "CONTINUE" ), tr( "CANCEL" ), 0, 1, 1 ); + tr( "OPERATION_LAUNCH" ), tr( "PREVIOUS_NOT_FINISHED" ), + tr( "CONTINUE" ), tr( "CANCEL" ), 0, 1, 1 ); - if( anAnsw == 1 ) + if ( anAnsw == 1 ) return false; else anOp->abort(); @@ -276,9 +276,11 @@ bool SUIT_Study::start( SUIT_Operation* theOp, const bool toCheck ) theOp->setState( SUIT_Operation::Running ); myOperations.append( theOp ); + emit theOp->started( theOp ); + operationStarted( theOp ); theOp->startOperation(); - + return true; } @@ -295,10 +297,14 @@ bool SUIT_Study::abort( SUIT_Operation* theOp ) if ( !theOp || myOperations.find( theOp ) == -1 ) return false; - theOp->abortOperation(); theOp->setExecStatus( SUIT_Operation::Rejected ); + + theOp->abortOperation(); + operationAborted( theOp ); emit theOp->aborted( theOp ); + stop( theOp ); + return true; } @@ -315,11 +321,16 @@ bool SUIT_Study::commit( SUIT_Operation* theOp ) if ( !theOp || myOperations.find( theOp ) == -1 ) return false; - theOp->commitOperation(); theOp->setExecStatus( SUIT_Operation::Accepted ); + + theOp->commitOperation(); + operationCommited( theOp ); emit theOp->committed( theOp ); + stop( theOp ); + emit studyModified( this ); + return true; } @@ -387,14 +398,19 @@ void SUIT_Study::stop( SUIT_Operation* theOp ) // get last operation which can be resumed SUIT_Operation* anOp, *aResultOp = 0; - for( anOp = myOperations.last(); anOp; anOp = myOperations.prev() ) + for ( anOp = myOperations.last(); anOp; anOp = myOperations.prev() ) + { if ( anOp && anOp != theOp && blockingOperation( anOp ) == 0 ) { aResultOp = anOp; break; } + } + theOp->stopOperation(); + operationStopped( theOp ); emit theOp->stopped( theOp ); + if ( aResultOp ) resume( aResultOp ); } @@ -408,12 +424,71 @@ const QPtrList& SUIT_Study::operations() const return myOperations; } +/*! + * \brief Perform some actions when operation starting +*/ +void SUIT_Study::operationStarted( SUIT_Operation* op ) +{ + if ( !op ) + return; + if ( op->testFlags( SUIT_Operation::Transaction ) ) + openTransaction(); +} +/*! + * \brief Perform some actions when operation aborted +*/ +void SUIT_Study::operationAborted( SUIT_Operation* op ) +{ + if ( op->testFlags( SUIT_Operation::Transaction ) ) + abortTransaction(); +} +/*! + * \brief Perform some actions when operation commited +*/ +void SUIT_Study::operationCommited( SUIT_Operation* op ) +{ + if ( op->testFlags( SUIT_Operation::Transaction ) ) + commitTransaction( op->operationName() ); +} +/*! + * \brief Perform some actions when operation stopped +*/ +void SUIT_Study::operationStopped( SUIT_Operation* ) +{ +} +/*! + * \brief Opens transaction for data modifications. +*/ +bool SUIT_Study::openTransaction() +{ + return true; +} +/*! + * \brief Aborts transaction and all performed data modifications. +*/ +bool SUIT_Study::abortTransaction() +{ + return true; +} +/*! + * \brief Commits transaction and all performed data modifications. +*/ +bool SUIT_Study::commitTransaction( const QString& ) +{ + return true; +} - +/*! + * \brief Returns TRUE if transaction is opened. +*/ +bool SUIT_Study::hasTransaction() const +{ + return false; +} diff --git a/src/SUIT/SUIT_Study.h b/src/SUIT/SUIT_Study.h index bd1f419c8..d82ebef2d 100755 --- a/src/SUIT/SUIT_Study.h +++ b/src/SUIT/SUIT_Study.h @@ -33,8 +33,8 @@ public: virtual bool isSaved() const; virtual bool isModified() const; - virtual void closeDocument(bool permanently = true); virtual void createDocument(); + virtual void closeDocument( bool = true ); virtual bool openDocument( const QString& ); bool saveDocument(); @@ -66,6 +66,16 @@ protected: virtual void setRoot( SUIT_DataObject* ); virtual void setStudyName( const QString& ); + virtual void operationStarted( SUIT_Operation* ); + virtual void operationAborted( SUIT_Operation* ); + virtual void operationStopped( SUIT_Operation* ); + virtual void operationCommited( SUIT_Operation* ); + + virtual bool openTransaction(); + virtual bool abortTransaction(); + virtual bool hasTransaction() const; + virtual bool commitTransaction( const QString& = QString::null ); + private: typedef QPtrList Operations; void stop( SUIT_Operation* ); @@ -79,6 +89,8 @@ private: bool myIsModified; Operations myOperations; bool myBlockChangeState; + + friend class SUIT_Operation; }; #ifdef WIN32 -- 2.39.2