LibreOffice Module sw (master)  1
undraw.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <UndoDraw.hxx>
21 
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>
28 
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>
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>
45 
47 {
51 };
52 
53 // Draw-Objecte
54 
55 void SwDoc::AddDrawUndo( std::unique_ptr<SdrUndoAction> pUndo )
56 {
57  if (GetIDocumentUndoRedo().DoesUndo() &&
58  GetIDocumentUndoRedo().DoesDrawUndo())
59  {
60  const SdrMarkList* pMarkList = nullptr;
62  if( pSh && pSh->HasDrawView() )
63  pMarkList = &pSh->GetDrawView()->GetMarkedObjectList();
64 
65  GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwSdrUndo>(std::move(pUndo), pMarkList, *this) );
66  }
67 }
68 
69 SwSdrUndo::SwSdrUndo( std::unique_ptr<SdrUndoAction> pUndo, const SdrMarkList* pMrkLst, const SwDoc& rDoc )
70  : SwUndo( SwUndoId::DRAWUNDO, &rDoc ), m_pSdrUndo( std::move(pUndo) )
71 {
72  if( pMrkLst && pMrkLst->GetMarkCount() )
73  m_pMarkList.reset( new SdrMarkList( *pMrkLst ) );
74 }
75 
77 {
78  m_pSdrUndo.reset();
79  m_pMarkList.reset();
80 }
81 
83 {
84  m_pSdrUndo->Undo();
85  rContext.SetSelections(nullptr, m_pMarkList.get());
86 }
87 
89 {
90  m_pSdrUndo->Redo();
91  rContext.SetSelections(nullptr, m_pMarkList.get());
92 }
93 
94 OUString SwSdrUndo::GetComment() const
95 {
96  return m_pSdrUndo->GetComment();
97 }
98 
99 static void lcl_SaveAnchor( SwFrameFormat* pFormat, sal_uLong& rNodePos )
100 {
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;
107 
108  rNodePos = rAnchor.GetContentAnchor()->nNode.GetIndex();
109  sal_Int32 nContentPos = 0;
110 
111  if (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId())
112  {
113  nContentPos = rAnchor.GetContentAnchor()->nContent.GetIndex();
114 
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 )
122  {
123  // just set pointer to 0, don't delete
124  const_cast<SwFormatFlyCnt&>(pAttr->GetFlyCnt()).SetFlyFormat();
125  SwIndex aIdx( pTextNd, nContentPos );
126  pTextNd->EraseText( aIdx, 1 );
127  }
128  }
129  else if (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId())
130  {
131  nContentPos = rAnchor.GetContentAnchor()->nContent.GetIndex();
132  }
133 
134  pFormat->SetFormatAttr( SwFormatAnchor( rAnchor.GetAnchorId(), nContentPos ) );
135 }
136 
137 static void lcl_RestoreAnchor( SwFrameFormat* pFormat, sal_uLong nNodePos )
138 {
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;
145 
146  const sal_Int32 nContentPos = rAnchor.GetPageNum();
147  SwNodes& rNds = pFormat->GetDoc()->GetNodes();
148 
149  SwNodeIndex aIdx( rNds, nNodePos );
150  SwPosition aPos( aIdx );
151 
152  SwFormatAnchor aTmp( rAnchor.GetAnchorId() );
153  if ((RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) ||
154  (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()))
155  {
156  aPos.nContent.Assign( aIdx.GetNode().GetContentNode(), nContentPos );
157  }
158  aTmp.SetAnchor( &aPos );
159  RndStdIds nAnchorId = rAnchor.GetAnchorId();
160  pFormat->SetFormatAttr( aTmp );
161 
162  if (RndStdIds::FLY_AS_CHAR == nAnchorId)
163  {
164  SwTextNode *pTextNd = aIdx.GetNode().GetTextNode();
165  OSL_ENSURE( pTextNd, "no Text Node" );
166  SwFormatFlyCnt aFormat( pFormat );
167  pTextNd->InsertItem( aFormat, nContentPos, nContentPos );
168  }
169 }
170 
171 SwUndoDrawGroup::SwUndoDrawGroup( sal_uInt16 nCnt, const SwDoc& rDoc )
172  : SwUndo( SwUndoId::DRAWGROUP, &rDoc ), m_nSize( nCnt + 1 ), m_bDeleteFormat( true )
173 {
174  m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] );
175 }
176 
178 {
179  if( m_bDeleteFormat )
180  {
181  SwUndoGroupObjImpl* pTmp = m_pObjArray.get() + 1;
182  for( sal_uInt16 n = 1; n < m_nSize; ++n, ++pTmp )
183  delete pTmp->pFormat;
184  }
185  else
186  delete m_pObjArray[0].pFormat;
187 }
188 
190 {
191  m_bDeleteFormat = false;
192 
193  // save group object
194  SwDrawFrameFormat* pFormat = m_pObjArray[0].pFormat;
195 
197  auto pObj = m_pObjArray[0].pObj;
198  pObj->SetUserCall(nullptr);
199 
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->GetOtherTextBoxFormat())
203  {
204  if (auto pChildren = pObj->getChildrenOfSdrObject())
205  {
206  for (size_t idx = 0; idx < pChildren->GetObjCount(); idx++)
207  {
208  auto pChild = pChildren->GetObj(idx);
209 
210  if (auto pTextBox = pOldTextBoxNode->GetTextBox(pChild))
211  vTextBoxes.push_back(std::pair(pChild, pTextBox));
212  }
213  }
214  }
215 
216  ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
217 
218  pFormat->RemoveAllUnos();
219 
220  // remove from array
221  SwDoc* pDoc = pFormat->GetDoc();
222  SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
223  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
224 
225  for( sal_uInt16 n = 1; n < m_nSize; ++n )
226  {
227  SwUndoGroupObjImpl& rSave = m_pObjArray[n];
228 
229  ::lcl_RestoreAnchor( rSave.pFormat, rSave.nNodeIdx );
230  rFlyFormats.push_back( rSave.pFormat );
231 
232  pObj = rSave.pObj;
233 
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 );
238 
239  for (auto& rElem : vTextBoxes)
240  {
241  if (rElem.first == pObj)
242  {
243  auto pNewTextBoxNode = new SwTextBoxNode(rSave.pFormat);
244  rSave.pFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
245  pNewTextBoxNode->AddTextBox(rElem.first, rElem.second);
246  rElem.second->SetOtherTextBoxFormat(pNewTextBoxNode);
247  break;
248  }
249  }
250 
251  SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
252 
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();
258  }
259 }
260 
262 {
263  m_bDeleteFormat = true;
264 
265  // remove from array
266  SwDoc* pDoc = m_pObjArray[0].pFormat->GetDoc();
267  SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
268 
269  // This will store the textboxes from the ex-group-shapes
270  std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
271 
272  for( sal_uInt16 n = 1; n < m_nSize; ++n )
273  {
274  SwUndoGroupObjImpl& rSave = m_pObjArray[n];
275 
276  SdrObject* pObj = rSave.pObj;
277 
278  SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
279 
280  // Save the textboxes
281  if (auto pOldTextBoxNode = rSave.pFormat->GetOtherTextBoxFormat())
282  {
283  if (auto pTextBox = pOldTextBoxNode->GetTextBox(pObj))
284  vTextBoxes.push_back(std::pair(pObj, pTextBox));
285  }
286 
287  // object will destroy itself
288  pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
289  pObj->SetUserCall( nullptr );
290 
291  ::lcl_SaveAnchor( rSave.pFormat, rSave.nNodeIdx );
292 
293  rSave.pFormat->RemoveAllUnos();
294 
295  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), rSave.pFormat ));
296  }
297 
298  // re-insert group object
299  ::lcl_RestoreAnchor( m_pObjArray[0].pFormat, m_pObjArray[0].nNodeIdx );
300  rFlyFormats.push_back( m_pObjArray[0].pFormat );
301 
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 );
307 
308  SwDrawFrameFormat* pDrawFrameFormat = m_pObjArray[0].pFormat;
309 
310  // Restore the textboxes
311  if (vTextBoxes.size())
312  {
313  auto pNewTextBoxNode = new SwTextBoxNode(m_pObjArray[0].pFormat);
314  for (auto& rElem : vTextBoxes)
315  {
316  pNewTextBoxNode->AddTextBox(rElem.first, rElem.second);
317  rElem.second->SetOtherTextBoxFormat(pNewTextBoxNode);
318  }
319  m_pObjArray[0].pFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
320  }
321 
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();
327 }
328 
329 void SwUndoDrawGroup::AddObj( sal_uInt16 nPos, SwDrawFrameFormat* pFormat, SdrObject* pObj )
330 {
331  SwUndoGroupObjImpl& rSave = m_pObjArray[nPos + 1];
332  rSave.pObj = pObj;
333  rSave.pFormat = pFormat;
334  ::lcl_SaveAnchor( pFormat, rSave.nNodeIdx );
335 
336  pFormat->RemoveAllUnos();
337 
338  // remove from array
339  SwFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats();
340  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
341 }
342 
344 {
345  m_pObjArray[0].pObj = nullptr;
346  m_pObjArray[0].pFormat = pFormat;
347 }
348 
350  : SwUndo( SwUndoId::DRAWUNGROUP, &rDoc ), m_bDeleteFormat( false )
351 {
352  m_nSize = o3tl::narrowing<sal_uInt16>(pObj->GetSubList()->GetObjCount()) + 1;
353  m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] );
354 
355  SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
356  SwDrawFrameFormat* pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
357 
358  m_pObjArray[0].pObj = pObj;
359  m_pObjArray[0].pFormat = pFormat;
360 
361  // object will destroy itself
362  pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
363  pObj->SetUserCall( nullptr );
364 
365  ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
366 
367  pFormat->RemoveAllUnos();
368 
369  // remove from array
370  SwFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats();
371  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
372 }
373 
375 {
376  if( m_bDeleteFormat )
377  {
378  SwUndoGroupObjImpl* pTmp = m_pObjArray.get() + 1;
379  for( sal_uInt16 n = 1; n < m_nSize; ++n, ++pTmp )
380  delete pTmp->pFormat;
381  }
382  else
383  delete m_pObjArray[0].pFormat;
384 }
385 
387 {
388  m_bDeleteFormat = true;
389 
390  SwDoc *const pDoc = & rContext.GetDoc();
391  SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
392 
393  // This will store the textboxes what were owned by this group
394  std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
395 
396  // remove from array
397  for( sal_uInt16 n = 1; n < m_nSize; ++n )
398  {
399  SwUndoGroupObjImpl& rSave = m_pObjArray[n];
400 
401  ::lcl_SaveAnchor( rSave.pFormat, rSave.nNodeIdx );
402 
403  // copy the textboxes for later use to this vector
404  if (auto pTxBxNd = rSave.pFormat->GetOtherTextBoxFormat())
405  {
406  if (auto pGroupObj = m_pObjArray[0].pObj)
407  {
408  if (auto pChildren = pGroupObj->getChildrenOfSdrObject())
409  {
410  for (size_t idx = 0; idx < pChildren->GetObjCount(); idx++)
411  {
412  auto pChild = pChildren->GetObj(idx);
413  if (auto pTextBox = pTxBxNd->GetTextBox(pChild))
414  vTextBoxes.push_back(std::pair(pChild, pTextBox));
415  }
416  }
417  }
418  }
419 
420  rSave.pFormat->RemoveAllUnos();
421 
422  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), rSave.pFormat ));
423  }
424 
425  // re-insert group object
426  ::lcl_RestoreAnchor( m_pObjArray[0].pFormat, m_pObjArray[0].nNodeIdx );
427  rFlyFormats.push_back( m_pObjArray[0].pFormat );
428 
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 );
433 
434  SwDrawFrameFormat* pDrawFrameFormat = m_pObjArray[0].pFormat;
435 
436  // Restore the vector content for the new formats
437  if (vTextBoxes.size())
438  {
439  auto pNewTxBxNd = new SwTextBoxNode(m_pObjArray[0].pFormat);
440  for (auto& rElem : vTextBoxes)
441  {
442  pNewTxBxNd->AddTextBox(rElem.first, rElem.second);
443  rElem.second->SetOtherTextBoxFormat(pNewTxBxNd);
444  }
445  m_pObjArray[0].pFormat->SetOtherTextBoxFormat(pNewTxBxNd);
446  }
447 
448 
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();
454 }
455 
457 {
458  m_bDeleteFormat = false;
459 
460  // save group object
461  SwDrawFrameFormat* pFormat = m_pObjArray[0].pFormat;
463  m_pObjArray[0].pObj->SetUserCall( nullptr );
464 
465  ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
466 
467  // Store the textboxes in this vector for later use.
468  std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
469  if (auto pTextBoxNode = pFormat->GetOtherTextBoxFormat())
470  {
471  auto pMasterObj = m_pObjArray[0].pObj;
472 
473  if (auto pObjList = pMasterObj->getChildrenOfSdrObject())
474  for (size_t idx = 0; idx < pObjList->GetObjCount(); idx++)
475  {
476  vTextBoxes.push_back(std::pair(pObjList->GetObj(idx), pTextBoxNode->GetTextBox(pObjList->GetObj(idx))));
477  }
478  }
479 
480  pFormat->RemoveAllUnos();
481 
482  // remove from array
483  SwDoc* pDoc = pFormat->GetDoc();
484  SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
485  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
486 
487  for( sal_uInt16 n = 1; n < m_nSize; ++n )
488  {
489  SwUndoGroupObjImpl& rSave = m_pObjArray[n];
490 
491  ::lcl_RestoreAnchor( rSave.pFormat, rSave.nNodeIdx );
492  rFlyFormats.push_back( rSave.pFormat );
493 
494  SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
495 
496  // Restore the textboxes for the restored group shape.
497  for (auto& pElem : vTextBoxes)
498  {
499  if (pElem.first == rSave.pObj)
500  {
501  auto pTmpTxBxNd = new SwTextBoxNode(rSave.pFormat);
502  pTmpTxBxNd->AddTextBox(rSave.pObj, pElem.second);
503  pFormat->SetOtherTextBoxFormat(pTmpTxBxNd);
504  pElem.second->SetOtherTextBoxFormat(pTmpTxBxNd);
505  break;
506  }
507  }
508 
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();
514  }
515 }
516 
517 void SwUndoDrawUnGroup::AddObj( sal_uInt16 nPos, SwDrawFrameFormat* pFormat )
518 {
519  SwUndoGroupObjImpl& rSave = m_pObjArray[ nPos + 1 ];
520  rSave.pFormat = pFormat;
521  rSave.pObj = nullptr;
522 }
523 
525  : SwUndo( SwUndoId::DRAWUNGROUP, &rDoc )
526 {
527 }
528 
530 {
531 }
532 
533 void
535 {
536  for (const std::pair< SwDrawFrameFormat*, SdrObject* > & rPair : m_aDrawFormatsAndObjs)
537  {
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 )
543  {
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 );
548  }
549  }
550 }
551 
552 void
554 {
555  for (const std::pair< SwDrawFrameFormat*, SdrObject* > & rPair : m_aDrawFormatsAndObjs)
556  {
557  SwDrawFrameFormat* pFormat( rPair.first );
558  SdrObject* pObj( rPair.second );
559  SwDrawContact *pContact = new SwDrawContact( pFormat, pObj );
560  pContact->ConnectToLayout();
561  pContact->MoveObjToVisibleLayer( pObj );
562  }
563 }
564 
566  SdrObject* pDrawObject )
567 {
568  m_aDrawFormatsAndObjs.emplace_back( pDrawFrameFormat, pDrawObject );
569 }
570 
571 SwUndoDrawDelete::SwUndoDrawDelete( sal_uInt16 nCnt, const SwDoc& rDoc )
572  : SwUndo( SwUndoId::DRAWDELETE, &rDoc ), m_bDeleteFormat( true )
573 {
574  m_pObjArray.reset( new SwUndoGroupObjImpl[ nCnt ] );
575  m_pMarkList.reset( new SdrMarkList() );
576 }
577 
579 {
580  if( m_bDeleteFormat )
581  {
582  SwUndoGroupObjImpl* pTmp = m_pObjArray.get();
583  for( size_t n = 0; n < m_pMarkList->GetMarkCount(); ++n, ++pTmp )
584  delete pTmp->pFormat;
585  }
586 }
587 
589 {
590  m_bDeleteFormat = false;
591  SwFrameFormats & rFlyFormats = *rContext.GetDoc().GetSpzFrameFormats();
592  for( size_t n = 0; n < m_pMarkList->GetMarkCount(); ++n )
593  {
594  SwUndoGroupObjImpl& rSave = m_pObjArray[n];
595  ::lcl_RestoreAnchor( rSave.pFormat, rSave.nNodeIdx );
596  rFlyFormats.push_back( 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 );
602 
603  SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
604 
605  // #i45952# - notify that position attributes are already set
606  OSL_ENSURE(pDrawFrameFormat,
607  "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
608  if (pDrawFrameFormat)
609  pDrawFrameFormat->PosAttrSet();
610  }
611  rContext.SetSelections(nullptr, m_pMarkList.get());
612 }
613 
615 {
616  m_bDeleteFormat = true;
617  SwFrameFormats & rFlyFormats = *rContext.GetDoc().GetSpzFrameFormats();
618  for( size_t n = 0; n < m_pMarkList->GetMarkCount(); ++n )
619  {
620  SwUndoGroupObjImpl& rSave = m_pObjArray[n];
621  SdrObject *pObj = rSave.pObj;
622  SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
623  SwDrawFrameFormat *pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
624 
625  // object will destroy itself
626  pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
627  pObj->SetUserCall( nullptr );
628 
629  pFormat->RemoveAllUnos();
630 
631  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
632  ::lcl_SaveAnchor( pFormat, rSave.nNodeIdx );
633  }
634 }
635 
637  const SdrMark& rMark )
638 {
639  SwUndoGroupObjImpl& rSave = m_pObjArray[ m_pMarkList->GetMarkCount() ];
640  rSave.pObj = rMark.GetMarkedSdrObj();
641  rSave.pFormat = pFormat;
642  ::lcl_SaveAnchor( pFormat, rSave.nNodeIdx );
643 
644  pFormat->RemoveAllUnos();
645 
646  // remove from array
647  SwDoc* pDoc = pFormat->GetDoc();
648  SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
649  rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
650 
651  m_pMarkList->InsertEntry( rMark );
652 }
653 
655 {
656  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUndoDrawDelete"));
657 
658  for (size_t i = 0; i < m_pMarkList->GetMarkCount(); ++i)
659  {
661  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUndoGroupObjImpl"));
662  (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("index"),
663  BAD_CAST(OString::number(i).getStr()));
664 
665  if (rObj.pFormat)
666  {
667  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("pFormat"));
668  rObj.pFormat->dumpAsXml(pWriter);
669  (void)xmlTextWriterEndElement(pWriter);
670  }
671  (void)xmlTextWriterEndElement(pWriter);
672  }
673 
674  (void)xmlTextWriterEndElement(pWriter);
675 }
676 
677 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool erase(const value_type &x)
Definition: docfmt.cxx:2130
std::unique_ptr< SdrMarkList > m_pMarkList
Definition: UndoDraw.hxx:39
virtual ~SwUndoDrawUnGroupConnectToLayout() override
Definition: undraw.cxx:529
void SetSelections(SwFrameFormat *const pSelFormat, SdrMarkList *const pMarkList)
Definition: UndoCore.hxx:99
size_t GetMarkCount() const
Marks a position in the document model.
Definition: pam.hxx:35
std::unique_ptr< SdrMarkList > m_pMarkList
Definition: UndoDraw.hxx:117
SdrView * GetDrawView()
Definition: vnew.cxx:373
std::pair< const_iterator, bool > push_back(const value_type &x)
Definition: docfmt.cxx:2122
SwUndoId
Definition: swundo.hxx:29
SwNodeIndex nNode
Definition: pam.hxx:37
const_iterator begin() const
sal_uInt16 GetPageNum() const
Definition: fmtanchr.hxx:66
sal_uIntPtr sal_uLong
void AddObj(sal_uInt16 nPos, SwDrawFrameFormat *, SdrObject *)
Definition: undraw.cxx:329
sal_Int64 n
Definition: doc.hxx:188
size_t GetObjCount() const
Textboxes are basically textframe + shape pairs.
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(57)
void PosAttrSet()
Definition: frmfmt.hxx:401
void AddFormatAndObj(SwDrawFrameFormat *pDrawFrameFormat, SdrObject *pDrawObject)
Definition: undraw.cxx:565
bool HasDrawView() const
Definition: vnew.cxx:358
SwNode & GetNode() const
Definition: ndindex.hxx:119
void SetOtherTextBoxFormat(SwTextBoxNode *pNew)
Definition: frmfmt.hxx:106
void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: undraw.cxx:654
sal_uLong nNodeIdx
Definition: undraw.cxx:50
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
const_iterator end() const
static void lcl_SaveAnchor(SwFrameFormat *pFormat, sal_uLong &rNodePos)
Definition: undraw.cxx:99
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:171
bool m_bDeleteFormat
Definition: UndoDraw.hxx:56
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:744
std::unique_ptr< SwUndoGroupObjImpl[]> m_pObjArray
Definition: UndoDraw.hxx:83
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
Definition: ndtxt.cxx:3012
void SetGroupFormat(SwDrawFrameFormat *)
Definition: undraw.cxx:343
virtual void UndoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:588
sal_uInt16 m_nSize
Definition: UndoDraw.hxx:84
SwIndex nContent
Definition: pam.hxx:38
virtual void RedoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:88
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
SwTextAttr * InsertItem(SfxPoolItem &rAttr, const sal_Int32 nStart, const sal_Int32 nEnd, const SetAttrMode nMode=SetAttrMode::DEFAULT)
create new text attribute from rAttr and insert it
Definition: thints.cxx:1270
virtual void UndoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:534
SwUndoDrawGroup(sal_uInt16 nCnt, const SwDoc &rDoc)
Definition: undraw.cxx:171
SwDoc & GetDoc() const
Definition: UndoCore.hxx:95
virtual void MoveObjToVisibleLayer(SdrObject *_pDrawObj)
method to move drawing object to corresponding visible layer
Definition: dcontact.cxx:209
virtual void UndoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:189
Specific frame formats (frames, DrawObjects).
SdrObject * GetMarkedSdrObj() const
struct _xmlTextWriter * xmlTextWriterPtr
virtual void AppendUndo(std::unique_ptr< SwUndo > pUndo)=0
Add new Undo action.
virtual void RedoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:553
Style of a layout element.
Definition: frmfmt.hxx:59
std::vector< std::pair< SwDrawFrameFormat *, SdrObject * > > m_aDrawFormatsAndObjs
Definition: UndoDraw.hxx:101
void AddObj(SwDrawFrameFormat *, const SdrMark &)
Definition: undraw.cxx:636
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
SwFrameFormat * GetFormat()
Definition: dcontact.hxx:112
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
virtual void RedoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:614
SwContentNode * GetContentNode()
Definition: node.hxx:616
const SdrMarkList & GetMarkedObjectList() const
FlyAnchors.
Definition: fmtanchr.hxx:34
static void lcl_RestoreAnchor(SwFrameFormat *pFormat, sal_uLong nNodePos)
Definition: undraw.cxx:137
Marks a character position inside a document model node.
Definition: index.hxx:33
virtual ~SwUndoDrawUnGroup() override
Definition: undraw.cxx:374
std::unique_ptr< SwUndoGroupObjImpl[]> m_pObjArray
Definition: UndoDraw.hxx:54
void AddDrawUndo(std::unique_ptr< SdrUndoAction >)
Definition: undraw.cxx:55
Marks a node in the document model.
Definition: ndindex.hxx:31
virtual SdrObjList * GetSubList() const override
void SetUserCall(SdrObjUserCall *pUser)
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:123
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: atrfrm.cxx:2866
virtual ~SwUndoDrawDelete() override
Definition: undraw.cxx:578
void Changed_(const SdrObject &rObj, SdrUserCallType eType, const tools::Rectangle *pOldBoundRect)
Used by Changed() and by UndoDraw.
Definition: dcontact.cxx:1100
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
const sal_uInt16 idx[]
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:450
virtual void RedoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:261
void EraseText(const SwIndex &rIdx, const sal_Int32 nCount=SAL_MAX_INT32, const SwInsertFlags nMode=SwInsertFlags::DEFAULT)
delete text content ATTENTION: must not be called with a range that overlaps the start of an attribut...
Definition: ndtxt.cxx:2632
virtual const tools::Rectangle & GetLastBoundRect() const
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual ~SwUndoDrawGroup() override
Definition: undraw.cxx:177
void AddObj(sal_uInt16 nPos, SwDrawFrameFormat *)
Definition: undraw.cxx:517
SwUndoDrawUnGroupConnectToLayout(const SwDoc &rDoc)
Definition: undraw.cxx:524
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
virtual OUString GetComment() const override
Returns textual comment for this undo object.
Definition: undraw.cxx:94
sal_Int32 GetIndex() const
Definition: index.hxx:91
void ConnectToLayout(const SwFormatAnchor *pAnch=nullptr)
Inserts SdrObject in the arrays of the layout ((SwPageFrame and SwFrame).
Definition: dcontact.cxx:1781
virtual void Changed(const SdrObject &rObj, SdrUserCallType eType, const tools::Rectangle &rOldBoundRect) override
Virtual methods of SdrObjUserCall.
Definition: dcontact.cxx:965
SwNodes & GetNodes()
Definition: doc.hxx:409
SwDrawFrameFormat * pFormat
Definition: undraw.cxx:48
std::unique_ptr< SwUndoGroupObjImpl[]> m_pObjArray
Definition: UndoDraw.hxx:116
virtual void UndoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:82
virtual void UndoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:386
virtual ~SwSdrUndo() override
Definition: undraw.cxx:76
Format of a fly content.
Definition: fmtflcnt.hxx:32
virtual void CallSwClientNotify(const SfxHint &rHint) const override
Definition: calbck.cxx:326
void RemoveAllUnos()
Definition: format.cxx:763
SdrObject * pObj
Definition: undraw.cxx:49
SwFrameFormat * GetFrameFormat() const
Definition: fmtflcnt.hxx:45
RndStdIds
sal_uInt16 m_nSize
Definition: UndoDraw.hxx:55
std::unique_ptr< SdrUndoAction > m_pSdrUndo
Definition: UndoDraw.hxx:38
SwUndoDrawDelete(sal_uInt16 nCnt, const SwDoc &rDoc)
Definition: undraw.cxx:571
SdrObjUserCall * GetUserCall() const
SwUndoDrawUnGroup(SdrObjGroup *, const SwDoc &rDoc)
Definition: undraw.cxx:349
SwTextBoxNode * GetOtherTextBoxFormat() const
Definition: frmfmt.hxx:105
virtual void RedoImpl(::sw::UndoRedoContext &) override
Definition: undraw.cxx:456
SwSdrUndo(std::unique_ptr< SdrUndoAction >, const SdrMarkList *pMarkList, const SwDoc &rDoc)
Definition: undraw.cxx:69
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:856
sal_uInt32 m_nSize
const SwFormatFlyCnt & GetFlyCnt() const
Definition: txatbase.hxx:210
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo