/* -*- 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 .
*/
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();
}
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;
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;
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();
}
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);
}
} elseif (pEntry->nWID == FN_TEXT_BOX)
{ auto pObj = SdrObject::getSdrObjectFromXShape(mxShape); if (pEntry->nMemberId == MID_TEXT_BOX)
{ bool bValue(false);
aValue >>= bValue;
//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);
} elseif( 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() );
}
} elseif(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 elseif ( 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();
}
}
} elseif (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;
} elseif (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;
}
} elseif (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# elseif ( 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 );
} elseif ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID )
{
aRet <<= pFormat->GetPositionLayoutDir();
} // #i36248# elseif ( 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 );
} elseif ( 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 );
} elseif (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
¤ Dauer der Verarbeitung: 0.32 Sekunden
(vorverarbeitet)
¤
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.