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