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 <UndoDraw.hxx>
22 #include <svx/svdogrp.hxx>
23 #include <svx/svdundo.hxx>
24 #include <svx/svdpage.hxx>
25 #include <svx/svdmark.hxx>
26 #include <svx/svdview.hxx>
27 #include <osl/diagnose.h>
29 #include <hintids.hxx>
30 #include <fmtanchr.hxx>
31 #include <fmtflcnt.hxx>
32 #include <txtflcnt.hxx>
35 #include <IDocumentUndoRedo.hxx>
36 #include <IDocumentLayoutAccess.hxx>
40 #include <UndoCore.hxx>
41 #include <dcontact.hxx>
43 #include <frameformats.hxx>
44 #include <textboxhelper.hxx>
46 struct SwUndoGroupObjImpl
48 SwDrawFrameFormat
* pFormat
;
50 SwNodeOffset nNodeIdx
;
55 void SwDoc::AddDrawUndo( std::unique_ptr
<SdrUndoAction
> pUndo
)
57 if (GetIDocumentUndoRedo().DoesUndo() &&
58 GetIDocumentUndoRedo().DoesDrawUndo())
60 const SdrMarkList
* pMarkList
= nullptr;
61 SwViewShell
* pSh
= getIDocumentLayoutAccess().GetCurrentViewShell();
62 if( pSh
&& pSh
->HasDrawView() )
63 pMarkList
= &pSh
->GetDrawView()->GetMarkedObjectList();
65 GetIDocumentUndoRedo().AppendUndo( std::make_unique
<SwSdrUndo
>(std::move(pUndo
), pMarkList
, *this) );
69 SwSdrUndo::SwSdrUndo( std::unique_ptr
<SdrUndoAction
> pUndo
, const SdrMarkList
* pMrkLst
, const SwDoc
& rDoc
)
70 : SwUndo( SwUndoId::DRAWUNDO
, &rDoc
), m_pSdrUndo( std::move(pUndo
) )
72 if( pMrkLst
&& pMrkLst
->GetMarkCount() )
73 m_pMarkList
.reset( new SdrMarkList( *pMrkLst
) );
76 SwSdrUndo::~SwSdrUndo()
82 void SwSdrUndo::UndoImpl(::sw::UndoRedoContext
& rContext
)
85 rContext
.SetSelections(nullptr, m_pMarkList
.get());
88 void SwSdrUndo::RedoImpl(::sw::UndoRedoContext
& rContext
)
91 rContext
.SetSelections(nullptr, m_pMarkList
.get());
94 OUString
SwSdrUndo::GetComment() const
96 return m_pSdrUndo
->GetComment();
99 static void lcl_SaveAnchor( SwFrameFormat
* pFormat
, SwNodeOffset
& rNodePos
)
101 const SwFormatAnchor
& rAnchor
= pFormat
->GetAnchor();
102 if (!((RndStdIds::FLY_AT_PARA
== rAnchor
.GetAnchorId()) ||
103 (RndStdIds::FLY_AT_CHAR
== rAnchor
.GetAnchorId()) ||
104 (RndStdIds::FLY_AT_FLY
== rAnchor
.GetAnchorId()) ||
105 (RndStdIds::FLY_AS_CHAR
== rAnchor
.GetAnchorId())))
108 rNodePos
= rAnchor
.GetAnchorNode()->GetIndex();
109 sal_Int32 nContentPos
= 0;
111 if (RndStdIds::FLY_AS_CHAR
== rAnchor
.GetAnchorId())
113 nContentPos
= rAnchor
.GetAnchorContentOffset();
115 // destroy TextAttribute
116 SwTextNode
*pTextNd
= pFormat
->GetDoc()->GetNodes()[ rNodePos
]->GetTextNode();
117 OSL_ENSURE( pTextNd
, "No text node found!" );
118 SwTextFlyCnt
* pAttr
= static_cast<SwTextFlyCnt
*>(
119 pTextNd
->GetTextAttrForCharAt( nContentPos
, RES_TXTATR_FLYCNT
));
120 // attribute still in text node, delete
121 if( pAttr
&& pAttr
->GetFlyCnt().GetFrameFormat() == pFormat
)
123 // just set pointer to 0, don't delete
124 const_cast<SwFormatFlyCnt
&>(pAttr
->GetFlyCnt()).SetFlyFormat();
125 SwContentIndex
aIdx( pTextNd
, nContentPos
);
126 pTextNd
->EraseText( aIdx
, 1 );
129 else if (RndStdIds::FLY_AT_CHAR
== rAnchor
.GetAnchorId())
131 nContentPos
= rAnchor
.GetAnchorContentOffset();
134 pFormat
->SetFormatAttr( SwFormatAnchor( rAnchor
.GetAnchorId(), nContentPos
) );
137 static void lcl_RestoreAnchor( SwFrameFormat
* pFormat
, SwNodeOffset nNodePos
)
139 const SwFormatAnchor
& rAnchor
= pFormat
->GetAnchor();
140 if (!((RndStdIds::FLY_AT_PARA
== rAnchor
.GetAnchorId()) ||
141 (RndStdIds::FLY_AT_CHAR
== rAnchor
.GetAnchorId()) ||
142 (RndStdIds::FLY_AT_FLY
== rAnchor
.GetAnchorId()) ||
143 (RndStdIds::FLY_AS_CHAR
== rAnchor
.GetAnchorId())))
146 const sal_Int32 nContentPos
= rAnchor
.GetPageNum();
147 SwNodes
& rNds
= pFormat
->GetDoc()->GetNodes();
149 SwNodeIndex
aIdx( rNds
, nNodePos
);
150 SwPosition
aPos( aIdx
);
152 SwFormatAnchor
aTmp( rAnchor
.GetAnchorId() );
153 if ((RndStdIds::FLY_AS_CHAR
== rAnchor
.GetAnchorId()) ||
154 (RndStdIds::FLY_AT_CHAR
== rAnchor
.GetAnchorId()))
156 aPos
.SetContent( nContentPos
);
158 aTmp
.SetAnchor( &aPos
);
159 RndStdIds nAnchorId
= rAnchor
.GetAnchorId();
160 pFormat
->SetFormatAttr( aTmp
);
162 if (RndStdIds::FLY_AS_CHAR
== nAnchorId
)
164 SwTextNode
*pTextNd
= aIdx
.GetNode().GetTextNode();
165 OSL_ENSURE( pTextNd
, "no Text Node" );
166 SwFormatFlyCnt
aFormat( pFormat
);
167 pTextNd
->InsertItem( aFormat
, nContentPos
, nContentPos
);
171 SwUndoDrawGroup::SwUndoDrawGroup( sal_uInt16 nCnt
, const SwDoc
& rDoc
)
172 : SwUndo( SwUndoId::DRAWGROUP
, &rDoc
), m_nSize( nCnt
+ 1 ), m_bDeleteFormat( true )
174 m_pObjArray
.reset( new SwUndoGroupObjImpl
[ m_nSize
] );
177 SwUndoDrawGroup::~SwUndoDrawGroup()
179 if( m_bDeleteFormat
)
181 SwUndoGroupObjImpl
* pTmp
= m_pObjArray
.get() + 1;
182 for( sal_uInt16 n
= 1; n
< m_nSize
; ++n
, ++pTmp
)
183 delete pTmp
->pFormat
;
186 delete m_pObjArray
[0].pFormat
;
189 void SwUndoDrawGroup::UndoImpl(::sw::UndoRedoContext
&)
191 m_bDeleteFormat
= false;
194 SwDrawFrameFormat
* pFormat
= m_pObjArray
[0].pFormat
;
196 pFormat
->CallSwClientNotify(sw::ContactChangedHint(&m_pObjArray
[0].pObj
));
197 auto pObj
= m_pObjArray
[0].pObj
;
198 pObj
->SetUserCall(nullptr);
200 // This will store the textboxes what were owned by this group
201 std::vector
<std::pair
<SdrObject
*, SwFrameFormat
*>> vTextBoxes
;
202 if (auto pOldTextBoxNode
= pFormat
->GetOtherTextBoxFormats())
204 if (auto pChildren
= pObj
->getChildrenOfSdrObject())
206 for (size_t idx
= 0; idx
< pChildren
->GetObjCount(); idx
++)
208 auto pChild
= pChildren
->GetObj(idx
);
210 if (auto pTextBox
= pOldTextBoxNode
->GetTextBox(pChild
))
211 vTextBoxes
.push_back(std::pair(pChild
, pTextBox
));
216 ::lcl_SaveAnchor( pFormat
, m_pObjArray
[0].nNodeIdx
);
218 pFormat
->RemoveAllUnos();
221 SwDoc
* pDoc
= pFormat
->GetDoc();
222 sw::SpzFrameFormats
& rFlyFormats
= *pDoc
->GetSpzFrameFormats();
223 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), pFormat
));
225 for( sal_uInt16 n
= 1; n
< m_nSize
; ++n
)
227 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[n
];
229 ::lcl_RestoreAnchor( rSave
.pFormat
, rSave
.nNodeIdx
);
230 rFlyFormats
.push_back(static_cast<sw::SpzFrameFormat
*>(rSave
.pFormat
));
234 SwDrawContact
*pContact
= new SwDrawContact( rSave
.pFormat
, pObj
);
235 pContact
->ConnectToLayout();
236 // #i45718# - follow-up of #i35635# move object to visible layer
237 pContact
->MoveObjToVisibleLayer( pObj
);
239 for (auto& rElem
: vTextBoxes
)
241 if (rElem
.first
== pObj
)
243 auto pNewTextBoxNode
= std::make_shared
<SwTextBoxNode
>(SwTextBoxNode(rSave
.pFormat
));
244 rSave
.pFormat
->SetOtherTextBoxFormats(pNewTextBoxNode
);
245 pNewTextBoxNode
->AddTextBox(rElem
.first
, rElem
.second
);
246 rElem
.second
->SetOtherTextBoxFormats(pNewTextBoxNode
);
251 SwDrawFrameFormat
* pDrawFrameFormat
= rSave
.pFormat
;
253 // #i45952# - notify that position attributes are already set
254 OSL_ENSURE(pDrawFrameFormat
,
255 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
256 if (pDrawFrameFormat
)
257 pDrawFrameFormat
->PosAttrSet();
261 void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext
&)
263 m_bDeleteFormat
= true;
266 SwDoc
* pDoc
= m_pObjArray
[0].pFormat
->GetDoc();
267 sw::SpzFrameFormats
& rFlyFormats
= *pDoc
->GetSpzFrameFormats();
269 // This will store the textboxes from the ex-group-shapes
270 std::vector
<std::pair
<SdrObject
*, SwFrameFormat
*>> vTextBoxes
;
272 for( sal_uInt16 n
= 1; n
< m_nSize
; ++n
)
274 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[n
];
276 SdrObject
* pObj
= rSave
.pObj
;
278 SwDrawContact
*pContact
= static_cast<SwDrawContact
*>(GetUserCall(pObj
));
280 // Save the textboxes
281 if (auto pOldTextBoxNode
= rSave
.pFormat
->GetOtherTextBoxFormats())
283 if (auto pTextBox
= pOldTextBoxNode
->GetTextBox(pObj
))
284 vTextBoxes
.push_back(std::pair(pObj
, pTextBox
));
287 // object will destroy itself
288 pContact
->Changed( *pObj
, SdrUserCallType::Delete
, pObj
->GetLastBoundRect() );
289 pObj
->SetUserCall( nullptr );
291 ::lcl_SaveAnchor( rSave
.pFormat
, rSave
.nNodeIdx
);
293 rSave
.pFormat
->RemoveAllUnos();
295 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), rSave
.pFormat
));
298 // re-insert group object
299 ::lcl_RestoreAnchor( m_pObjArray
[0].pFormat
, m_pObjArray
[0].nNodeIdx
);
300 rFlyFormats
.push_back(static_cast<sw::SpzFrameFormat
*>(m_pObjArray
[0].pFormat
));
302 SwDrawContact
*pContact
= new SwDrawContact( m_pObjArray
[0].pFormat
, m_pObjArray
[0].pObj
);
303 // #i26791# - correction: connect object to layout
304 pContact
->ConnectToLayout();
305 // #i45718# - follow-up of #i35635# move object to visible layer
306 pContact
->MoveObjToVisibleLayer( m_pObjArray
[0].pObj
);
308 SwDrawFrameFormat
* pDrawFrameFormat
= m_pObjArray
[0].pFormat
;
310 // Restore the textboxes
311 if (vTextBoxes
.size())
313 auto pNewTextBoxNode
= std::make_shared
<SwTextBoxNode
>(SwTextBoxNode(m_pObjArray
[0].pFormat
));
314 for (auto& rElem
: vTextBoxes
)
316 pNewTextBoxNode
->AddTextBox(rElem
.first
, rElem
.second
);
317 rElem
.second
->SetOtherTextBoxFormats(pNewTextBoxNode
);
319 m_pObjArray
[0].pFormat
->SetOtherTextBoxFormats(pNewTextBoxNode
);
322 // #i45952# - notify that position attributes are already set
323 OSL_ENSURE(pDrawFrameFormat
,
324 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
325 if (pDrawFrameFormat
)
326 pDrawFrameFormat
->PosAttrSet();
329 void SwUndoDrawGroup::AddObj( sal_uInt16 nPos
, SwDrawFrameFormat
* pFormat
, SdrObject
* pObj
)
331 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[nPos
+ 1];
333 rSave
.pFormat
= pFormat
;
334 ::lcl_SaveAnchor( pFormat
, rSave
.nNodeIdx
);
336 pFormat
->RemoveAllUnos();
339 sw::SpzFrameFormats
& rFlyFormats
= *pFormat
->GetDoc()->GetSpzFrameFormats();
340 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), pFormat
));
343 void SwUndoDrawGroup::SetGroupFormat( SwDrawFrameFormat
* pFormat
)
345 m_pObjArray
[0].pObj
= nullptr;
346 m_pObjArray
[0].pFormat
= pFormat
;
349 SwUndoDrawUnGroup::SwUndoDrawUnGroup( SdrObjGroup
* pObj
, const SwDoc
& rDoc
)
350 : SwUndo( SwUndoId::DRAWUNGROUP
, &rDoc
), m_bDeleteFormat( false )
352 m_nSize
= o3tl::narrowing
<sal_uInt16
>(pObj
->GetSubList()->GetObjCount()) + 1;
353 m_pObjArray
.reset( new SwUndoGroupObjImpl
[ m_nSize
] );
355 SwDrawContact
*pContact
= static_cast<SwDrawContact
*>(GetUserCall(pObj
));
356 SwDrawFrameFormat
* pFormat
= static_cast<SwDrawFrameFormat
*>(pContact
->GetFormat());
358 m_pObjArray
[0].pObj
= pObj
;
359 m_pObjArray
[0].pFormat
= pFormat
;
361 // object will destroy itself
362 pContact
->Changed( *pObj
, SdrUserCallType::Delete
, pObj
->GetLastBoundRect() );
363 pObj
->SetUserCall( nullptr );
365 ::lcl_SaveAnchor( pFormat
, m_pObjArray
[0].nNodeIdx
);
367 pFormat
->RemoveAllUnos();
370 sw::SpzFrameFormats
& rFlyFormats
= *pFormat
->GetDoc()->GetSpzFrameFormats();
371 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), pFormat
));
374 SwUndoDrawUnGroup::~SwUndoDrawUnGroup()
376 if( m_bDeleteFormat
)
378 SwUndoGroupObjImpl
* pTmp
= m_pObjArray
.get() + 1;
379 for( sal_uInt16 n
= 1; n
< m_nSize
; ++n
, ++pTmp
)
380 delete pTmp
->pFormat
;
383 delete m_pObjArray
[0].pFormat
;
386 void SwUndoDrawUnGroup::UndoImpl(::sw::UndoRedoContext
& rContext
)
388 m_bDeleteFormat
= true;
390 SwDoc
*const pDoc
= & rContext
.GetDoc();
391 sw::SpzFrameFormats
& rFlyFormats
= *pDoc
->GetSpzFrameFormats();
393 // This will store the textboxes what were owned by this group
394 std::vector
<std::pair
<SdrObject
*, SwFrameFormat
*>> vTextBoxes
;
397 for( sal_uInt16 n
= 1; n
< m_nSize
; ++n
)
399 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[n
];
401 ::lcl_SaveAnchor( rSave
.pFormat
, rSave
.nNodeIdx
);
403 // copy the textboxes for later use to this vector
404 if (auto pTxBxNd
= rSave
.pFormat
->GetOtherTextBoxFormats())
406 if (auto pGroupObj
= m_pObjArray
[0].pObj
)
408 if (auto pChildren
= pGroupObj
->getChildrenOfSdrObject())
410 for (size_t idx
= 0; idx
< pChildren
->GetObjCount(); idx
++)
412 auto pChild
= pChildren
->GetObj(idx
);
413 if (auto pTextBox
= pTxBxNd
->GetTextBox(pChild
))
414 vTextBoxes
.push_back(std::pair(pChild
, pTextBox
));
420 rSave
.pFormat
->RemoveAllUnos();
422 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), rSave
.pFormat
));
425 // re-insert group object
426 ::lcl_RestoreAnchor( m_pObjArray
[0].pFormat
, m_pObjArray
[0].nNodeIdx
);
427 rFlyFormats
.push_back(static_cast<sw::SpzFrameFormat
*>(m_pObjArray
[0].pFormat
));
429 SwDrawContact
*pContact
= new SwDrawContact( m_pObjArray
[0].pFormat
, m_pObjArray
[0].pObj
);
430 pContact
->ConnectToLayout();
431 // #i45718# - follow-up of #i35635# move object to visible layer
432 pContact
->MoveObjToVisibleLayer( m_pObjArray
[0].pObj
);
434 SwDrawFrameFormat
* pDrawFrameFormat
= m_pObjArray
[0].pFormat
;
436 // Restore the vector content for the new formats
437 if (vTextBoxes
.size())
439 auto pNewTxBxNd
= std::make_shared
<SwTextBoxNode
>( SwTextBoxNode(m_pObjArray
[0].pFormat
));
440 for (auto& rElem
: vTextBoxes
)
442 pNewTxBxNd
->AddTextBox(rElem
.first
, rElem
.second
);
443 rElem
.second
->SetOtherTextBoxFormats(pNewTxBxNd
);
445 m_pObjArray
[0].pFormat
->SetOtherTextBoxFormats(pNewTxBxNd
);
449 // #i45952# - notify that position attributes are already set
450 OSL_ENSURE(pDrawFrameFormat
,
451 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
452 if (pDrawFrameFormat
)
453 pDrawFrameFormat
->PosAttrSet();
456 void SwUndoDrawUnGroup::RedoImpl(::sw::UndoRedoContext
&)
458 m_bDeleteFormat
= false;
461 SwDrawFrameFormat
* pFormat
= m_pObjArray
[0].pFormat
;
462 pFormat
->CallSwClientNotify(sw::ContactChangedHint(&(m_pObjArray
[0].pObj
)));
463 m_pObjArray
[0].pObj
->SetUserCall( nullptr );
465 ::lcl_SaveAnchor( pFormat
, m_pObjArray
[0].nNodeIdx
);
467 // Store the textboxes in this vector for later use.
468 std::vector
<std::pair
<SdrObject
*, SwFrameFormat
*>> vTextBoxes
;
469 if (auto pTextBoxNode
= pFormat
->GetOtherTextBoxFormats())
471 auto pMasterObj
= m_pObjArray
[0].pObj
;
473 if (auto pObjList
= pMasterObj
->getChildrenOfSdrObject())
474 for (size_t idx
= 0; idx
< pObjList
->GetObjCount(); idx
++)
476 vTextBoxes
.push_back(std::pair(pObjList
->GetObj(idx
), pTextBoxNode
->GetTextBox(pObjList
->GetObj(idx
))));
480 pFormat
->RemoveAllUnos();
483 SwDoc
* pDoc
= pFormat
->GetDoc();
484 sw::SpzFrameFormats
& rFlyFormats
= *pDoc
->GetSpzFrameFormats();
485 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), pFormat
));
487 for( sal_uInt16 n
= 1; n
< m_nSize
; ++n
)
489 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[n
];
491 ::lcl_RestoreAnchor( rSave
.pFormat
, rSave
.nNodeIdx
);
492 rFlyFormats
.push_back(static_cast<sw::SpzFrameFormat
*>(rSave
.pFormat
));
494 SwDrawFrameFormat
* pDrawFrameFormat
= rSave
.pFormat
;
496 // Restore the textboxes for the restored group shape.
497 for (auto& pElem
: vTextBoxes
)
499 if (pElem
.first
== rSave
.pObj
)
501 auto pTmpTxBxNd
= std::make_shared
<SwTextBoxNode
>(SwTextBoxNode(rSave
.pFormat
));
502 pTmpTxBxNd
->AddTextBox(rSave
.pObj
, pElem
.second
);
503 pFormat
->SetOtherTextBoxFormats(pTmpTxBxNd
);
504 pElem
.second
->SetOtherTextBoxFormats(pTmpTxBxNd
);
509 // #i45952# - notify that position attributes are already set
510 OSL_ENSURE(pDrawFrameFormat
,
511 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
512 if (pDrawFrameFormat
)
513 pDrawFrameFormat
->PosAttrSet();
517 void SwUndoDrawUnGroup::AddObj( sal_uInt16 nPos
, SwDrawFrameFormat
* pFormat
)
519 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[ nPos
+ 1 ];
520 rSave
.pFormat
= pFormat
;
521 rSave
.pObj
= nullptr;
524 SwUndoDrawUnGroupConnectToLayout::SwUndoDrawUnGroupConnectToLayout(const SwDoc
& rDoc
)
525 : SwUndo( SwUndoId::DRAWUNGROUP
, &rDoc
)
529 SwUndoDrawUnGroupConnectToLayout::~SwUndoDrawUnGroupConnectToLayout()
534 SwUndoDrawUnGroupConnectToLayout::UndoImpl(::sw::UndoRedoContext
&)
536 for (const std::pair
< SwDrawFrameFormat
*, SdrObject
* > & rPair
: m_aDrawFormatsAndObjs
)
538 SdrObject
* pObj( rPair
.second
);
539 SwDrawContact
* pDrawContact( dynamic_cast<SwDrawContact
*>(pObj
->GetUserCall()) );
540 OSL_ENSURE( pDrawContact
,
541 "<SwUndoDrawUnGroupConnectToLayout::Undo(..)> -- missing SwDrawContact instance" );
544 // deletion of instance <pDrawContact> and thus disconnection from
545 // the Writer layout.
546 pDrawContact
->Changed( *pObj
, SdrUserCallType::Delete
, pObj
->GetLastBoundRect() );
547 pObj
->SetUserCall( nullptr );
553 SwUndoDrawUnGroupConnectToLayout::RedoImpl(::sw::UndoRedoContext
&)
555 for (const std::pair
< SwDrawFrameFormat
*, SdrObject
* > & rPair
: m_aDrawFormatsAndObjs
)
557 SwDrawFrameFormat
* pFormat( rPair
.first
);
558 SdrObject
* pObj( rPair
.second
);
559 SwDrawContact
*pContact
= new SwDrawContact( pFormat
, pObj
);
560 pContact
->ConnectToLayout();
561 pContact
->MoveObjToVisibleLayer( pObj
);
565 void SwUndoDrawUnGroupConnectToLayout::AddFormatAndObj( SwDrawFrameFormat
* pDrawFrameFormat
,
566 SdrObject
* pDrawObject
)
568 m_aDrawFormatsAndObjs
.emplace_back( pDrawFrameFormat
, pDrawObject
);
571 SwUndoDrawDelete::SwUndoDrawDelete( sal_uInt16 nCnt
, const SwDoc
& rDoc
)
572 : SwUndo( SwUndoId::DRAWDELETE
, &rDoc
), m_bDeleteFormat( true )
574 m_pObjArray
.reset( new SwUndoGroupObjImpl
[ nCnt
] );
575 m_pMarkList
.reset( new SdrMarkList() );
578 SwUndoDrawDelete::~SwUndoDrawDelete()
580 if( m_bDeleteFormat
)
582 SwUndoGroupObjImpl
* pTmp
= m_pObjArray
.get();
583 for( size_t n
= 0; n
< m_pMarkList
->GetMarkCount(); ++n
, ++pTmp
)
584 delete pTmp
->pFormat
;
588 void SwUndoDrawDelete::UndoImpl(::sw::UndoRedoContext
& rContext
)
590 m_bDeleteFormat
= false;
591 sw::SpzFrameFormats
& rFlyFormats
= *rContext
.GetDoc().GetSpzFrameFormats();
592 for( size_t n
= 0; n
< m_pMarkList
->GetMarkCount(); ++n
)
594 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[n
];
595 ::lcl_RestoreAnchor( rSave
.pFormat
, rSave
.nNodeIdx
);
596 rFlyFormats
.push_back(static_cast<sw::SpzFrameFormat
*>(rSave
.pFormat
));
597 SdrObject
*pObj
= rSave
.pObj
;
598 SwDrawContact
*pContact
= new SwDrawContact( rSave
.pFormat
, pObj
);
599 pContact
->Changed_( *pObj
, SdrUserCallType::Inserted
, nullptr );
600 // #i45718# - follow-up of #i35635# move object to visible layer
601 pContact
->MoveObjToVisibleLayer( pObj
);
603 SwDrawFrameFormat
* pDrawFrameFormat
= rSave
.pFormat
;
604 if (pDrawFrameFormat
->GetOtherTextBoxFormats())
606 SwTextBoxHelper::synchronizeGroupTextBoxProperty(
607 SwTextBoxHelper::changeAnchor
, pDrawFrameFormat
, pObj
);
610 // #i45952# - notify that position attributes are already set
611 OSL_ENSURE(pDrawFrameFormat
,
612 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
613 if (pDrawFrameFormat
)
614 pDrawFrameFormat
->PosAttrSet();
616 rContext
.SetSelections(nullptr, m_pMarkList
.get());
619 void SwUndoDrawDelete::RedoImpl(::sw::UndoRedoContext
& rContext
)
621 m_bDeleteFormat
= true;
622 sw::SpzFrameFormats
& rFlyFormats
= *rContext
.GetDoc().GetSpzFrameFormats();
623 for( size_t n
= 0; n
< m_pMarkList
->GetMarkCount(); ++n
)
625 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[n
];
626 SdrObject
*pObj
= rSave
.pObj
;
627 SwDrawContact
*pContact
= static_cast<SwDrawContact
*>(GetUserCall(pObj
));
628 SwDrawFrameFormat
*pFormat
= static_cast<SwDrawFrameFormat
*>(pContact
->GetFormat());
630 // object will destroy itself
631 pContact
->Changed( *pObj
, SdrUserCallType::Delete
, pObj
->GetLastBoundRect() );
632 pObj
->SetUserCall( nullptr );
634 pFormat
->RemoveAllUnos();
636 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), pFormat
));
637 ::lcl_SaveAnchor( pFormat
, rSave
.nNodeIdx
);
641 void SwUndoDrawDelete::AddObj( SwDrawFrameFormat
* pFormat
,
642 const SdrMark
& rMark
)
644 SwUndoGroupObjImpl
& rSave
= m_pObjArray
[ m_pMarkList
->GetMarkCount() ];
645 rSave
.pObj
= rMark
.GetMarkedSdrObj();
646 rSave
.pFormat
= pFormat
;
647 ::lcl_SaveAnchor( pFormat
, rSave
.nNodeIdx
);
649 pFormat
->RemoveAllUnos();
652 SwDoc
* pDoc
= pFormat
->GetDoc();
653 sw::SpzFrameFormats
& rFlyFormats
= *pDoc
->GetSpzFrameFormats();
654 rFlyFormats
.erase( std::find( rFlyFormats
.begin(), rFlyFormats
.end(), pFormat
));
656 m_pMarkList
->InsertEntry( rMark
);
659 void SwUndoDrawDelete::dumpAsXml(xmlTextWriterPtr pWriter
) const
661 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwUndoDrawDelete"));
663 for (size_t i
= 0; i
< m_pMarkList
->GetMarkCount(); ++i
)
665 SwUndoGroupObjImpl
& rObj
= m_pObjArray
[i
];
666 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwUndoGroupObjImpl"));
667 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("index"),
668 BAD_CAST(OString::number(i
).getStr()));
672 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("pFormat"));
673 rObj
.pFormat
->dumpAsXml(pWriter
);
674 (void)xmlTextWriterEndElement(pWriter
);
676 (void)xmlTextWriterEndElement(pWriter
);
679 (void)xmlTextWriterEndElement(pWriter
);
682 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */