/* -*- 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 .
*/
SwDocModifyAndUndoGuard::~SwDocModifyAndUndoGuard()
{ if (helper && helper->GetUndo())
{ // helper tracks changes, even when DoesUndo is false, to detect modified state if (doc->GetIDocumentUndoRedo().DoesUndo())
doc->GetIDocumentUndoRedo().AppendUndo(helper->ReleaseUndo());
// Check if it is still in Doc
SwFormat* SwUndoFormatAttr::GetFormat( const SwDoc& rDoc )
{ switch (m_nFormatWhich)
{ case RES_TXTFMTCOLL: case RES_CONDTXTFMTCOLL: return rDoc.FindTextFormatCollByName(m_sFormatName);
case RES_GRFFMTCOLL: return rDoc.GetGrfFormatColls()->FindFormatByName(m_sFormatName);
case RES_CHRFMT: return rDoc.FindCharFormatByName(m_sFormatName);
case RES_FRMFMT: if (m_nNodeIndex && (m_nNodeIndex < rDoc.GetNodes().Count()))
{
SwNode* pNd = rDoc.GetNodes()[m_nNodeIndex]; if (pNd->IsTableNode())
{ returnstatic_cast<SwTableNode*>(pNd)->GetTable().GetFrameFormat();
} elseif (pNd->IsSectionNode())
{ returnstatic_cast<SwSectionNode*>(pNd)->GetSection().GetFormat();
} elseif (pNd->IsStartNode() && (SwTableBoxStartNode == static_cast<SwStartNode*>(pNd)->GetStartNodeType()))
{
SwTableNode* pTableNode = pNd->FindTableNode(); if (pTableNode)
{
SwTableBox* pBox = pTableNode->GetTable().GetTableBox(m_nNodeIndex); if (pBox)
{ return pBox->GetFrameFormat();
}
}
}
}
[[fallthrough]]; case RES_DRAWFRMFMT: case RES_FLYFRMFMT:
{ auto it = rDoc.GetSpzFrameFormats()->findByTypeAndName( m_nFormatWhich, m_sFormatName ); if( it != rDoc.GetSpzFrameFormats()->typeAndNameEnd() ) return *it;
SwFormat* pFormat = rDoc.GetFrameFormats()->FindFormatByName(m_sFormatName); if (pFormat) return pFormat;
} break;
}
return nullptr;
}
void SwUndoFormatAttr::RedoImpl(::sw::UndoRedoContext & rContext)
{ // #i35443# - Because the undo stores the attributes for // redo, the same code as for <Undo(..)> can be applied for <Redo(..)>
UndoImpl(rContext);
}
void SwUndoFormatAttr::RepeatImpl(::sw::RepeatContext & rContext)
{ if (!m_oOldSet) return;
SwDoc & rDoc(rContext.GetDoc());
SwFormat * pFormat = GetFormat(rDoc); if (!pFormat) return;
case RES_FLYFRMFMT: { // Check if the cursor is in a flying frame // Steps: search in all FlyFrameFormats for the FlyContent attribute // and validate if the cursor is in the respective section
SwFrameFormat *const pFly =
rContext.GetRepeatPaM().GetPointNode().GetFlyFormat(); if( pFly ) { // Bug 43672: do not set all attributes! if (SfxItemState::SET ==
pFormat->GetAttrSet().GetItemState( RES_CNTNT )) {
SfxItemSet aTmpSet( pFormat->GetAttrSet() );
aTmpSet.ClearItem( RES_CNTNT ); if( aTmpSet.Count() ) {
rDoc.SetAttr( aTmpSet, *pFly );
}
} else {
rDoc.SetAttr( pFormat->GetAttrSet(), *pFly );
}
} break;
}
}
}
void SwUndoFormatAttr::PutAttr( const SfxPoolItem& rItem, const SwDoc& rDoc )
{ if (RES_CNTNT == rItem.Which())
{ return; // tdf#126017 never save SwNodeIndex, it will go stale
}
m_oOldSet->Put( rItem ); if ( RES_ANCHOR == rItem.Which() )
{
SwFormat * pFormat = GetFormat( rDoc );
SaveFlyAnchor( pFormat, m_bSaveDrawPt );
}
}
void SwUndoFormatAttr::SaveFlyAnchor( const SwFormat * pFormat, bool bSvDrwPt )
{ // Format is valid, otherwise you would not reach this point here if( bSvDrwPt ) { if (pFormat && RES_DRAWFRMFMT == pFormat->Which()) {
Point aPt( static_cast<const SwFrameFormat*>(pFormat)->FindSdrObject()
->GetRelativePos() ); // store old value as attribute, to keep SwUndoFormatAttr small
m_oOldSet->Put( SwFormatFrameSize( SwFrameSize::Variable, aPt.X(), aPt.Y() ) );
}
}
Point aDrawSavePt, aDrawOldPt; if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() ) { if( RES_DRAWFRMFMT == pFrameFormat->Which() ) { // get the old cached value const SwFormatFrameSize& rOldSize = m_oOldSet->Get( RES_FRM_SIZE );
aDrawSavePt.setX( rOldSize.GetWidth() );
aDrawSavePt.setY( rOldSize.GetHeight() );
m_oOldSet->ClearItem( RES_FRM_SIZE );
// write the current value into cache
aDrawOldPt = pFrameFormat->FindSdrObject()->GetRelativePos();
} else {
pFrameFormat->DelFrames(); // delete Frames
}
}
const SwFormatAnchor &rOldAnch = pFrameFormat->GetAnchor(); // #i54336# // Consider case, that as-character anchored object has moved its anchor position. if (RndStdIds::FLY_AS_CHAR == rOldAnch.GetAnchorId()) { // With InContents it's tricky: the text attribute needs to be deleted. // Unfortunately, this not only destroys the Frames but also the format. // To prevent that, first detach the connection between attribute and // format.
SwTextNode *pTextNode = static_cast<SwTextNode*>(rOldAnch.GetAnchorNode());
OSL_ENSURE( pTextNode->HasHints(), "Missing FlyInCnt-Hint." ); const sal_Int32 nIdx = rOldAnch.GetAnchorContentOffset();
SwTextAttr * const pHint =
pTextNode->GetTextAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
assert(pHint && "Missing Hint.");
OSL_ENSURE( pHint->Which() == RES_TXTATR_FLYCNT, "Missing FlyInCnt-Hint." );
OSL_ENSURE( pHint->GetFlyCnt().GetFrameFormat() == pFrameFormat, "Wrong TextFlyCnt-Hint." ); const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt()).SetFlyFormat();
// Connection is now detached, therefore the attribute can be deleted
pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
}
{
m_oOldSet->Put( aNewAnchor );
SwUndoFormatAttrHelper aTmp( *pFrameFormat, m_bSaveDrawPt );
pFrameFormat->SetFormatAttr( *m_oOldSet ); if ( aTmp.GetUndo() ) {
m_nNodeIndex = aTmp.GetUndo()->m_nNodeIndex; // transfer ownership of helper object's old set if (aTmp.GetUndo()->m_oOldSet)
m_oOldSet.emplace(std::move(*aTmp.GetUndo()->m_oOldSet)); else
m_oOldSet.reset();
} else {
m_oOldSet->ClearItem();
}
}
if ( RES_DRAWFRMFMT == pFrameFormat->Which() )
{ // The Draw model also prepared an Undo object for its right positioning // which unfortunately is relative. Therefore block here a position // change of the Contact object by setting the anchor. const SwFormatVertOrient& rVertOrient = pFrameFormat->GetVertOrient(); const SwFormatHoriOrient& rHoriOrient = pFrameFormat->GetHoriOrient();
Point aFormatPos(rHoriOrient.GetPos(), rVertOrient.GetPos()); if (aDrawSavePt != aFormatPos)
{ // If the position would be the same, then skip the call: either it would do nothing or // it would just go wrong.
pFrameFormat->CallSwClientNotify(sw::RestoreFlyAnchorHint(aDrawSavePt));
}
// cache the old value again
m_oOldSet->Put(SwFormatFrameSize(SwFrameSize::Variable, aDrawOldPt.X(), aDrawOldPt.Y()));
}
if (RndStdIds::FLY_AS_CHAR == aNewAnchor.GetAnchorId()) {
SwTextNode* pTextNd = aNewAnchor.GetAnchorNode()->GetTextNode();
OSL_ENSURE( pTextNd, "no Text Node at position." );
SwFormatFlyCnt aFormat( pFrameFormat );
pTextNd->InsertItem( aFormat, aNewAnchor.GetAnchorContentOffset(), 0 );
}
if (RES_DRAWFRMFMT != pFrameFormat->Which())
pFrameFormat->MakeFrames(); else
{
pFrameFormat->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::POST_RESTORE_FLY_ANCHOR));
}
// Save character style as a style name, not as a reference const SfxPoolItem* pItem = m_AttrSet.GetItem(RES_TXTATR_CHARFMT); if (pItem)
{
uno::Any aValue;
pItem->QueryValue(aValue, RES_TXTATR_CHARFMT);
OUString sTmp; if (aValue >>= sTmp)
m_aChrFormatName = UIName(sTmp);
}
}
SwUndoAttr::SwUndoAttr( const SwPaM& rRange, SfxItemSet aSet, const SetAttrMode nFlags )
: SwUndo( SwUndoId::INSATTR, rRange.GetDoc() ), SwUndRng( rRange )
, m_AttrSet(std::move( aSet ))
, m_pHistory( new SwHistory )
, m_nNodeIndex( NODE_OFFSET_MAX )
, m_nInsertFlags( nFlags )
{ // Save character style as a style name, not as a reference const SfxPoolItem* pItem = m_AttrSet.GetItem(RES_TXTATR_CHARFMT); if (pItem)
{
uno::Any aValue;
pItem->QueryValue(aValue, RES_TXTATR_CHARFMT);
OUString sTmp; if (aValue >>= sTmp)
m_aChrFormatName = UIName(sTmp);
}
}
// Restore pointer to char format from name if (!m_aChrFormatName.isEmpty())
{
SwCharFormat* pCharFormat = rDoc.FindCharFormatByName(m_aChrFormatName); if (pCharFormat)
{
SwFormatCharFormat aFormat(pCharFormat);
m_AttrSet.Put(aFormat);
}
}
if ( NODE_OFFSET_MAX != m_nNodeIndex ) {
rPam.SetMark(); if ( rPam.Move( fnMoveBackward ) ) {
rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( *m_pRedlineData, rPam ), true);
}
rPam.DeleteMark();
} else { if (m_pRedlineSaveData)
{ // We saved some (typically non-format) redline before our action. First set that on // the document, so AppendRedline() can create a hierarchical redline.
SetSaveData(rDoc, *m_pRedlineSaveData);
}
rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( *m_pRedlineData, rPam ), true);
}
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.