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
GetPage() const65 SdPage* GetPage() const { return mpPage; }
GetModel()66 SdrModel* GetModel() { return (mpPage != 0) ? mpPage->GetModel() : 0; }
67
68 // XInterface:
69 virtual Any SAL_CALL queryInterface(Type const & type) throw (RuntimeException);
acquire()70 virtual void SAL_CALL acquire() throw () { ::cppu::WeakComponentImplHelper1< XAnnotation >::acquire(); }
release()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
getsd::AnnotationData139 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
setsd::AnnotationData147 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
createAnnotation(Reference<XAnnotation> & xAnnotation,SdPage * pPage)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
Annotation(const Reference<XComponentContext> & context,SdPage * pPage)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.
disposing()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
queryInterface(Type const & type)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:
getPropertySetInfo()204 Reference< XPropertySetInfo > SAL_CALL Annotation::getPropertySetInfo() throw (RuntimeException)
205 {
206 return ::cppu::PropertySetMixin< XAnnotation >::getPropertySetInfo();
207 }
208
setPropertyValue(const OUString & aPropertyName,const Any & aValue)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
getPropertyValue(const OUString & aPropertyName)214 Any SAL_CALL Annotation::getPropertyValue(const OUString & aPropertyName) throw (RuntimeException, UnknownPropertyException, WrappedTargetException)
215 {
216 return ::cppu::PropertySetMixin< XAnnotation >::getPropertyValue(aPropertyName);
217 }
218
addPropertyChangeListener(const OUString & aPropertyName,const Reference<XPropertyChangeListener> & xListener)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
removePropertyChangeListener(const OUString & aPropertyName,const Reference<XPropertyChangeListener> & xListener)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
addVetoableChangeListener(const OUString & aPropertyName,const Reference<XVetoableChangeListener> & xListener)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
removeVetoableChangeListener(const OUString & aPropertyName,const Reference<XVetoableChangeListener> & xListener)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
getAnchor()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:
getPosition()252 RealPoint2D SAL_CALL Annotation::getPosition() throw (RuntimeException)
253 {
254 osl::MutexGuard g(m_aMutex);
255 return m_Position;
256 }
257
setPosition(const RealPoint2D & the_value)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:
getSize()271 RealSize2D SAL_CALL Annotation::getSize() throw (RuntimeException)
272 {
273 osl::MutexGuard g(m_aMutex);
274 return m_Size;
275 }
276
setSize(const RealSize2D & the_value)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
getAuthor()289 OUString SAL_CALL Annotation::getAuthor() throw (RuntimeException)
290 {
291 osl::MutexGuard g(m_aMutex);
292 return m_Author;
293 }
294
setAuthor(const OUString & the_value)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
getDateTime()307 util::DateTime SAL_CALL Annotation::getDateTime() throw (RuntimeException)
308 {
309 osl::MutexGuard g(m_aMutex);
310 return m_DateTime;
311 }
312
setDateTime(const util::DateTime & the_value)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
createChangeUndo()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
getTextRange()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
CreateUndoInsertOrRemoveAnnotation(const Reference<XAnnotation> & xAnnotation,bool bInsert)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
UndoInsertOrRemoveAnnotation(Annotation & rAnnotation,bool bInsert)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
Undo()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
Redo()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
UndoAnnotation(Annotation & rAnnotation)421 UndoAnnotation::UndoAnnotation( Annotation& rAnnotation )
422 : SdrUndoAction( *rAnnotation.GetModel() )
423 , mxAnnotation( &rAnnotation )
424 {
425 maUndoData.get( mxAnnotation );
426 }
427
Undo()428 void UndoAnnotation::Undo()
429 {
430 maRedoData.get( mxAnnotation );
431 maUndoData.set( mxAnnotation );
432 }
433
Redo()434 void UndoAnnotation::Redo()
435 {
436 maUndoData.get( mxAnnotation );
437 maRedoData.set( mxAnnotation );
438 }
439
440 } // namespace sd
441
442