1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sd.hxx" 30 31 #include "osl/time.h" 32 #include "sal/config.h" 33 34 #include <com/sun/star/uno/XComponentContext.hpp> 35 #include <com/sun/star/office/XAnnotation.hpp> 36 #include <com/sun/star/drawing/XDrawPage.hpp> 37 38 #include <comphelper/processfactory.hxx> 39 #include <cppuhelper/propertysetmixin.hxx> 40 #include <cppuhelper/compbase1.hxx> 41 #include <cppuhelper/basemutex.hxx> 42 43 #include "drawdoc.hxx" 44 #include "sdpage.hxx" 45 #include "textapi.hxx" 46 47 using ::rtl::OUString; 48 using namespace ::com::sun::star::uno; 49 using namespace ::com::sun::star::lang; 50 using namespace ::com::sun::star::beans; 51 using namespace ::com::sun::star::office; 52 using namespace ::com::sun::star::drawing; 53 using namespace ::com::sun::star::geometry; 54 using namespace ::com::sun::star::text; 55 using namespace ::com::sun::star::util; 56 using namespace ::com::sun::star; 57 58 extern void NotifyDocumentEvent( SdDrawDocument* pDocument, const rtl::OUString& rEventName, const Reference< XInterface >& xSource ); 59 60 namespace sd { 61 62 class Annotation : private ::cppu::BaseMutex, 63 public ::cppu::WeakComponentImplHelper1< XAnnotation>, 64 public ::cppu::PropertySetMixin< XAnnotation > 65 { 66 public: 67 explicit Annotation( const Reference< XComponentContext >& context, SdPage* pPage ); 68 69 SdPage* GetPage() const { return mpPage; } 70 SdrModel* GetModel() { return (mpPage != 0) ? mpPage->GetModel() : 0; } 71 72 // XInterface: 73 virtual Any SAL_CALL queryInterface(Type const & type) throw (RuntimeException); 74 virtual void SAL_CALL acquire() throw () { ::cppu::WeakComponentImplHelper1< XAnnotation >::acquire(); } 75 virtual void SAL_CALL release() throw () { ::cppu::WeakComponentImplHelper1< XAnnotation >::release(); } 76 77 // ::com::sun::star::beans::XPropertySet: 78 virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException); 79 virtual void SAL_CALL setPropertyValue(const OUString & aPropertyName, const Any & aValue) throw (RuntimeException, UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException); 80 virtual Any SAL_CALL getPropertyValue(const OUString & PropertyName) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); 81 virtual void SAL_CALL addPropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); 82 virtual void SAL_CALL removePropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & aListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); 83 virtual void SAL_CALL addVetoableChangeListener(const OUString & PropertyName, const Reference< XVetoableChangeListener > & aListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); 84 virtual void SAL_CALL removeVetoableChangeListener(const OUString & PropertyName, const Reference< XVetoableChangeListener > & aListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException); 85 86 // ::com::sun::star::office::XAnnotation: 87 virtual ::com::sun::star::uno::Any SAL_CALL getAnchor() throw (::com::sun::star::uno::RuntimeException); 88 virtual RealPoint2D SAL_CALL getPosition() throw (RuntimeException); 89 virtual void SAL_CALL setPosition(const RealPoint2D & the_value) throw (RuntimeException); 90 virtual ::com::sun::star::geometry::RealSize2D SAL_CALL getSize() throw (::com::sun::star::uno::RuntimeException); 91 virtual void SAL_CALL setSize( const ::com::sun::star::geometry::RealSize2D& _size ) throw (::com::sun::star::uno::RuntimeException); 92 virtual OUString SAL_CALL getAuthor() throw (RuntimeException); 93 virtual void SAL_CALL setAuthor(const OUString & the_value) throw (RuntimeException); 94 virtual util::DateTime SAL_CALL getDateTime() throw (RuntimeException); 95 virtual void SAL_CALL setDateTime(const util::DateTime & the_value) throw (RuntimeException); 96 virtual Reference< XText > SAL_CALL getTextRange() throw (RuntimeException); 97 98 private: 99 Annotation(const Annotation &); // not defined 100 Annotation& operator=(const Annotation &); // not defined 101 102 // destructor is private and will be called indirectly by the release call virtual ~Annotation() {} 103 104 void createChangeUndo(); 105 106 // overload WeakComponentImplHelperBase::disposing() 107 // This function is called upon disposing the component, 108 // if your component needs special work when it becomes 109 // disposed, do it here. 110 virtual void SAL_CALL disposing(); 111 112 SdPage* mpPage; 113 Reference< XComponentContext > m_xContext; 114 mutable ::osl::Mutex m_aMutex; 115 RealPoint2D m_Position; 116 RealSize2D m_Size; 117 OUString m_Author; 118 util::DateTime m_DateTime; 119 rtl::Reference< TextApiObject > m_TextRange; 120 }; 121 122 class UndoInsertOrRemoveAnnotation : public SdrUndoAction 123 { 124 public: 125 UndoInsertOrRemoveAnnotation( Annotation& rAnnotation, bool bInsert ); 126 127 virtual void Undo(); 128 virtual void Redo(); 129 130 protected: 131 rtl::Reference< Annotation > mxAnnotation; 132 bool mbInsert; 133 int mnIndex; 134 }; 135 136 struct AnnotationData 137 { 138 RealPoint2D m_Position; 139 RealSize2D m_Size; 140 OUString m_Author; 141 util::DateTime m_DateTime; 142 143 void get( const rtl::Reference< Annotation >& xAnnotation ) 144 { 145 m_Position = xAnnotation->getPosition(); 146 m_Size = xAnnotation->getSize(); 147 m_Author = xAnnotation->getAuthor(); 148 m_DateTime = xAnnotation->getDateTime(); 149 } 150 151 void set( const rtl::Reference< Annotation >& xAnnotation ) 152 { 153 xAnnotation->setPosition(m_Position); 154 xAnnotation->setSize(m_Size); 155 xAnnotation->setAuthor(m_Author); 156 xAnnotation->setDateTime(m_DateTime); 157 } 158 }; 159 160 class UndoAnnotation : public SdrUndoAction 161 { 162 public: 163 UndoAnnotation( Annotation& rAnnotation ); 164 165 virtual void Undo(); 166 virtual void Redo(); 167 168 protected: 169 rtl::Reference< Annotation > mxAnnotation; 170 AnnotationData maUndoData; 171 AnnotationData maRedoData; 172 }; 173 174 void createAnnotation( Reference< XAnnotation >& xAnnotation, SdPage* pPage ) 175 { 176 Reference<XComponentContext> xContext (comphelper_getProcessComponentContext()); 177 xAnnotation.set( new Annotation(xContext, pPage) ); 178 pPage->addAnnotation(xAnnotation); 179 } 180 181 Annotation::Annotation( const Reference< XComponentContext >& context, SdPage* pPage ) 182 : ::cppu::WeakComponentImplHelper1< XAnnotation >(m_aMutex) 183 , ::cppu::PropertySetMixin< XAnnotation >(context, static_cast< Implements >(IMPLEMENTS_PROPERTY_SET), Sequence< ::rtl::OUString >()) 184 , mpPage( pPage ) 185 { 186 } 187 188 // overload WeakComponentImplHelperBase::disposing() 189 // This function is called upon disposing the component, 190 // if your component needs special work when it becomes 191 // disposed, do it here. 192 void SAL_CALL Annotation::disposing() 193 { 194 mpPage = 0; 195 if( m_TextRange.is() ) 196 { 197 m_TextRange->dispose(); 198 m_TextRange.clear(); 199 } 200 } 201 202 Any Annotation::queryInterface(Type const & type) throw (RuntimeException) 203 { 204 return ::cppu::WeakComponentImplHelper1< XAnnotation>::queryInterface(type); 205 } 206 207 // com.sun.star.beans.XPropertySet: 208 Reference< XPropertySetInfo > SAL_CALL Annotation::getPropertySetInfo() throw (RuntimeException) 209 { 210 return ::cppu::PropertySetMixin< XAnnotation >::getPropertySetInfo(); 211 } 212 213 void SAL_CALL Annotation::setPropertyValue(const OUString & aPropertyName, const Any & aValue) throw (RuntimeException, UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException) 214 { 215 ::cppu::PropertySetMixin< XAnnotation >::setPropertyValue(aPropertyName, aValue); 216 } 217 218 Any SAL_CALL Annotation::getPropertyValue(const OUString & aPropertyName) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) 219 { 220 return ::cppu::PropertySetMixin< XAnnotation >::getPropertyValue(aPropertyName); 221 } 222 223 void SAL_CALL Annotation::addPropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) 224 { 225 ::cppu::PropertySetMixin< XAnnotation >::addPropertyChangeListener(aPropertyName, xListener); 226 } 227 228 void SAL_CALL Annotation::removePropertyChangeListener(const OUString & aPropertyName, const Reference< XPropertyChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) 229 { 230 ::cppu::PropertySetMixin< XAnnotation >::removePropertyChangeListener(aPropertyName, xListener); 231 } 232 233 void SAL_CALL Annotation::addVetoableChangeListener(const OUString & aPropertyName, const Reference< XVetoableChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) 234 { 235 ::cppu::PropertySetMixin< XAnnotation >::addVetoableChangeListener(aPropertyName, xListener); 236 } 237 238 void SAL_CALL Annotation::removeVetoableChangeListener(const OUString & aPropertyName, const Reference< XVetoableChangeListener > & xListener) throw (RuntimeException, UnknownPropertyException, WrappedTargetException) 239 { 240 ::cppu::PropertySetMixin< XAnnotation >::removeVetoableChangeListener(aPropertyName, xListener); 241 } 242 243 Any SAL_CALL Annotation::getAnchor() throw (RuntimeException) 244 { 245 osl::MutexGuard g(m_aMutex); 246 Any aRet; 247 if( mpPage ) 248 { 249 Reference< XDrawPage > xPage( mpPage->getUnoPage(), UNO_QUERY ); 250 aRet <<= xPage; 251 } 252 return aRet; 253 } 254 255 // ::com::sun::star::office::XAnnotation: 256 RealPoint2D SAL_CALL Annotation::getPosition() throw (RuntimeException) 257 { 258 osl::MutexGuard g(m_aMutex); 259 return m_Position; 260 } 261 262 void SAL_CALL Annotation::setPosition(const RealPoint2D & the_value) throw (RuntimeException) 263 { 264 prepareSet( 265 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Position")), 266 Any(), Any(), 0); 267 { 268 osl::MutexGuard g(m_aMutex); 269 createChangeUndo(); 270 m_Position = the_value; 271 } 272 } 273 274 // ::com::sun::star::office::XAnnotation: 275 RealSize2D SAL_CALL Annotation::getSize() throw (RuntimeException) 276 { 277 osl::MutexGuard g(m_aMutex); 278 return m_Size; 279 } 280 281 void SAL_CALL Annotation::setSize(const RealSize2D & the_value) throw (RuntimeException) 282 { 283 prepareSet( 284 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size")), 285 Any(), Any(), 0); 286 { 287 osl::MutexGuard g(m_aMutex); 288 createChangeUndo(); 289 m_Size = the_value; 290 } 291 } 292 293 OUString SAL_CALL Annotation::getAuthor() throw (RuntimeException) 294 { 295 osl::MutexGuard g(m_aMutex); 296 return m_Author; 297 } 298 299 void SAL_CALL Annotation::setAuthor(const OUString & the_value) throw (RuntimeException) 300 { 301 prepareSet( 302 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Author")), 303 Any(), Any(), 0); 304 { 305 osl::MutexGuard g(m_aMutex); 306 createChangeUndo(); 307 m_Author = the_value; 308 } 309 } 310 311 util::DateTime SAL_CALL Annotation::getDateTime() throw (RuntimeException) 312 { 313 osl::MutexGuard g(m_aMutex); 314 return m_DateTime; 315 } 316 317 void SAL_CALL Annotation::setDateTime(const util::DateTime & the_value) throw (RuntimeException) 318 { 319 prepareSet( 320 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DateTime")), 321 Any(), Any(), 0); 322 { 323 osl::MutexGuard g(m_aMutex); 324 createChangeUndo(); 325 m_DateTime = the_value; 326 } 327 } 328 329 void Annotation::createChangeUndo() 330 { 331 SdrModel* pModel = GetModel(); 332 if( pModel && pModel->IsUndoEnabled() ) 333 pModel->AddUndo( new UndoAnnotation( *this ) ); 334 335 if( pModel ) 336 { 337 pModel->SetChanged(); 338 Reference< XInterface > xSource( static_cast<uno::XWeak*>( this ) ); 339 NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), OUString( RTL_CONSTASCII_USTRINGPARAM("OnAnnotationChanged") ), xSource ); 340 } 341 } 342 343 Reference< XText > SAL_CALL Annotation::getTextRange() throw (RuntimeException) 344 { 345 osl::MutexGuard g(m_aMutex); 346 if( !m_TextRange.is() && (mpPage != 0) ) 347 { 348 m_TextRange = TextApiObject::create( static_cast< SdDrawDocument* >( mpPage->GetModel() ) ); 349 } 350 return Reference< XText >( m_TextRange.get() ); 351 } 352 353 SdrUndoAction* CreateUndoInsertOrRemoveAnnotation( const Reference< XAnnotation >& xAnnotation, bool bInsert ) 354 { 355 Annotation* pAnnotation = dynamic_cast< Annotation* >( xAnnotation.get() ); 356 if( pAnnotation ) 357 { 358 return new UndoInsertOrRemoveAnnotation( *pAnnotation, bInsert ); 359 } 360 else 361 { 362 return 0; 363 } 364 } 365 366 UndoInsertOrRemoveAnnotation::UndoInsertOrRemoveAnnotation( Annotation& rAnnotation, bool bInsert ) 367 : SdrUndoAction( *rAnnotation.GetModel() ) 368 , mxAnnotation( &rAnnotation ) 369 , mbInsert( bInsert ) 370 , mnIndex( 0 ) 371 { 372 SdPage* pPage = rAnnotation.GetPage(); 373 if( pPage ) 374 { 375 Reference< XAnnotation > xAnnotation( &rAnnotation ); 376 377 const AnnotationVector& rVec = pPage->getAnnotations(); 378 for( AnnotationVector::const_iterator iter = rVec.begin(); iter != rVec.end(); iter++ ) 379 { 380 if( (*iter) == xAnnotation ) 381 break; 382 383 mnIndex++; 384 } 385 } 386 } 387 388 void UndoInsertOrRemoveAnnotation::Undo() 389 { 390 SdPage* pPage = mxAnnotation->GetPage(); 391 SdrModel* pModel = mxAnnotation->GetModel(); 392 if( pPage && pModel ) 393 { 394 Reference< XAnnotation > xAnnotation( mxAnnotation.get() ); 395 if( mbInsert ) 396 { 397 pPage->removeAnnotation( xAnnotation ); 398 } 399 else 400 { 401 pPage->addAnnotation( xAnnotation, mnIndex ); 402 } 403 } 404 } 405 406 void UndoInsertOrRemoveAnnotation::Redo() 407 { 408 SdPage* pPage = mxAnnotation->GetPage(); 409 SdrModel* pModel = mxAnnotation->GetModel(); 410 if( pPage && pModel ) 411 { 412 Reference< XAnnotation > xAnnotation( mxAnnotation.get() ); 413 414 if( mbInsert ) 415 { 416 pPage->addAnnotation( xAnnotation, mnIndex ); 417 } 418 else 419 { 420 pPage->removeAnnotation( xAnnotation ); 421 } 422 } 423 } 424 425 UndoAnnotation::UndoAnnotation( Annotation& rAnnotation ) 426 : SdrUndoAction( *rAnnotation.GetModel() ) 427 , mxAnnotation( &rAnnotation ) 428 { 429 maUndoData.get( mxAnnotation ); 430 } 431 432 void UndoAnnotation::Undo() 433 { 434 maRedoData.get( mxAnnotation ); 435 maUndoData.set( mxAnnotation ); 436 } 437 438 void UndoAnnotation::Redo() 439 { 440 maUndoData.get( mxAnnotation ); 441 maRedoData.set( mxAnnotation ); 442 } 443 444 } // namespace sd 445 446