1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <initializer_list>
24 #include <string_view>
26 #include <sal/log.hxx>
31 #include <drawdoc.hxx>
32 #include <unodraw.hxx>
33 #include <unoframe.hxx>
34 #include <unoparagraph.hxx>
35 #include <unotextrange.hxx>
36 #include <svx/svditer.hxx>
37 #include <swunohelper.hxx>
38 #include <textboxhelper.hxx>
40 #include <IDocumentUndoRedo.hxx>
41 #include <IDocumentDrawModelAccess.hxx>
42 #include <IDocumentLayoutAccess.hxx>
43 #include <fmtcntnt.hxx>
44 #include <fmtflcnt.hxx>
45 #include <txatbase.hxx>
48 #include <unoport.hxx>
49 #include <TextCursorHelper.hxx>
50 #include <dflyobj.hxx>
52 #include <svx/svdview.hxx>
53 #include <svx/unoshape.hxx>
54 #include <dcontact.hxx>
55 #include <fmtornt.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 <o3tl/any.hxx>
62 #include <o3tl/safeint.hxx>
63 #include <svx/shapepropertynotifier.hxx>
64 #include <crstate.hxx>
65 #include <comphelper/extract.hxx>
66 #include <comphelper/profilezone.hxx>
67 #include <comphelper/sequence.hxx>
68 #include <cppuhelper/supportsservice.hxx>
69 #include <svx/scene3d.hxx>
70 #include <tools/UnitConversion.hxx>
71 #include <com/sun/star/beans/PropertyAttribute.hpp>
72 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
73 #include <com/sun/star/frame/XModel.hpp>
74 #include <fmtwrapinfluenceonobjpos.hxx>
75 #include <com/sun/star/text/TextContentAnchorType.hpp>
76 #include <basegfx/matrix/b2dhommatrixtools.hxx>
77 #include <com/sun/star/drawing/PointSequence.hpp>
78 #include <com/sun/star/lang/IllegalArgumentException.hpp>
79 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
80 #include <docmodel/uno/UnoTheme.hxx>
82 using namespace ::com::sun::star
;
84 class SwShapeDescriptor_Impl
87 std::unique_ptr
<SwFormatHoriOrient
> m_pHOrient
;
88 std::unique_ptr
<SwFormatVertOrient
> m_pVOrient
;
89 std::unique_ptr
<SwFormatAnchor
> m_pAnchor
;
90 std::unique_ptr
<SwFormatSurround
> m_pSurround
;
91 std::unique_ptr
<SvxULSpaceItem
> m_pULSpace
;
92 std::unique_ptr
<SvxLRSpaceItem
> m_pLRSpace
;
94 uno::Reference
< text::XTextRange
> m_xTextRange
;
96 std::unique_ptr
<SwFormatFollowTextFlow
> m_pFollowTextFlow
;
98 std::unique_ptr
<SwFormatWrapInfluenceOnObjPos
> m_pWrapInfluenceOnObjPos
;
100 sal_Int16 mnPositionLayoutDir
;
102 SwShapeDescriptor_Impl(const SwShapeDescriptor_Impl
&) = delete;
103 SwShapeDescriptor_Impl
& operator=(const SwShapeDescriptor_Impl
&) = delete;
106 bool m_bInitializedPropertyNotifier
;
109 SwShapeDescriptor_Impl(SwDoc
const*const pDoc
)
110 : m_isInReading(pDoc
&& pDoc
->IsInReading())
111 // #i32349# - no defaults, in order to determine on
112 // adding a shape, if positioning attributes are set or not.
115 , m_pFollowTextFlow( new SwFormatFollowTextFlow(false) )
117 , m_pWrapInfluenceOnObjPos( new SwFormatWrapInfluenceOnObjPos(
118 text::WrapInfluenceOnPosition::ONCE_CONCURRENT
) )
120 , mnPositionLayoutDir(text::PositionLayoutDir::PositionInLayoutDirOfAnchor
)
121 , m_bInitializedPropertyNotifier(false)
124 SwFormatAnchor
* GetAnchor(bool bCreate
= false)
126 if (bCreate
&& !m_pAnchor
)
128 m_pAnchor
.reset(new SwFormatAnchor(RndStdIds::FLY_AS_CHAR
));
130 return m_pAnchor
.get();
132 SwFormatHoriOrient
* GetHOrient(bool bCreate
= false)
134 if (bCreate
&& !m_pHOrient
)
137 m_pHOrient
.reset(new SwFormatHoriOrient(0, text::HoriOrientation::NONE
, text::RelOrientation::FRAME
));
139 return m_pHOrient
.get();
141 SwFormatVertOrient
* GetVOrient(bool bCreate
= false)
143 if (bCreate
&& !m_pVOrient
)
145 if (m_isInReading
&& // tdf#113938 extensions might rely on old default
146 (!GetAnchor(true) || m_pAnchor
->GetAnchorId() == RndStdIds::FLY_AS_CHAR
))
147 { // for as-char, NONE ("from-top") is not a good default
148 m_pVOrient
.reset(new SwFormatVertOrient(0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
));
152 m_pVOrient
.reset(new SwFormatVertOrient(0, text::VertOrientation::NONE
, text::RelOrientation::FRAME
));
155 return m_pVOrient
.get();
158 SwFormatSurround
* GetSurround(bool bCreate
= false)
160 if (bCreate
&& !m_pSurround
)
162 m_pSurround
.reset(new SwFormatSurround());
164 return m_pSurround
.get();
166 SvxLRSpaceItem
* GetLRSpace(bool bCreate
= false)
168 if (bCreate
&& !m_pLRSpace
)
170 m_pLRSpace
.reset(new SvxLRSpaceItem(RES_LR_SPACE
));
172 return m_pLRSpace
.get();
174 SvxULSpaceItem
* GetULSpace(bool bCreate
= false)
176 if (bCreate
&& !m_pULSpace
)
178 m_pULSpace
.reset(new SvxULSpaceItem(RES_UL_SPACE
));
180 return m_pULSpace
.get();
182 uno::Reference
< text::XTextRange
> & GetTextRange()
186 bool IsOpaque() const
190 const bool& GetOpaque() const
194 void RemoveHOrient() { m_pHOrient
.reset(); }
195 void RemoveVOrient() { m_pVOrient
.reset(); }
196 void RemoveAnchor() { m_pAnchor
.reset(); }
197 void RemoveSurround() { m_pSurround
.reset(); }
198 void RemoveULSpace() { m_pULSpace
.reset(); }
199 void RemoveLRSpace() { m_pLRSpace
.reset(); }
200 void SetOpaque(bool bSet
){m_bOpaque
= bSet
;}
203 SwFormatFollowTextFlow
* GetFollowTextFlow( bool _bCreate
= false )
205 if (_bCreate
&& !m_pFollowTextFlow
)
207 m_pFollowTextFlow
.reset(new SwFormatFollowTextFlow(false));
209 return m_pFollowTextFlow
.get();
211 void RemoveFollowTextFlow()
213 m_pFollowTextFlow
.reset();
217 sal_Int16
GetPositionLayoutDir() const
219 return mnPositionLayoutDir
;
221 void SetPositionLayoutDir( sal_Int16 _nPositionLayoutDir
)
223 switch ( _nPositionLayoutDir
)
225 case text::PositionLayoutDir::PositionInHoriL2R
:
226 case text::PositionLayoutDir::PositionInLayoutDirOfAnchor
:
228 mnPositionLayoutDir
= _nPositionLayoutDir
;
233 OSL_FAIL( "<SwShapeDescriptor_Impl::SetPositionLayoutDir(..)> - invalid attribute value." );
239 SwFormatWrapInfluenceOnObjPos
* GetWrapInfluenceOnObjPos(
240 const bool _bCreate
= false )
242 if (_bCreate
&& !m_pWrapInfluenceOnObjPos
)
244 m_pWrapInfluenceOnObjPos
.reset(new SwFormatWrapInfluenceOnObjPos(
246 text::WrapInfluenceOnPosition::ONCE_CONCURRENT
));
248 return m_pWrapInfluenceOnObjPos
.get();
250 void RemoveWrapInfluenceOnObjPos()
252 m_pWrapInfluenceOnObjPos
.reset();
256 SwFmDrawPage::SwFmDrawPage( SwDoc
* pDoc
, SdrPage
* pPage
)
257 : SwFmDrawPage_Base(pPage
)
259 , m_pPageView(nullptr)
260 , m_pPropertySet(aSwMapProvider
.GetPropertySet(PROPERTY_MAP_TEXT_PAGE
))
264 SwFmDrawPage::~SwFmDrawPage() noexcept
266 while (!m_vShapes
.empty())
267 m_vShapes
.back()->dispose();
271 const SdrMarkList
& SwFmDrawPage::PreGroup(const uno::Reference
< drawing::XShapes
> & xShapes
)
273 SelectObjectsInView( xShapes
, GetPageView() );
274 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
278 void SwFmDrawPage::PreUnGroup(const uno::Reference
< drawing::XShapeGroup
>& rShapeGroup
)
280 SelectObjectInView( rShapeGroup
, GetPageView() );
283 SdrPageView
* SwFmDrawPage::GetPageView()
286 m_pPageView
= mpView
->ShowSdrPage( mpPage
);
290 void SwFmDrawPage::RemovePageView()
292 if(m_pPageView
&& mpView
)
293 mpView
->HideSdrPage();
294 m_pPageView
= nullptr;
297 uno::Reference
<drawing::XShape
> SwFmDrawPage::GetShape(SdrObject
* pObj
)
301 SwFrameFormat
* pFormat
= ::FindFrameFormat( pObj
);
302 // TODO see comment at
303 // <https://gerrit.libreoffice.org/c/core/+/78734/4#message-5ee4e724a8073c5c475f07da0b5d79bc34e61de5>
304 // "make page bookkeep the SwXShapes" [-loplugin:crosscast]:
305 SwFmDrawPage
* pPage
= dynamic_cast<SwFmDrawPage
*>(pFormat
);
306 if(!pPage
|| pPage
->m_vShapes
.empty())
307 return uno::Reference
<drawing::XShape
>(pObj
->getUnoShape(), uno::UNO_QUERY
);
308 for(const auto & pShape
: pPage
->m_vShapes
)
310 SvxShape
* pSvxShape
= pShape
->GetSvxShape();
311 if (pSvxShape
&& pSvxShape
->GetSdrObject() == pObj
)
317 uno::Reference
<drawing::XShapeGroup
> SwFmDrawPage::GetShapeGroup(SdrObject
* pObj
)
319 return uno::Reference
<drawing::XShapeGroup
>(GetShape(pObj
), uno::UNO_QUERY
);
322 uno::Reference
< drawing::XShape
> SwFmDrawPage::CreateShape( SdrObject
*pObj
) const
324 uno::Reference
< drawing::XShape
> xRet
;
325 if(dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) != nullptr || pObj
->GetObjInventor() == SdrInventor::Swg
)
327 SwFlyDrawContact
* pFlyContact
= static_cast<SwFlyDrawContact
*>(pObj
->GetUserCall());
330 SwFrameFormat
* pFlyFormat
= pFlyContact
->GetFormat();
331 SwDoc
* pDoc
= pFlyFormat
->GetDoc();
332 const SwNodeIndex
* pIdx
;
333 if( RES_FLYFRMFMT
== pFlyFormat
->Which()
334 && nullptr != ( pIdx
= pFlyFormat
->GetContent().GetContentIdx() )
335 && pIdx
->GetNodes().IsDocNodes()
338 const SwNode
* pNd
= pDoc
->GetNodes()[ pIdx
->GetIndex() + 1 ];
339 if(!pNd
->IsNoTextNode())
341 xRet
.set(static_cast<cppu::OWeakObject
*>(SwXTextFrame::CreateXTextFrame(*pDoc
, pFlyFormat
).get()),
344 else if( pNd
->IsGrfNode() )
346 xRet
.set(static_cast<cppu::OWeakObject
*>(SwXTextGraphicObject::CreateXTextGraphicObject(
347 *pDoc
, pFlyFormat
).get()), uno::UNO_QUERY
);
349 else if( pNd
->IsOLENode() )
351 xRet
.set(static_cast<cppu::OWeakObject
*>(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
352 *pDoc
, pFlyFormat
).get()), uno::UNO_QUERY
);
357 OSL_FAIL( "<SwFmDrawPage::CreateShape(..)> - could not retrieve type. Thus, no shape created." );
364 // own block - temporary object has to be destroyed before
365 // the delegator is set #81670#
367 xRet
= SvxFmDrawPage::CreateShape( pObj
);
369 uno::Reference
< XUnoTunnel
> xShapeTunnel(xRet
, uno::UNO_QUERY
);
370 //don't create an SwXShape if it already exists
371 rtl::Reference
<SwXShape
> pShape
= comphelper::getFromUnoTunnel
<SwXShape
>(xShapeTunnel
);
374 xShapeTunnel
= nullptr;
375 uno::Reference
< uno::XInterface
> xCreate(xRet
, uno::UNO_QUERY
);
377 if ( pObj
->IsGroupObject() && (!pObj
->Is3DObj() || DynCastE3dScene(pObj
)) )
378 pShape
= new SwXGroupShape(xCreate
, nullptr);
380 pShape
= new SwXShape(xCreate
, nullptr);
383 const_cast<std::vector
<rtl::Reference
<SwXShape
>>*>(&m_vShapes
)->push_back(pShape
);
384 pShape
->m_pPage
= this;
389 uno::Reference
<beans::XPropertySetInfo
> SwFmDrawPage::getPropertySetInfo()
391 static uno::Reference
<beans::XPropertySetInfo
> xRet
= m_pPropertySet
->getPropertySetInfo();
395 void SwFmDrawPage::setPropertyValue(const OUString
& rPropertyName
, const uno::Any
& aValue
)
397 SolarMutexGuard aGuard
;
398 const SfxItemPropertyMapEntry
* pEntry
= m_pPropertySet
->getPropertyMap().getByName(rPropertyName
);
400 switch (pEntry
? pEntry
->nWID
: -1)
404 SdrPage
* pPage
= GetSdrPage();
405 css::uno::Reference
<css::util::XTheme
> xTheme
;
406 if (aValue
>>= xTheme
)
408 auto& rUnoTheme
= dynamic_cast<UnoTheme
&>(*xTheme
);
409 pPage
->getSdrPageProperties().SetTheme(rUnoTheme
.getTheme());
413 case WID_PAGE_BOTTOM
:
418 case WID_PAGE_HEIGHT
:
419 case WID_PAGE_NUMBER
:
420 case WID_PAGE_ORIENT
:
421 case WID_PAGE_USERATTRIBS
:
422 case WID_PAGE_ISDARK
:
424 case WID_PAGE_BACKFULL
:
428 throw beans::UnknownPropertyException(rPropertyName
, static_cast<cppu::OWeakObject
*>(this));
432 uno::Any
SwFmDrawPage::getPropertyValue(const OUString
& rPropertyName
)
434 SolarMutexGuard aGuard
;
435 const SfxItemPropertyMapEntry
* pEntry
= m_pPropertySet
->getPropertyMap().getByName( rPropertyName
);
439 switch (pEntry
? pEntry
->nWID
: -1)
443 css::uno::Reference
<css::util::XTheme
> xTheme
;
445 auto pTheme
= GetSdrPage()->getSdrPageProperties().GetTheme();
447 xTheme
= model::theme::createXTheme(pTheme
);
452 case WID_PAGE_NUMBER
:
454 const sal_uInt16
nPageNumber(GetSdrPage()->GetPageNum());
455 aAny
<<= o3tl::narrowing
<sal_Int16
>(nPageNumber
);
459 case WID_PAGE_BOTTOM
:
464 case WID_PAGE_HEIGHT
:
465 case WID_PAGE_ORIENT
:
466 case WID_PAGE_USERATTRIBS
:
467 case WID_PAGE_ISDARK
:
469 case WID_PAGE_BACKFULL
:
473 throw beans::UnknownPropertyException(rPropertyName
, static_cast<cppu::OWeakObject
*>(this));
478 void SwFmDrawPage::addPropertyChangeListener(const OUString
& /*PropertyName*/,
479 const uno::Reference
<beans::XPropertyChangeListener
> & /*aListener*/)
481 OSL_FAIL("not implemented");
484 void SwFmDrawPage::removePropertyChangeListener(const OUString
& /*PropertyName*/,
485 const uno::Reference
<beans::XPropertyChangeListener
> & /*aListener*/)
487 OSL_FAIL("not implemented");
490 void SwFmDrawPage::addVetoableChangeListener(const OUString
& /*PropertyName*/,
491 const uno::Reference
<beans::XVetoableChangeListener
> & /*aListener*/)
493 OSL_FAIL("not implemented");
496 void SwFmDrawPage::removeVetoableChangeListener(const OUString
& /*PropertyName*/,
497 const uno::Reference
<beans::XVetoableChangeListener
> & /*aListener*/)
499 OSL_FAIL("not implemented");
504 class SwXShapesEnumeration
505 : public SwSimpleEnumeration_Base
508 std::vector
< css::uno::Any
> m_aShapes
;
510 virtual ~SwXShapesEnumeration() override
{};
512 explicit SwXShapesEnumeration(SwFmDrawPage
* const pDrawPage
);
515 virtual sal_Bool SAL_CALL
hasMoreElements() override
;
516 virtual uno::Any SAL_CALL
nextElement() override
;
519 virtual OUString SAL_CALL
getImplementationName() override
;
520 virtual sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
521 virtual uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
;
525 SwXShapesEnumeration::SwXShapesEnumeration(SwFmDrawPage
* const pDrawPage
)
527 SolarMutexGuard aGuard
;
528 sal_Int32 nCount
= pDrawPage
->getCount();
529 m_aShapes
.reserve(nCount
);
530 for(sal_Int32 nIdx
= 0; nIdx
< nCount
; nIdx
++)
532 uno::Reference
<drawing::XShape
> xShape(pDrawPage
->getByIndex(nIdx
), uno::UNO_QUERY
);
533 m_aShapes
.push_back(uno::Any(xShape
));
537 sal_Bool
SwXShapesEnumeration::hasMoreElements()
539 SolarMutexGuard aGuard
;
540 return !m_aShapes
.empty();
543 uno::Any
SwXShapesEnumeration::nextElement()
545 SolarMutexGuard aGuard
;
546 if(m_aShapes
.empty())
547 throw container::NoSuchElementException();
548 uno::Any aResult
= m_aShapes
.back();
549 m_aShapes
.pop_back();
553 OUString
SwXShapesEnumeration::getImplementationName()
555 return "SwXShapeEnumeration";
558 sal_Bool
SwXShapesEnumeration::supportsService(const OUString
& ServiceName
)
560 return cppu::supportsService(this, ServiceName
);
563 uno::Sequence
< OUString
> SwXShapesEnumeration::getSupportedServiceNames()
565 return { OUString("com.sun.star.container.XEnumeration") };
568 uno::Reference
< container::XEnumeration
> SwFmDrawPage::createEnumeration()
570 SolarMutexGuard aGuard
;
571 return uno::Reference
< container::XEnumeration
>(
572 new SwXShapesEnumeration(this));
575 OUString
SwFmDrawPage::getImplementationName()
577 return "SwFmDrawPage";
580 sal_Bool
SwFmDrawPage::supportsService(const OUString
& rServiceName
)
582 return cppu::supportsService(this, rServiceName
);
585 uno::Sequence
< OUString
> SwFmDrawPage::getSupportedServiceNames()
587 return { "com.sun.star.drawing.GenericDrawPage" };
590 sal_Int32
SwFmDrawPage::getCount()
592 SolarMutexGuard aGuard
;
594 throw uno::RuntimeException();
595 if(!m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
598 return SwTextBoxHelper::getCount(GetSdrPage());
601 uno::Any
SwFmDrawPage::getByIndex(sal_Int32 nIndex
)
603 SolarMutexGuard aGuard
;
605 throw uno::RuntimeException();
606 if(!m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
607 throw lang::IndexOutOfBoundsException();
609 return SwTextBoxHelper::getByIndex(GetSdrPage(), nIndex
);
612 uno::Type
SwFmDrawPage::getElementType()
614 return cppu::UnoType
<drawing::XShape
>::get();
617 sal_Bool
SwFmDrawPage::hasElements()
619 SolarMutexGuard aGuard
;
621 throw uno::RuntimeException();
622 if(!m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
624 return SvxFmDrawPage::hasElements();
627 void SwFmDrawPage::add(const uno::Reference
< drawing::XShape
> & xShape
)
629 SolarMutexGuard aGuard
;
631 throw uno::RuntimeException();
632 uno::Reference
< lang::XUnoTunnel
> xShapeTunnel(xShape
, uno::UNO_QUERY
);
633 SwXShape
* pShape
= comphelper::getFromUnoTunnel
<SwXShape
>(xShapeTunnel
);
634 SvxShape
* pSvxShape
= comphelper::getFromUnoTunnel
<SvxShape
>(xShapeTunnel
);
636 // this is not a writer shape
638 throw uno::RuntimeException("illegal object",
639 static_cast< cppu::OWeakObject
* > ( this ) );
641 // we're already registered in the model / SwXDrawPage::add() already called
642 if(pShape
->m_pPage
|| !pShape
->m_bDescriptor
)
645 // we're inserted elsewhere already
646 if ( pSvxShape
->GetSdrObject() )
648 if ( pSvxShape
->GetSdrObject()->IsInserted() )
653 SvxFmDrawPage::add(xShape
);
655 OSL_ENSURE(pSvxShape
, "Why is here no SvxShape?");
656 // this position is definitely in 1/100 mm
657 awt::Point
aMM100Pos(pSvxShape
->getPosition());
659 // now evaluate the properties of SwShapeDescriptor_Impl
660 SwShapeDescriptor_Impl
* pDesc
= pShape
->GetDescImpl();
662 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1> aSet( m_pDoc
->GetAttrPool() );
663 SwFormatAnchor
aAnchor( RndStdIds::FLY_AS_CHAR
);
664 bool bOpaque
= false;
667 if(pDesc
->GetSurround())
668 aSet
.Put( *pDesc
->GetSurround());
669 // all items are already in Twip
670 if(pDesc
->GetLRSpace())
672 aSet
.Put(*pDesc
->GetLRSpace());
674 if(pDesc
->GetULSpace())
676 aSet
.Put(*pDesc
->GetULSpace());
678 if(pDesc
->GetAnchor())
679 aAnchor
= *pDesc
->GetAnchor();
681 // #i32349# - if no horizontal position exists, create one
682 if ( !pDesc
->GetHOrient() )
684 SwFormatHoriOrient
* pHori
= pDesc
->GetHOrient( true );
685 SwTwips nHoriPos
= o3tl::toTwips(aMM100Pos
.X
, o3tl::Length::mm100
);
686 pHori
->SetPos( nHoriPos
);
689 if(pDesc
->GetHOrient()->GetHoriOrient() == text::HoriOrientation::NONE
)
690 aMM100Pos
.X
= convertTwipToMm100(pDesc
->GetHOrient()->GetPos());
691 aSet
.Put( *pDesc
->GetHOrient() );
693 // #i32349# - if no vertical position exists, create one
694 if ( !pDesc
->GetVOrient() )
696 SwFormatVertOrient
* pVert
= pDesc
->GetVOrient( true );
697 SwTwips nVertPos
= o3tl::toTwips(aMM100Pos
.Y
, o3tl::Length::mm100
);
698 pVert
->SetPos( nVertPos
);
701 if(pDesc
->GetVOrient()->GetVertOrient() == text::VertOrientation::NONE
)
702 aMM100Pos
.Y
= convertTwipToMm100(pDesc
->GetVOrient()->GetPos());
703 aSet
.Put( *pDesc
->GetVOrient() );
706 if(pDesc
->GetSurround())
707 aSet
.Put( *pDesc
->GetSurround());
708 bOpaque
= pDesc
->IsOpaque();
711 if ( pDesc
->GetFollowTextFlow() )
713 aSet
.Put( *pDesc
->GetFollowTextFlow() );
717 if ( pDesc
->GetWrapInfluenceOnObjPos() )
719 aSet
.Put( *pDesc
->GetWrapInfluenceOnObjPos() );
723 pSvxShape
->setPosition(aMM100Pos
);
724 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
725 // #108784# - set layer of new drawing object to corresponding
727 if(SdrInventor::FmForm
!= pObj
->GetObjInventor())
728 pObj
->SetLayer( bOpaque
? m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleHeavenId() : m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId() );
730 pObj
->SetLayer(m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleControlsId());
732 std::optional
<SwPaM
> pPam(m_pDoc
->GetNodes().GetEndOfContent());
733 std::unique_ptr
<SwUnoInternalPaM
> pInternalPam
;
734 uno::Reference
< text::XTextRange
> xRg
;
735 if( pDesc
&& (xRg
= pDesc
->GetTextRange()).is() )
737 pInternalPam
.reset(new SwUnoInternalPaM(*m_pDoc
));
738 if (!::sw::XTextRangeToSwPaM(*pInternalPam
, xRg
))
739 throw uno::RuntimeException();
741 if(RndStdIds::FLY_AT_FLY
== aAnchor
.GetAnchorId() &&
742 !pInternalPam
->GetPointNode().FindFlyStartNode())
744 aAnchor
.SetType(RndStdIds::FLY_AS_CHAR
);
746 else if (RndStdIds::FLY_AT_PAGE
== aAnchor
.GetAnchorId()
747 && 0 == aAnchor
.GetPageNum())
749 aAnchor
.SetAnchor(pInternalPam
->Start());
750 aAnchor
.SetType(RndStdIds::FLY_AT_CHAR
); // convert invalid at-page
754 else if ((aAnchor
.GetAnchorId() != RndStdIds::FLY_AT_PAGE
) && m_pDoc
->getIDocumentLayoutAccess().GetCurrentLayout())
756 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
757 Point
aTmp(o3tl::toTwips(aMM100Pos
.X
, o3tl::Length::mm100
), o3tl::toTwips(aMM100Pos
.Y
, o3tl::Length::mm100
));
758 m_pDoc
->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( pPam
->GetPoint(), aTmp
, &aState
);
759 aAnchor
.SetAnchor( pPam
->GetPoint() );
761 // #i32349# - adjustment of vertical positioning
762 // attributes no longer needed, because it's already got a default.
766 aAnchor
.SetType(RndStdIds::FLY_AT_PAGE
);
768 // #i32349# - adjustment of vertical positioning
769 // attributes no longer needed, because it's already got a default.
772 SwPaM
* pTemp
= pInternalPam
.get();
775 UnoActionContext
aAction(m_pDoc
);
776 m_pDoc
->getIDocumentContentOperations().InsertDrawObj( *pTemp
, *pObj
, aSet
);
778 if (pSvxShape
->GetSdrObject()->GetName().isEmpty())
780 pSvxShape
->GetSdrObject()->SetName(m_pDoc
->GetUniqueShapeName());
783 SwFrameFormat
* pFormat
= ::FindFrameFormat( pObj
);
786 if (pFormat
->GetName().isEmpty())
788 pFormat
->SetFormatName(pSvxShape
->GetSdrObject()->GetName(), false);
791 pShape
->m_bDescriptor
= false;
794 pInternalPam
.reset();
797 void SwFmDrawPage::remove(const uno::Reference
< drawing::XShape
> & xShape
)
799 SolarMutexGuard aGuard
;
801 throw uno::RuntimeException();
802 // tdf#41466 remove TextFrame too which is belonged to the actual shape
803 auto xTextFrame
= SwTextBoxHelper::getUnoTextFrame(xShape
);
806 uno::Reference
<lang::XComponent
> xComp(xTextFrame
, uno::UNO_QUERY
);
811 uno::Reference
<lang::XComponent
> xComp(xShape
, uno::UNO_QUERY
);
815 uno::Reference
< drawing::XShapeGroup
> SwFmDrawPage::group(const uno::Reference
< drawing::XShapes
> & xShapes
)
817 SolarMutexGuard aGuard
;
818 if(!m_pDoc
|| !xShapes
.is())
819 throw uno::RuntimeException();
820 uno::Reference
< drawing::XShapeGroup
> xRet
;
821 // mark and return MarkList
822 const SdrMarkList
& rMarkList
= PreGroup(xShapes
);
823 if ( rMarkList
.GetMarkCount() > 0 )
825 for (size_t i
= 0; i
< rMarkList
.GetMarkCount(); ++i
)
827 const SdrObject
*pObj
= rMarkList
.GetMark( i
)->GetMarkedSdrObj();
828 if (RndStdIds::FLY_AS_CHAR
== ::FindFrameFormat(const_cast<SdrObject
*>(
829 pObj
))->GetAnchor().GetAnchorId())
831 throw lang::IllegalArgumentException(
832 "Shape must not have 'as character' anchor!", nullptr, 0);
836 UnoActionContext
aContext(m_pDoc
);
837 m_pDoc
->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
839 SwDrawContact
* pContact
= m_pDoc
->GroupSelection( *GetDrawView() );
841 GetDrawView()->GetMarkedObjectList(),
842 RndStdIds::FLY_AT_PARA
,
845 GetDrawView()->UnmarkAll();
847 xRet
= SwFmDrawPage::GetShapeGroup( pContact
->GetMaster() );
848 m_pDoc
->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
854 void SwFmDrawPage::ungroup(const uno::Reference
< drawing::XShapeGroup
> & rShapeGroup
)
856 SolarMutexGuard aGuard
;
858 throw uno::RuntimeException();
860 PreUnGroup(rShapeGroup
);
861 UnoActionContext
aContext(m_pDoc
);
862 m_pDoc
->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
864 m_pDoc
->UnGroupSelection( *GetDrawView() );
865 m_pDoc
->ChgAnchor( GetDrawView()->GetMarkedObjectList(),
866 RndStdIds::FLY_AT_PARA
,
868 m_pDoc
->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
873 * Renamed and outlined to detect where it's called
875 void SwFmDrawPage::InvalidateSwDoc()
880 const uno::Sequence
< sal_Int8
> & SwXShape::getUnoTunnelId()
882 static const comphelper::UnoIdInit theSwXShapeUnoTunnelId
;
883 return theSwXShapeUnoTunnelId
.getSeq();
886 sal_Int64 SAL_CALL
SwXShape::getSomething( const uno::Sequence
< sal_Int8
>& rId
)
888 if( comphelper::isUnoTunnelId
<SwXShape
>(rId
) )
890 return comphelper::getSomething_cast(this);
893 if( m_xShapeAgg
.is() )
895 const uno::Type
& rTunnelType
= cppu::UnoType
<lang::XUnoTunnel
>::get();
896 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rTunnelType
);
897 if(auto xAggTunnel
= o3tl::tryAccess
<uno::Reference
<lang::XUnoTunnel
>>(
901 return (*xAggTunnel
)->getSomething(rId
);
908 void lcl_addShapePropertyEventFactories( SdrObject
& _rObj
, SwXShape
& _rShape
)
910 auto pProvider
= std::make_unique
<svx::PropertyValueProvider
>( _rShape
, "AnchorType" );
911 _rObj
.registerProvider( svx::ShapePropertyProviderId::TextDocAnchor
, std::move(pProvider
) );
916 uno::Reference
<uno::XInterface
> & xShape
,
917 SwDoc
const*const pDoc
)
919 , m_pPropSet(aSwMapProvider
.GetPropertySet(PROPERTY_MAP_TEXT_SHAPE
))
920 , m_pPropertyMapEntries(aSwMapProvider
.GetPropertyMapEntries(PROPERTY_MAP_TEXT_SHAPE
))
921 , m_pImpl(new SwShapeDescriptor_Impl(pDoc
))
922 , m_bDescriptor(true)
924 if(!xShape
.is()) // default Ctor
927 const uno::Type
& rAggType
= cppu::UnoType
<uno::XAggregation
>::get();
928 //aAgg contains a reference of the SvxShape!
930 uno::Any aAgg
= xShape
->queryInterface(rAggType
);
931 aAgg
>>= m_xShapeAgg
;
933 if ( m_xShapeAgg
.is() )
935 m_xShapeAgg
->queryAggregation( cppu::UnoType
<drawing::XShape
>::get()) >>= mxShape
;
936 OSL_ENSURE( mxShape
.is(),
937 "<SwXShape::SwXShape(..)> - no XShape found at <xShapeAgg>" );
941 osl_atomic_increment(&m_refCount
);
942 if( m_xShapeAgg
.is() )
943 m_xShapeAgg
->setDelegator( static_cast<cppu::OWeakObject
*>(this) );
944 osl_atomic_decrement(&m_refCount
);
946 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(m_xShapeAgg
);
949 lcl_addShapePropertyEventFactories( *pObj
, *this );
950 m_pImpl
->m_bInitializedPropertyNotifier
= true;
955 SwFrameFormat
* SwXShape::GetFrameFormat() const
957 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(m_xShapeAgg
);
959 return ::FindFrameFormat( pObj
);
963 void SwXShape::AddExistingShapeToFormat( SdrObject
const & _rObj
)
965 SdrObjListIter
aIter( _rObj
, SdrIterMode::DeepNoGroups
);
966 while ( aIter
.IsMore() )
968 SdrObject
* pCurrent
= aIter
.Next();
969 OSL_ENSURE( pCurrent
, "SwXShape::AddExistingShapeToFormat: invalid object list element!" );
973 auto pSwShape
= comphelper::getFromUnoTunnel
<SwXShape
>(pCurrent
->getWeakUnoShape());
976 if ( pSwShape
->m_bDescriptor
)
977 pSwShape
->m_bDescriptor
= false;
979 if ( !pSwShape
->m_pImpl
->m_bInitializedPropertyNotifier
)
981 lcl_addShapePropertyEventFactories( *pCurrent
, *pSwShape
);
982 pSwShape
->m_pImpl
->m_bInitializedPropertyNotifier
= true;
988 SwXShape::~SwXShape()
990 SolarMutexGuard aGuard
;
992 if (m_xShapeAgg
.is())
994 uno::Reference
< uno::XInterface
> xRef
;
995 m_xShapeAgg
->setDelegator(xRef
);
999 const_cast<SwFmDrawPage
*>(m_pPage
)->RemoveShape(this);
1002 uno::Any
SwXShape::queryInterface( const uno::Type
& aType
)
1005 SdrObject
* pObj
= nullptr;
1007 if ((aType
== cppu::UnoType
<text::XText
>::get())
1008 || (aType
== cppu::UnoType
<text::XTextRange
>::get())
1009 || (aType
== cppu::UnoType
<text::XTextAppend
>::get()))
1011 pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1013 aRet
= SwTextBoxHelper::queryInterface(GetFrameFormat(), aType
, pObj
);
1014 if (aRet
.hasValue())
1017 aRet
= SwXShapeBaseClass::queryInterface(aType
);
1018 // #i53320# - follow-up of #i31698#
1019 // interface drawing::XShape is overloaded. Thus, provide
1020 // correct object instance.
1021 if(!aRet
.hasValue() && m_xShapeAgg
.is())
1023 if(aType
== cppu::UnoType
<XShape
>::get())
1024 aRet
<<= uno::Reference
<XShape
>(this);
1026 aRet
= m_xShapeAgg
->queryAggregation(aType
);
1031 uno::Sequence
< uno::Type
> SwXShape::getTypes( )
1033 uno::Sequence
< uno::Type
> aRet
= SwXShapeBaseClass::getTypes();
1034 if(m_xShapeAgg
.is())
1036 uno::Any aProv
= m_xShapeAgg
->queryAggregation(cppu::UnoType
<XTypeProvider
>::get());
1037 if(aProv
.hasValue())
1039 uno::Reference
< XTypeProvider
> xAggProv
;
1041 return comphelper::concatSequences(aRet
, xAggProv
->getTypes());
1047 uno::Sequence
< sal_Int8
> SwXShape::getImplementationId( )
1049 return css::uno::Sequence
<sal_Int8
>();
1052 uno::Reference
< beans::XPropertySetInfo
> SwXShape::getPropertySetInfo()
1054 SolarMutexGuard aGuard
;
1055 if (!mxPropertySetInfo
)
1057 if(m_xShapeAgg
.is())
1059 const uno::Type
& rPropSetType
= cppu::UnoType
<beans::XPropertySet
>::get();
1060 uno::Any aPSet
= m_xShapeAgg
->queryAggregation( rPropSetType
);
1061 if(auto xPrSet
= o3tl::tryAccess
<uno::Reference
<beans::XPropertySet
>>(
1064 uno::Reference
< beans::XPropertySetInfo
> xInfo
= (*xPrSet
)->getPropertySetInfo();
1065 // Expand PropertySetInfo!
1066 const uno::Sequence
<beans::Property
> aPropSeq
= xInfo
->getProperties();
1067 mxPropertySetInfo
= new SfxExtItemPropertySetInfo( m_pPropertyMapEntries
, aPropSeq
);
1070 if(!mxPropertySetInfo
)
1071 mxPropertySetInfo
= m_pPropSet
->getPropertySetInfo();
1073 return mxPropertySetInfo
;
1076 void SwXShape::setPropertyValue(const OUString
& rPropertyName
, const uno::Any
& aValue
)
1078 SolarMutexGuard aGuard
;
1079 SwFrameFormat
* pFormat
= GetFrameFormat();
1080 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
1081 if(!m_xShapeAgg
.is())
1086 if ( pEntry
->nFlags
& beans::PropertyAttribute::READONLY
)
1087 throw beans::PropertyVetoException ("Property is read-only: " + rPropertyName
, static_cast < cppu::OWeakObject
* > ( this ) );
1088 // with the layout it is possible to move the anchor without changing the position
1091 SwAttrSet
aSet(pFormat
->GetAttrSet());
1092 SwDoc
* pDoc
= pFormat
->GetDoc();
1093 if(RES_ANCHOR
== pEntry
->nWID
&& MID_ANCHOR_ANCHORFRAME
== pEntry
->nMemberId
)
1096 uno::Reference
<text::XTextFrame
> xFrame
;
1097 if(aValue
>>= xFrame
)
1099 SwXFrame
* pFrame
= dynamic_cast<SwXFrame
*>(xFrame
.get());
1100 if(pFrame
&& pFrame
->GetFrameFormat() &&
1101 pFrame
->GetFrameFormat()->GetDoc() == pDoc
)
1103 UnoActionContext
aCtx(pDoc
);
1104 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
- 1> aItemSet( pDoc
->GetAttrPool() );
1105 aItemSet
.SetParent(&pFormat
->GetAttrSet());
1106 SwFormatAnchor aAnchor
= static_cast<const SwFormatAnchor
&>(aItemSet
.Get(pEntry
->nWID
));
1107 SwPosition
aPos(*pFrame
->GetFrameFormat()->GetContent().GetContentIdx());
1108 aAnchor
.SetAnchor(&aPos
);
1109 aAnchor
.SetType(RndStdIds::FLY_AT_FLY
);
1110 aItemSet
.Put(aAnchor
);
1111 pFormat
->SetFormatAttr(aItemSet
);
1116 throw lang::IllegalArgumentException();
1118 else if(RES_OPAQUE
== pEntry
->nWID
)
1120 SvxShape
* pSvxShape
= GetSvxShape();
1121 SAL_WARN_IF(!pSvxShape
, "sw.uno", "No SvxShape found!");
1124 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1125 // set layer of new drawing
1126 // object to corresponding invisible layer.
1127 bool bIsVisible
= pDoc
->getIDocumentDrawModelAccess().IsVisibleLayerId( pObj
->GetLayer() );
1128 if(SdrInventor::FmForm
!= pObj
->GetObjInventor())
1130 pObj
->SetLayer( *o3tl::doAccess
<bool>(aValue
)
1131 ? ( bIsVisible
? pDoc
->getIDocumentDrawModelAccess().GetHeavenId() : pDoc
->getIDocumentDrawModelAccess().GetInvisibleHeavenId() )
1132 : ( bIsVisible
? pDoc
->getIDocumentDrawModelAccess().GetHellId() : pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId() ));
1136 pObj
->SetLayer( bIsVisible
? pDoc
->getIDocumentDrawModelAccess().GetControlsId() : pDoc
->getIDocumentDrawModelAccess().GetInvisibleControlsId());
1142 // #i26791# - special handling for property FN_TEXT_RANGE
1143 else if ( FN_TEXT_RANGE
== pEntry
->nWID
)
1145 SwFormatAnchor
aAnchor( aSet
.Get( RES_ANCHOR
) );
1146 if (aAnchor
.GetAnchorId() == RndStdIds::FLY_AT_PAGE
)
1148 // set property <TextRange> not valid for to-page anchored shapes
1149 throw lang::IllegalArgumentException();
1152 std::unique_ptr
<SwUnoInternalPaM
> pInternalPam(
1153 new SwUnoInternalPaM( *(pFormat
->GetDoc()) ));
1154 uno::Reference
< text::XTextRange
> xRg
;
1156 if (!::sw::XTextRangeToSwPaM(*pInternalPam
, xRg
) )
1158 throw uno::RuntimeException();
1161 if (aAnchor
.GetAnchorId() == RndStdIds::FLY_AS_CHAR
)
1163 //delete old SwFormatFlyCnt
1164 //With AnchorAsCharacter the current TextAttribute has to be deleted.
1165 //Tbis removes the frame format too.
1166 //To prevent this the connection between format and attribute has to be broken before.
1167 SwTextNode
*pTextNode
= aAnchor
.GetAnchorNode()->GetTextNode();
1168 SAL_WARN_IF( !pTextNode
->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
1169 const sal_Int32 nIdx
= aAnchor
.GetAnchorContentOffset();
1170 SwTextAttr
* const pHint
=
1171 pTextNode
->GetTextAttrForCharAt(
1172 nIdx
, RES_TXTATR_FLYCNT
);
1173 assert(pHint
&& "Missing Hint.");
1174 SAL_WARN_IF( pHint
->Which() != RES_TXTATR_FLYCNT
,
1175 "sw.uno", "Missing FlyInCnt-Hint." );
1176 SAL_WARN_IF( pHint
->GetFlyCnt().GetFrameFormat() != pFormat
,
1177 "sw.uno", "Wrong TextFlyCnt-Hint." );
1178 const_cast<SwFormatFlyCnt
&>(pHint
->GetFlyCnt())
1181 //The connection is removed now the attribute can be deleted.
1182 pTextNode
->DeleteAttributes( RES_TXTATR_FLYCNT
, nIdx
);
1184 SwTextNode
*pNd
= pInternalPam
->GetPointNode().GetTextNode();
1185 SAL_WARN_IF( !pNd
, "sw.uno", "Cursor not at TextNode." );
1186 SwFormatFlyCnt
aFormat( pFormat
);
1187 pNd
->InsertItem(aFormat
, pInternalPam
->GetPoint()
1188 ->GetContentIndex(), 0 );
1189 //Refetch in case SwTextNode::InsertItem causes it to be deleted
1190 pFormat
= GetFrameFormat();
1194 aAnchor
.SetAnchor( pInternalPam
->GetPoint() );
1196 pFormat
->SetFormatAttr(aSet
);
1199 else if (pEntry
->nWID
== FN_TEXT_BOX
)
1201 auto pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1202 if (pEntry
->nMemberId
== MID_TEXT_BOX
)
1208 SwTextBoxHelper::create(pFormat
, pObj
);
1210 SwTextBoxHelper::destroy(pFormat
, pObj
);
1212 else if (pEntry
->nMemberId
== MID_TEXT_BOX_CONTENT
)
1214 if (aValue
.getValueType()
1215 == cppu::UnoType
<uno::Reference
<text::XTextFrame
>>::get())
1216 SwTextBoxHelper::set(pFormat
, pObj
,
1217 aValue
.get
<uno::Reference
<text::XTextFrame
>>());
1219 SAL_WARN( "sw.uno", "This is not a TextFrame!" );
1222 else if (pEntry
->nWID
== RES_CHAIN
)
1224 if (pEntry
->nMemberId
== MID_CHAIN_NEXTNAME
|| pEntry
->nMemberId
== MID_CHAIN_PREVNAME
)
1225 SwTextBoxHelper::syncProperty(pFormat
, pEntry
->nWID
, pEntry
->nMemberId
, aValue
,
1226 SdrObject::getSdrObjectFromXShape(mxShape
));
1229 else if ( FN_SHAPE_POSITION_LAYOUT_DIR
== pEntry
->nWID
)
1231 sal_Int16 nPositionLayoutDir
= 0;
1232 aValue
>>= nPositionLayoutDir
;
1233 pFormat
->SetPositionLayoutDir( nPositionLayoutDir
);
1235 else if( pDoc
->getIDocumentLayoutAccess().GetCurrentLayout())
1237 UnoActionContext
aCtx(pDoc
);
1238 if(RES_ANCHOR
== pEntry
->nWID
&& MID_ANCHOR_ANCHORTYPE
== pEntry
->nMemberId
)
1240 SdrObject
* pObj
= pFormat
->FindSdrObject();
1242 SdrMark
aMark(pObj
);
1243 aList
.InsertEntry(aMark
);
1244 sal_Int32 nAnchor
= 0;
1245 cppu::enum2int( nAnchor
, aValue
);
1246 pDoc
->ChgAnchor( aList
, static_cast<RndStdIds
>(nAnchor
),
1251 m_pPropSet
->setPropertyValue(*pEntry
, aValue
, aSet
);
1252 pFormat
->SetFormatAttr(aSet
);
1255 else if( RES_FRM_SIZE
== pEntry
->nWID
&&
1256 ( pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT
|| pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH
1257 || pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT_RELATION
1258 || pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH_RELATION
) )
1260 SvxShape
* pSvxShape
= GetSvxShape();
1261 SAL_WARN_IF(!pSvxShape
, "sw.uno", "No SvxShape found!");
1264 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1265 sal_Int16
nPercent(100);
1266 aValue
>>= nPercent
;
1267 switch (pEntry
->nMemberId
)
1269 case MID_FRMSIZE_REL_WIDTH
:
1270 pObj
->SetRelativeWidth( nPercent
/ 100.0 );
1272 case MID_FRMSIZE_REL_HEIGHT
:
1273 pObj
->SetRelativeHeight( nPercent
/ 100.0 );
1275 case MID_FRMSIZE_REL_WIDTH_RELATION
:
1276 pObj
->SetRelativeWidthRelation(nPercent
);
1278 case MID_FRMSIZE_REL_HEIGHT_RELATION
:
1279 pObj
->SetRelativeHeightRelation(nPercent
);
1284 else if (pEntry
->nWID
== RES_HORI_ORIENT
1285 && pEntry
->nMemberId
== MID_HORIORIENT_RELATION
1286 && aSet
.Get(RES_ANCHOR
).GetAnchorId() == RndStdIds::FLY_AT_PAGE
)
1288 uno::Any
value(aValue
);
1289 sal_Int16
nRelOrient(text::RelOrientation::PAGE_FRAME
);
1290 aValue
>>= nRelOrient
;
1291 if (sw::GetAtPageRelOrientation(nRelOrient
, true))
1293 SAL_WARN("sw.core", "SwXShape: fixing invalid horizontal RelOrientation for at-page anchor");
1294 value
<<= nRelOrient
;
1296 m_pPropSet
->setPropertyValue( *pEntry
, value
, aSet
);
1297 pFormat
->SetFormatAttr(aSet
);
1301 m_pPropSet
->setPropertyValue( *pEntry
, aValue
, aSet
);
1303 if(RES_ANCHOR
== pEntry
->nWID
&& MID_ANCHOR_ANCHORTYPE
== pEntry
->nMemberId
)
1305 bool bSetAttr
= true;
1306 text::TextContentAnchorType eNewAnchor
= static_cast<text::TextContentAnchorType
>(SWUnoHelper::GetEnumAsInt32( aValue
));
1308 //if old anchor was in_cntnt the related text attribute has to be removed
1309 const SwFormatAnchor
& rOldAnchor
= pFormat
->GetAnchor();
1310 RndStdIds eOldAnchorId
= rOldAnchor
.GetAnchorId();
1311 SdrObject
* pObj
= pFormat
->FindSdrObject();
1312 SwFrameFormat
*pFlyFormat
= FindFrameFormat( pObj
);
1313 pFlyFormat
->DelFrames();
1314 if( text::TextContentAnchorType_AS_CHARACTER
!= eNewAnchor
&&
1315 (RndStdIds::FLY_AS_CHAR
== eOldAnchorId
))
1317 //With AnchorAsCharacter the current TextAttribute has to be deleted.
1318 //Tbis removes the frame format too.
1319 //To prevent this the connection between format and attribute has to be broken before.
1320 SwTextNode
*pTextNode
= rOldAnchor
.GetAnchorNode()->GetTextNode();
1321 SAL_WARN_IF( !pTextNode
->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
1322 const sal_Int32 nIdx
= rOldAnchor
.GetAnchorContentOffset();
1323 SwTextAttr
* const pHint
=
1324 pTextNode
->GetTextAttrForCharAt(
1325 nIdx
, RES_TXTATR_FLYCNT
);
1326 assert(pHint
&& "Missing Hint.");
1327 SAL_WARN_IF( pHint
->Which() != RES_TXTATR_FLYCNT
,
1328 "sw.uno", "Missing FlyInCnt-Hint." );
1329 SAL_WARN_IF( pHint
->GetFlyCnt().GetFrameFormat() != pFlyFormat
,
1330 "sw.uno", "Wrong TextFlyCnt-Hint." );
1331 const_cast<SwFormatFlyCnt
&>(pHint
->GetFlyCnt())
1334 //The connection is removed now the attribute can be deleted.
1335 pTextNode
->DeleteAttributes(RES_TXTATR_FLYCNT
, nIdx
);
1337 else if( text::TextContentAnchorType_AT_PAGE
!= eNewAnchor
&&
1338 (RndStdIds::FLY_AT_PAGE
== eOldAnchorId
))
1340 SwFormatAnchor
aNewAnchor( aSet
.Get( RES_ANCHOR
) );
1341 //if the fly has been anchored at page then it needs to be connected
1342 //to the content position
1343 SwPaM
aPam(pDoc
->GetNodes().GetEndOfContent());
1344 if( pDoc
->getIDocumentLayoutAccess().GetCurrentLayout() )
1346 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
1347 Point
aTmp( pObj
->GetSnapRect().TopLeft() );
1348 pDoc
->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam
.GetPoint(), aTmp
, &aState
);
1352 //without access to the layout the last node of the body will be used as anchor position
1353 aPam
.Move( fnMoveBackward
, GoInDoc
);
1355 //anchor position has to be inserted after the text attribute has been inserted
1356 aNewAnchor
.SetAnchor( aPam
.GetPoint() );
1357 aSet
.Put( aNewAnchor
);
1358 pFormat
->SetFormatAttr(aSet
);
1361 if( text::TextContentAnchorType_AS_CHARACTER
== eNewAnchor
&&
1362 (RndStdIds::FLY_AS_CHAR
!= eOldAnchorId
))
1364 SwPaM
aPam(pDoc
->GetNodes().GetEndOfContent());
1365 if( pDoc
->getIDocumentLayoutAccess().GetCurrentLayout() )
1367 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
1368 Point
aTmp( pObj
->GetSnapRect().TopLeft() );
1369 pDoc
->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam
.GetPoint(), aTmp
, &aState
);
1373 //without access to the layout the last node of the body will be used as anchor position
1374 aPam
.Move( fnMoveBackward
, GoInDoc
);
1376 //the RES_TXTATR_FLYCNT needs to be added now
1377 SwTextNode
*pNd
= aPam
.GetPointNode().GetTextNode();
1378 SAL_WARN_IF( !pNd
, "sw.uno", "Cursor is not in a TextNode." );
1379 SwFormatFlyCnt
aFormat( pFlyFormat
);
1380 pNd
->InsertItem(aFormat
,
1381 aPam
.GetPoint()->GetContentIndex(), 0 );
1382 aPam
.GetPoint()->AdjustContent(-1); // InsertItem moved it
1383 SwFormatAnchor
aNewAnchor(
1384 aSet
.Get(RES_ANCHOR
));
1385 aNewAnchor
.SetAnchor( aPam
.GetPoint() );
1386 aSet
.Put( aNewAnchor
);
1389 pFormat
->SetFormatAttr(aSet
);
1391 // If this property is an anchor change, and there is a group shape with textboxes
1392 // do anchor sync in time unless the anchor sync in the porfly will cause crash during
1393 // layout calculation (When importing an inline shape in docx via dmapper).
1394 if (pFormat
->Which() == RES_DRAWFRMFMT
&& pFormat
->GetOtherTextBoxFormats()
1395 && pFormat
->GetOtherTextBoxFormats()->GetTextBoxCount()
1396 > o3tl::make_unsigned(1))
1397 SwTextBoxHelper::synchronizeGroupTextBoxProperty(
1398 SwTextBoxHelper::changeAnchor
, pFormat
,
1399 SdrObject::getSdrObjectFromXShape(mxShape
));
1402 pFormat
->SetFormatAttr(aSet
);
1405 // We have a pFormat and a pEntry as well: try to sync TextBox property.
1406 SwTextBoxHelper::syncProperty(pFormat
, pEntry
->nWID
, pEntry
->nMemberId
, aValue
,
1407 SdrObject::getSdrObjectFromXShape(mxShape
));
1411 SfxPoolItem
* pItem
= nullptr;
1412 switch(pEntry
->nWID
)
1415 pItem
= m_pImpl
->GetAnchor(true);
1417 case RES_HORI_ORIENT
:
1418 pItem
= m_pImpl
->GetHOrient(true);
1420 case RES_VERT_ORIENT
:
1421 pItem
= m_pImpl
->GetVOrient(true);
1424 pItem
= m_pImpl
->GetLRSpace(true);
1427 pItem
= m_pImpl
->GetULSpace(true);
1430 pItem
= m_pImpl
->GetSurround(true);
1433 if(auto tr
= o3tl::tryAccess
<
1434 uno::Reference
<text::XTextRange
>>(aValue
))
1436 uno::Reference
< text::XTextRange
> & rRange
= m_pImpl
->GetTextRange();
1441 m_pImpl
->SetOpaque(*o3tl::doAccess
<bool>(aValue
));
1444 case RES_FOLLOW_TEXT_FLOW
:
1446 pItem
= m_pImpl
->GetFollowTextFlow( true );
1450 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1452 pItem
= m_pImpl
->GetWrapInfluenceOnObjPos( true );
1456 case FN_SHAPE_POSITION_LAYOUT_DIR
:
1458 sal_Int16 nPositionLayoutDir
= 0;
1459 aValue
>>= nPositionLayoutDir
;
1460 m_pImpl
->SetPositionLayoutDir( nPositionLayoutDir
);
1465 pItem
->PutValue(aValue
, pEntry
->nMemberId
);
1470 const uno::Type
& rPSetType
=
1471 cppu::UnoType
<beans::XPropertySet
>::get();
1472 uno::Any aPSet
= m_xShapeAgg
->queryAggregation(rPSetType
);
1473 auto xPrSet
= o3tl::tryAccess
<uno::Reference
<beans::XPropertySet
>>(
1476 throw uno::RuntimeException();
1477 // #i31698# - setting the caption point of a
1478 // caption object doesn't have to change the object position.
1479 // Thus, keep the position, before the caption point is set and
1480 // restore it afterwards.
1481 awt::Point
aKeepedPosition( 0, 0 );
1482 if ( rPropertyName
== "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
1484 aKeepedPosition
= getPosition();
1486 if( pFormat
&& pFormat
->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() )
1488 UnoActionContext
aCtx(pFormat
->GetDoc());
1489 (*xPrSet
)->setPropertyValue(rPropertyName
, aValue
);
1492 (*xPrSet
)->setPropertyValue(rPropertyName
, aValue
);
1496 // We have a pFormat (but no pEntry): try to sync TextBox property.
1497 SwTextBoxHelper::syncProperty(pFormat
, rPropertyName
, aValue
,
1498 SdrObject::getSdrObjectFromXShape(mxShape
));
1501 // #i31698# - restore object position, if caption point is set.
1502 if ( rPropertyName
== "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
1504 setPosition( aKeepedPosition
);
1509 uno::Any
SwXShape::getPropertyValue(const OUString
& rPropertyName
)
1511 SolarMutexGuard aGuard
;
1513 SwFrameFormat
* pFormat
= GetFrameFormat();
1514 if(m_xShapeAgg
.is())
1516 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
1521 if(RES_OPAQUE
== pEntry
->nWID
)
1523 SvxShape
* pSvxShape
= GetSvxShape();
1524 OSL_ENSURE(pSvxShape
, "No SvxShape found!");
1527 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1528 // consider invisible layers
1530 ( pObj
->GetLayer() != pFormat
->GetDoc()->getIDocumentDrawModelAccess().GetHellId() &&
1531 pObj
->GetLayer() != pFormat
->GetDoc()->getIDocumentDrawModelAccess().GetInvisibleHellId() );
1534 else if(FN_ANCHOR_POSITION
== pEntry
->nWID
)
1536 SvxShape
* pSvxShape
= GetSvxShape();
1537 OSL_ENSURE(pSvxShape
, "No SvxShape found!");
1540 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1541 Point aPt
= pObj
->GetAnchorPos();
1542 awt::Point
aPoint( convertTwipToMm100( aPt
.X() ),
1543 convertTwipToMm100( aPt
.Y() ) );
1547 // #i26791# - special handling for FN_TEXT_RANGE
1548 else if ( FN_TEXT_RANGE
== pEntry
->nWID
)
1550 const SwFormatAnchor aAnchor
= pFormat
->GetAnchor();
1551 if (aAnchor
.GetAnchorId() == RndStdIds::FLY_AT_PAGE
)
1553 // return nothing, because property <TextRange> isn't
1554 // valid for to-page anchored shapes
1560 if ( aAnchor
.GetAnchorNode() )
1562 const rtl::Reference
<SwXTextRange
> xTextRange
1563 = SwXTextRange::CreateXTextRange(
1565 *aAnchor
.GetContentAnchor(),
1567 aRet
<<= uno::Reference
<text::XTextRange
>(xTextRange
);
1577 else if (pEntry
->nWID
== FN_TEXT_BOX
)
1579 if (pEntry
->nMemberId
== MID_TEXT_BOX
)
1581 auto pSvxShape
= GetSvxShape();
1582 bool bValue
= SwTextBoxHelper::isTextBox(
1583 pFormat
, RES_DRAWFRMFMT
,
1584 ((pSvxShape
&& pSvxShape
->GetSdrObject()) ? pSvxShape
->GetSdrObject()
1585 : pFormat
->FindRealSdrObject()));
1588 else if (pEntry
->nMemberId
== MID_TEXT_BOX_CONTENT
)
1590 auto pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1591 auto xRange
= SwTextBoxHelper::queryInterface(
1592 pFormat
, cppu::UnoType
<text::XText
>::get(),
1593 pObj
? pObj
: pFormat
->FindRealSdrObject());
1594 uno::Reference
<text::XTextFrame
> xFrame(xRange
, uno::UNO_QUERY
);
1599 else if (pEntry
->nWID
== RES_CHAIN
)
1601 switch (pEntry
->nMemberId
)
1603 case MID_CHAIN_PREVNAME
:
1604 case MID_CHAIN_NEXTNAME
:
1605 case MID_CHAIN_NAME
:
1606 SwTextBoxHelper::getProperty(pFormat
, pEntry
->nWID
, pEntry
->nMemberId
, aRet
);
1611 else if ( FN_SHAPE_TRANSFORMATION_IN_HORI_L2R
== pEntry
->nWID
)
1613 // get property <::drawing::Shape::Transformation>
1614 // without conversion to layout direction as below
1615 aRet
= _getPropAtAggrObj( "Transformation" );
1617 else if ( FN_SHAPE_POSITION_LAYOUT_DIR
== pEntry
->nWID
)
1619 aRet
<<= pFormat
->GetPositionLayoutDir();
1622 else if ( FN_SHAPE_STARTPOSITION_IN_HORI_L2R
== pEntry
->nWID
)
1624 // get property <::drawing::Shape::StartPosition>
1625 // without conversion to layout direction as below
1626 aRet
= _getPropAtAggrObj( "StartPosition" );
1628 else if ( FN_SHAPE_ENDPOSITION_IN_HORI_L2R
== pEntry
->nWID
)
1630 // get property <::drawing::Shape::EndPosition>
1631 // without conversion to layout direction as below
1632 aRet
= _getPropAtAggrObj( "EndPosition" );
1634 else if (pEntry
->nWID
== RES_FRM_SIZE
&&
1635 (pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT
||
1636 pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH
||
1637 pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT_RELATION
||
1638 pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH_RELATION
))
1640 SvxShape
* pSvxShape
= GetSvxShape();
1641 SAL_WARN_IF(!pSvxShape
, "sw.uno", "No SvxShape found!");
1645 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1646 switch (pEntry
->nMemberId
)
1648 case MID_FRMSIZE_REL_WIDTH
:
1649 if (pObj
->GetRelativeWidth())
1650 nRet
= *pObj
->GetRelativeWidth() * 100;
1652 case MID_FRMSIZE_REL_HEIGHT
:
1653 if (pObj
->GetRelativeHeight())
1654 nRet
= *pObj
->GetRelativeHeight() * 100;
1656 case MID_FRMSIZE_REL_WIDTH_RELATION
:
1657 nRet
= pObj
->GetRelativeWidthRelation();
1659 case MID_FRMSIZE_REL_HEIGHT_RELATION
:
1660 nRet
= pObj
->GetRelativeHeightRelation();
1668 const SwAttrSet
& rSet
= pFormat
->GetAttrSet();
1669 m_pPropSet
->getPropertyValue(*pEntry
, rSet
, aRet
);
1674 SfxPoolItem
* pItem
= nullptr;
1675 switch(pEntry
->nWID
)
1678 pItem
= m_pImpl
->GetAnchor();
1680 case RES_HORI_ORIENT
:
1681 pItem
= m_pImpl
->GetHOrient();
1683 case RES_VERT_ORIENT
:
1684 pItem
= m_pImpl
->GetVOrient();
1687 pItem
= m_pImpl
->GetLRSpace();
1690 pItem
= m_pImpl
->GetULSpace();
1693 pItem
= m_pImpl
->GetSurround();
1695 case FN_TEXT_RANGE
:
1696 aRet
<<= m_pImpl
->GetTextRange();
1699 aRet
<<= m_pImpl
->GetOpaque();
1701 case FN_ANCHOR_POSITION
:
1703 aRet
<<= awt::Point();
1707 case RES_FOLLOW_TEXT_FLOW
:
1709 pItem
= m_pImpl
->GetFollowTextFlow();
1713 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1715 pItem
= m_pImpl
->GetWrapInfluenceOnObjPos();
1719 case FN_SHAPE_TRANSFORMATION_IN_HORI_L2R
:
1721 // get property <::drawing::Shape::Transformation>
1722 // without conversion to layout direction as below
1723 aRet
= _getPropAtAggrObj( "Transformation" );
1726 case FN_SHAPE_POSITION_LAYOUT_DIR
:
1728 aRet
<<= m_pImpl
->GetPositionLayoutDir();
1732 case FN_SHAPE_STARTPOSITION_IN_HORI_L2R
:
1734 // get property <::drawing::Shape::StartPosition>
1735 // without conversion to layout direction as below
1736 aRet
= _getPropAtAggrObj( "StartPosition" );
1739 case FN_SHAPE_ENDPOSITION_IN_HORI_L2R
:
1741 // get property <::drawing::Shape::StartPosition>
1742 // without conversion to layout direction as below
1743 aRet
= _getPropAtAggrObj( "EndPosition" );
1748 pItem
->QueryValue(aRet
, pEntry
->nMemberId
);
1753 aRet
= _getPropAtAggrObj( rPropertyName
);
1755 // #i31698# - convert the position (translation)
1756 // of the drawing object in the transformation
1757 if ( rPropertyName
== "Transformation" )
1759 drawing::HomogenMatrix3 aMatrix
;
1761 aRet
<<= ConvertTransformationToLayoutDir( aMatrix
);
1764 else if ( rPropertyName
== "StartPosition" )
1766 awt::Point aStartPos
;
1769 aRet
<<= ConvertStartOrEndPosToLayoutDir( aStartPos
);
1771 else if ( rPropertyName
== "EndPosition" )
1776 aRet
<<= ConvertStartOrEndPosToLayoutDir( aEndPos
);
1779 else if ( rPropertyName
== "PolyPolygonBezier" )
1781 drawing::PolyPolygonBezierCoords aPath
;
1783 aRet
<<= ConvertPolyPolygonBezierToLayoutDir( aPath
);
1785 else if (rPropertyName
== "ZOrder")
1787 // Convert the real draw page position to the logical one that ignores textboxes.
1790 const SdrObject
* pObj
= pFormat
->FindRealSdrObject();
1793 bool bConvert
= true;
1794 if (SvxShape
* pSvxShape
= GetSvxShape())
1795 // In case of group shapes, pSvxShape points to the child shape, while pObj points to the outermost group shape.
1796 if (pSvxShape
->GetSdrObject() != pObj
)
1797 // Textboxes are not expected inside group shapes, so no conversion is necessary there.
1801 aRet
<<= SwTextBoxHelper::getOrdNum(pObj
);
1811 uno::Any
SwXShape::_getPropAtAggrObj( const OUString
& _rPropertyName
)
1815 const uno::Type
& rPSetType
=
1816 cppu::UnoType
<beans::XPropertySet
>::get();
1817 uno::Any aPSet
= m_xShapeAgg
->queryAggregation(rPSetType
);
1818 auto xPrSet
= o3tl::tryAccess
<uno::Reference
<beans::XPropertySet
>>(aPSet
);
1821 throw uno::RuntimeException();
1823 aRet
= (*xPrSet
)->getPropertyValue( _rPropertyName
);
1828 beans::PropertyState
SwXShape::getPropertyState( const OUString
& rPropertyName
)
1830 SolarMutexGuard aGuard
;
1831 uno::Sequence
< OUString
> aNames
{ rPropertyName
};
1832 uno::Sequence
< beans::PropertyState
> aStates
= getPropertyStates(aNames
);
1833 return aStates
.getConstArray()[0];
1836 uno::Sequence
< beans::PropertyState
> SwXShape::getPropertyStates(
1837 const uno::Sequence
< OUString
>& aPropertyNames
)
1839 SolarMutexGuard aGuard
;
1840 SwFrameFormat
* pFormat
= GetFrameFormat();
1841 uno::Sequence
< beans::PropertyState
> aRet(aPropertyNames
.getLength());
1842 if(!m_xShapeAgg
.is())
1843 throw uno::RuntimeException();
1845 SvxShape
* pSvxShape
= GetSvxShape();
1846 bool bGroupMember
= false;
1847 bool bFormControl
= false;
1848 SdrObject
* pObject
= pSvxShape
? pSvxShape
->GetSdrObject() : nullptr;
1851 bGroupMember
= pObject
->getParentSdrObjectFromSdrObject() != nullptr;
1852 bFormControl
= pObject
->GetObjInventor() == SdrInventor::FmForm
;
1854 const OUString
* pNames
= aPropertyNames
.getConstArray();
1855 beans::PropertyState
* pRet
= aRet
.getArray();
1856 uno::Reference
< XPropertyState
> xShapePrState
;
1857 for(sal_Int32 nProperty
= 0; nProperty
< aPropertyNames
.getLength(); nProperty
++)
1859 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( pNames
[nProperty
] );
1862 if(RES_OPAQUE
== pEntry
->nWID
)
1863 pRet
[nProperty
] = bFormControl
?
1864 beans::PropertyState_DEFAULT_VALUE
: beans::PropertyState_DIRECT_VALUE
;
1865 else if(FN_ANCHOR_POSITION
== pEntry
->nWID
)
1866 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1867 else if(FN_TEXT_RANGE
== pEntry
->nWID
)
1868 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1869 else if(bGroupMember
)
1870 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1871 else if (pEntry
->nWID
== RES_FRM_SIZE
&&
1872 (pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT_RELATION
||
1873 pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH_RELATION
))
1874 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1875 else if (pEntry
->nWID
== FN_TEXT_BOX
)
1877 // The TextBox property is set, if we can find a textbox for this shape.
1879 && SwTextBoxHelper::isTextBox(pFormat
, RES_DRAWFRMFMT
,
1880 SdrObject::getSdrObjectFromXShape(mxShape
)))
1881 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1883 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1887 const SwAttrSet
& rSet
= pFormat
->GetAttrSet();
1888 SfxItemState eItemState
= rSet
.GetItemState(pEntry
->nWID
, false);
1890 if(SfxItemState::SET
== eItemState
)
1891 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1892 else if(SfxItemState::DEFAULT
== eItemState
)
1893 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1895 pRet
[nProperty
] = beans::PropertyState_AMBIGUOUS_VALUE
;
1899 SfxPoolItem
* pItem
= nullptr;
1900 switch(pEntry
->nWID
)
1903 pItem
= m_pImpl
->GetAnchor();
1905 case RES_HORI_ORIENT
:
1906 pItem
= m_pImpl
->GetHOrient();
1908 case RES_VERT_ORIENT
:
1909 pItem
= m_pImpl
->GetVOrient();
1912 pItem
= m_pImpl
->GetLRSpace();
1915 pItem
= m_pImpl
->GetULSpace();
1918 pItem
= m_pImpl
->GetSurround();
1921 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1923 pItem
= m_pImpl
->GetWrapInfluenceOnObjPos();
1928 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1930 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1935 if(!xShapePrState
.is())
1937 const uno::Type
& rPStateType
= cppu::UnoType
<XPropertyState
>::get();
1938 uno::Any aPState
= m_xShapeAgg
->queryAggregation(rPStateType
);
1939 auto ps
= o3tl::tryAccess
<uno::Reference
<XPropertyState
>>(
1942 throw uno::RuntimeException();
1943 xShapePrState
= *ps
;
1945 pRet
[nProperty
] = xShapePrState
->getPropertyState(pNames
[nProperty
]);
1952 void SwXShape::setPropertyToDefault( const OUString
& rPropertyName
)
1954 SolarMutexGuard aGuard
;
1955 SwFrameFormat
* pFormat
= GetFrameFormat();
1956 if(!m_xShapeAgg
.is())
1957 throw uno::RuntimeException();
1959 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
1962 if ( pEntry
->nFlags
& beans::PropertyAttribute::READONLY
)
1963 throw uno::RuntimeException("Property is read-only: " + rPropertyName
, static_cast < cppu::OWeakObject
* > ( this ) );
1966 const SfxItemSet
& rSet
= pFormat
->GetAttrSet();
1967 SfxItemSet
aSet(pFormat
->GetDoc()->GetAttrPool(), pEntry
->nWID
, pEntry
->nWID
);
1968 aSet
.SetParent(&rSet
);
1969 aSet
.ClearItem(pEntry
->nWID
);
1970 pFormat
->GetDoc()->SetAttr(aSet
, *pFormat
);
1974 switch(pEntry
->nWID
)
1976 case RES_ANCHOR
: m_pImpl
->RemoveAnchor(); break;
1977 case RES_HORI_ORIENT
: m_pImpl
->RemoveHOrient(); break;
1978 case RES_VERT_ORIENT
: m_pImpl
->RemoveVOrient(); break;
1979 case RES_LR_SPACE
: m_pImpl
->RemoveLRSpace(); break;
1980 case RES_UL_SPACE
: m_pImpl
->RemoveULSpace(); break;
1981 case RES_SURROUND
: m_pImpl
->RemoveSurround();break;
1982 case RES_OPAQUE
: m_pImpl
->SetOpaque(false); break;
1983 case FN_TEXT_RANGE
:
1986 case RES_FOLLOW_TEXT_FLOW
:
1988 m_pImpl
->RemoveFollowTextFlow();
1992 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1994 m_pImpl
->RemoveWrapInfluenceOnObjPos();
2002 const uno::Type
& rPStateType
= cppu::UnoType
<XPropertyState
>::get();
2003 uno::Any aPState
= m_xShapeAgg
->queryAggregation(rPStateType
);
2004 auto xShapePrState
= o3tl::tryAccess
<uno::Reference
<XPropertyState
>>(
2007 throw uno::RuntimeException();
2008 (*xShapePrState
)->setPropertyToDefault( rPropertyName
);
2013 uno::Any
SwXShape::getPropertyDefault( const OUString
& rPropertyName
)
2015 SolarMutexGuard aGuard
;
2016 SwFrameFormat
* pFormat
= GetFrameFormat();
2018 if(!m_xShapeAgg
.is())
2019 throw uno::RuntimeException();
2021 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
2024 if(!(pEntry
->nWID
< RES_FRMATR_END
&& pFormat
))
2025 throw uno::RuntimeException();
2027 const SfxPoolItem
& rDefItem
=
2028 pFormat
->GetDoc()->GetAttrPool().GetDefaultItem(pEntry
->nWID
);
2029 rDefItem
.QueryValue(aRet
, pEntry
->nMemberId
);
2034 const uno::Type
& rPStateType
= cppu::UnoType
<XPropertyState
>::get();
2035 uno::Any aPState
= m_xShapeAgg
->queryAggregation(rPStateType
);
2036 auto xShapePrState
= o3tl::tryAccess
<uno::Reference
<XPropertyState
>>(
2039 throw uno::RuntimeException();
2040 (*xShapePrState
)->getPropertyDefault( rPropertyName
);
2046 void SwXShape::addPropertyChangeListener(
2047 const OUString
& _propertyName
,
2048 const uno::Reference
< beans::XPropertyChangeListener
> & _listener
)
2050 if ( !m_xShapeAgg
.is() )
2051 throw uno::RuntimeException("no shape aggregate", *this );
2053 // must be handled by the aggregate
2054 uno::Reference
< beans::XPropertySet
> xShapeProps
;
2055 if ( m_xShapeAgg
->queryAggregation( cppu::UnoType
<beans::XPropertySet
>::get() ) >>= xShapeProps
)
2056 xShapeProps
->addPropertyChangeListener( _propertyName
, _listener
);
2059 void SwXShape::removePropertyChangeListener(
2060 const OUString
& _propertyName
,
2061 const uno::Reference
< beans::XPropertyChangeListener
> & _listener
)
2063 if ( !m_xShapeAgg
.is() )
2064 throw uno::RuntimeException("no shape aggregate", *this );
2066 // must be handled by the aggregate
2067 uno::Reference
< beans::XPropertySet
> xShapeProps
;
2068 if ( m_xShapeAgg
->queryAggregation( cppu::UnoType
<beans::XPropertySet
>::get() ) >>= xShapeProps
)
2069 xShapeProps
->removePropertyChangeListener( _propertyName
, _listener
);
2072 void SwXShape::addVetoableChangeListener(
2073 const OUString
& /*PropertyName*/,
2074 const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/ )
2076 OSL_FAIL("not implemented");
2079 void SwXShape::removeVetoableChangeListener(
2080 const OUString
& /*PropertyName*/,
2081 const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
2083 OSL_FAIL("not implemented");
2086 void SwXShape::attach(const uno::Reference
< text::XTextRange
> & xTextRange
)
2088 SolarMutexGuard aGuard
;
2090 // get access to SwDoc
2091 // (see also SwXTextRange::XTextRangeToSwPaM)
2092 const SwDoc
* pDoc
= nullptr;
2093 if (auto pRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get()))
2094 pDoc
= &pRange
->GetDoc();
2095 else if (auto pText
= dynamic_cast<SwXText
*>(xTextRange
.get()))
2096 pDoc
= pText
->GetDoc();
2097 else if (auto pCursor
= dynamic_cast<OTextCursorHelper
*>(xTextRange
.get()))
2098 pDoc
= pCursor
->GetDoc();
2099 else if (auto pPortion
= dynamic_cast<SwXTextPortion
*>(xTextRange
.get()))
2100 pDoc
= &pPortion
->GetCursor().GetDoc();
2101 else if (auto pParagraph
= dynamic_cast<SwXParagraph
*>(xTextRange
.get());
2102 pParagraph
&& pParagraph
->GetTextNode())
2103 pDoc
= &pParagraph
->GetTextNode()->GetDoc();
2106 throw uno::RuntimeException();
2107 const SwDocShell
* pDocSh
= pDoc
->GetDocShell();
2111 uno::Reference
<frame::XModel
> xModel
= pDocSh
->GetModel();
2112 uno::Reference
< drawing::XDrawPageSupplier
> xDPS(xModel
, uno::UNO_QUERY
);
2115 uno::Reference
< drawing::XDrawPage
> xDP( xDPS
->getDrawPage() );
2119 aPos
<<= xTextRange
;
2120 setPropertyValue("TextRange", aPos
);
2121 uno::Reference
< drawing::XShape
> xTemp( static_cast<cppu::OWeakObject
*>(this), uno::UNO_QUERY
);
2127 uno::Reference
< text::XTextRange
> SwXShape::getAnchor()
2129 SolarMutexGuard aGuard
;
2130 uno::Reference
< text::XTextRange
> aRef
;
2131 SwFrameFormat
* pFormat
= GetFrameFormat();
2134 const SwFormatAnchor
& rAnchor
= pFormat
->GetAnchor();
2135 // return an anchor for non-page bound frames
2136 // and for page bound frames that have a page no == NULL and a content position
2137 if ((rAnchor
.GetAnchorId() != RndStdIds::FLY_AT_PAGE
) ||
2138 (rAnchor
.GetAnchorNode() && !rAnchor
.GetPageNum()))
2140 if (rAnchor
.GetAnchorId() == RndStdIds::FLY_AT_PARA
)
2141 { // ensure that SwXTextRange has SwContentIndex
2142 const SwNode
* pAnchorNode
= rAnchor
.GetAnchorNode();
2143 aRef
= SwXTextRange::CreateXTextRange(*pFormat
->GetDoc(), SwPosition(*pAnchorNode
), nullptr);
2147 aRef
= SwXTextRange::CreateXTextRange(*pFormat
->GetDoc(), *rAnchor
.GetContentAnchor(), nullptr);
2152 aRef
= m_pImpl
->GetTextRange().get();
2156 void SwXShape::dispose()
2158 SolarMutexGuard aGuard
;
2159 SwFrameFormat
* pFormat
= GetFrameFormat();
2162 // determine correct <SdrObject>
2163 SvxShape
* pSvxShape
= GetSvxShape();
2164 SdrObject
* pObj
= pSvxShape
? pSvxShape
->GetSdrObject() : nullptr;
2165 // safety assertion:
2166 // <pObj> must be the same as <pFormat->FindSdrObject()>, if <pObj> isn't
2167 // a 'virtual' drawing object.
2168 // correct assertion and refine it for safety reason.
2169 OSL_ENSURE( !pObj
||
2170 dynamic_cast<const SwDrawVirtObj
*>( pObj
) != nullptr ||
2171 pObj
->getParentSdrObjectFromSdrObject() ||
2172 pObj
== pFormat
->FindSdrObject(),
2173 "<SwXShape::dispose(..) - different 'master' drawing objects!!" );
2174 // perform delete of draw frame format *not*
2175 // for 'virtual' drawing objects.
2176 // no delete of draw format for members
2179 dynamic_cast<const SwDrawVirtObj
*>( pObj
) == nullptr &&
2180 !pObj
->getParentSdrObjectFromSdrObject() &&
2181 pObj
->IsInserted() )
2183 const SwFormatAnchor
& rFormatAnchor
= pFormat
->GetAnchor();
2184 if (rFormatAnchor
.GetAnchorId() == RndStdIds::FLY_AS_CHAR
)
2186 SwTextNode
*pTextNode
= rFormatAnchor
.GetAnchorNode()->GetTextNode();
2187 const sal_Int32 nIdx
= rFormatAnchor
.GetAnchorContentOffset();
2188 pTextNode
->DeleteAttributes( RES_TXTATR_FLYCNT
, nIdx
);
2191 pFormat
->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat( pFormat
);
2194 if(m_xShapeAgg
.is())
2196 uno::Any
aAgg(m_xShapeAgg
->queryAggregation( cppu::UnoType
<XComponent
>::get()));
2197 uno::Reference
<XComponent
> xComp
;
2204 auto pPage
= const_cast<SwFmDrawPage
*>(m_pPage
);
2206 pPage
->RemoveShape(this);
2210 void SwXShape::addEventListener(
2211 const uno::Reference
< lang::XEventListener
> & aListener
)
2213 SvxShape
* pSvxShape
= GetSvxShape();
2215 pSvxShape
->addEventListener(aListener
);
2218 void SwXShape::removeEventListener(
2219 const uno::Reference
< lang::XEventListener
> & aListener
)
2221 SvxShape
* pSvxShape
= GetSvxShape();
2223 pSvxShape
->removeEventListener(aListener
);
2226 OUString
SwXShape::getImplementationName()
2231 sal_Bool
SwXShape::supportsService(const OUString
& rServiceName
)
2233 return cppu::supportsService(this, rServiceName
);
2236 uno::Sequence
< OUString
> SwXShape::getSupportedServiceNames()
2238 uno::Sequence
< OUString
> aSeq
;
2239 if (SvxShape
* pSvxShape
= GetSvxShape())
2240 aSeq
= pSvxShape
->getSupportedServiceNames();
2241 return comphelper::concatSequences(
2242 aSeq
, std::initializer_list
<std::u16string_view
>{ u
"com.sun.star.drawing.Shape" });
2245 SvxShape
* SwXShape::GetSvxShape()
2247 if(m_xShapeAgg
.is())
2248 return comphelper::getFromUnoTunnel
<SvxShape
>(m_xShapeAgg
);
2253 // implementation of virtual methods from drawing::XShape
2254 awt::Point SAL_CALL
SwXShape::getPosition()
2256 awt::Point
aPos( GetAttrPosition() );
2258 // handle group members
2259 SvxShape
* pSvxShape
= GetSvxShape();
2262 SdrObject
* pTopGroupObj
= GetTopGroupObj( pSvxShape
);
2265 // #i34750# - get attribute position of top group
2266 // shape and add offset between top group object and group member
2267 uno::Reference
< drawing::XShape
> xGroupShape( pTopGroupObj
->getUnoShape(), uno::UNO_QUERY
);
2268 aPos
= xGroupShape
->getPosition();
2269 // add offset between top group object and group member
2270 // to the determined attribute position
2272 // consider the layout direction
2273 const tools::Rectangle aMemberObjRect
= GetSvxShape()->GetSdrObject()->GetSnapRect();
2274 const tools::Rectangle aGroupObjRect
= pTopGroupObj
->GetSnapRect();
2275 // #i53320# - relative position of group member and
2276 // top group object is always given in horizontal left-to-right layout.
2277 awt::Point
aOffset( 0, 0 );
2279 aOffset
.X
= ( aMemberObjRect
.Left() - aGroupObjRect
.Left() );
2280 aOffset
.Y
= ( aMemberObjRect
.Top() - aGroupObjRect
.Top() );
2282 aOffset
.X
= convertTwipToMm100(aOffset
.X
);
2283 aOffset
.Y
= convertTwipToMm100(aOffset
.Y
);
2284 aPos
.X
+= aOffset
.X
;
2285 aPos
.Y
+= aOffset
.Y
;
2292 void SAL_CALL
SwXShape::setPosition( const awt::Point
& aPosition
)
2294 SdrObject
* pTopGroupObj
= GetTopGroupObj();
2295 if ( !pTopGroupObj
)
2297 // #i37877# - no adjustment of position attributes,
2298 // if the position also has to be applied at the drawing object and
2299 // a contact object is already registered at the drawing object.
2300 bool bApplyPosAtDrawObj(false);
2301 bool bNoAdjustOfPosProp(false);
2302 // #i35798# - apply position also to drawing object,
2303 // if drawing object has no anchor position set.
2306 SvxShape
* pSvxShape
= GetSvxShape();
2309 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2311 pObj
->GetAnchorPos().X() == 0 &&
2312 pObj
->GetAnchorPos().Y() == 0 )
2314 bApplyPosAtDrawObj
= true;
2315 if ( pObj
->GetUserCall() &&
2316 dynamic_cast<const SwDrawContact
*>( pObj
->GetUserCall()) != nullptr )
2318 bNoAdjustOfPosProp
= true;
2323 // shape isn't a group member. Thus, set positioning attributes
2324 if ( !bNoAdjustOfPosProp
)
2326 AdjustPositionProperties( aPosition
);
2328 if ( bApplyPosAtDrawObj
)
2330 mxShape
->setPosition( aPosition
);
2333 else if ( mxShape
.is() )
2335 // shape is a member of a group. Thus, set its position.
2336 awt::Point
aNewPos( aPosition
);
2337 // The given position is given in the according layout direction. Thus,
2338 // it has to be converted to a position in horizontal left-to-right
2340 // convert given absolute attribute position in layout direction into
2341 // position in horizontal left-to-right layout.
2343 aNewPos
= ConvertPositionToHoriL2R( aNewPos
, getSize() );
2345 // Convert given absolute position in horizontal left-to-right
2346 // layout into relative position in horizontal left-to-right layout.
2347 uno::Reference
< drawing::XShape
> xGroupShape( pTopGroupObj
->getUnoShape(), uno::UNO_QUERY
);
2350 // use method <xGroupShape->getPosition()> to get the correct
2351 // position of the top group object.
2352 awt::Point
aAttrPosInHoriL2R(
2353 ConvertPositionToHoriL2R( xGroupShape
->getPosition(),
2354 xGroupShape
->getSize() ) );
2355 aNewPos
.X
= o3tl::saturating_sub(aNewPos
.X
, aAttrPosInHoriL2R
.X
);
2356 aNewPos
.Y
= o3tl::saturating_sub(aNewPos
.Y
, aAttrPosInHoriL2R
.Y
);
2358 // convert relative position in horizontal left-to-right layout into
2359 // absolute position in horizontal left-to-right layout
2362 // use method <SvxShape->getPosition()> to get the correct
2363 // 'Drawing layer' position of the top group shape.
2364 auto pSvxGroupShape
= comphelper::getFromUnoTunnel
<SvxShape
>(pTopGroupObj
->getUnoShape());
2365 const awt::Point aGroupPos
= pSvxGroupShape
->getPosition();
2366 aNewPos
.X
= o3tl::saturating_add(aNewPos
.X
, aGroupPos
.X
);
2367 aNewPos
.Y
= o3tl::saturating_add(aNewPos
.Y
, aGroupPos
.Y
);
2370 mxShape
->setPosition( aNewPos
);
2374 awt::Size SAL_CALL
SwXShape::getSize()
2379 aSize
= mxShape
->getSize();
2384 void SAL_CALL
SwXShape::setSize( const awt::Size
& aSize
)
2386 comphelper::ProfileZone
aZone("SwXShape::setSize");
2390 mxShape
->setSize( aSize
);
2392 SwTextBoxHelper::syncProperty(GetFrameFormat(), RES_FRM_SIZE
, MID_FRMSIZE_SIZE
, uno::Any(aSize
));
2395 // implementation of virtual methods from drawing::XShapeDescriptor
2396 OUString SAL_CALL
SwXShape::getShapeType()
2400 return mxShape
->getShapeType();
2404 /** method to determine top group object
2407 SdrObject
* SwXShape::GetTopGroupObj( SvxShape
* _pSvxShape
)
2409 SdrObject
* pTopGroupObj( nullptr );
2411 SvxShape
* pSvxShape
= _pSvxShape
? _pSvxShape
: GetSvxShape();
2414 SdrObject
* pSdrObj
= pSvxShape
->GetSdrObject();
2415 if ( pSdrObj
&& pSdrObj
->getParentSdrObjectFromSdrObject() )
2417 pTopGroupObj
= pSdrObj
->getParentSdrObjectFromSdrObject();
2418 while ( pTopGroupObj
->getParentSdrObjectFromSdrObject() )
2420 pTopGroupObj
= pTopGroupObj
->getParentSdrObjectFromSdrObject();
2425 return pTopGroupObj
;
2428 /** method to determine position according to the positioning attributes
2431 awt::Point
SwXShape::GetAttrPosition()
2433 awt::Point aAttrPos
;
2435 uno::Any
aHoriPos( getPropertyValue("HoriOrientPosition") );
2436 aHoriPos
>>= aAttrPos
.X
;
2437 uno::Any
aVertPos( getPropertyValue("VertOrientPosition") );
2438 aVertPos
>>= aAttrPos
.Y
;
2439 // #i35798# - fallback, if attribute position is (0,0)
2440 // and no anchor position is applied to the drawing object
2441 SvxShape
* pSvxShape
= GetSvxShape();
2444 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2446 pObj
->GetAnchorPos().X() == 0 &&
2447 pObj
->GetAnchorPos().Y() == 0 &&
2448 aAttrPos
.X
== 0 && aAttrPos
.Y
== 0 )
2450 const tools::Rectangle aObjRect
= pObj
->GetSnapRect();
2451 aAttrPos
.X
= convertTwipToMm100(aObjRect
.Left());
2452 aAttrPos
.Y
= convertTwipToMm100(aObjRect
.Top());
2455 // #i35007# - If drawing object is anchored as-character,
2456 // it's x-position isn't sensible. Thus, return the x-position as zero in this case.
2457 text::TextContentAnchorType eTextAnchorType
=
2458 text::TextContentAnchorType_AT_PARAGRAPH
;
2460 uno::Any aAny
= getPropertyValue( "AnchorType" );
2461 aAny
>>= eTextAnchorType
;
2463 if ( eTextAnchorType
== text::TextContentAnchorType_AS_CHARACTER
)
2471 /** method to convert the position (translation) of the drawing object to
2472 the layout direction horizontal left-to-right.
2475 awt::Point
SwXShape::ConvertPositionToHoriL2R( const awt::Point
& rObjPos
,
2476 const awt::Size
& rObjSize
)
2478 awt::Point
aObjPosInHoriL2R( rObjPos
);
2480 SwFrameFormat
* pFrameFormat
= GetFrameFormat();
2483 SwFrameFormat::tLayoutDir eLayoutDir
= pFrameFormat
->GetLayoutDir();
2484 switch ( eLayoutDir
)
2486 case SwFrameFormat::HORI_L2R
:
2491 case SwFrameFormat::HORI_R2L
:
2493 aObjPosInHoriL2R
.X
= -rObjPos
.X
- rObjSize
.Width
;
2496 case SwFrameFormat::VERT_R2L
:
2498 aObjPosInHoriL2R
.X
= -rObjPos
.Y
- rObjSize
.Width
;
2499 aObjPosInHoriL2R
.Y
= rObjPos
.X
;
2504 OSL_FAIL( "<SwXShape::ConvertPositionToHoriL2R(..)> - unsupported layout direction" );
2509 return aObjPosInHoriL2R
;
2512 /** method to convert the transformation of the drawing object to the layout
2513 direction, the drawing object is in
2516 drawing::HomogenMatrix3
SwXShape::ConvertTransformationToLayoutDir(
2517 const drawing::HomogenMatrix3
& rMatrixInHoriL2R
)
2519 drawing::HomogenMatrix3
aMatrix(rMatrixInHoriL2R
);
2521 // #i44334#, #i44681# - direct manipulation of the
2522 // transformation structure isn't valid, if it contains rotation.
2523 SvxShape
* pSvxShape
= GetSvxShape();
2524 OSL_ENSURE( pSvxShape
,
2525 "<SwXShape::ConvertTransformationToLayoutDir(..)> - no SvxShape found!");
2528 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2530 "<SwXShape::ConvertTransformationToLayoutDir(..)> - no SdrObject found!");
2533 // get position of object in Writer coordinate system.
2534 awt::Point
aPos( getPosition() );
2535 // get position of object in Drawing layer coordinate system
2536 const Point
aTmpObjPos( pObj
->GetSnapRect().TopLeft() );
2537 const awt::Point
aObjPos(
2538 convertTwipToMm100( aTmpObjPos
.X() - pObj
->GetAnchorPos().X() ),
2539 convertTwipToMm100( aTmpObjPos
.Y() - pObj
->GetAnchorPos().Y() ) );
2540 // determine difference between these positions according to the
2541 // Writer coordinate system
2542 const awt::Point
aTranslateDiff( aPos
.X
- aObjPos
.X
,
2543 aPos
.Y
- aObjPos
.Y
);
2544 // apply translation difference to transformation matrix.
2545 if ( aTranslateDiff
.X
!= 0 || aTranslateDiff
.Y
!= 0 )
2547 // #i73079# - use correct matrix type
2548 ::basegfx::B2DHomMatrix aTempMatrix
;
2550 aTempMatrix
.set(0, 0, aMatrix
.Line1
.Column1
);
2551 aTempMatrix
.set(0, 1, aMatrix
.Line1
.Column2
);
2552 aTempMatrix
.set(0, 2, aMatrix
.Line1
.Column3
);
2553 aTempMatrix
.set(1, 0, aMatrix
.Line2
.Column1
);
2554 aTempMatrix
.set(1, 1, aMatrix
.Line2
.Column2
);
2555 aTempMatrix
.set(1, 2, aMatrix
.Line2
.Column3
);
2556 // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
2557 assert( aMatrix
.Line3
.Column1
== 0 );
2558 assert( aMatrix
.Line3
.Column2
== 0 );
2559 assert( aMatrix
.Line3
.Column3
== 1 );
2561 aTempMatrix
.translate( aTranslateDiff
.X
, aTranslateDiff
.Y
);
2562 aMatrix
.Line1
.Column1
= aTempMatrix
.get(0, 0);
2563 aMatrix
.Line1
.Column2
= aTempMatrix
.get(0, 1);
2564 aMatrix
.Line1
.Column3
= aTempMatrix
.get(0, 2);
2565 aMatrix
.Line2
.Column1
= aTempMatrix
.get(1, 0);
2566 aMatrix
.Line2
.Column2
= aTempMatrix
.get(1, 1);
2567 aMatrix
.Line2
.Column3
= aTempMatrix
.get(1, 2);
2568 aMatrix
.Line3
.Column1
= 0;
2569 aMatrix
.Line3
.Column2
= 0;
2570 aMatrix
.Line3
.Column3
= 1;
2578 /** method to adjust the positioning properties
2581 void SwXShape::AdjustPositionProperties( const awt::Point
& rPosition
)
2583 // handle x-position
2584 // #i35007# - no handling of x-position, if drawing
2585 // object is anchored as-character, because it doesn't make sense.
2586 text::TextContentAnchorType eTextAnchorType
=
2587 text::TextContentAnchorType_AT_PARAGRAPH
;
2589 uno::Any aAny
= getPropertyValue( "AnchorType" );
2590 aAny
>>= eTextAnchorType
;
2592 if ( eTextAnchorType
!= text::TextContentAnchorType_AS_CHARACTER
)
2594 // determine current x-position
2595 static const OUStringLiteral
aHoriPosPropStr(u
"HoriOrientPosition");
2596 uno::Any
aHoriPos( getPropertyValue( aHoriPosPropStr
) );
2597 sal_Int32 dCurrX
= 0;
2598 aHoriPos
>>= dCurrX
;
2599 // change x-position attribute, if needed
2600 if ( dCurrX
!= rPosition
.X
)
2602 // adjust x-position orientation to text::HoriOrientation::NONE, if needed
2603 // Note: has to be done before setting x-position attribute
2604 static const OUStringLiteral
aHoriOrientPropStr(u
"HoriOrient");
2605 uno::Any
aHoriOrient( getPropertyValue( aHoriOrientPropStr
) );
2606 sal_Int16 eHoriOrient
;
2607 if (aHoriOrient
>>= eHoriOrient
) // may be void
2609 if ( eHoriOrient
!= text::HoriOrientation::NONE
)
2611 eHoriOrient
= text::HoriOrientation::NONE
;
2612 aHoriOrient
<<= eHoriOrient
;
2613 setPropertyValue( aHoriOrientPropStr
, aHoriOrient
);
2616 // set x-position attribute
2617 aHoriPos
<<= rPosition
.X
;
2618 setPropertyValue( aHoriPosPropStr
, aHoriPos
);
2622 // handle y-position
2624 // determine current y-position
2625 static const OUStringLiteral
aVertPosPropStr(u
"VertOrientPosition");
2626 uno::Any
aVertPos( getPropertyValue( aVertPosPropStr
) );
2627 sal_Int32 dCurrY
= 0;
2628 aVertPos
>>= dCurrY
;
2629 // change y-position attribute, if needed
2630 if ( dCurrY
!= rPosition
.Y
)
2632 // adjust y-position orientation to text::VertOrientation::NONE, if needed
2633 // Note: has to be done before setting y-position attribute
2634 static const OUStringLiteral
aVertOrientPropStr(u
"VertOrient");
2635 uno::Any
aVertOrient( getPropertyValue( aVertOrientPropStr
) );
2636 sal_Int16 eVertOrient
;
2637 if (aVertOrient
>>= eVertOrient
) // may be void
2639 if ( eVertOrient
!= text::VertOrientation::NONE
)
2641 eVertOrient
= text::VertOrientation::NONE
;
2642 aVertOrient
<<= eVertOrient
;
2643 setPropertyValue( aVertOrientPropStr
, aVertOrient
);
2646 // set y-position attribute
2647 aVertPos
<<= rPosition
.Y
;
2648 setPropertyValue( aVertPosPropStr
, aVertPos
);
2653 /** method to convert start or end position of the drawing object to the
2654 Writer specific position, which is the attribute position in layout direction
2657 css::awt::Point
SwXShape::ConvertStartOrEndPosToLayoutDir(
2658 const css::awt::Point
& aStartOrEndPos
)
2660 awt::Point
aConvertedPos( aStartOrEndPos
);
2662 SvxShape
* pSvxShape
= GetSvxShape();
2663 OSL_ENSURE( pSvxShape
,
2664 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!");
2667 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2669 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!");
2672 // get position of object in Writer coordinate system.
2673 awt::Point
aPos( getPosition() );
2674 // get position of object in Drawing layer coordinate system
2675 const Point
aTmpObjPos( pObj
->GetSnapRect().TopLeft() );
2676 const awt::Point
aObjPos(
2677 convertTwipToMm100( aTmpObjPos
.X() - pObj
->GetAnchorPos().X() ),
2678 convertTwipToMm100( aTmpObjPos
.Y() - pObj
->GetAnchorPos().Y() ) );
2679 // determine difference between these positions according to the
2680 // Writer coordinate system
2681 const awt::Point
aTranslateDiff( aPos
.X
- aObjPos
.X
,
2682 aPos
.Y
- aObjPos
.Y
);
2683 // apply translation difference to transformation matrix.
2684 if ( aTranslateDiff
.X
!= 0 || aTranslateDiff
.Y
!= 0 )
2686 aConvertedPos
.X
= aConvertedPos
.X
+ aTranslateDiff
.X
;
2687 aConvertedPos
.Y
= aConvertedPos
.Y
+ aTranslateDiff
.Y
;
2692 return aConvertedPos
;
2695 css::drawing::PolyPolygonBezierCoords
SwXShape::ConvertPolyPolygonBezierToLayoutDir(
2696 const css::drawing::PolyPolygonBezierCoords
& aPath
)
2698 drawing::PolyPolygonBezierCoords
aConvertedPath( aPath
);
2700 SvxShape
* pSvxShape
= GetSvxShape();
2701 OSL_ENSURE( pSvxShape
,
2702 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!");
2705 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2707 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!");
2710 // get position of object in Writer coordinate system.
2711 awt::Point
aPos( getPosition() );
2712 // get position of object in Drawing layer coordinate system
2713 const Point
aTmpObjPos( pObj
->GetSnapRect().TopLeft() );
2714 const awt::Point
aObjPos(
2715 convertTwipToMm100( aTmpObjPos
.X() - pObj
->GetAnchorPos().X() ),
2716 convertTwipToMm100( aTmpObjPos
.Y() - pObj
->GetAnchorPos().Y() ) );
2717 // determine difference between these positions according to the
2718 // Writer coordinate system
2719 const awt::Point
aTranslateDiff( aPos
.X
- aObjPos
.X
,
2720 aPos
.Y
- aObjPos
.Y
);
2721 // apply translation difference to PolyPolygonBezier.
2722 if ( aTranslateDiff
.X
!= 0 || aTranslateDiff
.Y
!= 0 )
2724 const basegfx::B2DHomMatrix
aMatrix(basegfx::utils::createTranslateB2DHomMatrix(
2725 aTranslateDiff
.X
, aTranslateDiff
.Y
));
2727 for(drawing::PointSequence
& rInnerSequence
: asNonConstRange(aConvertedPath
.Coordinates
))
2729 for(awt::Point
& rPoint
: asNonConstRange(rInnerSequence
))
2731 basegfx::B2DPoint
aNewCoordinatePair(rPoint
.X
, rPoint
.Y
);
2732 aNewCoordinatePair
*= aMatrix
;
2733 rPoint
.X
= basegfx::fround(aNewCoordinatePair
.getX());
2734 rPoint
.Y
= basegfx::fround(aNewCoordinatePair
.getY());
2741 return aConvertedPath
;
2744 SwXGroupShape::SwXGroupShape(uno::Reference
<XInterface
> & xShape
,
2745 SwDoc
const*const pDoc
)
2746 : SwXShape(xShape
, pDoc
)
2748 #if OSL_DEBUG_LEVEL > 0
2749 uno::Reference
<XShapes
> xShapes(m_xShapeAgg
, uno::UNO_QUERY
);
2750 OSL_ENSURE(xShapes
.is(), "no SvxShape found or shape is not a group shape");
2754 SwXGroupShape::~SwXGroupShape()
2758 uno::Any
SwXGroupShape::queryInterface( const uno::Type
& rType
)
2761 if(rType
== cppu::UnoType
<XShapes
>::get())
2762 aRet
<<= uno::Reference
<XShapes
>(this);
2764 aRet
= SwXShape::queryInterface(rType
);
2768 void SwXGroupShape::acquire( ) noexcept
2770 SwXShape::acquire();
2773 void SwXGroupShape::release( ) noexcept
2775 SwXShape::release();
2778 void SwXGroupShape::add( const uno::Reference
< XShape
>& xShape
)
2780 SolarMutexGuard aGuard
;
2781 SvxShape
* pSvxShape
= GetSvxShape();
2782 SwFrameFormat
* pFormat
= GetFrameFormat();
2783 if(!(pSvxShape
&& pFormat
))
2784 throw uno::RuntimeException();
2786 uno::Reference
<XShapes
> xShapes
;
2787 if( m_xShapeAgg
.is() )
2789 const uno::Type
& rType
= cppu::UnoType
<XShapes
>::get();
2790 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2794 throw uno::RuntimeException();
2796 xShapes
->add(xShape
);
2799 uno::Reference
<lang::XUnoTunnel
> xTunnel(xShape
, uno::UNO_QUERY
);
2800 SwXShape
* pSwShape
= comphelper::getFromUnoTunnel
<SwXShape
>(xTunnel
);
2801 if(!(pSwShape
&& pSwShape
->m_bDescriptor
))
2804 SvxShape
* pAddShape
= comphelper::getFromUnoTunnel
<SvxShape
>(xTunnel
);
2807 SdrObject
* pObj
= pAddShape
->GetSdrObject();
2810 SwDoc
* pDoc
= pFormat
->GetDoc();
2811 // set layer of new drawing
2812 // object to corresponding invisible layer.
2813 if( SdrInventor::FmForm
!= pObj
->GetObjInventor())
2815 pObj
->SetLayer( pSwShape
->m_pImpl
->GetOpaque()
2816 ? pDoc
->getIDocumentDrawModelAccess().GetInvisibleHeavenId()
2817 : pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId() );
2821 pObj
->SetLayer(pDoc
->getIDocumentDrawModelAccess().GetInvisibleControlsId());
2825 pSwShape
->m_bDescriptor
= false;
2828 void SwXGroupShape::remove( const uno::Reference
< XShape
>& xShape
)
2830 SolarMutexGuard aGuard
;
2831 uno::Reference
<XShapes
> xShapes
;
2832 if( m_xShapeAgg
.is() )
2834 const uno::Type
& rType
= cppu::UnoType
<XShapes
>::get();
2835 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2839 throw uno::RuntimeException();
2840 xShapes
->remove(xShape
);
2843 sal_Int32
SwXGroupShape::getCount()
2845 SolarMutexGuard aGuard
;
2846 uno::Reference
<XIndexAccess
> xAcc
;
2847 if( m_xShapeAgg
.is() )
2849 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2850 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2854 throw uno::RuntimeException();
2855 return xAcc
->getCount();
2858 uno::Any
SwXGroupShape::getByIndex(sal_Int32 nIndex
)
2860 SolarMutexGuard aGuard
;
2861 uno::Reference
<XIndexAccess
> xAcc
;
2862 if( m_xShapeAgg
.is() )
2864 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2865 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2869 throw uno::RuntimeException();
2870 return xAcc
->getByIndex(nIndex
);
2873 uno::Type
SwXGroupShape::getElementType( )
2875 SolarMutexGuard aGuard
;
2876 uno::Reference
<XIndexAccess
> xAcc
;
2877 if( m_xShapeAgg
.is() )
2879 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2880 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2884 throw uno::RuntimeException();
2885 return xAcc
->getElementType();
2888 sal_Bool
SwXGroupShape::hasElements( )
2890 SolarMutexGuard aGuard
;
2891 uno::Reference
<XIndexAccess
> xAcc
;
2892 if( m_xShapeAgg
.is() )
2894 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2895 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2899 throw uno::RuntimeException();
2900 return xAcc
->hasElements();
2903 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */