/* -*- 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 .
*/
SwUndoFlyBase::~SwUndoFlyBase()
{ if( m_bDelFormat ) // delete during an Undo?
{ if (constauto& pTextBoxes = m_pFrameFormat->GetOtherTextBoxFormats())
{ // Clear and unregister before release. if (m_pFrameFormat->Which() == RES_FLYFRMFMT)
pTextBoxes->DelTextBox(m_pFrameFormat);
if (m_pFrameFormat->Which() == RES_DRAWFRMFMT)
pTextBoxes->ClearAll();
// clear that before delete
m_pFrameFormat->SetOtherTextBoxFormats(nullptr);
} delete m_pFrameFormat;
}
}
// Set InContentAttribute not until there is content! // Otherwise the layout would format the Fly beforehand but would not find // content; this happened with graphics from the internet. if (RndStdIds::FLY_AS_CHAR == m_nRndId)
{ // there must be at least the attribute in a TextNode
SwContentNode* pCNd = aAnchor.GetAnchorNode()->GetContentNode();
OSL_ENSURE( pCNd->IsTextNode(), "no Text Node at position." );
SwFormatFlyCnt aFormat( m_pFrameFormat );
pCNd->GetTextNode()->InsertItem(aFormat, m_nContentPos, m_nContentPos, SetAttrMode::NOHINTEXPAND);
}
if (m_pFrameFormat->GetOtherTextBoxFormats())
{ // recklessly assume that this thing will live longer than the // SwUndoFlyBase - not sure what could be done if that isn't the case...
m_pFrameFormat->GetOtherTextBoxFormats()->GetOwnerShape()->SetOtherTextBoxFormats(
m_pFrameFormat->GetOtherTextBoxFormats());
if (m_pFrameFormat->GetOtherTextBoxFormats()->GetOwnerShape()->Which() == RES_DRAWFRMFMT)
{
if (pSdrObject)
{ // Make sure the old UNO wrapper is no longer cached after changing the shape + // textframe pair. Otherwise we would have a wrapper which doesn't know about its // textframe, even if it's there.
pSdrObject->setUnoShape(nullptr);
}
} if (m_pFrameFormat->Which() == RES_FLYFRMFMT)
{
SwFrameFormat* pShapeFormat = m_pFrameFormat->GetOtherTextBoxFormats()->GetOwnerShape();
pShapeFormat->SetFormatAttr(m_pFrameFormat->GetContent());
}
}
switch( m_nRndId )
{ case RndStdIds::FLY_AS_CHAR: case RndStdIds::FLY_AT_CHAR:
{ const SwFormatAnchor& rAnchor = m_pFrameFormat->GetAnchor();
m_nNodePagePos = rAnchor.GetAnchorNode()->GetIndex();
m_nContentPos = rAnchor.GetAnchorContentOffset();
} break; case RndStdIds::FLY_AT_PARA: case RndStdIds::FLY_AT_FLY:
{ const SwFormatAnchor& rAnchor = m_pFrameFormat->GetAnchor();
m_nNodePagePos = rAnchor.GetAnchorNode()->GetIndex();
} break; case RndStdIds::FLY_AT_PAGE: break; default: break;
}
m_bDelFormat = false;
}
void SwUndoFlyBase::DelFly( SwDoc& rDoc )
{
m_bDelFormat = true; // delete Format in DTOR
m_pFrameFormat->DelFrames(); // destroy Frames
if (m_pFrameFormat->GetOtherTextBoxFormats())
{ // tdf#108867 clear that pointer
m_pFrameFormat->GetOtherTextBoxFormats()->GetOwnerShape()->SetOtherTextBoxFormats(nullptr);
}
// all Uno objects should now log themselves off
m_pFrameFormat->RemoveAllUnos();
if ( RES_DRAWFRMFMT != m_pFrameFormat->Which() )
{ // if there is content than save it const SwFormatContent& rContent = m_pFrameFormat->GetContent();
OSL_ENSURE( rContent.GetContentIdx(), "Fly without content" );
// delete from array
sw::SpzFrameFormats& rFlyFormats = *rDoc.GetSpzFrameFormats();
rFlyFormats.erase(static_cast<sw::SpzFrameFormat*>(m_pFrameFormat));
}
SwUndoInsLayFormat::SwUndoInsLayFormat( SwFrameFormat* pFormat, SwNodeOffset nNodeIdx, sal_Int32 nCntIdx )
: SwUndoFlyBase( pFormat, RES_DRAWFRMFMT == pFormat->Which() ?
SwUndoId::INSDRAWFMT : SwUndoId::INSLAYFMT ),
mnCursorSaveIndexPara( nNodeIdx ), mnCursorSaveIndexPos( nCntIdx )
{ const SwFormatAnchor& rAnchor = m_pFrameFormat->GetAnchor();
m_nRndId = rAnchor.GetAnchorId();
m_bDelFormat = false; // note: SwUndoInsLayFormat is called with the content being fully inserted // from most places but with only an empty content section from // CopyLayoutFormat(); it's not necessary here to init m_nNodePagePos // because Undo will do it.
}
SwUndoInsLayFormat::~SwUndoInsLayFormat()
{
}
void SwUndoInsLayFormat::UndoImpl(::sw::UndoRedoContext & rContext)
{
SwDoc & rDoc(rContext.GetDoc()); const SwFormatContent& rContent = m_pFrameFormat->GetContent(); if( rContent.GetContentIdx() ) // no content
{
assert(&rContent.GetContentIdx()->GetNodes() == &rDoc.GetNodes()); if( mnCursorSaveIndexPara > SwNodeOffset(0) )
{
SwTextNode *const pNode =
rDoc.GetNodes()[mnCursorSaveIndexPara]->GetTextNode(); if( pNode )
{
SwNodeIndex aIdx( rDoc.GetNodes(),
rContent.GetContentIdx()->GetIndex() );
SwNodeIndex aEndIdx( rDoc.GetNodes(),
aIdx.GetNode().EndOfSectionIndex() );
SwPosition aPos( *pNode, mnCursorSaveIndexPos ); // don't delete bookmarks here, DelFly() will save them in history
::PaMCorrAbs(SwPaM(aIdx, aEndIdx), aPos); // TODO: is aPos actually a sensible pos for e.g. SwXText* ?
}
}
}
DelFly(rDoc);
}
// HACK: disable caching: // the SfxUndoManager calls GetComment() too early: the pFrameFormat does not // have a SwDrawContact yet, so it will fall back to SwUndo::GetComment(), // which sets pComment to a wrong value. // if (! pComment) if ((true))
{ /* If frame format is present and has an SdrObject use the undo comment of the SdrObject. Otherwise use the default comment.
*/ bool bDone = false; if (m_pFrameFormat)
{ const SdrObject * pSdrObj = m_pFrameFormat->FindSdrObject(); if ( pSdrObj )
{
aResult = SdrUndoNewObj::GetComment( *pSdrObj );
bDone = true;
}
}
// Is the new Format still existent?
SwFrameFormat* pDerivedFromFrameFormat = rDoc.FindFrameFormatByName(m_DerivedFromFormatName); if (!pDerivedFromFrameFormat) return;
void SwUndoSetFlyFormat::PutAttr( sal_uInt16 nWhich, const SfxPoolItem* pItem )
{ if( pItem && !SfxPoolItem::areSame(pItem, GetDfltAttr( nWhich ) ) )
{ // Special treatment for this anchor if( RES_ANCHOR == nWhich )
{ // only keep the first change
OSL_ENSURE( !m_bAnchorChanged, "multiple changes of an anchor are not allowed!" );
m_bAnchorChanged = true;
const SwFormatAnchor* pAnchor = static_cast<const SwFormatAnchor*>(pItem);
m_nOldAnchorType = pAnchor->GetAnchorId(); switch( m_nOldAnchorType )
{ case RndStdIds::FLY_AS_CHAR: case RndStdIds::FLY_AT_CHAR:
m_nOldContent = pAnchor->GetAnchorContentOffset();
[[fallthrough]]; case RndStdIds::FLY_AT_PARA: case RndStdIds::FLY_AT_FLY:
m_nOldNode = pAnchor->GetAnchorNode()->GetIndex(); break;
default:
m_nOldContent = pAnchor->GetPageNum();
}
pAnchor = &m_pFrameFormat->GetAnchor();
m_nNewAnchorType = pAnchor->GetAnchorId(); switch( m_nNewAnchorType )
{ case RndStdIds::FLY_AS_CHAR: case RndStdIds::FLY_AT_CHAR:
m_nNewContent = pAnchor->GetAnchorContentOffset();
[[fallthrough]]; case RndStdIds::FLY_AT_PARA: case RndStdIds::FLY_AT_FLY:
m_nNewNode = pAnchor->GetAnchorNode()->GetIndex(); break;
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.