/* -*- 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 <doc.hxx>
#include <frmtool.hxx>
#include <hints.hxx>
#include <fmtornt.hxx>
#include <rootfrm.hxx>
#include <flyfrms.hxx>
#include <dflyobj.hxx>
#include <IDocumentSettingAccess.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <osl/diagnose.h>
#include <o3tl/deleter.hxx>
SwFlyInContentFrame::SwFlyInContentFrame( SwFlyFrameFormat *pFormat, SwFrame* pSib, SwFrame *pAnch ) :
SwFlyFrame( pFormat, pSib, pAnch )
{
m_bInCnt = true ;
SwTwips nRel = pFormat->GetVertOrient().GetPos();
// OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
Point aRelPos;
if ( pAnch && pAnch->IsVertical() )
aRelPos.setX(-nRel);
else
aRelPos.setY(nRel);
SetCurrRelPos( aRelPos );
}
void SwFlyInContentFrame::DestroyImpl()
{
if ( !GetFormat()->GetDoc().IsInDtor() && GetAnchorFrame() )
{
SwRect aTmp( GetObjRectWithSpaces() );
SwFlyInContentFrame::NotifyBackground( FindPageFrame(), aTmp, PrepareHint::FlyFrameLeave );
}
SwFlyFrame::DestroyImpl();
}
SwFlyInContentFrame::~SwFlyInContentFrame()
{
}
// #i28701#
void SwFlyInContentFrame::SetRefPoint( const Point& rPoint,
const Point& rRelAttr,
const Point& rRelPos )
{
// OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
OSL_ENSURE( rPoint != m_aRef || rRelAttr != GetCurrRelPos(), "SetRefPoint: no change" );
std::unique_ptr<SwFlyNotify, o3tl::default_delete<SwFlyNotify>> xNotify;
// No notify at a locked fly frame, if a fly frame is locked, there's
// already a SwFlyNotify object on the stack (MakeAll).
if ( !IsLocked() )
xNotify.reset(new SwFlyNotify( this ));
m_aRef = rPoint;
SetCurrRelPos( rRelAttr );
SwRectFnSet aRectFnSet(GetAnchorFrame());
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this );
aRectFnSet.SetPos( aFrm, rPoint + rRelPos );
}
// #i68520#
InvalidateObjRectWithSpaces();
if (xNotify)
{
InvalidatePage();
setFrameAreaPositionValid(false );
m_bInvalid = true ;
Calc(getRootFrame()->GetCurrShell()->GetOut());
xNotify.reset();
}
}
void SwFlyInContentFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
{
if (rHint.GetId() == SfxHintId::SwAutoFormatUsedHint)
{
// There's a FlyFrame, so use it
static_cast <const sw::AutoFormatUsedHint&>(rHint).SetUsed();
return ;
}
if (rHint.GetId() == SfxHintId::SwFormatChange)
{
auto pFormatChangeHint = static_cast <const SwFormatChangeHint*>(&rHint);
if (pFormatChangeHint->m_pNewFormat)
{
SwFlyFrame::SwClientNotify(rMod, rHint);
if (GetAnchorFrame())
AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, GetFormat());
}
return ;
}
if (rHint.GetId() == SfxHintId::SwAttrSetChange)
{
auto pChangeHint = static_cast <const sw::AttrSetChangeHint*>(&rHint);
std::pair<std::unique_ptr<SwAttrSetChg>, std::unique_ptr<SwAttrSetChg>> aTweakedChgs;
std::pair<const SwAttrSetChg*, const SwAttrSetChg*> aSuperArgs(nullptr, nullptr);
const SwAttrSetChg* pOldAttrSetChg = pChangeHint->m_pOld;
const SwAttrSetChg* pNewAttrSetChg = pChangeHint->m_pNew;
if (pOldAttrSetChg
&& pNewAttrSetChg
&& ((SfxItemState::SET == pNewAttrSetChg->GetChgSet()->GetItemState(RES_SURROUND, false ))
|| (SfxItemState::SET == pNewAttrSetChg->GetChgSet()->GetItemState(RES_FRMMACRO, false ))))
{
aTweakedChgs.second = std::make_unique<SwAttrSetChg>(*pOldAttrSetChg);
aTweakedChgs.second->ClearItem(RES_SURROUND);
aTweakedChgs.second->ClearItem(RES_FRMMACRO);
if (aTweakedChgs.second->Count())
{
aTweakedChgs.first = std::make_unique<SwAttrSetChg>(*pOldAttrSetChg);
aTweakedChgs.first->ClearItem(RES_SURROUND);
aTweakedChgs.first->ClearItem(RES_FRMMACRO);
aSuperArgs = std::pair<const SwAttrSetChg*, const SwAttrSetChg*>(aTweakedChgs.first.get(), aTweakedChgs.second.get());
}
} else if (pNewAttrSetChg && pNewAttrSetChg->GetChgSet()->Count())
aSuperArgs = std::pair<const SwAttrSetChg*, const SwAttrSetChg*>(pChangeHint->m_pOld, pChangeHint->m_pNew);
if (aSuperArgs.second)
{
SwFlyFrame::SwClientNotify(rMod, sw::AttrSetChangeHint(aSuperArgs.first, aSuperArgs.second));
if (GetAnchorFrame())
AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, GetFormat());
}
return ;
}
if (rHint.GetId() == SfxHintId::SwObjectDying
|| rHint.GetId() == SfxHintId::SwUpdateAttr)
{
SwFlyFrame::SwClientNotify(rMod, rHint);
if (GetAnchorFrame())
AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, GetFormat());
return ;
}
if (rHint.GetId() != SfxHintId::SwLegacyModify)
return ;
auto pLegacy = static_cast <const sw::LegacyModifyHint*>(&rHint);
std::pair<const SfxPoolItem*, const SfxPoolItem*> aSuperArgs(nullptr, nullptr);
switch (pLegacy->GetWhich())
{
case RES_SURROUND:
case RES_FRMMACRO:
break ;
default :
aSuperArgs = std::pair<const SfxPoolItem*, const SfxPoolItem*>(pLegacy->m_pOld, pLegacy->m_pNew);
}
if (aSuperArgs.second)
{
SwFlyFrame::SwClientNotify(rMod, sw::LegacyModifyHint(aSuperArgs.first, aSuperArgs.second));
if (GetAnchorFrame())
AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, GetFormat());
}
}
/// Here the content gets formatted initially.
void SwFlyInContentFrame::Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs )
{
if ( !getFrameArea().Height() )
{
Lock(); //don't format the anchor on the crook.
SwContentFrame *pContent = ContainsContent();
while ( pContent )
{ pContent->Calc(pRenderContext);
pContent = pContent->GetNextContentFrame();
}
Unlock();
}
SwFlyFrame::Format( pRenderContext, pAttrs );
}
/** Calculate object position
*
* @ note : In contrast to other Frames , we only calculate the relative position
* here . The absolute position is only calculated using SetAbsPos .
**/
void SwFlyInContentFrame::MakeObjPos()
{
if ( isFrameAreaPositionValid() )
return ;
setFrameAreaPositionValid(true );
SwFlyFrameFormat *pFormat = GetFormat();
const SwFormatVertOrient &rVert = pFormat->GetVertOrient();
//Update the current values in the format if needed, during this we of
//course must not send any Modify.
const bool bVert = GetAnchorFrame()->IsVertical();
SwTwips nOld = rVert.GetPos();
SwTwips nAct = bVert ? -GetCurrRelPos().X() : GetCurrRelPos().Y();
if ( nAct != nOld )
{
SwFormatVertOrient aVert( rVert );
aVert.SetPos( nAct );
pFormat->LockModify();
pFormat->SetFormatAttr( aVert );
pFormat->UnlockModify();
}
}
void SwFlyInContentFrame::ActionOnInvalidation( const InvalidationType _nInvalid )
{
if ( INVALID_POS == _nInvalid || INVALID_ALL == _nInvalid )
AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged, GetFrameFormat() );
}
void SwFlyInContentFrame::NotifyBackground( SwPageFrame *, const SwRect& rRect,
PrepareHint eHint)
{
if ( eHint == PrepareHint::FlyFrameAttributesChanged )
AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged );
else
AnchorFrame()->Prepare( eHint, static_cast <void const *>(&rRect) );
}
Point const & SwFlyInContentFrame::GetRelPos() const
{
Calc(getRootFrame()->GetCurrShell()->GetOut());
return GetCurrRelPos();
}
/// @see SwRowFrame::RegistFlys()
void SwFlyInContentFrame::RegistFlys()
{
SwPageFrame *pPage = FindPageFrame();
OSL_ENSURE( pPage, "Register Flys without pages?" );
::RegistFlys( pPage, this );
}
void SwFlyInContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
{
// OD 2004-01-19 #110582#
if ( !GetFormat()->GetDoc().getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
{
return ;
}
if ( !GetAnchorFrame() || IsLocked() || IsColLocked() || !FindPageFrame() )
return ;
Lock(); // The curtain falls
//does the notification in the DTor
const SwFlyNotify aNotify( this );
SwBorderAttrAccess aAccess( SwFrame::GetCache(), this );
const SwBorderAttrs &rAttrs = *aAccess.Get();
if ( IsClipped() )
{
setFrameAreaSizeValid(false );
m_bHeightClipped = m_bWidthClipped = false ;
}
while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() || !m_bValidContentPos )
{
//Only stop, if the flag is set!!
if ( !isFrameAreaSizeValid() )
{
setFramePrintAreaValid(false );
}
if ( !isFramePrintAreaValid() )
{
MakePrtArea( rAttrs );
m_bValidContentPos = false ;
}
if ( !isFrameAreaSizeValid() )
{
Format( getRootFrame()->GetCurrShell()->GetOut(), &rAttrs );
}
if ( !isFrameAreaPositionValid() )
{
MakeObjPos();
}
if ( !m_bValidContentPos )
MakeContentPos( rAttrs );
// re-activate clipping of as-character anchored Writer fly frames
// depending on compatibility option <ClipAsCharacterAnchoredWriterFlyFrames>
if ( isFrameAreaPositionValid() &&
isFrameAreaSizeValid() &&
GetFormat()->getIDocumentSettingAccess().get( DocumentSettingId::CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME ) )
{
SwFrame* pFrame = AnchorFrame();
if ( getFrameArea().Left() == (pFrame->getFrameArea().Left()+pFrame->getFramePrintArea().Left()) &&
getFrameArea().Width() > pFrame->getFramePrintArea().Width() )
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this );
aFrm.Width( pFrame->getFramePrintArea().Width() );
setFramePrintAreaValid(false );
m_bWidthClipped = true ;
}
}
}
Unlock();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=94 H=98 G=95
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland