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