summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Benisch <tbe@openoffice.org>2009-09-29 11:03:35 +0000
committerThomas Benisch <tbe@openoffice.org>2009-09-29 11:03:35 +0000
commit189c8860787a5086061cb1960b00788c25ade73b (patch)
treede0317ed6fe52ae698336251dd47498de4d3dda6
parent63ec5317c74d46f2c8d4027a6571402caf262ed5 (diff)
#i12587# Inserting/editing arbitrary text objects in chart
-rw-r--r--chart2/source/controller/main/ChartController.cxx19
-rw-r--r--chart2/source/controller/main/ChartController.hxx2
-rw-r--r--chart2/source/controller/main/ChartController_TextEdit.cxx23
-rw-r--r--chart2/source/controller/main/ChartController_Tools.cxx19
-rw-r--r--chart2/source/inc/UndoManager.hxx22
-rw-r--r--chart2/source/tools/ImplUndoManager.cxx28
-rw-r--r--chart2/source/tools/ImplUndoManager.hxx16
-rw-r--r--chart2/source/tools/UndoManager.cxx100
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