xref: /AOO41X/main/sw/source/core/undo/undraw.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <UndoDraw.hxx>
28 
29 #include <rtl/string.h>
30 #include <rtl/memory.h>
31 
32 #include <rtl/string.h>
33 #include <svx/svdogrp.hxx>
34 #include <svx/svdundo.hxx>
35 #include <svx/svdpage.hxx>
36 #include <svx/svdmark.hxx>
37 
38 #include <hintids.hxx>
39 #include <hints.hxx>
40 #include <fmtanchr.hxx>
41 #include <fmtflcnt.hxx>
42 #include <txtflcnt.hxx>
43 #include <frmfmt.hxx>
44 #include <doc.hxx>
45 #include <IDocumentUndoRedo.hxx>
46 #include <docary.hxx>
47 #include <frame.hxx>
48 #include <swundo.hxx>           // fuer die UndoIds
49 #include <pam.hxx>
50 #include <ndtxt.hxx>
51 #include <UndoCore.hxx>
52 #include <dcontact.hxx>
53 #include <dview.hxx>
54 #include <rootfrm.hxx>
55 #include <viewsh.hxx>
56 
57 
58 struct SwUndoGroupObjImpl
59 {
60     SwDrawFrmFmt* pFmt;
61     SdrObject* pObj;
62     sal_uLong nNodeIdx;
63 };
64 
65 
66 // Draw-Objecte
67 
IMPL_LINK(SwDoc,AddDrawUndo,SdrUndoAction *,pUndo)68 IMPL_LINK( SwDoc, AddDrawUndo, SdrUndoAction *, pUndo )
69 {
70 #if OSL_DEBUG_LEVEL > 1
71     sal_uInt16 nId = pUndo->GetId();
72     (void)nId;
73     String sComment( pUndo->GetComment() );
74 #endif
75 
76     if (GetIDocumentUndoRedo().DoesUndo() &&
77         GetIDocumentUndoRedo().DoesDrawUndo())
78     {
79         const SdrMarkList* pMarkList = 0;
80         ViewShell* pSh = GetCurrentViewShell();
81         if( pSh && pSh->HasDrawView() )
82             pMarkList = &pSh->GetDrawView()->GetMarkedObjectList();
83 
84         GetIDocumentUndoRedo().AppendUndo( new SwSdrUndo(pUndo, pMarkList) );
85     }
86     else
87         delete pUndo;
88     return 0;
89 }
90 
SwSdrUndo(SdrUndoAction * pUndo,const SdrMarkList * pMrkLst)91 SwSdrUndo::SwSdrUndo( SdrUndoAction* pUndo, const SdrMarkList* pMrkLst )
92     : SwUndo( UNDO_DRAWUNDO ), pSdrUndo( pUndo )
93 {
94     if( pMrkLst && pMrkLst->GetMarkCount() )
95         pMarkList = new SdrMarkList( *pMrkLst );
96     else
97         pMarkList = 0;
98 }
99 
~SwSdrUndo()100 SwSdrUndo::~SwSdrUndo()
101 {
102     delete pSdrUndo;
103     delete pMarkList;
104 }
105 
UndoImpl(::sw::UndoRedoContext & rContext)106 void SwSdrUndo::UndoImpl(::sw::UndoRedoContext & rContext)
107 {
108     pSdrUndo->Undo();
109     rContext.SetSelections(0, pMarkList);
110 }
111 
RedoImpl(::sw::UndoRedoContext & rContext)112 void SwSdrUndo::RedoImpl(::sw::UndoRedoContext & rContext)
113 {
114     pSdrUndo->Redo();
115     rContext.SetSelections(0, pMarkList);
116 }
117 
GetComment() const118 String SwSdrUndo::GetComment() const
119 {
120     return pSdrUndo->GetComment();
121 }
122 
123 //--------------------------------------------
124 
lcl_SendRemoveToUno(SwFmt & rFmt)125 void lcl_SendRemoveToUno( SwFmt& rFmt )
126 {
127     SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, &rFmt );
128     rFmt.ModifyNotification( &aMsgHint, &aMsgHint );
129 }
130 
lcl_SaveAnchor(SwFrmFmt * pFmt,sal_uLong & rNodePos)131 void lcl_SaveAnchor( SwFrmFmt* pFmt, sal_uLong& rNodePos )
132 {
133     const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
134     if ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
135         (FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
136         (FLY_AT_FLY  == rAnchor.GetAnchorId()) ||
137         (FLY_AS_CHAR == rAnchor.GetAnchorId()))
138     {
139         rNodePos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
140         xub_StrLen nCntntPos = 0;
141 
142         if (FLY_AS_CHAR == rAnchor.GetAnchorId())
143         {
144             nCntntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex();
145 
146             // destroy TextAttribute
147             SwTxtNode *pTxtNd = pFmt->GetDoc()->GetNodes()[ rNodePos ]->GetTxtNode();
148             ASSERT( pTxtNd, "No text node found!" );
149             SwTxtFlyCnt* pAttr = static_cast<SwTxtFlyCnt*>(
150                 pTxtNd->GetTxtAttrForCharAt( nCntntPos, RES_TXTATR_FLYCNT ));
151             // attribute still in text node, delete
152             if( pAttr && pAttr->GetFlyCnt().GetFrmFmt() == pFmt )
153             {
154                 // just set pointer to 0, don't delete
155                 ((SwFmtFlyCnt&)pAttr->GetFlyCnt()).SetFlyFmt();
156                 SwIndex aIdx( pTxtNd, nCntntPos );
157                 pTxtNd->EraseText( aIdx, 1 );
158             }
159         }
160         else if (FLY_AT_CHAR == rAnchor.GetAnchorId())
161         {
162             nCntntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex();
163         }
164 
165         pFmt->SetFmtAttr( SwFmtAnchor( rAnchor.GetAnchorId(), nCntntPos ) );
166     }
167 }
168 
lcl_RestoreAnchor(SwFrmFmt * pFmt,sal_uLong & rNodePos)169 void lcl_RestoreAnchor( SwFrmFmt* pFmt, sal_uLong& rNodePos )
170 {
171     const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
172     if ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
173         (FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
174         (FLY_AT_FLY  == rAnchor.GetAnchorId()) ||
175         (FLY_AS_CHAR == rAnchor.GetAnchorId()))
176     {
177         xub_StrLen nCntntPos = rAnchor.GetPageNum();
178         SwNodes& rNds = pFmt->GetDoc()->GetNodes();
179 
180         SwNodeIndex aIdx( rNds, rNodePos );
181         SwPosition aPos( aIdx );
182 
183         SwFmtAnchor aTmp( rAnchor.GetAnchorId() );
184         if ((FLY_AS_CHAR == rAnchor.GetAnchorId()) ||
185             (FLY_AT_CHAR == rAnchor.GetAnchorId()))
186         {
187             aPos.nContent.Assign( aIdx.GetNode().GetCntntNode(), nCntntPos );
188         }
189         aTmp.SetAnchor( &aPos );
190         pFmt->SetFmtAttr( aTmp );
191 
192         if (FLY_AS_CHAR == rAnchor.GetAnchorId())
193         {
194             SwTxtNode *pTxtNd = aIdx.GetNode().GetTxtNode();
195             ASSERT( pTxtNd, "no Text Node" );
196             SwFmtFlyCnt aFmt( pFmt );
197             pTxtNd->InsertItem( aFmt, nCntntPos, nCntntPos );
198         }
199     }
200 }
201 
SwUndoDrawGroup(sal_uInt16 nCnt)202 SwUndoDrawGroup::SwUndoDrawGroup( sal_uInt16 nCnt )
203     : SwUndo( UNDO_DRAWGROUP ), nSize( nCnt + 1 ), bDelFmt( sal_True )
204 {
205     pObjArr = new SwUndoGroupObjImpl[ nSize ];
206 }
207 
~SwUndoDrawGroup()208 SwUndoDrawGroup::~SwUndoDrawGroup()
209 {
210     if( bDelFmt )
211     {
212         SwUndoGroupObjImpl* pTmp = pObjArr + 1;
213         for( sal_uInt16 n = 1; n < nSize; ++n, ++pTmp )
214             delete pTmp->pFmt;
215     }
216     else
217         delete pObjArr->pFmt;
218 
219     delete [] pObjArr;
220 }
221 
UndoImpl(::sw::UndoRedoContext &)222 void SwUndoDrawGroup::UndoImpl(::sw::UndoRedoContext &)
223 {
224     bDelFmt = sal_False;
225 
226     // save group object
227     SwDrawFrmFmt* pFmt = pObjArr->pFmt;
228     SwDrawContact* pDrawContact = (SwDrawContact*)pFmt->FindContactObj();
229     SdrObject* pObj = pDrawContact->GetMaster();
230     pObjArr->pObj = pObj;
231 
232     // object will destroy itself
233     pDrawContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
234     pObj->SetUserCall( 0 );
235 
236     ::lcl_SaveAnchor( pFmt, pObjArr->nNodeIdx );
237 
238     // notify UNO objects to decouple
239     ::lcl_SendRemoveToUno( *pFmt );
240 
241     // remove from array
242     SwDoc* pDoc = pFmt->GetDoc();
243     SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
244     rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
245 
246     for( sal_uInt16 n = 1; n < nSize; ++n )
247     {
248         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
249 
250         ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
251         rFlyFmts.Insert( rSave.pFmt, rFlyFmts.Count() );
252 
253         pObj = rSave.pObj;
254 
255         SwDrawContact *pContact = new SwDrawContact( rSave.pFmt, pObj );
256         pContact->ConnectToLayout();
257         // #i45718# - follow-up of #i35635# move object to visible layer
258         pContact->MoveObjToVisibleLayer( pObj );
259         // #i45952# - notify that position attributes are already set
260         ASSERT( rSave.pFmt->ISA(SwDrawFrmFmt),
261                 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
262         if ( rSave.pFmt->ISA(SwDrawFrmFmt) )
263         {
264             static_cast<SwDrawFrmFmt*>(rSave.pFmt)->PosAttrSet();
265         }
266     }
267 }
268 
RedoImpl(::sw::UndoRedoContext &)269 void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
270 {
271     bDelFmt = sal_True;
272 
273     // remove from array
274     SwDoc* pDoc = pObjArr->pFmt->GetDoc();
275     SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
276     SdrObject* pObj;
277 
278     for( sal_uInt16 n = 1; n < nSize; ++n )
279     {
280         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
281 
282         pObj = rSave.pObj;
283 
284         SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
285 
286         // object will destroy itself
287         pContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
288         pObj->SetUserCall( 0 );
289 
290         ::lcl_SaveAnchor( rSave.pFmt, rSave.nNodeIdx );
291 
292         // notify UNO objects to decouple
293         ::lcl_SendRemoveToUno( *rSave.pFmt );
294 
295         rFlyFmts.Remove( rFlyFmts.GetPos( rSave.pFmt ));
296     }
297 
298     // re-insert group object
299     ::lcl_RestoreAnchor( pObjArr->pFmt, pObjArr->nNodeIdx );
300     rFlyFmts.Insert( pObjArr->pFmt, rFlyFmts.Count() );
301 
302     SwDrawContact *pContact = new SwDrawContact( pObjArr->pFmt, pObjArr->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( pObjArr->pObj );
307     // #i45952# - notify that position attributes are already set
308     ASSERT( pObjArr->pFmt->ISA(SwDrawFrmFmt),
309             "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
310     if ( pObjArr->pFmt->ISA(SwDrawFrmFmt) )
311     {
312         static_cast<SwDrawFrmFmt*>(pObjArr->pFmt)->PosAttrSet();
313     }
314 }
315 
AddObj(sal_uInt16 nPos,SwDrawFrmFmt * pFmt,SdrObject * pObj)316 void SwUndoDrawGroup::AddObj( sal_uInt16 nPos, SwDrawFrmFmt* pFmt, SdrObject* pObj )
317 {
318     SwUndoGroupObjImpl& rSave = *( pObjArr + nPos + 1 );
319     rSave.pObj = pObj;
320     rSave.pFmt = pFmt;
321     ::lcl_SaveAnchor( pFmt, rSave.nNodeIdx );
322 
323     // notify UNO objects to decouple
324     ::lcl_SendRemoveToUno( *pFmt );
325 
326     // remove from array
327     SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pFmt->GetDoc()->GetSpzFrmFmts();
328     rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
329 }
330 
SetGroupFmt(SwDrawFrmFmt * pFmt)331 void SwUndoDrawGroup::SetGroupFmt( SwDrawFrmFmt* pFmt )
332 {
333     pObjArr->pObj = 0;
334     pObjArr->pFmt = pFmt;
335 }
336 
337 
338 // ------------------------------
339 
SwUndoDrawUnGroup(SdrObjGroup * pObj)340 SwUndoDrawUnGroup::SwUndoDrawUnGroup( SdrObjGroup* pObj )
341     : SwUndo( UNDO_DRAWUNGROUP ), bDelFmt( sal_False )
342 {
343     nSize = (sal_uInt16)pObj->GetSubList()->GetObjCount() + 1;
344     pObjArr = new SwUndoGroupObjImpl[ nSize ];
345 
346     SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
347     SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
348 
349     pObjArr->pObj = pObj;
350     pObjArr->pFmt = pFmt;
351 
352     // object will destroy itself
353     pContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
354     pObj->SetUserCall( 0 );
355 
356     ::lcl_SaveAnchor( pFmt, pObjArr->nNodeIdx );
357 
358     // notify UNO objects to decouple
359     ::lcl_SendRemoveToUno( *pFmt );
360 
361     // remove from array
362     SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pFmt->GetDoc()->GetSpzFrmFmts();
363     rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
364 }
365 
~SwUndoDrawUnGroup()366 SwUndoDrawUnGroup::~SwUndoDrawUnGroup()
367 {
368     if( bDelFmt )
369     {
370         SwUndoGroupObjImpl* pTmp = pObjArr + 1;
371         for( sal_uInt16 n = 1; n < nSize; ++n, ++pTmp )
372             delete pTmp->pFmt;
373     }
374     else
375         delete pObjArr->pFmt;
376 
377     delete [] pObjArr;
378 }
379 
UndoImpl(::sw::UndoRedoContext & rContext)380 void SwUndoDrawUnGroup::UndoImpl(::sw::UndoRedoContext & rContext)
381 {
382     bDelFmt = sal_True;
383 
384     SwDoc *const pDoc = & rContext.GetDoc();
385     SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
386 
387     // remove from array
388     for( sal_uInt16 n = 1; n < nSize; ++n )
389     {
390         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
391 
392         ::lcl_SaveAnchor( rSave.pFmt, rSave.nNodeIdx );
393 
394         // notify UNO objects to decouple
395         ::lcl_SendRemoveToUno( *rSave.pFmt );
396 
397         rFlyFmts.Remove( rFlyFmts.GetPos( rSave.pFmt ));
398     }
399 
400     // re-insert group object
401     ::lcl_RestoreAnchor( pObjArr->pFmt, pObjArr->nNodeIdx );
402     rFlyFmts.Insert( pObjArr->pFmt, rFlyFmts.Count() );
403 
404     SwDrawContact *pContact = new SwDrawContact( pObjArr->pFmt, pObjArr->pObj );
405     pContact->ConnectToLayout();
406     // #i45718# - follow-up of #i35635# move object to visible layer
407     pContact->MoveObjToVisibleLayer( pObjArr->pObj );
408     // #i45952# - notify that position attributes are already set
409     ASSERT( pObjArr->pFmt->ISA(SwDrawFrmFmt),
410             "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
411     if ( pObjArr->pFmt->ISA(SwDrawFrmFmt) )
412     {
413         static_cast<SwDrawFrmFmt*>(pObjArr->pFmt)->PosAttrSet();
414     }
415 }
416 
RedoImpl(::sw::UndoRedoContext &)417 void SwUndoDrawUnGroup::RedoImpl(::sw::UndoRedoContext &)
418 {
419     bDelFmt = sal_False;
420 
421     // save group object
422     SwDrawFrmFmt* pFmt = pObjArr->pFmt;
423     SwDrawContact* pContact = (SwDrawContact*)pFmt->FindContactObj();
424 
425         // object will destroy itself
426     pContact->Changed( *pObjArr->pObj, SDRUSERCALL_DELETE,
427         pObjArr->pObj->GetLastBoundRect() );
428     pObjArr->pObj->SetUserCall( 0 );
429 
430     ::lcl_SaveAnchor( pFmt, pObjArr->nNodeIdx );
431 
432     // notify UNO objects to decouple
433     ::lcl_SendRemoveToUno( *pFmt );
434 
435     // remove from array
436     SwDoc* pDoc = pFmt->GetDoc();
437     SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
438     rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
439 
440     for( sal_uInt16 n = 1; n < nSize; ++n )
441     {
442         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
443 
444         ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
445         rFlyFmts.Insert( rSave.pFmt, rFlyFmts.Count() );
446 
447         // #i45952# - notify that position attributes are already set
448         ASSERT( rSave.pFmt->ISA(SwDrawFrmFmt),
449                 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
450         if ( rSave.pFmt->ISA(SwDrawFrmFmt) )
451         {
452             static_cast<SwDrawFrmFmt*>(rSave.pFmt)->PosAttrSet();
453         }
454     }
455 }
456 
AddObj(sal_uInt16 nPos,SwDrawFrmFmt * pFmt)457 void SwUndoDrawUnGroup::AddObj( sal_uInt16 nPos, SwDrawFrmFmt* pFmt )
458 {
459     SwUndoGroupObjImpl& rSave = *( pObjArr + nPos + 1 );
460     rSave.pFmt = pFmt;
461     rSave.pObj = 0;
462 }
463 
SwUndoDrawUnGroupConnectToLayout()464 SwUndoDrawUnGroupConnectToLayout::SwUndoDrawUnGroupConnectToLayout()
465     : SwUndo( UNDO_DRAWUNGROUP )
466 {
467 }
468 
~SwUndoDrawUnGroupConnectToLayout()469 SwUndoDrawUnGroupConnectToLayout::~SwUndoDrawUnGroupConnectToLayout()
470 {
471 }
472 
473 void
UndoImpl(::sw::UndoRedoContext &)474 SwUndoDrawUnGroupConnectToLayout::UndoImpl(::sw::UndoRedoContext &)
475 {
476     for ( std::vector< SdrObject >::size_type i = 0;
477           i < aDrawFmtsAndObjs.size(); ++i )
478     {
479         SdrObject* pObj( aDrawFmtsAndObjs[i].second );
480         SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(pObj->GetUserCall()) );
481         ASSERT( pDrawContact,
482                 "<SwUndoDrawUnGroupConnectToLayout::Undo(..)> -- missing SwDrawContact instance" );
483         if ( pDrawContact )
484         {
485             // deletion of instance <pDrawContact> and thus disconnection from
486             // the Writer layout.
487             pDrawContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
488             pObj->SetUserCall( 0 );
489         }
490     }
491 }
492 
493 void
RedoImpl(::sw::UndoRedoContext &)494 SwUndoDrawUnGroupConnectToLayout::RedoImpl(::sw::UndoRedoContext &)
495 {
496     for ( std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >::size_type i = 0;
497           i < aDrawFmtsAndObjs.size(); ++i )
498     {
499         SwDrawFrmFmt* pFmt( aDrawFmtsAndObjs[i].first );
500         SdrObject* pObj( aDrawFmtsAndObjs[i].second );
501         SwDrawContact *pContact = new SwDrawContact( pFmt, pObj );
502         pContact->ConnectToLayout();
503         pContact->MoveObjToVisibleLayer( pObj );
504     }
505 }
506 
AddFmtAndObj(SwDrawFrmFmt * pDrawFrmFmt,SdrObject * pDrawObject)507 void SwUndoDrawUnGroupConnectToLayout::AddFmtAndObj( SwDrawFrmFmt* pDrawFrmFmt,
508                                                      SdrObject* pDrawObject )
509 {
510     aDrawFmtsAndObjs.push_back(
511             std::pair< SwDrawFrmFmt*, SdrObject* >( pDrawFrmFmt, pDrawObject ) );
512 }
513 
514 //-------------------------------------
515 
SwUndoDrawDelete(sal_uInt16 nCnt)516 SwUndoDrawDelete::SwUndoDrawDelete( sal_uInt16 nCnt )
517     : SwUndo( UNDO_DRAWDELETE ), nSize( nCnt ), bDelFmt( sal_True )
518 {
519     pObjArr = new SwUndoGroupObjImpl[ nSize ];
520     pMarkLst = new SdrMarkList();
521 }
522 
~SwUndoDrawDelete()523 SwUndoDrawDelete::~SwUndoDrawDelete()
524 {
525     if( bDelFmt )
526     {
527         SwUndoGroupObjImpl* pTmp = pObjArr;
528         for( sal_uInt16 n = 0; n < pMarkLst->GetMarkCount(); ++n, ++pTmp )
529             delete pTmp->pFmt;
530     }
531     delete [] pObjArr;
532     delete pMarkLst;
533 }
534 
UndoImpl(::sw::UndoRedoContext & rContext)535 void SwUndoDrawDelete::UndoImpl(::sw::UndoRedoContext & rContext)
536 {
537     bDelFmt = sal_False;
538     SwSpzFrmFmts & rFlyFmts = *rContext.GetDoc().GetSpzFrmFmts();
539     for( sal_uInt16 n = 0; n < pMarkLst->GetMarkCount(); ++n )
540     {
541         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
542         ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
543         rFlyFmts.Insert( rSave.pFmt, rFlyFmts.Count() );
544         SdrObject *pObj = rSave.pObj;
545         SwDrawContact *pContact = new SwDrawContact( rSave.pFmt, pObj );
546         pContact->_Changed( *pObj, SDRUSERCALL_INSERTED, NULL );
547         // #i45718# - follow-up of #i35635# move object to visible layer
548         pContact->MoveObjToVisibleLayer( pObj );
549         // #i45952# - notify that position attributes are already set
550         ASSERT( rSave.pFmt->ISA(SwDrawFrmFmt),
551                 "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
552         if ( rSave.pFmt->ISA(SwDrawFrmFmt) )
553         {
554             static_cast<SwDrawFrmFmt*>(rSave.pFmt)->PosAttrSet();
555         }
556         // <--
557     }
558     rContext.SetSelections(0, pMarkLst);
559 }
560 
RedoImpl(::sw::UndoRedoContext & rContext)561 void SwUndoDrawDelete::RedoImpl(::sw::UndoRedoContext & rContext)
562 {
563     bDelFmt = sal_True;
564     SwSpzFrmFmts & rFlyFmts = *rContext.GetDoc().GetSpzFrmFmts();
565     for( sal_uInt16 n = 0; n < pMarkLst->GetMarkCount(); ++n )
566     {
567         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
568         SdrObject *pObj = rSave.pObj;
569         SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
570         SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
571 
572         // object will destroy itself
573         pContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
574         pObj->SetUserCall( 0 );
575 
576         // notify UNO objects to decouple
577         ::lcl_SendRemoveToUno( *pFmt );
578 
579         rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
580         ::lcl_SaveAnchor( pFmt, rSave.nNodeIdx );
581     }
582 }
583 
AddObj(sal_uInt16,SwDrawFrmFmt * pFmt,const SdrMark & rMark)584 void SwUndoDrawDelete::AddObj( sal_uInt16 , SwDrawFrmFmt* pFmt,
585                                 const SdrMark& rMark )
586 {
587     SwUndoGroupObjImpl& rSave = *( pObjArr + pMarkLst->GetMarkCount() );
588     rSave.pObj = rMark.GetMarkedSdrObj();
589     rSave.pFmt = pFmt;
590     ::lcl_SaveAnchor( pFmt, rSave.nNodeIdx );
591 
592     // notify UNO objects to decouple
593     ::lcl_SendRemoveToUno( *pFmt );
594 
595     // remove from array
596     SwDoc* pDoc = pFmt->GetDoc();
597     SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
598     rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
599 
600     pMarkLst->InsertEntry( rMark );
601 }
602 
603