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