android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / undo / undraw.cxx
blob3fd7fa8ce2449c6405b64121255c809a5ec3bc86
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
33 #include <frmfmt.hxx>
34 #include <doc.hxx>
35 #include <IDocumentUndoRedo.hxx>
36 #include <IDocumentLayoutAccess.hxx>
37 #include <swundo.hxx>
38 #include <pam.hxx>
39 #include <ndtxt.hxx>
40 #include <UndoCore.hxx>
41 #include <dcontact.hxx>
42 #include <viewsh.hxx>
43 #include <frameformats.hxx>
44 #include <textboxhelper.hxx>
46 struct SwUndoGroupObjImpl
48 SwDrawFrameFormat* pFormat;
49 SdrObject* pObj;
50 SwNodeOffset nNodeIdx;
53 // Draw-Objecte
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()
78 m_pSdrUndo.reset();
79 m_pMarkList.reset();
82 void SwSdrUndo::UndoImpl(::sw::UndoRedoContext & rContext)
84 m_pSdrUndo->Undo();
85 rContext.SetSelections(nullptr, m_pMarkList.get());
88 void SwSdrUndo::RedoImpl(::sw::UndoRedoContext & rContext)
90 m_pSdrUndo->Redo();
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())))
106 return;
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())))
144 return;
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;
185 else
186 delete m_pObjArray[0].pFormat;
189 void SwUndoDrawGroup::UndoImpl(::sw::UndoRedoContext &)
191 m_bDeleteFormat = false;
193 // save group object
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();
220 // remove from array
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));
232 pObj = rSave.pObj;
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);
247 break;
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;
265 // remove from array
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];
332 rSave.pObj = pObj;
333 rSave.pFormat = pFormat;
334 ::lcl_SaveAnchor( pFormat, rSave.nNodeIdx );
336 pFormat->RemoveAllUnos();
338 // remove from array
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();
369 // remove from array
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;
382 else
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;
396 // remove from array
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;
460 // save group object
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();
482 // remove from array
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);
505 break;
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()
533 void
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" );
542 if ( pDrawContact )
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 );
552 void
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();
651 // remove from array
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()));
670 if (rObj.pFormat)
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: */