#i12587# Inserting/editing arbitrary text objects in chart

This commit is contained in:
Thomas Benisch 2009-09-29 11:03:35 +00:00
parent 63ec5317c7
commit 189c886078
8 changed files with 208 additions and 21 deletions

View file

@ -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();
}

View file

@ -477,6 +477,8 @@ public:
bool isShapeContext() const;
DECL_LINK( NotifyUndoActionHdl, SdrUndoAction* );
public:
//-----------------------------------------------------------------
//-----------------------------------------------------------------

View file

@ -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;

View file

@ -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 )
{

View file

@ -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;

View file

@ -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() :

View file

@ -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

View file

@ -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