1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <libxml/xmlwriter.h>
22 #include <svl/itemiter.hxx>
23 #include <svx/svdundo.hxx>
24 #include <osl/diagnose.h>
25 #include <hintids.hxx>
27 #include <fmtflcnt.hxx>
28 #include <fmtanchr.hxx>
29 #include <fmtcntnt.hxx>
30 #include <txtflcnt.hxx>
32 #include <UndoCore.hxx>
35 #include <IDocumentLayoutAccess.hxx>
36 #include <rootfrm.hxx>
42 #include <frameformats.hxx>
43 #include <svx/svdobj.hxx>
45 SwUndoFlyBase::SwUndoFlyBase( SwFrameFormat
* pFormat
, SwUndoId nUndoId
)
46 : SwUndo(nUndoId
, pFormat
->GetDoc())
47 , m_pFrameFormat(pFormat
)
50 , m_nRndId(RndStdIds::FLY_AT_PARA
)
55 SwUndoFlyBase::~SwUndoFlyBase()
57 if( m_bDelFormat
) // delete during an Undo?
59 if (const auto& pTextBoxes
= m_pFrameFormat
->GetOtherTextBoxFormats())
61 // Clear and unregister before release.
62 if (m_pFrameFormat
->Which() == RES_FLYFRMFMT
)
63 pTextBoxes
->DelTextBox(m_pFrameFormat
);
65 if (m_pFrameFormat
->Which() == RES_DRAWFRMFMT
)
66 pTextBoxes
->ClearAll();
68 // clear that before delete
69 m_pFrameFormat
->SetOtherTextBoxFormats(nullptr);
71 delete m_pFrameFormat
;
75 void SwUndoFlyBase::dumpAsXml(xmlTextWriterPtr pWriter
) const
77 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwUndoFlyBase"));
78 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_nNodePagePos"),
79 BAD_CAST(OString::number(sal_Int32(m_nNodePagePos
)).getStr()));
80 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_nContentPos"),
81 BAD_CAST(OString::number(m_nContentPos
).getStr()));
82 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_nRndId"),
83 BAD_CAST(OString::number(static_cast<int>(m_nRndId
)).getStr()));
84 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_bDelFormat"),
85 BAD_CAST(OString::boolean(m_bDelFormat
).getStr()));
87 SwUndo::dumpAsXml(pWriter
);
88 SwUndoSaveSection::dumpAsXml(pWriter
);
92 m_pFrameFormat
->dumpAsXml(pWriter
);
95 (void)xmlTextWriterEndElement(pWriter
);
98 void SwUndoFlyBase::InsFly(::sw::UndoRedoContext
& rContext
, bool bShowSelFrame
)
100 SwDoc
*const pDoc
= & rContext
.GetDoc();
102 // add again into array
103 sw::SpzFrameFormats
& rFlyFormats
= *pDoc
->GetSpzFrameFormats();
104 rFlyFormats
.push_back( static_cast<sw::SpzFrameFormat
*>(m_pFrameFormat
));
106 // OD 26.06.2003 #108784# - insert 'master' drawing object into drawing page
107 if ( RES_DRAWFRMFMT
== m_pFrameFormat
->Which() )
108 m_pFrameFormat
->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::PREP_INSERT_FLY
));
110 SwFormatAnchor
aAnchor( m_nRndId
);
112 if (RndStdIds::FLY_AT_PAGE
== m_nRndId
)
114 aAnchor
.SetPageNum( o3tl::narrowing
<sal_uInt16
>(sal_Int32(m_nNodePagePos
)) );
118 SwPosition
aNewPos(*pDoc
->GetNodes()[m_nNodePagePos
]);
119 if ((RndStdIds::FLY_AS_CHAR
== m_nRndId
) || (RndStdIds::FLY_AT_CHAR
== m_nRndId
))
121 aNewPos
.SetContent( m_nContentPos
);
123 aAnchor
.SetAnchor( &aNewPos
);
126 m_pFrameFormat
->SetFormatAttr( aAnchor
); // reset anchor
128 if( RES_DRAWFRMFMT
!= m_pFrameFormat
->Which() )
130 // get Content and reset ContentAttribute
131 SwNodeIndex
aIdx( pDoc
->GetNodes() );
132 RestoreSection( pDoc
, &aIdx
, SwFlyStartNode
);
133 m_pFrameFormat
->SetFormatAttr( SwFormatContent( aIdx
.GetNode().GetStartNode() ));
136 // Set InContentAttribute not until there is content!
137 // Otherwise the layout would format the Fly beforehand but would not find
138 // content; this happened with graphics from the internet.
139 if (RndStdIds::FLY_AS_CHAR
== m_nRndId
)
141 // there must be at least the attribute in a TextNode
142 SwContentNode
* pCNd
= aAnchor
.GetAnchorNode()->GetContentNode();
143 OSL_ENSURE( pCNd
->IsTextNode(), "no Text Node at position." );
144 SwFormatFlyCnt
aFormat( m_pFrameFormat
);
145 pCNd
->GetTextNode()->InsertItem(aFormat
, m_nContentPos
, m_nContentPos
, SetAttrMode::NOHINTEXPAND
);
148 if (m_pFrameFormat
->GetOtherTextBoxFormats())
150 // recklessly assume that this thing will live longer than the
151 // SwUndoFlyBase - not sure what could be done if that isn't the case...
152 m_pFrameFormat
->GetOtherTextBoxFormats()->GetOwnerShape()->SetOtherTextBoxFormats(
153 m_pFrameFormat
->GetOtherTextBoxFormats());
155 SdrObject
* pSdrObject
156 = m_pFrameFormat
->GetOtherTextBoxFormats()->GetOwnerShape()->FindSdrObject();
157 if (pSdrObject
&& m_pFrameFormat
->Which() == RES_FLYFRMFMT
)
158 m_pFrameFormat
->GetOtherTextBoxFormats()->AddTextBox(pSdrObject
, m_pFrameFormat
);
160 if (m_pFrameFormat
->GetOtherTextBoxFormats()->GetOwnerShape()->Which() == RES_DRAWFRMFMT
)
165 // Make sure the old UNO wrapper is no longer cached after changing the shape +
166 // textframe pair. Otherwise we would have a wrapper which doesn't know about its
167 // textframe, even if it's there.
168 pSdrObject
->setUnoShape(nullptr);
171 if (m_pFrameFormat
->Which() == RES_FLYFRMFMT
)
173 SwFrameFormat
* pShapeFormat
= m_pFrameFormat
->GetOtherTextBoxFormats()->GetOwnerShape();
174 pShapeFormat
->SetFormatAttr(m_pFrameFormat
->GetContent());
178 m_pFrameFormat
->MakeFrames();
182 rContext
.SetSelections(m_pFrameFormat
, nullptr);
186 GetHistory()->Rollback( pDoc
);
190 case RndStdIds::FLY_AS_CHAR
:
191 case RndStdIds::FLY_AT_CHAR
:
193 const SwFormatAnchor
& rAnchor
= m_pFrameFormat
->GetAnchor();
194 m_nNodePagePos
= rAnchor
.GetAnchorNode()->GetIndex();
195 m_nContentPos
= rAnchor
.GetAnchorContentOffset();
198 case RndStdIds::FLY_AT_PARA
:
199 case RndStdIds::FLY_AT_FLY
:
201 const SwFormatAnchor
& rAnchor
= m_pFrameFormat
->GetAnchor();
202 m_nNodePagePos
= rAnchor
.GetAnchorNode()->GetIndex();
205 case RndStdIds::FLY_AT_PAGE
:
209 m_bDelFormat
= false;
212 void SwUndoFlyBase::DelFly( SwDoc
* pDoc
)
214 m_bDelFormat
= true; // delete Format in DTOR
215 m_pFrameFormat
->DelFrames(); // destroy Frames
217 if (m_pFrameFormat
->GetOtherTextBoxFormats())
218 { // tdf#108867 clear that pointer
219 m_pFrameFormat
->GetOtherTextBoxFormats()->GetOwnerShape()->SetOtherTextBoxFormats(nullptr);
222 // all Uno objects should now log themselves off
223 m_pFrameFormat
->RemoveAllUnos();
225 if ( RES_DRAWFRMFMT
!= m_pFrameFormat
->Which() )
227 // if there is content than save it
228 const SwFormatContent
& rContent
= m_pFrameFormat
->GetContent();
229 OSL_ENSURE( rContent
.GetContentIdx(), "Fly without content" );
231 SaveSection( *rContent
.GetContentIdx() );
232 const_cast<SwFormatContent
&>(rContent
).SetNewContentIdx( nullptr );
234 // OD 02.07.2003 #108784# - remove 'master' drawing object from drawing page
236 m_pFrameFormat
->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::PREP_DELETE_FLY
));
238 const SwFormatAnchor
& rAnchor
= m_pFrameFormat
->GetAnchor();
239 SwNode
* pAnchorNode
= rAnchor
.GetAnchorNode();
240 // The positions in Nodes array got shifted.
241 m_nRndId
= rAnchor
.GetAnchorId();
242 if (RndStdIds::FLY_AS_CHAR
== m_nRndId
)
244 m_nNodePagePos
= pAnchorNode
->GetIndex();
245 m_nContentPos
= rAnchor
.GetAnchorContentOffset();
246 SwTextNode
*const pTextNd
= pAnchorNode
->GetTextNode();
247 assert(pTextNd
&& "No Textnode found");
248 SwTextFlyCnt
* const pAttr
= static_cast<SwTextFlyCnt
*>(
249 pTextNd
->GetTextAttrForCharAt( m_nContentPos
, RES_TXTATR_FLYCNT
) );
250 // attribute is still in TextNode, delete
251 if( pAttr
&& pAttr
->GetFlyCnt().GetFrameFormat() == m_pFrameFormat
)
253 // Pointer to 0, do not delete
254 const_cast<SwFormatFlyCnt
&>(pAttr
->GetFlyCnt()).SetFlyFormat();
255 pTextNd
->EraseText( *rAnchor
.GetContentAnchor(), 1 );
258 else if (RndStdIds::FLY_AT_CHAR
== m_nRndId
)
260 m_nNodePagePos
= pAnchorNode
->GetIndex();
261 m_nContentPos
= rAnchor
.GetAnchorContentOffset();
263 else if ((RndStdIds::FLY_AT_PARA
== m_nRndId
) || (RndStdIds::FLY_AT_FLY
== m_nRndId
))
265 m_nNodePagePos
= pAnchorNode
->GetIndex();
269 m_nNodePagePos
= SwNodeOffset(rAnchor
.GetPageNum());
272 m_pFrameFormat
->ResetFormatAttr( RES_ANCHOR
); // delete anchor
275 sw::SpzFrameFormats
& rFlyFormats
= *pDoc
->GetSpzFrameFormats();
276 rFlyFormats
.erase(static_cast<sw::SpzFrameFormat
*>(m_pFrameFormat
));
279 SwUndoInsLayFormat::SwUndoInsLayFormat( SwFrameFormat
* pFormat
, SwNodeOffset nNodeIdx
, sal_Int32 nCntIdx
)
280 : SwUndoFlyBase( pFormat
, RES_DRAWFRMFMT
== pFormat
->Which() ?
281 SwUndoId::INSDRAWFMT
: SwUndoId::INSLAYFMT
),
282 mnCursorSaveIndexPara( nNodeIdx
), mnCursorSaveIndexPos( nCntIdx
)
284 const SwFormatAnchor
& rAnchor
= m_pFrameFormat
->GetAnchor();
285 m_nRndId
= rAnchor
.GetAnchorId();
286 m_bDelFormat
= false;
287 // note: SwUndoInsLayFormat is called with the content being fully inserted
288 // from most places but with only an empty content section from
289 // CopyLayoutFormat(); it's not necessary here to init m_nNodePagePos
290 // because Undo will do it.
293 SwUndoInsLayFormat::~SwUndoInsLayFormat()
297 void SwUndoInsLayFormat::UndoImpl(::sw::UndoRedoContext
& rContext
)
299 SwDoc
& rDoc(rContext
.GetDoc());
300 const SwFormatContent
& rContent
= m_pFrameFormat
->GetContent();
301 if( rContent
.GetContentIdx() ) // no content
303 assert(&rContent
.GetContentIdx()->GetNodes() == &rDoc
.GetNodes());
304 if( mnCursorSaveIndexPara
> SwNodeOffset(0) )
306 SwTextNode
*const pNode
=
307 rDoc
.GetNodes()[mnCursorSaveIndexPara
]->GetTextNode();
310 SwNodeIndex
aIdx( rDoc
.GetNodes(),
311 rContent
.GetContentIdx()->GetIndex() );
312 SwNodeIndex
aEndIdx( rDoc
.GetNodes(),
313 aIdx
.GetNode().EndOfSectionIndex() );
314 SwPosition
aPos( *pNode
, mnCursorSaveIndexPos
);
315 // don't delete bookmarks here, DelFly() will save them in history
316 ::PaMCorrAbs(SwPaM(aIdx
, aEndIdx
), aPos
);
317 // TODO: is aPos actually a sensible pos for e.g. SwXText* ?
324 void SwUndoInsLayFormat::RedoImpl(::sw::UndoRedoContext
& rContext
)
329 void SwUndoInsLayFormat::RepeatImpl(::sw::RepeatContext
& rContext
)
331 SwDoc
*const pDoc
= & rContext
.GetDoc();
332 // get anchor and reset it
333 SwFormatAnchor
aAnchor( m_pFrameFormat
->GetAnchor() );
334 if ((RndStdIds::FLY_AT_PARA
== aAnchor
.GetAnchorId()) ||
335 (RndStdIds::FLY_AT_CHAR
== aAnchor
.GetAnchorId()) ||
336 (RndStdIds::FLY_AS_CHAR
== aAnchor
.GetAnchorId()))
338 SwPosition
aPos( *rContext
.GetRepeatPaM().GetPoint() );
339 aAnchor
.SetAnchor( &aPos
);
341 else if( RndStdIds::FLY_AT_FLY
== aAnchor
.GetAnchorId() )
343 SwStartNode
const*const pSttNd
=
344 rContext
.GetRepeatPaM().GetPointNode().FindFlyStartNode();
347 SwPosition
aPos( *pSttNd
);
348 aAnchor
.SetAnchor( &aPos
);
355 else if (RndStdIds::FLY_AT_PAGE
== aAnchor
.GetAnchorId())
357 aAnchor
.SetPageNum( pDoc
->getIDocumentLayoutAccess().GetCurrentLayout()->GetCurrPage( &rContext
.GetRepeatPaM() ));
360 OSL_FAIL( "What kind of anchor is this?" );
363 (void) pDoc
->getIDocumentLayoutAccess().CopyLayoutFormat( *m_pFrameFormat
, aAnchor
, true, true );
366 OUString
SwUndoInsLayFormat::GetComment() const
370 // HACK: disable caching:
371 // the SfxUndoManager calls GetComment() too early: the pFrameFormat does not
372 // have a SwDrawContact yet, so it will fall back to SwUndo::GetComment(),
373 // which sets pComment to a wrong value.
378 If frame format is present and has an SdrObject use the undo
379 comment of the SdrObject. Otherwise use the default comment.
384 const SdrObject
* pSdrObj
= m_pFrameFormat
->FindSdrObject();
387 aResult
= SdrUndoNewObj::GetComment( *pSdrObj
);
393 aResult
= SwUndo::GetComment();
396 aResult
= *maComment
;
402 lcl_GetSwUndoId(SwFrameFormat
const *const pFrameFormat
)
404 if (RES_DRAWFRMFMT
!= pFrameFormat
->Which())
406 const SwFormatContent
& rContent
= pFrameFormat
->GetContent();
407 OSL_ENSURE( rContent
.GetContentIdx(), "Fly without content" );
409 SwNodeIndex
firstNode(*rContent
.GetContentIdx(), 1);
410 SwNoTextNode
*const pNoTextNode(firstNode
.GetNode().GetNoTextNode());
411 if (pNoTextNode
&& pNoTextNode
->IsGrfNode())
413 return SwUndoId::DELGRF
;
415 else if (pNoTextNode
&& pNoTextNode
->IsOLENode())
417 // surprisingly not SwUndoId::DELOLE, which does not seem to work
418 return SwUndoId::DELETE
;
421 return SwUndoId::DELLAYFMT
;
424 SwUndoDelLayFormat::SwUndoDelLayFormat( SwFrameFormat
* pFormat
)
425 : SwUndoFlyBase( pFormat
, lcl_GetSwUndoId(pFormat
) )
426 , m_bShowSelFrame( true )
428 SwDoc
* pDoc
= pFormat
->GetDoc();
432 SwRewriter
SwUndoDelLayFormat::GetRewriter() const
434 SwRewriter aRewriter
;
436 SwDoc
* pDoc
= m_pFrameFormat
->GetDoc();
440 const SwNodeIndex
* pIdx
= GetMvSttIdx();
441 if( SwNodeOffset(1) == GetMvNodeCnt() && pIdx
)
443 SwNode
*const pNd
= & pIdx
->GetNode();
445 if ( pNd
->IsNoTextNode() && pNd
->IsOLENode())
447 SwOLENode
* pOLENd
= pNd
->GetOLENode();
449 aRewriter
.AddRule(UndoArg1
, pOLENd
->GetDescription());
457 void SwUndoDelLayFormat::UndoImpl(::sw::UndoRedoContext
& rContext
)
459 InsFly( rContext
, m_bShowSelFrame
);
462 void SwUndoDelLayFormat::RedoImpl(::sw::UndoRedoContext
& rContext
)
464 SwDoc
& rDoc(rContext
.GetDoc());
465 const SwFormatContent
& rContent
= m_pFrameFormat
->GetContent();
466 if( rContent
.GetContentIdx() ) // no content
468 RemoveIdxFromSection(rDoc
, rContent
.GetContentIdx()->GetIndex());
474 void SwUndoDelLayFormat::RedoForRollback()
476 const SwFormatContent
& rContent
= m_pFrameFormat
->GetContent();
477 if( rContent
.GetContentIdx() ) // no content
478 RemoveIdxFromSection( *m_pFrameFormat
->GetDoc(),
479 rContent
.GetContentIdx()->GetIndex() );
481 DelFly( m_pFrameFormat
->GetDoc() );
484 SwUndoSetFlyFormat::SwUndoSetFlyFormat( SwFrameFormat
& rFlyFormat
, const SwFrameFormat
& rNewFrameFormat
)
485 : SwUndo( SwUndoId::SETFLYFRMFMT
, rFlyFormat
.GetDoc() ), SwClient( &rFlyFormat
), m_pFrameFormat( &rFlyFormat
),
486 m_DerivedFromFormatName( rFlyFormat
.IsDefault() ? u
""_ustr
: rFlyFormat
.DerivedFrom()->GetName() ),
487 m_NewFormatName( rNewFrameFormat
.GetName() ),
488 m_oItemSet( std::in_place
, *rFlyFormat
.GetAttrSet().GetPool(),
489 rFlyFormat
.GetAttrSet().GetRanges() ),
490 m_nOldNode( 0 ), m_nNewNode( 0 ),
491 m_nOldContent( 0 ), m_nNewContent( 0 ),
492 m_nOldAnchorType( RndStdIds::FLY_AT_PARA
), m_nNewAnchorType( RndStdIds::FLY_AT_PARA
), m_bAnchorChanged( false )
496 SwRewriter
SwUndoSetFlyFormat::GetRewriter() const
498 SwRewriter aRewriter
;
500 aRewriter
.AddRule(UndoArg1
, m_NewFormatName
);
505 SwUndoSetFlyFormat::~SwUndoSetFlyFormat()
509 void SwUndoSetFlyFormat::GetAnchor( SwFormatAnchor
& rAnchor
,
510 SwNodeOffset nNode
, sal_Int32 nContent
)
512 RndStdIds nAnchorTyp
= rAnchor
.GetAnchorId();
513 if (RndStdIds::FLY_AT_PAGE
!= nAnchorTyp
)
515 SwNode
* pNd
= m_pFrameFormat
->GetDoc()->GetNodes()[ nNode
];
517 if( RndStdIds::FLY_AT_FLY
== nAnchorTyp
518 ? ( !pNd
->IsStartNode() || SwFlyStartNode
!=
519 static_cast<SwStartNode
*>(pNd
)->GetStartNodeType() )
520 : !pNd
->IsTextNode() )
522 pNd
= nullptr; // invalid position
526 SwPosition
aPos( *pNd
);
527 if ((RndStdIds::FLY_AS_CHAR
== nAnchorTyp
) ||
528 (RndStdIds::FLY_AT_CHAR
== nAnchorTyp
))
530 if (nContent
> pNd
->GetTextNode()->GetText().getLength())
532 pNd
= nullptr; // invalid position
536 aPos
.SetContent(nContent
);
541 rAnchor
.SetAnchor( &aPos
);
547 // invalid position - assign first page
548 rAnchor
.SetType( RndStdIds::FLY_AT_PAGE
);
549 rAnchor
.SetPageNum( 1 );
553 rAnchor
.SetPageNum( nContent
);
556 void SwUndoSetFlyFormat::UndoImpl(::sw::UndoRedoContext
& rContext
)
558 SwDoc
& rDoc
= rContext
.GetDoc();
560 // Is the new Format still existent?
561 SwFrameFormat
* pDerivedFromFrameFormat
= rDoc
.FindFrameFormatByName(m_DerivedFromFormatName
);
562 if (!pDerivedFromFrameFormat
)
565 if( m_bAnchorChanged
)
566 m_pFrameFormat
->DelFrames();
568 if( m_pFrameFormat
->DerivedFrom() != pDerivedFromFrameFormat
)
569 m_pFrameFormat
->SetDerivedFrom(pDerivedFromFrameFormat
);
571 SfxItemIter
aIter( *m_oItemSet
);
572 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
574 if( IsInvalidItem( pItem
))
575 m_pFrameFormat
->ResetFormatAttr( aIter
.GetCurWhich() );
577 m_pFrameFormat
->SetFormatAttr( *pItem
);
580 if( m_bAnchorChanged
)
582 const SwFormatAnchor
& rOldAnch
= m_pFrameFormat
->GetAnchor();
583 if (RndStdIds::FLY_AS_CHAR
== rOldAnch
.GetAnchorId())
585 // With InContents it's tricky: the text attribute needs to be
586 // deleted. Unfortunately, this not only destroys the Frames but
587 // also the format. To prevent that, first detach the
588 // connection between attribute and format.
589 SwNode
*pAnchorNode
= rOldAnch
.GetAnchorNode();
590 SwTextNode
*pTextNode
= pAnchorNode
->GetTextNode();
591 OSL_ENSURE( pTextNode
->HasHints(), "Missing FlyInCnt-Hint." );
592 const sal_Int32 nIdx
= rOldAnch
.GetAnchorContentOffset();
593 SwTextAttr
* pHint
= pTextNode
->GetTextAttrForCharAt(
594 nIdx
, RES_TXTATR_FLYCNT
);
595 assert(pHint
&& "Missing Hint.");
596 OSL_ENSURE( pHint
->Which() == RES_TXTATR_FLYCNT
,
597 "Missing FlyInCnt-Hint." );
598 OSL_ENSURE( pHint
->GetFlyCnt().GetFrameFormat() == m_pFrameFormat
,
599 "Wrong TextFlyCnt-Hint." );
600 const_cast<SwFormatFlyCnt
&>(pHint
->GetFlyCnt()).SetFlyFormat();
602 // Connection is now detached, therefore the attribute can be
604 pTextNode
->DeleteAttributes( RES_TXTATR_FLYCNT
, nIdx
, nIdx
);
608 SwFormatAnchor
aNewAnchor( m_nOldAnchorType
);
609 GetAnchor( aNewAnchor
, m_nOldNode
, m_nOldContent
);
610 m_pFrameFormat
->SetFormatAttr( aNewAnchor
);
612 if (RndStdIds::FLY_AS_CHAR
== aNewAnchor
.GetAnchorId())
614 SwNode
* pAnchorNode
= aNewAnchor
.GetAnchorNode();
615 SwFormatFlyCnt
aFormat( m_pFrameFormat
);
616 pAnchorNode
->GetTextNode()->InsertItem( aFormat
,
620 m_pFrameFormat
->MakeFrames();
622 rContext
.SetSelections(m_pFrameFormat
, nullptr);
625 void SwUndoSetFlyFormat::RedoImpl(::sw::UndoRedoContext
& rContext
)
627 SwDoc
& rDoc
= rContext
.GetDoc();
629 // Is the new Format still existent?
630 SwFrameFormat
* pNewFrameFormat
= rDoc
.FindFrameFormatByName(m_NewFormatName
);
631 if (!pNewFrameFormat
)
634 if( m_bAnchorChanged
)
636 SwFormatAnchor
aNewAnchor( m_nNewAnchorType
);
637 GetAnchor( aNewAnchor
, m_nNewNode
, m_nNewContent
);
638 SfxItemSet
aSet( rDoc
.GetAttrPool(), aFrameFormatSetRange
);
639 aSet
.Put( aNewAnchor
);
640 rDoc
.SetFrameFormatToFly( *m_pFrameFormat
, *pNewFrameFormat
, &aSet
);
643 rDoc
.SetFrameFormatToFly( *m_pFrameFormat
, *pNewFrameFormat
);
645 rContext
.SetSelections(m_pFrameFormat
, nullptr);
648 void SwUndoSetFlyFormat::PutAttr( sal_uInt16 nWhich
, const SfxPoolItem
* pItem
)
650 if( pItem
&& !SfxPoolItem::areSame(pItem
, GetDfltAttr( nWhich
) ) )
652 // Special treatment for this anchor
653 if( RES_ANCHOR
== nWhich
)
655 // only keep the first change
656 OSL_ENSURE( !m_bAnchorChanged
, "multiple changes of an anchor are not allowed!" );
658 m_bAnchorChanged
= true;
660 const SwFormatAnchor
* pAnchor
= static_cast<const SwFormatAnchor
*>(pItem
);
661 m_nOldAnchorType
= pAnchor
->GetAnchorId();
662 switch( m_nOldAnchorType
)
664 case RndStdIds::FLY_AS_CHAR
:
665 case RndStdIds::FLY_AT_CHAR
:
666 m_nOldContent
= pAnchor
->GetAnchorContentOffset();
668 case RndStdIds::FLY_AT_PARA
:
669 case RndStdIds::FLY_AT_FLY
:
670 m_nOldNode
= pAnchor
->GetAnchorNode()->GetIndex();
674 m_nOldContent
= pAnchor
->GetPageNum();
677 pAnchor
= &m_pFrameFormat
->GetAnchor();
678 m_nNewAnchorType
= pAnchor
->GetAnchorId();
679 switch( m_nNewAnchorType
)
681 case RndStdIds::FLY_AS_CHAR
:
682 case RndStdIds::FLY_AT_CHAR
:
683 m_nNewContent
= pAnchor
->GetAnchorContentOffset();
685 case RndStdIds::FLY_AT_PARA
:
686 case RndStdIds::FLY_AT_FLY
:
687 m_nNewNode
= pAnchor
->GetAnchorNode()->GetIndex();
691 m_nNewContent
= pAnchor
->GetPageNum();
695 m_oItemSet
->Put( *pItem
);
698 m_oItemSet
->InvalidateItem( nWhich
);
701 void SwUndoSetFlyFormat::SwClientNotify(const SwModify
&, const SfxHint
& rHint
)
703 if (rHint
.GetId() != SfxHintId::SwLegacyModify
)
705 auto pLegacy
= static_cast<const sw::LegacyModifyHint
*>(&rHint
);
708 const sal_uInt16 nWhich
= pLegacy
->m_pOld
->Which();
709 if(nWhich
< POOLATTR_END
)
710 PutAttr(nWhich
, pLegacy
->m_pOld
);
711 else if(RES_ATTRSET_CHG
== nWhich
)
713 SfxItemIter
aIter(*static_cast<const SwAttrSetChg
*>(pLegacy
->m_pOld
)->GetChgSet());
714 for(const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
715 PutAttr(pItem
->Which(), pItem
);
719 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */