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 <crstate.hxx>
64 #include <comphelper/extract.hxx>
65 #include <comphelper/profilezone.hxx>
66 #include <comphelper/sequence.hxx>
67 #include <cppuhelper/supportsservice.hxx>
68 #include <svx/scene3d.hxx>
69 #include <tools/UnitConversion.hxx>
70 #include <com/sun/star/beans/PropertyAttribute.hpp>
71 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
72 #include <com/sun/star/frame/XModel.hpp>
73 #include <fmtwrapinfluenceonobjpos.hxx>
74 #include <com/sun/star/text/TextContentAnchorType.hpp>
75 #include <basegfx/matrix/b2dhommatrixtools.hxx>
76 #include <com/sun/star/drawing/PointSequence.hpp>
77 #include <com/sun/star/lang/IllegalArgumentException.hpp>
78 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
79 #include <docmodel/uno/UnoTheme.hxx>
81 using namespace ::com::sun::star
;
83 class SwShapeDescriptor_Impl
86 std::unique_ptr
<SwFormatHoriOrient
> m_pHOrient
;
87 std::unique_ptr
<SwFormatVertOrient
> m_pVOrient
;
88 std::unique_ptr
<SwFormatAnchor
> m_pAnchor
;
89 std::unique_ptr
<SwFormatSurround
> m_pSurround
;
90 std::unique_ptr
<SvxULSpaceItem
> m_pULSpace
;
91 std::unique_ptr
<SvxLRSpaceItem
> m_pLRSpace
;
93 uno::Reference
< text::XTextRange
> m_xTextRange
;
95 std::unique_ptr
<SwFormatFollowTextFlow
> m_pFollowTextFlow
;
97 std::unique_ptr
<SwFormatWrapInfluenceOnObjPos
> m_pWrapInfluenceOnObjPos
;
99 sal_Int16 mnPositionLayoutDir
;
101 SwShapeDescriptor_Impl(const SwShapeDescriptor_Impl
&) = delete;
102 SwShapeDescriptor_Impl
& operator=(const SwShapeDescriptor_Impl
&) = delete;
105 SwShapeDescriptor_Impl(SwDoc
const*const pDoc
)
106 : m_isInReading(pDoc
&& pDoc
->IsInReading())
107 // #i32349# - no defaults, in order to determine on
108 // adding a shape, if positioning attributes are set or not.
111 , m_pFollowTextFlow( new SwFormatFollowTextFlow(false) )
113 , m_pWrapInfluenceOnObjPos( new SwFormatWrapInfluenceOnObjPos(
114 text::WrapInfluenceOnPosition::ONCE_CONCURRENT
) )
116 , mnPositionLayoutDir(text::PositionLayoutDir::PositionInLayoutDirOfAnchor
)
119 SwFormatAnchor
* GetAnchor(bool bCreate
= false)
121 if (bCreate
&& !m_pAnchor
)
123 m_pAnchor
.reset(new SwFormatAnchor(RndStdIds::FLY_AS_CHAR
));
125 return m_pAnchor
.get();
127 SwFormatHoriOrient
* GetHOrient(bool bCreate
= false)
129 if (bCreate
&& !m_pHOrient
)
132 m_pHOrient
.reset(new SwFormatHoriOrient(0, text::HoriOrientation::NONE
, text::RelOrientation::FRAME
));
134 return m_pHOrient
.get();
136 SwFormatVertOrient
* GetVOrient(bool bCreate
= false)
138 if (bCreate
&& !m_pVOrient
)
140 if (m_isInReading
&& // tdf#113938 extensions might rely on old default
141 (!GetAnchor(true) || m_pAnchor
->GetAnchorId() == RndStdIds::FLY_AS_CHAR
))
142 { // for as-char, NONE ("from-top") is not a good default
143 m_pVOrient
.reset(new SwFormatVertOrient(0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
));
147 m_pVOrient
.reset(new SwFormatVertOrient(0, text::VertOrientation::NONE
, text::RelOrientation::FRAME
));
150 return m_pVOrient
.get();
153 SwFormatSurround
* GetSurround(bool bCreate
= false)
155 if (bCreate
&& !m_pSurround
)
157 m_pSurround
.reset(new SwFormatSurround());
159 return m_pSurround
.get();
161 SvxLRSpaceItem
* GetLRSpace(bool bCreate
= false)
163 if (bCreate
&& !m_pLRSpace
)
165 m_pLRSpace
.reset(new SvxLRSpaceItem(RES_LR_SPACE
));
167 return m_pLRSpace
.get();
169 SvxULSpaceItem
* GetULSpace(bool bCreate
= false)
171 if (bCreate
&& !m_pULSpace
)
173 m_pULSpace
.reset(new SvxULSpaceItem(RES_UL_SPACE
));
175 return m_pULSpace
.get();
177 uno::Reference
< text::XTextRange
> & GetTextRange()
181 bool IsOpaque() const
185 const bool& GetOpaque() const
189 void RemoveHOrient() { m_pHOrient
.reset(); }
190 void RemoveVOrient() { m_pVOrient
.reset(); }
191 void RemoveAnchor() { m_pAnchor
.reset(); }
192 void RemoveSurround() { m_pSurround
.reset(); }
193 void RemoveULSpace() { m_pULSpace
.reset(); }
194 void RemoveLRSpace() { m_pLRSpace
.reset(); }
195 void SetOpaque(bool bSet
){m_bOpaque
= bSet
;}
198 SwFormatFollowTextFlow
* GetFollowTextFlow( bool _bCreate
= false )
200 if (_bCreate
&& !m_pFollowTextFlow
)
202 m_pFollowTextFlow
.reset(new SwFormatFollowTextFlow(false));
204 return m_pFollowTextFlow
.get();
206 void RemoveFollowTextFlow()
208 m_pFollowTextFlow
.reset();
212 sal_Int16
GetPositionLayoutDir() const
214 return mnPositionLayoutDir
;
216 void SetPositionLayoutDir( sal_Int16 _nPositionLayoutDir
)
218 switch ( _nPositionLayoutDir
)
220 case text::PositionLayoutDir::PositionInHoriL2R
:
221 case text::PositionLayoutDir::PositionInLayoutDirOfAnchor
:
223 mnPositionLayoutDir
= _nPositionLayoutDir
;
228 OSL_FAIL( "<SwShapeDescriptor_Impl::SetPositionLayoutDir(..)> - invalid attribute value." );
234 SwFormatWrapInfluenceOnObjPos
* GetWrapInfluenceOnObjPos(
235 const bool _bCreate
= false )
237 if (_bCreate
&& !m_pWrapInfluenceOnObjPos
)
239 m_pWrapInfluenceOnObjPos
.reset(new SwFormatWrapInfluenceOnObjPos(
241 text::WrapInfluenceOnPosition::ONCE_CONCURRENT
));
243 return m_pWrapInfluenceOnObjPos
.get();
245 void RemoveWrapInfluenceOnObjPos()
247 m_pWrapInfluenceOnObjPos
.reset();
251 SwFmDrawPage::SwFmDrawPage( SwDoc
* pDoc
, SdrPage
* pPage
)
252 : SwFmDrawPage_Base(pPage
)
254 , m_pPageView(nullptr)
255 , m_pPropertySet(aSwMapProvider
.GetPropertySet(PROPERTY_MAP_TEXT_PAGE
))
259 SwFmDrawPage::~SwFmDrawPage() noexcept
261 while (!m_vShapes
.empty())
262 m_vShapes
.back()->dispose();
266 const SdrMarkList
& SwFmDrawPage::PreGroup(const uno::Reference
< drawing::XShapes
> & xShapes
)
268 SelectObjectsInView( xShapes
, GetPageView() );
269 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
273 void SwFmDrawPage::PreUnGroup(const uno::Reference
< drawing::XShapeGroup
>& rShapeGroup
)
275 SelectObjectInView( rShapeGroup
, GetPageView() );
278 SdrPageView
* SwFmDrawPage::GetPageView()
281 m_pPageView
= mpView
->ShowSdrPage( mpPage
);
285 void SwFmDrawPage::RemovePageView()
287 if(m_pPageView
&& mpView
)
288 mpView
->HideSdrPage();
289 m_pPageView
= nullptr;
292 uno::Reference
<drawing::XShape
> SwFmDrawPage::GetShape(SdrObject
* pObj
)
296 SwFrameFormat
* pFormat
= ::FindFrameFormat( pObj
);
297 // TODO see comment at
298 // <https://gerrit.libreoffice.org/c/core/+/78734/4#message-5ee4e724a8073c5c475f07da0b5d79bc34e61de5>
299 // "make page bookkeep the SwXShapes" [-loplugin:crosscast]:
300 SwFmDrawPage
* pPage
= dynamic_cast<SwFmDrawPage
*>(pFormat
);
301 if(!pPage
|| pPage
->m_vShapes
.empty())
302 return uno::Reference
<drawing::XShape
>(pObj
->getUnoShape(), uno::UNO_QUERY
);
303 for(const auto & pShape
: pPage
->m_vShapes
)
305 SvxShape
* pSvxShape
= pShape
->GetSvxShape();
306 if (pSvxShape
&& pSvxShape
->GetSdrObject() == pObj
)
312 uno::Reference
<drawing::XShapeGroup
> SwFmDrawPage::GetShapeGroup(SdrObject
* pObj
)
314 return uno::Reference
<drawing::XShapeGroup
>(GetShape(pObj
), uno::UNO_QUERY
);
317 uno::Reference
< drawing::XShape
> SwFmDrawPage::CreateShape( SdrObject
*pObj
) const
320 uno::Reference
< drawing::XShape
> xRet
;
321 if(dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) != nullptr || pObj
->GetObjInventor() == SdrInventor::Swg
)
323 SwFlyDrawContact
* pFlyContact
= static_cast<SwFlyDrawContact
*>(pObj
->GetUserCall());
326 SwFrameFormat
* pFlyFormat
= pFlyContact
->GetFormat();
327 SwDoc
* pDoc
= pFlyFormat
->GetDoc();
328 const SwNodeIndex
* pIdx
;
329 if( RES_FLYFRMFMT
== pFlyFormat
->Which()
330 && nullptr != ( pIdx
= pFlyFormat
->GetContent().GetContentIdx() )
331 && pIdx
->GetNodes().IsDocNodes()
334 const SwNode
* pNd
= pDoc
->GetNodes()[ pIdx
->GetIndex() + 1 ];
335 if(!pNd
->IsNoTextNode())
337 xRet
.set(cppu::getXWeak(SwXTextFrame::CreateXTextFrame(*pDoc
, pFlyFormat
).get()),
340 else if( pNd
->IsGrfNode() )
342 xRet
.set(cppu::getXWeak(SwXTextGraphicObject::CreateXTextGraphicObject(
343 *pDoc
, pFlyFormat
).get()), uno::UNO_QUERY
);
345 else if( pNd
->IsOLENode() )
347 xRet
.set(cppu::getXWeak(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
348 *pDoc
, pFlyFormat
).get()), uno::UNO_QUERY
);
353 OSL_FAIL( "<SwFmDrawPage::CreateShape(..)> - could not retrieve type. Thus, no shape created." );
360 // own block - temporary object has to be destroyed before
361 // the delegator is set #81670#
363 xRet
= SvxDrawPage::CreateShape( pObj
);
365 uno::Reference
< XUnoTunnel
> xShapeTunnel(xRet
, uno::UNO_QUERY
);
366 //don't create an SwXShape if it already exists
367 rtl::Reference
<SwXShape
> pShape
= comphelper::getFromUnoTunnel
<SwXShape
>(xShapeTunnel
);
370 xShapeTunnel
= nullptr;
371 uno::Reference
< uno::XInterface
> xCreate(xRet
, uno::UNO_QUERY
);
373 if ( pObj
->IsGroupObject() && (!pObj
->Is3DObj() || DynCastE3dScene(pObj
)) )
374 pShape
= new SwXGroupShape(xCreate
, nullptr);
376 pShape
= new SwXShape(xCreate
, nullptr);
379 const_cast<std::vector
<rtl::Reference
<SwXShape
>>*>(&m_vShapes
)->push_back(pShape
);
380 pShape
->m_pPage
= this;
385 uno::Reference
<beans::XPropertySetInfo
> SwFmDrawPage::getPropertySetInfo()
387 static uno::Reference
<beans::XPropertySetInfo
> xRet
= m_pPropertySet
->getPropertySetInfo();
391 void SwFmDrawPage::setPropertyValue(const OUString
& rPropertyName
, const uno::Any
& aValue
)
393 SolarMutexGuard aGuard
;
394 const SfxItemPropertyMapEntry
* pEntry
= m_pPropertySet
->getPropertyMap().getByName(rPropertyName
);
396 switch (pEntry
? pEntry
->nWID
: -1)
400 SdrPage
* pPage
= GetSdrPage();
401 css::uno::Reference
<css::util::XTheme
> xTheme
;
402 if (aValue
>>= xTheme
)
404 auto& rUnoTheme
= dynamic_cast<UnoTheme
&>(*xTheme
);
405 pPage
->getSdrModelFromSdrPage().setTheme(rUnoTheme
.getTheme());
409 case WID_PAGE_BOTTOM
:
414 case WID_PAGE_HEIGHT
:
415 case WID_PAGE_NUMBER
:
416 case WID_PAGE_ORIENT
:
417 case WID_PAGE_USERATTRIBS
:
418 case WID_PAGE_ISDARK
:
420 case WID_PAGE_BACKFULL
:
424 throw beans::UnknownPropertyException(rPropertyName
, getXWeak());
428 uno::Any
SwFmDrawPage::getPropertyValue(const OUString
& rPropertyName
)
430 SolarMutexGuard aGuard
;
431 const SfxItemPropertyMapEntry
* pEntry
= m_pPropertySet
->getPropertyMap().getByName( rPropertyName
);
435 switch (pEntry
? pEntry
->nWID
: -1)
439 css::uno::Reference
<css::util::XTheme
> xTheme
;
441 auto pTheme
= GetSdrPage()->getSdrModelFromSdrPage().getTheme();
443 xTheme
= model::theme::createXTheme(pTheme
);
448 case WID_PAGE_NUMBER
:
450 const sal_uInt16
nPageNumber(GetSdrPage()->GetPageNum());
451 aAny
<<= o3tl::narrowing
<sal_Int16
>(nPageNumber
);
455 case WID_PAGE_BOTTOM
:
460 case WID_PAGE_HEIGHT
:
461 case WID_PAGE_ORIENT
:
462 case WID_PAGE_USERATTRIBS
:
463 case WID_PAGE_ISDARK
:
465 case WID_PAGE_BACKFULL
:
469 throw beans::UnknownPropertyException(rPropertyName
, getXWeak());
474 void SwFmDrawPage::addPropertyChangeListener(const OUString
& /*PropertyName*/,
475 const uno::Reference
<beans::XPropertyChangeListener
> & /*aListener*/)
477 OSL_FAIL("not implemented");
480 void SwFmDrawPage::removePropertyChangeListener(const OUString
& /*PropertyName*/,
481 const uno::Reference
<beans::XPropertyChangeListener
> & /*aListener*/)
483 OSL_FAIL("not implemented");
486 void SwFmDrawPage::addVetoableChangeListener(const OUString
& /*PropertyName*/,
487 const uno::Reference
<beans::XVetoableChangeListener
> & /*aListener*/)
489 OSL_FAIL("not implemented");
492 void SwFmDrawPage::removeVetoableChangeListener(const OUString
& /*PropertyName*/,
493 const uno::Reference
<beans::XVetoableChangeListener
> & /*aListener*/)
495 OSL_FAIL("not implemented");
500 class SwXShapesEnumeration
501 : public SwSimpleEnumeration_Base
504 std::vector
< css::uno::Any
> m_aShapes
;
506 virtual ~SwXShapesEnumeration() override
{};
508 explicit SwXShapesEnumeration(SwFmDrawPage
* const pDrawPage
);
511 virtual sal_Bool SAL_CALL
hasMoreElements() override
;
512 virtual uno::Any SAL_CALL
nextElement() override
;
515 virtual OUString SAL_CALL
getImplementationName() override
;
516 virtual sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
517 virtual uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
;
521 SwXShapesEnumeration::SwXShapesEnumeration(SwFmDrawPage
* const pDrawPage
)
523 SolarMutexGuard aGuard
;
524 sal_Int32 nCount
= pDrawPage
->getCount();
525 m_aShapes
.reserve(nCount
);
526 for(sal_Int32 nIdx
= 0; nIdx
< nCount
; nIdx
++)
528 uno::Reference
<drawing::XShape
> xShape(pDrawPage
->getByIndex(nIdx
), uno::UNO_QUERY
);
529 m_aShapes
.push_back(uno::Any(xShape
));
533 sal_Bool
SwXShapesEnumeration::hasMoreElements()
535 SolarMutexGuard aGuard
;
536 return !m_aShapes
.empty();
539 uno::Any
SwXShapesEnumeration::nextElement()
541 SolarMutexGuard aGuard
;
542 if(m_aShapes
.empty())
543 throw container::NoSuchElementException();
544 uno::Any aResult
= m_aShapes
.back();
545 m_aShapes
.pop_back();
549 OUString
SwXShapesEnumeration::getImplementationName()
551 return u
"SwXShapeEnumeration"_ustr
;
554 sal_Bool
SwXShapesEnumeration::supportsService(const OUString
& ServiceName
)
556 return cppu::supportsService(this, ServiceName
);
559 uno::Sequence
< OUString
> SwXShapesEnumeration::getSupportedServiceNames()
561 return { u
"com.sun.star.container.XEnumeration"_ustr
};
564 uno::Reference
< container::XEnumeration
> SwFmDrawPage::createEnumeration()
566 SolarMutexGuard aGuard
;
567 return uno::Reference
< container::XEnumeration
>(
568 new SwXShapesEnumeration(this));
571 OUString
SwFmDrawPage::getImplementationName()
573 return u
"SwFmDrawPage"_ustr
;
576 sal_Bool
SwFmDrawPage::supportsService(const OUString
& rServiceName
)
578 return cppu::supportsService(this, rServiceName
);
581 uno::Sequence
< OUString
> SwFmDrawPage::getSupportedServiceNames()
583 return { u
"com.sun.star.drawing.GenericDrawPage"_ustr
};
586 sal_Int32
SwFmDrawPage::getCount()
588 SolarMutexGuard aGuard
;
590 throw uno::RuntimeException();
591 if(!m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
594 return SwTextBoxHelper::getCount(GetSdrPage());
597 uno::Any
SwFmDrawPage::getByIndex(sal_Int32 nIndex
)
599 SolarMutexGuard aGuard
;
601 throw uno::RuntimeException();
602 if(!m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
603 throw lang::IndexOutOfBoundsException();
605 return SwTextBoxHelper::getByIndex(GetSdrPage(), nIndex
);
608 uno::Type
SwFmDrawPage::getElementType()
610 return cppu::UnoType
<drawing::XShape
>::get();
613 sal_Bool
SwFmDrawPage::hasElements()
615 SolarMutexGuard aGuard
;
617 throw uno::RuntimeException();
618 if(!m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
620 return SvxDrawPage::hasElements();
623 void SwFmDrawPage::add(const uno::Reference
< drawing::XShape
> & xShape
)
625 SolarMutexGuard aGuard
;
627 throw uno::RuntimeException();
628 uno::Reference
< lang::XUnoTunnel
> xShapeTunnel(xShape
, uno::UNO_QUERY
);
629 SwXShape
* pShape
= comphelper::getFromUnoTunnel
<SwXShape
>(xShapeTunnel
);
630 SvxShape
* pSvxShape
= comphelper::getFromUnoTunnel
<SvxShape
>(xShapeTunnel
);
632 // this is not a writer shape
634 throw uno::RuntimeException(u
"illegal object"_ustr
,
637 // we're already registered in the model / SwXDrawPage::add() already called
638 if(pShape
->m_pPage
|| !pShape
->m_bDescriptor
)
641 // we're inserted elsewhere already
642 if ( pSvxShape
->GetSdrObject() )
644 if ( pSvxShape
->GetSdrObject()->IsInserted() )
649 SvxDrawPage::add(xShape
);
651 OSL_ENSURE(pSvxShape
, "Why is here no SvxShape?");
652 // this position is definitely in 1/100 mm
653 awt::Point
aMM100Pos(pSvxShape
->getPosition());
655 // now evaluate the properties of SwShapeDescriptor_Impl
656 SwShapeDescriptor_Impl
* pDesc
= pShape
->GetDescImpl();
658 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1> aSet( m_pDoc
->GetAttrPool() );
659 SwFormatAnchor
aAnchor( RndStdIds::FLY_AS_CHAR
);
660 bool bOpaque
= false;
663 if(pDesc
->GetSurround())
664 aSet
.Put( *pDesc
->GetSurround());
665 // all items are already in Twip
666 if(pDesc
->GetLRSpace())
668 aSet
.Put(*pDesc
->GetLRSpace());
670 if(pDesc
->GetULSpace())
672 aSet
.Put(*pDesc
->GetULSpace());
674 if(pDesc
->GetAnchor())
675 aAnchor
= *pDesc
->GetAnchor();
677 // #i32349# - if no horizontal position exists, create one
678 if ( !pDesc
->GetHOrient() )
680 SwFormatHoriOrient
* pHori
= pDesc
->GetHOrient( true );
681 SwTwips nHoriPos
= o3tl::toTwips(aMM100Pos
.X
, o3tl::Length::mm100
);
682 pHori
->SetPos( nHoriPos
);
685 if(pDesc
->GetHOrient()->GetHoriOrient() == text::HoriOrientation::NONE
)
686 aMM100Pos
.X
= convertTwipToMm100(pDesc
->GetHOrient()->GetPos());
687 aSet
.Put( *pDesc
->GetHOrient() );
689 // #i32349# - if no vertical position exists, create one
690 if ( !pDesc
->GetVOrient() )
692 SwFormatVertOrient
* pVert
= pDesc
->GetVOrient( true );
693 SwTwips nVertPos
= o3tl::toTwips(aMM100Pos
.Y
, o3tl::Length::mm100
);
694 pVert
->SetPos( nVertPos
);
697 if(pDesc
->GetVOrient()->GetVertOrient() == text::VertOrientation::NONE
)
698 aMM100Pos
.Y
= convertTwipToMm100(pDesc
->GetVOrient()->GetPos());
699 aSet
.Put( *pDesc
->GetVOrient() );
702 if(pDesc
->GetSurround())
703 aSet
.Put( *pDesc
->GetSurround());
704 bOpaque
= pDesc
->IsOpaque();
707 if ( pDesc
->GetFollowTextFlow() )
709 aSet
.Put( *pDesc
->GetFollowTextFlow() );
713 if ( pDesc
->GetWrapInfluenceOnObjPos() )
715 aSet
.Put( *pDesc
->GetWrapInfluenceOnObjPos() );
719 pSvxShape
->setPosition(aMM100Pos
);
720 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
721 // #108784# - set layer of new drawing object to corresponding
723 if(SdrInventor::FmForm
!= pObj
->GetObjInventor())
724 pObj
->SetLayer( bOpaque
? m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleHeavenId() : m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId() );
726 pObj
->SetLayer(m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleControlsId());
728 std::optional
<SwPaM
> pPam(m_pDoc
->GetNodes().GetEndOfContent());
729 std::unique_ptr
<SwUnoInternalPaM
> pInternalPam
;
730 uno::Reference
< text::XTextRange
> xRg
;
731 if( pDesc
&& (xRg
= pDesc
->GetTextRange()).is() )
733 pInternalPam
.reset(new SwUnoInternalPaM(*m_pDoc
));
734 if (!::sw::XTextRangeToSwPaM(*pInternalPam
, xRg
))
735 throw uno::RuntimeException();
737 if(RndStdIds::FLY_AT_FLY
== aAnchor
.GetAnchorId() &&
738 !pInternalPam
->GetPointNode().FindFlyStartNode())
740 aAnchor
.SetType(RndStdIds::FLY_AS_CHAR
);
742 else if (RndStdIds::FLY_AT_PAGE
== aAnchor
.GetAnchorId()
743 && 0 == aAnchor
.GetPageNum())
745 aAnchor
.SetAnchor(pInternalPam
->Start());
746 aAnchor
.SetType(RndStdIds::FLY_AT_CHAR
); // convert invalid at-page
750 else if ((aAnchor
.GetAnchorId() != RndStdIds::FLY_AT_PAGE
) && m_pDoc
->getIDocumentLayoutAccess().GetCurrentLayout())
752 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
753 Point
aTmp(o3tl::toTwips(aMM100Pos
.X
, o3tl::Length::mm100
), o3tl::toTwips(aMM100Pos
.Y
, o3tl::Length::mm100
));
754 m_pDoc
->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( pPam
->GetPoint(), aTmp
, &aState
);
755 aAnchor
.SetAnchor( pPam
->GetPoint() );
757 // #i32349# - adjustment of vertical positioning
758 // attributes no longer needed, because it's already got a default.
762 aAnchor
.SetType(RndStdIds::FLY_AT_PAGE
);
764 // #i32349# - adjustment of vertical positioning
765 // attributes no longer needed, because it's already got a default.
768 SwPaM
* pTemp
= pInternalPam
.get();
771 UnoActionContext
aAction(m_pDoc
);
772 m_pDoc
->getIDocumentContentOperations().InsertDrawObj( *pTemp
, *pObj
, aSet
);
774 if (pSvxShape
->GetSdrObject()->GetName().isEmpty())
776 pSvxShape
->GetSdrObject()->SetName(m_pDoc
->GetUniqueShapeName());
779 SwFrameFormat
* pFormat
= ::FindFrameFormat( pObj
);
782 if (pFormat
->GetName().isEmpty())
784 pFormat
->SetFormatName(pSvxShape
->GetSdrObject()->GetName(), false);
787 pShape
->m_bDescriptor
= false;
790 pInternalPam
.reset();
793 void SwFmDrawPage::remove(const uno::Reference
< drawing::XShape
> & xShape
)
795 SolarMutexGuard aGuard
;
797 throw uno::RuntimeException();
798 // tdf#41466 remove TextFrame too which is belonged to the actual shape
799 auto xTextFrame
= SwTextBoxHelper::getUnoTextFrame(xShape
);
802 uno::Reference
<lang::XComponent
> xComp(xTextFrame
, uno::UNO_QUERY
);
807 uno::Reference
<lang::XComponent
> xComp(xShape
, uno::UNO_QUERY
);
811 uno::Reference
< drawing::XShapeGroup
> SwFmDrawPage::group(const uno::Reference
< drawing::XShapes
> & xShapes
)
813 SolarMutexGuard aGuard
;
814 if(!m_pDoc
|| !xShapes
.is())
815 throw uno::RuntimeException();
816 uno::Reference
< drawing::XShapeGroup
> xRet
;
817 // mark and return MarkList
818 const SdrMarkList
& rMarkList
= PreGroup(xShapes
);
819 if ( rMarkList
.GetMarkCount() > 0 )
821 for (size_t i
= 0; i
< rMarkList
.GetMarkCount(); ++i
)
823 const SdrObject
*pObj
= rMarkList
.GetMark( i
)->GetMarkedSdrObj();
824 if (RndStdIds::FLY_AS_CHAR
== ::FindFrameFormat(const_cast<SdrObject
*>(
825 pObj
))->GetAnchor().GetAnchorId())
827 throw lang::IllegalArgumentException(
828 u
"Shape must not have 'as character' anchor!"_ustr
, nullptr, 0);
832 UnoActionContext
aContext(m_pDoc
);
833 m_pDoc
->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
835 SwDrawContact
* pContact
= m_pDoc
->GroupSelection( *GetDrawView() );
837 GetDrawView()->GetMarkedObjectList(),
838 RndStdIds::FLY_AT_PARA
,
841 GetDrawView()->UnmarkAll();
843 xRet
= SwFmDrawPage::GetShapeGroup( pContact
->GetMaster() );
844 m_pDoc
->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
850 void SwFmDrawPage::ungroup(const uno::Reference
< drawing::XShapeGroup
> & rShapeGroup
)
852 SolarMutexGuard aGuard
;
854 throw uno::RuntimeException();
856 PreUnGroup(rShapeGroup
);
857 UnoActionContext
aContext(m_pDoc
);
858 m_pDoc
->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
860 m_pDoc
->UnGroupSelection( *GetDrawView() );
861 m_pDoc
->ChgAnchor( GetDrawView()->GetMarkedObjectList(),
862 RndStdIds::FLY_AT_PARA
,
864 m_pDoc
->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
869 * Renamed and outlined to detect where it's called
871 void SwFmDrawPage::InvalidateSwDoc()
876 const uno::Sequence
< sal_Int8
> & SwXShape::getUnoTunnelId()
878 static const comphelper::UnoIdInit theSwXShapeUnoTunnelId
;
879 return theSwXShapeUnoTunnelId
.getSeq();
882 sal_Int64 SAL_CALL
SwXShape::getSomething( const uno::Sequence
< sal_Int8
>& rId
)
884 if( comphelper::isUnoTunnelId
<SwXShape
>(rId
) )
886 return comphelper::getSomething_cast(this);
889 if( m_xShapeAgg
.is() )
891 const uno::Type
& rTunnelType
= cppu::UnoType
<lang::XUnoTunnel
>::get();
892 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rTunnelType
);
893 if(auto xAggTunnel
= o3tl::tryAccess
<uno::Reference
<lang::XUnoTunnel
>>(
897 return (*xAggTunnel
)->getSomething(rId
);
904 uno::Reference
<uno::XInterface
> & xShape
,
905 SwDoc
const*const pDoc
)
907 , m_pPropSet(aSwMapProvider
.GetPropertySet(PROPERTY_MAP_TEXT_SHAPE
))
908 , m_pPropertyMapEntries(aSwMapProvider
.GetPropertyMapEntries(PROPERTY_MAP_TEXT_SHAPE
))
909 , m_pImpl(new SwShapeDescriptor_Impl(pDoc
))
910 , m_bDescriptor(true)
912 if(!xShape
.is()) // default Ctor
915 const uno::Type
& rAggType
= cppu::UnoType
<uno::XAggregation
>::get();
916 //aAgg contains a reference of the SvxShape!
918 uno::Any aAgg
= xShape
->queryInterface(rAggType
);
919 aAgg
>>= m_xShapeAgg
;
921 if ( m_xShapeAgg
.is() )
923 m_xShapeAgg
->queryAggregation( cppu::UnoType
<drawing::XShape
>::get()) >>= mxShape
;
924 OSL_ENSURE( mxShape
.is(),
925 "<SwXShape::SwXShape(..)> - no XShape found at <xShapeAgg>" );
929 osl_atomic_increment(&m_refCount
);
930 if( m_xShapeAgg
.is() )
931 m_xShapeAgg
->setDelegator( getXWeak() );
932 osl_atomic_decrement(&m_refCount
);
935 SwFrameFormat
* SwXShape::GetFrameFormat() const
937 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(m_xShapeAgg
);
939 return ::FindFrameFormat( pObj
);
943 void SwXShape::AddExistingShapeToFormat( SdrObject
const & _rObj
)
945 SdrObjListIter
aIter( _rObj
, SdrIterMode::DeepNoGroups
);
946 while ( aIter
.IsMore() )
948 SdrObject
* pCurrent
= aIter
.Next();
949 OSL_ENSURE( pCurrent
, "SwXShape::AddExistingShapeToFormat: invalid object list element!" );
953 auto pSwShape
= comphelper::getFromUnoTunnel
<SwXShape
>(pCurrent
->getWeakUnoShape());
956 if ( pSwShape
->m_bDescriptor
)
957 pSwShape
->m_bDescriptor
= false;
962 SwXShape::~SwXShape()
964 SolarMutexGuard aGuard
;
966 if (m_xShapeAgg
.is())
968 uno::Reference
< uno::XInterface
> xRef
;
969 m_xShapeAgg
->setDelegator(xRef
);
973 const_cast<SwFmDrawPage
*>(m_pPage
)->RemoveShape(this);
976 uno::Any
SwXShape::queryInterface( const uno::Type
& aType
)
979 SdrObject
* pObj
= nullptr;
981 if ((aType
== cppu::UnoType
<text::XText
>::get())
982 || (aType
== cppu::UnoType
<text::XTextRange
>::get())
983 || (aType
== cppu::UnoType
<text::XTextAppend
>::get()))
985 pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
987 aRet
= SwTextBoxHelper::queryInterface(GetFrameFormat(), aType
, pObj
);
991 aRet
= SwXShapeBaseClass::queryInterface(aType
);
992 // #i53320# - follow-up of #i31698#
993 // interface drawing::XShape is overloaded. Thus, provide
994 // correct object instance.
995 if(!aRet
.hasValue() && m_xShapeAgg
.is())
997 if(aType
== cppu::UnoType
<XShape
>::get())
998 aRet
<<= uno::Reference
<XShape
>(this);
1000 aRet
= m_xShapeAgg
->queryAggregation(aType
);
1005 uno::Sequence
< uno::Type
> SwXShape::getTypes( )
1007 uno::Sequence
< uno::Type
> aRet
= SwXShapeBaseClass::getTypes();
1008 if(m_xShapeAgg
.is())
1010 uno::Any aProv
= m_xShapeAgg
->queryAggregation(cppu::UnoType
<XTypeProvider
>::get());
1011 if(aProv
.hasValue())
1013 uno::Reference
< XTypeProvider
> xAggProv
;
1015 return comphelper::concatSequences(aRet
, xAggProv
->getTypes());
1021 uno::Sequence
< sal_Int8
> SwXShape::getImplementationId( )
1023 return css::uno::Sequence
<sal_Int8
>();
1026 uno::Reference
< beans::XPropertySetInfo
> SwXShape::getPropertySetInfo()
1028 SolarMutexGuard aGuard
;
1029 if (!mxPropertySetInfo
)
1031 if(m_xShapeAgg
.is())
1033 const uno::Type
& rPropSetType
= cppu::UnoType
<beans::XPropertySet
>::get();
1034 uno::Any aPSet
= m_xShapeAgg
->queryAggregation( rPropSetType
);
1035 if(auto xPrSet
= o3tl::tryAccess
<uno::Reference
<beans::XPropertySet
>>(
1038 uno::Reference
< beans::XPropertySetInfo
> xInfo
= (*xPrSet
)->getPropertySetInfo();
1039 // Expand PropertySetInfo!
1040 const uno::Sequence
<beans::Property
> aPropSeq
= xInfo
->getProperties();
1041 mxPropertySetInfo
= new SfxExtItemPropertySetInfo( m_pPropertyMapEntries
, aPropSeq
);
1044 if(!mxPropertySetInfo
)
1045 mxPropertySetInfo
= m_pPropSet
->getPropertySetInfo();
1047 return mxPropertySetInfo
;
1050 void SwXShape::setPropertyValue(const OUString
& rPropertyName
, const uno::Any
& aValue
)
1052 SolarMutexGuard aGuard
;
1053 SwFrameFormat
* pFormat
= GetFrameFormat();
1054 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
1055 if(!m_xShapeAgg
.is())
1060 if ( pEntry
->nFlags
& beans::PropertyAttribute::READONLY
)
1061 throw beans::PropertyVetoException ("Property is read-only: " + rPropertyName
, getXWeak() );
1062 // with the layout it is possible to move the anchor without changing the position
1065 SwAttrSet
aSet(pFormat
->GetAttrSet());
1066 SwDoc
* pDoc
= pFormat
->GetDoc();
1067 if(RES_ANCHOR
== pEntry
->nWID
&& MID_ANCHOR_ANCHORFRAME
== pEntry
->nMemberId
)
1070 uno::Reference
<text::XTextFrame
> xFrame
;
1071 if(aValue
>>= xFrame
)
1073 SwXFrame
* pFrame
= dynamic_cast<SwXFrame
*>(xFrame
.get());
1074 if(pFrame
&& pFrame
->GetFrameFormat() &&
1075 pFrame
->GetFrameFormat()->GetDoc() == pDoc
)
1077 UnoActionContext
aCtx(pDoc
);
1078 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
- 1> aItemSet( pDoc
->GetAttrPool() );
1079 aItemSet
.SetParent(&pFormat
->GetAttrSet());
1080 SwFormatAnchor aAnchor
= static_cast<const SwFormatAnchor
&>(aItemSet
.Get(pEntry
->nWID
));
1081 SwPosition
aPos(*pFrame
->GetFrameFormat()->GetContent().GetContentIdx());
1082 aAnchor
.SetAnchor(&aPos
);
1083 aAnchor
.SetType(RndStdIds::FLY_AT_FLY
);
1084 aItemSet
.Put(aAnchor
);
1085 pFormat
->SetFormatAttr(aItemSet
);
1090 throw lang::IllegalArgumentException();
1092 else if(RES_OPAQUE
== pEntry
->nWID
)
1094 SvxShape
* pSvxShape
= GetSvxShape();
1095 SAL_WARN_IF(!pSvxShape
, "sw.uno", "No SvxShape found!");
1098 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1099 // set layer of new drawing
1100 // object to corresponding invisible layer.
1101 bool bIsVisible
= pDoc
->getIDocumentDrawModelAccess().IsVisibleLayerId( pObj
->GetLayer() );
1102 if(SdrInventor::FmForm
!= pObj
->GetObjInventor())
1104 pObj
->SetLayer( *o3tl::doAccess
<bool>(aValue
)
1105 ? ( bIsVisible
? pDoc
->getIDocumentDrawModelAccess().GetHeavenId() : pDoc
->getIDocumentDrawModelAccess().GetInvisibleHeavenId() )
1106 : ( bIsVisible
? pDoc
->getIDocumentDrawModelAccess().GetHellId() : pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId() ));
1110 pObj
->SetLayer( bIsVisible
? pDoc
->getIDocumentDrawModelAccess().GetControlsId() : pDoc
->getIDocumentDrawModelAccess().GetInvisibleControlsId());
1116 // #i26791# - special handling for property FN_TEXT_RANGE
1117 else if ( FN_TEXT_RANGE
== pEntry
->nWID
)
1119 SwFormatAnchor
aAnchor( aSet
.Get( RES_ANCHOR
) );
1120 if (aAnchor
.GetAnchorId() == RndStdIds::FLY_AT_PAGE
)
1122 // set property <TextRange> not valid for to-page anchored shapes
1123 throw lang::IllegalArgumentException();
1126 std::unique_ptr
<SwUnoInternalPaM
> pInternalPam(
1127 new SwUnoInternalPaM( *(pFormat
->GetDoc()) ));
1128 uno::Reference
< text::XTextRange
> xRg
;
1130 if (!::sw::XTextRangeToSwPaM(*pInternalPam
, xRg
) )
1132 throw uno::RuntimeException();
1135 if (aAnchor
.GetAnchorId() == RndStdIds::FLY_AS_CHAR
)
1137 //delete old SwFormatFlyCnt
1138 //With AnchorAsCharacter the current TextAttribute has to be deleted.
1139 //Tbis removes the frame format too.
1140 //To prevent this the connection between format and attribute has to be broken before.
1141 SwTextNode
*pTextNode
= aAnchor
.GetAnchorNode()->GetTextNode();
1142 SAL_WARN_IF( !pTextNode
->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
1143 const sal_Int32 nIdx
= aAnchor
.GetAnchorContentOffset();
1144 SwTextAttr
* const pHint
=
1145 pTextNode
->GetTextAttrForCharAt(
1146 nIdx
, RES_TXTATR_FLYCNT
);
1147 assert(pHint
&& "Missing Hint.");
1148 SAL_WARN_IF( pHint
->Which() != RES_TXTATR_FLYCNT
,
1149 "sw.uno", "Missing FlyInCnt-Hint." );
1150 SAL_WARN_IF( pHint
->GetFlyCnt().GetFrameFormat() != pFormat
,
1151 "sw.uno", "Wrong TextFlyCnt-Hint." );
1152 const_cast<SwFormatFlyCnt
&>(pHint
->GetFlyCnt())
1155 //The connection is removed now the attribute can be deleted.
1156 pTextNode
->DeleteAttributes( RES_TXTATR_FLYCNT
, nIdx
);
1158 SwTextNode
*pNd
= pInternalPam
->GetPointNode().GetTextNode();
1159 SAL_WARN_IF( !pNd
, "sw.uno", "Cursor not at TextNode." );
1160 SwFormatFlyCnt
aFormat( pFormat
);
1161 pNd
->InsertItem(aFormat
, pInternalPam
->GetPoint()
1162 ->GetContentIndex(), 0 );
1163 //Refetch in case SwTextNode::InsertItem causes it to be deleted
1164 pFormat
= GetFrameFormat();
1168 aAnchor
.SetAnchor( pInternalPam
->GetPoint() );
1170 pFormat
->SetFormatAttr(aSet
);
1173 else if (pEntry
->nWID
== FN_TEXT_BOX
)
1175 auto pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1176 if (pEntry
->nMemberId
== MID_TEXT_BOX
)
1182 SwTextBoxHelper::create(pFormat
, pObj
);
1184 SwTextBoxHelper::destroy(pFormat
, pObj
);
1186 else if (pEntry
->nMemberId
== MID_TEXT_BOX_CONTENT
)
1188 if (uno::Reference
<text::XTextFrame
> xTextFrame
; aValue
>>= xTextFrame
)
1189 SwTextBoxHelper::set(pFormat
, pObj
, xTextFrame
);
1191 SAL_WARN( "sw.uno", "This is not a TextFrame!" );
1194 else if (pEntry
->nWID
== RES_CHAIN
)
1196 if (pEntry
->nMemberId
== MID_CHAIN_NEXTNAME
|| pEntry
->nMemberId
== MID_CHAIN_PREVNAME
)
1197 SwTextBoxHelper::syncProperty(pFormat
, pEntry
->nWID
, pEntry
->nMemberId
, aValue
,
1198 SdrObject::getSdrObjectFromXShape(mxShape
));
1201 else if ( FN_SHAPE_POSITION_LAYOUT_DIR
== pEntry
->nWID
)
1203 sal_Int16 nPositionLayoutDir
= 0;
1204 aValue
>>= nPositionLayoutDir
;
1205 pFormat
->SetPositionLayoutDir( nPositionLayoutDir
);
1207 else if( pDoc
->getIDocumentLayoutAccess().GetCurrentLayout())
1209 UnoActionContext
aCtx(pDoc
);
1210 if(RES_ANCHOR
== pEntry
->nWID
&& MID_ANCHOR_ANCHORTYPE
== pEntry
->nMemberId
)
1212 SdrObject
* pObj
= pFormat
->FindSdrObject();
1214 SdrMark
aMark(pObj
);
1215 aList
.InsertEntry(aMark
);
1216 sal_Int32 nAnchor
= 0;
1217 cppu::enum2int( nAnchor
, aValue
);
1218 pDoc
->ChgAnchor( aList
, static_cast<RndStdIds
>(nAnchor
),
1223 SfxItemPropertySet::setPropertyValue(*pEntry
, aValue
, aSet
);
1224 pFormat
->SetFormatAttr(aSet
);
1227 else if( RES_FRM_SIZE
== pEntry
->nWID
&&
1228 ( pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT
|| pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH
1229 || pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT_RELATION
1230 || pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH_RELATION
) )
1232 SvxShape
* pSvxShape
= GetSvxShape();
1233 SAL_WARN_IF(!pSvxShape
, "sw.uno", "No SvxShape found!");
1236 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1237 sal_Int16
nPercent(100);
1238 aValue
>>= nPercent
;
1239 switch (pEntry
->nMemberId
)
1241 case MID_FRMSIZE_REL_WIDTH
:
1242 pObj
->SetRelativeWidth( nPercent
/ 100.0 );
1244 case MID_FRMSIZE_REL_HEIGHT
:
1245 pObj
->SetRelativeHeight( nPercent
/ 100.0 );
1247 case MID_FRMSIZE_REL_WIDTH_RELATION
:
1248 pObj
->SetRelativeWidthRelation(nPercent
);
1250 case MID_FRMSIZE_REL_HEIGHT_RELATION
:
1251 pObj
->SetRelativeHeightRelation(nPercent
);
1256 else if (pEntry
->nWID
== RES_HORI_ORIENT
1257 && pEntry
->nMemberId
== MID_HORIORIENT_RELATION
1258 && aSet
.Get(RES_ANCHOR
).GetAnchorId() == RndStdIds::FLY_AT_PAGE
)
1260 uno::Any
value(aValue
);
1261 sal_Int16
nRelOrient(text::RelOrientation::PAGE_FRAME
);
1262 aValue
>>= nRelOrient
;
1263 if (sw::GetAtPageRelOrientation(nRelOrient
, true))
1265 SAL_WARN("sw.core", "SwXShape: fixing invalid horizontal RelOrientation for at-page anchor");
1266 value
<<= nRelOrient
;
1268 SfxItemPropertySet::setPropertyValue( *pEntry
, value
, aSet
);
1269 pFormat
->SetFormatAttr(aSet
);
1273 SfxItemPropertySet::setPropertyValue( *pEntry
, aValue
, aSet
);
1275 if(RES_ANCHOR
== pEntry
->nWID
&& MID_ANCHOR_ANCHORTYPE
== pEntry
->nMemberId
)
1277 bool bSetAttr
= true;
1278 text::TextContentAnchorType eNewAnchor
= static_cast<text::TextContentAnchorType
>(SWUnoHelper::GetEnumAsInt32( aValue
));
1280 //if old anchor was in_cntnt the related text attribute has to be removed
1281 const SwFormatAnchor
& rOldAnchor
= pFormat
->GetAnchor();
1282 RndStdIds eOldAnchorId
= rOldAnchor
.GetAnchorId();
1283 SdrObject
* pObj
= pFormat
->FindSdrObject();
1284 SwFrameFormat
*pFlyFormat
= FindFrameFormat( pObj
);
1285 pFlyFormat
->DelFrames();
1286 if( text::TextContentAnchorType_AS_CHARACTER
!= eNewAnchor
&&
1287 (RndStdIds::FLY_AS_CHAR
== eOldAnchorId
))
1289 //With AnchorAsCharacter the current TextAttribute has to be deleted.
1290 //Tbis removes the frame format too.
1291 //To prevent this the connection between format and attribute has to be broken before.
1292 SwTextNode
*pTextNode
= rOldAnchor
.GetAnchorNode()->GetTextNode();
1293 SAL_WARN_IF( !pTextNode
->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
1294 const sal_Int32 nIdx
= rOldAnchor
.GetAnchorContentOffset();
1295 SwTextAttr
* const pHint
=
1296 pTextNode
->GetTextAttrForCharAt(
1297 nIdx
, RES_TXTATR_FLYCNT
);
1298 assert(pHint
&& "Missing Hint.");
1299 SAL_WARN_IF( pHint
->Which() != RES_TXTATR_FLYCNT
,
1300 "sw.uno", "Missing FlyInCnt-Hint." );
1301 SAL_WARN_IF( pHint
->GetFlyCnt().GetFrameFormat() != pFlyFormat
,
1302 "sw.uno", "Wrong TextFlyCnt-Hint." );
1303 const_cast<SwFormatFlyCnt
&>(pHint
->GetFlyCnt())
1306 //The connection is removed now the attribute can be deleted.
1307 pTextNode
->DeleteAttributes(RES_TXTATR_FLYCNT
, nIdx
);
1309 else if( text::TextContentAnchorType_AT_PAGE
!= eNewAnchor
&&
1310 (RndStdIds::FLY_AT_PAGE
== eOldAnchorId
))
1312 SwFormatAnchor
aNewAnchor( aSet
.Get( RES_ANCHOR
) );
1313 //if the fly has been anchored at page then it needs to be connected
1314 //to the content position
1315 SwPaM
aPam(pDoc
->GetNodes().GetEndOfContent());
1316 if( pDoc
->getIDocumentLayoutAccess().GetCurrentLayout() )
1318 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
1319 Point
aTmp( pObj
->GetSnapRect().TopLeft() );
1320 pDoc
->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam
.GetPoint(), aTmp
, &aState
);
1324 //without access to the layout the last node of the body will be used as anchor position
1325 aPam
.Move( fnMoveBackward
, GoInDoc
);
1327 //anchor position has to be inserted after the text attribute has been inserted
1328 aNewAnchor
.SetAnchor( aPam
.GetPoint() );
1329 aSet
.Put( aNewAnchor
);
1330 pFormat
->SetFormatAttr(aSet
);
1333 if( text::TextContentAnchorType_AS_CHARACTER
== eNewAnchor
&&
1334 (RndStdIds::FLY_AS_CHAR
!= eOldAnchorId
))
1336 SwPaM
aPam(pDoc
->GetNodes().GetEndOfContent());
1337 if( pDoc
->getIDocumentLayoutAccess().GetCurrentLayout() )
1339 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
1340 Point
aTmp( pObj
->GetSnapRect().TopLeft() );
1341 pDoc
->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam
.GetPoint(), aTmp
, &aState
);
1345 //without access to the layout the last node of the body will be used as anchor position
1346 aPam
.Move( fnMoveBackward
, GoInDoc
);
1348 //the RES_TXTATR_FLYCNT needs to be added now
1349 SwTextNode
*pNd
= aPam
.GetPointNode().GetTextNode();
1350 SAL_WARN_IF( !pNd
, "sw.uno", "Cursor is not in a TextNode." );
1351 SwFormatFlyCnt
aFormat( pFlyFormat
);
1352 pNd
->InsertItem(aFormat
,
1353 aPam
.GetPoint()->GetContentIndex(), 0 );
1354 aPam
.GetPoint()->AdjustContent(-1); // InsertItem moved it
1355 SwFormatAnchor
aNewAnchor(
1356 aSet
.Get(RES_ANCHOR
));
1357 aNewAnchor
.SetAnchor( aPam
.GetPoint() );
1358 aSet
.Put( aNewAnchor
);
1361 pFormat
->SetFormatAttr(aSet
);
1363 // If this property is an anchor change, and there is a group shape with textboxes
1364 // do anchor sync in time unless the anchor sync in the porfly will cause crash during
1365 // layout calculation (When importing an inline shape in docx via dmapper).
1366 if (pFormat
->Which() == RES_DRAWFRMFMT
&& pFormat
->GetOtherTextBoxFormats())
1368 SwTextBoxHelper::synchronizeGroupTextBoxProperty(
1369 SwTextBoxHelper::changeAnchor
, pFormat
,
1370 SdrObject::getSdrObjectFromXShape(mxShape
));
1374 pFormat
->SetFormatAttr(aSet
);
1377 // We have a pFormat and a pEntry as well: try to sync TextBox property.
1378 SwTextBoxHelper::syncProperty(pFormat
, pEntry
->nWID
, pEntry
->nMemberId
, aValue
,
1379 SdrObject::getSdrObjectFromXShape(mxShape
));
1383 SfxPoolItem
* pItem
= nullptr;
1384 switch(pEntry
->nWID
)
1387 pItem
= m_pImpl
->GetAnchor(true);
1389 case RES_HORI_ORIENT
:
1390 pItem
= m_pImpl
->GetHOrient(true);
1392 case RES_VERT_ORIENT
:
1393 pItem
= m_pImpl
->GetVOrient(true);
1396 pItem
= m_pImpl
->GetLRSpace(true);
1399 pItem
= m_pImpl
->GetULSpace(true);
1402 pItem
= m_pImpl
->GetSurround(true);
1405 if(auto tr
= o3tl::tryAccess
<
1406 uno::Reference
<text::XTextRange
>>(aValue
))
1408 uno::Reference
< text::XTextRange
> & rRange
= m_pImpl
->GetTextRange();
1413 m_pImpl
->SetOpaque(*o3tl::doAccess
<bool>(aValue
));
1416 case RES_FOLLOW_TEXT_FLOW
:
1418 pItem
= m_pImpl
->GetFollowTextFlow( true );
1422 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1424 pItem
= m_pImpl
->GetWrapInfluenceOnObjPos( true );
1428 case FN_SHAPE_POSITION_LAYOUT_DIR
:
1430 sal_Int16 nPositionLayoutDir
= 0;
1431 aValue
>>= nPositionLayoutDir
;
1432 m_pImpl
->SetPositionLayoutDir( nPositionLayoutDir
);
1437 pItem
->PutValue(aValue
, pEntry
->nMemberId
);
1442 const uno::Type
& rPSetType
=
1443 cppu::UnoType
<beans::XPropertySet
>::get();
1444 uno::Any aPSet
= m_xShapeAgg
->queryAggregation(rPSetType
);
1445 auto xPrSet
= o3tl::tryAccess
<uno::Reference
<beans::XPropertySet
>>(
1448 throw uno::RuntimeException();
1449 // #i31698# - setting the caption point of a
1450 // caption object doesn't have to change the object position.
1451 // Thus, keep the position, before the caption point is set and
1452 // restore it afterwards.
1453 awt::Point
aKeepedPosition( 0, 0 );
1454 if ( rPropertyName
== "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
1456 aKeepedPosition
= getPosition();
1458 if( pFormat
&& pFormat
->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() )
1460 UnoActionContext
aCtx(pFormat
->GetDoc());
1461 (*xPrSet
)->setPropertyValue(rPropertyName
, aValue
);
1464 (*xPrSet
)->setPropertyValue(rPropertyName
, aValue
);
1468 // We have a pFormat (but no pEntry): try to sync TextBox property.
1469 SwTextBoxHelper::syncProperty(pFormat
, rPropertyName
, aValue
,
1470 SdrObject::getSdrObjectFromXShape(mxShape
));
1473 // #i31698# - restore object position, if caption point is set.
1474 if ( rPropertyName
== "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
1476 setPosition( aKeepedPosition
);
1481 uno::Any
SwXShape::getPropertyValue(const OUString
& rPropertyName
)
1483 SolarMutexGuard aGuard
;
1485 SwFrameFormat
* pFormat
= GetFrameFormat();
1486 if(m_xShapeAgg
.is())
1488 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
1493 if(RES_OPAQUE
== pEntry
->nWID
)
1495 SvxShape
* pSvxShape
= GetSvxShape();
1496 OSL_ENSURE(pSvxShape
, "No SvxShape found!");
1499 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1500 // consider invisible layers
1501 SdrLayerID nLayerId
= pObj
->GetLayer();
1502 const IDocumentDrawModelAccess
& rIDMA
= pFormat
->GetDoc()->getIDocumentDrawModelAccess();
1504 ( nLayerId
!= rIDMA
.GetHellId() &&
1505 nLayerId
!= rIDMA
.GetHeaderFooterHellId() &&
1506 nLayerId
!= rIDMA
.GetInvisibleHellId() );
1509 else if(FN_ANCHOR_POSITION
== pEntry
->nWID
)
1511 SvxShape
* pSvxShape
= GetSvxShape();
1512 OSL_ENSURE(pSvxShape
, "No SvxShape found!");
1515 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1516 Point aPt
= pObj
->GetAnchorPos();
1517 awt::Point
aPoint( convertTwipToMm100( aPt
.X() ),
1518 convertTwipToMm100( aPt
.Y() ) );
1522 // #i26791# - special handling for FN_TEXT_RANGE
1523 else if ( FN_TEXT_RANGE
== pEntry
->nWID
)
1525 const SwFormatAnchor aAnchor
= pFormat
->GetAnchor();
1526 if (aAnchor
.GetAnchorId() == RndStdIds::FLY_AT_PAGE
)
1528 // return nothing, because property <TextRange> isn't
1529 // valid for to-page anchored shapes
1534 if ( aAnchor
.GetAnchorNode() )
1536 const rtl::Reference
<SwXTextRange
> xTextRange
1537 = SwXTextRange::CreateXTextRange(
1539 *aAnchor
.GetContentAnchor(),
1541 aRet
<<= uno::Reference
<text::XTextRange
>(xTextRange
);
1550 else if (pEntry
->nWID
== FN_TEXT_BOX
)
1552 if (pEntry
->nMemberId
== MID_TEXT_BOX
)
1554 auto pSvxShape
= GetSvxShape();
1555 bool bValue
= SwTextBoxHelper::isTextBox(
1556 pFormat
, RES_DRAWFRMFMT
,
1557 ((pSvxShape
&& pSvxShape
->GetSdrObject()) ? pSvxShape
->GetSdrObject()
1558 : pFormat
->FindRealSdrObject()));
1561 else if (pEntry
->nMemberId
== MID_TEXT_BOX_CONTENT
)
1563 auto pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1564 auto xRange
= SwTextBoxHelper::queryInterface(
1565 pFormat
, cppu::UnoType
<text::XText
>::get(),
1566 pObj
? pObj
: pFormat
->FindRealSdrObject());
1567 uno::Reference
<text::XTextFrame
> xFrame(xRange
, uno::UNO_QUERY
);
1572 else if (pEntry
->nWID
== RES_CHAIN
)
1574 switch (pEntry
->nMemberId
)
1576 case MID_CHAIN_PREVNAME
:
1577 case MID_CHAIN_NEXTNAME
:
1578 case MID_CHAIN_NAME
:
1579 SwTextBoxHelper::getProperty(pFormat
, pEntry
->nWID
, pEntry
->nMemberId
, aRet
);
1584 else if ( FN_SHAPE_TRANSFORMATION_IN_HORI_L2R
== pEntry
->nWID
)
1586 // get property <::drawing::Shape::Transformation>
1587 // without conversion to layout direction as below
1588 aRet
= _getPropAtAggrObj( u
"Transformation"_ustr
);
1590 else if ( FN_SHAPE_POSITION_LAYOUT_DIR
== pEntry
->nWID
)
1592 aRet
<<= pFormat
->GetPositionLayoutDir();
1595 else if ( FN_SHAPE_STARTPOSITION_IN_HORI_L2R
== pEntry
->nWID
)
1597 // get property <::drawing::Shape::StartPosition>
1598 // without conversion to layout direction as below
1599 aRet
= _getPropAtAggrObj( u
"StartPosition"_ustr
);
1601 else if ( FN_SHAPE_ENDPOSITION_IN_HORI_L2R
== pEntry
->nWID
)
1603 // get property <::drawing::Shape::EndPosition>
1604 // without conversion to layout direction as below
1605 aRet
= _getPropAtAggrObj( u
"EndPosition"_ustr
);
1607 else if (pEntry
->nWID
== RES_FRM_SIZE
&&
1608 (pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT
||
1609 pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH
||
1610 pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT_RELATION
||
1611 pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH_RELATION
))
1613 SvxShape
* pSvxShape
= GetSvxShape();
1614 SAL_WARN_IF(!pSvxShape
, "sw.uno", "No SvxShape found!");
1618 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
1619 switch (pEntry
->nMemberId
)
1621 case MID_FRMSIZE_REL_WIDTH
:
1622 if (pObj
->GetRelativeWidth())
1623 nRet
= *pObj
->GetRelativeWidth() * 100;
1625 case MID_FRMSIZE_REL_HEIGHT
:
1626 if (pObj
->GetRelativeHeight())
1627 nRet
= *pObj
->GetRelativeHeight() * 100;
1629 case MID_FRMSIZE_REL_WIDTH_RELATION
:
1630 nRet
= pObj
->GetRelativeWidthRelation();
1632 case MID_FRMSIZE_REL_HEIGHT_RELATION
:
1633 nRet
= pObj
->GetRelativeHeightRelation();
1641 const SwAttrSet
& rSet
= pFormat
->GetAttrSet();
1642 SfxItemPropertySet::getPropertyValue(*pEntry
, rSet
, aRet
);
1647 SfxPoolItem
* pItem
= nullptr;
1648 switch(pEntry
->nWID
)
1651 pItem
= m_pImpl
->GetAnchor();
1653 case RES_HORI_ORIENT
:
1654 pItem
= m_pImpl
->GetHOrient();
1656 case RES_VERT_ORIENT
:
1657 pItem
= m_pImpl
->GetVOrient();
1660 pItem
= m_pImpl
->GetLRSpace();
1663 pItem
= m_pImpl
->GetULSpace();
1666 pItem
= m_pImpl
->GetSurround();
1668 case FN_TEXT_RANGE
:
1669 aRet
<<= m_pImpl
->GetTextRange();
1672 aRet
<<= m_pImpl
->GetOpaque();
1674 case FN_ANCHOR_POSITION
:
1676 aRet
<<= awt::Point();
1680 case RES_FOLLOW_TEXT_FLOW
:
1682 pItem
= m_pImpl
->GetFollowTextFlow();
1686 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1688 pItem
= m_pImpl
->GetWrapInfluenceOnObjPos();
1692 case FN_SHAPE_TRANSFORMATION_IN_HORI_L2R
:
1694 // get property <::drawing::Shape::Transformation>
1695 // without conversion to layout direction as below
1696 aRet
= _getPropAtAggrObj( u
"Transformation"_ustr
);
1699 case FN_SHAPE_POSITION_LAYOUT_DIR
:
1701 aRet
<<= m_pImpl
->GetPositionLayoutDir();
1705 case FN_SHAPE_STARTPOSITION_IN_HORI_L2R
:
1707 // get property <::drawing::Shape::StartPosition>
1708 // without conversion to layout direction as below
1709 aRet
= _getPropAtAggrObj( u
"StartPosition"_ustr
);
1712 case FN_SHAPE_ENDPOSITION_IN_HORI_L2R
:
1714 // get property <::drawing::Shape::StartPosition>
1715 // without conversion to layout direction as below
1716 aRet
= _getPropAtAggrObj( u
"EndPosition"_ustr
);
1721 pItem
->QueryValue(aRet
, pEntry
->nMemberId
);
1726 aRet
= _getPropAtAggrObj( rPropertyName
);
1728 // #i31698# - convert the position (translation)
1729 // of the drawing object in the transformation
1730 if ( rPropertyName
== "Transformation" )
1732 drawing::HomogenMatrix3 aMatrix
;
1734 aRet
<<= ConvertTransformationToLayoutDir( aMatrix
);
1737 else if ( rPropertyName
== "StartPosition" )
1739 awt::Point aStartPos
;
1742 aRet
<<= ConvertStartOrEndPosToLayoutDir( aStartPos
);
1744 else if ( rPropertyName
== "EndPosition" )
1749 aRet
<<= ConvertStartOrEndPosToLayoutDir( aEndPos
);
1752 else if ( rPropertyName
== "PolyPolygonBezier" )
1754 drawing::PolyPolygonBezierCoords aPath
;
1756 aRet
<<= ConvertPolyPolygonBezierToLayoutDir( aPath
);
1758 else if (rPropertyName
== "ZOrder")
1760 // Convert the real draw page position to the logical one that ignores textboxes.
1763 const SdrObject
* pObj
= pFormat
->FindRealSdrObject();
1766 bool bConvert
= true;
1767 if (SvxShape
* pSvxShape
= GetSvxShape())
1768 // In case of group shapes, pSvxShape points to the child shape, while pObj points to the outermost group shape.
1769 if (pSvxShape
->GetSdrObject() != pObj
)
1770 // Textboxes are not expected inside group shapes, so no conversion is necessary there.
1774 aRet
<<= SwTextBoxHelper::getOrdNum(pObj
);
1784 uno::Any
SwXShape::_getPropAtAggrObj( const OUString
& _rPropertyName
)
1788 const uno::Type
& rPSetType
=
1789 cppu::UnoType
<beans::XPropertySet
>::get();
1790 uno::Any aPSet
= m_xShapeAgg
->queryAggregation(rPSetType
);
1791 auto xPrSet
= o3tl::tryAccess
<uno::Reference
<beans::XPropertySet
>>(aPSet
);
1794 throw uno::RuntimeException();
1796 aRet
= (*xPrSet
)->getPropertyValue( _rPropertyName
);
1801 beans::PropertyState
SwXShape::getPropertyState( const OUString
& rPropertyName
)
1803 SolarMutexGuard aGuard
;
1804 uno::Sequence
< OUString
> aNames
{ rPropertyName
};
1805 uno::Sequence
< beans::PropertyState
> aStates
= getPropertyStates(aNames
);
1806 return aStates
.getConstArray()[0];
1809 uno::Sequence
< beans::PropertyState
> SwXShape::getPropertyStates(
1810 const uno::Sequence
< OUString
>& aPropertyNames
)
1812 SolarMutexGuard aGuard
;
1813 SwFrameFormat
* pFormat
= GetFrameFormat();
1814 uno::Sequence
< beans::PropertyState
> aRet(aPropertyNames
.getLength());
1815 if(!m_xShapeAgg
.is())
1816 throw uno::RuntimeException();
1818 SvxShape
* pSvxShape
= GetSvxShape();
1819 bool bGroupMember
= false;
1820 bool bFormControl
= false;
1821 SdrObject
* pObject
= pSvxShape
? pSvxShape
->GetSdrObject() : nullptr;
1824 bGroupMember
= pObject
->getParentSdrObjectFromSdrObject() != nullptr;
1825 bFormControl
= pObject
->GetObjInventor() == SdrInventor::FmForm
;
1827 const OUString
* pNames
= aPropertyNames
.getConstArray();
1828 beans::PropertyState
* pRet
= aRet
.getArray();
1829 uno::Reference
< XPropertyState
> xShapePrState
;
1830 for(sal_Int32 nProperty
= 0; nProperty
< aPropertyNames
.getLength(); nProperty
++)
1832 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( pNames
[nProperty
] );
1835 if(RES_OPAQUE
== pEntry
->nWID
)
1836 pRet
[nProperty
] = bFormControl
?
1837 beans::PropertyState_DEFAULT_VALUE
: beans::PropertyState_DIRECT_VALUE
;
1838 else if(FN_ANCHOR_POSITION
== pEntry
->nWID
)
1839 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1840 else if(FN_TEXT_RANGE
== pEntry
->nWID
)
1841 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1842 else if(bGroupMember
)
1843 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1844 else if (pEntry
->nWID
== RES_FRM_SIZE
&&
1845 (pEntry
->nMemberId
== MID_FRMSIZE_REL_HEIGHT_RELATION
||
1846 pEntry
->nMemberId
== MID_FRMSIZE_REL_WIDTH_RELATION
))
1847 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1848 else if (pEntry
->nWID
== FN_TEXT_BOX
)
1850 // The TextBox property is set, if we can find a textbox for this shape.
1852 && SwTextBoxHelper::isTextBox(pFormat
, RES_DRAWFRMFMT
,
1853 SdrObject::getSdrObjectFromXShape(mxShape
)))
1854 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1856 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1860 const SwAttrSet
& rSet
= pFormat
->GetAttrSet();
1861 SfxItemState eItemState
= rSet
.GetItemState(pEntry
->nWID
, false);
1863 if(SfxItemState::SET
== eItemState
)
1864 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1865 else if(SfxItemState::DEFAULT
== eItemState
)
1866 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1868 pRet
[nProperty
] = beans::PropertyState_AMBIGUOUS_VALUE
;
1872 SfxPoolItem
* pItem
= nullptr;
1873 switch(pEntry
->nWID
)
1876 pItem
= m_pImpl
->GetAnchor();
1878 case RES_HORI_ORIENT
:
1879 pItem
= m_pImpl
->GetHOrient();
1881 case RES_VERT_ORIENT
:
1882 pItem
= m_pImpl
->GetVOrient();
1885 pItem
= m_pImpl
->GetLRSpace();
1888 pItem
= m_pImpl
->GetULSpace();
1891 pItem
= m_pImpl
->GetSurround();
1894 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1896 pItem
= m_pImpl
->GetWrapInfluenceOnObjPos();
1901 pRet
[nProperty
] = beans::PropertyState_DIRECT_VALUE
;
1903 pRet
[nProperty
] = beans::PropertyState_DEFAULT_VALUE
;
1908 if(!xShapePrState
.is())
1910 const uno::Type
& rPStateType
= cppu::UnoType
<XPropertyState
>::get();
1911 uno::Any aPState
= m_xShapeAgg
->queryAggregation(rPStateType
);
1912 auto ps
= o3tl::tryAccess
<uno::Reference
<XPropertyState
>>(
1915 throw uno::RuntimeException();
1916 xShapePrState
= *ps
;
1918 pRet
[nProperty
] = xShapePrState
->getPropertyState(pNames
[nProperty
]);
1925 void SwXShape::setPropertyToDefault( const OUString
& rPropertyName
)
1927 SolarMutexGuard aGuard
;
1928 SwFrameFormat
* pFormat
= GetFrameFormat();
1929 if(!m_xShapeAgg
.is())
1930 throw uno::RuntimeException();
1932 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
1935 if ( pEntry
->nFlags
& beans::PropertyAttribute::READONLY
)
1936 throw uno::RuntimeException("Property is read-only: " + rPropertyName
, getXWeak() );
1939 const SfxItemSet
& rSet
= pFormat
->GetAttrSet();
1940 SfxItemSet
aSet(pFormat
->GetDoc()->GetAttrPool(), pEntry
->nWID
, pEntry
->nWID
);
1941 aSet
.SetParent(&rSet
);
1942 aSet
.ClearItem(pEntry
->nWID
);
1943 pFormat
->GetDoc()->SetAttr(aSet
, *pFormat
);
1947 switch(pEntry
->nWID
)
1949 case RES_ANCHOR
: m_pImpl
->RemoveAnchor(); break;
1950 case RES_HORI_ORIENT
: m_pImpl
->RemoveHOrient(); break;
1951 case RES_VERT_ORIENT
: m_pImpl
->RemoveVOrient(); break;
1952 case RES_LR_SPACE
: m_pImpl
->RemoveLRSpace(); break;
1953 case RES_UL_SPACE
: m_pImpl
->RemoveULSpace(); break;
1954 case RES_SURROUND
: m_pImpl
->RemoveSurround();break;
1955 case RES_OPAQUE
: m_pImpl
->SetOpaque(false); break;
1956 case FN_TEXT_RANGE
:
1959 case RES_FOLLOW_TEXT_FLOW
:
1961 m_pImpl
->RemoveFollowTextFlow();
1965 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
1967 m_pImpl
->RemoveWrapInfluenceOnObjPos();
1975 const uno::Type
& rPStateType
= cppu::UnoType
<XPropertyState
>::get();
1976 uno::Any aPState
= m_xShapeAgg
->queryAggregation(rPStateType
);
1977 auto xShapePrState
= o3tl::tryAccess
<uno::Reference
<XPropertyState
>>(
1980 throw uno::RuntimeException();
1981 (*xShapePrState
)->setPropertyToDefault( rPropertyName
);
1986 uno::Any
SwXShape::getPropertyDefault( const OUString
& rPropertyName
)
1988 SolarMutexGuard aGuard
;
1989 SwFrameFormat
* pFormat
= GetFrameFormat();
1991 if(!m_xShapeAgg
.is())
1992 throw uno::RuntimeException();
1994 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
1997 if(!(pEntry
->nWID
< RES_FRMATR_END
&& pFormat
))
1998 throw uno::RuntimeException();
2000 const SfxPoolItem
& rDefItem
=
2001 pFormat
->GetDoc()->GetAttrPool().GetUserOrPoolDefaultItem(pEntry
->nWID
);
2002 rDefItem
.QueryValue(aRet
, pEntry
->nMemberId
);
2007 const uno::Type
& rPStateType
= cppu::UnoType
<XPropertyState
>::get();
2008 uno::Any aPState
= m_xShapeAgg
->queryAggregation(rPStateType
);
2009 auto xShapePrState
= o3tl::tryAccess
<uno::Reference
<XPropertyState
>>(
2012 throw uno::RuntimeException();
2013 (*xShapePrState
)->getPropertyDefault( rPropertyName
);
2019 void SwXShape::addPropertyChangeListener(
2020 const OUString
& _propertyName
,
2021 const uno::Reference
< beans::XPropertyChangeListener
> & _listener
)
2023 if ( !m_xShapeAgg
.is() )
2024 throw uno::RuntimeException(u
"no shape aggregate"_ustr
, *this );
2026 // must be handled by the aggregate
2027 uno::Reference
< beans::XPropertySet
> xShapeProps
;
2028 if ( m_xShapeAgg
->queryAggregation( cppu::UnoType
<beans::XPropertySet
>::get() ) >>= xShapeProps
)
2029 xShapeProps
->addPropertyChangeListener( _propertyName
, _listener
);
2032 void SwXShape::removePropertyChangeListener(
2033 const OUString
& _propertyName
,
2034 const uno::Reference
< beans::XPropertyChangeListener
> & _listener
)
2036 if ( !m_xShapeAgg
.is() )
2037 throw uno::RuntimeException(u
"no shape aggregate"_ustr
, *this );
2039 // must be handled by the aggregate
2040 uno::Reference
< beans::XPropertySet
> xShapeProps
;
2041 if ( m_xShapeAgg
->queryAggregation( cppu::UnoType
<beans::XPropertySet
>::get() ) >>= xShapeProps
)
2042 xShapeProps
->removePropertyChangeListener( _propertyName
, _listener
);
2045 void SwXShape::addVetoableChangeListener(
2046 const OUString
& /*PropertyName*/,
2047 const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/ )
2049 OSL_FAIL("not implemented");
2052 void SwXShape::removeVetoableChangeListener(
2053 const OUString
& /*PropertyName*/,
2054 const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
2056 OSL_FAIL("not implemented");
2059 void SwXShape::attach(const uno::Reference
< text::XTextRange
> & xTextRange
)
2061 SolarMutexGuard aGuard
;
2063 // get access to SwDoc
2064 // (see also SwXTextRange::XTextRangeToSwPaM)
2065 const SwDoc
* pDoc
= nullptr;
2066 if (auto pRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get()))
2067 pDoc
= &pRange
->GetDoc();
2068 else if (auto pText
= dynamic_cast<SwXText
*>(xTextRange
.get()))
2069 pDoc
= pText
->GetDoc();
2070 else if (auto pCursor
= dynamic_cast<OTextCursorHelper
*>(xTextRange
.get()))
2071 pDoc
= pCursor
->GetDoc();
2072 else if (auto pPortion
= dynamic_cast<SwXTextPortion
*>(xTextRange
.get()))
2073 pDoc
= &pPortion
->GetCursor().GetDoc();
2074 else if (auto pParagraph
= dynamic_cast<SwXParagraph
*>(xTextRange
.get());
2075 pParagraph
&& pParagraph
->GetTextNode())
2076 pDoc
= &pParagraph
->GetTextNode()->GetDoc();
2079 throw uno::RuntimeException();
2080 const SwDocShell
* pDocSh
= pDoc
->GetDocShell();
2084 uno::Reference
<frame::XModel
> xModel
= pDocSh
->GetModel();
2085 uno::Reference
< drawing::XDrawPageSupplier
> xDPS(xModel
, uno::UNO_QUERY
);
2088 uno::Reference
< drawing::XDrawPage
> xDP( xDPS
->getDrawPage() );
2092 aPos
<<= xTextRange
;
2093 setPropertyValue(u
"TextRange"_ustr
, aPos
);
2094 uno::Reference
< drawing::XShape
> xTemp( getXWeak(), uno::UNO_QUERY
);
2100 uno::Reference
< text::XTextRange
> SwXShape::getAnchor()
2102 SolarMutexGuard aGuard
;
2103 uno::Reference
< text::XTextRange
> aRef
;
2104 SwFrameFormat
* pFormat
= GetFrameFormat();
2107 const SwFormatAnchor
& rAnchor
= pFormat
->GetAnchor();
2108 // return an anchor for non-page bound frames
2109 // and for page bound frames that have a page no == NULL and a content position
2110 if ((rAnchor
.GetAnchorId() != RndStdIds::FLY_AT_PAGE
) ||
2111 (rAnchor
.GetAnchorNode() && !rAnchor
.GetPageNum()))
2113 if (rAnchor
.GetAnchorId() == RndStdIds::FLY_AT_PARA
)
2114 { // ensure that SwXTextRange has SwContentIndex
2115 const SwNode
* pAnchorNode
= rAnchor
.GetAnchorNode();
2116 aRef
= SwXTextRange::CreateXTextRange(*pFormat
->GetDoc(), SwPosition(*pAnchorNode
), nullptr);
2120 aRef
= SwXTextRange::CreateXTextRange(*pFormat
->GetDoc(), *rAnchor
.GetContentAnchor(), nullptr);
2125 aRef
= m_pImpl
->GetTextRange().get();
2129 void SwXShape::dispose()
2131 SolarMutexGuard aGuard
;
2132 SwFrameFormat
* pFormat
= GetFrameFormat();
2135 // determine correct <SdrObject>
2136 SvxShape
* pSvxShape
= GetSvxShape();
2137 SdrObject
* pObj
= pSvxShape
? pSvxShape
->GetSdrObject() : nullptr;
2138 // safety assertion:
2139 // <pObj> must be the same as <pFormat->FindSdrObject()>, if <pObj> isn't
2140 // a 'virtual' drawing object.
2141 // correct assertion and refine it for safety reason.
2142 OSL_ENSURE( !pObj
||
2143 dynamic_cast<const SwDrawVirtObj
*>( pObj
) != nullptr ||
2144 pObj
->getParentSdrObjectFromSdrObject() ||
2145 pObj
== pFormat
->FindSdrObject(),
2146 "<SwXShape::dispose(..) - different 'master' drawing objects!!" );
2147 // perform delete of draw frame format *not*
2148 // for 'virtual' drawing objects.
2149 // no delete of draw format for members
2152 dynamic_cast<const SwDrawVirtObj
*>( pObj
) == nullptr &&
2153 !pObj
->getParentSdrObjectFromSdrObject() &&
2154 pObj
->IsInserted() )
2156 const SwFormatAnchor
& rFormatAnchor
= pFormat
->GetAnchor();
2157 if (rFormatAnchor
.GetAnchorId() == RndStdIds::FLY_AS_CHAR
)
2159 SwTextNode
*pTextNode
= rFormatAnchor
.GetAnchorNode()->GetTextNode();
2160 const sal_Int32 nIdx
= rFormatAnchor
.GetAnchorContentOffset();
2161 pTextNode
->DeleteAttributes( RES_TXTATR_FLYCNT
, nIdx
);
2164 pFormat
->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat( pFormat
);
2167 if(m_xShapeAgg
.is())
2169 uno::Any
aAgg(m_xShapeAgg
->queryAggregation( cppu::UnoType
<XComponent
>::get()));
2170 uno::Reference
<XComponent
> xComp
;
2177 auto pPage
= const_cast<SwFmDrawPage
*>(m_pPage
);
2179 pPage
->RemoveShape(this);
2183 void SwXShape::addEventListener(
2184 const uno::Reference
< lang::XEventListener
> & aListener
)
2186 SvxShape
* pSvxShape
= GetSvxShape();
2188 pSvxShape
->addEventListener(aListener
);
2191 void SwXShape::removeEventListener(
2192 const uno::Reference
< lang::XEventListener
> & aListener
)
2194 SvxShape
* pSvxShape
= GetSvxShape();
2196 pSvxShape
->removeEventListener(aListener
);
2199 OUString
SwXShape::getImplementationName()
2201 return u
"SwXShape"_ustr
;
2204 sal_Bool
SwXShape::supportsService(const OUString
& rServiceName
)
2206 return cppu::supportsService(this, rServiceName
);
2209 uno::Sequence
< OUString
> SwXShape::getSupportedServiceNames()
2211 uno::Sequence
< OUString
> aSeq
;
2212 if (SvxShape
* pSvxShape
= GetSvxShape())
2213 aSeq
= pSvxShape
->getSupportedServiceNames();
2214 return comphelper::concatSequences(
2215 aSeq
, std::initializer_list
<OUString
>{ u
"com.sun.star.drawing.Shape"_ustr
});
2218 SvxShape
* SwXShape::GetSvxShape()
2220 if(m_xShapeAgg
.is())
2221 return comphelper::getFromUnoTunnel
<SvxShape
>(m_xShapeAgg
);
2226 // implementation of virtual methods from drawing::XShape
2227 awt::Point SAL_CALL
SwXShape::getPosition()
2229 awt::Point
aPos( GetAttrPosition() );
2231 // handle group members
2232 SvxShape
* pSvxShape
= GetSvxShape();
2235 SdrObject
* pTopGroupObj
= GetTopGroupObj( pSvxShape
);
2238 // #i34750# - get attribute position of top group
2239 // shape and add offset between top group object and group member
2240 uno::Reference
< drawing::XShape
> xGroupShape( pTopGroupObj
->getUnoShape(), uno::UNO_QUERY
);
2241 aPos
= xGroupShape
->getPosition();
2242 // add offset between top group object and group member
2243 // to the determined attribute position
2245 // consider the layout direction
2246 const tools::Rectangle aMemberObjRect
= GetSvxShape()->GetSdrObject()->GetSnapRect();
2247 const tools::Rectangle aGroupObjRect
= pTopGroupObj
->GetSnapRect();
2248 // #i53320# - relative position of group member and
2249 // top group object is always given in horizontal left-to-right layout.
2250 awt::Point
aOffset( 0, 0 );
2252 aOffset
.X
= ( aMemberObjRect
.Left() - aGroupObjRect
.Left() );
2253 aOffset
.Y
= ( aMemberObjRect
.Top() - aGroupObjRect
.Top() );
2255 aOffset
.X
= convertTwipToMm100(aOffset
.X
);
2256 aOffset
.Y
= convertTwipToMm100(aOffset
.Y
);
2257 aPos
.X
+= aOffset
.X
;
2258 aPos
.Y
+= aOffset
.Y
;
2265 void SAL_CALL
SwXShape::setPosition( const awt::Point
& aPosition
)
2267 SdrObject
* pTopGroupObj
= GetTopGroupObj();
2268 if ( !pTopGroupObj
)
2270 // #i37877# - no adjustment of position attributes,
2271 // if the position also has to be applied at the drawing object and
2272 // a contact object is already registered at the drawing object.
2273 bool bApplyPosAtDrawObj(false);
2274 bool bNoAdjustOfPosProp(false);
2275 // #i35798# - apply position also to drawing object,
2276 // if drawing object has no anchor position set.
2279 SvxShape
* pSvxShape
= GetSvxShape();
2282 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2284 pObj
->GetAnchorPos().X() == 0 &&
2285 pObj
->GetAnchorPos().Y() == 0 )
2287 bApplyPosAtDrawObj
= true;
2288 if ( pObj
->GetUserCall() &&
2289 dynamic_cast<const SwDrawContact
*>( pObj
->GetUserCall()) != nullptr )
2291 bNoAdjustOfPosProp
= true;
2296 // shape isn't a group member. Thus, set positioning attributes
2297 if ( !bNoAdjustOfPosProp
)
2299 AdjustPositionProperties( aPosition
);
2301 if ( bApplyPosAtDrawObj
)
2303 mxShape
->setPosition( aPosition
);
2306 else if ( mxShape
.is() )
2308 // shape is a member of a group. Thus, set its position.
2309 awt::Point
aNewPos( aPosition
);
2310 // The given position is given in the according layout direction. Thus,
2311 // it has to be converted to a position in horizontal left-to-right
2313 // convert given absolute attribute position in layout direction into
2314 // position in horizontal left-to-right layout.
2316 aNewPos
= ConvertPositionToHoriL2R( aNewPos
, getSize() );
2318 // Convert given absolute position in horizontal left-to-right
2319 // layout into relative position in horizontal left-to-right layout.
2320 uno::Reference
< drawing::XShape
> xGroupShape( pTopGroupObj
->getUnoShape(), uno::UNO_QUERY
);
2323 // use method <xGroupShape->getPosition()> to get the correct
2324 // position of the top group object.
2325 awt::Point
aAttrPosInHoriL2R(
2326 ConvertPositionToHoriL2R( xGroupShape
->getPosition(),
2327 xGroupShape
->getSize() ) );
2328 aNewPos
.X
= o3tl::saturating_sub(aNewPos
.X
, aAttrPosInHoriL2R
.X
);
2329 aNewPos
.Y
= o3tl::saturating_sub(aNewPos
.Y
, aAttrPosInHoriL2R
.Y
);
2331 // convert relative position in horizontal left-to-right layout into
2332 // absolute position in horizontal left-to-right layout
2335 // use method <SvxShape->getPosition()> to get the correct
2336 // 'Drawing layer' position of the top group shape.
2337 auto pSvxGroupShape
= comphelper::getFromUnoTunnel
<SvxShape
>(pTopGroupObj
->getUnoShape());
2338 const awt::Point aGroupPos
= pSvxGroupShape
->getPosition();
2339 aNewPos
.X
= o3tl::saturating_add(aNewPos
.X
, aGroupPos
.X
);
2340 aNewPos
.Y
= o3tl::saturating_add(aNewPos
.Y
, aGroupPos
.Y
);
2343 mxShape
->setPosition( aNewPos
);
2347 awt::Size SAL_CALL
SwXShape::getSize()
2352 aSize
= mxShape
->getSize();
2357 void SAL_CALL
SwXShape::setSize( const awt::Size
& aSize
)
2359 comphelper::ProfileZone
aZone("SwXShape::setSize");
2363 mxShape
->setSize( aSize
);
2365 SwTextBoxHelper::syncProperty(GetFrameFormat(), RES_FRM_SIZE
, MID_FRMSIZE_SIZE
, uno::Any(aSize
));
2368 // implementation of virtual methods from drawing::XShapeDescriptor
2369 OUString SAL_CALL
SwXShape::getShapeType()
2373 return mxShape
->getShapeType();
2377 /** method to determine top group object
2380 SdrObject
* SwXShape::GetTopGroupObj( SvxShape
* _pSvxShape
)
2382 SdrObject
* pTopGroupObj( nullptr );
2384 SvxShape
* pSvxShape
= _pSvxShape
? _pSvxShape
: GetSvxShape();
2387 SdrObject
* pSdrObj
= pSvxShape
->GetSdrObject();
2388 if ( pSdrObj
&& pSdrObj
->getParentSdrObjectFromSdrObject() )
2390 pTopGroupObj
= pSdrObj
->getParentSdrObjectFromSdrObject();
2391 while ( pTopGroupObj
->getParentSdrObjectFromSdrObject() )
2393 pTopGroupObj
= pTopGroupObj
->getParentSdrObjectFromSdrObject();
2398 return pTopGroupObj
;
2401 /** method to determine position according to the positioning attributes
2404 awt::Point
SwXShape::GetAttrPosition()
2406 awt::Point aAttrPos
;
2408 uno::Any
aHoriPos( getPropertyValue(u
"HoriOrientPosition"_ustr
) );
2409 aHoriPos
>>= aAttrPos
.X
;
2410 uno::Any
aVertPos( getPropertyValue(u
"VertOrientPosition"_ustr
) );
2411 aVertPos
>>= aAttrPos
.Y
;
2412 // #i35798# - fallback, if attribute position is (0,0)
2413 // and no anchor position is applied to the drawing object
2414 SvxShape
* pSvxShape
= GetSvxShape();
2417 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2419 pObj
->GetAnchorPos().X() == 0 &&
2420 pObj
->GetAnchorPos().Y() == 0 &&
2421 aAttrPos
.X
== 0 && aAttrPos
.Y
== 0 )
2423 const tools::Rectangle aObjRect
= pObj
->GetSnapRect();
2424 aAttrPos
.X
= convertTwipToMm100(aObjRect
.Left());
2425 aAttrPos
.Y
= convertTwipToMm100(aObjRect
.Top());
2428 // #i35007# - If drawing object is anchored as-character,
2429 // it's x-position isn't sensible. Thus, return the x-position as zero in this case.
2430 text::TextContentAnchorType eTextAnchorType
=
2431 text::TextContentAnchorType_AT_PARAGRAPH
;
2433 uno::Any aAny
= getPropertyValue( u
"AnchorType"_ustr
);
2434 aAny
>>= eTextAnchorType
;
2436 if ( eTextAnchorType
== text::TextContentAnchorType_AS_CHARACTER
)
2444 /** method to convert the position (translation) of the drawing object to
2445 the layout direction horizontal left-to-right.
2448 awt::Point
SwXShape::ConvertPositionToHoriL2R( const awt::Point
& rObjPos
,
2449 const awt::Size
& rObjSize
)
2451 awt::Point
aObjPosInHoriL2R( rObjPos
);
2453 SwFrameFormat
* pFrameFormat
= GetFrameFormat();
2456 SwFrameFormat::tLayoutDir eLayoutDir
= pFrameFormat
->GetLayoutDir();
2457 switch ( eLayoutDir
)
2459 case SwFrameFormat::HORI_L2R
:
2464 case SwFrameFormat::HORI_R2L
:
2466 aObjPosInHoriL2R
.X
= -rObjPos
.X
- rObjSize
.Width
;
2469 case SwFrameFormat::VERT_R2L
:
2471 aObjPosInHoriL2R
.X
= -rObjPos
.Y
- rObjSize
.Width
;
2472 aObjPosInHoriL2R
.Y
= rObjPos
.X
;
2477 OSL_FAIL( "<SwXShape::ConvertPositionToHoriL2R(..)> - unsupported layout direction" );
2482 return aObjPosInHoriL2R
;
2485 /** method to convert the transformation of the drawing object to the layout
2486 direction, the drawing object is in
2489 drawing::HomogenMatrix3
SwXShape::ConvertTransformationToLayoutDir(
2490 const drawing::HomogenMatrix3
& rMatrixInHoriL2R
)
2492 drawing::HomogenMatrix3
aMatrix(rMatrixInHoriL2R
);
2494 // #i44334#, #i44681# - direct manipulation of the
2495 // transformation structure isn't valid, if it contains rotation.
2496 SvxShape
* pSvxShape
= GetSvxShape();
2497 OSL_ENSURE( pSvxShape
,
2498 "<SwXShape::ConvertTransformationToLayoutDir(..)> - no SvxShape found!");
2501 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2503 "<SwXShape::ConvertTransformationToLayoutDir(..)> - no SdrObject found!");
2506 // get position of object in Writer coordinate system.
2507 awt::Point
aPos( getPosition() );
2508 // get position of object in Drawing layer coordinate system
2509 const Point
aTmpObjPos( pObj
->GetSnapRect().TopLeft() );
2510 const awt::Point
aObjPos(
2511 convertTwipToMm100( aTmpObjPos
.X() - pObj
->GetAnchorPos().X() ),
2512 convertTwipToMm100( aTmpObjPos
.Y() - pObj
->GetAnchorPos().Y() ) );
2513 // determine difference between these positions according to the
2514 // Writer coordinate system
2515 const awt::Point
aTranslateDiff( aPos
.X
- aObjPos
.X
,
2516 aPos
.Y
- aObjPos
.Y
);
2517 // apply translation difference to transformation matrix.
2518 if ( aTranslateDiff
.X
!= 0 || aTranslateDiff
.Y
!= 0 )
2520 // #i73079# - use correct matrix type
2521 ::basegfx::B2DHomMatrix aTempMatrix
;
2523 aTempMatrix
.set(0, 0, aMatrix
.Line1
.Column1
);
2524 aTempMatrix
.set(0, 1, aMatrix
.Line1
.Column2
);
2525 aTempMatrix
.set(0, 2, aMatrix
.Line1
.Column3
);
2526 aTempMatrix
.set(1, 0, aMatrix
.Line2
.Column1
);
2527 aTempMatrix
.set(1, 1, aMatrix
.Line2
.Column2
);
2528 aTempMatrix
.set(1, 2, aMatrix
.Line2
.Column3
);
2529 // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
2530 assert( aMatrix
.Line3
.Column1
== 0 );
2531 assert( aMatrix
.Line3
.Column2
== 0 );
2532 assert( aMatrix
.Line3
.Column3
== 1 );
2534 aTempMatrix
.translate( aTranslateDiff
.X
, aTranslateDiff
.Y
);
2535 aMatrix
.Line1
.Column1
= aTempMatrix
.get(0, 0);
2536 aMatrix
.Line1
.Column2
= aTempMatrix
.get(0, 1);
2537 aMatrix
.Line1
.Column3
= aTempMatrix
.get(0, 2);
2538 aMatrix
.Line2
.Column1
= aTempMatrix
.get(1, 0);
2539 aMatrix
.Line2
.Column2
= aTempMatrix
.get(1, 1);
2540 aMatrix
.Line2
.Column3
= aTempMatrix
.get(1, 2);
2541 aMatrix
.Line3
.Column1
= 0;
2542 aMatrix
.Line3
.Column2
= 0;
2543 aMatrix
.Line3
.Column3
= 1;
2551 /** method to adjust the positioning properties
2554 void SwXShape::AdjustPositionProperties( const awt::Point
& rPosition
)
2556 // handle x-position
2557 // #i35007# - no handling of x-position, if drawing
2558 // object is anchored as-character, because it doesn't make sense.
2559 text::TextContentAnchorType eTextAnchorType
=
2560 text::TextContentAnchorType_AT_PARAGRAPH
;
2562 uno::Any aAny
= getPropertyValue( u
"AnchorType"_ustr
);
2563 aAny
>>= eTextAnchorType
;
2565 if ( eTextAnchorType
!= text::TextContentAnchorType_AS_CHARACTER
)
2567 // determine current x-position
2568 static constexpr OUString
aHoriPosPropStr(u
"HoriOrientPosition"_ustr
);
2569 uno::Any
aHoriPos( getPropertyValue( aHoriPosPropStr
) );
2570 sal_Int32 dCurrX
= 0;
2571 aHoriPos
>>= dCurrX
;
2572 // change x-position attribute, if needed
2573 if ( dCurrX
!= rPosition
.X
)
2575 // adjust x-position orientation to text::HoriOrientation::NONE, if needed
2576 // Note: has to be done before setting x-position attribute
2577 static constexpr OUString
aHoriOrientPropStr(u
"HoriOrient"_ustr
);
2578 uno::Any
aHoriOrient( getPropertyValue( aHoriOrientPropStr
) );
2579 sal_Int16 eHoriOrient
;
2580 if (aHoriOrient
>>= eHoriOrient
) // may be void
2582 if ( eHoriOrient
!= text::HoriOrientation::NONE
)
2584 eHoriOrient
= text::HoriOrientation::NONE
;
2585 aHoriOrient
<<= eHoriOrient
;
2586 setPropertyValue( aHoriOrientPropStr
, aHoriOrient
);
2589 // set x-position attribute
2590 aHoriPos
<<= rPosition
.X
;
2591 setPropertyValue( aHoriPosPropStr
, aHoriPos
);
2595 // handle y-position
2597 // determine current y-position
2598 static constexpr OUString
aVertPosPropStr(u
"VertOrientPosition"_ustr
);
2599 uno::Any
aVertPos( getPropertyValue( aVertPosPropStr
) );
2600 sal_Int32 dCurrY
= 0;
2601 aVertPos
>>= dCurrY
;
2602 // change y-position attribute, if needed
2603 if ( dCurrY
!= rPosition
.Y
)
2605 // adjust y-position orientation to text::VertOrientation::NONE, if needed
2606 // Note: has to be done before setting y-position attribute
2607 static constexpr OUString
aVertOrientPropStr(u
"VertOrient"_ustr
);
2608 uno::Any
aVertOrient( getPropertyValue( aVertOrientPropStr
) );
2609 sal_Int16 eVertOrient
;
2610 if (aVertOrient
>>= eVertOrient
) // may be void
2612 if ( eVertOrient
!= text::VertOrientation::NONE
)
2614 eVertOrient
= text::VertOrientation::NONE
;
2615 aVertOrient
<<= eVertOrient
;
2616 setPropertyValue( aVertOrientPropStr
, aVertOrient
);
2619 // set y-position attribute
2620 aVertPos
<<= rPosition
.Y
;
2621 setPropertyValue( aVertPosPropStr
, aVertPos
);
2626 /** method to convert start or end position of the drawing object to the
2627 Writer specific position, which is the attribute position in layout direction
2630 css::awt::Point
SwXShape::ConvertStartOrEndPosToLayoutDir(
2631 const css::awt::Point
& aStartOrEndPos
)
2633 awt::Point
aConvertedPos( aStartOrEndPos
);
2635 SvxShape
* pSvxShape
= GetSvxShape();
2636 OSL_ENSURE( pSvxShape
,
2637 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!");
2640 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2642 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!");
2645 // get position of object in Writer coordinate system.
2646 awt::Point
aPos( getPosition() );
2647 // get position of object in Drawing layer coordinate system
2648 const Point
aTmpObjPos( pObj
->GetSnapRect().TopLeft() );
2649 const awt::Point
aObjPos(
2650 convertTwipToMm100( aTmpObjPos
.X() - pObj
->GetAnchorPos().X() ),
2651 convertTwipToMm100( aTmpObjPos
.Y() - pObj
->GetAnchorPos().Y() ) );
2652 // determine difference between these positions according to the
2653 // Writer coordinate system
2654 const awt::Point
aTranslateDiff( aPos
.X
- aObjPos
.X
,
2655 aPos
.Y
- aObjPos
.Y
);
2656 // apply translation difference to transformation matrix.
2657 if ( aTranslateDiff
.X
!= 0 || aTranslateDiff
.Y
!= 0 )
2659 aConvertedPos
.X
= aConvertedPos
.X
+ aTranslateDiff
.X
;
2660 aConvertedPos
.Y
= aConvertedPos
.Y
+ aTranslateDiff
.Y
;
2665 return aConvertedPos
;
2668 css::drawing::PolyPolygonBezierCoords
SwXShape::ConvertPolyPolygonBezierToLayoutDir(
2669 const css::drawing::PolyPolygonBezierCoords
& aPath
)
2671 drawing::PolyPolygonBezierCoords
aConvertedPath( aPath
);
2673 SvxShape
* pSvxShape
= GetSvxShape();
2674 OSL_ENSURE( pSvxShape
,
2675 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!");
2678 const SdrObject
* pObj
= pSvxShape
->GetSdrObject();
2680 "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!");
2683 // get position of object in Writer coordinate system.
2684 awt::Point
aPos( getPosition() );
2685 // get position of object in Drawing layer coordinate system
2686 const Point
aTmpObjPos( pObj
->GetSnapRect().TopLeft() );
2687 const awt::Point
aObjPos(
2688 convertTwipToMm100( aTmpObjPos
.X() - pObj
->GetAnchorPos().X() ),
2689 convertTwipToMm100( aTmpObjPos
.Y() - pObj
->GetAnchorPos().Y() ) );
2690 // determine difference between these positions according to the
2691 // Writer coordinate system
2692 const awt::Point
aTranslateDiff( aPos
.X
- aObjPos
.X
,
2693 aPos
.Y
- aObjPos
.Y
);
2694 // apply translation difference to PolyPolygonBezier.
2695 if ( aTranslateDiff
.X
!= 0 || aTranslateDiff
.Y
!= 0 )
2697 const basegfx::B2DHomMatrix
aMatrix(basegfx::utils::createTranslateB2DHomMatrix(
2698 aTranslateDiff
.X
, aTranslateDiff
.Y
));
2700 for(drawing::PointSequence
& rInnerSequence
: asNonConstRange(aConvertedPath
.Coordinates
))
2702 for(awt::Point
& rPoint
: asNonConstRange(rInnerSequence
))
2704 basegfx::B2DPoint
aNewCoordinatePair(rPoint
.X
, rPoint
.Y
);
2705 aNewCoordinatePair
*= aMatrix
;
2706 rPoint
.X
= basegfx::fround(aNewCoordinatePair
.getX());
2707 rPoint
.Y
= basegfx::fround(aNewCoordinatePair
.getY());
2714 return aConvertedPath
;
2717 SwXGroupShape::SwXGroupShape(uno::Reference
<XInterface
> & xShape
,
2718 SwDoc
const*const pDoc
)
2719 : SwXShape(xShape
, pDoc
)
2721 #if OSL_DEBUG_LEVEL > 0
2722 uno::Reference
<XShapes
> xShapes(m_xShapeAgg
, uno::UNO_QUERY
);
2723 OSL_ENSURE(xShapes
.is(), "no SvxShape found or shape is not a group shape");
2727 SwXGroupShape::~SwXGroupShape()
2731 uno::Any
SwXGroupShape::queryInterface( const uno::Type
& rType
)
2734 if(rType
== cppu::UnoType
<XShapes
>::get())
2735 aRet
<<= uno::Reference
<XShapes
>(this);
2737 aRet
= SwXShape::queryInterface(rType
);
2741 void SwXGroupShape::acquire( ) noexcept
2743 SwXShape::acquire();
2746 void SwXGroupShape::release( ) noexcept
2748 SwXShape::release();
2751 void SwXGroupShape::add( const uno::Reference
< XShape
>& xShape
)
2753 SolarMutexGuard aGuard
;
2754 SvxShape
* pSvxShape
= GetSvxShape();
2755 SwFrameFormat
* pFormat
= GetFrameFormat();
2756 if(!(pSvxShape
&& pFormat
))
2757 throw uno::RuntimeException();
2759 uno::Reference
<XShapes
> xShapes
;
2760 if( m_xShapeAgg
.is() )
2762 const uno::Type
& rType
= cppu::UnoType
<XShapes
>::get();
2763 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2767 throw uno::RuntimeException();
2769 xShapes
->add(xShape
);
2772 uno::Reference
<lang::XUnoTunnel
> xTunnel(xShape
, uno::UNO_QUERY
);
2773 SwXShape
* pSwShape
= comphelper::getFromUnoTunnel
<SwXShape
>(xTunnel
);
2774 if(!(pSwShape
&& pSwShape
->m_bDescriptor
))
2777 SvxShape
* pAddShape
= comphelper::getFromUnoTunnel
<SvxShape
>(xTunnel
);
2780 SdrObject
* pObj
= pAddShape
->GetSdrObject();
2783 SwDoc
* pDoc
= pFormat
->GetDoc();
2784 // set layer of new drawing
2785 // object to corresponding invisible layer.
2786 if( SdrInventor::FmForm
!= pObj
->GetObjInventor())
2788 pObj
->SetLayer( pSwShape
->m_pImpl
->GetOpaque()
2789 ? pDoc
->getIDocumentDrawModelAccess().GetInvisibleHeavenId()
2790 : pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId() );
2794 pObj
->SetLayer(pDoc
->getIDocumentDrawModelAccess().GetInvisibleControlsId());
2798 pSwShape
->m_bDescriptor
= false;
2801 void SwXGroupShape::remove( const uno::Reference
< XShape
>& xShape
)
2803 SolarMutexGuard aGuard
;
2804 uno::Reference
<XShapes
> xShapes
;
2805 if( m_xShapeAgg
.is() )
2807 const uno::Type
& rType
= cppu::UnoType
<XShapes
>::get();
2808 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2812 throw uno::RuntimeException();
2813 xShapes
->remove(xShape
);
2816 sal_Int32
SwXGroupShape::getCount()
2818 SolarMutexGuard aGuard
;
2819 uno::Reference
<XIndexAccess
> xAcc
;
2820 if( m_xShapeAgg
.is() )
2822 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2823 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2827 throw uno::RuntimeException();
2828 return xAcc
->getCount();
2831 uno::Any
SwXGroupShape::getByIndex(sal_Int32 nIndex
)
2833 SolarMutexGuard aGuard
;
2834 uno::Reference
<XIndexAccess
> xAcc
;
2835 if( m_xShapeAgg
.is() )
2837 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2838 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2842 throw uno::RuntimeException();
2843 return xAcc
->getByIndex(nIndex
);
2846 uno::Type
SwXGroupShape::getElementType( )
2848 SolarMutexGuard aGuard
;
2849 uno::Reference
<XIndexAccess
> xAcc
;
2850 if( m_xShapeAgg
.is() )
2852 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2853 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2857 throw uno::RuntimeException();
2858 return xAcc
->getElementType();
2861 sal_Bool
SwXGroupShape::hasElements( )
2863 SolarMutexGuard aGuard
;
2864 uno::Reference
<XIndexAccess
> xAcc
;
2865 if( m_xShapeAgg
.is() )
2867 const uno::Type
& rType
= cppu::UnoType
<XIndexAccess
>::get();
2868 uno::Any aAgg
= m_xShapeAgg
->queryAggregation( rType
);
2872 throw uno::RuntimeException();
2873 return xAcc
->hasElements();
2876 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */