diff options
author | Thomas Benisch <tbe@openoffice.org> | 2009-09-29 11:03:35 +0000 |
---|---|---|
committer | Thomas Benisch <tbe@openoffice.org> | 2009-09-29 11:03:35 +0000 |
commit | 189c8860787a5086061cb1960b00788c25ade73b (patch) | |
tree | de0317ed6fe52ae698336251dd47498de4d3dda6 | |
parent | 63ec5317c74d46f2c8d4027a6571402caf262ed5 (diff) |
#i12587# Inserting/editing arbitrary text objects in chart
-rw-r--r-- | chart2/source/controller/main/ChartController.cxx | 19 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController.hxx | 2 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController_TextEdit.cxx | 23 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController_Tools.cxx | 19 | ||||
-rw-r--r-- | chart2/source/inc/UndoManager.hxx | 22 | ||||
-rw-r--r-- | chart2/source/tools/ImplUndoManager.cxx | 28 | ||||
-rw-r--r-- | chart2/source/tools/ImplUndoManager.hxx | 16 | ||||
-rw-r--r-- | chart2/source/tools/UndoManager.cxx | 100 |
8 files changed, 208 insertions, 21 deletions
diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx index b104e232b3b6e..cde145046dec2 100644 --- a/chart2/source/controller/main/ChartController.cxx +++ b/chart2/source/controller/main/ChartController.cxx @@ -56,6 +56,7 @@ #include "AccessibleChartView.hxx" #include "DrawCommandDispatch.hxx" #include "ShapeController.hxx" +#include "UndoManager.hxx" #include <comphelper/InlineContainer.hxx> @@ -1384,6 +1385,20 @@ void SAL_CALL ChartController::modified( const lang::EventObject& /* aEvent */ ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- +IMPL_LINK( ChartController, NotifyUndoActionHdl, SdrUndoAction*, pUndoAction ) +{ + ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID(); + if ( aObjectCID.getLength() == 0 ) + { + UndoManager* pUndoManager = UndoManager::getImplementation( m_xUndoManager ); + if ( pUndoManager ) + { + pUndoManager->addShapeUndoAction( pUndoAction ); + } + } + return 0L; +} + DrawModelWrapper* ChartController::GetDrawModelWrapper() { if( !m_pDrawModelWrapper.get() ) @@ -1391,6 +1406,10 @@ DrawModelWrapper* ChartController::GetDrawModelWrapper() ExplicitValueProvider* pProvider = ExplicitValueProvider::getExplicitValueProvider( m_xChartView ); if( pProvider ) m_pDrawModelWrapper = pProvider->getDrawModelWrapper(); + if ( m_pDrawModelWrapper.get() ) + { + m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl( LINK( this, ChartController, NotifyUndoActionHdl ) ); + } } return m_pDrawModelWrapper.get(); } diff --git a/chart2/source/controller/main/ChartController.hxx b/chart2/source/controller/main/ChartController.hxx index d391975b832b0..99035429f95d5 100644 --- a/chart2/source/controller/main/ChartController.hxx +++ b/chart2/source/controller/main/ChartController.hxx @@ -477,6 +477,8 @@ public: bool isShapeContext() const; + DECL_LINK( NotifyUndoActionHdl, SdrUndoAction* ); + public: //----------------------------------------------------------------- //----------------------------------------------------------------- diff --git a/chart2/source/controller/main/ChartController_TextEdit.cxx b/chart2/source/controller/main/ChartController_TextEdit.cxx index 41eb44d215ca9..ed041b3d6cc6d 100644 --- a/chart2/source/controller/main/ChartController_TextEdit.cxx +++ b/chart2/source/controller/main/ChartController_TextEdit.cxx @@ -166,15 +166,26 @@ bool ChartController::EndTextEdit() TitleHelper::setCompleteString( aString, uno::Reference< ::com::sun::star::chart2::XTitle >::query( xPropSet ), m_xCC ); - } - try - { - m_xUndoManager->postAction( C2U("Edit Text") ); + try + { + m_xUndoManager->postAction( C2U("Edit Text") ); + } + catch( uno::RuntimeException& e) + { + ASSERT_EXCEPTION( e ); + } } - catch( uno::RuntimeException& e) + else { - ASSERT_EXCEPTION( e ); + try + { + m_xUndoManager->cancelAction(); + } + catch ( uno::RuntimeException& e ) + { + ASSERT_EXCEPTION( e ); + } } } return true; diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx index a19e6dcd807d0..6a991b01ee3cb 100644 --- a/chart2/source/controller/main/ChartController_Tools.cxx +++ b/chart2/source/controller/main/ChartController_Tools.cxx @@ -79,10 +79,13 @@ // for SolarMutex #include <vcl/svapp.hxx> #include <vos/mutex.hxx> +#include <svx/dialmgr.hxx> +#include <svx/dialogs.hrc> // for OutlinerView #include <svx/outliner.hxx> #include <svx/svditer.hxx> #include <svx/svdpage.hxx> +#include <svx/svdundo.hxx> #include <svx/unoapi.hxx> #include <svx/unopage.hxx> @@ -413,13 +416,14 @@ void ChartController::impl_PasteGraphic( void ChartController::impl_PasteShapes( SdrModel* pModel ) { DrawModelWrapper* pDrawModelWrapper( this->GetDrawModelWrapper() ); - if ( pDrawModelWrapper ) + if ( pDrawModelWrapper && m_pDrawViewWrapper ) { Reference< drawing::XDrawPage > xDestPage( pDrawModelWrapper->getMainDrawPage() ); SdrPage* pDestPage = GetSdrPageFromXDrawPage( xDestPage ); if ( pDestPage ) { Reference< drawing::XShape > xSelShape; + m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) ); sal_uInt16 nCount = pModel->GetPageCount(); for ( sal_uInt16 i = 0; i < nCount; ++i ) { @@ -442,6 +446,7 @@ void ChartController::impl_PasteShapes( SdrModel* pModel ) } pDestPage->InsertObject( pNewObj ); + m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pNewObj ) ); xSelShape = xShape; } } @@ -456,6 +461,8 @@ void ChartController::impl_PasteShapes( SdrModel* pModel ) // select last inserted shape m_aSelection.setSelection( xSelShape ); m_aSelection.applySelection( m_pDrawViewWrapper ); + + m_pDrawViewWrapper->EndUndo(); } } } @@ -463,7 +470,7 @@ void ChartController::impl_PasteShapes( SdrModel* pModel ) void ChartController::impl_PasteStringAsTextShape( const OUString& rString, const awt::Point& rPosition ) { DrawModelWrapper* pDrawModelWrapper( this->GetDrawModelWrapper() ); - if ( pDrawModelWrapper ) + if ( pDrawModelWrapper && m_pDrawViewWrapper ) { const Reference< lang::XMultiServiceFactory >& xShapeFactory( pDrawModelWrapper->getShapeFactory() ); const Reference< drawing::XDrawPage >& xDrawPage( pDrawModelWrapper->getMainDrawPage() ); @@ -495,6 +502,14 @@ void ChartController::impl_PasteStringAsTextShape( const OUString& rString, cons m_aSelection.setSelection( xTextShape ); m_aSelection.applySelection( m_pDrawViewWrapper ); + + SdrObject* pObj = DrawViewWrapper::getSdrObject( xTextShape ); + if ( pObj ) + { + m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) ); + m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pObj ) ); + m_pDrawViewWrapper->EndUndo(); + } } catch ( const uno::Exception& ex ) { diff --git a/chart2/source/inc/UndoManager.hxx b/chart2/source/inc/UndoManager.hxx index 6c71e668a2b50..72cb5f85eb9d4 100644 --- a/chart2/source/inc/UndoManager.hxx +++ b/chart2/source/inc/UndoManager.hxx @@ -39,8 +39,9 @@ #include <com/sun/star/util/XModifyListener.hpp> #include <com/sun/star/chart2/XUndoManager.hpp> #include <com/sun/star/chart2/XUndoHelper.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> -#include <cppuhelper/compbase3.hxx> +#include <cppuhelper/compbase4.hxx> #include <rtl/ustring.hxx> // for pair @@ -48,6 +49,8 @@ // for auto_ptr #include <memory> +class SdrUndoAction; + namespace com { namespace sun { namespace star { namespace frame { class XModel; @@ -65,10 +68,11 @@ class UndoElement; class UndoStack; class ModifyBroadcaster; -typedef ::cppu::WeakComponentImplHelper3< +typedef ::cppu::WeakComponentImplHelper4< ::com::sun::star::util::XModifyBroadcaster, ::com::sun::star::chart2::XUndoManager, - ::com::sun::star::chart2::XUndoHelper > + ::com::sun::star::chart2::XUndoHelper, + ::com::sun::star::lang::XUnoTunnel > UndoManager_Base; } // namespace impl @@ -90,6 +94,15 @@ public: explicit UndoManager(); virtual ~UndoManager(); + void addShapeUndoAction( SdrUndoAction* pAction ); + + // ____ XUnoTunnel ____ + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) + throw (::com::sun::star::uno::RuntimeException); + + static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId(); + static UndoManager* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xObj ); + protected: // ____ ConfigItemListener ____ virtual void notify( const ::rtl::OUString & rPropertyName ); @@ -148,7 +161,8 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xCurrentModel, impl::UndoStack * pStackToRemoveFrom, - impl::UndoStack * pStackToAddTo ); + impl::UndoStack * pStackToAddTo, + bool bUndo = true ); ::std::auto_ptr< impl::UndoStack > m_apUndoStack; ::std::auto_ptr< impl::UndoStack > m_apRedoStack; diff --git a/chart2/source/tools/ImplUndoManager.cxx b/chart2/source/tools/ImplUndoManager.cxx index 91d5f869bc53d..bf5bfc7800ad4 100644 --- a/chart2/source/tools/ImplUndoManager.cxx +++ b/chart2/source/tools/ImplUndoManager.cxx @@ -110,7 +110,10 @@ UndoElement::~UndoElement() void UndoElement::initialize( const Reference< frame::XModel > & xModel ) { - m_xModel.set( UndoElement::cloneModel( xModel )); + if ( xModel.is() ) + { + m_xModel.set( UndoElement::cloneModel( xModel ) ); + } } void UndoElement::dispose() @@ -356,6 +359,29 @@ UndoElement * UndoElementWithSelection::createFromModel( 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() : diff --git a/chart2/source/tools/ImplUndoManager.hxx b/chart2/source/tools/ImplUndoManager.hxx index 94d04b69a5a40..62469f8b9dd6f 100644 --- a/chart2/source/tools/ImplUndoManager.hxx +++ b/chart2/source/tools/ImplUndoManager.hxx @@ -41,6 +41,9 @@ #include <utility> #include <deque> + +class SdrUndoAction; + namespace com { namespace sun { namespace star { namespace chart2 { class XInternalDataProvider; @@ -149,6 +152,19 @@ private: ::com::sun::star::uno::Any m_aSelection; }; +class ShapeUndoElement : public UndoElement +{ +public: + ShapeUndoElement( const ::rtl::OUString& rActionString, SdrUndoAction* pAction ); + ShapeUndoElement( const ShapeUndoElement& rOther ); + virtual ~ShapeUndoElement(); + + SdrUndoAction* getSdrUndoAction(); + +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 diff --git a/chart2/source/tools/UndoManager.cxx b/chart2/source/tools/UndoManager.cxx index e1542ade6020e..b280db180d024 100644 --- a/chart2/source/tools/UndoManager.cxx +++ b/chart2/source/tools/UndoManager.cxx @@ -44,6 +44,8 @@ #include <unotools/configitem.hxx> #include <cppuhelper/compbase1.hxx> +#include <rtl/uuid.h> +#include <svx/svdundo.hxx> #include <functional> @@ -134,10 +136,31 @@ UndoManager::~UndoManager() m_pLastRemeberedUndoElement = 0; } +void UndoManager::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(); + } +} + void UndoManager::impl_undoRedo( Reference< frame::XModel > & xCurrentModel, impl::UndoStack * pStackToRemoveFrom, - impl::UndoStack * pStackToAddTo ) + impl::UndoStack * pStackToAddTo, + bool bUndo ) { if( pStackToRemoveFrom && ! pStackToRemoveFrom->empty() ) { @@ -145,11 +168,32 @@ void UndoManager::impl_undoRedo( impl::UndoElement * pTop( pStackToRemoveFrom->top()); if( pTop ) { - // put a clone of current model into redo/undo stack with the same - // action string as the undo/redo - pStackToAddTo->push( pTop->createFromModel( xCurrentModel )); - // change current model by properties of the model from undo - pTop->applyToModel( xCurrentModel ); + 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( xCurrentModel )); + // change current model by properties of the model from undo + pTop->applyToModel( xCurrentModel ); + } // remove the top undo element pStackToRemoveFrom->pop(), pTop = 0; ChartViewHelper::setViewToDirtyState( xCurrentModel ); @@ -290,14 +334,14 @@ void SAL_CALL UndoManager::undo( Reference< frame::XModel >& xCurrentModel ) throw (uno::RuntimeException) { OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get()); - impl_undoRedo( xCurrentModel, m_apUndoStack.get(), m_apRedoStack.get()); + impl_undoRedo( xCurrentModel, m_apUndoStack.get(), m_apRedoStack.get(), true ); } void SAL_CALL UndoManager::redo( Reference< frame::XModel >& xCurrentModel ) throw (uno::RuntimeException) { OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get()); - impl_undoRedo( xCurrentModel, m_apRedoStack.get(), m_apUndoStack.get()); + impl_undoRedo( xCurrentModel, m_apRedoStack.get(), m_apUndoStack.get(), false ); } ::sal_Bool SAL_CALL UndoManager::undoPossible() @@ -352,4 +396,44 @@ void SAL_CALL UndoManager::applyModelContent( impl::UndoElement::applyModelContentToModel( xModelToChange, xModelToCopyFrom ); } +// ____ XUnoTunnel ____ +sal_Int64 UndoManager::getSomething( const Sequence< sal_Int8 >& rId ) + throw (uno::RuntimeException) +{ + if ( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ) ); + } + return 0; +} + +// static +const Sequence< sal_Int8 >& UndoManager::getUnoTunnelId() +{ + static Sequence< sal_Int8 >* pSeq = 0; + if( !pSeq ) + { + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +// static +UndoManager* UndoManager::getImplementation( const Reference< uno::XInterface > xObj ) +{ + UndoManager* pRet = NULL; + Reference< lang::XUnoTunnel > xUT( xObj, uno::UNO_QUERY ); + if ( xUT.is() ) + { + pRet = reinterpret_cast< UndoManager* >( sal::static_int_cast< sal_IntPtr >( xUT->getSomething( getUnoTunnelId() ) ) ); + } + return pRet; +} + } // namespace chart |