diff options
author | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2010-11-15 22:12:48 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2010-11-15 22:12:48 +0100 |
commit | 3909360c32b8e018bab468db7aece015c6d1a2b4 (patch) | |
tree | 510f0eee22cf9de1df62db9e575c253c4a02ed6f /chart2/source | |
parent | 5aa51f86396a4e8709d42c64b11946a9987a7876 (diff) |
undoapi: step 2.2 of the migration of css.chart2.XUndoManager to css.document.XUndoManager:
base the implementation of XDocumentActions on the document's UndoManager
Diffstat (limited to 'chart2/source')
-rw-r--r-- | chart2/source/controller/main/DocumentActions.cxx | 303 | ||||
-rw-r--r-- | chart2/source/controller/main/ImplDocumentActions.cxx | 584 | ||||
-rw-r--r-- | chart2/source/controller/main/ImplDocumentActions.hxx | 208 | ||||
-rw-r--r-- | chart2/source/inc/DocumentActions.hxx | 45 | ||||
-rwxr-xr-x | chart2/source/model/main/ChartModel.cxx | 2 |
5 files changed, 457 insertions, 685 deletions
diff --git a/chart2/source/controller/main/DocumentActions.cxx b/chart2/source/controller/main/DocumentActions.cxx index e4fe1ab0fc3f..a4864541fc70 100644 --- a/chart2/source/controller/main/DocumentActions.cxx +++ b/chart2/source/controller/main/DocumentActions.cxx @@ -37,11 +37,13 @@ #include <com/sun/star/util/XCloneable.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/document/XUndoManagerSupplier.hpp> #include <unotools/configitem.hxx> +#include <tools/diagnose_ex.h> #include <cppuhelper/compbase1.hxx> +#include <comphelper/namedvaluecollection.hxx> #include <rtl/uuid.h> -#include <svx/svdundo.hxx> #include <functional> @@ -49,7 +51,14 @@ using namespace ::com::sun::star; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::RuntimeException; using ::com::sun::star::frame::XModel; +using ::com::sun::star::document::XUndoManagerSupplier; +using ::com::sun::star::document::XUndoAction; using ::rtl::OUString; @@ -73,7 +82,7 @@ public: void fireEvent(); -protected: +public: // ____ XModifyBroadcaster ____ virtual void SAL_CALL addModifyListener( const Reference< util::XModifyListener >& xListener ) throw (uno::RuntimeException); @@ -118,44 +127,33 @@ void ModifyBroadcaster::fireEvent() } // namespace impl -DocumentActions::DocumentActions( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rModel ) : - impl::DocumentActions_Base( m_aMutex ), - m_apUndoStack( new impl::UndoStack()), - m_apRedoStack( new impl::UndoStack()), - m_pLastRemeberedUndoElement( 0 ), - m_nMaxNumberOfUndos( 100 ), - m_pModifyBroadcaster( 0 ), - m_aModel( rModel ) -{} +DocumentActions::DocumentActions( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rModel ) + :impl::DocumentActions_Base( m_aMutex ) + ,m_pDocumentSnapshot() + ,m_pModifyBroadcaster( NULL ) + ,m_aModel( rModel ) + ,m_xUndoManager() +{ + Reference< XUndoManagerSupplier > xSuppUndo( rModel, UNO_QUERY_THROW ); + m_xUndoManager.set( xSuppUndo->getUndoManager(), UNO_SET_THROW ); +} DocumentActions::~DocumentActions() { - DisposeHelper::Dispose( m_xModifyBroadcaster ); - m_apUndoStack->disposeAndClear(); - m_apRedoStack->disposeAndClear(); - - delete m_pLastRemeberedUndoElement; - m_pLastRemeberedUndoElement = 0; + if ( m_pModifyBroadcaster.is() ) + { + m_pModifyBroadcaster->dispose(); + m_pModifyBroadcaster.clear(); + } } void DocumentActions::addShapeUndoAction( SdrUndoAction* pAction ) { if ( !pAction ) - { return; - } - - impl::ShapeUndoElement* pShapeUndoElement = new impl::ShapeUndoElement( pAction->GetComment(), pAction ); - if ( pShapeUndoElement ) - { - m_apUndoStack->push( pShapeUndoElement ); - m_apRedoStack->disposeAndClear(); - if ( !m_apUndoStepsConfigItem.get() ) - { - retrieveConfigUndoSteps(); - } - fireModifyEvent(); - } + const Reference< XUndoAction > xAction( new impl::ShapeUndoElement( *pAction ) ); + m_xUndoManager->addUndoAction( xAction ); + impl_fireModifyEvent(); } Reference< XModel > DocumentActions::impl_getModel() const @@ -164,228 +162,191 @@ Reference< XModel > DocumentActions::impl_getModel() const return xModel; } -void DocumentActions::impl_undoRedo( - impl::UndoStack * pStackToRemoveFrom, - impl::UndoStack * pStackToAddTo, - bool bUndo ) +void DocumentActions::impl_fireModifyEvent() { - if( pStackToRemoveFrom && ! pStackToRemoveFrom->empty() ) - { - // get model from undo/redo - impl::UndoElement * pTop( pStackToRemoveFrom->top()); - if( pTop ) - { - Reference< XModel > xModel( impl_getModel() ); - impl::ShapeUndoElement* pShapeUndoElement = dynamic_cast< impl::ShapeUndoElement* >( pTop ); - if ( pShapeUndoElement ) - { - impl::ShapeUndoElement* pNewShapeUndoElement = new impl::ShapeUndoElement( *pShapeUndoElement ); - pStackToAddTo->push( pNewShapeUndoElement ); - SdrUndoAction* pAction = pNewShapeUndoElement->getSdrUndoAction(); - if ( pAction ) - { - if ( bUndo ) - { - pAction->Undo(); - } - else - { - pAction->Redo(); - } - } - } - else - { - // put a clone of current model into redo/undo stack with the same - // action string as the undo/redo - pStackToAddTo->push( pTop->createFromModel( xModel )); - // change current model by properties of the model from undo - pTop->applyToModel( xModel ); - } - // remove the top undo element - pStackToRemoveFrom->pop(), pTop = 0; - ChartViewHelper::setViewToDirtyState( xModel ); - fireModifyEvent(); - } - } - else - { - OSL_ENSURE( false, "Can't Undo/Redo" ); - } -} - -void DocumentActions::fireModifyEvent() -{ - if( m_xModifyBroadcaster.is()) + if ( m_pModifyBroadcaster.is() ) m_pModifyBroadcaster->fireEvent(); } -// ____ ConfigItemListener ____ -void DocumentActions::notify( const ::rtl::OUString & rPropertyName ) -{ - OSL_ENSURE( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Steps" )), - "Unwanted config property change Notified" ); - if( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Steps" ))) - retrieveConfigUndoSteps(); -} - -void DocumentActions::retrieveConfigUndoSteps() -{ - if( ! m_apUndoStepsConfigItem.get()) - m_apUndoStepsConfigItem.reset( new impl::UndoStepsConfigItem( *this )); - m_nMaxNumberOfUndos = m_apUndoStepsConfigItem->getUndoSteps(); - m_apUndoStack->limitSize( m_nMaxNumberOfUndos ); - m_apRedoStack->limitSize( m_nMaxNumberOfUndos ); - - // a list of available undo steps could shrink here - fireModifyEvent(); -} - // ____ XModifyBroadcaster ____ void SAL_CALL DocumentActions::addModifyListener( const Reference< util::XModifyListener >& aListener ) throw (uno::RuntimeException) { - if( ! m_xModifyBroadcaster.is()) - { - m_pModifyBroadcaster = new impl::ModifyBroadcaster(); - m_xModifyBroadcaster.set( static_cast< cppu::OWeakObject* >( m_pModifyBroadcaster ), uno::UNO_QUERY ); - } - m_xModifyBroadcaster->addModifyListener( aListener ); + if ( !m_pModifyBroadcaster.is() ) + m_pModifyBroadcaster.set( new impl::ModifyBroadcaster() ); + + m_pModifyBroadcaster->addModifyListener( aListener ); } void SAL_CALL DocumentActions::removeModifyListener( const Reference< util::XModifyListener >& aListener ) throw (uno::RuntimeException) { - if( ! m_xModifyBroadcaster.is()) - { - m_pModifyBroadcaster = new impl::ModifyBroadcaster(); - m_xModifyBroadcaster.set( static_cast< cppu::OWeakObject* >( m_pModifyBroadcaster ), uno::UNO_QUERY ); - } - m_xModifyBroadcaster->removeModifyListener( aListener ); + if ( m_pModifyBroadcaster.is() ) + m_pModifyBroadcaster->removeModifyListener( aListener ); } // ____ chart2::XDocumentActions ____ void SAL_CALL DocumentActions::preAction( ) throw (uno::RuntimeException) { - OSL_ENSURE( ! m_pLastRemeberedUndoElement, "Looks like postAction or cancelAction call was missing" ); - m_pLastRemeberedUndoElement = new impl::UndoElement( impl_getModel() ); + ENSURE_OR_THROW( !m_pDocumentSnapshot, "DocumentActions::preAction: already started an action!" ); + m_pDocumentSnapshot.reset( new impl::ChartModelClone( impl_getModel(), impl::E_MODEL ) ); } -void SAL_CALL DocumentActions::preActionWithArguments( - const Sequence< beans::PropertyValue >& aArguments ) - throw (uno::RuntimeException) +void SAL_CALL DocumentActions::preActionWithArguments( const Sequence< beans::PropertyValue >& aArguments ) throw (uno::RuntimeException, lang::IllegalArgumentException) { - Reference< XModel > xModel( impl_getModel() ); - bool bActionHandled( false ); - OSL_ENSURE( ! m_pLastRemeberedUndoElement, "Looks like postAction or cancelAction call was missing" ); - if( aArguments.getLength() > 0 ) - { - OSL_ENSURE( aArguments.getLength() == 1, "More than one argument is not supported yet" ); - if( aArguments[0].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("WithData"))) - { - m_pLastRemeberedUndoElement = new impl::UndoElementWithData( xModel ); - bActionHandled = true; - } - else if( aArguments[0].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("WithSelection"))) - { - m_pLastRemeberedUndoElement = new impl::UndoElementWithSelection( xModel ); - bActionHandled = true; - } - } + ENSURE_OR_THROW( !m_pDocumentSnapshot, "DocumentActions::preAction: already started an action!" ); + + impl::ModelFacet eModelFacet( impl::E_MODEL ); + ::comphelper::NamedValueCollection aArgs( aArguments ); - if( !bActionHandled ) - preAction(); + const sal_Bool bWithData = aArgs.getOrDefault( "WithData", sal_False ); + if ( bWithData ) + eModelFacet = impl::E_MODEL_WITH_DATA; + + const sal_Bool bWithSelection = aArgs.getOrDefault( "WithSelection", sal_False ); + if ( bWithSelection ) + eModelFacet = impl::E_MODEL_WITH_SELECTION; + + const Reference< XModel > xModel( impl_getModel() ); + m_pDocumentSnapshot.reset( new impl::ChartModelClone( xModel, eModelFacet ) ); } void SAL_CALL DocumentActions::postAction( const OUString& aUndoText ) throw (uno::RuntimeException) { - OSL_ENSURE( m_pLastRemeberedUndoElement, "Looks like preAction call was missing" ); - if( m_pLastRemeberedUndoElement ) - { - m_pLastRemeberedUndoElement->setActionString( aUndoText ); - m_apUndoStack->push( m_pLastRemeberedUndoElement ); - m_pLastRemeberedUndoElement = 0; + ENSURE_OR_THROW( !!m_pDocumentSnapshot.get(), "no current action" ); - // redo no longer possible - m_apRedoStack->disposeAndClear(); + const Reference< XUndoAction > xAction( new impl::UndoElement( aUndoText, impl_getModel(), m_pDocumentSnapshot ) ); + m_pDocumentSnapshot.reset(); - // it suffices to get the number of undo steps from config after the - // first time postAction has been called - if( ! m_apUndoStepsConfigItem.get()) - retrieveConfigUndoSteps(); + m_xUndoManager->addUndoAction( xAction ); - fireModifyEvent(); - } + impl_fireModifyEvent(); } void SAL_CALL DocumentActions::cancelAction() throw (uno::RuntimeException) { - delete m_pLastRemeberedUndoElement; - m_pLastRemeberedUndoElement = 0; + ENSURE_OR_THROW( !!m_pDocumentSnapshot.get(), "no current action" ); + + m_pDocumentSnapshot->dispose(); + m_pDocumentSnapshot.reset(); } void SAL_CALL DocumentActions::cancelActionWithUndo( ) throw (uno::RuntimeException) { - if( m_pLastRemeberedUndoElement ) - { - m_pLastRemeberedUndoElement->applyToModel( impl_getModel() ); - cancelAction(); - } + ENSURE_OR_THROW( !!m_pDocumentSnapshot.get(), "no current action" ); + + m_pDocumentSnapshot->applyToModel( impl_getModel() ); + m_pDocumentSnapshot->dispose(); + m_pDocumentSnapshot.reset(); } void SAL_CALL DocumentActions::undo( ) throw (uno::RuntimeException) { - OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get()); - impl_undoRedo( m_apUndoStack.get(), m_apRedoStack.get(), true ); + try + { + m_xUndoManager->undo(); + } + catch ( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } } void SAL_CALL DocumentActions::redo( ) throw (uno::RuntimeException) { - OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get()); - impl_undoRedo( m_apRedoStack.get(), m_apUndoStack.get(), false ); + try + { + m_xUndoManager->redo(); + } + catch ( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } } ::sal_Bool SAL_CALL DocumentActions::undoPossible() throw (uno::RuntimeException) { - return ! m_apUndoStack->empty(); + return m_xUndoManager->isUndoPossible(); } ::sal_Bool SAL_CALL DocumentActions::redoPossible() throw (uno::RuntimeException) { - return ! m_apRedoStack->empty(); + return m_xUndoManager->isRedoPossible(); } OUString SAL_CALL DocumentActions::getCurrentUndoString() throw (uno::RuntimeException) { - return m_apUndoStack->topUndoString(); + OUString sTitle; + try + { + sTitle = m_xUndoManager->getCurrentUndoActionTitle(); + } + catch ( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return sTitle; } OUString SAL_CALL DocumentActions::getCurrentRedoString() throw (uno::RuntimeException) { - return m_apRedoStack->topUndoString(); + OUString sTitle; + try + { + sTitle = m_xUndoManager->getCurrentRedoActionTitle(); + } + catch ( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return sTitle; } Sequence< OUString > SAL_CALL DocumentActions::getAllUndoStrings() throw (uno::RuntimeException) { - return m_apUndoStack->getUndoStrings(); + Sequence< OUString > aStrings; + try + { + aStrings = m_xUndoManager->getAllUndoActionTitles(); + } + catch ( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return aStrings; } Sequence< OUString > SAL_CALL DocumentActions::getAllRedoStrings() throw (uno::RuntimeException) { - return m_apRedoStack->getUndoStrings(); + Sequence< ::rtl::OUString > aStrings; + try + { + aStrings = m_xUndoManager->getAllRedoActionTitles(); + } + catch ( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return aStrings; } // ____ XUnoTunnel ____ diff --git a/chart2/source/controller/main/ImplDocumentActions.cxx b/chart2/source/controller/main/ImplDocumentActions.cxx index 8103bec54114..f477052908ff 100644 --- a/chart2/source/controller/main/ImplDocumentActions.cxx +++ b/chart2/source/controller/main/ImplDocumentActions.cxx @@ -43,462 +43,344 @@ #include <com/sun/star/util/XCloneable.hpp> #include <com/sun/star/util/XModifiable.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +#include <tools/diagnose_ex.h> +#include <svx/svdundo.hxx> #include <boost/bind.hpp> #include <algorithm> using namespace ::com::sun::star; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::Sequence; using ::rtl::OUString; -using ::com::sun::star::chart::XComplexDescriptionAccess; namespace chart { namespace impl { -void ImplApplyDataToModel( - const Reference< frame::XModel > & xModel, - const Reference< chart2::XInternalDataProvider > & xData ) + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::frame::XModel; + using ::com::sun::star::util::XCloneable; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::view::XSelectionSupplier; + using ::com::sun::star::chart2::XChartDocument; + using ::com::sun::star::chart::XComplexDescriptionAccess; + using ::com::sun::star::chart2::XTitled; + using ::com::sun::star::chart2::XInternalDataProvider; + using ::com::sun::star::util::XModifiable; + using ::com::sun::star::document::UndoFailedException; + /** === end UNO using === **/ + +// ===================================================================================================================== +// = helper +// ===================================================================================================================== +namespace { - Reference< chart2::XChartDocument > xDoc( xModel, uno::UNO_QUERY ); - OSL_ASSERT( xDoc.is() && xDoc->hasInternalDataProvider()); - - // copy data from stored internal data provider - if( xDoc.is() && xDoc->hasInternalDataProvider()) + Reference< XModel > lcl_cloneModel( const Reference< XModel > & xModel ) { - Reference< XComplexDescriptionAccess > xCurrentData( xDoc->getDataProvider(), uno::UNO_QUERY ); - Reference< XComplexDescriptionAccess > xSavedData( xData, uno::UNO_QUERY ); - if( xCurrentData.is() && xSavedData.is()) + Reference< XModel > xResult; + try { - xCurrentData->setData( xSavedData->getData()); - xCurrentData->setComplexRowDescriptions( xSavedData->getComplexRowDescriptions()); - xCurrentData->setComplexColumnDescriptions( xSavedData->getComplexColumnDescriptions()); + const Reference< XCloneable > xCloneable( xModel, UNO_QUERY_THROW ); + xResult.set( xCloneable->createClone(), UNO_QUERY_THROW ); } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return xResult; } -} -// ---------------------------------------- - -UndoElement::UndoElement( - const OUString & rActionString, - const Reference< frame::XModel > & xModel ) : - m_aActionString( rActionString ) -{ - initialize( xModel ); } -UndoElement::UndoElement( - const Reference< frame::XModel > & xModel ) -{ - initialize( xModel ); -} +// ===================================================================================================================== +// = ChartModelClone +// ===================================================================================================================== -UndoElement::UndoElement( const UndoElement & rOther ) : - m_aActionString( rOther.m_aActionString ) +// --------------------------------------------------------------------------------------------------------------------- +ChartModelClone::ChartModelClone( const Reference< XModel >& i_model, const ModelFacet i_facet ) { - initialize( rOther.m_xModel ); -} + m_xModelClone.set( lcl_cloneModel( i_model ) ); -UndoElement::~UndoElement() -{} + try + { + if ( i_facet == E_MODEL_WITH_DATA ) + { + const Reference< XChartDocument > xChartDoc( m_xModelClone, UNO_QUERY_THROW ); + ENSURE_OR_THROW( xChartDoc->hasInternalDataProvider(), "invalid chart model" ); -void UndoElement::initialize( const Reference< frame::XModel > & xModel ) -{ - if ( xModel.is() ) + const Reference< XCloneable > xCloneable( xChartDoc->getDataProvider(), UNO_QUERY_THROW ); + m_xDataClone.set( xCloneable->createClone(), UNO_QUERY_THROW ); + } + + if ( i_facet == E_MODEL_WITH_SELECTION ) + { + const Reference< XSelectionSupplier > xSelSupp( m_xModelClone->getCurrentController(), UNO_QUERY_THROW ); + m_aSelection = xSelSupp->getSelection(); + } + } + catch( const Exception& ) { - m_xModel.set( UndoElement::cloneModel( xModel ) ); + DBG_UNHANDLED_EXCEPTION(); } } -void UndoElement::dispose() -{ - Reference< lang::XComponent > xComp( m_xModel, uno::UNO_QUERY ); - if( xComp.is()) - xComp->dispose(); - m_xModel.set( 0 ); -} - -void UndoElement::applyToModel( - const Reference< frame::XModel > & xModel ) -{ - UndoElement::applyModelContentToModel( xModel, m_xModel ); -} -UndoElement * UndoElement::createFromModel( - const Reference< frame::XModel > & xModel ) +// --------------------------------------------------------------------------------------------------------------------- +ChartModelClone::~ChartModelClone() { - return new UndoElement( getActionString(), xModel ); + if ( !impl_isDisposed() ) + dispose(); } -void UndoElement::setActionString( const ::rtl::OUString & rActionString ) +// --------------------------------------------------------------------------------------------------------------------- +void ChartModelClone::dispose() { - m_aActionString = rActionString; -} + if ( impl_isDisposed() ) + return; -OUString UndoElement::getActionString() const -{ - return m_aActionString; + try + { + Reference< XComponent > xComp( m_xModelClone, UNO_QUERY_THROW ); + xComp->dispose(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + m_xModelClone.clear(); + m_xDataClone.clear(); + m_aSelection.clear(); } -// static -Reference< frame::XModel > UndoElement::cloneModel( const Reference< frame::XModel > & xModel ) +// --------------------------------------------------------------------------------------------------------------------- +ModelFacet ChartModelClone::getFacet() const { - Reference< frame::XModel > xResult; - uno::Reference< util::XCloneable > xCloneable( xModel, uno::UNO_QUERY ); - OSL_ENSURE( xCloneable.is(), "Cannot clone model" ); - if( xCloneable.is()) - xResult.set( xCloneable->createClone(), uno::UNO_QUERY ); - - return xResult; + if ( m_aSelection.hasValue() ) + return E_MODEL_WITH_SELECTION; + if ( m_xDataClone.is() ) + return E_MODEL_WITH_DATA; + return E_MODEL; } -// static -void UndoElement::applyModelContentToModel( - const Reference< frame::XModel > & xModel, - const Reference< frame::XModel > & xModelToCopyFrom, - const Reference< chart2::XInternalDataProvider > & xData /* = 0 */ ) +// --------------------------------------------------------------------------------------------------------------------- +void ChartModelClone::applyToModel( const Reference< XModel >& i_model ) const { + applyModelContentToModel( i_model, m_xModelClone, m_xDataClone ); - if( xModelToCopyFrom.is() && xModel.is()) + if ( m_aSelection.hasValue() ) { try { - // /-- loccked controllers of destination - ControllerLockGuard aLockedControllers( xModel ); - Reference< chart2::XChartDocument > xSource( xModelToCopyFrom, uno::UNO_QUERY_THROW ); - Reference< chart2::XChartDocument > xDestination( xModel, uno::UNO_QUERY_THROW ); - - // propagate the correct flag for plotting of hidden values to the data provider and all used sequences - ChartModelHelper::setIncludeHiddenCells( ChartModelHelper::isIncludeHiddenCells( xModelToCopyFrom ) , xModel ); - - // diagram - xDestination->setFirstDiagram( xSource->getFirstDiagram()); - - // main title - Reference< chart2::XTitled > xDestinationTitled( xDestination, uno::UNO_QUERY_THROW ); - Reference< chart2::XTitled > xSourceTitled( xSource, uno::UNO_QUERY_THROW ); - xDestinationTitled->setTitleObject( xSourceTitled->getTitleObject()); - - // page background - comphelper::copyProperties( - xSource->getPageBackground(), - xDestination->getPageBackground() ); - - // apply data (not applied in standard Undo) - if( xData.is()) - ImplApplyDataToModel( xModel, xData ); - - // register all sequences at the internal data provider to get adapted - // indexes when columns are added/removed - if( xDestination->hasInternalDataProvider()) - { - Reference< chart2::XInternalDataProvider > xNewDataProvider( xDestination->getDataProvider(), uno::UNO_QUERY ); - Reference< chart2::data::XDataSource > xUsedData( DataSourceHelper::getUsedData( xModel )); - if( xUsedData.is() && xNewDataProvider.is()) - { - Sequence< Reference< chart2::data::XLabeledDataSequence > > aData( xUsedData->getDataSequences()); - for( sal_Int32 i=0; i<aData.getLength(); ++i ) - { - xNewDataProvider->registerDataSequenceForChanges( aData[i]->getValues()); - xNewDataProvider->registerDataSequenceForChanges( aData[i]->getLabel()); - } - } - } - - // restore modify status - Reference< util::XModifiable > xSourceMod( xSource, uno::UNO_QUERY ); - Reference< util::XModifiable > xDestMod( xDestination, uno::UNO_QUERY ); - if( xSourceMod.is() && xDestMod.is() && - ! xSourceMod->isModified() ) - { - xDestMod->setModified( sal_False ); - } - // \-- loccked controllers of destination + Reference< XSelectionSupplier > xCurrentSelectionSuppl( i_model->getCurrentController(), UNO_QUERY_THROW ); + xCurrentSelectionSuppl->select( m_aSelection ); } - catch( uno::Exception & ) + catch( const Exception& ) { + DBG_UNHANDLED_EXCEPTION(); } } } -// ---------------------------------------- - -UndoElementWithData::UndoElementWithData( - const OUString & rActionString, - const Reference< frame::XModel > & xModel ) : - UndoElement( rActionString, xModel ) -{ - initializeData(); -} - -UndoElementWithData::UndoElementWithData( - const Reference< frame::XModel > & xModel ) : - UndoElement( xModel ) -{ - initializeData(); -} - - -UndoElementWithData::UndoElementWithData( - const UndoElementWithData & rOther ) : - UndoElement( rOther ) -{ - initializeData(); -} - -UndoElementWithData::~UndoElementWithData() -{} - -void UndoElementWithData::initializeData() +// --------------------------------------------------------------------------------------------------------------------- +namespace { - try + void ImplApplyDataToModel( const Reference< XModel >& i_model, const Reference< XInternalDataProvider > & i_data ) { - Reference< chart2::XChartDocument > xChartDoc( m_xModel, uno::UNO_QUERY_THROW ); - OSL_ASSERT( xChartDoc->hasInternalDataProvider()); - if( xChartDoc->hasInternalDataProvider()) + Reference< XChartDocument > xDoc( i_model, UNO_QUERY ); + OSL_ASSERT( xDoc.is() && xDoc->hasInternalDataProvider() ); + + // copy data from stored internal data provider + if( xDoc.is() && xDoc->hasInternalDataProvider()) { - Reference< util::XCloneable > xCloneable( xChartDoc->getDataProvider(), uno::UNO_QUERY ); - OSL_ENSURE( xCloneable.is(), "Cannot clone data" ); - if( xCloneable.is()) - m_xData.set( xCloneable->createClone(), uno::UNO_QUERY ); + Reference< XComplexDescriptionAccess > xCurrentData( xDoc->getDataProvider(), UNO_QUERY ); + Reference< XComplexDescriptionAccess > xSavedData( i_data, UNO_QUERY ); + if ( xCurrentData.is() && xSavedData.is() ) + { + xCurrentData->setData( xSavedData->getData() ); + xCurrentData->setComplexRowDescriptions( xSavedData->getComplexRowDescriptions() ); + xCurrentData->setComplexColumnDescriptions( xSavedData->getComplexColumnDescriptions() ); + } } } - catch( uno::Exception & ) - { - } -} - -void UndoElementWithData::dispose() -{ - UndoElement::dispose(); - m_xData.set( 0 ); -} - -void UndoElementWithData::applyToModel( - const Reference< frame::XModel > & xModel ) -{ - UndoElement::applyModelContentToModel( xModel, m_xModel, m_xData ); } -UndoElement * UndoElementWithData::createFromModel( - const Reference< frame::XModel > & xModel ) -{ - return new UndoElementWithData( getActionString(), xModel ); -} - -// ======================================== - -// ---------------------------------------- - -UndoElementWithSelection::UndoElementWithSelection( - const OUString & rActionString, - const Reference< frame::XModel > & xModel ) : - UndoElement( rActionString, xModel ) -{ - initialize( xModel ); -} - -UndoElementWithSelection::UndoElementWithSelection( - const Reference< frame::XModel > & xModel ) : - UndoElement( xModel ) -{ - initialize( xModel ); -} - -UndoElementWithSelection::UndoElementWithSelection( - const UndoElementWithSelection & rOther ) : - UndoElement( rOther ) -{ - initialize( rOther.m_xModel ); -} - -UndoElementWithSelection::~UndoElementWithSelection() -{} - -void UndoElementWithSelection::initialize( const Reference< frame::XModel > & xModel ) +// --------------------------------------------------------------------------------------------------------------------- +void ChartModelClone::applyModelContentToModel( const Reference< XModel >& i_model, + const Reference< XModel >& i_modelToCopyFrom, const Reference< XInternalDataProvider >& i_data ) { + ENSURE_OR_RETURN_VOID( i_model.is(), "ChartModelElement::applyModelContentToModel: invalid source model!" ); + ENSURE_OR_RETURN_VOID( i_modelToCopyFrom.is(), "ChartModelElement::applyModelContentToModel: invalid source model!" ); try { - uno::Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), uno::UNO_QUERY ); - OSL_ASSERT( xSelSupp.is() ); + // /-- loccked controllers of destination + ControllerLockGuard aLockedControllers( i_model ); + Reference< XChartDocument > xSource( i_modelToCopyFrom, UNO_QUERY_THROW ); + Reference< XChartDocument > xDestination( i_model, UNO_QUERY_THROW ); + + // propagate the correct flag for plotting of hidden values to the data provider and all used sequences + ChartModelHelper::setIncludeHiddenCells( ChartModelHelper::isIncludeHiddenCells( i_modelToCopyFrom ) , i_model ); + + // diagram + xDestination->setFirstDiagram( xSource->getFirstDiagram() ); + + // main title + Reference< XTitled > xDestinationTitled( xDestination, UNO_QUERY_THROW ); + Reference< XTitled > xSourceTitled( xSource, UNO_QUERY_THROW ); + xDestinationTitled->setTitleObject( xSourceTitled->getTitleObject() ); + + // page background + ::comphelper::copyProperties( + xSource->getPageBackground(), + xDestination->getPageBackground() ); + + // apply data (not applied in standard Undo) + if ( i_data.is() ) + ImplApplyDataToModel( i_model, i_data ); + + // register all sequences at the internal data provider to get adapted + // indexes when columns are added/removed + if ( xDestination->hasInternalDataProvider() ) + { + Reference< XInternalDataProvider > xNewDataProvider( xDestination->getDataProvider(), UNO_QUERY ); + Reference< chart2::data::XDataSource > xUsedData( DataSourceHelper::getUsedData( i_model ) ); + if ( xUsedData.is() && xNewDataProvider.is() ) + { + Sequence< Reference< chart2::data::XLabeledDataSequence > > aData( xUsedData->getDataSequences() ); + for( sal_Int32 i=0; i<aData.getLength(); ++i ) + { + xNewDataProvider->registerDataSequenceForChanges( aData[i]->getValues() ); + xNewDataProvider->registerDataSequenceForChanges( aData[i]->getLabel() ); + } + } + } - if( xSelSupp.is() ) - m_aSelection = xSelSupp->getSelection(); + // restore modify status + Reference< XModifiable > xSourceMod( xSource, UNO_QUERY ); + Reference< XModifiable > xDestMod( xDestination, UNO_QUERY ); + if ( xSourceMod.is() && xDestMod.is() && !xSourceMod->isModified() ) + { + xDestMod->setModified( sal_False ); + } + // \-- loccked controllers of destination } - catch( const uno::Exception & ) + catch( const Exception& ) { + DBG_UNHANDLED_EXCEPTION(); } } -void UndoElementWithSelection::dispose() -{ - UndoElement::dispose(); - m_aSelection.clear(); -} - -void UndoElementWithSelection::applyToModel( - const Reference< frame::XModel > & xModel ) -{ - UndoElement::applyModelContentToModel( xModel, m_xModel ); - Reference< view::XSelectionSupplier > xCurrentSelectionSuppl( xModel->getCurrentController(), uno::UNO_QUERY ); - OSL_ASSERT( xCurrentSelectionSuppl.is() ); - - if( xCurrentSelectionSuppl.is()) - xCurrentSelectionSuppl->select( m_aSelection ); -} - -UndoElement * UndoElementWithSelection::createFromModel( - const Reference< frame::XModel > & xModel ) -{ - return new UndoElementWithSelection( getActionString(), xModel ); -} - -// ---------------------------------------- - -ShapeUndoElement::ShapeUndoElement( const OUString& rActionString, SdrUndoAction* pAction ) - :UndoElement( rActionString, Reference< frame::XModel >() ) - ,m_pAction( pAction ) -{ -} - -ShapeUndoElement::ShapeUndoElement( const ShapeUndoElement& rOther ) - :UndoElement( rOther ) - ,m_pAction( rOther.m_pAction ) -{ -} - -ShapeUndoElement::~ShapeUndoElement() -{ -} - -SdrUndoAction* ShapeUndoElement::getSdrUndoAction() -{ - return m_pAction; -} - -// ======================================== - -UndoStack::UndoStack() : - m_nSizeLimit( 1000 ) -{ -} - -UndoStack::~UndoStack() +// --------------------------------------------------------------------------------------------------------------------- +UndoElement::UndoElement( const OUString& i_actionString, const Reference< XModel >& i_documentModel, const ::boost::shared_ptr< ChartModelClone >& i_modelClone ) + :UndoElement_MBase() + ,UndoElement_TBase( m_aMutex ) + ,m_sActionString( i_actionString ) + ,m_xDocumentModel( i_documentModel ) + ,m_pModelClone( i_modelClone ) { - disposeAndClear(); } -void UndoStack::pop() +// --------------------------------------------------------------------------------------------------------------------- +UndoElement::~UndoElement() { - if( ! empty()) - { - top()->dispose(); - delete top(); - m_aStack.pop_back(); - } } -void UndoStack::push( UndoElement * pElement ) +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL UndoElement::disposing() { - m_aStack.push_back( pElement ); - applyLimitation(); + if ( !!m_pModelClone ) + m_pModelClone->dispose(); + m_pModelClone.reset(); + m_xDocumentModel.clear(); } -UndoElement * UndoStack::top() const +// --------------------------------------------------------------------------------------------------------------------- +::rtl::OUString SAL_CALL UndoElement::getTitle() throw (RuntimeException) { - return m_aStack.back(); + return m_sActionString; } -OUString UndoStack::topUndoString() const +// --------------------------------------------------------------------------------------------------------------------- +void UndoElement::impl_toggleModelState() { - if( ! empty()) - return top()->getActionString(); - return OUString(); + // get a snapshot of the current state of our model + ::boost::shared_ptr< ChartModelClone > pNewClone( new ChartModelClone( m_xDocumentModel, m_pModelClone->getFacet() ) ); + // apply the previous snapshot to our model + m_pModelClone->applyToModel( m_xDocumentModel ); + // remember the new snapshot, for the next toggle + m_pModelClone = pNewClone; } -Sequence< OUString > UndoStack::getUndoStrings() const +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL UndoElement::undo( ) throw (UndoFailedException, RuntimeException) { - sal_Int32 nSize( static_cast< sal_Int32 >( m_aStack.size())); - Sequence< OUString > aResult( nSize ); - for( sal_Int32 i=0; i<nSize; ++i ) - aResult[i] = m_aStack[i]->getActionString(); - return aResult; + impl_toggleModelState(); } -bool UndoStack::empty() const +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL UndoElement::redo( ) throw (UndoFailedException, RuntimeException) { - return m_aStack.empty(); + impl_toggleModelState(); } -void UndoStack::disposeAndClear() -{ - ::std::for_each( m_aStack.begin(), m_aStack.end(), ::boost::mem_fn( & UndoElement::dispose )); - ::std::for_each( m_aStack.begin(), m_aStack.end(), CommonFunctors::DeletePtr< UndoElement >() ); - m_aStack.clear(); -} +// ===================================================================================================================== +// = ShapeUndoElement +// ===================================================================================================================== -void UndoStack::limitSize( sal_Int32 nMaxSize ) +// --------------------------------------------------------------------------------------------------------------------- +ShapeUndoElement::ShapeUndoElement( SdrUndoAction& i_sdrUndoAction ) + :ShapeUndoElement_MBase() + ,ShapeUndoElement_TBase( m_aMutex ) + ,m_pAction( &i_sdrUndoAction ) { - m_nSizeLimit = nMaxSize; - applyLimitation(); } -void UndoStack::applyLimitation() -{ - if( m_aStack.size() > static_cast< sal_uInt32 >( m_nSizeLimit )) - { - tUndoStackType::iterator aBegin( m_aStack.begin()); - tUndoStackType::iterator aEnd( aBegin + (m_aStack.size() - m_nSizeLimit)); - // dispose and remove all undo elements that are over the limit - ::std::for_each( aBegin, aEnd, ::boost::mem_fn( & UndoElement::dispose )); - ::std::for_each( aBegin, aEnd, CommonFunctors::DeletePtr< UndoElement >() ); - m_aStack.erase( aBegin, aEnd ); - } -} - -// ================================================================================ - -namespace -{ -static const OUString aUndoStepsPropName( RTL_CONSTASCII_USTRINGPARAM("Steps")); -} // anonymous namespace - -UndoStepsConfigItem::UndoStepsConfigItem( ConfigItemListener & rListener ) : - ::utl::ConfigItem( OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Undo"))), - m_rListener( rListener ) +// --------------------------------------------------------------------------------------------------------------------- +ShapeUndoElement::~ShapeUndoElement() { - EnableNotification( Sequence< OUString >( & aUndoStepsPropName, 1 )); } -UndoStepsConfigItem::~UndoStepsConfigItem() +// --------------------------------------------------------------------------------------------------------------------- +::rtl::OUString SAL_CALL ShapeUndoElement::getTitle() throw (RuntimeException) { + if ( !m_pAction ) + throw DisposedException( ::rtl::OUString(), *this ); + return m_pAction->GetComment(); } -void UndoStepsConfigItem::Notify( const Sequence< OUString > & aPropertyNames ) +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL ShapeUndoElement::undo( ) throw (UndoFailedException, RuntimeException) { - for( sal_Int32 nIdx=0; nIdx<aPropertyNames.getLength(); ++nIdx ) - { - if( aPropertyNames[nIdx].equals( aUndoStepsPropName )) - m_rListener.notify( aPropertyNames[nIdx] ); - } + if ( !m_pAction ) + throw DisposedException( ::rtl::OUString(), *this ); + m_pAction->Undo(); } -void UndoStepsConfigItem::Commit() +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL ShapeUndoElement::redo( ) throw (UndoFailedException, RuntimeException) { + if ( !m_pAction ) + throw DisposedException( ::rtl::OUString(), *this ); + m_pAction->Redo(); } -// mtehod is not const, because GetProperties is not const -sal_Int32 UndoStepsConfigItem::getUndoSteps() +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL ShapeUndoElement::disposing() { - sal_Int32 nSteps = -1; - Sequence< uno::Any > aValues( - GetProperties( Sequence< OUString >( & aUndoStepsPropName, 1 ))); - if( aValues.getLength()) - aValues[0] >>= nSteps; - return nSteps; } } // namespace impl diff --git a/chart2/source/controller/main/ImplDocumentActions.hxx b/chart2/source/controller/main/ImplDocumentActions.hxx index aaf8f18c1231..889968dfe4c7 100644 --- a/chart2/source/controller/main/ImplDocumentActions.hxx +++ b/chart2/source/controller/main/ImplDocumentActions.hxx @@ -30,14 +30,19 @@ #include "ConfigItemListener.hxx" #include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/document/XUndoAction.hpp> #include <com/sun/star/uno/Sequence.hxx> #include <rtl/ustring.hxx> #include <unotools/configitem.hxx> +#include <cppuhelper/compbase1.hxx> +#include <cppuhelper/basemutex.hxx> #include <utility> #include <deque> +#include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp> class SdrUndoAction; @@ -53,173 +58,110 @@ namespace chart namespace impl { -class UndoElement +enum ModelFacet { -public: - UndoElement( const ::rtl::OUString & rActionString, - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - UndoElement( const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - UndoElement( const UndoElement & rOther ); - virtual ~UndoElement(); + E_MODEL, + E_MODEL_WITH_DATA, + E_MODEL_WITH_SELECTION +}; - virtual void dispose(); - virtual UndoElement * createFromModel( - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); +class ChartModelClone : public ::boost::noncopyable +{ +public: + ChartModelClone( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& i_model, + const ModelFacet i_facet + ); - virtual void applyToModel( - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); + ~ChartModelClone(); - void setActionString( const ::rtl::OUString & rActionString ); - ::rtl::OUString getActionString() const; + ModelFacet getFacet() const; - static ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > cloneModel( - const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xModel ); + void applyToModel( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& i_model ) const; static void applyModelContentToModel( - const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xModel, - const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xModelToCopyFrom, - const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XInternalDataProvider > & xData = 0 ); + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & i_model, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & i_modelToCopyFrom, + const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XInternalDataProvider > & i_data ); -protected: - ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > m_xModel; + void dispose(); private: - void initialize( const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - - ::rtl::OUString m_aActionString; -}; - -class UndoElementWithData : public UndoElement -{ -public: - UndoElementWithData( const ::rtl::OUString & rActionString, - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - UndoElementWithData( const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - UndoElementWithData( const UndoElementWithData & rOther ); - virtual ~UndoElementWithData(); - - virtual void dispose(); - virtual UndoElement * createFromModel( - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - - virtual void applyToModel( - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); + bool impl_isDisposed() const { return !m_xModelClone.is(); } private: - void initializeData(); - - ::com::sun::star::uno::Reference< - ::com::sun::star::chart2::XInternalDataProvider > m_xData; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > m_xModelClone; + ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XInternalDataProvider > m_xDataClone; + ::com::sun::star::uno::Any m_aSelection; }; -class UndoElementWithSelection : public UndoElement -{ -public: - UndoElementWithSelection( const ::rtl::OUString & rActionString, - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - UndoElementWithSelection( const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - UndoElementWithSelection( const UndoElementWithSelection & rOther ); - virtual ~UndoElementWithSelection(); - - virtual void dispose(); - virtual UndoElement * createFromModel( - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - - virtual void applyToModel( - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - -private: - void initialize( const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel > & xModel ); - - ::com::sun::star::uno::Any m_aSelection; -}; +typedef ::cppu::BaseMutex UndoElement_MBase; +typedef ::cppu::WeakComponentImplHelper1< ::com::sun::star::document::XUndoAction > UndoElement_TBase; -class ShapeUndoElement : public UndoElement +class UndoElement :public UndoElement_MBase + ,public UndoElement_TBase + ,public ::boost::noncopyable { public: - ShapeUndoElement( const ::rtl::OUString& rActionString, SdrUndoAction* pAction ); - ShapeUndoElement( const ShapeUndoElement& rOther ); - virtual ~ShapeUndoElement(); + /** creates a new undo action + + @param i_actionString + is the title of the Undo action + @param i_documentModel + is the actual document model which the undo actions operates on + @param i_modelClone + is the cloned model from before the changes, which the Undo action represents, have been applied. + Upon <member>invoking</member>, the clone model is applied to the document model. + */ + UndoElement( const ::rtl::OUString & i_actionString, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& i_documentModel, + const ::boost::shared_ptr< ChartModelClone >& i_modelClone + ); + + // XUndoAction + virtual ::rtl::OUString SAL_CALL getTitle() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL undo( ) throw (::com::sun::star::document::UndoFailedException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL redo( ) throw (::com::sun::star::document::UndoFailedException, ::com::sun::star::uno::RuntimeException); + + // OComponentHelper + virtual void SAL_CALL disposing(); - SdrUndoAction* getSdrUndoAction(); +protected: + virtual ~UndoElement(); private: - SdrUndoAction* m_pAction; -}; - -/** Note that all models that are put into this container are at some point - disposed of inside this class. (At least in the destructor). That means - the models retrieved here should never be used, but instead their content - should be copied to a living model. - */ -class UndoStack -{ -public: - UndoStack(); - // disposes of all models left in the stack - ~UndoStack(); - - // removes he last undo action and disposes of the model - void pop(); - void push( UndoElement * rElement ); - - // precondition: !empty() - UndoElement * top() const; - ::rtl::OUString topUndoString() const; - - ::com::sun::star::uno::Sequence< ::rtl::OUString > getUndoStrings() const; - - bool empty() const; - void disposeAndClear(); - - // removes all actions that have been inserted more than nMaxSize steps ago. - // The models of those actions are disposed of - void limitSize( sal_Int32 nMaxSize ); + void impl_toggleModelState(); private: - void applyLimitation(); - - typedef ::std::deque< UndoElement * > tUndoStackType; - - tUndoStackType m_aStack; - sal_Int32 m_nSizeLimit; + ::rtl::OUString m_sActionString; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > m_xDocumentModel; + ::boost::shared_ptr< ChartModelClone > m_pModelClone; }; -// ---------------------------------------- -class UndoStepsConfigItem : public ::utl::ConfigItem +typedef ::cppu::BaseMutex ShapeUndoElement_MBase; +typedef ::cppu::WeakComponentImplHelper1< ::com::sun::star::document::XUndoAction > ShapeUndoElement_TBase; +class ShapeUndoElement :public ShapeUndoElement_MBase + ,public ShapeUndoElement_TBase { public: - explicit UndoStepsConfigItem( ConfigItemListener & rListener ); - virtual ~UndoStepsConfigItem(); + ShapeUndoElement( SdrUndoAction& i_sdrUndoAction ); + + // XUndoAction + virtual ::rtl::OUString SAL_CALL getTitle() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL undo( ) throw (::com::sun::star::document::UndoFailedException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL redo( ) throw (::com::sun::star::document::UndoFailedException, ::com::sun::star::uno::RuntimeException); - sal_Int32 getUndoSteps(); + // OComponentHelper + virtual void SAL_CALL disposing(); protected: - // ____ ::utl::ConfigItem ____ - virtual void Notify( const ::com::sun::star::uno::Sequence< ::rtl::OUString > & aPropertyNames ); - virtual void Commit(); + virtual ~ShapeUndoElement(); private: - ConfigItemListener & m_rListener; + SdrUndoAction* m_pAction; }; - } // namespace impl } // namespace chart diff --git a/chart2/source/inc/DocumentActions.hxx b/chart2/source/inc/DocumentActions.hxx index 52c3282002a9..4cb6dc5d0f02 100644 --- a/chart2/source/inc/DocumentActions.hxx +++ b/chart2/source/inc/DocumentActions.hxx @@ -27,7 +27,6 @@ #ifndef CHART2_UNDOMANAGER_HXX #define CHART2_UNDOMANAGER_HXX -#include "ConfigItemListener.hxx" #include "MutexContainer.hxx" #include <com/sun/star/uno/Reference.hxx> @@ -37,15 +36,19 @@ #include <com/sun/star/chart2/XDocumentActions.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/document/XUndoManager.hpp> #include <cppuhelper/compbase3.hxx> #include <rtl/ustring.hxx> +#include <rtl/ref.hxx> // for pair #include <utility> // for auto_ptr #include <memory> +#include <boost/shared_ptr.hpp> + class SdrUndoAction; namespace com { namespace sun { namespace star { @@ -60,10 +63,11 @@ namespace chart namespace impl { -class UndoStepsConfigItem; +class UndoStepsConfigItem; class UndoElement; -class UndoStack; -class ModifyBroadcaster; +class UndoStack; +class ChartModelClone; +class ModifyBroadcaster; typedef ::cppu::WeakComponentImplHelper3< ::com::sun::star::util::XModifyBroadcaster, @@ -83,7 +87,6 @@ typedef ::cppu::WeakComponentImplHelper3< */ class DocumentActions : public MutexContainer, - public ConfigItemListener, public impl::DocumentActions_Base { public: @@ -100,9 +103,6 @@ public: static DocumentActions* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xObj ); protected: - // ____ ConfigItemListener ____ - virtual void notify( const ::rtl::OUString & rPropertyName ); - // ____ util::XModifyBroadcaster ____ virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) @@ -127,28 +127,13 @@ protected: virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAllRedoStrings( ) throw (::com::sun::star::uno::RuntimeException); private: - void retrieveConfigUndoSteps(); - void fireModifyEvent(); - void impl_undoRedo( - impl::UndoStack * pStackToRemoveFrom, - impl::UndoStack * pStackToAddTo, - bool bUndo = true ); - - ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > - impl_getModel() const; - - ::std::auto_ptr< impl::UndoStack > m_apUndoStack; - ::std::auto_ptr< impl::UndoStack > m_apRedoStack; - - impl::UndoElement * m_pLastRemeberedUndoElement; - - ::std::auto_ptr< impl::UndoStepsConfigItem > m_apUndoStepsConfigItem; - sal_Int32 m_nMaxNumberOfUndos; - ::com::sun::star::uno::Reference< - ::com::sun::star::util::XModifyBroadcaster > m_xModifyBroadcaster; - // pointer is valid as long as m_xModifyBroadcaster.is() - impl::ModifyBroadcaster * m_pModifyBroadcaster; - ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XModel > m_aModel; + void impl_fireModifyEvent(); + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > impl_getModel() const; + + ::boost::shared_ptr< impl::ChartModelClone > m_pDocumentSnapshot; + ::rtl::Reference< impl::ModifyBroadcaster > m_pModifyBroadcaster; + ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XModel > m_aModel; + ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoManager > m_xUndoManager; }; } // namespace chart diff --git a/chart2/source/model/main/ChartModel.cxx b/chart2/source/model/main/ChartModel.cxx index 10ff9095fc54..6ba450d76f5f 100755 --- a/chart2/source/model/main/ChartModel.cxx +++ b/chart2/source/model/main/ChartModel.cxx @@ -557,6 +557,8 @@ void SAL_CALL ChartModel::dispose() throw(uno::RuntimeException) m_pUndoManager.clear(); // that's important, since the UndoManager implementation delegates its ref counting to ourself. + m_xDocumentActions.clear(); + m_aControllers.disposeAndClear( lang::EventObject( static_cast< cppu::OWeakObject * >( this ))); m_xCurrentController.clear(); |