diff options
Diffstat (limited to 'sd/source/core/annotations/Annotation.cxx')
-rw-r--r-- | sd/source/core/annotations/Annotation.cxx | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/sd/source/core/annotations/Annotation.cxx b/sd/source/core/annotations/Annotation.cxx new file mode 100644 index 000000000000..b9a8bd9c0f6d --- /dev/null +++ b/sd/source/core/annotations/Annotation.cxx @@ -0,0 +1,445 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "osl/time.h" +#include "sal/config.h" + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/office/XAnnotation.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> + +#include <comphelper/processfactory.hxx> +#include <cppuhelper/propertysetmixin.hxx> +#include <cppuhelper/compbase1.hxx> +#include <cppuhelper/basemutex.hxx> + +#include "drawdoc.hxx" +#include "sdpage.hxx" +#include "textapi.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::office; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::geometry; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star; + +extern void NotifyDocumentEvent( SdDrawDocument* pDocument, const rtl::OUString& rEventName, const Reference< XInterface >& xSource ); + +namespace sd { + +class Annotation : private ::cppu::BaseMutex, + public ::cppu::WeakComponentImplHelper1< XAnnotation>, + public ::cppu::PropertySetMixin< XAnnotation > +{ +public: + explicit Annotation( const Reference< XComponentContext >& context, SdPage* pPage ); + + SdPage* GetPage() const { return mpPage; } + SdrModel* GetModel() { return (mpPage != 0) ? mpPage->GetModel() : 0; } + + // XInterface: + virtual Any SAL_CALL queryInterface(Type const & type) throw (RuntimeException); + virtual void SAL_CALL acquire() throw () { ::cppu::WeakComponentImplHelper1< XAnnotation >::acquire(); } + virtual void SAL_CALL release() throw () { ::cppu::WeakComponentImplHelper1< XAnnotation >::release(); } + + // ::com::sun::star::beans::XPropertySet: + virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException); + virtual void SAL_CALL setPropertyValue(const OUString & aPropertyName, const Any & aValue) throw (RuntimeException, UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException); + virtual Any SAL_CALL getPropertyValue(const OUString & PropertyName) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); + virtual void SAL_CALL addPropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); + virtual void SAL_CALL removePropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & aListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); + virtual void SAL_CALL addVetoableChangeListener(const OUString & PropertyName, const Reference< XVetoableChangeListener > & aListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); + virtual void SAL_CALL removeVetoableChangeListener(const OUString & PropertyName, const Reference< XVetoableChangeListener > & aListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); + + // ::com::sun::star::office::XAnnotation: + virtual ::com::sun::star::uno::Any SAL_CALL getAnchor() throw (::com::sun::star::uno::RuntimeException); + virtual RealPoint2D SAL_CALL getPosition() throw (RuntimeException); + virtual void SAL_CALL setPosition(const RealPoint2D & the_value) throw (RuntimeException); + virtual ::com::sun::star::geometry::RealSize2D SAL_CALL getSize() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setSize( const ::com::sun::star::geometry::RealSize2D& _size ) throw (::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getAuthor() throw (RuntimeException); + virtual void SAL_CALL setAuthor(const OUString & the_value) throw (RuntimeException); + virtual util::DateTime SAL_CALL getDateTime() throw (RuntimeException); + virtual void SAL_CALL setDateTime(const util::DateTime & the_value) throw (RuntimeException); + virtual Reference< XText > SAL_CALL getTextRange() throw (RuntimeException); + +private: + Annotation(const Annotation &); // not defined + Annotation& operator=(const Annotation &); // not defined + + // destructor is private and will be called indirectly by the release call virtual ~Annotation() {} + + void createChangeUndo(); + + // overload WeakComponentImplHelperBase::disposing() + // This function is called upon disposing the component, + // if your component needs special work when it becomes + // disposed, do it here. + virtual void SAL_CALL disposing(); + + SdPage* mpPage; + Reference< XComponentContext > m_xContext; + mutable ::osl::Mutex m_aMutex; + RealPoint2D m_Position; + RealSize2D m_Size; + OUString m_Author; + util::DateTime m_DateTime; + rtl::Reference< TextApiObject > m_TextRange; +}; + +class UndoInsertOrRemoveAnnotation : public SdrUndoAction +{ +public: + UndoInsertOrRemoveAnnotation( Annotation& rAnnotation, bool bInsert ); + + virtual void Undo(); + virtual void Redo(); + +protected: + rtl::Reference< Annotation > mxAnnotation; + bool mbInsert; + int mnIndex; +}; + +struct AnnotationData +{ + RealPoint2D m_Position; + RealSize2D m_Size; + OUString m_Author; + util::DateTime m_DateTime; + + void get( const rtl::Reference< Annotation >& xAnnotation ) + { + m_Position = xAnnotation->getPosition(); + m_Size = xAnnotation->getSize(); + m_Author = xAnnotation->getAuthor(); + m_DateTime = xAnnotation->getDateTime(); + } + + void set( const rtl::Reference< Annotation >& xAnnotation ) + { + xAnnotation->setPosition(m_Position); + xAnnotation->setSize(m_Size); + xAnnotation->setAuthor(m_Author); + xAnnotation->setDateTime(m_DateTime); + } +}; + +class UndoAnnotation : public SdrUndoAction +{ +public: + UndoAnnotation( Annotation& rAnnotation ); + + virtual void Undo(); + virtual void Redo(); + +protected: + rtl::Reference< Annotation > mxAnnotation; + AnnotationData maUndoData; + AnnotationData maRedoData; +}; + +void createAnnotation( Reference< XAnnotation >& xAnnotation, SdPage* pPage ) +{ + Reference<XComponentContext> xContext (comphelper_getProcessComponentContext()); + xAnnotation.set( new Annotation(xContext, pPage) ); + pPage->addAnnotation(xAnnotation); +} + +Annotation::Annotation( const Reference< XComponentContext >& context, SdPage* pPage ) +: ::cppu::WeakComponentImplHelper1< XAnnotation >(m_aMutex) +, ::cppu::PropertySetMixin< XAnnotation >(context, static_cast< Implements >(IMPLEMENTS_PROPERTY_SET), Sequence< ::rtl::OUString >()) +, mpPage( pPage ) +{ +} + +// overload WeakComponentImplHelperBase::disposing() +// This function is called upon disposing the component, +// if your component needs special work when it becomes +// disposed, do it here. +void SAL_CALL Annotation::disposing() +{ + mpPage = 0; + if( m_TextRange.is() ) + { + m_TextRange->dispose(); + m_TextRange.clear(); + } +} + +Any Annotation::queryInterface(Type const & type) throw (RuntimeException) +{ + return ::cppu::WeakComponentImplHelper1< XAnnotation>::queryInterface(type); +} + +// com.sun.star.beans.XPropertySet: +Reference< XPropertySetInfo > SAL_CALL Annotation::getPropertySetInfo() throw (RuntimeException) +{ + return ::cppu::PropertySetMixin< XAnnotation >::getPropertySetInfo(); +} + +void SAL_CALL Annotation::setPropertyValue(const OUString & aPropertyName, const Any & aValue) throw (RuntimeException, UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException) +{ + ::cppu::PropertySetMixin< XAnnotation >::setPropertyValue(aPropertyName, aValue); +} + +Any SAL_CALL Annotation::getPropertyValue(const OUString & aPropertyName) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) +{ + return ::cppu::PropertySetMixin< XAnnotation >::getPropertyValue(aPropertyName); +} + +void SAL_CALL Annotation::addPropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) +{ + ::cppu::PropertySetMixin< XAnnotation >::addPropertyChangeListener(aPropertyName, xListener); +} + +void SAL_CALL Annotation::removePropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) +{ + ::cppu::PropertySetMixin< XAnnotation >::removePropertyChangeListener(aPropertyName, xListener); +} + +void SAL_CALL Annotation::addVetoableChangeListener(const OUString & aPropertyName, const Reference< XVetoableChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) +{ + ::cppu::PropertySetMixin< XAnnotation >::addVetoableChangeListener(aPropertyName, xListener); +} + +void SAL_CALL Annotation::removeVetoableChangeListener(const OUString & aPropertyName, const Reference< XVetoableChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) +{ + ::cppu::PropertySetMixin< XAnnotation >::removeVetoableChangeListener(aPropertyName, xListener); +} + +Any SAL_CALL Annotation::getAnchor() throw (RuntimeException) +{ + osl::MutexGuard g(m_aMutex); + Any aRet; + if( mpPage ) + { + Reference< XDrawPage > xPage( mpPage->getUnoPage(), UNO_QUERY ); + aRet <<= xPage; + } + return aRet; +} + +// ::com::sun::star::office::XAnnotation: +RealPoint2D SAL_CALL Annotation::getPosition() throw (RuntimeException) +{ + osl::MutexGuard g(m_aMutex); + return m_Position; +} + +void SAL_CALL Annotation::setPosition(const RealPoint2D & the_value) throw (RuntimeException) +{ + prepareSet( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Position")), + Any(), Any(), 0); + { + osl::MutexGuard g(m_aMutex); + createChangeUndo(); + m_Position = the_value; + } +} + +// ::com::sun::star::office::XAnnotation: +RealSize2D SAL_CALL Annotation::getSize() throw (RuntimeException) +{ + osl::MutexGuard g(m_aMutex); + return m_Size; +} + +void SAL_CALL Annotation::setSize(const RealSize2D & the_value) throw (RuntimeException) +{ + prepareSet( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size")), + Any(), Any(), 0); + { + osl::MutexGuard g(m_aMutex); + createChangeUndo(); + m_Size = the_value; + } +} + +OUString SAL_CALL Annotation::getAuthor() throw (RuntimeException) +{ + osl::MutexGuard g(m_aMutex); + return m_Author; +} + +void SAL_CALL Annotation::setAuthor(const OUString & the_value) throw (RuntimeException) +{ + prepareSet( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Author")), + Any(), Any(), 0); + { + osl::MutexGuard g(m_aMutex); + createChangeUndo(); + m_Author = the_value; + } +} + +util::DateTime SAL_CALL Annotation::getDateTime() throw (RuntimeException) +{ + osl::MutexGuard g(m_aMutex); + return m_DateTime; +} + +void SAL_CALL Annotation::setDateTime(const util::DateTime & the_value) throw (RuntimeException) +{ + prepareSet( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DateTime")), + Any(), Any(), 0); + { + osl::MutexGuard g(m_aMutex); + createChangeUndo(); + m_DateTime = the_value; + } +} + +void Annotation::createChangeUndo() +{ + SdrModel* pModel = GetModel(); + if( pModel && pModel->IsUndoEnabled() ) + pModel->AddUndo( new UndoAnnotation( *this ) ); + + if( pModel ) + { + pModel->SetChanged(); + Reference< XInterface > xSource( static_cast<uno::XWeak*>( this ) ); + NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), OUString( RTL_CONSTASCII_USTRINGPARAM("OnAnnotationChanged") ), xSource ); + } +} + +Reference< XText > SAL_CALL Annotation::getTextRange() throw (RuntimeException) +{ + osl::MutexGuard g(m_aMutex); + if( !m_TextRange.is() && (mpPage != 0) ) + { + m_TextRange = TextApiObject::create( static_cast< SdDrawDocument* >( mpPage->GetModel() ) ); + } + return Reference< XText >( m_TextRange.get() ); +} + +SdrUndoAction* CreateUndoInsertOrRemoveAnnotation( const Reference< XAnnotation >& xAnnotation, bool bInsert ) +{ + Annotation* pAnnotation = dynamic_cast< Annotation* >( xAnnotation.get() ); + if( pAnnotation ) + { + return new UndoInsertOrRemoveAnnotation( *pAnnotation, bInsert ); + } + else + { + return 0; + } +} + +UndoInsertOrRemoveAnnotation::UndoInsertOrRemoveAnnotation( Annotation& rAnnotation, bool bInsert ) +: SdrUndoAction( *rAnnotation.GetModel() ) +, mxAnnotation( &rAnnotation ) +, mbInsert( bInsert ) +, mnIndex( 0 ) +{ + SdPage* pPage = rAnnotation.GetPage(); + if( pPage ) + { + Reference< XAnnotation > xAnnotation( &rAnnotation ); + + const AnnotationVector& rVec = pPage->getAnnotations(); + for( AnnotationVector::const_iterator iter = rVec.begin(); iter != rVec.end(); iter++ ) + { + if( (*iter) == xAnnotation ) + break; + + mnIndex++; + } + } +} + +void UndoInsertOrRemoveAnnotation::Undo() +{ + SdPage* pPage = mxAnnotation->GetPage(); + SdrModel* pModel = mxAnnotation->GetModel(); + if( pPage && pModel ) + { + Reference< XAnnotation > xAnnotation( mxAnnotation.get() ); + if( mbInsert ) + { + pPage->removeAnnotation( xAnnotation ); + } + else + { + pPage->addAnnotation( xAnnotation, mnIndex ); + } + } +} + +void UndoInsertOrRemoveAnnotation::Redo() +{ + SdPage* pPage = mxAnnotation->GetPage(); + SdrModel* pModel = mxAnnotation->GetModel(); + if( pPage && pModel ) + { + Reference< XAnnotation > xAnnotation( mxAnnotation.get() ); + + if( mbInsert ) + { + pPage->addAnnotation( xAnnotation, mnIndex ); + } + else + { + pPage->removeAnnotation( xAnnotation ); + } + } +} + +UndoAnnotation::UndoAnnotation( Annotation& rAnnotation ) +: SdrUndoAction( *rAnnotation.GetModel() ) +, mxAnnotation( &rAnnotation ) +{ + maUndoData.get( mxAnnotation ); +} + +void UndoAnnotation::Undo() +{ + maRedoData.get( mxAnnotation ); + maUndoData.set( mxAnnotation ); +} + +void UndoAnnotation::Redo() +{ + maUndoData.get( mxAnnotation ); + maRedoData.set( mxAnnotation ); +} + +} // namespace sd + |