xref: /trunk/main/sw/source/core/unocore/unodraw.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_sw.hxx"
30 
31 #include <swtypes.hxx>
32 #include <cmdid.h>
33 
34 #include <unomid.h>
35 #include <unodraw.hxx>
36 #include <unocoll.hxx>
37 #include <unoframe.hxx>
38 #include <unoparagraph.hxx>
39 #include <unotextrange.hxx>
40 #include <unoprnms.hxx>
41 #include <editeng/unoprnms.hxx>
42 #include <svx/svditer.hxx>
43 #include <swunohelper.hxx>
44 #include <doc.hxx>
45 #include <IDocumentUndoRedo.hxx>
46 #include <fmtcntnt.hxx>
47 #include <fmtflcnt.hxx>
48 #include <txtatr.hxx>
49 #include <docsh.hxx>
50 #include <unomap.hxx>
51 #include <unoport.hxx>
52 #include <unocrsr.hxx>
53 #include <TextCursorHelper.hxx>
54 #include <swundo.hxx>
55 #include <dflyobj.hxx>
56 #include <ndtxt.hxx>
57 #include <svx/svdview.hxx>
58 #include <svx/unoshape.hxx>
59 #include <dcontact.hxx>
60 #include <svx/fmglob.hxx>
61 #include <fmtornt.hxx>
62 #include <fmtanchr.hxx>
63 #include <fmtsrnd.hxx>
64 #include <fmtfollowtextflow.hxx>
65 #include <rootfrm.hxx>
66 #include <editeng/lrspitem.hxx>
67 #include <editeng/ulspitem.hxx>
68 #include <svx/shapepropertynotifier.hxx>
69 #include <crstate.hxx>
70 #include <vos/mutex.hxx>
71 #include <comphelper/extract.hxx>
72 #include <comphelper/stl_types.hxx>
73 #include <comphelper/makesequence.hxx>
74 #include <svx/scene3d.hxx>
75 #include <com/sun/star/beans/PropertyAttribute.hpp>
76 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
77 #include <com/sun/star/text/HoriOrientation.hpp>
78 #include <com/sun/star/text/VertOrientation.hpp>
79 #include <basegfx/numeric/ftools.hxx>
80 #include <algorithm>
81 #include <fmtwrapinfluenceonobjpos.hxx>
82 #include <com/sun/star/text/TextContentAnchorType.hpp>
83 #include <basegfx/matrix/b2dhommatrix.hxx>
84 #include <basegfx/matrix/b2dhommatrixtools.hxx>
85 #include <com/sun/star/drawing/PointSequence.hpp>
86 #include <vcl/svapp.hxx>
87 #include <slist>
88 #include <iterator>
89 #include <switerator.hxx>
90 
91 using ::rtl::OUString;
92 using namespace ::com::sun::star;
93 
94 DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence< sal_Int8 > *,  SwShapeImplementationIdMap );
95 
96 static SwShapeImplementationIdMap aImplementationIdMap;
97 
98 class SwShapeDescriptor_Impl
99 {
100     SwFmtHoriOrient*    pHOrient;
101     SwFmtVertOrient*    pVOrient;
102     SwFmtAnchor*        pAnchor;
103     SwFmtSurround*      pSurround;
104     SvxULSpaceItem*     pULSpace;
105     SvxLRSpaceItem*     pLRSpace;
106     sal_Bool            bOpaque;
107     uno::Reference< text::XTextRange > xTextRange;
108     // OD 2004-04-21 #i26791#
109     SwFmtFollowTextFlow* mpFollowTextFlow;
110     // OD 2004-05-05 #i28701# - add property 'WrapInfluenceOnObjPos'
111     SwFmtWrapInfluenceOnObjPos* pWrapInfluenceOnObjPos;
112     // --> OD 2004-08-06 #i28749#
113     sal_Int16 mnPositionLayoutDir;
114     // <--
115 
116 public:
117     bool    bInitializedPropertyNotifier;
118 
119 public:
120     SwShapeDescriptor_Impl() :
121      // --> OD 2004-08-18 #i32349# - no defaults, in order to determine on
122      // adding a shape, if positioning attributes are set or not.
123      pHOrient( 0L ),
124      pVOrient( 0L ),
125      // <--
126      pAnchor(0),
127      pSurround(0),
128      pULSpace(0),
129      pLRSpace(0),
130      bOpaque(sal_False),
131      // OD 2004-04-21 #i26791#
132      mpFollowTextFlow( new SwFmtFollowTextFlow( sal_False ) ),
133      // OD 2004-05-05 #i28701#
134      // --> OD 2004-10-18 #i35017# - constant name has changed
135      pWrapInfluenceOnObjPos( new SwFmtWrapInfluenceOnObjPos(
136                             text::WrapInfluenceOnPosition::ONCE_CONCURRENT ) ),
137      // <--
138      // --> OD 2004-08-06 #i28749#
139      mnPositionLayoutDir( text::PositionLayoutDir::PositionInLayoutDirOfAnchor ),
140      bInitializedPropertyNotifier(false)
141      {}
142 
143     ~SwShapeDescriptor_Impl()
144     {
145         delete pHOrient;
146         delete pVOrient;
147         delete pAnchor;
148         delete pSurround;
149         delete pULSpace;
150         delete pLRSpace;
151         // OD 2004-04-22 #i26791#
152         delete mpFollowTextFlow;
153         // OD 2004-05-05 #i28701#
154         delete pWrapInfluenceOnObjPos;
155     }
156     SwFmtAnchor*    GetAnchor(sal_Bool bCreate = sal_False)
157         {
158             if(bCreate && !pAnchor)
159             {
160                 pAnchor = new SwFmtAnchor(FLY_AS_CHAR);
161             }
162             return pAnchor;
163         }
164     SwFmtHoriOrient* GetHOrient(sal_Bool bCreate = sal_False)
165         {
166             if (bCreate && !pHOrient)
167             {
168                 // OD 2004-06-03 #i26791# - change default
169                 pHOrient = new SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
170             }
171             return pHOrient;
172         }
173     SwFmtVertOrient* GetVOrient(sal_Bool bCreate = sal_False)
174         {
175             if(bCreate && !pVOrient)
176             {
177                 // OD 2004-04-21 #i26791# - change default
178                 pVOrient = new SwFmtVertOrient( 0, text::VertOrientation::NONE, text::RelOrientation::FRAME );
179             }
180             return pVOrient;
181         }
182 
183     SwFmtSurround*  GetSurround(sal_Bool bCreate = sal_False)
184         {
185             if(bCreate && !pSurround)
186                 pSurround = new SwFmtSurround();
187             return pSurround;
188         }
189     SvxLRSpaceItem* GetLRSpace(sal_Bool bCreate = sal_False)
190         {
191             if(bCreate && !pLRSpace)
192                 pLRSpace = new SvxLRSpaceItem(RES_LR_SPACE);
193             return pLRSpace;
194         }
195     SvxULSpaceItem* GetULSpace(sal_Bool bCreate = sal_False)
196         {
197             if(bCreate && !pULSpace)
198                 pULSpace = new SvxULSpaceItem(RES_UL_SPACE);
199             return pULSpace;
200         }
201     uno::Reference< text::XTextRange > &    GetTextRange()
202     {
203         return xTextRange;
204     }
205     sal_Bool    IsOpaque()
206         {
207             return bOpaque;
208         }
209     const sal_Bool&    GetOpaque()
210         {
211             return bOpaque;
212         }
213     void RemoveHOrient(){DELETEZ(pHOrient);}
214     void RemoveVOrient(){DELETEZ(pVOrient);}
215     void RemoveAnchor(){DELETEZ(pAnchor);}
216     void RemoveSurround(){DELETEZ(pSurround);}
217     void RemoveULSpace(){DELETEZ(pULSpace);}
218     void RemoveLRSpace(){DELETEZ(pLRSpace);}
219     void SetOpaque(sal_Bool bSet){bOpaque = bSet;}
220 
221     // OD 2004-04-21 #i26791#
222     SwFmtFollowTextFlow* GetFollowTextFlow( sal_Bool _bCreate = sal_False )
223     {
224         if ( _bCreate && !mpFollowTextFlow )
225             mpFollowTextFlow = new SwFmtFollowTextFlow( sal_False );
226         return mpFollowTextFlow;
227     }
228     void RemoveFollowTextFlow()
229     {
230         DELETEZ(mpFollowTextFlow);
231     }
232 
233     // --> OD 2004-08-06 #i28749#
234     sal_Int16 GetPositionLayoutDir() const
235     {
236         return mnPositionLayoutDir;
237     }
238     void SetPositionLayoutDir( sal_Int16 _nPositionLayoutDir )
239     {
240         switch ( _nPositionLayoutDir )
241         {
242             case text::PositionLayoutDir::PositionInHoriL2R:
243             case text::PositionLayoutDir::PositionInLayoutDirOfAnchor:
244             {
245                 mnPositionLayoutDir = _nPositionLayoutDir;
246             }
247             break;
248             default:
249             {
250                 ASSERT( false,
251                         "<SwShapeDescriptor_Impl::SetPositionLayoutDir(..)> - invalid attribute value." );
252             }
253         }
254     }
255     void RemovePositionLayoutDir()
256     {
257         mnPositionLayoutDir = text::PositionLayoutDir::PositionInLayoutDirOfAnchor;
258     }
259     // <--
260 
261     // OD 2004-05-05 #i28701#
262     inline SwFmtWrapInfluenceOnObjPos* GetWrapInfluenceOnObjPos(
263                                         const sal_Bool _bCreate = sal_False )
264     {
265         if ( _bCreate && !pWrapInfluenceOnObjPos )
266         {
267             pWrapInfluenceOnObjPos = new SwFmtWrapInfluenceOnObjPos(
268                         // --> OD 2004-10-18 #i35017# - constant name has changed
269                         text::WrapInfluenceOnPosition::ONCE_CONCURRENT );
270                         // <--
271         }
272         return pWrapInfluenceOnObjPos;
273     }
274     inline void RemoveWrapInfluenceOnObjPos()
275     {
276         DELETEZ(pWrapInfluenceOnObjPos);
277     }
278 };
279 /****************************************************************************
280     class SwFmDrawPage
281 ****************************************************************************/
282 
283 SwFmDrawPage::SwFmDrawPage( SdrPage* pPage ) :
284     SvxFmDrawPage( pPage ), pPageView(0)
285 {
286 }
287 
288 SwFmDrawPage::~SwFmDrawPage() throw ()
289 {
290     RemovePageView();
291 }
292 
293 const SdrMarkList&  SwFmDrawPage::PreGroup(const uno::Reference< drawing::XShapes > & xShapes)
294 {
295     _SelectObjectsInView( xShapes, GetPageView() );
296     const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
297     return rMarkList;
298 }
299 
300 void SwFmDrawPage::PreUnGroup(const uno::Reference< drawing::XShapeGroup >  xShapeGroup)
301 {
302     uno::Reference< drawing::XShape >  xShape( xShapeGroup, uno::UNO_QUERY);
303     _SelectObjectInView( xShape, GetPageView() );
304 }
305 
306 SdrPageView*    SwFmDrawPage::GetPageView()
307 {
308     if(!pPageView)
309         pPageView = mpView->ShowSdrPage( mpPage );
310     return pPageView;
311 }
312 
313 void    SwFmDrawPage::RemovePageView()
314 {
315     if(pPageView && mpView)
316         mpView->HideSdrPage();
317     pPageView = 0;
318 }
319 
320 uno::Reference< uno::XInterface >   SwFmDrawPage::GetInterface( SdrObject* pObj )
321 {
322     uno::Reference< XInterface >  xShape;
323     if( pObj )
324     {
325         SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
326         SwXShape* pxShape = SwIterator<SwXShape,SwFmt>::FirstElement( *pFmt );
327         if(pxShape)
328         {
329             xShape =  *(cppu::OWeakObject*)pxShape;
330         }
331         else
332             xShape = pObj->getUnoShape();
333     }
334     return xShape;
335 }
336 
337 SdrObject* SwFmDrawPage::_CreateSdrObject( const uno::Reference< drawing::XShape > & xShape ) throw ()
338 {
339     //TODO: stimmt das so - kann die Methode weg?
340     return SvxFmDrawPage::_CreateSdrObject( xShape );
341 }
342 
343 uno::Reference< drawing::XShape >  SwFmDrawPage::_CreateShape( SdrObject *pObj ) const throw ()
344 {
345     uno::Reference< drawing::XShape >  xRet;
346     if(pObj->ISA(SwVirtFlyDrawObj) || pObj->GetObjInventor() == SWGInventor)
347     {
348         SwFlyDrawContact* pFlyContact = (SwFlyDrawContact*)pObj->GetUserCall();
349         if(pFlyContact)
350         {
351             FlyCntType eType = FLYCNTTYPE_ALL;
352             SwFrmFmt* pFlyFmt = pFlyContact->GetFmt();
353             SwDoc* pDoc = pFlyFmt->GetDoc();
354             const SwNodeIndex* pIdx;
355             if( RES_FLYFRMFMT == pFlyFmt->Which()
356                 && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
357                 && pIdx->GetNodes().IsDocNodes()
358                 )
359             {
360                 const SwNode* pNd = pDoc->GetNodes()[ pIdx->GetIndex() + 1 ];
361                 if(!pNd->IsNoTxtNode())
362                     eType = FLYCNTTYPE_FRM;
363                 else if( pNd->IsGrfNode() )
364                     eType = FLYCNTTYPE_GRF;
365                 else if( pNd->IsOLENode() )
366                     eType = FLYCNTTYPE_OLE;
367             }
368             else
369             {
370                 ASSERT( false,
371                         "<SwFmDrawPage::_CreateShape(..)> - could not retrieve type. Thus, no shape created." );
372                 return xRet;
373             }
374             DBG_ASSERT( eType != FLYCNTTYPE_ALL, "unexpected FlyCntType value for eType" );
375             xRet = SwXFrames::GetObject( *pFlyFmt, eType );
376         }
377     }
378     else
379     {
380         // own block - temporary object has to be destroyed before
381         // the delegator is set #81670#
382         {
383             xRet = SvxFmDrawPage::_CreateShape( pObj );
384         }
385         uno::Reference< XUnoTunnel > xShapeTunnel(xRet, uno::UNO_QUERY);
386         //don't create an SwXShape if it already exists
387         SwXShape* pShape = 0;
388         if(xShapeTunnel.is())
389             pShape = reinterpret_cast< SwXShape * >(
390                     sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SwXShape::getUnoTunnelId()) ));
391         if(!pShape)
392         {
393             xShapeTunnel = 0;
394             uno::Reference< uno::XInterface > xCreate(xRet, uno::UNO_QUERY);
395             xRet = 0;
396             uno::Reference< beans::XPropertySet >  xPrSet;
397             if ( pObj->IsGroupObject() && (!pObj->Is3DObj() || ( PTR_CAST(E3dScene,pObj ) != NULL ) ) )
398                 xPrSet = new SwXGroupShape( xCreate );
399             else
400                 xPrSet = new SwXShape( xCreate );
401             xRet = uno::Reference< drawing::XShape >(xPrSet, uno::UNO_QUERY);
402         }
403     }
404     return xRet;
405 }
406 
407 /****************************************************************************
408     class SwXShapesEnumeration
409 ****************************************************************************/
410 namespace
411 {
412     class SwXShapesEnumeration
413         : public SwSimpleEnumeration_Base
414     {
415         private:
416             typedef ::std::slist< ::com::sun::star::uno::Any > shapescontainer_t;
417             shapescontainer_t m_aShapes;
418         protected:
419             virtual ~SwXShapesEnumeration() {};
420         public:
421             SwXShapesEnumeration(SwXDrawPage* const pDrawPage);
422 
423             //XEnumeration
424             virtual sal_Bool SAL_CALL hasMoreElements(void) throw(uno::RuntimeException);
425             virtual uno::Any SAL_CALL nextElement(void) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
426 
427             //XServiceInfo
428             virtual OUString SAL_CALL getImplementationName(void) throw(uno::RuntimeException);
429             virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(uno::RuntimeException);
430             virtual uno::Sequence<OUString> SAL_CALL getSupportedServiceNames(void) throw(uno::RuntimeException);
431     };
432 }
433 
434 SwXShapesEnumeration::SwXShapesEnumeration(SwXDrawPage* const pDrawPage)
435     : m_aShapes()
436 {
437     vos::OGuard aGuard(Application::GetSolarMutex());
438     ::std::insert_iterator<shapescontainer_t> pInserter = ::std::insert_iterator<shapescontainer_t>(m_aShapes, m_aShapes.begin());
439     sal_Int32 nCount = pDrawPage->getCount();
440     for(sal_Int32 nIdx = 0; nIdx < nCount; nIdx++)
441     {
442         uno::Reference<drawing::XShape> xShape = uno::Reference<drawing::XShape>(pDrawPage->getByIndex(nIdx), uno::UNO_QUERY);
443         *pInserter++ = uno::makeAny(xShape);
444     }
445 }
446 
447 sal_Bool SwXShapesEnumeration::hasMoreElements(void) throw(uno::RuntimeException)
448 {
449     vos::OGuard aGuard(Application::GetSolarMutex());
450     return !m_aShapes.empty();
451 }
452 
453 uno::Any SwXShapesEnumeration::nextElement(void) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
454 {
455     vos::OGuard aGuard(Application::GetSolarMutex());
456     if(m_aShapes.empty())
457         throw container::NoSuchElementException();
458     uno::Any aResult = *m_aShapes.begin();
459     m_aShapes.pop_front();
460     return aResult;
461 }
462 
463 OUString SwXShapesEnumeration::getImplementationName(void) throw(uno::RuntimeException)
464 {
465     return C2U("SwXShapeEnumeration");
466 }
467 
468 sal_Bool SwXShapesEnumeration::supportsService(const OUString& ServiceName) throw(uno::RuntimeException)
469 {
470     return C2U("com.sun.star.container.XEnumeration") == ServiceName;
471 }
472 
473 uno::Sequence< OUString > SwXShapesEnumeration::getSupportedServiceNames(void) throw(uno::RuntimeException)
474 {
475     return ::comphelper::makeSequence(C2U("com.sun.star.container.XEnumeration"));
476 }
477 /****************************************************************************
478     class SwXDrawPage
479 ****************************************************************************/
480 uno::Reference< container::XEnumeration > SwXDrawPage::createEnumeration(void) throw( uno::RuntimeException )
481 {
482     vos::OGuard aGuard(Application::GetSolarMutex());
483     return uno::Reference< container::XEnumeration >(
484         new SwXShapesEnumeration(this));
485 }
486 
487 rtl::OUString SwXDrawPage::getImplementationName(void) throw( uno::RuntimeException )
488 {
489     return C2U("SwXDrawPage");
490 }
491 
492 sal_Bool SwXDrawPage::supportsService(const rtl::OUString& rServiceName) throw( uno::RuntimeException )
493 {
494     return C2U("com.sun.star.drawing.GenericDrawPage") == rServiceName;
495 }
496 
497 uno::Sequence< rtl::OUString > SwXDrawPage::getSupportedServiceNames(void) throw( uno::RuntimeException )
498 {
499     uno::Sequence< rtl::OUString > aRet(1);
500     rtl::OUString* pArray = aRet.getArray();
501     pArray[0] = C2U("com.sun.star.drawing.GenericDrawPage");
502     return aRet;
503 }
504 
505 SwXDrawPage::SwXDrawPage(SwDoc* pDc) :
506     pDoc(pDc),
507     pDrawPage(0)
508 {
509 }
510 
511 SwXDrawPage::~SwXDrawPage()
512 {
513     if(xPageAgg.is())
514     {
515         uno::Reference< uno::XInterface >  xInt;
516         xPageAgg->setDelegator(xInt);
517     }
518 }
519 
520 uno::Any SwXDrawPage::queryInterface( const uno::Type& aType )
521                                                 throw( uno::RuntimeException )
522 {
523     uno::Any aRet = SwXDrawPageBaseClass::queryInterface(aType);
524     if(!aRet.hasValue())
525     {
526         // secure with checking if page exists. This may not be the case
527         // either for new SW docs with no yet graphics usage or when
528         // the doc is closed and someone else still holds a UNO reference
529         // to the XDrawPage (in that case, pDoc is set to 0)
530         SwFmDrawPage* pPage = GetSvxPage();
531 
532         if(pPage)
533         {
534             aRet = pPage->queryAggregation(aType);
535         }
536     }
537     return aRet;
538 }
539 
540 uno::Sequence< uno::Type > SwXDrawPage::getTypes() throw( uno::RuntimeException )
541 {
542     uno::Sequence< uno::Type > aPageTypes = SwXDrawPageBaseClass::getTypes();
543     uno::Sequence< uno::Type > aSvxTypes = GetSvxPage()->getTypes();
544 
545     long nIndex = aPageTypes.getLength();
546     aPageTypes.realloc(aPageTypes.getLength() + aSvxTypes.getLength() + 1);
547 
548     uno::Type* pPageTypes = aPageTypes.getArray();
549     const uno::Type* pSvxTypes = aSvxTypes.getConstArray();
550     long nPos;
551     for(nPos = 0; nPos < aSvxTypes.getLength(); nPos++)
552     {
553         pPageTypes[nIndex++] = pSvxTypes[nPos];
554     }
555     pPageTypes[nIndex] = ::getCppuType((uno::Reference<form::XFormsSupplier2>*)0);
556     return aPageTypes;
557 }
558 
559 sal_Int32 SwXDrawPage::getCount(void) throw( uno::RuntimeException )
560 {
561     vos::OGuard  aGuard(Application::GetSolarMutex());
562     if(!pDoc)
563         throw uno::RuntimeException();
564     if(!pDoc->GetDrawModel())
565         return 0;
566     else
567     {
568         ((SwXDrawPage*)this)->GetSvxPage();
569         return pDrawPage->getCount();
570     }
571 }
572 
573 uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex)
574         throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException,
575                uno::RuntimeException )
576 {
577     vos::OGuard  aGuard(Application::GetSolarMutex());
578     if(!pDoc)
579         throw uno::RuntimeException();
580     if(!pDoc->GetDrawModel())
581         throw lang::IndexOutOfBoundsException();
582 
583     ((SwXDrawPage*)this)->GetSvxPage();
584     return pDrawPage->getByIndex( nIndex );
585 }
586 
587 uno::Type  SwXDrawPage::getElementType(void) throw( uno::RuntimeException )
588 {
589     return ::getCppuType((const uno::Reference<drawing::XShape>*)0);
590 }
591 
592 sal_Bool SwXDrawPage::hasElements(void) throw( uno::RuntimeException )
593 {
594     vos::OGuard  aGuard(Application::GetSolarMutex());
595     if(!pDoc)
596         throw uno::RuntimeException();
597     if(!pDoc->GetDrawModel())
598         return sal_False;
599     else
600         return ((SwXDrawPage*)this)->GetSvxPage()->hasElements();
601 }
602 
603 void SwXDrawPage::add(const uno::Reference< drawing::XShape > & xShape)
604     throw( uno::RuntimeException )
605 {
606     vos::OGuard  aGuard(Application::GetSolarMutex());
607     if(!pDoc)
608         throw uno::RuntimeException();
609     uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShape, uno::UNO_QUERY);
610     SwXShape* pShape = 0;
611     SvxShape* pSvxShape = 0;
612     if(xShapeTunnel.is())
613     {
614         pShape      = reinterpret_cast< SwXShape * >(
615                 sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SwXShape::getUnoTunnelId()) ));
616         pSvxShape   = reinterpret_cast< SvxShape * >(
617                 sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SvxShape::getUnoTunnelId()) ));
618     }
619 
620     if(!pShape || pShape->GetRegisteredIn() || !pShape->m_bDescriptor )
621     {
622         uno::RuntimeException aExcept;
623         if(pShape)
624             aExcept.Message = C2U("object already inserted");
625         else
626             aExcept.Message = C2U("illegal object");
627         throw aExcept;
628     }
629 
630     // --> OD, HB
631     if ( pSvxShape->GetSdrObject() )
632     {
633         if ( pSvxShape->GetSdrObject()->IsInserted() )
634         {
635             return;
636         }
637     }
638     // <--
639     GetSvxPage()->add(xShape);
640 
641     uno::Reference< uno::XAggregation >     xAgg = pShape->GetAggregationInterface();
642 
643     DBG_ASSERT(pSvxShape, "warum gibt es hier kein SvxShape?");
644     //diese Position ist auf jeden Fall in 1/100 mm
645     awt::Point aMM100Pos(pSvxShape->getPosition());
646 
647     //jetzt noch die Properties aus dem SwShapeDescriptor_Impl auswerten
648     SwShapeDescriptor_Impl* pDesc = pShape->GetDescImpl();
649 
650     SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
651                                         RES_FRMATR_END-1 );
652     SwFmtAnchor aAnchor( FLY_AS_CHAR );
653     sal_Bool bOpaque = sal_False;
654     if( pDesc )
655     {
656         if(pDesc->GetSurround())
657             aSet.Put( *pDesc->GetSurround());
658         //die Items sind schon in Twip gesetzt
659         if(pDesc->GetLRSpace())
660         {
661             aSet.Put(*pDesc->GetLRSpace());
662         }
663         if(pDesc->GetULSpace())
664         {
665             aSet.Put(*pDesc->GetULSpace());
666         }
667         if(pDesc->GetAnchor())
668             aAnchor = *pDesc->GetAnchor();
669 
670         // --> OD 2004-08-18 #i32349# - if no horizontal position exists, create one
671         if ( !pDesc->GetHOrient() )
672         {
673             SwFmtHoriOrient* pHori = pDesc->GetHOrient( sal_True );
674             SwTwips nHoriPos = MM100_TO_TWIP(aMM100Pos.X);
675             pHori->SetPos( nHoriPos );
676         }
677         // <--
678         {
679             if(pDesc->GetHOrient()->GetHoriOrient() == text::HoriOrientation::NONE)
680                 aMM100Pos.X = TWIP_TO_MM100(pDesc->GetHOrient()->GetPos());
681             aSet.Put( *pDesc->GetHOrient() );
682         }
683         // --> OD 2004-08-18 #i32349# - if no vertical position exists, create one
684         if ( !pDesc->GetVOrient() )
685         {
686             SwFmtVertOrient* pVert = pDesc->GetVOrient( sal_True );
687             SwTwips nVertPos = MM100_TO_TWIP(aMM100Pos.Y);
688             pVert->SetPos( nVertPos );
689         }
690         // <--
691         {
692             if(pDesc->GetVOrient()->GetVertOrient() == text::VertOrientation::NONE)
693                 aMM100Pos.Y = TWIP_TO_MM100(pDesc->GetVOrient()->GetPos());
694             aSet.Put( *pDesc->GetVOrient() );
695         }
696 
697         if(pDesc->GetSurround())
698             aSet.Put( *pDesc->GetSurround());
699         bOpaque = pDesc->IsOpaque();
700 
701         // OD 2004-04-22 #i26791#
702         if ( pDesc->GetFollowTextFlow() )
703         {
704             aSet.Put( *pDesc->GetFollowTextFlow() );
705         }
706 
707         // OD 2004-05-05 #i28701#
708         if ( pDesc->GetWrapInfluenceOnObjPos() )
709         {
710             aSet.Put( *pDesc->GetWrapInfluenceOnObjPos() );
711         }
712     }
713 
714     pSvxShape->setPosition(aMM100Pos);
715     SdrObject* pObj = pSvxShape->GetSdrObject();
716     // OD 25.06.2003 #108784# - set layer of new drawing object to corresponding
717     // invisible layer.
718     if(FmFormInventor != pObj->GetObjInventor())
719         pObj->SetLayer( bOpaque ? pDoc->GetInvisibleHeavenId() : pDoc->GetInvisibleHellId() );
720     else
721         pObj->SetLayer(pDoc->GetInvisibleControlsId());
722 
723     SwPaM* pPam = new SwPaM(pDoc->GetNodes().GetEndOfContent());
724     SwUnoInternalPaM* pInternalPam = 0;
725     uno::Reference< text::XTextRange >  xRg;
726     if( pDesc && (xRg = pDesc->GetTextRange()).is() )
727     {
728         pInternalPam = new SwUnoInternalPaM(*pDoc);
729         if (::sw::XTextRangeToSwPaM(*pInternalPam, xRg))
730         {
731             if(FLY_AT_FLY == aAnchor.GetAnchorId() &&
732                                 !pInternalPam->GetNode()->FindFlyStartNode())
733             {
734                         aAnchor.SetType(FLY_AS_CHAR);
735             }
736             else if (FLY_AT_PAGE == aAnchor.GetAnchorId())
737             {
738                 aAnchor.SetAnchor(pInternalPam->Start());
739             }
740         }
741         else
742             throw uno::RuntimeException();
743     }
744     else if ((aAnchor.GetAnchorId() != FLY_AT_PAGE) && pDoc->GetCurrentLayout())
745     {
746         SwCrsrMoveState aState( MV_SETONLYTEXT );
747         Point aTmp(MM100_TO_TWIP(aMM100Pos.X), MM100_TO_TWIP(aMM100Pos.Y));
748         pDoc->GetCurrentLayout()->GetCrsrOfst( pPam->GetPoint(), aTmp, &aState );   //swmod 080218
749         aAnchor.SetAnchor( pPam->GetPoint() );
750 
751         // --> OD 2004-08-18 #i32349# - adjustment of vertical positioning
752         // attributes no longer needed, because its already got a default.
753     }
754     else
755     {
756         aAnchor.SetType(FLY_AT_PAGE);
757 
758         // --> OD 2004-08-18 #i32349# - adjustment of vertical positioning
759         // attributes no longer needed, because its already got a default.
760     }
761     aSet.Put(aAnchor);
762     SwPaM* pTemp = pInternalPam;
763     if ( !pTemp )
764         pTemp = pPam;
765     UnoActionContext aAction(pDoc);
766     pDoc->Insert( *pTemp, *pObj, &aSet, NULL );
767     SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
768     if(pFmt)
769         pFmt->Add(pShape);
770     pShape->m_bDescriptor = sal_False;
771 
772     delete pPam;
773     delete pInternalPam;
774 }
775 
776 void SwXDrawPage::remove(const uno::Reference< drawing::XShape > & xShape) throw( uno::RuntimeException )
777 {
778     vos::OGuard  aGuard(Application::GetSolarMutex());
779     if(!pDoc)
780         throw uno::RuntimeException();
781     uno::Reference<lang::XComponent> xComp(xShape, uno::UNO_QUERY);
782     xComp->dispose();
783 }
784 
785 uno::Reference< drawing::XShapeGroup >  SwXDrawPage::group(const uno::Reference< drawing::XShapes > & xShapes) throw( uno::RuntimeException )
786 {
787     vos::OGuard  aGuard(Application::GetSolarMutex());
788     if(!pDoc || !xShapes.is())
789         throw uno::RuntimeException();
790     uno::Reference< drawing::XShapeGroup >  xRet;
791     if(xPageAgg.is())
792     {
793 
794         SwFmDrawPage* pPage = GetSvxPage();
795         if(pPage)//kann das auch Null sein?
796         {
797             //markieren und MarkList zurueckgeben
798             const SdrMarkList& rMarkList = pPage->PreGroup(xShapes);
799             if ( rMarkList.GetMarkCount() > 1 )
800             {
801                 sal_Bool bFlyInCnt = sal_False;
802                 for ( sal_uInt16 i = 0; !bFlyInCnt && i < rMarkList.GetMarkCount(); ++i )
803                 {
804                     const SdrObject *pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
805                     if (FLY_AS_CHAR == ::FindFrmFmt(const_cast<SdrObject*>(
806                                             pObj))->GetAnchor().GetAnchorId())
807                     {
808                         bFlyInCnt = sal_True;
809                     }
810                 }
811                 if( bFlyInCnt )
812                     throw uno::RuntimeException();
813                 if( !bFlyInCnt )
814                 {
815                     UnoActionContext aContext(pDoc);
816                     pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
817 
818                     SwDrawContact* pContact = pDoc->GroupSelection( *pPage->GetDrawView() );
819                     pDoc->ChgAnchor(
820                         pPage->GetDrawView()->GetMarkedObjectList(),
821                         FLY_AT_PARA/*int eAnchorId*/,
822                         sal_True, sal_False );
823 
824                     pPage->GetDrawView()->UnmarkAll();
825                     if(pContact)
826                     {
827                         uno::Reference< uno::XInterface >  xInt = pPage->GetInterface( pContact->GetMaster() );
828                         xRet = uno::Reference< drawing::XShapeGroup >(xInt, uno::UNO_QUERY);
829                     }
830                     pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
831                 }
832             }
833             pPage->RemovePageView();
834         }
835     }
836     return xRet;
837 }
838 
839 void SwXDrawPage::ungroup(const uno::Reference< drawing::XShapeGroup > & xShapeGroup) throw( uno::RuntimeException )
840 {
841     vos::OGuard  aGuard(Application::GetSolarMutex());
842     if(!pDoc)
843         throw uno::RuntimeException();
844     if(xPageAgg.is())
845     {
846         SwFmDrawPage* pPage = GetSvxPage();
847         if(pPage)//kann das auch Null sein?
848         {
849             pPage->PreUnGroup(xShapeGroup);
850             UnoActionContext aContext(pDoc);
851             pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
852 
853             pDoc->UnGroupSelection( *pPage->GetDrawView() );
854             pDoc->ChgAnchor( pPage->GetDrawView()->GetMarkedObjectList(),
855                         FLY_AT_PARA/*int eAnchorId*/,
856                         sal_True, sal_False );
857             pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
858         }
859         pPage->RemovePageView();
860     }
861 }
862 
863 SwFmDrawPage*   SwXDrawPage::GetSvxPage()
864 {
865     if(!xPageAgg.is() && pDoc)
866     {
867         vos::OGuard  aGuard(Application::GetSolarMutex());
868         // --> OD 2005-08-08 #i52858# - method name changed
869         SdrModel* pModel = pDoc->GetOrCreateDrawModel();
870         // <--
871         SdrPage* pPage = pModel->GetPage( 0 );
872 
873         {
874             // waehrend des queryInterface braucht man ein Ref auf das
875             // Objekt, sonst wird es geloescht.
876             pDrawPage = new SwFmDrawPage(pPage);
877             uno::Reference< drawing::XDrawPage >  xPage = pDrawPage;
878             uno::Any aAgg = xPage->queryInterface(::getCppuType((uno::Reference< uno::XAggregation >*)0));
879             if(aAgg.getValueType() == ::getCppuType((uno::Reference< uno::XAggregation >*)0))
880                 xPageAgg = *(uno::Reference< uno::XAggregation >*)aAgg.getValue();
881         }
882         if( xPageAgg.is() )
883             xPageAgg->setDelegator( (cppu::OWeakObject*)this );
884     }
885     return pDrawPage;
886 }
887 
888 // renamed and outlined to detect where it's called
889 void SwXDrawPage::InvalidateSwDoc()
890 {
891     pDoc = 0;
892 }
893 
894 /****************************************************************************
895 
896 ****************************************************************************/
897 TYPEINIT1(SwXShape, SwClient);
898 
899 const uno::Sequence< sal_Int8 > & SwXShape::getUnoTunnelId()
900 {
901     static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
902     return aSeq;
903 }
904 
905 sal_Int64 SAL_CALL SwXShape::getSomething( const uno::Sequence< sal_Int8 >& rId )
906     throw(uno::RuntimeException)
907 {
908     if( rId.getLength() == 16
909         && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
910                                         rId.getConstArray(), 16 ) )
911     {
912         return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
913     }
914 
915     if( xShapeAgg.is() )
916     {
917         const uno::Type& rTunnelType = ::getCppuType((uno::Reference<lang::XUnoTunnel>*)0 );
918         uno::Any aAgg = xShapeAgg->queryAggregation( rTunnelType );
919         if(aAgg.getValueType() == rTunnelType)
920         {
921             uno::Reference<lang::XUnoTunnel> xAggTunnel =
922                     *(uno::Reference<lang::XUnoTunnel>*)aAgg.getValue();
923             if(xAggTunnel.is())
924                 return xAggTunnel->getSomething(rId);
925         }
926     }
927     return 0;
928 }
929 namespace
930 {
931     static void lcl_addShapePropertyEventFactories( SdrObject& _rObj, SwXShape& _rShape )
932     {
933         ::svx::PPropertyValueProvider pProvider( new ::svx::PropertyValueProvider( _rShape, "AnchorType" ) );
934         _rObj.getShapePropertyChangeNotifier().registerProvider( ::svx::eTextShapeAnchorType, pProvider );
935     }
936 }
937 
938 
939 SwXShape::SwXShape(uno::Reference< uno::XInterface > & xShape) :
940     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_SHAPE)),
941     m_pPropertyMapEntries(aSwMapProvider.GetPropertyMapEntries(PROPERTY_MAP_TEXT_SHAPE)),
942     pImplementationId(0),
943     pImpl(new SwShapeDescriptor_Impl()),
944     m_bDescriptor(sal_True)
945 {
946     if(xShape.is())  // default Ctor
947     {
948         const uno::Type& rAggType = ::getCppuType((const uno::Reference< uno::XAggregation >*)0);
949         //aAgg contains a reference of the SvxShape!
950         {
951             uno::Any aAgg = xShape->queryInterface(rAggType);
952             if(aAgg.getValueType() == rAggType)
953                 xShapeAgg = *(uno::Reference< uno::XAggregation >*)aAgg.getValue();
954             // --> OD 2004-07-23 #i31698#
955             if ( xShapeAgg.is() )
956             {
957                 xShapeAgg->queryAggregation( ::getCppuType((uno::Reference< drawing::XShape >*)0) ) >>= mxShape;
958                 ASSERT( mxShape.is(),
959                         "<SwXShape::SwXShape(..)> - no XShape found at <xShapeAgg>" );
960             }
961             // <--
962         }
963         xShape = 0;
964         m_refCount++;
965         if( xShapeAgg.is() )
966             xShapeAgg->setDelegator( (cppu::OWeakObject*)this );
967         m_refCount--;
968 
969         uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
970         SvxShape* pShape = 0;
971         if(xShapeTunnel.is())
972             pShape = reinterpret_cast< SvxShape * >(
973                     sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SvxShape::getUnoTunnelId()) ));
974 
975         SdrObject* pObj = pShape ? pShape->GetSdrObject() : 0;
976         if(pObj)
977         {
978             SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
979             if(pFmt)
980                 pFmt->Add(this);
981 
982             lcl_addShapePropertyEventFactories( *pObj, *this );
983             pImpl->bInitializedPropertyNotifier = true;
984         }
985     }
986 }
987 
988 void SwXShape::AddExistingShapeToFmt( SdrObject& _rObj )
989 {
990     SdrObjListIter aIter( _rObj, IM_DEEPNOGROUPS );
991     while ( aIter.IsMore() )
992     {
993         SdrObject* pCurrent = aIter.Next();
994         OSL_ENSURE( pCurrent, "SwXShape::AddExistingShapeToFmt: invalid object list element!" );
995         if ( !pCurrent )
996             continue;
997 
998         SwXShape* pSwShape = NULL;
999         uno::Reference< lang::XUnoTunnel > xShapeTunnel( pCurrent->getWeakUnoShape(), uno::UNO_QUERY );
1000         if ( xShapeTunnel.is() )
1001             pSwShape = reinterpret_cast< SwXShape * >(
1002                     sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething( SwXShape::getUnoTunnelId() ) ) );
1003         if ( pSwShape )
1004         {
1005             if ( pSwShape->m_bDescriptor )
1006             {
1007                 SwFrmFmt* pFmt = ::FindFrmFmt( const_cast< SdrObject* >( pCurrent ) );
1008                 if ( pFmt )
1009                     pFmt->Add( pSwShape );
1010                 pSwShape->m_bDescriptor = sal_False;
1011             }
1012 
1013             if ( !pSwShape->pImpl->bInitializedPropertyNotifier )
1014             {
1015                 lcl_addShapePropertyEventFactories( *pCurrent, *pSwShape );
1016                 pSwShape->pImpl->bInitializedPropertyNotifier = true;
1017             }
1018         }
1019     }
1020 }
1021 
1022 
1023 SwXShape::~SwXShape()
1024 {
1025     if (xShapeAgg.is())
1026     {
1027         uno::Reference< uno::XInterface >  xRef;
1028         xShapeAgg->setDelegator(xRef);
1029     }
1030     delete pImpl;
1031 }
1032 
1033 uno::Any SwXShape::queryInterface( const uno::Type& aType ) throw( uno::RuntimeException )
1034 {
1035     uno::Any aRet = SwXShapeBaseClass::queryInterface(aType);
1036     // --> OD 2005-08-15 #i53320# - follow-up of #i31698#
1037     // interface drawing::XShape is overloaded. Thus, provide
1038     // correct object instance.
1039     if(!aRet.hasValue() && xShapeAgg.is())
1040     {
1041         if(aType == ::getCppuType((uno::Reference<XShape>*)0))
1042             aRet <<= uno::Reference<XShape>(this);
1043         else
1044             aRet = xShapeAgg->queryAggregation(aType);
1045     }
1046     // <--
1047     return aRet;
1048 }
1049 
1050 uno::Sequence< uno::Type > SwXShape::getTypes(  ) throw(uno::RuntimeException)
1051 {
1052     uno::Sequence< uno::Type > aRet = SwXShapeBaseClass::getTypes();
1053     if(xShapeAgg.is())
1054     {
1055         uno::Any aProv = xShapeAgg->queryAggregation(::getCppuType((uno::Reference< XTypeProvider >*)0));
1056         if(aProv.hasValue())
1057         {
1058             uno::Reference< XTypeProvider > xAggProv;
1059             aProv >>= xAggProv;
1060             uno::Sequence< uno::Type > aAggTypes = xAggProv->getTypes();
1061             const uno::Type* pAggTypes = aAggTypes.getConstArray();
1062             long nIndex = aRet.getLength();
1063 
1064             aRet.realloc(nIndex + aAggTypes.getLength());
1065             uno::Type* pBaseTypes = aRet.getArray();
1066 
1067             for(long i = 0; i < aAggTypes.getLength(); i++)
1068                 pBaseTypes[nIndex++] = pAggTypes[i];
1069         }
1070     }
1071     return aRet;
1072 }
1073 
1074 uno::Sequence< sal_Int8 > SwXShape::getImplementationId(  ) throw(uno::RuntimeException)
1075 {
1076     vos::OGuard aGuard( Application::GetSolarMutex() );
1077     // do we need to compute the implementation id for this instance?
1078     if( !pImplementationId && xShapeAgg.is())
1079     {
1080         uno::Reference< XShape > xAggShape;
1081         xShapeAgg->queryAggregation( ::getCppuType((uno::Reference< XShape >*)0) ) >>= xAggShape;
1082 
1083         if( xAggShape.is() )
1084         {
1085             const rtl::OUString aShapeType( xAggShape->getShapeType() );
1086             // did we already compute an implementation id for the agregated shape type?
1087             SwShapeImplementationIdMap::iterator aIter( aImplementationIdMap.find(aShapeType ) );
1088             if( aIter == aImplementationIdMap.end() )
1089             {
1090                 // we need to create a new implementation id for this
1091                 // note: this memory is not free'd until application exists
1092                 //       but since we have a fixed set of shapetypes and the
1093                 //       memory will be reused this is ok.
1094                 pImplementationId = new uno::Sequence< sal_Int8 >( 16 );
1095                 rtl_createUuid( (sal_uInt8 *) pImplementationId->getArray(), 0, sal_True );
1096                 aImplementationIdMap[ aShapeType ] = pImplementationId;
1097             }
1098             else
1099             {
1100                 // use the already computed implementation id
1101                 pImplementationId = (*aIter).second;
1102             }
1103         }
1104     }
1105     if( NULL == pImplementationId )
1106     {
1107         DBG_ERROR( "Could not create an implementation id for a SwXShape!" );
1108         return uno::Sequence< sal_Int8 > ();
1109     }
1110     else
1111     {
1112         return *pImplementationId;
1113     }
1114 }
1115 
1116 uno::Reference< beans::XPropertySetInfo >  SwXShape::getPropertySetInfo(void) throw( uno::RuntimeException )
1117 {
1118     vos::OGuard  aGuard(Application::GetSolarMutex());
1119     uno::Reference< beans::XPropertySetInfo >  aRet;
1120     if(xShapeAgg.is())
1121     {
1122         const uno::Type& rPropSetType = ::getCppuType((const uno::Reference< beans::XPropertySet >*)0);
1123         uno::Any aPSet = xShapeAgg->queryAggregation( rPropSetType );
1124         if(aPSet.getValueType() == rPropSetType && aPSet.getValue())
1125         {
1126             uno::Reference< beans::XPropertySet >  xPrSet =
1127                     *(uno::Reference< beans::XPropertySet >*)aPSet.getValue();
1128             uno::Reference< beans::XPropertySetInfo >  xInfo = xPrSet->getPropertySetInfo();
1129             // PropertySetInfo verlaengern!
1130             const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
1131             aRet = new SfxExtItemPropertySetInfo( m_pPropertyMapEntries, aPropSeq );
1132         }
1133     }
1134     if(!aRet.is())
1135         aRet = m_pPropSet->getPropertySetInfo();
1136     return aRet;
1137 }
1138 
1139 void SwXShape::setPropertyValue(const rtl::OUString& rPropertyName, const uno::Any& aValue)
1140      throw( beans::UnknownPropertyException, beans::PropertyVetoException,
1141             lang::IllegalArgumentException, lang::WrappedTargetException,
1142             uno::RuntimeException)
1143 {
1144     vos::OGuard  aGuard(Application::GetSolarMutex());
1145     SwFrmFmt*   pFmt = GetFrmFmt();
1146     const SfxItemPropertySimpleEntry*  pEntry = m_pPropSet->getPropertyMap()->getByName( rPropertyName );
1147     if(xShapeAgg.is())
1148     {
1149         if(pEntry)
1150         {
1151             if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
1152                 throw beans::PropertyVetoException ( rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1153             //mit Layout kann der Anker umgesetzt werden, ohne dass sich die Position aendert
1154             if(pFmt)
1155             {
1156                 SwAttrSet aSet(pFmt->GetAttrSet());
1157                 SwDoc* pDoc = pFmt->GetDoc();
1158                 if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORFRAME == pEntry->nMemberId)
1159                 {
1160                     sal_Bool bDone = sal_True;
1161                     uno::Reference<text::XTextFrame> xFrame;
1162                     if(aValue >>= xFrame)
1163                     {
1164                         uno::Reference<lang::XUnoTunnel> xTunnel(xFrame, uno::UNO_QUERY);
1165                         SwXFrame* pFrame = xTunnel.is() ?
1166                                 reinterpret_cast< SwXFrame * >(
1167                                     sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething(SwXFrame::getUnoTunnelId()) ))
1168                                 : 0;
1169                         if(pFrame && pFrame->GetFrmFmt() &&
1170                             pFrame->GetFrmFmt()->GetDoc() == pDoc)
1171                         {
1172                             UnoActionContext aCtx(pDoc);
1173                             SfxItemSet aItemSet( pDoc->GetAttrPool(),
1174                                         RES_FRMATR_BEGIN, RES_FRMATR_END - 1 );
1175                             aItemSet.SetParent(&pFmt->GetAttrSet());
1176                             SwFmtAnchor aAnchor = (const SwFmtAnchor&)aItemSet.Get(pEntry->nWID);
1177                             SwPosition aPos(*pFrame->GetFrmFmt()->GetCntnt().GetCntntIdx());
1178                             aAnchor.SetAnchor(&aPos);
1179                             aAnchor.SetType(FLY_AT_FLY);
1180                             aItemSet.Put(aAnchor);
1181                             pFmt->SetFmtAttr(aItemSet);
1182                             bDone = sal_True;
1183                         }
1184                     }
1185                     if(!bDone)
1186                         throw lang::IllegalArgumentException();
1187                 }
1188                 else if(RES_OPAQUE == pEntry->nWID)
1189                 {
1190                     SvxShape* pSvxShape = GetSvxShape();
1191                     DBG_ASSERT(pSvxShape, "No SvxShape found!");
1192                     if(pSvxShape)
1193                     {
1194                         SdrObject* pObj = pSvxShape->GetSdrObject();
1195                         // OD 25.06.2003 #108784# - set layer of new drawing
1196                         // object to corresponding invisible layer.
1197                         bool bIsVisible = pDoc->IsVisibleLayerId( pObj->GetLayer() );
1198                         if(FmFormInventor != pObj->GetObjInventor())
1199                         {
1200                             pObj->SetLayer( *(sal_Bool*)aValue.getValue()
1201                                             ? ( bIsVisible ? pDoc->GetHeavenId() : pDoc->GetInvisibleHeavenId() )
1202                                             : ( bIsVisible ? pDoc->GetHellId() : pDoc->GetInvisibleHellId() ));
1203                         }
1204                         else
1205                         {
1206                             pObj->SetLayer( bIsVisible ? pDoc->GetControlsId() : pDoc->GetInvisibleControlsId());
1207                         }
1208 
1209                     }
1210 
1211                 }
1212                 // OD 2004-04-22 #i26791# - special handling for property FN_TEXT_RANGE
1213                 else if ( FN_TEXT_RANGE == pEntry->nWID )
1214                 {
1215                     SwFmtAnchor aAnchor( static_cast<const SwFmtAnchor&>(aSet.Get( RES_ANCHOR )) );
1216                     if (aAnchor.GetAnchorId() == FLY_AT_PAGE)
1217                     {
1218                         // set property <TextRange> not valid for to-page anchored shapes
1219                         throw lang::IllegalArgumentException();
1220                     }
1221                     else
1222                     {
1223                         SwUnoInternalPaM* pInternalPam =
1224                                         new SwUnoInternalPaM( *(pFmt->GetDoc()) );
1225                         uno::Reference< text::XTextRange > xRg;
1226                         aValue >>= xRg;
1227                         if (::sw::XTextRangeToSwPaM(*pInternalPam, xRg) )
1228                         {
1229                             if (aAnchor.GetAnchorId() == FLY_AS_CHAR)
1230                             {
1231                                 //delete old SwFmtFlyCnt
1232                                 //With AnchorAsCharacter the current TxtAttribute has to be deleted.
1233                                 //Tbis removes the frame format too.
1234                                 //To prevent this the connection between format and attribute has to be broken before.
1235                                 const SwPosition *pPos = aAnchor.GetCntntAnchor();
1236                                 SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1237                                 ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1238                                 const xub_StrLen nIdx = pPos->nContent.GetIndex();
1239                                 SwTxtAttr * const pHnt =
1240                                     pTxtNode->GetTxtAttrForCharAt(
1241                                         nIdx, RES_TXTATR_FLYCNT );
1242                                 DBG_ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1243                                             "Missing FlyInCnt-Hint." );
1244                                 DBG_ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFmt,
1245                                             "Wrong TxtFlyCnt-Hint." );
1246                                 const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt())
1247                                     .SetFlyFmt();
1248 
1249                                 //The connection is removed now the attribute can be deleted.
1250                                 pTxtNode->DeleteAttributes(
1251                                     RES_TXTATR_FLYCNT, nIdx );
1252                                 //create a new one
1253                                 SwTxtNode *pNd = pInternalPam->GetNode()->GetTxtNode();
1254                                 DBG_ASSERT( pNd, "Cursor not at TxtNode." );
1255                                 SwFmtFlyCnt aFmt( pFmt );
1256                                 pNd->InsertItem(aFmt, pInternalPam->GetPoint()
1257                                         ->nContent.GetIndex(), 0 );
1258                             }
1259                             else
1260                             {
1261                                 aAnchor.SetAnchor( pInternalPam->GetPoint() );
1262                                 aSet.Put(aAnchor);
1263                                 pFmt->SetFmtAttr(aSet);
1264                             }
1265                         }
1266                         else
1267                         {
1268                             throw uno::RuntimeException();
1269                         }
1270                         delete pInternalPam;
1271                     }
1272                 }
1273                 // --> OD 2004-08-06 #i28749#
1274                 else if ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID )
1275                 {
1276                     sal_Int16 nPositionLayoutDir = 0;
1277                     aValue >>= nPositionLayoutDir;
1278                     pFmt->SetPositionLayoutDir( nPositionLayoutDir );
1279                 }
1280                 // <--
1281                 else if( pDoc->GetCurrentLayout())  //swmod 080218
1282                 {
1283                     UnoActionContext aCtx(pDoc);
1284                     if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORTYPE == pEntry->nMemberId)
1285                     {
1286                         SdrObject* pObj = pFmt->FindSdrObject();
1287                         SdrMarkList aList;
1288                         SdrMark aMark(pObj);
1289                         aList.InsertEntry(aMark);
1290                         sal_Int32 nAnchor = 0;
1291                         cppu::enum2int( nAnchor, aValue );
1292                         pDoc->ChgAnchor( aList, (RndStdIds)nAnchor,
1293                                                 sal_False, sal_True );
1294                     }
1295                     else
1296                     {
1297                         m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
1298                         pFmt->SetFmtAttr(aSet);
1299                     }
1300                 }
1301                 else
1302                 {
1303                     m_pPropSet->setPropertyValue( *pEntry, aValue, aSet );
1304 
1305                     if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORTYPE == pEntry->nMemberId)
1306                     {
1307                         bool bSetAttr = true;
1308                         sal_Int32 eNewAnchor = SWUnoHelper::GetEnumAsInt32( aValue );
1309 
1310                         //if old anchor was in_cntnt the related text attribute has to be removed
1311                         const SwFmtAnchor& rOldAnchor = pFmt->GetAnchor();
1312                         RndStdIds eOldAnchorId = rOldAnchor.GetAnchorId();
1313                         SdrObject* pObj = pFmt->FindSdrObject();
1314                         SwFrmFmt *pFlyFmt = FindFrmFmt( pObj );
1315                         pFlyFmt->DelFrms();
1316                         if( text::TextContentAnchorType_AS_CHARACTER != eNewAnchor &&
1317                             (FLY_AS_CHAR == eOldAnchorId))
1318                         {
1319                             //With AnchorAsCharacter the current TxtAttribute has to be deleted.
1320                             //Tbis removes the frame format too.
1321                             //To prevent this the connection between format and attribute has to be broken before.
1322                             const SwPosition *pPos = rOldAnchor.GetCntntAnchor();
1323                             SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1324                             ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1325                             const xub_StrLen nIdx = pPos->nContent.GetIndex();
1326                             SwTxtAttr * const pHnt =
1327                                 pTxtNode->GetTxtAttrForCharAt(
1328                                     nIdx, RES_TXTATR_FLYCNT );
1329                             DBG_ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1330                                         "Missing FlyInCnt-Hint." );
1331                             DBG_ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFlyFmt,
1332                                         "Wrong TxtFlyCnt-Hint." );
1333                             const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt())
1334                                 .SetFlyFmt();
1335 
1336                             //The connection is removed now the attribute can be deleted.
1337                             pTxtNode->DeleteAttributes(RES_TXTATR_FLYCNT, nIdx);
1338                         }
1339                         else if( text::TextContentAnchorType_AT_PAGE != eNewAnchor &&
1340                                 (FLY_AT_PAGE == eOldAnchorId))
1341                         {
1342                             SwFmtAnchor aNewAnchor( dynamic_cast< const SwFmtAnchor& >( aSet.Get( RES_ANCHOR ) ) );
1343                             //if the fly has been anchored at page then it needs to be connected
1344                             //to the content position
1345                             SwPaM aPam(pDoc->GetNodes().GetEndOfContent());
1346                             if( pDoc->GetCurrentLayout() )
1347                             {
1348                                 SwCrsrMoveState aState( MV_SETONLYTEXT );
1349                                 Point aTmp( pObj->GetSnapRect().TopLeft() );
1350                                 pDoc->GetCurrentLayout()->GetCrsrOfst( aPam.GetPoint(), aTmp, &aState );
1351                             }
1352                             else
1353                             {
1354                                 //without access to the layout the last node of the body will be used as anchor position
1355                                 aPam.Move( fnMoveBackward, fnGoDoc );
1356                             }
1357                             //anchor position has to be inserted after the text attribute has been inserted
1358                             aNewAnchor.SetAnchor( aPam.GetPoint() );
1359                             aSet.Put( aNewAnchor );
1360                             pFmt->SetFmtAttr(aSet);
1361                             bSetAttr = false;
1362                             if( text::TextContentAnchorType_AS_CHARACTER == eNewAnchor &&
1363                                 (FLY_AS_CHAR != eOldAnchorId))
1364                             {
1365                                 //the RES_TXTATR_FLYCNT needs to be added now
1366                                 SwTxtNode *pNd = aPam.GetNode()->GetTxtNode();
1367                                 DBG_ASSERT( pNd, "Crsr is not in a TxtNode." );
1368                                 SwFmtFlyCnt aFmt( pFlyFmt );
1369                                 pNd->InsertItem(aFmt,
1370                                     aPam.GetPoint()->nContent.GetIndex(), 0 );
1371                                 //aPam.GetPoint()->nContent--;
1372 
1373                             }
1374                         }
1375                         if( bSetAttr )
1376                             pFmt->SetFmtAttr(aSet);
1377                     }
1378                     else
1379                         pFmt->SetFmtAttr(aSet);
1380                 }
1381             }
1382             else
1383             {
1384                 SfxPoolItem* pItem = 0;
1385                 switch(pEntry->nWID)
1386                 {
1387                     case RES_ANCHOR:
1388                         pItem = pImpl->GetAnchor(sal_True);
1389                     break;
1390                     case RES_HORI_ORIENT:
1391                         pItem = pImpl->GetHOrient(sal_True);
1392                     break;
1393                     case RES_VERT_ORIENT:
1394                         pItem = pImpl->GetVOrient(sal_True);
1395                     break;
1396                     case  RES_LR_SPACE:
1397                         pItem = pImpl->GetLRSpace(sal_True);
1398                     break;
1399                     case  RES_UL_SPACE:
1400                         pItem = pImpl->GetULSpace(sal_True);
1401                     break;
1402                     case  RES_SURROUND:
1403                         pItem = pImpl->GetSurround(sal_True);
1404                     break;
1405                     case  FN_TEXT_RANGE:
1406                     {
1407                         const uno::Type rTextRangeType =
1408                             ::getCppuType((uno::Reference< text::XTextRange>*)0);
1409                         if(aValue.getValueType() == rTextRangeType)
1410                         {
1411                             uno::Reference< text::XTextRange > & rRange = pImpl->GetTextRange();
1412                             rRange = *(uno::Reference< text::XTextRange > *)aValue.getValue();
1413                         }
1414                     }
1415                     break;
1416                     case RES_OPAQUE :
1417                         pImpl->SetOpaque(*(sal_Bool*)aValue.getValue());
1418                     break;
1419                     // OD 2004-04-22 #i26791#
1420                     case RES_FOLLOW_TEXT_FLOW:
1421                     {
1422                         pItem = pImpl->GetFollowTextFlow( sal_True );
1423                     }
1424                     break;
1425                     // OD 2004-05-05 #i28701#
1426                     case RES_WRAP_INFLUENCE_ON_OBJPOS:
1427                     {
1428                         pItem = pImpl->GetWrapInfluenceOnObjPos( sal_True );
1429                     }
1430                     break;
1431                     // --> OD 2004-08-06 #i28749#
1432                     case FN_SHAPE_POSITION_LAYOUT_DIR :
1433                     {
1434                         sal_Int16 nPositionLayoutDir = 0;
1435                         aValue >>= nPositionLayoutDir;
1436                         pImpl->SetPositionLayoutDir( nPositionLayoutDir );
1437                     }
1438                     break;
1439                     // <--
1440                 }
1441                 if(pItem)
1442                     ((SfxPoolItem*)pItem)->PutValue(aValue, pEntry->nMemberId);
1443             }
1444         }
1445         else
1446         {
1447             uno::Reference< beans::XPropertySet >  xPrSet;
1448             const uno::Type& rPSetType =
1449                 ::getCppuType((const uno::Reference< beans::XPropertySet >*)0);
1450             uno::Any aPSet = xShapeAgg->queryAggregation(rPSetType);
1451             if(aPSet.getValueType() != rPSetType || !aPSet.getValue())
1452                 throw uno::RuntimeException();
1453             xPrSet = *(uno::Reference< beans::XPropertySet >*)aPSet.getValue();
1454             // --> OD 2004-08-05 #i31698# - setting the caption point of a
1455             // caption object doesn't have to change the object position.
1456             // Thus, keep the position, before the caption point is set and
1457             // restore it afterwards.
1458             awt::Point aKeepedPosition( 0, 0 );
1459             if ( rPropertyName.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CaptionPoint"))) &&
1460                  getShapeType().equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape"))) )
1461             {
1462                     aKeepedPosition = getPosition();
1463             }
1464             // <--
1465             if( pFmt && pFmt->GetDoc()->GetCurrentViewShell() ) //swmod 071108//swmod 071225
1466             {
1467                 UnoActionContext aCtx(pFmt->GetDoc());
1468                 xPrSet->setPropertyValue(rPropertyName, aValue);
1469             }
1470             else
1471                 xPrSet->setPropertyValue(rPropertyName, aValue);
1472             // --> OD 2004-11-11 #i35007# - adjustment of the position
1473             // attributes, if the transformation is set, causes wrong alignments
1474             // and is no longer needed.
1475             // The position attributes are set, if the drawing object is added
1476             // to the draw page - see <SwXDrawPage::add(..)> -  and on its first
1477             // positioning - see <SwAnchoredDrawObject::MakeObjPos().
1478 //            // --> OD 2004-07-28 #i31698# - additionally adjust the position
1479 //            // properties of the shape, if the transformation is set and
1480 //            // the shape isn't a group member.
1481 //            if ( rPropertyName.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation"))) &&
1482 //                 !_GetTopGroupObj() )
1483 //            {
1484 //                drawing::HomogenMatrix3 aMatrix;
1485 //                aValue >>= aMatrix;
1486 //                awt::Point aNewPos( basegfx::fround( aMatrix.Line1.Column3 ),
1487 //                                    basegfx::fround( aMatrix.Line2.Column3 ) );
1488 //                _AdjustPositionProperties( aNewPos );
1489 //            }
1490             // --> OD 2004-08-05 #i31698# - restore object position, if caption
1491             // point is set.
1492             if ( rPropertyName.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CaptionPoint"))) &&
1493                  getShapeType().equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape"))) )
1494             {
1495                 setPosition( aKeepedPosition );
1496             }
1497         }
1498     }
1499 }
1500 
1501 uno::Any SwXShape::getPropertyValue(const rtl::OUString& rPropertyName)
1502     throw( beans::UnknownPropertyException, lang::WrappedTargetException,
1503            uno::RuntimeException )
1504 {
1505     vos::OGuard  aGuard(Application::GetSolarMutex());
1506     uno::Any aRet;
1507     SwFrmFmt*   pFmt = GetFrmFmt();
1508     if(xShapeAgg.is())
1509     {
1510         const SfxItemPropertySimpleEntry*  pEntry = m_pPropSet->getPropertyMap()->getByName( rPropertyName );
1511         if(pEntry)
1512         {
1513             if(pFmt)
1514             {
1515                 if(RES_OPAQUE == pEntry->nWID)
1516                 {
1517                     SvxShape* pSvxShape = GetSvxShape();
1518                     DBG_ASSERT(pSvxShape, "No SvxShape found!");
1519                     if(pSvxShape)
1520                     {
1521                         SdrObject* pObj = pSvxShape->GetSdrObject();
1522                         // OD 02.07.2003 #108784# - consider invisible layers
1523                         sal_Bool bOpaque =
1524                             ( pObj->GetLayer() != pFmt->GetDoc()->GetHellId() &&
1525                               pObj->GetLayer() != pFmt->GetDoc()->GetInvisibleHellId() );
1526                         aRet.setValue(&bOpaque, ::getBooleanCppuType());
1527                     }
1528                 }
1529                 else if(FN_ANCHOR_POSITION == pEntry->nWID)
1530                 {
1531                     SvxShape* pSvxShape = GetSvxShape();
1532                     DBG_ASSERT(pSvxShape, "No SvxShape found!");
1533                     if(pSvxShape)
1534                     {
1535                         SdrObject* pObj = pSvxShape->GetSdrObject();
1536                         Point aPt = pObj->GetAnchorPos();
1537                         awt::Point aPoint( TWIP_TO_MM100( aPt.X() ),
1538                                            TWIP_TO_MM100( aPt.Y() ) );
1539                         aRet.setValue(&aPoint, ::getCppuType( (awt::Point*)0 ));
1540                     }
1541                 }
1542                 // OD 2004-04-22 #i26791# - special handling for FN_TEXT_RANGE
1543                 else if ( FN_TEXT_RANGE == pEntry->nWID )
1544                 {
1545                     const SwFmtAnchor aAnchor = pFmt->GetAnchor();
1546                     if (aAnchor.GetAnchorId() == FLY_AT_PAGE)
1547                     {
1548                         // return nothing, because property <TextRange> isn't
1549                         // valid for to-page anchored shapes
1550                         uno::Any aAny;
1551                         aRet = aAny;
1552                     }
1553                     else
1554                     {
1555                         if ( aAnchor.GetCntntAnchor() )
1556                         {
1557                             const uno::Reference< text::XTextRange > xTextRange
1558                                 = SwXTextRange::CreateXTextRange(
1559                                                     *pFmt->GetDoc(),
1560                                                     *aAnchor.GetCntntAnchor(),
1561                                                     0L );
1562                             aRet.setValue(&xTextRange, ::getCppuType((uno::Reference<text::XTextRange>*)0));
1563                         }
1564                         else
1565                         {
1566                             // return nothing
1567                             uno::Any aAny;
1568                             aRet = aAny;
1569                         }
1570                     }
1571                 }
1572                 // --> OD 2004-08-06 #i28749#
1573                 else if ( FN_SHAPE_TRANSFORMATION_IN_HORI_L2R == pEntry->nWID )
1574                 {
1575                     // get property <::drawing::Shape::Transformation>
1576                     // without conversion to layout direction as below
1577                     aRet = _getPropAtAggrObj( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")) );
1578                 }
1579                 else if ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID )
1580                 {
1581                     aRet <<= pFmt->GetPositionLayoutDir();
1582                 }
1583                 // <--
1584                 // --> OD 2004-10-28 #i36248#
1585                 else if ( FN_SHAPE_STARTPOSITION_IN_HORI_L2R == pEntry->nWID )
1586                 {
1587                     // get property <::drawing::Shape::StartPosition>
1588                     // without conversion to layout direction as below
1589                     aRet = _getPropAtAggrObj( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition")) );
1590                 }
1591                 else if ( FN_SHAPE_ENDPOSITION_IN_HORI_L2R == pEntry->nWID )
1592                 {
1593                     // get property <::drawing::Shape::EndPosition>
1594                     // without conversion to layout direction as below
1595                     aRet = _getPropAtAggrObj( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition")) );
1596                 }
1597                 // <--
1598                 else
1599                 {
1600                     const SwAttrSet& rSet = pFmt->GetAttrSet();
1601                     m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
1602                 }
1603             }
1604             else
1605             {
1606                 SfxPoolItem* pItem = 0;
1607                 switch(pEntry->nWID)
1608                 {
1609                     case RES_ANCHOR:
1610                         pItem = pImpl->GetAnchor();
1611                     break;
1612                     case RES_HORI_ORIENT:
1613                         pItem = pImpl->GetHOrient();
1614                     break;
1615                     case RES_VERT_ORIENT:
1616                         pItem = pImpl->GetVOrient();
1617                     break;
1618                     case  RES_LR_SPACE:
1619                         pItem = pImpl->GetLRSpace();
1620                     break;
1621                     case  RES_UL_SPACE:
1622                         pItem = pImpl->GetULSpace();
1623                     break;
1624                     case  RES_SURROUND:
1625                         pItem = pImpl->GetSurround();
1626                     break;
1627                     case FN_TEXT_RANGE :
1628                         aRet.setValue(&pImpl->GetTextRange(), ::getCppuType((uno::Reference<text::XTextRange>*)0));
1629                     break;
1630                     case RES_OPAQUE :
1631                         aRet.setValue(&pImpl->GetOpaque(), ::getBooleanCppuType());
1632                     break;
1633                     case FN_ANCHOR_POSITION :
1634                     {
1635                         awt::Point aPoint;
1636                         aRet.setValue(&aPoint, ::getCppuType( (awt::Point*)0 ));
1637                     }
1638                     break;
1639                     // OD 2004-04-22 #i26791#
1640                     case RES_FOLLOW_TEXT_FLOW :
1641                     {
1642                         pItem = pImpl->GetFollowTextFlow();
1643                     }
1644                     break;
1645                     // OD 2004-05-05 #i28701#
1646                     case RES_WRAP_INFLUENCE_ON_OBJPOS:
1647                     {
1648                         pItem = pImpl->GetWrapInfluenceOnObjPos();
1649                     }
1650                     break;
1651                     // --> OD 2004-08-06 #i28749#
1652                     case FN_SHAPE_TRANSFORMATION_IN_HORI_L2R:
1653                     {
1654                         // get property <::drawing::Shape::Transformation>
1655                         // without conversion to layout direction as below
1656                         aRet = _getPropAtAggrObj( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")) );
1657                     }
1658                     break;
1659                     case FN_SHAPE_POSITION_LAYOUT_DIR:
1660                     {
1661                         aRet <<= pImpl->GetPositionLayoutDir();
1662                     }
1663                     break;
1664                     // <--
1665                     // --> OD 2004-08-06 #i36248#
1666                     case FN_SHAPE_STARTPOSITION_IN_HORI_L2R:
1667                     {
1668                         // get property <::drawing::Shape::StartPosition>
1669                         // without conversion to layout direction as below
1670                         aRet = _getPropAtAggrObj( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition")) );
1671                     }
1672                     break;
1673                     case FN_SHAPE_ENDPOSITION_IN_HORI_L2R:
1674                     {
1675                         // get property <::drawing::Shape::StartPosition>
1676                         // without conversion to layout direction as below
1677                         aRet = _getPropAtAggrObj( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition")) );
1678                     }
1679                     break;
1680                     // <--
1681                 }
1682                 if(pItem)
1683                     pItem->QueryValue(aRet, pEntry->nMemberId);
1684             }
1685         }
1686         else
1687         {
1688             aRet = _getPropAtAggrObj( rPropertyName );
1689 
1690             // --> OD 2004-07-28 #i31698# - convert the position (translation)
1691             // of the drawing object in the transformation
1692             if ( rPropertyName.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation"))) )
1693             {
1694                 drawing::HomogenMatrix3 aMatrix;
1695                 aRet >>= aMatrix;
1696                 aRet <<= _ConvertTransformationToLayoutDir( aMatrix );
1697             }
1698             // <--
1699             // --> OD 2004-10-28 #i36248#
1700             else if ( rPropertyName.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition"))) )
1701             {
1702                 awt::Point aStartPos;
1703                 aRet >>= aStartPos;
1704                 // --> OD 2009-01-12 #i59051#
1705                 aRet <<= _ConvertStartOrEndPosToLayoutDir( aStartPos );
1706                 // <--
1707             }
1708             else if ( rPropertyName.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition"))) )
1709             {
1710                 awt::Point aEndPos;
1711                 aRet >>= aEndPos;
1712                 // --> OD 2009-01-12 #i59051#
1713                 aRet <<= _ConvertStartOrEndPosToLayoutDir( aEndPos );
1714                 // <--
1715             }
1716             // --> OD 2009-01-16 #i59051#
1717             else if ( rPropertyName.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PolyPolygonBezier"))) )
1718             {
1719                 drawing::PolyPolygonBezierCoords aPath;
1720                 aRet >>= aPath;
1721                 aRet <<= _ConvertPolyPolygonBezierToLayoutDir( aPath );
1722                 // <--
1723             }
1724             // <--
1725         }
1726     }
1727     return aRet;
1728 }
1729 
1730 uno::Any SwXShape::_getPropAtAggrObj( const ::rtl::OUString& _rPropertyName )
1731     throw( beans::UnknownPropertyException, lang::WrappedTargetException,
1732            uno::RuntimeException )
1733 {
1734     uno::Any aRet;
1735 
1736     uno::Reference< beans::XPropertySet >  xPrSet;
1737     const uno::Type& rPSetType =
1738                 ::getCppuType((const uno::Reference< beans::XPropertySet >*)0);
1739     uno::Any aPSet = xShapeAgg->queryAggregation(rPSetType);
1740     if ( aPSet.getValueType() != rPSetType || !aPSet.getValue() )
1741     {
1742         throw uno::RuntimeException();
1743     }
1744     xPrSet = *(uno::Reference< beans::XPropertySet >*)aPSet.getValue();
1745     aRet = xPrSet->getPropertyValue( _rPropertyName );
1746 
1747     return aRet;
1748 }
1749 
1750 
1751 beans::PropertyState SwXShape::getPropertyState( const rtl::OUString& rPropertyName )
1752     throw(beans::UnknownPropertyException, uno::RuntimeException)
1753 {
1754     vos::OGuard  aGuard(Application::GetSolarMutex());
1755     uno::Sequence< rtl::OUString > aNames(1);
1756     rtl::OUString* pStrings = aNames.getArray();
1757     pStrings[0] = rPropertyName;
1758     uno::Sequence< beans::PropertyState > aStates = getPropertyStates(aNames);
1759     return aStates.getConstArray()[0];
1760 }
1761 
1762 uno::Sequence< beans::PropertyState > SwXShape::getPropertyStates(
1763     const uno::Sequence< rtl::OUString >& aPropertyNames )
1764         throw(beans::UnknownPropertyException, uno::RuntimeException)
1765 {
1766     vos::OGuard  aGuard(Application::GetSolarMutex());
1767     SwFrmFmt*   pFmt = GetFrmFmt();
1768     uno::Sequence< beans::PropertyState > aRet(aPropertyNames.getLength());
1769     if(xShapeAgg.is())
1770     {
1771         SvxShape* pSvxShape = GetSvxShape();
1772         sal_Bool bGroupMember = sal_False;
1773         sal_Bool bFormControl = sal_False;
1774         SdrObject* pObject = pSvxShape->GetSdrObject();
1775         if(pObject)
1776         {
1777             bGroupMember = pObject->GetUpGroup() != 0;
1778             bFormControl = pObject->GetObjInventor() == FmFormInventor;
1779         }
1780         const rtl::OUString* pNames = aPropertyNames.getConstArray();
1781         beans::PropertyState* pRet = aRet.getArray();
1782         uno::Reference< XPropertyState >  xShapePrState;
1783         for(sal_Int32 nProperty = 0; nProperty < aPropertyNames.getLength(); nProperty++)
1784         {
1785             const SfxItemPropertySimpleEntry*  pEntry = m_pPropSet->getPropertyMap()->getByName( pNames[nProperty] );
1786             if(pEntry)
1787             {
1788                 if(RES_OPAQUE == pEntry->nWID)
1789                     pRet[nProperty] = bFormControl ?
1790                         beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
1791                 else if(FN_ANCHOR_POSITION == pEntry->nWID)
1792                     pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
1793                 else if(FN_TEXT_RANGE == pEntry->nWID)
1794                     pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
1795                 else if(bGroupMember)
1796                     pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
1797                 else if(pFmt)
1798                 {
1799                     const SwAttrSet& rSet = pFmt->GetAttrSet();
1800                     SfxItemState eItemState = rSet.GetItemState(pEntry->nWID, sal_False);
1801 
1802                     if(SFX_ITEM_SET == eItemState)
1803                         pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
1804                     else if(SFX_ITEM_DEFAULT == eItemState)
1805                         pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
1806                     else
1807                         pRet[nProperty] = beans::PropertyState_AMBIGUOUS_VALUE;
1808                 }
1809                 else
1810                 {
1811                     SfxPoolItem* pItem = 0;
1812                     switch(pEntry->nWID)
1813                     {
1814                         case RES_ANCHOR:
1815                             pItem = pImpl->GetAnchor();
1816                         break;
1817                         case RES_HORI_ORIENT:
1818                             pItem = pImpl->GetHOrient();
1819                         break;
1820                         case RES_VERT_ORIENT:
1821                             pItem = pImpl->GetVOrient();
1822                         break;
1823                         case  RES_LR_SPACE:
1824                             pItem = pImpl->GetLRSpace();
1825                         break;
1826                         case  RES_UL_SPACE:
1827                             pItem = pImpl->GetULSpace();
1828                         break;
1829                         case  RES_SURROUND:
1830                             pItem = pImpl->GetSurround();
1831                         break;
1832                         // OD 2004-05-05 #i28701#
1833                         case RES_WRAP_INFLUENCE_ON_OBJPOS:
1834                         {
1835                             pItem = pImpl->GetWrapInfluenceOnObjPos();
1836                         }
1837                         break;
1838                     }
1839                     if(pItem)
1840                         pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
1841                     else
1842                         pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
1843                 }
1844             }
1845             else
1846             {
1847                 if(!xShapePrState.is())
1848                 {
1849                     const uno::Type& rPStateType = ::getCppuType((uno::Reference< XPropertyState >*)0);
1850                     uno::Any aPState = xShapeAgg->queryAggregation(rPStateType);
1851                     if(aPState.getValueType() != rPStateType || !aPState.getValue())
1852                         throw uno::RuntimeException();
1853                     xShapePrState = *(uno::Reference< XPropertyState >*)aPState.getValue();
1854                 }
1855                 pRet[nProperty] = xShapePrState->getPropertyState(pNames[nProperty]);
1856             }
1857         }
1858     }
1859     else
1860         throw uno::RuntimeException();
1861     return aRet;
1862 }
1863 
1864 void SwXShape::setPropertyToDefault( const rtl::OUString& rPropertyName )
1865     throw(beans::UnknownPropertyException, uno::RuntimeException)
1866 {
1867     vos::OGuard  aGuard(Application::GetSolarMutex());
1868     SwFrmFmt*   pFmt = GetFrmFmt();
1869     if(xShapeAgg.is())
1870     {
1871         const SfxItemPropertySimpleEntry*  pEntry = m_pPropSet->getPropertyMap()->getByName( rPropertyName );
1872         if(pEntry)
1873         {
1874             if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
1875                 throw uno::RuntimeException( rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1876             if(pFmt)
1877             {
1878                 const SfxItemSet& rSet = pFmt->GetAttrSet();
1879                 SfxItemSet aSet(pFmt->GetDoc()->GetAttrPool(), pEntry->nWID, pEntry->nWID);
1880                 aSet.SetParent(&rSet);
1881                 aSet.ClearItem(pEntry->nWID);
1882                 pFmt->GetDoc()->SetAttr(aSet, *pFmt);
1883             }
1884             else
1885             {
1886                 switch(pEntry->nWID)
1887                 {
1888                     case RES_ANCHOR:        pImpl->RemoveAnchor();  break;
1889                     case RES_HORI_ORIENT:   pImpl->RemoveHOrient(); break;
1890                     case RES_VERT_ORIENT:   pImpl->RemoveVOrient(); break;
1891                     case  RES_LR_SPACE:     pImpl->RemoveLRSpace(); break;
1892                     case  RES_UL_SPACE:     pImpl->RemoveULSpace(); break;
1893                     case  RES_SURROUND:     pImpl->RemoveSurround();break;
1894                     case RES_OPAQUE :       pImpl->SetOpaque(sal_False);  break;
1895                     case FN_TEXT_RANGE :
1896                     break;
1897                     // OD 2004-04-22 #i26791#
1898                     case RES_FOLLOW_TEXT_FLOW:
1899                     {
1900                         pImpl->RemoveFollowTextFlow();
1901                     }
1902                     break;
1903                     // OD 2004-05-05 #i28701#
1904                     case RES_WRAP_INFLUENCE_ON_OBJPOS:
1905                     {
1906                         pImpl->RemoveWrapInfluenceOnObjPos();
1907                     }
1908                     break;
1909                 }
1910             }
1911         }
1912         else
1913         {
1914             const uno::Type& rPStateType = ::getCppuType((uno::Reference< XPropertyState >*)0);
1915             uno::Any aPState = xShapeAgg->queryAggregation(rPStateType);
1916             if(aPState.getValueType() != rPStateType || !aPState.getValue())
1917                 throw uno::RuntimeException();
1918             uno::Reference< XPropertyState > xShapePrState = *(uno::Reference< XPropertyState >*)aPState.getValue();
1919             xShapePrState->setPropertyToDefault( rPropertyName );
1920         }
1921     }
1922     else
1923         throw uno::RuntimeException();
1924 }
1925 
1926 uno::Any SwXShape::getPropertyDefault( const rtl::OUString& rPropertyName )
1927     throw( beans::UnknownPropertyException, lang::WrappedTargetException,
1928            uno::RuntimeException )
1929 {
1930     vos::OGuard  aGuard(Application::GetSolarMutex());
1931     SwFrmFmt*   pFmt = GetFrmFmt();
1932     uno::Any aRet;
1933     if(xShapeAgg.is())
1934     {
1935         const SfxItemPropertySimpleEntry*  pEntry = m_pPropSet->getPropertyMap()->getByName( rPropertyName );
1936         if(pEntry)
1937         {
1938             if(pEntry->nWID < RES_FRMATR_END && pFmt)
1939             {
1940                 const SfxPoolItem& rDefItem =
1941                     pFmt->GetDoc()->GetAttrPool().GetDefaultItem(pEntry->nWID);
1942                 rDefItem.QueryValue(aRet, pEntry->nMemberId);
1943             }
1944             else
1945                 throw uno::RuntimeException();
1946         }
1947         else
1948         {
1949             const uno::Type& rPStateType = ::getCppuType((uno::Reference< XPropertyState >*)0);
1950             uno::Any aPState = xShapeAgg->queryAggregation(rPStateType);
1951             if(aPState.getValueType() != rPStateType || !aPState.getValue())
1952                 throw uno::RuntimeException();
1953             uno::Reference< XPropertyState > xShapePrState = *(uno::Reference< XPropertyState >*)aPState.getValue();
1954             xShapePrState->getPropertyDefault( rPropertyName );
1955         }
1956     }
1957     else
1958         throw uno::RuntimeException();
1959     return aRet;
1960 }
1961 
1962 void SwXShape::addPropertyChangeListener(
1963     const rtl::OUString& _propertyName,
1964     const uno::Reference< beans::XPropertyChangeListener > & _listener )
1965     throw( beans::UnknownPropertyException, lang::WrappedTargetException,
1966            uno::RuntimeException )
1967 {
1968     if ( !xShapeAgg.is() )
1969         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no shape aggregate" ) ), *this );
1970 
1971     // must be handled by the aggregate
1972     uno::Reference< beans::XPropertySet > xShapeProps;
1973     if ( xShapeAgg->queryAggregation( beans::XPropertySet::static_type() ) >>= xShapeProps )
1974         xShapeProps->addPropertyChangeListener( _propertyName, _listener );
1975 }
1976 
1977 void SwXShape::removePropertyChangeListener(
1978     const rtl::OUString& _propertyName,
1979     const uno::Reference< beans::XPropertyChangeListener > & _listener)
1980     throw( beans::UnknownPropertyException, lang::WrappedTargetException,
1981            uno::RuntimeException )
1982 {
1983     if ( !xShapeAgg.is() )
1984         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no shape aggregate" ) ), *this );
1985 
1986     // must be handled by the aggregate
1987     uno::Reference< beans::XPropertySet > xShapeProps;
1988     if ( xShapeAgg->queryAggregation( beans::XPropertySet::static_type() ) >>= xShapeProps )
1989         xShapeProps->removePropertyChangeListener( _propertyName, _listener );
1990 }
1991 
1992 void SwXShape::addVetoableChangeListener(
1993     const rtl::OUString& /*PropertyName*/,
1994     const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/ )
1995     throw( beans::UnknownPropertyException, lang::WrappedTargetException,
1996            uno::RuntimeException )
1997 {
1998     DBG_WARNING("not implemented");
1999 }
2000 
2001 void SwXShape::removeVetoableChangeListener(
2002     const rtl::OUString& /*PropertyName*/,
2003     const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
2004     throw( beans::UnknownPropertyException, lang::WrappedTargetException,
2005            uno::RuntimeException )
2006 {
2007     DBG_WARNING("not implemented");
2008 }
2009 
2010 void SwXShape::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
2011 {
2012     ClientModify(this, pOld, pNew);
2013 }
2014 
2015 void SwXShape::attach(const uno::Reference< text::XTextRange > & xTextRange)
2016     throw( lang::IllegalArgumentException, uno::RuntimeException )
2017 {
2018     vos::OGuard  aGuard(Application::GetSolarMutex());
2019 
2020     // get access to SwDoc
2021     // (see also SwXTextRange::XTextRangeToSwPaM)
2022     SwDoc*      pDoc = 0;
2023     uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
2024     if(xRangeTunnel.is())
2025     {
2026         SwXTextRange* pRange = 0;
2027         OTextCursorHelper* pCursor = 0;
2028         SwXTextPortion* pPortion = 0;
2029         SwXText* pText = 0;
2030         SwXParagraph* pParagraph = 0;
2031 
2032         pRange  = reinterpret_cast< SwXTextRange * >(
2033                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId()) ));
2034         pText   = reinterpret_cast< SwXText * >(
2035                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXText::getUnoTunnelId()) ));
2036         pCursor = reinterpret_cast< OTextCursorHelper * >(
2037                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId()) ));
2038         pPortion = reinterpret_cast< SwXTextPortion * >(
2039                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextPortion::getUnoTunnelId()) ));
2040         pParagraph = reinterpret_cast< SwXParagraph * >(
2041                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXParagraph::getUnoTunnelId( ) ) ) );
2042 
2043         if (pRange)
2044             pDoc = pRange->GetDoc();
2045         else if (!pDoc && pText)
2046             pDoc = pText->GetDoc();
2047         else if (!pDoc && pCursor)
2048             pDoc = pCursor->GetDoc();
2049         else if ( !pDoc && pPortion && pPortion->GetCursor() )
2050         {
2051             pDoc = pPortion->GetCursor()->GetDoc();
2052         }
2053         else if ( !pDoc && pParagraph && pParagraph->GetTxtNode( ) )
2054         {
2055             pDoc = const_cast<SwDoc*>(pParagraph->GetTxtNode()->GetDoc());
2056         }
2057 
2058     }
2059 
2060     if(!pDoc)
2061         throw uno::RuntimeException();
2062     SwDocShell *pDocSh = pDoc->GetDocShell();
2063     if (pDocSh)
2064     {
2065         uno::Reference< frame::XModel > xModel;
2066         xModel = pDocSh->GetModel();
2067         uno::Reference< drawing::XDrawPageSupplier > xDPS(xModel, uno::UNO_QUERY);
2068         if (xDPS.is())
2069         {
2070             uno::Reference< drawing::XDrawPage > xDP( xDPS->getDrawPage() );
2071             if (xDP.is())
2072             {
2073                 uno::Any aPos;
2074                 aPos <<= xTextRange;
2075                 setPropertyValue(S2U("TextRange"), aPos);
2076                 uno::Reference< drawing::XShape > xTemp( (cppu::OWeakObject*) this, uno::UNO_QUERY );
2077                 xDP->add( xTemp );
2078             }
2079         }
2080     }
2081 }
2082 
2083 uno::Reference< text::XTextRange >  SwXShape::getAnchor(void) throw( uno::RuntimeException )
2084 {
2085     vos::OGuard  aGuard(Application::GetSolarMutex());
2086     uno::Reference< text::XTextRange >  aRef;
2087     SwFrmFmt* pFmt = GetFrmFmt();
2088     if(pFmt)
2089     {
2090         const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
2091         // return an anchor for non-page bound frames
2092         // and for page bound frames that have a page no == NULL and a content position
2093         if ((rAnchor.GetAnchorId() != FLY_AT_PAGE) ||
2094             (rAnchor.GetCntntAnchor() && !rAnchor.GetPageNum()))
2095         {
2096             const SwPosition &rPos = *(pFmt->GetAnchor().GetCntntAnchor());
2097             aRef = SwXTextRange::CreateXTextRange(*pFmt->GetDoc(), rPos, 0);
2098         }
2099     }
2100     else
2101         aRef = pImpl->GetTextRange();
2102     return aRef;
2103 }
2104 
2105 void SwXShape::dispose(void) throw( uno::RuntimeException )
2106 {
2107     vos::OGuard  aGuard(Application::GetSolarMutex());
2108     SwFrmFmt* pFmt = GetFrmFmt();
2109     if(pFmt)
2110     {
2111         // OD 10.07.2003 #110742# - determine correct <SdrObject>
2112         //SdrObject* pObj = pFmt->FindSdrObject();
2113         SdrObject* pObj = GetSvxShape()->GetSdrObject();
2114         // OD 10.07.2003 #110742# - safety assertion:
2115         // <pObj> must be the same as <pFmt->FindSdrObject()>, if <pObj> isn't
2116         // a 'virtual' drawing object.
2117         // OD 25.08.2003 #111713# - refine assertion for safety reason.
2118         // --> OD 2005-02-02 #119236# - correct assertion and refine it.
2119         ASSERT( !pObj ||
2120                 pObj->ISA(SwDrawVirtObj) ||
2121                 pObj->GetUpGroup() ||
2122                 pObj == pFmt->FindSdrObject(),
2123                 "<SwXShape::dispose(..) - different 'master' drawing objects!!" );
2124         // <--
2125         // OD 10.07.2003 #110742# - perform delete of draw frame format *not*
2126         // for 'virtual' drawing objects.
2127         // --> OD 2005-02-02 #119236# - no delete of draw format for members
2128         // of a group
2129         if ( pObj &&
2130              !pObj->ISA(SwDrawVirtObj) &&
2131              !pObj->GetUpGroup() &&
2132              pObj->IsInserted() )
2133         // <--
2134         {
2135             if (pFmt->GetAnchor().GetAnchorId() == FLY_AS_CHAR)
2136             {
2137                 const SwPosition &rPos = *(pFmt->GetAnchor().GetCntntAnchor());
2138                 SwTxtNode *pTxtNode = rPos.nNode.GetNode().GetTxtNode();
2139                 const xub_StrLen nIdx = rPos.nContent.GetIndex();
2140                 pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx );
2141             }
2142             else
2143                 pFmt->GetDoc()->DelLayoutFmt( pFmt );
2144         }
2145     }
2146     if(xShapeAgg.is())
2147     {
2148         uno::Any aAgg(xShapeAgg->queryAggregation( ::getCppuType((uno::Reference<XComponent>*)0)));
2149         uno::Reference<XComponent> xComp;
2150         aAgg >>= xComp;
2151         if(xComp.is())
2152             xComp->dispose();
2153     }
2154 }
2155 
2156 void SwXShape::addEventListener(
2157                     const uno::Reference< lang::XEventListener > & aListener)
2158                     throw( uno::RuntimeException )
2159 {
2160     uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
2161     SvxShape* pSvxShape = GetSvxShape();
2162     if(pSvxShape)
2163         pSvxShape->addEventListener(aListener);
2164 }
2165 
2166 void SwXShape::removeEventListener(
2167                     const uno::Reference< lang::XEventListener > & aListener)
2168                     throw( uno::RuntimeException )
2169 {
2170     SvxShape* pSvxShape = GetSvxShape();
2171     if(pSvxShape)
2172         pSvxShape->removeEventListener(aListener);
2173 }
2174 
2175 rtl::OUString SwXShape::getImplementationName(void) throw( uno::RuntimeException )
2176 {
2177     return C2U("SwXShape");
2178 }
2179 
2180 sal_Bool SwXShape::supportsService(const rtl::OUString& rServiceName) throw( uno::RuntimeException )
2181 {
2182     sal_Bool bRet = sal_False;
2183     if(COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.drawing.Shape"))
2184         bRet = sal_True;
2185     else if(xShapeAgg.is())
2186     {
2187         uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
2188         SvxShape* pSvxShape = GetSvxShape();
2189         bRet = pSvxShape->supportsService(rServiceName);
2190     }
2191     return bRet;
2192 }
2193 
2194 uno::Sequence< rtl::OUString > SwXShape::getSupportedServiceNames(void) throw( uno::RuntimeException )
2195 {
2196     uno::Sequence< rtl::OUString > aSeq;
2197     if(xShapeAgg.is())
2198     {
2199         uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
2200         SvxShape* pSvxShape = GetSvxShape();
2201         if(pSvxShape)
2202             aSeq = pSvxShape->getSupportedServiceNames();
2203     }
2204     else
2205     {
2206         aSeq.realloc(1);
2207         aSeq.getArray()[0] = C2U("com.sun.star.drawing.Shape");
2208     }
2209     return aSeq;
2210 }
2211 
2212 SvxShape*   SwXShape::GetSvxShape()
2213 {
2214     SvxShape* pSvxShape = 0;
2215     if(xShapeAgg.is())
2216     {
2217         uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
2218         if(xShapeTunnel.is())
2219             pSvxShape = reinterpret_cast< SvxShape * >(
2220                     sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SvxShape::getUnoTunnelId()) ));
2221     }
2222     return pSvxShape;
2223 }
2224 
2225 // --> OD 2004-07-22 #i31698# -
2226 // implementation of virtual methods from drawing::XShape
2227 awt::Point SAL_CALL SwXShape::getPosition() throw ( uno::RuntimeException )
2228 {
2229     awt::Point aPos( _GetAttrPosition() );
2230 
2231     // handle group members
2232     SvxShape* pSvxShape = GetSvxShape();
2233     if ( pSvxShape )
2234     {
2235         SdrObject* pTopGroupObj = _GetTopGroupObj( pSvxShape );
2236         if ( pTopGroupObj )
2237         {
2238             // --> OD 2004-10-01 #i34750# - get attribute position of top group
2239             // shape and add offset between top group object and group member
2240             uno::Reference< drawing::XShape > xGroupShape =
2241                     uno::Reference< drawing::XShape >( pTopGroupObj->getUnoShape(),
2242                                                        uno::UNO_QUERY );
2243             aPos = xGroupShape->getPosition();
2244             // add offset between top group object and group member
2245             // to the determined attribute position
2246             // --> OD 2004-10-01 #i34750# - correction:
2247             // consider the layout direction
2248             const Rectangle aMemberObjRect = GetSvxShape()->GetSdrObject()->GetSnapRect();
2249             const Rectangle aGroupObjRect = pTopGroupObj->GetSnapRect();
2250             // --> OD 2005-08-16 #i53320# - relative position of group member and
2251             // top group object is always given in horizontal left-to-right layout.
2252 //            const SwFrmFmt::tLayoutDir eLayoutDir = GetFrmFmt()
2253 //                                                    ? GetFrmFmt()->GetLayoutDir()
2254 //                                                    : SwFrmFmt::HORI_L2R;
2255             awt::Point aOffset( 0, 0 );
2256 //            switch ( eLayoutDir )
2257 //            {
2258 //                case SwFrmFmt::HORI_L2R:
2259                 {
2260                     aOffset.X = ( aMemberObjRect.Left() - aGroupObjRect.Left() );
2261                     aOffset.Y = ( aMemberObjRect.Top() - aGroupObjRect.Top() );
2262                 }
2263 //                break;
2264 //                case SwFrmFmt::HORI_R2L:
2265 //                {
2266 //                    aOffset.X = ( aGroupObjRect.Right() - aMemberObjRect.Right() );
2267 //                    aOffset.Y = ( aMemberObjRect.Top() - aGroupObjRect.Top() );
2268 //                }
2269 //                break;
2270 //                case SwFrmFmt::VERT_R2L:
2271 //                {
2272 //                    aOffset.X = ( aMemberObjRect.Top() - aGroupObjRect.Top() );
2273 //                    aOffset.Y = ( aGroupObjRect.Right() - aMemberObjRect.Right() );
2274 //                }
2275 //                break;
2276 //                default:
2277 //                {
2278 //                    ASSERT( false,
2279 //                            "<SwXShape::getPosition()> - unsupported layout direction" );
2280 //                }
2281 //            }
2282             // <--
2283             aOffset.X = TWIP_TO_MM100(aOffset.X);
2284             aOffset.Y = TWIP_TO_MM100(aOffset.Y);
2285             aPos.X += aOffset.X;
2286             aPos.Y += aOffset.Y;
2287             // <--
2288         }
2289     }
2290 
2291     return aPos;
2292 }
2293 void SAL_CALL SwXShape::setPosition( const awt::Point& aPosition )
2294                                                 throw ( uno::RuntimeException )
2295 {
2296     SdrObject* pTopGroupObj = _GetTopGroupObj();
2297     if ( !pTopGroupObj )
2298     {
2299         // --> OD 2005-02-10 #i37877# - no adjustment of position attributes,
2300         // if the position also has to be applied at the drawing object and
2301         // a contact object is already registered at the drawing object.
2302         bool bApplyPosAtDrawObj(false);
2303         bool bNoAdjustOfPosProp(false);
2304         // --> OD 2004-10-19 #i35798# - apply position also to drawing object,
2305         // if drawing object has no anchor position set.
2306         if ( mxShape.is() )
2307         {
2308             SvxShape* pSvxShape = GetSvxShape();
2309             if ( pSvxShape )
2310             {
2311                 const SdrObject* pObj = pSvxShape->GetSdrObject();
2312                 if ( pObj &&
2313                      pObj->GetAnchorPos().X() == 0 &&
2314                      pObj->GetAnchorPos().Y() == 0 )
2315                 {
2316                     bApplyPosAtDrawObj = true;
2317                     if ( pObj->GetUserCall() &&
2318                          pObj->GetUserCall()->ISA(SwDrawContact) )
2319                     {
2320                         bNoAdjustOfPosProp = true;
2321                     }
2322                 }
2323             }
2324         }
2325         // <--
2326         // shape isn't a group member. Thus, set positioning attributes
2327         if ( !bNoAdjustOfPosProp )
2328         {
2329             _AdjustPositionProperties( aPosition );
2330         }
2331         if ( bApplyPosAtDrawObj )
2332         {
2333             mxShape->setPosition( aPosition );
2334         }
2335         // <--
2336     }
2337     else if ( mxShape.is() )
2338     {
2339         // shape is a member of a group. Thus, set its position.
2340         awt::Point aNewPos( aPosition );
2341         // The given position is given in the according layout direction. Thus,
2342         // it has to be converted to a position in horizontal left-to-right
2343         // layout.
2344         // convert given absolute attribute position in layout direction into
2345         // position in horizontal left-to-right layout.
2346         {
2347             aNewPos = _ConvertPositionToHoriL2R( aNewPos, getSize() );
2348         }
2349         // Convert given absolute position in horizontal left-to-right
2350         // layout into relative position in horizontal left-to-right layout.
2351         uno::Reference< drawing::XShape > xGroupShape =
2352                 uno::Reference< drawing::XShape >( pTopGroupObj->getUnoShape(),
2353                                                    uno::UNO_QUERY );
2354         {
2355             // --> OD 2004-09-29 #i34750# - correction:
2356             // use method <xGroupShape->getPosition()> to get the correct
2357             // position of the top group object.
2358             awt::Point aAttrPosInHoriL2R(
2359                     _ConvertPositionToHoriL2R( xGroupShape->getPosition(),
2360                                                xGroupShape->getSize() ) );
2361             // <--
2362             aNewPos.X -= aAttrPosInHoriL2R.X;
2363             aNewPos.Y -= aAttrPosInHoriL2R.Y;
2364         }
2365         // convert relative position in horizontal left-to-right layout into
2366         // absolute position in horizontal left-to-right layout
2367         {
2368             // --> OD 2004-10-01 #i34750# - correction:
2369             // use method <SvxShape->getPosition()> to get the correct
2370             // 'Drawing layer' position of the top group shape.
2371             uno::Reference< lang::XUnoTunnel > xGrpShapeTunnel(
2372                                                     pTopGroupObj->getUnoShape(),
2373                                                     uno::UNO_QUERY );
2374             SvxShape* pSvxGroupShape = reinterpret_cast< SvxShape * >(
2375                     sal::static_int_cast< sal_IntPtr >( xGrpShapeTunnel->getSomething(SvxShape::getUnoTunnelId()) ));
2376             const awt::Point aGroupPos = pSvxGroupShape->getPosition();
2377             aNewPos.X += aGroupPos.X;
2378             aNewPos.Y += aGroupPos.Y;
2379             // <--
2380         }
2381         // set position
2382         mxShape->setPosition( aNewPos );
2383     }
2384 }
2385 awt::Size SAL_CALL SwXShape::getSize() throw ( uno::RuntimeException )
2386 {
2387     awt::Size aSize;
2388     if ( mxShape.is() )
2389     {
2390         aSize = mxShape->getSize();
2391     }
2392     return aSize;
2393 }
2394 void SAL_CALL SwXShape::setSize( const awt::Size& aSize )
2395                                         throw ( beans::PropertyVetoException,
2396                                                 uno::RuntimeException )
2397 {
2398     if ( mxShape.is() )
2399     {
2400         mxShape->setSize( aSize );
2401     }
2402 }
2403 // <--
2404 // --> OD 2004-07-22 #i31698# -
2405 // implementation of virtual methods from drawing::XShapeDescriptor
2406 ::rtl::OUString SAL_CALL SwXShape::getShapeType() throw ( uno::RuntimeException )
2407 {
2408     ::rtl::OUString aType;
2409     if ( mxShape.is() )
2410     {
2411         aType = mxShape->getShapeType();
2412     }
2413     return aType;
2414 }
2415 // <--
2416 /** method to determine top group object
2417 
2418     OD 2004-08-03 #i31698#
2419 
2420     @author OD
2421 */
2422 SdrObject* SwXShape::_GetTopGroupObj( SvxShape* _pSvxShape )
2423 {
2424     SdrObject* pTopGroupObj( 0L );
2425 
2426     SvxShape* pSvxShape = _pSvxShape ? _pSvxShape : GetSvxShape();
2427     if ( pSvxShape )
2428     {
2429         SdrObject* pSdrObj = pSvxShape->GetSdrObject();
2430         if ( pSdrObj && pSdrObj->GetUpGroup() )
2431         {
2432             pTopGroupObj = pSdrObj->GetUpGroup();
2433             while ( pTopGroupObj->GetUpGroup() )
2434             {
2435                 pTopGroupObj = pTopGroupObj->GetUpGroup();
2436             }
2437         }
2438     }
2439 
2440     return pTopGroupObj;
2441 }
2442 
2443 /** method to determine position according to the positioning attributes
2444 
2445     OD 2004-08-03 #i31698#
2446 
2447     @author OD
2448 */
2449 awt::Point SwXShape::_GetAttrPosition()
2450 {
2451     awt::Point aAttrPos;
2452 
2453     uno::Any aHoriPos( getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HoriOrientPosition")) ) );
2454     aHoriPos >>= aAttrPos.X;
2455     uno::Any aVertPos( getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VertOrientPosition")) ) );
2456     aVertPos >>= aAttrPos.Y;
2457     // --> OD 2004-10-19 #i35798# - fallback, if attribute position is (0,0)
2458     // and no anchor position is applied to the drawing object
2459     SvxShape* pSvxShape = GetSvxShape();
2460     if ( pSvxShape )
2461     {
2462         const SdrObject* pObj = pSvxShape->GetSdrObject();
2463         if ( pObj &&
2464              pObj->GetAnchorPos().X() == 0 &&
2465              pObj->GetAnchorPos().Y() == 0 &&
2466              aAttrPos.X == 0 && aAttrPos.Y == 0 )
2467         {
2468             const Rectangle aObjRect = pObj->GetSnapRect();
2469             aAttrPos.X = TWIP_TO_MM100(aObjRect.Left());
2470             aAttrPos.Y = TWIP_TO_MM100(aObjRect.Top());
2471         }
2472     }
2473     // <--
2474     // --> OD 2004-11-10 #i35007# - If drawing object is anchored as-character,
2475     // it's x-position isn't sensible. Thus, return the x-position as zero in this case.
2476     text::TextContentAnchorType eTextAnchorType =
2477                             text::TextContentAnchorType_AT_PARAGRAPH;
2478     {
2479         rtl::OUString sAnchorType( RTL_CONSTASCII_USTRINGPARAM( "AnchorType" ) );
2480         uno::Any aAny = getPropertyValue( sAnchorType );
2481         aAny >>= eTextAnchorType;
2482     }
2483     if ( eTextAnchorType == text::TextContentAnchorType_AS_CHARACTER )
2484     {
2485         aAttrPos.X = 0;
2486     }
2487     // <--
2488 
2489     return aAttrPos;
2490 }
2491 
2492 /** method to convert the position (translation) of the drawing object to
2493     the layout direction horizontal left-to-right.
2494 
2495     OD 2004-07-27 #i31698#
2496 
2497     @author OD
2498 */
2499 awt::Point SwXShape::_ConvertPositionToHoriL2R( const awt::Point _aObjPos,
2500                                                 const awt::Size _aObjSize )
2501 {
2502     awt::Point aObjPosInHoriL2R( _aObjPos );
2503 
2504     SwFrmFmt* pFrmFmt = GetFrmFmt();
2505     if ( pFrmFmt )
2506     {
2507         SwFrmFmt::tLayoutDir eLayoutDir = pFrmFmt->GetLayoutDir();
2508         switch ( eLayoutDir )
2509         {
2510             case SwFrmFmt::HORI_L2R:
2511             {
2512                 // nothing to do
2513             }
2514             break;
2515             case SwFrmFmt::HORI_R2L:
2516             {
2517                 aObjPosInHoriL2R.X = -_aObjPos.X - _aObjSize.Width;
2518             }
2519             break;
2520             case SwFrmFmt::VERT_R2L:
2521             {
2522                 aObjPosInHoriL2R.X = -_aObjPos.Y - _aObjSize.Width;
2523                 aObjPosInHoriL2R.Y = _aObjPos.X;
2524             }
2525             break;
2526             default:
2527             {
2528                 ASSERT( false,
2529                         "<SwXShape::_ConvertPositionToHoriL2R(..)> - unsupported layout direction" );
2530             }
2531         }
2532     }
2533 
2534     return aObjPosInHoriL2R;
2535 }
2536 /** method to convert the transformation of the drawing object to the layout
2537     direction, the drawing object is in
2538 
2539     OD 2004-07-27 #i31698#
2540 
2541     @author OD
2542 */
2543 drawing::HomogenMatrix3 SwXShape::_ConvertTransformationToLayoutDir(
2544                                     drawing::HomogenMatrix3 _aMatrixInHoriL2R )
2545 {
2546     drawing::HomogenMatrix3 aMatrix( _aMatrixInHoriL2R );
2547 
2548     // --> OD 2005-03-10 #i44334#, #i44681# - direct manipulation of the
2549     // tranformation structure isn't valid, if it contains rotation.
2550     SvxShape* pSvxShape = GetSvxShape();
2551     ASSERT( pSvxShape,
2552             "<SwXShape::_ConvertTransformationToLayoutDir(..)> - no SvxShape found!")
2553     if ( pSvxShape )
2554     {
2555         const SdrObject* pObj = pSvxShape->GetSdrObject();
2556         ASSERT( pObj,
2557                 "<SwXShape::_ConvertTransformationToLayoutDir(..)> - no SdrObject found!")
2558         if ( pObj )
2559         {
2560             // get position of object in Writer coordinate system.
2561             awt::Point aPos( getPosition() );
2562             // get position of object in Drawing layer coordinate system
2563             const Point aTmpObjPos( pObj->GetSnapRect().TopLeft() );
2564             const awt::Point aObjPos(
2565                     TWIP_TO_MM100( aTmpObjPos.X() - pObj->GetAnchorPos().X() ),
2566                     TWIP_TO_MM100( aTmpObjPos.Y() - pObj->GetAnchorPos().Y() ) );
2567             // determine difference between these positions according to the
2568             // Writer coordinate system
2569             const awt::Point aTranslateDiff( aPos.X - aObjPos.X,
2570                                              aPos.Y - aObjPos.Y );
2571             // apply translation difference to transformation matrix.
2572             if ( aTranslateDiff.X != 0 || aTranslateDiff.Y != 0 )
2573             {
2574                 // --> OD 2007-01-03 #i73079# - use correct matrix type
2575                 ::basegfx::B2DHomMatrix aTempMatrix;
2576                 // <--
2577 
2578                 aTempMatrix.set(0, 0, aMatrix.Line1.Column1 );
2579                 aTempMatrix.set(0, 1, aMatrix.Line1.Column2 );
2580                 aTempMatrix.set(0, 2, aMatrix.Line1.Column3 );
2581                 aTempMatrix.set(1, 0, aMatrix.Line2.Column1 );
2582                 aTempMatrix.set(1, 1, aMatrix.Line2.Column2 );
2583                 aTempMatrix.set(1, 2, aMatrix.Line2.Column3 );
2584                 aTempMatrix.set(2, 0, aMatrix.Line3.Column1 );
2585                 aTempMatrix.set(2, 1, aMatrix.Line3.Column2 );
2586                 aTempMatrix.set(2, 2, aMatrix.Line3.Column3 );
2587 
2588                 // --> OD 2007-01-03 #i73079#
2589                 aTempMatrix.translate( aTranslateDiff.X, aTranslateDiff.Y );
2590                 // <--
2591 
2592                 aMatrix.Line1.Column1 = aTempMatrix.get(0, 0);
2593                 aMatrix.Line1.Column2 = aTempMatrix.get(0, 1);
2594                 aMatrix.Line1.Column3 = aTempMatrix.get(0, 2);
2595                 aMatrix.Line2.Column1 = aTempMatrix.get(1, 0);
2596                 aMatrix.Line2.Column2 = aTempMatrix.get(1, 1);
2597                 aMatrix.Line2.Column3 = aTempMatrix.get(1, 2);
2598                 aMatrix.Line3.Column1 = aTempMatrix.get(2, 0);
2599                 aMatrix.Line3.Column2 = aTempMatrix.get(2, 1);
2600                 aMatrix.Line3.Column3 = aTempMatrix.get(2, 2);
2601             }
2602         }
2603     }
2604     // <--
2605 
2606     return aMatrix;
2607 }
2608 
2609 /** method to adjust the positioning properties
2610 
2611     OD 2004-08-02 #i31698#
2612 
2613     @author OD
2614 */
2615 void SwXShape::_AdjustPositionProperties( const awt::Point _aPosition )
2616 {
2617     // handle x-position
2618     // --> OD 2004-11-10 #i35007# - no handling of x-position, if drawing
2619     // object is anchored as-character, because it doesn't make sense.
2620     text::TextContentAnchorType eTextAnchorType =
2621                             text::TextContentAnchorType_AT_PARAGRAPH;
2622     {
2623         rtl::OUString sAnchorType( RTL_CONSTASCII_USTRINGPARAM( "AnchorType" ) );
2624         uno::Any aAny = getPropertyValue( sAnchorType );
2625         aAny >>= eTextAnchorType;
2626     }
2627     if ( eTextAnchorType != text::TextContentAnchorType_AS_CHARACTER )
2628     // <--
2629     {
2630         // determine current x-postion
2631         rtl::OUString aHoriPosPropStr( RTL_CONSTASCII_USTRINGPARAM("HoriOrientPosition") );
2632         uno::Any aHoriPos( getPropertyValue( aHoriPosPropStr ) );
2633         sal_Int32 dCurrX = 0;
2634         aHoriPos >>= dCurrX;
2635         // change x-position attribute, if needed
2636         if ( dCurrX != _aPosition.X )
2637         {
2638             // adjust x-position orientation to text::HoriOrientation::NONE, if needed
2639             // Note: has to be done before setting x-position attribute
2640             rtl::OUString aHoriOrientPropStr( RTL_CONSTASCII_USTRINGPARAM("HoriOrient") );
2641             uno::Any aHoriOrient( getPropertyValue( aHoriOrientPropStr ) );
2642             sal_Int16 eHoriOrient;
2643             if (aHoriOrient >>= eHoriOrient) // may be void
2644             {
2645                 if ( eHoriOrient != text::HoriOrientation::NONE )
2646                 {
2647                     eHoriOrient = text::HoriOrientation::NONE;
2648                     aHoriOrient <<= eHoriOrient;
2649                     setPropertyValue( aHoriOrientPropStr, aHoriOrient );
2650                 }
2651             }
2652             // set x-position attribute
2653             aHoriPos <<= _aPosition.X;
2654             setPropertyValue( aHoriPosPropStr, aHoriPos );
2655         }
2656     }
2657 
2658     // handle y-position
2659     {
2660         // determine current y-postion
2661         rtl::OUString aVertPosPropStr( RTL_CONSTASCII_USTRINGPARAM("VertOrientPosition") );
2662         uno::Any aVertPos( getPropertyValue( aVertPosPropStr ) );
2663         sal_Int32 dCurrY = 0;
2664         aVertPos >>= dCurrY;
2665         // change y-position attribute, if needed
2666         if ( dCurrY != _aPosition.Y )
2667         {
2668             // adjust y-position orientation to text::VertOrientation::NONE, if needed
2669             // Note: has to be done before setting y-position attribute
2670             rtl::OUString aVertOrientPropStr( RTL_CONSTASCII_USTRINGPARAM("VertOrient") );
2671             uno::Any aVertOrient( getPropertyValue( aVertOrientPropStr ) );
2672             sal_Int16 eVertOrient;
2673             if (aVertOrient >>= eVertOrient) // may be void
2674             {
2675                 if ( eVertOrient != text::VertOrientation::NONE )
2676                 {
2677                     eVertOrient = text::VertOrientation::NONE;
2678                     aVertOrient <<= eVertOrient;
2679                     setPropertyValue( aVertOrientPropStr, aVertOrient );
2680                 }
2681             }
2682             // set y-position attribute
2683             aVertPos <<= _aPosition.Y;
2684             setPropertyValue( aVertPosPropStr, aVertPos );
2685         }
2686     }
2687 }
2688 
2689 /** method to convert start or end position of the drawing object to the
2690     Writer specific position, which is the attribute position in layout direction
2691 
2692     OD 2009-01-12 #i59051#
2693 
2694     @author OD
2695 */
2696 ::com::sun::star::awt::Point SwXShape::_ConvertStartOrEndPosToLayoutDir(
2697                             const ::com::sun::star::awt::Point& aStartOrEndPos )
2698 {
2699     awt::Point aConvertedPos( aStartOrEndPos );
2700 
2701     SvxShape* pSvxShape = GetSvxShape();
2702     ASSERT( pSvxShape,
2703             "<SwXShape::_ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!")
2704     if ( pSvxShape )
2705     {
2706         const SdrObject* pObj = pSvxShape->GetSdrObject();
2707         ASSERT( pObj,
2708                 "<SwXShape::_ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!")
2709         if ( pObj )
2710         {
2711             // get position of object in Writer coordinate system.
2712             awt::Point aPos( getPosition() );
2713             // get position of object in Drawing layer coordinate system
2714             const Point aTmpObjPos( pObj->GetSnapRect().TopLeft() );
2715             const awt::Point aObjPos(
2716                     TWIP_TO_MM100( aTmpObjPos.X() - pObj->GetAnchorPos().X() ),
2717                     TWIP_TO_MM100( aTmpObjPos.Y() - pObj->GetAnchorPos().Y() ) );
2718             // determine difference between these positions according to the
2719             // Writer coordinate system
2720             const awt::Point aTranslateDiff( aPos.X - aObjPos.X,
2721                                              aPos.Y - aObjPos.Y );
2722             // apply translation difference to transformation matrix.
2723             if ( aTranslateDiff.X != 0 || aTranslateDiff.Y != 0 )
2724             {
2725                 aConvertedPos.X = aConvertedPos.X + aTranslateDiff.X;
2726                 aConvertedPos.Y = aConvertedPos.Y + aTranslateDiff.Y;
2727             }
2728         }
2729     }
2730 
2731     return aConvertedPos;
2732 }
2733 
2734 ::com::sun::star::drawing::PolyPolygonBezierCoords SwXShape::_ConvertPolyPolygonBezierToLayoutDir(
2735                     const ::com::sun::star::drawing::PolyPolygonBezierCoords& aPath )
2736 {
2737     drawing::PolyPolygonBezierCoords aConvertedPath( aPath );
2738 
2739     SvxShape* pSvxShape = GetSvxShape();
2740     ASSERT( pSvxShape,
2741             "<SwXShape::_ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!")
2742     if ( pSvxShape )
2743     {
2744         const SdrObject* pObj = pSvxShape->GetSdrObject();
2745         ASSERT( pObj,
2746                 "<SwXShape::_ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!")
2747         if ( pObj )
2748         {
2749             // get position of object in Writer coordinate system.
2750             awt::Point aPos( getPosition() );
2751             // get position of object in Drawing layer coordinate system
2752             const Point aTmpObjPos( pObj->GetSnapRect().TopLeft() );
2753             const awt::Point aObjPos(
2754                     TWIP_TO_MM100( aTmpObjPos.X() - pObj->GetAnchorPos().X() ),
2755                     TWIP_TO_MM100( aTmpObjPos.Y() - pObj->GetAnchorPos().Y() ) );
2756             // determine difference between these positions according to the
2757             // Writer coordinate system
2758             const awt::Point aTranslateDiff( aPos.X - aObjPos.X,
2759                                              aPos.Y - aObjPos.Y );
2760             // apply translation difference to PolyPolygonBezier.
2761             if ( aTranslateDiff.X != 0 || aTranslateDiff.Y != 0 )
2762             {
2763                 const basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
2764                     aTranslateDiff.X, aTranslateDiff.Y));
2765 
2766                 const sal_Int32 nOuterSequenceCount(aConvertedPath.Coordinates.getLength());
2767                 drawing::PointSequence* pInnerSequence = aConvertedPath.Coordinates.getArray();
2768                 for(sal_Int32 a(0); a < nOuterSequenceCount; a++)
2769                 {
2770                     const sal_Int32 nInnerSequenceCount(pInnerSequence->getLength());
2771                     awt::Point* pArray = pInnerSequence->getArray();
2772 
2773                     for(sal_Int32 b(0); b < nInnerSequenceCount; b++)
2774                     {
2775                         basegfx::B2DPoint aNewCoordinatePair(pArray->X, pArray->Y);
2776                         aNewCoordinatePair *= aMatrix;
2777                         pArray->X = basegfx::fround(aNewCoordinatePair.getX());
2778                         pArray->Y = basegfx::fround(aNewCoordinatePair.getY());
2779                         pArray++;
2780                     }
2781                 }
2782             }
2783         }
2784     }
2785 
2786     return aConvertedPath;
2787 }
2788 
2789 
2790 SwXGroupShape::SwXGroupShape(uno::Reference< XInterface > & xShape) :
2791         SwXShape(xShape)
2792 {
2793 #ifdef DBG_UTIL
2794     uno::Reference<XShapes> xShapes(xShapeAgg, uno::UNO_QUERY);
2795     DBG_ASSERT(xShapes.is(), "no SvxShape found or shape is not a group shape");
2796 #endif
2797 }
2798 
2799 
2800 SwXGroupShape::~SwXGroupShape()
2801 {
2802 }
2803 
2804 uno::Any SwXGroupShape::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
2805 {
2806     uno::Any aRet;
2807     if(rType == ::getCppuType((uno::Reference<XShapes>*)0))
2808         aRet <<= uno::Reference<XShapes>(this);
2809     else
2810         aRet = SwXShape::queryInterface(rType);
2811     return aRet;
2812 }
2813 
2814 void SwXGroupShape::acquire(  ) throw()
2815 {
2816     SwXShape::acquire();
2817 }
2818 
2819 void SwXGroupShape::release(  ) throw()
2820 {
2821     SwXShape::release();
2822 }
2823 
2824 void SwXGroupShape::add( const uno::Reference< XShape >& xShape ) throw (uno::RuntimeException)
2825 {
2826     vos::OGuard  aGuard(Application::GetSolarMutex());
2827     SvxShape* pSvxShape = GetSvxShape();
2828     SwFrmFmt* pFmt = GetFrmFmt();
2829     if(pSvxShape && pFmt)
2830     {
2831         uno::Reference<XShapes> xShapes;
2832         if( xShapeAgg.is() )
2833         {
2834             const uno::Type& rType = ::getCppuType((uno::Reference<XShapes>*)0 );
2835             uno::Any aAgg = xShapeAgg->queryAggregation( rType );
2836             aAgg >>= xShapes;
2837         }
2838         if(xShapes.is())
2839             xShapes->add(xShape);
2840         else
2841             throw uno::RuntimeException();
2842 
2843         uno::Reference<lang::XUnoTunnel> xTunnel(xShape, uno::UNO_QUERY);
2844         SwXShape* pSwShape = 0;
2845         if(xShape.is())
2846             pSwShape = reinterpret_cast< SwXShape * >(
2847                     sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething(SwXShape::getUnoTunnelId()) ));
2848         if(pSwShape && pSwShape->m_bDescriptor)
2849         {
2850             SvxShape* pAddShape = reinterpret_cast< SvxShape * >(
2851                     sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething(SvxShape::getUnoTunnelId()) ));
2852             if(pAddShape)
2853             {
2854                 SdrObject* pObj = pAddShape->GetSdrObject();
2855                 if(pObj)
2856                 {
2857                     SwDoc* pDoc = pFmt->GetDoc();
2858                     // OD 25.06.2003 #108784# - set layer of new drawing
2859                     // object to corresponding invisible layer.
2860                     if( FmFormInventor != pObj->GetObjInventor())
2861                     {
2862                         pObj->SetLayer( pSwShape->pImpl->GetOpaque()
2863                                         ? pDoc->GetInvisibleHeavenId()
2864                                         : pDoc->GetInvisibleHellId() );
2865                     }
2866                     else
2867                     {
2868                         pObj->SetLayer(pDoc->GetInvisibleControlsId());
2869                     }
2870                 }
2871             }
2872             pSwShape->m_bDescriptor = sal_False;
2873             //add the group member to the format of the group
2874             SwFrmFmt* pShapeFmt = ::FindFrmFmt( pSvxShape->GetSdrObject() );
2875             if(pShapeFmt)
2876                 pFmt->Add(pSwShape);
2877         }
2878     }
2879     else
2880         throw uno::RuntimeException();
2881 }
2882 
2883 void SwXGroupShape::remove( const uno::Reference< XShape >& xShape ) throw (uno::RuntimeException)
2884 {
2885     vos::OGuard  aGuard(Application::GetSolarMutex());
2886     uno::Reference<XShapes> xShapes;
2887     if( xShapeAgg.is() )
2888     {
2889         const uno::Type& rType = ::getCppuType((uno::Reference<XShapes>*)0 );
2890         uno::Any aAgg = xShapeAgg->queryAggregation( rType );
2891         aAgg >>= xShapes;
2892     }
2893     if(!xShapes.is())
2894         throw uno::RuntimeException();
2895     xShapes->remove(xShape);
2896 }
2897 
2898 sal_Int32 SwXGroupShape::getCount(void) throw( uno::RuntimeException )
2899 {
2900     vos::OGuard  aGuard(Application::GetSolarMutex());
2901     uno::Reference<XIndexAccess> xAcc;
2902     if( xShapeAgg.is() )
2903     {
2904         const uno::Type& rType = ::getCppuType((uno::Reference<XIndexAccess>*)0 );
2905         uno::Any aAgg = xShapeAgg->queryAggregation( rType );
2906         aAgg >>= xAcc;
2907     }
2908     if(!xAcc.is())
2909         throw uno::RuntimeException();
2910     return xAcc->getCount();
2911 }
2912 
2913 uno::Any SwXGroupShape::getByIndex(sal_Int32 nIndex)
2914         throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException,
2915                uno::RuntimeException )
2916 {
2917     vos::OGuard  aGuard(Application::GetSolarMutex());
2918     uno::Reference<XIndexAccess> xAcc;
2919     if( xShapeAgg.is() )
2920     {
2921         const uno::Type& rType = ::getCppuType((uno::Reference<XIndexAccess>*)0 );
2922         uno::Any aAgg = xShapeAgg->queryAggregation( rType );
2923         aAgg >>= xAcc;
2924     }
2925     if(!xAcc.is())
2926         throw uno::RuntimeException();
2927     return xAcc->getByIndex(nIndex);
2928 }
2929 
2930 uno::Type SwXGroupShape::getElementType(  ) throw(uno::RuntimeException)
2931 {
2932     vos::OGuard  aGuard(Application::GetSolarMutex());
2933     uno::Reference<XIndexAccess> xAcc;
2934     if( xShapeAgg.is() )
2935     {
2936         const uno::Type& rType = ::getCppuType((uno::Reference<XIndexAccess>*)0 );
2937         uno::Any aAgg = xShapeAgg->queryAggregation( rType );
2938         aAgg >>= xAcc;
2939     }
2940     if(!xAcc.is())
2941         throw uno::RuntimeException();
2942     return xAcc->getElementType();
2943 }
2944 
2945 sal_Bool SwXGroupShape::hasElements(  ) throw(uno::RuntimeException)
2946 {
2947     vos::OGuard  aGuard(Application::GetSolarMutex());
2948     uno::Reference<XIndexAccess> xAcc;
2949     if( xShapeAgg.is() )
2950     {
2951         const uno::Type& rType = ::getCppuType((uno::Reference<XIndexAccess>*)0 );
2952         uno::Any aAgg = xShapeAgg->queryAggregation( rType );
2953         aAgg >>= xAcc;
2954     }
2955     if(!xAcc.is())
2956         throw uno::RuntimeException();
2957     return xAcc->hasElements();
2958 }
2959 
2960 
2961