xref: /aoo4110/main/sw/source/core/undo/undraw.cxx (revision b1cdbd2c)
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