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