Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/source/core/unocore/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 106 kB image not shown  

Quelle  unodraw.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <sal/config.h>

#include <initializer_list>
#include <memory>
#include <string_view>

#include <sal/log.hxx>

#include <cmdid.h>
#include <unomid.h>

#include <drawdoc.hxx>
#include <unodraw.hxx>
#include <unoframe.hxx>
#include <unoparagraph.hxx>
#include <unotextrange.hxx>
#include <svx/svditer.hxx>
#include <swunohelper.hxx>
#include <textboxhelper.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <fmtcntnt.hxx>
#include <fmtflcnt.hxx>
#include <txatbase.hxx>
#include <docsh.hxx>
#include <unomap.hxx>
#include <unoport.hxx>
#include <TextCursorHelper.hxx>
#include <dflyobj.hxx>
#include <ndtxt.hxx>
#include <svx/svdview.hxx>
#include <svx/unoshape.hxx>
#include <dcontact.hxx>
#include <fmtornt.hxx>
#include <fmtsrnd.hxx>
#include <fmtfollowtextflow.hxx>
#include <rootfrm.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <o3tl/any.hxx>
#include <o3tl/safeint.hxx>
#include <crstate.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/profilezone.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <svx/scene3d.hxx>
#include <tools/UnitConversion.hxx>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <fmtwrapinfluenceonobjpos.hxx>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <com/sun/star/drawing/PointSequence.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <docmodel/uno/UnoTheme.hxx>

using namespace ::com::sun::star;

class SwShapeDescriptor_Impl
{
    bool m_isInReading;
    std::unique_ptr<SwFormatHoriOrient> m_pHOrient;
    std::unique_ptr<SwFormatVertOrient> m_pVOrient;
    std::unique_ptr<SwFormatAnchor> m_pAnchor;
    std::unique_ptr<SwFormatSurround> m_pSurround;
    std::unique_ptr<SvxULSpaceItem> m_pULSpace;
    std::unique_ptr<SvxLRSpaceItem> m_pLRSpace;
    bool            m_bOpaque;
    uno::Reference< text::XTextRange > m_xTextRange;
    // #i26791#
    std::unique_ptr<SwFormatFollowTextFlow> m_pFollowTextFlow;
    // #i28701#
    std::unique_ptr<SwFormatWrapInfluenceOnObjPos> m_pWrapInfluenceOnObjPos;
    // #i28749#
    sal_Int16 mnPositionLayoutDir;

    SwShapeDescriptor_Impl(const SwShapeDescriptor_Impl&) = delete;
    SwShapeDescriptor_Impl& operator=(const SwShapeDescriptor_Impl&) = delete;

public:
    SwShapeDescriptor_Impl(SwDoc const*const pDoc)
        : m_isInReading(pDoc && pDoc->IsInReading())
     // #i32349# - no defaults, in order to determine on
     // adding a shape, if positioning attributes are set or not.
        , m_bOpaque(false)
     // #i26791#
        , m_pFollowTextFlow( new SwFormatFollowTextFlow(false) )
     // #i28701# #i35017#
        , m_pWrapInfluenceOnObjPos( new SwFormatWrapInfluenceOnObjPos(
                            text::WrapInfluenceOnPosition::ONCE_CONCURRENT) )
     // #i28749#
        , mnPositionLayoutDir(text::PositionLayoutDir::PositionInLayoutDirOfAnchor)
     {}

    SwFormatAnchor*    GetAnchor(bool bCreate = false)
        {
            if (bCreate && !m_pAnchor)
            {
                m_pAnchor.reset(new SwFormatAnchor(RndStdIds::FLY_AS_CHAR));
            }
            return m_pAnchor.get();
        }
    SwFormatHoriOrient* GetHOrient(bool bCreate = false)
        {
            if (bCreate && !m_pHOrient)
            {
                // #i26791#
                m_pHOrient.reset(new SwFormatHoriOrient(0, text::HoriOrientation::NONE, text::RelOrientation::FRAME));
            }
            return m_pHOrient.get();
        }
    SwFormatVertOrient* GetVOrient(bool bCreate = false)
        {
            if (bCreate && !m_pVOrient)
            {
                if (m_isInReading && // tdf#113938 extensions might rely on old default
                    (!GetAnchor(true) || m_pAnchor->GetAnchorId() == RndStdIds::FLY_AS_CHAR))
                {   // for as-char, NONE ("from-top") is not a good default
                    m_pVOrient.reset(new SwFormatVertOrient(0, text::VertOrientation::TOP, text::RelOrientation::FRAME));
                }
                else
                {   // #i26791#
                    m_pVOrient.reset(new SwFormatVertOrient(0, text::VertOrientation::NONE, text::RelOrientation::FRAME));
                }
            }
            return m_pVOrient.get();
        }

    SwFormatSurround*  GetSurround(bool bCreate = false)
        {
            if (bCreate && !m_pSurround)
            {
                m_pSurround.reset(new SwFormatSurround());
            }
            return m_pSurround.get();
        }
    SvxLRSpaceItem* GetLRSpace(bool bCreate = false)
        {
            if (bCreate && !m_pLRSpace)
            {
                m_pLRSpace.reset(new SvxLRSpaceItem(RES_LR_SPACE));
            }
            return m_pLRSpace.get();
        }
    SvxULSpaceItem* GetULSpace(bool bCreate = false)
        {
            if (bCreate && !m_pULSpace)
            {
                m_pULSpace.reset(new SvxULSpaceItem(RES_UL_SPACE));
            }
            return m_pULSpace.get();
        }
    uno::Reference< text::XTextRange > &    GetTextRange()
    {
        return m_xTextRange;
    }
    bool    IsOpaque() const
        {
            return m_bOpaque;
        }
    const bool&    GetOpaque() const
        {
            return m_bOpaque;
        }
    void RemoveHOrient() { m_pHOrient.reset(); }
    void RemoveVOrient() { m_pVOrient.reset(); }
    void RemoveAnchor() { m_pAnchor.reset(); }
    void RemoveSurround() { m_pSurround.reset(); }
    void RemoveULSpace() { m_pULSpace.reset(); }
    void RemoveLRSpace() { m_pLRSpace.reset(); }
    void SetOpaque(bool bSet){m_bOpaque = bSet;}

    // #i26791#
    SwFormatFollowTextFlow* GetFollowTextFlow( bool _bCreate = false )
    {
        if (_bCreate && !m_pFollowTextFlow)
        {
            m_pFollowTextFlow.reset(new SwFormatFollowTextFlow(false));
        }
        return m_pFollowTextFlow.get();
    }
    void RemoveFollowTextFlow()
    {
        m_pFollowTextFlow.reset();
    }

    // #i28749#
    sal_Int16 GetPositionLayoutDir() const
    {
        return mnPositionLayoutDir;
    }
    void SetPositionLayoutDir( sal_Int16 _nPositionLayoutDir )
    {
        switch ( _nPositionLayoutDir )
        {
            case text::PositionLayoutDir::PositionInHoriL2R:
            case text::PositionLayoutDir::PositionInLayoutDirOfAnchor:
            {
                mnPositionLayoutDir = _nPositionLayoutDir;
            }
            break;
            default:
            {
                OSL_FAIL( " - invalid attribute value." );
            }
        }
    }

    // #i28701#
    SwFormatWrapInfluenceOnObjPos* GetWrapInfluenceOnObjPos(
                                        const bool _bCreate = false )
    {
        if (_bCreate && !m_pWrapInfluenceOnObjPos)
        {
            m_pWrapInfluenceOnObjPos.reset(new SwFormatWrapInfluenceOnObjPos(
                        // #i35017#
                        text::WrapInfluenceOnPosition::ONCE_CONCURRENT));
        }
        return m_pWrapInfluenceOnObjPos.get();
    }
    void RemoveWrapInfluenceOnObjPos()
    {
        m_pWrapInfluenceOnObjPos.reset();
    }
};

SwFmDrawPage::SwFmDrawPage( SwDoc* pDoc, SdrPage* pPage )
    : SwFmDrawPage_Base(pPage)
    , m_pDoc(pDoc)
    , m_pPageView(nullptr)
    , m_pPropertySet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_PAGE))
{
}

SwFmDrawPage::~SwFmDrawPage() noexcept
{
    while (!m_vShapes.empty())
        m_vShapes.back()->dispose();
    RemovePageView();
}

const SdrMarkList&  SwFmDrawPage::PreGroup(const uno::Reference< drawing::XShapes > &&nbsp;xShapes)
{
    SelectObjectsInView( xShapes, GetPageView() );
    const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
    return rMarkList;
}

void SwFmDrawPage::PreUnGroup(const uno::Reference< drawing::XShapeGroup >&  rShapeGroup)
{
    SelectObjectInView( rShapeGroup, GetPageView() );
}

SdrPageView*    SwFmDrawPage::GetPageView()
{
    if(!m_pPageView)
        m_pPageView = mpView->ShowSdrPage( mpPage );
    return m_pPageView;
}

void    SwFmDrawPage::RemovePageView()
{
    if(m_pPageView && mpView)
        mpView->HideSdrPage();
    m_pPageView = nullptr;
}

uno::Reference<drawing::XShape> SwFmDrawPage::GetShape(SdrObject* pObj)
{
    if(!pObj)
        return nullptr;
    SwFrameFormat* pFormat = ::FindFrameFormat( pObj );
    // TODO see comment at
    // <https://gerrit.libreoffice.org/c/core/+/78734/4#message-5ee4e724a8073c5c475f07da0b5d79bc34e61de5>
    // "make page bookkeep the SwXShapes" [-loplugin:crosscast]:
    SwFmDrawPage* pPage = dynamic_cast<SwFmDrawPage*>(pFormat);
    if(!pPage || pPage->m_vShapes.empty())
        return uno::Reference<drawing::XShape>(pObj->getUnoShape(), uno::UNO_QUERY);
    for(const auto & pShape : pPage->m_vShapes)
    {
        SvxShape* pSvxShape = pShape->GetSvxShape();
        if (pSvxShape && pSvxShape->GetSdrObject() == pObj)
            return pShape;
    }
    return nullptr;
}

uno::Reference<drawing::XShapeGroup> SwFmDrawPage::GetShapeGroup(SdrObject* pObj)
{
    return uno::Reference<drawing::XShapeGroup>(GetShape(pObj), uno::UNO_QUERY);
}

uno::Reference< drawing::XShape > SwFmDrawPage::CreateShape( SdrObject *pObj ) const
{
    assert(pObj);
    uno::Reference< drawing::XShape >  xRet;
    if(dynamic_cast<const SwVirtFlyDrawObj*>( pObj) !=  nullptr || pObj->GetObjInventor() == SdrInventor::Swg)
    {
        SwFlyDrawContact* pFlyContact = static_cast<SwFlyDrawContact*>(pObj->GetUserCall());
        if(pFlyContact)
        {
            SwFrameFormat* pFlyFormat = pFlyContact->GetFormat();
            SwDoc& rDoc = pFlyFormat->GetDoc();
            const SwNodeIndex* pIdx;
            if( RES_FLYFRMFMT == pFlyFormat->Which()
                && nullptr != ( pIdx = pFlyFormat->GetContent().GetContentIdx() )
                && pIdx->GetNodes().IsDocNodes()
                )
            {
                const SwNode* pNd = rDoc.GetNodes()[ pIdx->GetIndex() + 1 ];
                if(!pNd->IsNoTextNode())
                {
                    xRet.set(cppu::getXWeak(SwXTextFrame::CreateXTextFrame(rDoc, pFlyFormat).get()),
                            uno::UNO_QUERY);
                }
                else if( pNd->IsGrfNode() )
                {
                    xRet.set(cppu::getXWeak(SwXTextGraphicObject::CreateXTextGraphicObject(
                                rDoc, pFlyFormat).get()), uno::UNO_QUERY);
                }
                else if( pNd->IsOLENode() )
                {
                    xRet.set(cppu::getXWeak(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
                                rDoc, pFlyFormat).get()), uno::UNO_QUERY);
                }
            }
            else
            {
                OSL_FAIL( " - could not retrieve type. Thus, no shape created." );
                return xRet;
            }
        }
    }
    else
    {
        // own block - temporary object has to be destroyed before
        // the delegator is set #81670#
        {
            xRet = SvxDrawPage::CreateShape( pObj );
        }
        uno::Reference< XUnoTunnel > xShapeTunnel(xRet, uno::UNO_QUERY);
        //don't create an SwXShape if it already exists
        rtl::Reference<SwXShape> pShape = comphelper::getFromUnoTunnel<SwXShape>(xShapeTunnel);
        if(!pShape)
        {
            xShapeTunnel = nullptr;
            uno::Reference< uno::XInterface > xCreate(xRet, uno::UNO_QUERY);
            xRet = nullptr;
            if ( pObj->IsGroupObject() && (!pObj->Is3DObj() || DynCastE3dScene(pObj)) )
                pShape = new SwXGroupShape(xCreate, nullptr);
            else
                pShape = new SwXShape(xCreate, nullptr);
            xRet = pShape;
        }
        const_cast<std::vector<rtl::Reference<SwXShape>>*>(&m_vShapes)->push_back(pShape);
        pShape->m_pPage = this;
    }
    return xRet;
}

uno::Reference<beans::XPropertySetInfo> SwFmDrawPage::getPropertySetInfo()
{
    static uno::Reference<beans::XPropertySetInfo> xRet = m_pPropertySet->getPropertySetInfo();
    return xRet;
}

void SwFmDrawPage::setPropertyValue(const OUString& rPropertyName, const uno::Any&&nbsp;aValue)
{
    SolarMutexGuard aGuard;
    const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName(rPropertyName);

    switch (pEntry ? pEntry->nWID : -1)
    {
        case WID_PAGE_THEME:
        {
            SdrPage* pPage = GetSdrPage();
            css::uno::Reference<css::util::XTheme> xTheme;
            if (aValue >>= xTheme)
            {
                auto& rUnoTheme = dynamic_cast<UnoTheme&>(*xTheme);
                pPage->getSdrModelFromSdrPage().setTheme(rUnoTheme.getTheme());
            }
        }
        break;
        case WID_PAGE_BOTTOM:
        case WID_PAGE_LEFT:
        case WID_PAGE_RIGHT:
        case WID_PAGE_TOP:
        case WID_PAGE_WIDTH:
        case WID_PAGE_HEIGHT:
        case WID_PAGE_NUMBER:
        case WID_PAGE_ORIENT:
        case WID_PAGE_USERATTRIBS:
        case WID_PAGE_ISDARK:
        case WID_NAVORDER:
        case WID_PAGE_BACKFULL:
            break;

        default:
            throw beans::UnknownPropertyException(rPropertyName, getXWeak());
    }
}

uno::Any SwFmDrawPage::getPropertyValue(const OUString& rPropertyName)
{
    SolarMutexGuard aGuard;
    const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName);

    uno::Any aAny;

    switch (pEntry ? pEntry->nWID : -1)
    {
        case WID_PAGE_THEME:
        {
            css::uno::Reference<css::util::XTheme> xTheme;

            auto pTheme = GetSdrPage()->getSdrModelFromSdrPage().getTheme();
            if (pTheme)
                xTheme = model::theme::createXTheme(pTheme);
            aAny <<= xTheme;
        }
        break;

        case WID_PAGE_NUMBER:
        {
            const sal_uInt16 nPageNumber(GetSdrPage()->GetPageNum());
            aAny <<= o3tl::narrowing<sal_Int16>(nPageNumber);
        }
        break;

        case WID_PAGE_BOTTOM:
        case WID_PAGE_LEFT:
        case WID_PAGE_RIGHT:
        case WID_PAGE_TOP:
        case WID_PAGE_WIDTH:
        case WID_PAGE_HEIGHT:
        case WID_PAGE_ORIENT:
        case WID_PAGE_USERATTRIBS:
        case WID_PAGE_ISDARK:
        case WID_NAVORDER:
        case WID_PAGE_BACKFULL:
            break;

        default:
            throw beans::UnknownPropertyException(rPropertyName, getXWeak());
    }
    return aAny;
}

void SwFmDrawPage::addPropertyChangeListener(const OUString& /*PropertyName*/,
    const uno::Reference<beans::XPropertyChangeListener> & /*aListener*/)
{
    OSL_FAIL("not implemented");
}

void SwFmDrawPage::removePropertyChangeListener(const OUString& /*PropertyName*/,
    const uno::Reference<beans::XPropertyChangeListener> & /*aListener*/)
{
    OSL_FAIL("not implemented");
}

void SwFmDrawPage::addVetoableChangeListener(const OUString& /*PropertyName*/,
    const uno::Reference<beans::XVetoableChangeListener> & /*aListener*/)
{
    OSL_FAIL("not implemented");
}

void SwFmDrawPage::removeVetoableChangeListener(const OUString& /*PropertyName*/,
    const uno::Reference<beans::XVetoableChangeListener> & /*aListener*/)
{
    OSL_FAIL("not implemented");
}

namespace
{
    class SwXShapesEnumeration
        : public SwSimpleEnumeration_Base
    {
        private:
            std::vector< css::uno::Any > m_aShapes;
        protected:
            virtual ~SwXShapesEnumeration() override {};
        public:
            explicit SwXShapesEnumeration(SwFmDrawPage* const pDrawPage);

            //XEnumeration
            virtual sal_Bool SAL_CALL hasMoreElements() override;
            virtual uno::Any SAL_CALL nextElement() override;

            //XServiceInfo
            virtual OUString SAL_CALL getImplementationName() override;
            virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
            virtual uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
    };
}

SwXShapesEnumeration::SwXShapesEnumeration(SwFmDrawPage* const pDrawPage)
{
    SolarMutexGuard aGuard;
    sal_Int32 nCount = pDrawPage->getCount();
    m_aShapes.reserve(nCount);
    for(sal_Int32 nIdx = 0; nIdx < nCount; nIdx++)
    {
        uno::Reference<drawing::XShape> xShape(pDrawPage->getByIndex(nIdx), uno::UNO_QUERY);
        m_aShapes.push_back(uno::Any(xShape));
    }
}

sal_Bool SwXShapesEnumeration::hasMoreElements()
{
    SolarMutexGuard aGuard;
    return !m_aShapes.empty();
}

uno::Any SwXShapesEnumeration::nextElement()
{
    SolarMutexGuard aGuard;
    if(m_aShapes.empty())
        throw container::NoSuchElementException();
    uno::Any aResult = m_aShapes.back();
    m_aShapes.pop_back();
    return aResult;
}

OUString SwXShapesEnumeration::getImplementationName()
{
    return u"SwXShapeEnumeration"_ustr;
}

sal_Bool SwXShapesEnumeration::supportsService(const OUString& ServiceName)
{
    return cppu::supportsService(this, ServiceName);
}

uno::Sequence< OUString > SwXShapesEnumeration::getSupportedServiceNames()
{
    return { u"com.sun.star.container.XEnumeration"_ustr };
}

uno::Reference< container::XEnumeration > SwFmDrawPage::createEnumeration()
{
    SolarMutexGuard aGuard;
    return uno::Reference< container::XEnumeration >(
        new SwXShapesEnumeration(this));
}

OUString SwFmDrawPage::getImplementationName()
{
    return u"SwFmDrawPage"_ustr;
}

sal_Bool SwFmDrawPage::supportsService(const OUString& rServiceName)
{
    return cppu::supportsService(this, rServiceName);
}

uno::Sequence< OUString > SwFmDrawPage::getSupportedServiceNames()
{
    return { u"com.sun.star.drawing.GenericDrawPage"_ustr };
}

sal_Int32 SwFmDrawPage::getCount()
{
    SolarMutexGuard aGuard;
    if(!m_pDoc)
        throw uno::RuntimeException();
    if(!m_pDoc->getIDocumentDrawModelAccess().GetDrawModel())
        return 0;
    else
        return SwTextBoxHelper::getCount(GetSdrPage());
}

uno::Any SwFmDrawPage::getByIndex(sal_Int32 nIndex)
{
    SolarMutexGuard aGuard;
    if(!m_pDoc)
        throw uno::RuntimeException();
    if(!m_pDoc->getIDocumentDrawModelAccess().GetDrawModel())
        throw lang::IndexOutOfBoundsException();

    return SwTextBoxHelper::getByIndex(GetSdrPage(), nIndex);
}

uno::Type  SwFmDrawPage::getElementType()
{
    return cppu::UnoType<drawing::XShape>::get();
}

sal_Bool SwFmDrawPage::hasElements()
{
    SolarMutexGuard aGuard;
    if(!m_pDoc)
        throw uno::RuntimeException();
    if(!m_pDoc->getIDocumentDrawModelAccess().GetDrawModel())
        return false;
    return SvxDrawPage::hasElements();
}

void SwFmDrawPage::add(const uno::Reference< drawing::XShape > & xShape)
{
    SolarMutexGuard aGuard;
    if(!m_pDoc)
        throw uno::RuntimeException();
    uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShape, uno::UNO_QUERY);
    SwXShape* pShape = comphelper::getFromUnoTunnel<SwXShape>(xShapeTunnel);
    SvxShape* pSvxShape = comphelper::getFromUnoTunnel<SvxShape>(xShapeTunnel);

    // this is not a writer shape
    if(!pShape)
        throw uno::RuntimeException(u"illegal object"_ustr,
                                    getXWeak() );

    // we're already registered in the model / SwXDrawPage::add() already called
    if(pShape->m_pPage || !pShape->m_bDescriptor )
        return;

    // we're inserted elsewhere already
    if ( pSvxShape->GetSdrObject() )
    {
        if ( pSvxShape->GetSdrObject()->IsInserted() )
        {
            return;
        }
    }
    SvxDrawPage::add(xShape);

    OSL_ENSURE(pSvxShape, "Why is here no SvxShape?");
    // this position is definitely in 1/100 mm
    awt::Point aMM100Pos(pSvxShape->getPosition());

    // now evaluate the properties of SwShapeDescriptor_Impl
    SwShapeDescriptor_Impl* pDesc = pShape->GetDescImpl();

    SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSet( m_pDoc->GetAttrPool() );
    SwFormatAnchor aAnchor( RndStdIds::FLY_AS_CHAR );
    bool bOpaque = false;
    if( pDesc )
    {
        if(pDesc->GetSurround())
            aSet.Put( *pDesc->GetSurround());
        // all items are already in Twip
        if(pDesc->GetLRSpace())
        {
            aSet.Put(*pDesc->GetLRSpace());
        }
        if(pDesc->GetULSpace())
        {
            aSet.Put(*pDesc->GetULSpace());
        }
        if(pDesc->GetAnchor())
            aAnchor = *pDesc->GetAnchor();

        // #i32349# - if no horizontal position exists, create one
        if ( !pDesc->GetHOrient() )
        {
            SwFormatHoriOrient* pHori = pDesc->GetHOrient( true );
            SwTwips nHoriPos = o3tl::toTwips(aMM100Pos.X, o3tl::Length::mm100);
            pHori->SetPos( nHoriPos );
        }
        {
            if(pDesc->GetHOrient()->GetHoriOrient() == text::HoriOrientation::NONE)
                aMM100Pos.X = convertTwipToMm100(pDesc->GetHOrient()->GetPos());
            aSet.Put( *pDesc->GetHOrient() );
        }
        // #i32349# - if no vertical position exists, create one
        if ( !pDesc->GetVOrient() )
        {
            SwFormatVertOrient* pVert = pDesc->GetVOrient( true );
            SwTwips nVertPos = o3tl::toTwips(aMM100Pos.Y, o3tl::Length::mm100);
            pVert->SetPos( nVertPos );
        }
        {
            if(pDesc->GetVOrient()->GetVertOrient() == text::VertOrientation::NONE)
                aMM100Pos.Y = convertTwipToMm100(pDesc->GetVOrient()->GetPos());
            aSet.Put( *pDesc->GetVOrient() );
        }

        if(pDesc->GetSurround())
            aSet.Put( *pDesc->GetSurround());
        bOpaque = pDesc->IsOpaque();

        // #i26791#
        if ( pDesc->GetFollowTextFlow() )
        {
            aSet.Put( *pDesc->GetFollowTextFlow() );
        }

        // #i28701#
        if ( pDesc->GetWrapInfluenceOnObjPos() )
        {
            aSet.Put( *pDesc->GetWrapInfluenceOnObjPos() );
        }
    }

    pSvxShape->setPosition(aMM100Pos);
    SdrObject* pObj = pSvxShape->GetSdrObject();
    // #108784# - set layer of new drawing object to corresponding
    // invisible layer.
    if(SdrInventor::FmForm != pObj->GetObjInventor())
        pObj->SetLayer( bOpaque ? m_pDoc->getIDocumentDrawModelAccess().GetInvisibleHeavenId() : m_pDoc->getIDocumentDrawModelAccess().GetInvisibleHellId() );
    else
        pObj->SetLayer(m_pDoc->getIDocumentDrawModelAccess().GetInvisibleControlsId());

    std::optional<SwPaM> pPam(m_pDoc->GetNodes().GetEndOfContent());
    std::unique_ptr<SwUnoInternalPaM> pInternalPam;
    uno::Reference< text::XTextRange >  xRg;
    if( pDesc && (xRg = pDesc->GetTextRange()).is() )
    {
        pInternalPam.reset(new SwUnoInternalPaM(*m_pDoc));
        if (!::sw::XTextRangeToSwPaM(*pInternalPam, xRg))
            throw uno::RuntimeException();

        if(RndStdIds::FLY_AT_FLY == aAnchor.GetAnchorId() &&
                            !pInternalPam->GetPointNode().FindFlyStartNode())
        {
                    aAnchor.SetType(RndStdIds::FLY_AS_CHAR);
        }
        else if (RndStdIds::FLY_AT_PAGE == aAnchor.GetAnchorId()
                    && 0 == aAnchor.GetPageNum())
        {
            aAnchor.SetAnchor(pInternalPam->Start());
            aAnchor.SetType(RndStdIds::FLY_AT_CHAR); // convert invalid at-page
        }

    }
    else if ((aAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE) && m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout())
    {
        SwCursorMoveState aState( CursorMoveState::SetOnlyText );
        Point aTmp(o3tl::toTwips(aMM100Pos.X, o3tl::Length::mm100), o3tl::toTwips(aMM100Pos.Y, o3tl::Length::mm100));
        m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( pPam->GetPoint(), aTmp, &aState );
        aAnchor.SetAnchor( pPam->GetPoint() );

        // #i32349# - adjustment of vertical positioning
        // attributes no longer needed, because it's already got a default.
    }
    else
    {
        aAnchor.SetType(RndStdIds::FLY_AT_PAGE);

        // #i32349# - adjustment of vertical positioning
        // attributes no longer needed, because it's already got a default.
    }
    aSet.Put(aAnchor);
    SwPaM* pTemp = pInternalPam.get();
    if ( !pTemp )
        pTemp = &*pPam;
    UnoActionContext aAction(m_pDoc);
    m_pDoc->getIDocumentContentOperations().InsertDrawObj( *pTemp, *pObj, aSet );

    if (pSvxShape->GetSdrObject()->GetName().isEmpty())
    {
        pSvxShape->GetSdrObject()->SetName(m_pDoc->GetUniqueShapeName().toString());
    }

    SwFrameFormat* pFormat = ::FindFrameFormat( pObj );
    if (pFormat)
    {
        if (pFormat->GetName().isEmpty())
        {
            pFormat->SetFormatName(UIName(pSvxShape->GetSdrObject()->GetName()), false);
        }
    }
    pShape->m_bDescriptor = false;

    pPam.reset();
    pInternalPam.reset();
}

void SwFmDrawPage::remove(const uno::Reference< drawing::XShape > & xShape)
{
    SolarMutexGuard aGuard;
    if(!m_pDoc)
        throw uno::RuntimeException();
    // tdf#41466 remove TextFrame too which is belonged to the actual shape
    auto xTextFrame = SwTextBoxHelper::getUnoTextFrame(xShape);
    if (xTextFrame)
    {
        uno::Reference<lang::XComponent> xComp(xTextFrame, uno::UNO_QUERY);
        if (xComp)
            xComp->dispose();
    }
    // remove shape
    uno::Reference<lang::XComponent> xComp(xShape, uno::UNO_QUERY);
    xComp->dispose();
}

uno::Reference< drawing::XShapeGroup >  SwFmDrawPage::group(const uno::Reference< drawing::XShapes > & xShapes)
{
    SolarMutexGuard aGuard;
    if(!m_pDoc || !xShapes.is())
        throw uno::RuntimeException();
    uno::Reference< drawing::XShapeGroup >  xRet;
    // mark and return MarkList
    const SdrMarkList& rMarkList = PreGroup(xShapes);
    if ( rMarkList.GetMarkCount() > 0 )
    {
        for (size_t i = 0; i < rMarkList.GetMarkCount(); ++i)
        {
            const SdrObject *pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
            if (RndStdIds::FLY_AS_CHAR == ::FindFrameFormat(const_cast<SdrObject*>(
                                    pObj))->GetAnchor().GetAnchorId())
            {
                throw lang::IllegalArgumentException(
                    u"Shape must not have 'as character' anchor!"_ustr, nullptr, 0);
            }
        }

        UnoActionContext aContext(m_pDoc);
        m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );

        SwDrawContact* pContact = m_pDoc->GroupSelection( *GetDrawView() );
        m_pDoc->ChgAnchor(
            GetDrawView()->GetMarkedObjectList(),
            RndStdIds::FLY_AT_PARA,
            truefalse );

        GetDrawView()->UnmarkAll();
        if(pContact)
            xRet = SwFmDrawPage::GetShapeGroup( pContact->GetMaster() );
        m_pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
    }
    RemovePageView();
    return xRet;
}

void SwFmDrawPage::ungroup(const uno::Reference< drawing::XShapeGroup > & rShapeGroup)
{
    SolarMutexGuard aGuard;
    if(!m_pDoc)
        throw uno::RuntimeException();

    PreUnGroup(rShapeGroup);
    UnoActionContext aContext(m_pDoc);
    m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );

    m_pDoc->UnGroupSelection( *GetDrawView() );
    m_pDoc->ChgAnchor( GetDrawView()->GetMarkedObjectList(),
                RndStdIds::FLY_AT_PARA,
                truefalse );
    m_pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
    RemovePageView();
}

/**
 * Renamed and outlined to detect where it's called
 */

void SwFmDrawPage::InvalidateSwDoc()
{
    m_pDoc = nullptr;
}

const uno::Sequence< sal_Int8 > & SwXShape::getUnoTunnelId()
{
    static const comphelper::UnoIdInit theSwXShapeUnoTunnelId;
    return theSwXShapeUnoTunnelId.getSeq();
}

sal_Int64 SAL_CALL SwXShape::getSomething( const uno::Sequence< sal_Int8 >& rId )
{
    if( comphelper::isUnoTunnelId<SwXShape>(rId) )
    {
        return comphelper::getSomething_cast(this);
    }

    if( m_xShapeAgg.is() )
    {
        const uno::Type& rTunnelType = cppu::UnoType<lang::XUnoTunnel>::get();
        uno::Any aAgg = m_xShapeAgg->queryAggregation( rTunnelType );
        if(auto xAggTunnel = o3tl::tryAccess<uno::Reference<lang::XUnoTunnel>>(
               aAgg))
        {
            if(xAggTunnel->is())
                return (*xAggTunnel)->getSomething(rId);
        }
    }
    return 0;
}

SwXShape::SwXShape(
        uno::Reference<uno::XInterface> & xShape,
        SwDoc const*const pDoc)
    : m_pPage(nullptr)
    , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_SHAPE))
    , m_pPropertyMapEntries(aSwMapProvider.GetPropertyMapEntries(PROPERTY_MAP_TEXT_SHAPE))
    , m_pImpl(new SwShapeDescriptor_Impl(pDoc))
    , m_bDescriptor(true)
{
    if(!xShape.is())  // default Ctor
        return;

    const uno::Type& rAggType = cppu::UnoType<uno::XAggregation>::get();
    //aAgg contains a reference of the SvxShape!
    {
        uno::Any aAgg = xShape->queryInterface(rAggType);
        aAgg >>= m_xShapeAgg;
        // #i31698#
        if ( m_xShapeAgg.is() )
        {
            m_xShapeAgg->queryAggregation( cppu::UnoType<drawing::XShape>::get()) >>= mxShape;
            OSL_ENSURE( mxShape.is(),
                    " - no XShape found at " );
        }
    }
    xShape = nullptr;
    osl_atomic_increment(&m_refCount);
    if( m_xShapeAgg.is() )
        m_xShapeAgg->setDelegator( getXWeak() );
    osl_atomic_decrement(&m_refCount);
}

SwFrameFormat* SwXShape::GetFrameFormat() const
{
    SdrObject* pObj = SdrObject::getSdrObjectFromXShape(m_xShapeAgg);
    if(pObj)
        return ::FindFrameFormat( pObj );
    return nullptr;
}

void SwXShape::AddExistingShapeToFormat( SdrObject const & _rObj )
{
    SdrObjListIter aIter( _rObj, SdrIterMode::DeepNoGroups );
    while ( aIter.IsMore() )
    {
        SdrObject* pCurrent = aIter.Next();
        OSL_ENSURE( pCurrent, "SwXShape::AddExistingShapeToFormat: invalid object list element!" );
        if ( !pCurrent )
            continue;

        auto pSwShape = comphelper::getFromUnoTunnel<SwXShape>(pCurrent->getWeakUnoShape());
        if ( pSwShape )
        {
            if ( pSwShape->m_bDescriptor )
                pSwShape->m_bDescriptor = false;
        }
    }
}

SwXShape::~SwXShape()
{
    SolarMutexGuard aGuard;

    if (m_xShapeAgg.is())
    {
        uno::Reference< uno::XInterface >  xRef;
        m_xShapeAgg->setDelegator(xRef);
    }
    m_pImpl.reset();
    if(m_pPage)
       const_cast<SwFmDrawPage*>(m_pPage)->RemoveShape(this);
    // these have to be destructed under the solarmutex
    m_xShapeAgg.clear();
    mxShape.clear();
}

uno::Any SwXShape::queryInterface( const uno::Type& aType )
{
    uno::Any aRet;
    SdrObject* pObj = nullptr;

    if ((aType == cppu::UnoType<text::XText>::get())
        || (aType == cppu::UnoType<text::XTextRange>::get())
        || (aType == cppu::UnoType<text::XTextAppend>::get()))
    {
        pObj = SdrObject::getSdrObjectFromXShape(mxShape);

        aRet = SwTextBoxHelper::queryInterface(GetFrameFormat(), aType, pObj);
        if (aRet.hasValue())
            return aRet;
    }
    aRet = SwXShapeBaseClass::queryInterface(aType);
    // #i53320# - follow-up of #i31698#
    // interface drawing::XShape is overloaded. Thus, provide
    // correct object instance.
    if(!aRet.hasValue() && m_xShapeAgg.is())
    {
        if(aType == cppu::UnoType<XShape>::get())
            aRet <<= uno::Reference<XShape>(this);
        else
            aRet = m_xShapeAgg->queryAggregation(aType);
    }
    return aRet;
}

uno::Sequence< uno::Type > SwXShape::getTypes(  )
{
    uno::Sequence< uno::Type > aRet = SwXShapeBaseClass::getTypes();
    if(m_xShapeAgg.is())
    {
        uno::Any aProv = m_xShapeAgg->queryAggregation(cppu::UnoType<XTypeProvider>::get());
        if(aProv.hasValue())
        {
            uno::Reference< XTypeProvider > xAggProv;
            aProv >>= xAggProv;
            return comphelper::concatSequences(aRet, xAggProv->getTypes());
        }
    }
    return aRet;
}

uno::Sequence< sal_Int8 > SwXShape::getImplementationId(  )
{
    return css::uno::Sequence<sal_Int8>();
}

uno::Reference< beans::XPropertySetInfo >  SwXShape::getPropertySetInfo()
{
    SolarMutexGuard aGuard;
    if (!mxPropertySetInfo)
    {
        if(m_xShapeAgg.is())
        {
            const uno::Type& rPropSetType = cppu::UnoType<beans::XPropertySet>::get();
            uno::Any aPSet = m_xShapeAgg->queryAggregation( rPropSetType );
            if(auto xPrSet = o3tl::tryAccess<uno::Reference<beans::XPropertySet>>(
                   aPSet))
            {
                uno::Reference< beans::XPropertySetInfo >  xInfo = (*xPrSet)->getPropertySetInfo();
                // Expand PropertySetInfo!
                const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
                mxPropertySetInfo = new SfxExtItemPropertySetInfo( m_pPropertyMapEntries, aPropSeq );
            }
        }
        if(!mxPropertySetInfo)
            mxPropertySetInfo = m_pPropSet->getPropertySetInfo();
    }
    return mxPropertySetInfo;
}

void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& ;aValue)
{
    SolarMutexGuard aGuard;
    SwFrameFormat*   pFormat = GetFrameFormat();
    const SfxItemPropertyMapEntry*  pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
    if(!m_xShapeAgg.is())
        return;

    if(pEntry)
    {
        if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
            throw beans::PropertyVetoException ("Property is read-only: " + rPropertyName, getXWeak() );
        // with the layout it is possible to move the anchor without changing the position
        if(pFormat)
        {
            SwAttrSet aSet(pFormat->GetAttrSet());
            SwDoc& rDoc = pFormat->GetDoc();
            if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORFRAME == pEntry->nMemberId)
            {
                bool bDone = false;
                uno::Reference<text::XTextFrame> xFrame;
                if(aValue >>= xFrame)
                {
                    SwXFrame* pFrame = dynamic_cast<SwXFrame*>(xFrame.get());
                    if(pFrame && pFrame->GetFrameFormat() &&
                        &pFrame->GetFrameFormat()->GetDoc() == &rDoc)
                    {
                        UnoActionContext aCtx(&rDoc);
                        SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aItemSet( rDoc.GetAttrPool() );
                        aItemSet.SetParent(&pFormat->GetAttrSet());
                        SwFormatAnchor aAnchor = static_cast<const SwFormatAnchor&>(aItemSet.Get(pEntry->nWID));
                        SwPosition aPos(*pFrame->GetFrameFormat()->GetContent().GetContentIdx());
                        aAnchor.SetAnchor(&aPos);
                        aAnchor.SetType(RndStdIds::FLY_AT_FLY);
                        aItemSet.Put(aAnchor);
                        pFormat->SetFormatAttr(aItemSet);
                        bDone = true;
                    }
                }
                if(!bDone)
                    throw lang::IllegalArgumentException();
            }
            else if(RES_OPAQUE == pEntry->nWID)
            {
                SvxShape* pSvxShape = GetSvxShape();
                SAL_WARN_IF(!pSvxShape, "sw.uno""No SvxShape found!");
                if(pSvxShape)
                {
                    SdrObject* pObj = pSvxShape->GetSdrObject();
                    // set layer of new drawing
                    // object to corresponding invisible layer.
                    bool bIsVisible = rDoc.getIDocumentDrawModelAccess().IsVisibleLayerId( pObj->GetLayer() );
                    if(SdrInventor::FmForm != pObj->GetObjInventor())
                    {
                        pObj->SetLayer( *o3tl::doAccess<bool>(aValue)
                                        ? ( bIsVisible ? rDoc.getIDocumentDrawModelAccess().GetHeavenId() : rDoc.getIDocumentDrawModelAccess().GetInvisibleHeavenId() )
                                        : ( bIsVisible ? rDoc.getIDocumentDrawModelAccess().GetHellId() : rDoc.getIDocumentDrawModelAccess().GetInvisibleHellId() ));
                    }
                    else
                    {
                        pObj->SetLayer( bIsVisible ? rDoc.getIDocumentDrawModelAccess().GetControlsId() : rDoc.getIDocumentDrawModelAccess().GetInvisibleControlsId());
                    }

                }

            }
            // #i26791# - special handling for property FN_TEXT_RANGE
            else if ( FN_TEXT_RANGE == pEntry->nWID )
            {
                SwFormatAnchor aAnchor( aSet.Get( RES_ANCHOR ) );
                if (aAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
                {
                    // set property <TextRange> not valid for to-page anchored shapes
                    throw lang::IllegalArgumentException();
                }

                std::unique_ptr<SwUnoInternalPaM> pInternalPam(
                                new SwUnoInternalPaM( pFormat->GetDoc() ));
                uno::Reference< text::XTextRange > xRg;
                aValue >>= xRg;
                if (!::sw::XTextRangeToSwPaM(*pInternalPam, xRg) )
                {
                    throw uno::RuntimeException();
                }

                if (aAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
                {
                    //delete old SwFormatFlyCnt
                    //With AnchorAsCharacter the current TextAttribute has to be deleted.
                    //Tbis removes the frame format too.
                    //To prevent this the connection between format and attribute has to be broken before.
                    SwTextNode *pTextNode = aAnchor.GetAnchorNode()->GetTextNode();
                    SAL_WARN_IF( !pTextNode->HasHints(), "sw.uno""Missing FlyInCnt-Hint." );
                    const sal_Int32 nIdx = aAnchor.GetAnchorContentOffset();
                    SwTextAttr * const pHint =
                            pTextNode->GetTextAttrForCharAt(
                            nIdx, RES_TXTATR_FLYCNT );
                    assert(pHint && "Missing Hint.");
                    SAL_WARN_IF( pHint->Which() != RES_TXTATR_FLYCNT,
                                "sw.uno""Missing FlyInCnt-Hint." );
                    SAL_WARN_IF( pHint->GetFlyCnt().GetFrameFormat() != pFormat,
                                "sw.uno""Wrong TextFlyCnt-Hint." );
                    const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt())
                        .SetFlyFormat();

                    //The connection is removed now the attribute can be deleted.
                    pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx );
                    //create a new one
                    SwTextNode *pNd = pInternalPam->GetPointNode().GetTextNode();
                    SAL_WARN_IF( !pNd, "sw.uno""Cursor not at TextNode." );
                    SwFormatFlyCnt aFormat( pFormat );
                    pNd->InsertItem(aFormat, pInternalPam->GetPoint()
                            ->GetContentIndex(), 0 );
                    //Refetch in case SwTextNode::InsertItem causes it to be deleted
                    pFormat = GetFrameFormat();
                }
                else
                {
                    aAnchor.SetAnchor( pInternalPam->GetPoint() );
                    aSet.Put(aAnchor);
                    pFormat->SetFormatAttr(aSet);
                }
            }
            else if (pEntry->nWID == FN_TEXT_BOX)
            {
                auto pObj = SdrObject::getSdrObjectFromXShape(mxShape);
                if (pEntry->nMemberId == MID_TEXT_BOX)
                {
                    bool bValue(false);
                    aValue >>= bValue;

                    if (bValue)
                        SwTextBoxHelper::create(pFormat, pObj);
                    else
                        SwTextBoxHelper::destroy(pFormat, pObj);
                }
                else if (pEntry->nMemberId == MID_TEXT_BOX_CONTENT)
                {
                    if (uno::Reference<text::XTextFrame> xTextFrame; aValue >>= xTextFrame)
                        SwTextBoxHelper::set(pFormat, pObj, xTextFrame);
                    else
                        SAL_WARN( "sw.uno""This is not a TextFrame!" );
                }
            }
            else if (pEntry->nWID == RES_CHAIN)
            {
                if (pEntry->nMemberId == MID_CHAIN_NEXTNAME || pEntry->nMemberId == MID_CHAIN_PREVNAME)
                    SwTextBoxHelper::syncProperty(pFormat, pEntry->nWID, pEntry->nMemberId, aValue,
                                                  SdrObject::getSdrObjectFromXShape(mxShape));
            }
            // #i28749#
            else if ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID )
            {
                sal_Int16 nPositionLayoutDir = 0;
                aValue >>= nPositionLayoutDir;
                pFormat->SetPositionLayoutDir( nPositionLayoutDir );
            }
            else if( rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
            {
                UnoActionContext aCtx(&rDoc);
                if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORTYPE == pEntry->nMemberId)
                {
                    SdrObject* pObj = pFormat->FindSdrObject();
                    SdrMarkList aList;
                    SdrMark aMark(pObj);
                    aList.InsertEntry(aMark);
                    sal_Int32 nAnchor = 0;
                    cppu::enum2int( nAnchor, aValue );
                    rDoc.ChgAnchor( aList, static_cast<RndStdIds>(nAnchor),
                                            falsetrue );
                }
                else
                {
                    SfxItemPropertySet::setPropertyValue(*pEntry, aValue, aSet);
                    pFormat->SetFormatAttr(aSet);
                }
            }
            else if( RES_FRM_SIZE == pEntry->nWID &&
                    ( pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT || pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH
                      || pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT_RELATION
                      || pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH_RELATION ) )
            {
                SvxShape* pSvxShape = GetSvxShape();
                SAL_WARN_IF(!pSvxShape, "sw.uno""No SvxShape found!");
                if(pSvxShape)
                {
                    SdrObject* pObj = pSvxShape->GetSdrObject();
                    sal_Int16 nPercent(100);
                    aValue >>= nPercent;
                    switch (pEntry->nMemberId)
                    {
                    case MID_FRMSIZE_REL_WIDTH:
                        pObj->SetRelativeWidth( nPercent / 100.0 );
                    break;
                    case MID_FRMSIZE_REL_HEIGHT:
                        pObj->SetRelativeHeight( nPercent / 100.0 );
                    break;
                    case MID_FRMSIZE_REL_WIDTH_RELATION:
                        pObj->SetRelativeWidthRelation(nPercent);
                    break;
                    case MID_FRMSIZE_REL_HEIGHT_RELATION:
                        pObj->SetRelativeHeightRelation(nPercent);
                    break;
                    }
                }
            }
            else if (pEntry->nWID == RES_HORI_ORIENT
                && pEntry->nMemberId == MID_HORIORIENT_RELATION
                && aSet.Get(RES_ANCHOR).GetAnchorId() == RndStdIds::FLY_AT_PAGE)
            {
                uno::Any value(aValue);
                sal_Int16 nRelOrient(text::RelOrientation::PAGE_FRAME);
                aValue >>= nRelOrient;
                if (sw::GetAtPageRelOrientation(nRelOrient, true))
                {
                    SAL_WARN("sw.core""SwXShape: fixing invalid horizontal RelOrientation for at-page anchor");
                    value <<= nRelOrient;
                }
                SfxItemPropertySet::setPropertyValue( *pEntry, value, aSet );
                pFormat->SetFormatAttr(aSet);
            }
            else
            {
                SfxItemPropertySet::setPropertyValue( *pEntry, aValue, aSet );

                if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORTYPE == pEntry->nMemberId)
                {
                    bool bSetAttr = true;
                    text::TextContentAnchorType eNewAnchor = static_cast<text::TextContentAnchorType>(SWUnoHelper::GetEnumAsInt32( aValue ));

                    //if old anchor was in_cntnt the related text attribute has to be removed
                    const SwFormatAnchor& rOldAnchor = pFormat->GetAnchor();
                    RndStdIds eOldAnchorId = rOldAnchor.GetAnchorId();
                    SdrObject* pObj = pFormat->FindSdrObject();
                    SwFrameFormat *pFlyFormat = FindFrameFormat( pObj );
                    pFlyFormat->DelFrames();
                    if( text::TextContentAnchorType_AS_CHARACTER != eNewAnchor &&
                        (RndStdIds::FLY_AS_CHAR == eOldAnchorId))
                    {
                        //With AnchorAsCharacter the current TextAttribute has to be deleted.
                        //Tbis removes the frame format too.
                        //To prevent this the connection between format and attribute has to be broken before.
                        SwTextNode *pTextNode = rOldAnchor.GetAnchorNode()->GetTextNode();
                        SAL_WARN_IF( !pTextNode->HasHints(), "sw.uno""Missing FlyInCnt-Hint." );
                        const sal_Int32 nIdx = rOldAnchor.GetAnchorContentOffset();
                        SwTextAttr * const pHint =
                            pTextNode->GetTextAttrForCharAt(
                                nIdx, RES_TXTATR_FLYCNT );
                        assert(pHint && "Missing Hint.");
                        SAL_WARN_IF( pHint->Which() != RES_TXTATR_FLYCNT,
                                    "sw.uno""Missing FlyInCnt-Hint." );
                        SAL_WARN_IF( pHint->GetFlyCnt().GetFrameFormat() != pFlyFormat,
                                    "sw.uno""Wrong TextFlyCnt-Hint." );
                        const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt())
                            .SetFlyFormat();

                        //The connection is removed now the attribute can be deleted.
                        pTextNode->DeleteAttributes(RES_TXTATR_FLYCNT, nIdx);
                    }
                    else if( text::TextContentAnchorType_AT_PAGE != eNewAnchor &&
                            (RndStdIds::FLY_AT_PAGE == eOldAnchorId))
                    {
                        SwFormatAnchor aNewAnchor( aSet.Get( RES_ANCHOR ) );
                        //if the fly has been anchored at page then it needs to be connected
                        //to the content position
                        SwPaM aPam(rDoc.GetNodes().GetEndOfContent());
                        if( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() )
                        {
                            SwCursorMoveState aState( CursorMoveState::SetOnlyText );
                            Point aTmp( pObj->GetSnapRect().TopLeft() );
                            rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam.GetPoint(), aTmp, &aState );
                        }
                        else
                        {
                            //without access to the layout the last node of the body will be used as anchor position
                            aPam.Move( fnMoveBackward, GoInDoc );
                        }
                        //anchor position has to be inserted after the text attribute has been inserted
                        aNewAnchor.SetAnchor( aPam.GetPoint() );
                        aSet.Put( aNewAnchor );
                        pFormat->SetFormatAttr(aSet);
                        bSetAttr = false;
                    }
                    if( text::TextContentAnchorType_AS_CHARACTER == eNewAnchor &&
                        (RndStdIds::FLY_AS_CHAR != eOldAnchorId))
                    {
                        SwPaM aPam(rDoc.GetNodes().GetEndOfContent());
                        if( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() )
                        {
                            SwCursorMoveState aState( CursorMoveState::SetOnlyText );
                            Point aTmp( pObj->GetSnapRect().TopLeft() );
                            rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam.GetPoint(), aTmp, &aState );
                        }
                        else
                        {
                            //without access to the layout the last node of the body will be used as anchor position
                            aPam.Move( fnMoveBackward, GoInDoc );
                        }
                        //the RES_TXTATR_FLYCNT needs to be added now
                        SwTextNode *pNd = aPam.GetPointNode().GetTextNode();
                        SAL_WARN_IF( !pNd, "sw.uno""Cursor is not in a TextNode." );
                        SwFormatFlyCnt aFormat( pFlyFormat );
                        pNd->InsertItem(aFormat,
                            aPam.GetPoint()->GetContentIndex(), 0 );
                        aPam.GetPoint()->AdjustContent(-1); // InsertItem moved it
                        SwFormatAnchor aNewAnchor(
                                aSet.Get(RES_ANCHOR));
                        aNewAnchor.SetAnchor( aPam.GetPoint() );
                        aSet.Put( aNewAnchor );
                    }
                    if( bSetAttr )
                        pFormat->SetFormatAttr(aSet);

                    // If this property is an anchor change, and there is a group shape with textboxes
                    // do anchor sync in time unless the anchor sync in the porfly will cause crash during
                    // layout calculation (When importing an inline shape in docx via dmapper).
                    if (pFormat->Which() == RES_DRAWFRMFMT && pFormat->GetOtherTextBoxFormats())
                    {
                        SwTextBoxHelper::synchronizeGroupTextBoxProperty(
                            SwTextBoxHelper::changeAnchor, pFormat,
                            SdrObject::getSdrObjectFromXShape(mxShape));
                    }
                }
                else
                    pFormat->SetFormatAttr(aSet);
            }

            // We have a pFormat and a pEntry as well: try to sync TextBox property.
            SwTextBoxHelper::syncProperty(pFormat, pEntry->nWID, pEntry->nMemberId, aValue,
                                          SdrObject::getSdrObjectFromXShape(mxShape));
        }
        else
        {
            SfxPoolItem* pItem = nullptr;
            switch(pEntry->nWID)
            {
                case RES_ANCHOR:
                    pItem = m_pImpl->GetAnchor(true);
                break;
                case RES_HORI_ORIENT:
                    pItem = m_pImpl->GetHOrient(true);
                break;
                case RES_VERT_ORIENT:
                    pItem = m_pImpl->GetVOrient(true);
                break;
                case  RES_LR_SPACE:
                    pItem = m_pImpl->GetLRSpace(true);
                break;
                case  RES_UL_SPACE:
                    pItem = m_pImpl->GetULSpace(true);
                break;
                case  RES_SURROUND:
                    pItem = m_pImpl->GetSurround(true);
                break;
                case  FN_TEXT_RANGE:
                    if(auto tr = o3tl::tryAccess<
                           uno::Reference<text::XTextRange>>(aValue))
                    {
                        uno::Reference< text::XTextRange > & rRange = m_pImpl->GetTextRange();
                        rRange = *tr;
                    }
                break;
                case RES_OPAQUE :
                    m_pImpl->SetOpaque(*o3tl::doAccess<bool>(aValue));
                break;
                // #i26791#
                case RES_FOLLOW_TEXT_FLOW:
                {
                    pItem = m_pImpl->GetFollowTextFlow( true );
                }
                break;
                // #i28701#
                case RES_WRAP_INFLUENCE_ON_OBJPOS:
                {
                    pItem = m_pImpl->GetWrapInfluenceOnObjPos( true );
                }
                break;
                // #i28749#
                case FN_SHAPE_POSITION_LAYOUT_DIR :
                {
                    sal_Int16 nPositionLayoutDir = 0;
                    aValue >>= nPositionLayoutDir;
                    m_pImpl->SetPositionLayoutDir( nPositionLayoutDir );
                }
                break;
            }
            if(pItem)
                pItem->PutValue(aValue, pEntry->nMemberId);
        }
    }
    else
    {
        const uno::Type& rPSetType =
            cppu::UnoType<beans::XPropertySet>::get();
        uno::Any aPSet = m_xShapeAgg->queryAggregation(rPSetType);
        auto xPrSet = o3tl::tryAccess<uno::Reference<beans::XPropertySet>>(
            aPSet);
        if(!xPrSet)
            throw uno::RuntimeException();
        // #i31698# - setting the caption point of a
        // caption object doesn't have to change the object position.
        // Thus, keep the position, before the caption point is set and
        // restore it afterwards.
        awt::Point aKeepedPosition( 0, 0 );
        if ( rPropertyName == "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
        {
                aKeepedPosition = getPosition();
        }
        if( pFormat && pFormat->GetDoc().getIDocumentLayoutAccess().GetCurrentViewShell() )
        {
            UnoActionContext aCtx(&pFormat->GetDoc());
            (*xPrSet)->setPropertyValue(rPropertyName, aValue);
        }
        else
            (*xPrSet)->setPropertyValue(rPropertyName, aValue);

        if (pFormat)
        {
            // We have a pFormat (but no pEntry): try to sync TextBox property.
            SwTextBoxHelper::syncProperty(pFormat, rPropertyName, aValue,
                                          SdrObject::getSdrObjectFromXShape(mxShape));
        }

        // #i31698# - restore object position, if caption point is set.
        if ( rPropertyName == "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
        {
            setPosition( aKeepedPosition );
        }
    }
}

uno::Any SwXShape::getPropertyValue(const OUString& rPropertyName)
{
    SolarMutexGuard aGuard;
    uno::Any aRet;
    SwFrameFormat*   pFormat = GetFrameFormat();
    if(m_xShapeAgg.is())
    {
        const SfxItemPropertyMapEntry*  pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
        if(pEntry)
        {
            if(pFormat)
            {
                if(RES_OPAQUE == pEntry->nWID)
                {
                    SvxShape* pSvxShape = GetSvxShape();
                    OSL_ENSURE(pSvxShape, "No SvxShape found!");
                    if(pSvxShape)
                    {
                        SdrObject* pObj = pSvxShape->GetSdrObject();
                        // consider invisible layers
                        SdrLayerID nLayerId = pObj->GetLayer();
                        const IDocumentDrawModelAccess& rIDMA = pFormat->GetDoc().getIDocumentDrawModelAccess();
                        aRet <<=
                            ( nLayerId != rIDMA.GetHellId() &&
                              nLayerId != rIDMA.GetHeaderFooterHellId() &&
                              nLayerId != rIDMA.GetInvisibleHellId() );
                    }
                }
                else if(FN_ANCHOR_POSITION == pEntry->nWID)
                {
                    SvxShape* pSvxShape = GetSvxShape();
                    OSL_ENSURE(pSvxShape, "No SvxShape found!");
                    if(pSvxShape)
                    {
                        SdrObject* pObj = pSvxShape->GetSdrObject();
                        Point aPt = pObj->GetAnchorPos();
                        awt::Point aPoint( convertTwipToMm100( aPt.X() ),
                                           convertTwipToMm100( aPt.Y() ) );
                        aRet <<= aPoint;
                    }
                }
                // #i26791# - special handling for FN_TEXT_RANGE
                else if ( FN_TEXT_RANGE == pEntry->nWID )
                {
                    const SwFormatAnchor aAnchor = pFormat->GetAnchor();
                    if (aAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
                    {
                        // return nothing, because property <TextRange> isn't
                        // valid for to-page anchored shapes
                        aRet = uno::Any();
                    }
                    else
                    {
                        if ( aAnchor.GetAnchorNode() )
                        {
                            const rtl::Reference<SwXTextRange> xTextRange
                                = SwXTextRange::CreateXTextRange(
                                                    pFormat->GetDoc(),
                                                    *aAnchor.GetContentAnchor(),
                                                    nullptr );
                            aRet <<= uno::Reference<text::XTextRange>(xTextRange);
                        }
                        else
                        {
                            // return nothing
                            aRet = uno::Any();
                        }
                    }
                }
                else if (pEntry->nWID == FN_TEXT_BOX)
                {
                    if (pEntry->nMemberId == MID_TEXT_BOX)
                    {
                        auto pSvxShape = GetSvxShape();
                        bool bValue = SwTextBoxHelper::isTextBox(
                            pFormat, RES_DRAWFRMFMT,
                            ((pSvxShape && pSvxShape->GetSdrObject()) ? pSvxShape->GetSdrObject()
                                : pFormat->FindRealSdrObject()));
                        aRet <<= bValue;
                    }
                    else if (pEntry->nMemberId == MID_TEXT_BOX_CONTENT)
                    {
                        auto pObj = SdrObject::getSdrObjectFromXShape(mxShape);
                        auto xRange = SwTextBoxHelper::queryInterface(
                            pFormat, cppu::UnoType<text::XText>::get(),
                            pObj ? pObj : pFormat->FindRealSdrObject());
                        uno::Reference<text::XTextFrame> xFrame(xRange, uno::UNO_QUERY);
                        if (xFrame.is())
                            aRet <<= xFrame;
                    }
                }
                else if (pEntry->nWID == RES_CHAIN)
                {
                    switch (pEntry->nMemberId)
                    {
                    case MID_CHAIN_PREVNAME:
                    case MID_CHAIN_NEXTNAME:
                    case MID_CHAIN_NAME:
                        SwTextBoxHelper::getProperty(pFormat, pEntry->nWID, pEntry->nMemberId, aRet);
                    break;
                    }
                }
                // #i28749#
                else if ( FN_SHAPE_TRANSFORMATION_IN_HORI_L2R == pEntry->nWID )
                {
                    // get property <::drawing::Shape::Transformation>
                    // without conversion to layout direction as below
                    aRet = _getPropAtAggrObj( u"Transformation"_ustr );
                }
                else if ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID )
                {
                    aRet <<= pFormat->GetPositionLayoutDir();
                }
                // #i36248#
                else if ( FN_SHAPE_STARTPOSITION_IN_HORI_L2R == pEntry->nWID )
                {
                    // get property <::drawing::Shape::StartPosition>
                    // without conversion to layout direction as below
                    aRet = _getPropAtAggrObj( u"StartPosition"_ustr );
                }
                else if ( FN_SHAPE_ENDPOSITION_IN_HORI_L2R == pEntry->nWID )
                {
                    // get property <::drawing::Shape::EndPosition>
                    // without conversion to layout direction as below
                    aRet = _getPropAtAggrObj( u"EndPosition"_ustr );
                }
                else if (pEntry->nWID == RES_FRM_SIZE &&
                         (pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT ||
                          pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH ||
                          pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT_RELATION ||
                          pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH_RELATION))
                {
                    SvxShape* pSvxShape = GetSvxShape();
                    SAL_WARN_IF(!pSvxShape, "sw.uno""No SvxShape found!");
                    sal_Int16 nRet = 0;
                    if (pSvxShape)
                    {
                        SdrObject* pObj = pSvxShape->GetSdrObject();
                        switch (pEntry->nMemberId)
                        {
                        case MID_FRMSIZE_REL_WIDTH:
                            if (pObj->GetRelativeWidth())
                                nRet = *pObj->GetRelativeWidth() * 100;
                            break;
                        case MID_FRMSIZE_REL_HEIGHT:
                            if (pObj->GetRelativeHeight())
                                nRet = *pObj->GetRelativeHeight() * 100;
                            break;
                        case MID_FRMSIZE_REL_WIDTH_RELATION:
                            nRet = pObj->GetRelativeWidthRelation();
                            break;
                        case MID_FRMSIZE_REL_HEIGHT_RELATION:
                            nRet = pObj->GetRelativeHeightRelation();
                            break;
                        }
                    }
                    aRet <<= nRet;
                }
                else
                {
                    const SwAttrSet& rSet = pFormat->GetAttrSet();
                    SfxItemPropertySet::getPropertyValue(*pEntry, rSet, aRet);
                }
            }
            else
            {
                SfxPoolItem* pItem = nullptr;
                switch(pEntry->nWID)
                {
                    case RES_ANCHOR:
                        pItem = m_pImpl->GetAnchor();
                    break;
                    case RES_HORI_ORIENT:
                        pItem = m_pImpl->GetHOrient();
                    break;
                    case RES_VERT_ORIENT:
                        pItem = m_pImpl->GetVOrient();
                    break;
                    case  RES_LR_SPACE:
                        pItem = m_pImpl->GetLRSpace();
                    break;
                    case  RES_UL_SPACE:
                        pItem = m_pImpl->GetULSpace();
                    break;
                    case  RES_SURROUND:
                        pItem = m_pImpl->GetSurround();
                    break;
                    case FN_TEXT_RANGE :
                        aRet <<= m_pImpl->GetTextRange();
                    break;
                    case RES_OPAQUE :
                        aRet <<= m_pImpl->GetOpaque();
                    break;
                    case FN_ANCHOR_POSITION :
                    {
                        aRet <<= awt::Point();
                    }
                    break;
                    // #i26791#
                    case RES_FOLLOW_TEXT_FLOW :
                    {
                        pItem = m_pImpl->GetFollowTextFlow();
                    }
                    break;
                    // #i28701#
                    case RES_WRAP_INFLUENCE_ON_OBJPOS:
                    {
                        pItem = m_pImpl->GetWrapInfluenceOnObjPos();
                    }
                    break;
                    // #i28749#
                    case FN_SHAPE_TRANSFORMATION_IN_HORI_L2R:
                    {
                        // get property <::drawing::Shape::Transformation>
                        // without conversion to layout direction as below
                        aRet = _getPropAtAggrObj( u"Transformation"_ustr );
                    }
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=94 H=98 G=95

¤ Dauer der Verarbeitung: 0.32 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.