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