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