xref: /aoo41x/main/sw/source/core/frmedt/fecopy.cxx (revision 5222b95b)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19efeef26fSAndrew Rist  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <hintids.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <vcl/graph.hxx>
31cdf0e10cSrcweir #include <sot/formats.hxx>
32cdf0e10cSrcweir #include <sot/storage.hxx>
33cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
34cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
35cdf0e10cSrcweir #include <sfx2/viewsh.hxx>
36cdf0e10cSrcweir #include <svx/xexch.hxx>
37cdf0e10cSrcweir #include <svx/xflasit.hxx>
38cdf0e10cSrcweir #include <svx/xfillit0.hxx>
39cdf0e10cSrcweir #include <svx/xflclit.hxx>
40cdf0e10cSrcweir #include <editeng/brshitem.hxx>
41cdf0e10cSrcweir #include <svx/svdocapt.hxx>
42cdf0e10cSrcweir #include <svx/svdouno.hxx>
43cdf0e10cSrcweir #include <svx/xfillit.hxx>
44cdf0e10cSrcweir #include <svx/svdpage.hxx>
45cdf0e10cSrcweir #include <svx/svdogrp.hxx>
46cdf0e10cSrcweir #include <svx/xoutbmp.hxx>
47cdf0e10cSrcweir #include <svx/svdoole2.hxx>
48cdf0e10cSrcweir #include <svx/fmmodel.hxx>
49cdf0e10cSrcweir #include <svx/unomodel.hxx>
50cdf0e10cSrcweir // --> OD 2005-08-03 #i50824#
51cdf0e10cSrcweir #include <svx/svditer.hxx>
52cdf0e10cSrcweir // <--
53cdf0e10cSrcweir // --> OD 2006-03-01 #b6382898#
54cdf0e10cSrcweir #include <svx/svdograf.hxx>
55cdf0e10cSrcweir // <--
56cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
57cdf0e10cSrcweir #include <fmtanchr.hxx>
58cdf0e10cSrcweir #include <fmtcntnt.hxx>
59cdf0e10cSrcweir #include <fmtornt.hxx>
60cdf0e10cSrcweir #include <fmtflcnt.hxx>
61cdf0e10cSrcweir #include <frmfmt.hxx>
62cdf0e10cSrcweir #include <docary.hxx>
63cdf0e10cSrcweir #include <txtfrm.hxx>
64cdf0e10cSrcweir #include <txtflcnt.hxx>
65cdf0e10cSrcweir #include <fesh.hxx>
66cdf0e10cSrcweir #include <doc.hxx>
67cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
68cdf0e10cSrcweir #include <rootfrm.hxx>
69cdf0e10cSrcweir #include <ndtxt.hxx>
70cdf0e10cSrcweir #include <pam.hxx>
71cdf0e10cSrcweir #include <tblsel.hxx>
72cdf0e10cSrcweir #include <swtable.hxx>
73cdf0e10cSrcweir #include <flyfrm.hxx>
74cdf0e10cSrcweir #include <pagefrm.hxx>
75cdf0e10cSrcweir #include <fldbas.hxx>
76cdf0e10cSrcweir #include <edimp.hxx>
77cdf0e10cSrcweir #include <swundo.hxx>
78cdf0e10cSrcweir #include <viewimp.hxx>
79cdf0e10cSrcweir #include <dview.hxx>
80cdf0e10cSrcweir #include <dcontact.hxx>
81cdf0e10cSrcweir #include <dflyobj.hxx>
82cdf0e10cSrcweir #include <docsh.hxx>
83cdf0e10cSrcweir #include <pagedesc.hxx>
84cdf0e10cSrcweir #include <mvsave.hxx>
85cdf0e10cSrcweir #include <vcl/virdev.hxx>
8652f1c2eeSArmin Le Grand #include <svx/svdundo.hxx>
87cdf0e10cSrcweir 
88cdf0e10cSrcweir using namespace ::com::sun::star;
89cdf0e10cSrcweir 
90cdf0e10cSrcweir /*************************************************************************
91cdf0e10cSrcweir |*
92cdf0e10cSrcweir |*	SwFEShell::Copy()	Copy fuer das Interne Clipboard.
93cdf0e10cSrcweir |*		Kopiert alle Selektionen in das Clipboard.
94cdf0e10cSrcweir |*
95cdf0e10cSrcweir |*	Ersterstellung		JP ??
96cdf0e10cSrcweir |*	Letzte Aenderung	MA 22. Feb. 95
97cdf0e10cSrcweir |
98cdf0e10cSrcweir |*************************************************************************/
99cdf0e10cSrcweir 
Copy(SwDoc * pClpDoc,const String * pNewClpTxt)100cdf0e10cSrcweir sal_Bool SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt )
101cdf0e10cSrcweir {
102cdf0e10cSrcweir 	ASSERT( pClpDoc, "kein Clipboard-Dokument"	);
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     pClpDoc->GetIDocumentUndoRedo().DoUndo(false); // always false!
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 	// steht noch Inhalt im ClpDocument, dann muss dieser geloescht werden
107cdf0e10cSrcweir 	SwNodeIndex aSttIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
108cdf0e10cSrcweir 	SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
109cdf0e10cSrcweir 	if( !pTxtNd || pTxtNd->GetTxt().Len() ||
110cdf0e10cSrcweir 		aSttIdx.GetIndex()+1 != pClpDoc->GetNodes().GetEndOfContent().GetIndex() )
111cdf0e10cSrcweir 	{
112cdf0e10cSrcweir 		pClpDoc->GetNodes().Delete( aSttIdx,
113cdf0e10cSrcweir 			pClpDoc->GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
114cdf0e10cSrcweir 		pTxtNd = pClpDoc->GetNodes().MakeTxtNode( aSttIdx,
115cdf0e10cSrcweir 							(SwTxtFmtColl*)pClpDoc->GetDfltTxtFmtColl() );
116cdf0e10cSrcweir 		aSttIdx--;
117cdf0e10cSrcweir 	}
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 	// stehen noch FlyFrames rum, loesche auch diese
120cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < pClpDoc->GetSpzFrmFmts()->Count(); ++n )
121cdf0e10cSrcweir 	{
122cdf0e10cSrcweir 		SwFlyFrmFmt* pFly = (SwFlyFrmFmt*)(*pClpDoc->GetSpzFrmFmts())[n];
123cdf0e10cSrcweir 		pClpDoc->DelLayoutFmt( pFly );
124cdf0e10cSrcweir 	}
125cdf0e10cSrcweir 	pClpDoc->GCFieldTypes();		// loesche die FieldTypes
126cdf0e10cSrcweir 
127cdf0e10cSrcweir 	// wurde ein String uebergeben, so kopiere diesen in das Clipboard-
128cdf0e10cSrcweir 	// Dokument. Somit kann auch der Calculator das interne Clipboard
129cdf0e10cSrcweir 	// benutzen.
130cdf0e10cSrcweir 	if( pNewClpTxt )
131cdf0e10cSrcweir 	{
132cdf0e10cSrcweir         pTxtNd->InsertText( *pNewClpTxt, SwIndex( pTxtNd ) );
133cdf0e10cSrcweir 		return sal_True;				// das wars.
134cdf0e10cSrcweir 	}
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	pClpDoc->LockExpFlds();
137cdf0e10cSrcweir 	pClpDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
138cdf0e10cSrcweir 	sal_Bool bRet;
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 	// soll ein FlyFrame kopiert werden ?
141cdf0e10cSrcweir 	if( IsFrmSelected() )
142cdf0e10cSrcweir 	{
143cdf0e10cSrcweir 		// hole das FlyFormat
144cdf0e10cSrcweir 		SwFlyFrm* pFly = FindFlyFrm();
145cdf0e10cSrcweir 		SwFrmFmt* pFlyFmt = pFly->GetFmt();
146cdf0e10cSrcweir 		SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
149cdf0e10cSrcweir             (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
150cdf0e10cSrcweir             (FLY_AT_FLY  == aAnchor.GetAnchorId()) ||
151cdf0e10cSrcweir             (FLY_AS_CHAR == aAnchor.GetAnchorId()))
152cdf0e10cSrcweir         {
153cdf0e10cSrcweir             SwPosition aPos( aSttIdx );
154cdf0e10cSrcweir             if ( FLY_AS_CHAR == aAnchor.GetAnchorId() )
155cdf0e10cSrcweir             {
156cdf0e10cSrcweir                 aPos.nContent.Assign( pTxtNd, 0 );
157cdf0e10cSrcweir             }
158cdf0e10cSrcweir 			aAnchor.SetAnchor( &aPos );
159cdf0e10cSrcweir 		}
160cdf0e10cSrcweir         pFlyFmt = pClpDoc->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 		// sorge dafuer das das "RootFmt" als erstes im SpzArray-steht
163cdf0e10cSrcweir 		// (Es wurden ggf. Flys in Flys kopiert.
164cdf0e10cSrcweir 		SwSpzFrmFmts& rSpzFrmFmts = *(SwSpzFrmFmts*)pClpDoc->GetSpzFrmFmts();
165cdf0e10cSrcweir 		if( rSpzFrmFmts[ 0 ] != pFlyFmt )
166cdf0e10cSrcweir 		{
167cdf0e10cSrcweir 			sal_uInt16 nPos = rSpzFrmFmts.GetPos( pFlyFmt );
168cdf0e10cSrcweir 			ASSERT( nPos != USHRT_MAX, "Fly steht nicht im Spz-Array" );
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 			rSpzFrmFmts.Remove( nPos );
171cdf0e10cSrcweir 			rSpzFrmFmts.Insert( pFlyFmt, 0 );
172cdf0e10cSrcweir 		}
173cdf0e10cSrcweir 
174cdf0e10cSrcweir         if ( FLY_AS_CHAR == aAnchor.GetAnchorId() )
175cdf0e10cSrcweir         {
176cdf0e10cSrcweir 			// JP 13.02.99 Bug 61863: wenn eine Rahmenselektion ins Clipboard
177cdf0e10cSrcweir 			//				gestellt wird, so muss beim Pasten auch wieder
178cdf0e10cSrcweir 			//				eine solche vorgefunden werden. Also muss im Node
179cdf0e10cSrcweir 			//				das kopierte TextAttribut wieder entfernt werden,
180cdf0e10cSrcweir 			//				sonst wird es als TextSelektion erkannt
181cdf0e10cSrcweir 			const SwIndex& rIdx = pFlyFmt->GetAnchor().GetCntntAnchor()->nContent;
182cdf0e10cSrcweir             SwTxtFlyCnt *const pTxtFly = static_cast<SwTxtFlyCnt *>(
183cdf0e10cSrcweir                 pTxtNd->GetTxtAttrForCharAt(
184cdf0e10cSrcweir                     rIdx.GetIndex(), RES_TXTATR_FLYCNT));
185cdf0e10cSrcweir 			if( pTxtFly )
186cdf0e10cSrcweir 			{
187cdf0e10cSrcweir 				((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 );
188cdf0e10cSrcweir                 pTxtNd->EraseText( rIdx, 1 );
189cdf0e10cSrcweir             }
190cdf0e10cSrcweir         }
191cdf0e10cSrcweir 		bRet = sal_True;
192cdf0e10cSrcweir 	}
193cdf0e10cSrcweir 	else if ( IsObjSelected() )
194cdf0e10cSrcweir 	{
195cdf0e10cSrcweir         SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 ));
196cdf0e10cSrcweir 		const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
197cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
198cdf0e10cSrcweir 		{
199cdf0e10cSrcweir 			SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 			if( Imp()->GetDrawView()->IsGroupEntered() ||
202cdf0e10cSrcweir 				( !pObj->GetUserCall() && pObj->GetUpGroup()) )
203cdf0e10cSrcweir 			{
204cdf0e10cSrcweir 				SfxItemSet aSet( pClpDoc->GetAttrPool(), aFrmFmtSetRange );
205cdf0e10cSrcweir 
206cdf0e10cSrcweir                 SwFmtAnchor aAnchor( FLY_AT_PARA );
207cdf0e10cSrcweir 				aAnchor.SetAnchor( &aPos );
208cdf0e10cSrcweir 				aSet.Put( aAnchor );
209cdf0e10cSrcweir 
210cdf0e10cSrcweir                 SdrObject *const pNew =
211cdf0e10cSrcweir                     pClpDoc->CloneSdrObj( *pObj, sal_False, sal_True );
212cdf0e10cSrcweir 
213cdf0e10cSrcweir                 SwPaM aTemp(aPos);
214*5222b95bSOliver-Rainer Wittmann                 pClpDoc->InsertDrawObj(aTemp, *pNew, aSet );
215cdf0e10cSrcweir 			}
216cdf0e10cSrcweir 			else
217cdf0e10cSrcweir 			{
218cdf0e10cSrcweir 				SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
219cdf0e10cSrcweir 				SwFrmFmt *pFmt = pContact->GetFmt();
220cdf0e10cSrcweir 				SwFmtAnchor aAnchor( pFmt->GetAnchor() );
221cdf0e10cSrcweir                 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
222cdf0e10cSrcweir                     (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
223cdf0e10cSrcweir                     (FLY_AT_FLY  == aAnchor.GetAnchorId()) ||
224cdf0e10cSrcweir                     (FLY_AS_CHAR == aAnchor.GetAnchorId()))
225cdf0e10cSrcweir                 {
226cdf0e10cSrcweir 					aAnchor.SetAnchor( &aPos );
227cdf0e10cSrcweir 				}
228cdf0e10cSrcweir 
229cdf0e10cSrcweir                 pClpDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
230cdf0e10cSrcweir 			}
231cdf0e10cSrcweir 		}
232cdf0e10cSrcweir 		bRet = sal_True;
233cdf0e10cSrcweir 	}
234cdf0e10cSrcweir 	else
235cdf0e10cSrcweir 		bRet = _CopySelToDoc( pClpDoc, 0 );		// kopiere die Selectionen
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	pClpDoc->SetRedlineMode_intern((RedlineMode_t)0 );
238cdf0e10cSrcweir 	pClpDoc->UnlockExpFlds();
239cdf0e10cSrcweir 	if( !pClpDoc->IsExpFldsLocked() )
240cdf0e10cSrcweir 		pClpDoc->UpdateExpFlds(NULL, true);
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 	return bRet;
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
lcl_FindBasePos(const SwFrm * pFrm,const Point & rPt)245cdf0e10cSrcweir const Point &lcl_FindBasePos( const SwFrm *pFrm, const Point &rPt )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir 	const SwFrm *pF = pFrm;
248cdf0e10cSrcweir 	while ( pF && !pF->Frm().IsInside( rPt ) )
249cdf0e10cSrcweir 	{
250cdf0e10cSrcweir 		if ( pF->IsCntntFrm() )
251cdf0e10cSrcweir 			pF = ((SwCntntFrm*)pF)->GetFollow();
252cdf0e10cSrcweir 		else
253cdf0e10cSrcweir 			pF = 0;
254cdf0e10cSrcweir 	}
255cdf0e10cSrcweir 	if ( pF )
256cdf0e10cSrcweir 		return pF->Frm().Pos();
257cdf0e10cSrcweir 	else
258cdf0e10cSrcweir 		return pFrm->Frm().Pos();
259cdf0e10cSrcweir }
260cdf0e10cSrcweir 
lcl_SetAnchor(const SwPosition & rPos,const SwNode & rNd,SwFlyFrm * pFly,const Point & rInsPt,SwFEShell & rDestShell,SwFmtAnchor & rAnchor,Point & rNewPos,sal_Bool bCheckFlyRecur)261cdf0e10cSrcweir sal_Bool lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly,
262cdf0e10cSrcweir 				const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor,
263cdf0e10cSrcweir 				Point& rNewPos, sal_Bool bCheckFlyRecur )
264cdf0e10cSrcweir {
265cdf0e10cSrcweir 	sal_Bool bRet = sal_True;
266cdf0e10cSrcweir 	rAnchor.SetAnchor( &rPos );
267cdf0e10cSrcweir 	SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->getLayoutFrm( rDestShell.GetLayout(), &rInsPt, 0, sal_False );
268cdf0e10cSrcweir 	SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm();
269cdf0e10cSrcweir     if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( *pTmpFly ) )
270cdf0e10cSrcweir     {
271cdf0e10cSrcweir 		bRet = sal_False;
272cdf0e10cSrcweir     }
273cdf0e10cSrcweir     else if ( FLY_AT_FLY == rAnchor.GetAnchorId() )
274cdf0e10cSrcweir     {
275cdf0e10cSrcweir 		if( pTmpFly )
276cdf0e10cSrcweir 		{
277cdf0e10cSrcweir 			const SwNodeIndex& rIdx = *pTmpFly->GetFmt()->GetCntnt().GetCntntIdx();
278cdf0e10cSrcweir 			SwPosition aPos( rIdx );
279cdf0e10cSrcweir 			rAnchor.SetAnchor( &aPos );
280cdf0e10cSrcweir 			rNewPos = pTmpFly->Frm().Pos();
281cdf0e10cSrcweir 		}
282cdf0e10cSrcweir 		else
283cdf0e10cSrcweir 		{
284cdf0e10cSrcweir             rAnchor.SetType( FLY_AT_PAGE );
285cdf0e10cSrcweir 			rAnchor.SetPageNum( rDestShell.GetPageNumber( rInsPt ) );
286cdf0e10cSrcweir 			const SwFrm *pPg = pTmpFrm->FindPageFrm();
287cdf0e10cSrcweir 			rNewPos = pPg->Frm().Pos();
288cdf0e10cSrcweir 		}
289cdf0e10cSrcweir 	}
290cdf0e10cSrcweir 	else
291cdf0e10cSrcweir 		rNewPos = ::lcl_FindBasePos( pTmpFrm, rInsPt );
292cdf0e10cSrcweir 	return bRet;
293cdf0e10cSrcweir }
294cdf0e10cSrcweir 
CopyDrawSel(SwFEShell * pDestShell,const Point & rSttPt,const Point & rInsPt,sal_Bool bIsMove,sal_Bool bSelectInsert)295cdf0e10cSrcweir sal_Bool SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt,
296cdf0e10cSrcweir 					const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir 	sal_Bool bRet = sal_True;
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 	//Die Liste muss kopiert werden, weil unten die neuen Objekte
301cdf0e10cSrcweir 	//selektiert werden.
302cdf0e10cSrcweir 	const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() );
303cdf0e10cSrcweir 	sal_uLong nMarkCount = aMrkList.GetMarkCount();
304cdf0e10cSrcweir 	if( !pDestShell->Imp()->GetDrawView() )
305cdf0e10cSrcweir 		// sollte mal eine erzeugt werden
306cdf0e10cSrcweir 		pDestShell->MakeDrawView();
307cdf0e10cSrcweir 	else if( bSelectInsert )
308cdf0e10cSrcweir 		pDestShell->Imp()->GetDrawView()->UnmarkAll();
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 	SdrPageView *pDestPgView = pDestShell->Imp()->GetPageView(),
311cdf0e10cSrcweir 				*pSrcPgView = Imp()->GetPageView();
312cdf0e10cSrcweir 	SwDrawView *pDestDrwView = pDestShell->Imp()->GetDrawView(),
313cdf0e10cSrcweir 				*pSrcDrwView = Imp()->GetDrawView();
314cdf0e10cSrcweir 	SwDoc* pDestDoc = pDestShell->GetDoc();
315cdf0e10cSrcweir 
316cdf0e10cSrcweir 	Size aSiz( rInsPt.X() - rSttPt.X(), rInsPt.Y() - rSttPt.Y() );
317cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < nMarkCount; ++i )
318cdf0e10cSrcweir 	{
319cdf0e10cSrcweir 		SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 		SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
322cdf0e10cSrcweir 		SwFrmFmt *pFmt = pContact->GetFmt();
323cdf0e10cSrcweir 		const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 		sal_Bool bInsWithFmt = sal_True;
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 		if( pDestDrwView->IsGroupEntered() )
328cdf0e10cSrcweir 		{
329cdf0e10cSrcweir 			// in die Gruppe einfuegen, wenns aus einer betretenen Gruppe
330cdf0e10cSrcweir 			// kommt oder das Object nicht zeichengebunden ist
331cdf0e10cSrcweir 			if( pSrcDrwView->IsGroupEntered() ||
332cdf0e10cSrcweir                 (FLY_AS_CHAR != rAnchor.GetAnchorId()) )
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 			{
335cdf0e10cSrcweir 				SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
336cdf0e10cSrcweir 										GetDoc() == pDestDoc, sal_False );
337cdf0e10cSrcweir 				pNew->NbcMove( aSiz );
338cdf0e10cSrcweir 				pDestDrwView->InsertObjectAtView( pNew, *pDestPgView );
339cdf0e10cSrcweir 				bInsWithFmt = sal_False;
340cdf0e10cSrcweir 			}
341cdf0e10cSrcweir 		}
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 		if( bInsWithFmt )
344cdf0e10cSrcweir 		{
345cdf0e10cSrcweir 			SwFmtAnchor aAnchor( rAnchor );
346cdf0e10cSrcweir 			Point aNewAnch;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir             if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
349cdf0e10cSrcweir                 (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
350cdf0e10cSrcweir                 (FLY_AT_FLY  == aAnchor.GetAnchorId()) ||
351cdf0e10cSrcweir                 (FLY_AS_CHAR == aAnchor.GetAnchorId()))
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir 				if ( this == pDestShell )
354cdf0e10cSrcweir 				{
355cdf0e10cSrcweir 					//gleiche Shell? Dann erfrage die Position an der
356cdf0e10cSrcweir 					//uebergebenen DokumentPosition
357cdf0e10cSrcweir 					SwPosition aPos( *GetCrsr()->GetPoint() );
358cdf0e10cSrcweir 					Point aPt( rInsPt );
359cdf0e10cSrcweir 					aPt -= rSttPt - pObj->GetSnapRect().TopLeft();
360cdf0e10cSrcweir 					SwCrsrMoveState aState( MV_SETONLYTEXT );
361cdf0e10cSrcweir 					GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
362cdf0e10cSrcweir 					const SwNode *pNd;
363cdf0e10cSrcweir 					if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
364cdf0e10cSrcweir 						bRet = sal_False;
365cdf0e10cSrcweir 					else
366cdf0e10cSrcweir 						bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt,
367cdf0e10cSrcweir 								*pDestShell, aAnchor, aNewAnch, sal_False );
368cdf0e10cSrcweir 				}
369cdf0e10cSrcweir 				else
370cdf0e10cSrcweir 				{
371cdf0e10cSrcweir 					SwPaM *pCrsr = pDestShell->GetCrsr();
372cdf0e10cSrcweir 					if( pCrsr->GetNode()->IsNoTxtNode() )
373cdf0e10cSrcweir 						bRet = sal_False;
374cdf0e10cSrcweir 					else
375cdf0e10cSrcweir 						bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(),
376cdf0e10cSrcweir 												*pCrsr->GetNode(), 0, rInsPt,
377cdf0e10cSrcweir 												*pDestShell, aAnchor,
378cdf0e10cSrcweir 												aNewAnch, sal_False );
379cdf0e10cSrcweir 				}
380cdf0e10cSrcweir 			}
381cdf0e10cSrcweir             else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
382cdf0e10cSrcweir 			{
383cdf0e10cSrcweir 				aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
384cdf0e10cSrcweir                 const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
385cdf0e10cSrcweir                 const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
386cdf0e10cSrcweir                 if ( pPg )
387cdf0e10cSrcweir                     aNewAnch = pPg->Frm().Pos();
388cdf0e10cSrcweir 			}
389cdf0e10cSrcweir 
390cdf0e10cSrcweir 			if( bRet )
391cdf0e10cSrcweir 			{
392cdf0e10cSrcweir 				if( pSrcDrwView->IsGroupEntered() ||
393cdf0e10cSrcweir 					( !pObj->GetUserCall() && pObj->GetUpGroup()) )
394cdf0e10cSrcweir 				{
395cdf0e10cSrcweir 					SfxItemSet aSet( pDestDoc->GetAttrPool(),aFrmFmtSetRange);
396cdf0e10cSrcweir 					aSet.Put( aAnchor );
397cdf0e10cSrcweir 					SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
398cdf0e10cSrcweir 												GetDoc() == pDestDoc, sal_True );
399*5222b95bSOliver-Rainer Wittmann 					pFmt = pDestDoc->InsertDrawObj( *pDestShell->GetCrsr(), *pNew, aSet );
400cdf0e10cSrcweir 				}
401cdf0e10cSrcweir 				else
402cdf0e10cSrcweir                     pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 				//Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind.
405cdf0e10cSrcweir 				if ( pFmt )
406cdf0e10cSrcweir 				{
407cdf0e10cSrcweir                     SdrObject* pNew = pFmt->FindSdrObject();
408cdf0e10cSrcweir                     if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
409cdf0e10cSrcweir                     {
410cdf0e10cSrcweir 						Point aPos( rInsPt );
411cdf0e10cSrcweir 						aPos -= aNewAnch;
412cdf0e10cSrcweir 						aPos -= rSttPt - pObj->GetSnapRect().TopLeft();
413cdf0e10cSrcweir                         // OD 2004-04-05 #i26791# - change attributes instead of
414cdf0e10cSrcweir                         // direct positioning
415cdf0e10cSrcweir                         pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
416cdf0e10cSrcweir                         pFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
417cdf0e10cSrcweir                         // --> OD 2005-04-15 #i47455# - notify draw frame format
418cdf0e10cSrcweir                         // that position attributes are already set.
419cdf0e10cSrcweir                         if ( pFmt->ISA(SwDrawFrmFmt) )
420cdf0e10cSrcweir                         {
421cdf0e10cSrcweir                             static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet();
422cdf0e10cSrcweir                         }
423cdf0e10cSrcweir                         // <--
424cdf0e10cSrcweir                     }
425cdf0e10cSrcweir 					if( bSelectInsert )
426cdf0e10cSrcweir 						pDestDrwView->MarkObj( pNew, pDestPgView );
427cdf0e10cSrcweir 				}
428cdf0e10cSrcweir 			}
429cdf0e10cSrcweir 		}
430cdf0e10cSrcweir 	}
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 	if ( bIsMove && bRet )
433cdf0e10cSrcweir 	{
434cdf0e10cSrcweir 		if( pDestShell == this )
435cdf0e10cSrcweir 		{
436cdf0e10cSrcweir 			const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() );
437cdf0e10cSrcweir 			pSrcDrwView->UnmarkAll();
438cdf0e10cSrcweir 
439cdf0e10cSrcweir             sal_uLong nMrkCnt = aMrkList.GetMarkCount();
440cdf0e10cSrcweir 			sal_uInt16 i;
441cdf0e10cSrcweir             for ( i = 0; i < nMrkCnt; ++i )
442cdf0e10cSrcweir 			{
443cdf0e10cSrcweir 				SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
444cdf0e10cSrcweir 				pSrcDrwView->MarkObj( pObj, pSrcPgView );
445cdf0e10cSrcweir 			}
446cdf0e10cSrcweir 			DelSelectedObj();
447cdf0e10cSrcweir             nMrkCnt = aList.GetMarkCount();
448cdf0e10cSrcweir             for ( i = 0; i < nMrkCnt; ++i )
449cdf0e10cSrcweir 			{
450cdf0e10cSrcweir 				SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj();
451cdf0e10cSrcweir 				pSrcDrwView->MarkObj( pObj, pSrcPgView );
452cdf0e10cSrcweir 			}
453cdf0e10cSrcweir 		}
454cdf0e10cSrcweir 		else
455cdf0e10cSrcweir 			DelSelectedObj();
456cdf0e10cSrcweir 	}
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 	return bRet;
459cdf0e10cSrcweir }
460cdf0e10cSrcweir 
Copy(SwFEShell * pDestShell,const Point & rSttPt,const Point & rInsPt,sal_Bool bIsMove,sal_Bool bSelectInsert)461cdf0e10cSrcweir sal_Bool SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
462cdf0e10cSrcweir 					const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 	ASSERT( pDestShell, "Copy ohne DestShell." );
467cdf0e10cSrcweir 	ASSERT( this == pDestShell || !pDestShell->IsObjSelected(),
468cdf0e10cSrcweir 			"Dest-Shell darf nie im Obj-Modus sein" );
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	SET_CURR_SHELL( pDestShell );
471cdf0e10cSrcweir 
472cdf0e10cSrcweir 	pDestShell->StartAllAction();
473cdf0e10cSrcweir 	pDestShell->GetDoc()->LockExpFlds();
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 	// Referenzen sollen verschoben werden.
476cdf0e10cSrcweir 	sal_Bool bCopyIsMove = pDoc->IsCopyIsMove();
477cdf0e10cSrcweir 	if( bIsMove )
478cdf0e10cSrcweir 		// am Doc ein Flag setzen, damit in den TextNodes
479cdf0e10cSrcweir 		pDoc->SetCopyIsMove( sal_True );
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 	RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode();
482cdf0e10cSrcweir 	pDestShell->GetDoc()->SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES));
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 	// sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
485cdf0e10cSrcweir 	// angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
486cdf0e10cSrcweir 	// kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
487cdf0e10cSrcweir 	// besorgt)
488cdf0e10cSrcweir 	SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD );
489cdf0e10cSrcweir 
490cdf0e10cSrcweir 	if( IsFrmSelected() )
491cdf0e10cSrcweir 	{
492cdf0e10cSrcweir 		SwFlyFrm* pFly = FindFlyFrm();
493cdf0e10cSrcweir 		SwFrmFmt* pFlyFmt = pFly->GetFmt();
494cdf0e10cSrcweir 		SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
495cdf0e10cSrcweir 		bRet = sal_True;
496cdf0e10cSrcweir 		Point aNewAnch;
497cdf0e10cSrcweir 
498cdf0e10cSrcweir         if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
499cdf0e10cSrcweir             (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
500cdf0e10cSrcweir             (FLY_AT_FLY  == aAnchor.GetAnchorId()) ||
501cdf0e10cSrcweir             (FLY_AS_CHAR == aAnchor.GetAnchorId()))
502cdf0e10cSrcweir         {
503cdf0e10cSrcweir 			if ( this == pDestShell )
504cdf0e10cSrcweir 			{
505cdf0e10cSrcweir 				// gleiche Shell? Dann erfrage die Position an der
506cdf0e10cSrcweir 				// uebergebenen DokumentPosition
507cdf0e10cSrcweir 				SwPosition aPos( *GetCrsr()->GetPoint() );
508cdf0e10cSrcweir 				Point aPt( rInsPt );
509cdf0e10cSrcweir 				aPt -= rSttPt - pFly->Frm().Pos();
510cdf0e10cSrcweir 				SwCrsrMoveState aState( MV_SETONLYTEXT );
511cdf0e10cSrcweir 				GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
512cdf0e10cSrcweir 				const SwNode *pNd;
513cdf0e10cSrcweir 				if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
514cdf0e10cSrcweir 					bRet = sal_False;
515cdf0e10cSrcweir 				else
516cdf0e10cSrcweir 				{	//Nicht in sich selbst kopieren
517cdf0e10cSrcweir 					const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
518cdf0e10cSrcweir 					if ( aPos.nNode > *pTmp && aPos.nNode <
519cdf0e10cSrcweir 						pTmp->GetNode().EndOfSectionIndex() )
520cdf0e10cSrcweir 					{
521cdf0e10cSrcweir 						bRet = sal_False;
522cdf0e10cSrcweir 					}
523cdf0e10cSrcweir 					else
524cdf0e10cSrcweir 						bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
525cdf0e10cSrcweir 										*pDestShell, aAnchor, aNewAnch, sal_True );
526cdf0e10cSrcweir 				}
527cdf0e10cSrcweir 			}
528cdf0e10cSrcweir 			else
529cdf0e10cSrcweir 			{
530cdf0e10cSrcweir 				const SwPaM *pCrsr = pDestShell->GetCrsr();
531cdf0e10cSrcweir 				if( pCrsr->GetNode()->IsNoTxtNode() )
532cdf0e10cSrcweir 					bRet = sal_False;
533cdf0e10cSrcweir 				else
534cdf0e10cSrcweir 					bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(),
535cdf0e10cSrcweir 											pFly, rInsPt, *pDestShell, aAnchor,
536cdf0e10cSrcweir 									aNewAnch, GetDoc() == pDestShell->GetDoc());
537cdf0e10cSrcweir 			}
538cdf0e10cSrcweir 		}
539cdf0e10cSrcweir         else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
540cdf0e10cSrcweir         {
541cdf0e10cSrcweir 			aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
542cdf0e10cSrcweir             const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
543cdf0e10cSrcweir             const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
544cdf0e10cSrcweir             if ( pPg )
545cdf0e10cSrcweir                 aNewAnch = pPg->Frm().Pos();
546cdf0e10cSrcweir         }
547cdf0e10cSrcweir 		else {
548cdf0e10cSrcweir 			ASSERT( !this, "was fuer ein Anchor ist es denn?" );
549cdf0e10cSrcweir         }
550cdf0e10cSrcweir 
551cdf0e10cSrcweir 		if( bRet )
552cdf0e10cSrcweir 		{
553cdf0e10cSrcweir 			SwFrmFmt *pOldFmt = pFlyFmt;
554cdf0e10cSrcweir             pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
555cdf0e10cSrcweir 
556cdf0e10cSrcweir             if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
557cdf0e10cSrcweir             {
558cdf0e10cSrcweir 				Point aPos( rInsPt );
559cdf0e10cSrcweir 				aPos -= aNewAnch;
560cdf0e10cSrcweir 				aPos -= rSttPt - pFly->Frm().Pos();
561cdf0e10cSrcweir                 pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
562cdf0e10cSrcweir                 pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
563cdf0e10cSrcweir 			}
564cdf0e10cSrcweir 
565cdf0e10cSrcweir 			const Point aPt( pDestShell->GetCrsrDocPos() );
566cdf0e10cSrcweir 
567cdf0e10cSrcweir 			if( bIsMove )
568cdf0e10cSrcweir 				GetDoc()->DelLayoutFmt( pOldFmt );
569cdf0e10cSrcweir 
570cdf0e10cSrcweir 			// nur selektieren wenn es in der gleichen Shell verschoben/
571cdf0e10cSrcweir 			//	kopiert wird
572cdf0e10cSrcweir 			if( bSelectInsert )
573cdf0e10cSrcweir 			{
574cdf0e10cSrcweir 				SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, sal_False );
575cdf0e10cSrcweir 				if( pFlyFrm )
576cdf0e10cSrcweir 				{
577cdf0e10cSrcweir 					//JP 12.05.98: sollte das nicht im SelectFlyFrm stehen???
578cdf0e10cSrcweir 					pDestShell->Imp()->GetDrawView()->UnmarkAll();
579cdf0e10cSrcweir 					pDestShell->SelectFlyFrm( *pFlyFrm, sal_True );
580cdf0e10cSrcweir 				}
581cdf0e10cSrcweir 			}
582cdf0e10cSrcweir 
583cdf0e10cSrcweir 			if( this != pDestShell && !pDestShell->HasShFcs() )
584cdf0e10cSrcweir 				pDestShell->Imp()->GetDrawView()->hideMarkHandles();
585cdf0e10cSrcweir 		}
586cdf0e10cSrcweir 	}
587cdf0e10cSrcweir 	else if ( IsObjSelected() )
588cdf0e10cSrcweir 		bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert );
589cdf0e10cSrcweir 	else if( IsTableMode() )
590cdf0e10cSrcweir 	{
591cdf0e10cSrcweir 		// kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
592cdf0e10cSrcweir 		// von der Originalen an und kopiere die selectierten Boxen.
593cdf0e10cSrcweir 		// Die Groessen werden prozentual korrigiert.
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 		// lasse ueber das Layout die Boxen suchen
596cdf0e10cSrcweir 		const SwTableNode* pTblNd;
597cdf0e10cSrcweir 		SwSelBoxes aBoxes;
598cdf0e10cSrcweir 		GetTblSel( *this, aBoxes );
599cdf0e10cSrcweir 		if( aBoxes.Count() &&
600cdf0e10cSrcweir 			0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) )
601cdf0e10cSrcweir 		{
602cdf0e10cSrcweir 			SwPosition* pDstPos = 0;
603cdf0e10cSrcweir 			if( this == pDestShell )
604cdf0e10cSrcweir 			{
605cdf0e10cSrcweir 				// gleiche Shell? Dann erzeuge einen Crsr an der
606cdf0e10cSrcweir 				// uebergebenen DokumentPosition
607cdf0e10cSrcweir 				pDstPos = new SwPosition( *GetCrsr()->GetPoint() );
608cdf0e10cSrcweir 				Point aPt( rInsPt );
609cdf0e10cSrcweir 				GetLayout()->GetCrsrOfst( pDstPos, aPt );
610cdf0e10cSrcweir 				if( !pDstPos->nNode.GetNode().IsNoTxtNode() )
611cdf0e10cSrcweir 					bRet = sal_True;
612cdf0e10cSrcweir 			}
613cdf0e10cSrcweir 			else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
614cdf0e10cSrcweir 			{
615cdf0e10cSrcweir 				pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
616cdf0e10cSrcweir 				bRet = sal_True;
617cdf0e10cSrcweir 			}
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 			if( bRet )
620cdf0e10cSrcweir 			{
621cdf0e10cSrcweir 				if( GetDoc() == pDestShell->GetDoc() )
622cdf0e10cSrcweir 					ParkTblCrsr();
623cdf0e10cSrcweir 
624cdf0e10cSrcweir 				bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0,
625cdf0e10cSrcweir 										bIsMove && this == pDestShell &&
626cdf0e10cSrcweir 										aBoxes.Count() == pTblNd->GetTable().
627cdf0e10cSrcweir 										GetTabSortBoxes().Count(),
628cdf0e10cSrcweir 										this != pDestShell );
629cdf0e10cSrcweir 
630cdf0e10cSrcweir 				if( this != pDestShell )
631cdf0e10cSrcweir 					*pDestShell->GetCrsr()->GetPoint() = *pDstPos;
632cdf0e10cSrcweir 
633cdf0e10cSrcweir 				// wieder alle geparkten Crsr erzeugen?
634cdf0e10cSrcweir 				if( GetDoc() == pDestShell->GetDoc() )
635cdf0e10cSrcweir 					GetCrsr();
636cdf0e10cSrcweir 
637cdf0e10cSrcweir 				// JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte
638cdf0e10cSrcweir 				//				Cursor auf die EinfuegePos. positioniert wird
639cdf0e10cSrcweir 				if( this == pDestShell )
640cdf0e10cSrcweir 					GetCrsrDocPos() = rInsPt;
641cdf0e10cSrcweir 			}
642cdf0e10cSrcweir 			delete pDstPos;
643cdf0e10cSrcweir 		}
644cdf0e10cSrcweir 	}
645cdf0e10cSrcweir 	else
646cdf0e10cSrcweir 	{
647cdf0e10cSrcweir 		bRet = sal_True;
648cdf0e10cSrcweir 		if( this == pDestShell )
649cdf0e10cSrcweir 		{
650cdf0e10cSrcweir 			// gleiche Shell? Dann erfrage die Position an der
651cdf0e10cSrcweir 			// uebergebenen DokumentPosition
652cdf0e10cSrcweir 			SwPosition aPos( *GetCrsr()->GetPoint() );
653cdf0e10cSrcweir 			Point aPt( rInsPt );
654cdf0e10cSrcweir 			GetLayout()->GetCrsrOfst( &aPos, aPt );
655cdf0e10cSrcweir 			bRet = !aPos.nNode.GetNode().IsNoTxtNode();
656cdf0e10cSrcweir 		}
657cdf0e10cSrcweir 		else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
658cdf0e10cSrcweir 			bRet = sal_False;
659cdf0e10cSrcweir 
660cdf0e10cSrcweir 		if( bRet )
661cdf0e10cSrcweir 			bRet = 0 != SwEditShell::Copy( pDestShell );
662cdf0e10cSrcweir 	}
663cdf0e10cSrcweir 
664cdf0e10cSrcweir 	pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode );
665cdf0e10cSrcweir 	pDoc->SetCopyIsMove( bCopyIsMove );
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 	// wurden neue Tabellenformeln eingefuegt ?
668cdf0e10cSrcweir 	if( pTblFldTyp->GetDepends() )
669cdf0e10cSrcweir 	{
670cdf0e10cSrcweir 		// alte Actions beenden; die Tabellen-Frames werden angelegt und
671cdf0e10cSrcweir 		// eine SSelection kann erzeugt werden
672cdf0e10cSrcweir 		sal_uInt16 nActCnt;
673cdf0e10cSrcweir 		for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt )
674cdf0e10cSrcweir 			pDestShell->EndAllAction();
675cdf0e10cSrcweir 
676cdf0e10cSrcweir 		for( ; nActCnt; --nActCnt )
677cdf0e10cSrcweir 			pDestShell->StartAllAction();
678cdf0e10cSrcweir 	}
679cdf0e10cSrcweir 	pDestShell->GetDoc()->UnlockExpFlds();
680cdf0e10cSrcweir 	pDestShell->GetDoc()->UpdateFlds(NULL, false);
681cdf0e10cSrcweir 
682cdf0e10cSrcweir 	pDestShell->EndAllAction();
683cdf0e10cSrcweir 	return bRet;
684cdf0e10cSrcweir }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir /*************************************************************************
687cdf0e10cSrcweir |*
688cdf0e10cSrcweir |*	SwFEShell::Paste()	Paste fuer das Interne Clipboard.
689cdf0e10cSrcweir |*		Kopiert den Inhalt vom Clipboard in das Dokument.
690cdf0e10cSrcweir |*
691cdf0e10cSrcweir |*	Ersterstellung		JP ??
692cdf0e10cSrcweir |*	Letzte Aenderung	MA 22. Feb. 95
693cdf0e10cSrcweir |
694cdf0e10cSrcweir |*************************************************************************/
695cdf0e10cSrcweir 
696cdf0e10cSrcweir namespace {
697cdf0e10cSrcweir     typedef boost::shared_ptr<SwPaM> PaMPtr;
698cdf0e10cSrcweir     typedef boost::shared_ptr<SwPosition> PositionPtr;
699cdf0e10cSrcweir     typedef std::pair< PaMPtr, PositionPtr > Insertion;
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
Paste(SwDoc * pClpDoc,sal_Bool bIncludingPageFrames)702cdf0e10cSrcweir sal_Bool SwFEShell::Paste( SwDoc* pClpDoc, sal_Bool bIncludingPageFrames )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir 	SET_CURR_SHELL( this );
705cdf0e10cSrcweir 	ASSERT( pClpDoc, "kein Clipboard-Dokument"	);
706cdf0e10cSrcweir     const sal_uInt16 nStartPageNumber = GetPhyPageNum();
707cdf0e10cSrcweir 	// dann bis zum Ende vom Nodes Array
708cdf0e10cSrcweir 	SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
709cdf0e10cSrcweir 	SwPaM aCpyPam( aIdx ); //DocStart
710cdf0e10cSrcweir 
711cdf0e10cSrcweir 	// sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
712cdf0e10cSrcweir 	// angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
713cdf0e10cSrcweir 	// kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
714cdf0e10cSrcweir 	// besorgt)
715cdf0e10cSrcweir 	SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
716cdf0e10cSrcweir 
717cdf0e10cSrcweir 	SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode();
718cdf0e10cSrcweir 	if( !pSrcNd )								// TabellenNode ?
719cdf0e10cSrcweir 	{											// nicht ueberspringen!!
720cdf0e10cSrcweir 		SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode();
721cdf0e10cSrcweir 		if( pCNd )
722cdf0e10cSrcweir 			aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 );
723cdf0e10cSrcweir 		else if( !aCpyPam.Move( fnMoveForward, fnGoNode ))
724cdf0e10cSrcweir 			aCpyPam.Move( fnMoveBackward, fnGoNode );
725cdf0e10cSrcweir 	}
726cdf0e10cSrcweir 
727cdf0e10cSrcweir 	aCpyPam.SetMark();
728cdf0e10cSrcweir 	aCpyPam.Move( fnMoveForward, fnGoDoc );
729cdf0e10cSrcweir 
730cdf0e10cSrcweir 	sal_Bool bRet = sal_True, bDelTbl = sal_True;
731cdf0e10cSrcweir 	StartAllAction();
732cdf0e10cSrcweir     GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
733cdf0e10cSrcweir 	GetDoc()->LockExpFlds();
734cdf0e10cSrcweir 
735cdf0e10cSrcweir     // When the clipboard content has been created by a rectangular selection
736cdf0e10cSrcweir     // the pasting is more sophisticated:
737cdf0e10cSrcweir     // every paragraph will be inserted into another position.
738cdf0e10cSrcweir     // The first positions are given by the actual cursor ring,
739cdf0e10cSrcweir     // if there are more text portions to insert than cursor in this ring,
740cdf0e10cSrcweir     // the additional insert positions will be created by moving the last
741cdf0e10cSrcweir     // cursor position into the next line (like pressing the cursor down key)
742cdf0e10cSrcweir     if( pClpDoc->IsColumnSelection() && !IsTableMode() )
743cdf0e10cSrcweir     {
744cdf0e10cSrcweir         // Creation of the list of insert positions
745cdf0e10cSrcweir         std::list< Insertion > aCopyList;
746cdf0e10cSrcweir         // The number of text portions of the rectangular selection
747cdf0e10cSrcweir         const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex()
748cdf0e10cSrcweir                        - aCpyPam.GetMark()->nNode.GetIndex();
749cdf0e10cSrcweir         sal_uInt32 nCount = nSelCount;
750cdf0e10cSrcweir         SwNodeIndex aClpIdx( aIdx );
751cdf0e10cSrcweir         SwPaM* pStartCursor = GetCrsr();
752cdf0e10cSrcweir         SwPaM* pCurrCrsr = pStartCursor;
753cdf0e10cSrcweir         sal_uInt32 nCursorCount = pStartCursor->numberOf();
754cdf0e10cSrcweir         // If the target selection is a multi-selection, often the last and first
755cdf0e10cSrcweir         // cursor of the ring points to identical document positions. Then
756cdf0e10cSrcweir         // we should avoid double insertion of text portions...
757cdf0e10cSrcweir         while( nCursorCount > 1 && *pCurrCrsr->GetPoint() ==
758cdf0e10cSrcweir             *(dynamic_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) )
759cdf0e10cSrcweir         {
760cdf0e10cSrcweir             --nCursorCount;
761cdf0e10cSrcweir             pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
762cdf0e10cSrcweir             pStartCursor = pCurrCrsr;
763cdf0e10cSrcweir         }
764cdf0e10cSrcweir         SwPosition aStartPos( *pStartCursor->GetPoint() );
765cdf0e10cSrcweir         SwPosition aInsertPos( aStartPos ); // first insertion position
766cdf0e10cSrcweir         bool bCompletePara = false;
767cdf0e10cSrcweir         sal_uInt16 nMove = 0;
768cdf0e10cSrcweir         while( nCount )
769cdf0e10cSrcweir         {
770cdf0e10cSrcweir             --nCount;
771cdf0e10cSrcweir             ASSERT( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" )
772cdf0e10cSrcweir             if( aIdx.GetNode().GetCntntNode() ) // robust
773cdf0e10cSrcweir             {
774cdf0e10cSrcweir                 Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ),
775cdf0e10cSrcweir                     PositionPtr( new SwPosition( aInsertPos ) ) );
776cdf0e10cSrcweir                 ++aIdx;
777cdf0e10cSrcweir                 aInsertion.first->SetMark();
778cdf0e10cSrcweir                 if( pStartCursor == pCurrCrsr->GetNext() )
779cdf0e10cSrcweir                 {   // Now we have to look for insertion positions...
780cdf0e10cSrcweir                     if( !nMove ) // Annotate the last given insert position
781cdf0e10cSrcweir                         aStartPos = aInsertPos;
782cdf0e10cSrcweir                     SwCursor aCrsr( aStartPos, 0, false);
783cdf0e10cSrcweir                     // Check if we find another insert position by moving
784cdf0e10cSrcweir                     // down the last given position
785cdf0e10cSrcweir                     if( aCrsr.UpDown( sal_False, ++nMove, 0, 0 ) )
786cdf0e10cSrcweir                         aInsertPos = *aCrsr.GetPoint();
787cdf0e10cSrcweir                     else // if there is no paragraph we have to create it
788cdf0e10cSrcweir                         bCompletePara = nCount > 0;
789cdf0e10cSrcweir                     nCursorCount = 0;
790cdf0e10cSrcweir                 }
791cdf0e10cSrcweir                 else // as long as we find more insert positions in the cursor ring
792cdf0e10cSrcweir                 {    // we'll take them
793cdf0e10cSrcweir                     pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
794cdf0e10cSrcweir                     aInsertPos = *pCurrCrsr->GetPoint();
795cdf0e10cSrcweir                     --nCursorCount;
796cdf0e10cSrcweir                 }
797cdf0e10cSrcweir                 // If there are no more paragraphs e.g. at the end of a document,
798cdf0e10cSrcweir                 // we insert complete paragraphs instead of text portions
799cdf0e10cSrcweir                 if( bCompletePara )
800cdf0e10cSrcweir                     aInsertion.first->GetPoint()->nNode = aIdx;
801cdf0e10cSrcweir                 else
802cdf0e10cSrcweir                     aInsertion.first->GetPoint()->nContent =
803cdf0e10cSrcweir                         aInsertion.first->GetCntntNode()->Len();
804cdf0e10cSrcweir                 aCopyList.push_back( aInsertion );
805cdf0e10cSrcweir             }
806cdf0e10cSrcweir             // If there are no text portions left but there are some more
807cdf0e10cSrcweir             // cursor positions to fill we have to restart with the first
808cdf0e10cSrcweir             // text portion
809cdf0e10cSrcweir             if( !nCount && nCursorCount )
810cdf0e10cSrcweir             {
811cdf0e10cSrcweir                 nCount = std::min( nSelCount, nCursorCount );
812cdf0e10cSrcweir                 aIdx = aClpIdx; // Start of clipboard content
813cdf0e10cSrcweir             }
814cdf0e10cSrcweir         }
815cdf0e10cSrcweir         std::list< Insertion >::const_iterator pCurr = aCopyList.begin();
816cdf0e10cSrcweir         std::list< Insertion >::const_iterator pEnd = aCopyList.end();
817cdf0e10cSrcweir         while( pCurr != pEnd )
818cdf0e10cSrcweir         {
819cdf0e10cSrcweir             SwPosition& rInsPos = *pCurr->second;
820cdf0e10cSrcweir             SwPaM& rCopy = *pCurr->first;
821cdf0e10cSrcweir             const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
822cdf0e10cSrcweir             if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() &&
823cdf0e10cSrcweir                 rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode )
824cdf0e10cSrcweir             {
825cdf0e10cSrcweir                 // if more than one node will be copied into a cell
826cdf0e10cSrcweir                 // the box attributes have to be removed
827cdf0e10cSrcweir                 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
828cdf0e10cSrcweir             }
829cdf0e10cSrcweir             {
830cdf0e10cSrcweir                 SwNodeIndex aIndexBefore(rInsPos.nNode);
831cdf0e10cSrcweir                 aIndexBefore--;
832cdf0e10cSrcweir                 pClpDoc->CopyRange( rCopy, rInsPos, false );
833cdf0e10cSrcweir                 {
834cdf0e10cSrcweir                     aIndexBefore++;
835cdf0e10cSrcweir                     SwPaM aPaM(SwPosition(aIndexBefore),
836cdf0e10cSrcweir                                SwPosition(rInsPos.nNode));
837cdf0e10cSrcweir                     aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
838cdf0e10cSrcweir                 }
839cdf0e10cSrcweir             }
840cdf0e10cSrcweir             SaveTblBoxCntnt( &rInsPos );
841cdf0e10cSrcweir             ++pCurr;
842cdf0e10cSrcweir         }
843cdf0e10cSrcweir     }
844cdf0e10cSrcweir     else
845cdf0e10cSrcweir     {
846cdf0e10cSrcweir         FOREACHPAM_START(this)
847cdf0e10cSrcweir 
848cdf0e10cSrcweir         if( pSrcNd &&
849cdf0e10cSrcweir 			0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode )))
850cdf0e10cSrcweir 		{
851cdf0e10cSrcweir 			SwPosition aDestPos( *PCURCRSR->GetPoint() );
852cdf0e10cSrcweir 
853cdf0e10cSrcweir 			sal_Bool bParkTblCrsr = sal_False;
854cdf0e10cSrcweir 			const SwStartNode* pSttNd =  PCURCRSR->GetNode()->FindTableBoxStartNode();
855cdf0e10cSrcweir 
856cdf0e10cSrcweir             // TABLE IN TABLE: Tabelle in Tabelle kopieren
857cdf0e10cSrcweir 			// lasse ueber das Layout die Boxen suchen
858cdf0e10cSrcweir 			SwSelBoxes aBoxes;
859cdf0e10cSrcweir 			if( IsTableMode() )		// Tabellen-Selecktion ??
860cdf0e10cSrcweir 			{
861cdf0e10cSrcweir 				GetTblSel( *this, aBoxes );
862cdf0e10cSrcweir 				ParkTblCrsr();
863cdf0e10cSrcweir 				bParkTblCrsr = sal_True;
864cdf0e10cSrcweir 			}
865cdf0e10cSrcweir 			else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR &&
866cdf0e10cSrcweir 				     ( !pSrcNd->GetTable().IsTblComplex() ||
867cdf0e10cSrcweir                        pDestNd->GetTable().IsNewModel() ) )
868cdf0e10cSrcweir 			{
869cdf0e10cSrcweir 				// dann die Tabelle "relativ" kopieren
870cdf0e10cSrcweir 				SwTableBox* pBox = pDestNd->GetTable().GetTblBox(
871cdf0e10cSrcweir 										pSttNd->GetIndex() );
872cdf0e10cSrcweir 				ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
873cdf0e10cSrcweir 				aBoxes.Insert( pBox );
874cdf0e10cSrcweir 			}
875cdf0e10cSrcweir 
876cdf0e10cSrcweir 			SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode());
877cdf0e10cSrcweir 			if( !bParkTblCrsr )
878cdf0e10cSrcweir 			{
879cdf0e10cSrcweir 				// erstmal aus der gesamten Tabelle raus
880cdf0e10cSrcweir // ????? was ist mit Tabelle alleine im Rahmen ???????
881cdf0e10cSrcweir 				SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
882cdf0e10cSrcweir 				SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
883cdf0e10cSrcweir                 // #i59539: Don't remove all redline
884cdf0e10cSrcweir                 SwPaM const tmpPaM(*pDestNd, *pDestNd->EndOfSectionNode());
885cdf0e10cSrcweir                 ::PaMCorrAbs(tmpPaM, aPos);
886cdf0e10cSrcweir 			}
887cdf0e10cSrcweir 
888cdf0e10cSrcweir 			bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
889cdf0e10cSrcweir 											sal_False, sal_False );
890cdf0e10cSrcweir 
891cdf0e10cSrcweir 			if( bParkTblCrsr )
892cdf0e10cSrcweir 				GetCrsr();
893cdf0e10cSrcweir 			else
894cdf0e10cSrcweir 			{
895cdf0e10cSrcweir 				// und wieder in die Box zurueck
896cdf0e10cSrcweir 				aNdIdx = *pSttNd;
897cdf0e10cSrcweir 				SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
898cdf0e10cSrcweir 				SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
899cdf0e10cSrcweir                 // #i59539: Don't remove all redline
900cdf0e10cSrcweir                 SwNode & rNode(PCURCRSR->GetPoint()->nNode.GetNode());
901cdf0e10cSrcweir                 SwCntntNode *const pCntntNode( rNode.GetCntntNode() );
902cdf0e10cSrcweir                 SwPaM const tmpPam(rNode, 0,
903cdf0e10cSrcweir                                    rNode, (pCntntNode) ? pCntntNode->Len() : 0);
904cdf0e10cSrcweir                 ::PaMCorrAbs(tmpPam, aPos);
905cdf0e10cSrcweir 			}
906cdf0e10cSrcweir 
907cdf0e10cSrcweir 			break;		// aus der "while"-Schleife heraus
908cdf0e10cSrcweir 		}
909cdf0e10cSrcweir         else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() &&
910cdf0e10cSrcweir 				 pClpDoc->GetSpzFrmFmts()->Count() )
911cdf0e10cSrcweir 		{
912cdf0e10cSrcweir 			// so langsam sollte mal eine DrawView erzeugt werden
913cdf0e10cSrcweir 			if( !Imp()->GetDrawView() )
914cdf0e10cSrcweir 				MakeDrawView();
915cdf0e10cSrcweir 
916cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
917cdf0e10cSrcweir 			{
918cdf0e10cSrcweir 				sal_Bool bInsWithFmt = sal_True;
919cdf0e10cSrcweir 				const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
920cdf0e10cSrcweir 
921cdf0e10cSrcweir 				if( Imp()->GetDrawView()->IsGroupEntered() &&
922cdf0e10cSrcweir 					RES_DRAWFRMFMT == rCpyFmt.Which() &&
923cdf0e10cSrcweir                     (FLY_AS_CHAR != rCpyFmt.GetAnchor().GetAnchorId()) )
924cdf0e10cSrcweir                 {
925cdf0e10cSrcweir 					const SdrObject* pSdrObj = rCpyFmt.FindSdrObject();
926cdf0e10cSrcweir 					if( pSdrObj )
927cdf0e10cSrcweir 					{
928cdf0e10cSrcweir 						SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj,
929cdf0e10cSrcweir 															sal_False, sal_False );
930cdf0e10cSrcweir 
931cdf0e10cSrcweir                         // Insert object sets any anchor position to 0.
932cdf0e10cSrcweir                         // Therefore we calculate the absolute position here
933cdf0e10cSrcweir                         // and after the insert the anchor of the object
934cdf0e10cSrcweir                         // is set to the anchor of the group object.
935cdf0e10cSrcweir                         Rectangle aSnapRect = pNew->GetSnapRect();
936cdf0e10cSrcweir                         if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() )
937cdf0e10cSrcweir                         {
938cdf0e10cSrcweir                             const Point aPoint( 0, 0 );
939cdf0e10cSrcweir                             // OD 2004-04-05 #i26791# - direct drawing object
940cdf0e10cSrcweir                             // positioning for group members
941cdf0e10cSrcweir                             pNew->NbcSetAnchorPos( aPoint );
942cdf0e10cSrcweir                             pNew->NbcSetSnapRect( aSnapRect );
943cdf0e10cSrcweir                         }
944cdf0e10cSrcweir 
945cdf0e10cSrcweir 						Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() );
946cdf0e10cSrcweir 
947cdf0e10cSrcweir                         Point aGrpAnchor( 0, 0 );
948cdf0e10cSrcweir                         SdrObjList* pList = pNew->GetObjList();
949cdf0e10cSrcweir                         if ( pList )
950cdf0e10cSrcweir                         {
951cdf0e10cSrcweir                             SdrObject* pOwner = pList->GetOwnerObj();
952cdf0e10cSrcweir                             if ( pOwner )
953cdf0e10cSrcweir                             {
954cdf0e10cSrcweir                                 SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner);
955cdf0e10cSrcweir                                 aGrpAnchor = pThisGroup->GetAnchorPos();
956cdf0e10cSrcweir                             }
957cdf0e10cSrcweir                         }
958cdf0e10cSrcweir 
959cdf0e10cSrcweir                         // OD 2004-04-05 #i26791# - direct drawing object
960cdf0e10cSrcweir                         // positioning for group members
961cdf0e10cSrcweir                         pNew->NbcSetAnchorPos( aGrpAnchor );
962cdf0e10cSrcweir                         pNew->SetSnapRect( aSnapRect );
963cdf0e10cSrcweir 
964cdf0e10cSrcweir 						bInsWithFmt = sal_False;
965cdf0e10cSrcweir 					}
966cdf0e10cSrcweir 				}
967cdf0e10cSrcweir 
968cdf0e10cSrcweir 				if( bInsWithFmt  )
969cdf0e10cSrcweir 				{
970cdf0e10cSrcweir 					SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
971cdf0e10cSrcweir                     if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
972cdf0e10cSrcweir                         (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
973cdf0e10cSrcweir                         (FLY_AS_CHAR == aAnchor.GetAnchorId()))
974cdf0e10cSrcweir                     {
975cdf0e10cSrcweir 						SwPosition* pPos = PCURCRSR->GetPoint();
976cdf0e10cSrcweir                         // #108784# allow shapes (no controls) in header/footer
977cdf0e10cSrcweir                         if( RES_DRAWFRMFMT == rCpyFmt.Which() &&
978cdf0e10cSrcweir                             GetDoc()->IsInHeaderFooter( pPos->nNode ) &&
979cdf0e10cSrcweir                             CheckControlLayer( rCpyFmt.FindSdrObject() ) )
980cdf0e10cSrcweir                             continue;
981cdf0e10cSrcweir 
982cdf0e10cSrcweir 						aAnchor.SetAnchor( pPos );
983cdf0e10cSrcweir                     }
984cdf0e10cSrcweir                     else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
985cdf0e10cSrcweir                     {
986cdf0e10cSrcweir 						aAnchor.SetPageNum( GetPhyPageNum() );
987cdf0e10cSrcweir 					}
988cdf0e10cSrcweir 					else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
989cdf0e10cSrcweir 					{
990cdf0e10cSrcweir 						Point aPt;
991cdf0e10cSrcweir 						lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(),
992cdf0e10cSrcweir 										0, aPt, *this, aAnchor, aPt, sal_False );
993cdf0e10cSrcweir 					}
994cdf0e10cSrcweir 
995cdf0e10cSrcweir                     SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
996cdf0e10cSrcweir 
997cdf0e10cSrcweir 					if( pNew )
998cdf0e10cSrcweir 					{
999cdf0e10cSrcweir 						if( RES_FLYFRMFMT == pNew->Which() )
1000cdf0e10cSrcweir 						{
1001cdf0e10cSrcweir 							const Point aPt( GetCrsrDocPos() );
1002cdf0e10cSrcweir 							SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)->
1003cdf0e10cSrcweir 														GetFrm( &aPt, sal_False );
1004cdf0e10cSrcweir 							if( pFlyFrm )
1005cdf0e10cSrcweir 								SelectFlyFrm( *pFlyFrm, sal_True );
1006cdf0e10cSrcweir 							// immer nur den ersten Fly-Frame nehmen; die anderen
1007cdf0e10cSrcweir 							// wurden ueber Fly in Fly ins ClipBoard kopiert !
1008cdf0e10cSrcweir 							break;
1009cdf0e10cSrcweir 						}
1010cdf0e10cSrcweir 						else
1011cdf0e10cSrcweir 						{
1012cdf0e10cSrcweir 							ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format.");
1013cdf0e10cSrcweir                             // --> OD 2005-09-01 #i52780# - drawing object has
1014cdf0e10cSrcweir                             // to be made visible on paste.
1015cdf0e10cSrcweir                             {
1016cdf0e10cSrcweir                                 SwDrawContact* pContact =
1017cdf0e10cSrcweir                                     static_cast<SwDrawContact*>(pNew->FindContactObj());
1018cdf0e10cSrcweir                                 pContact->MoveObjToVisibleLayer( pContact->GetMaster() );
1019cdf0e10cSrcweir                             }
1020cdf0e10cSrcweir                             // <--
1021cdf0e10cSrcweir                             SdrObject *pObj = pNew->FindSdrObject();
1022cdf0e10cSrcweir 							SwDrawView  *pDV = Imp()->GetDrawView();
1023cdf0e10cSrcweir 							pDV->MarkObj( pObj, pDV->GetSdrPageView() );
1024cdf0e10cSrcweir                             // --> OD 2005-04-15 #i47455# - notify draw frame format
1025cdf0e10cSrcweir                             // that position attributes are already set.
1026cdf0e10cSrcweir                             if ( pNew->ISA(SwDrawFrmFmt) )
1027cdf0e10cSrcweir                             {
1028cdf0e10cSrcweir                                 static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet();
1029cdf0e10cSrcweir                             }
1030cdf0e10cSrcweir                             // <--
1031cdf0e10cSrcweir 						}
1032cdf0e10cSrcweir 					}
1033cdf0e10cSrcweir 				}
1034cdf0e10cSrcweir 			}
1035cdf0e10cSrcweir 		}
1036cdf0e10cSrcweir 		else
1037cdf0e10cSrcweir 		{
1038cdf0e10cSrcweir 			if( bDelTbl && IsTableMode() )
1039cdf0e10cSrcweir 			{
1040cdf0e10cSrcweir 				SwEditShell::Delete();
1041cdf0e10cSrcweir 				bDelTbl = sal_False;
1042cdf0e10cSrcweir 			}
1043cdf0e10cSrcweir 
1044cdf0e10cSrcweir 			SwPosition& rInsPos = *PCURCRSR->GetPoint();
1045cdf0e10cSrcweir 			const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().
1046cdf0e10cSrcweir 													FindTableBoxStartNode();
1047cdf0e10cSrcweir 			if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() -
1048cdf0e10cSrcweir 								pBoxNd->GetIndex() &&
1049cdf0e10cSrcweir 				aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode )
1050cdf0e10cSrcweir 			{
1051cdf0e10cSrcweir 				// es wird mehr als 1 Node in die akt. Box kopiert. Dann
1052cdf0e10cSrcweir 				// muessen die BoxAttribute aber entfernt werden.
1053cdf0e10cSrcweir 				GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
1054cdf0e10cSrcweir 			}
1055cdf0e10cSrcweir             //find out if the clipboard document starts with a table
1056cdf0e10cSrcweir             bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
1057cdf0e10cSrcweir             SwPosition aInsertPosition( rInsPos );
1058cdf0e10cSrcweir 
1059cdf0e10cSrcweir             {
1060cdf0e10cSrcweir                 SwNodeIndex aIndexBefore(rInsPos.nNode);
1061cdf0e10cSrcweir 
1062cdf0e10cSrcweir                 aIndexBefore--;
1063cdf0e10cSrcweir 
1064cdf0e10cSrcweir                 pClpDoc->CopyRange( aCpyPam, rInsPos, false );
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir                 {
1067cdf0e10cSrcweir                     aIndexBefore++;
1068cdf0e10cSrcweir                     SwPaM aPaM(SwPosition(aIndexBefore),
1069cdf0e10cSrcweir                                SwPosition(rInsPos.nNode));
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir                     aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
1072cdf0e10cSrcweir                 }
1073cdf0e10cSrcweir             }
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir 			SaveTblBoxCntnt( &rInsPos );
1076cdf0e10cSrcweir             if(bIncludingPageFrames && bStartWithTable)
1077cdf0e10cSrcweir             {
1078cdf0e10cSrcweir                 //remove the paragraph in front of the table
1079cdf0e10cSrcweir                 SwPaM aPara(aInsertPosition);
1080cdf0e10cSrcweir                 GetDoc()->DelFullPara(aPara);
1081cdf0e10cSrcweir             }
1082cdf0e10cSrcweir             //additionally copy page bound frames
1083cdf0e10cSrcweir             if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->Count() )
1084cdf0e10cSrcweir             {
1085cdf0e10cSrcweir                 // create a draw view if necessary
1086cdf0e10cSrcweir                 if( !Imp()->GetDrawView() )
1087cdf0e10cSrcweir                     MakeDrawView();
1088cdf0e10cSrcweir 
1089cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
1090cdf0e10cSrcweir                 {
1091cdf0e10cSrcweir                     sal_Bool bInsWithFmt = sal_True;
1092cdf0e10cSrcweir                     const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
1093cdf0e10cSrcweir                     if( bInsWithFmt  )
1094cdf0e10cSrcweir                     {
1095cdf0e10cSrcweir                         SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1096cdf0e10cSrcweir                         if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
1097cdf0e10cSrcweir                         {
1098cdf0e10cSrcweir                             aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
1099cdf0e10cSrcweir                         }
1100cdf0e10cSrcweir                         else
1101cdf0e10cSrcweir                             continue;
1102cdf0e10cSrcweir                         GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1103cdf0e10cSrcweir                     }
1104cdf0e10cSrcweir                 }
1105cdf0e10cSrcweir             }
1106cdf0e10cSrcweir 		}
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir         FOREACHPAM_END()
1109cdf0e10cSrcweir     }
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir     GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir 	// wurden neue Tabellenformeln eingefuegt ?
1114cdf0e10cSrcweir 	if( pTblFldTyp->GetDepends() )
1115cdf0e10cSrcweir 	{
1116cdf0e10cSrcweir 		// alte Actions beenden; die Tabellen-Frames werden angelegt und
1117cdf0e10cSrcweir 		// eine Selection kann erzeugt werden
1118cdf0e10cSrcweir 		sal_uInt16 nActCnt;
1119cdf0e10cSrcweir 		for( nActCnt = 0; ActionPend(); ++nActCnt )
1120cdf0e10cSrcweir 			EndAllAction();
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir 		for( ; nActCnt; --nActCnt )
1123cdf0e10cSrcweir 			StartAllAction();
1124cdf0e10cSrcweir 	}
1125cdf0e10cSrcweir 	GetDoc()->UnlockExpFlds();
1126cdf0e10cSrcweir 	GetDoc()->UpdateFlds(NULL, false);
1127cdf0e10cSrcweir 	EndAllAction();
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir 	return bRet;
1130cdf0e10cSrcweir }
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir /*-- 14.06.2004 13:31:17---------------------------------------------------
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir   -----------------------------------------------------------------------*/
PastePages(SwFEShell & rToFill,sal_uInt16 nStartPage,sal_uInt16 nEndPage)1135cdf0e10cSrcweir sal_Bool SwFEShell::PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage)
1136cdf0e10cSrcweir {
1137cdf0e10cSrcweir     Push();
1138cdf0e10cSrcweir     if(!GotoPage(nStartPage))
1139cdf0e10cSrcweir     {
1140cdf0e10cSrcweir         Pop(sal_False);
1141cdf0e10cSrcweir         return sal_False;
1142cdf0e10cSrcweir     }
1143cdf0e10cSrcweir     MovePage( fnPageCurr, fnPageStart );
1144cdf0e10cSrcweir     SwPaM aCpyPam( *GetCrsr()->GetPoint() );
1145cdf0e10cSrcweir     String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName();
1146cdf0e10cSrcweir     SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, sal_True );
1147cdf0e10cSrcweir     if( pDesc )
1148cdf0e10cSrcweir         rToFill.ChgCurPageDesc( *pDesc );
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir     if(!GotoPage(nEndPage))
1151cdf0e10cSrcweir     {
1152cdf0e10cSrcweir         Pop(sal_False);
1153cdf0e10cSrcweir         return sal_False;
1154cdf0e10cSrcweir     }
1155cdf0e10cSrcweir     //if the page starts with a table a paragraph has to be inserted before
1156cdf0e10cSrcweir     SwNode* pTableNode = aCpyPam.GetNode()->FindTableNode();
1157cdf0e10cSrcweir     if(pTableNode)
1158cdf0e10cSrcweir     {
1159cdf0e10cSrcweir         //insert a paragraph
1160cdf0e10cSrcweir         StartUndo(UNDO_INSERT);
1161cdf0e10cSrcweir         SwNodeIndex aTblIdx(  *pTableNode, -1 );
1162cdf0e10cSrcweir         SwPosition aBefore(aTblIdx);
1163cdf0e10cSrcweir         if(GetDoc()->AppendTxtNode( aBefore ))
1164cdf0e10cSrcweir         {
1165cdf0e10cSrcweir             SwPaM aTmp(aBefore);
1166cdf0e10cSrcweir             aCpyPam = aTmp;
1167cdf0e10cSrcweir         }
1168cdf0e10cSrcweir         EndUndo(UNDO_INSERT);
1169cdf0e10cSrcweir     }
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir     MovePage( fnPageCurr, fnPageEnd );
1172cdf0e10cSrcweir     aCpyPam.SetMark();
1173cdf0e10cSrcweir     *aCpyPam.GetMark() = *GetCrsr()->GetPoint();
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir     SET_CURR_SHELL( this );
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir     StartAllAction();
1178cdf0e10cSrcweir     GetDoc()->LockExpFlds();
1179cdf0e10cSrcweir     SetSelection(aCpyPam);
1180cdf0e10cSrcweir     // copy the text of the selection
1181cdf0e10cSrcweir     SwEditShell::Copy(&rToFill);
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir     if(pTableNode)
1184cdf0e10cSrcweir     {
1185cdf0e10cSrcweir         //remove the inserted paragraph
1186cdf0e10cSrcweir         Undo();
1187cdf0e10cSrcweir         //remove the paragraph in the second doc, too
1188cdf0e10cSrcweir 	    SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 );
1189cdf0e10cSrcweir 	    SwPaM aPara( aIdx ); //DocStart
1190cdf0e10cSrcweir         rToFill.GetDoc()->DelFullPara(aPara);
1191cdf0e10cSrcweir     }
1192cdf0e10cSrcweir     // now the page bound objects
1193cdf0e10cSrcweir     //additionally copy page bound frames
1194cdf0e10cSrcweir     if( GetDoc()->GetSpzFrmFmts()->Count() )
1195cdf0e10cSrcweir     {
1196cdf0e10cSrcweir         // create a draw view if necessary
1197cdf0e10cSrcweir         if( !rToFill.Imp()->GetDrawView() )
1198cdf0e10cSrcweir             rToFill.MakeDrawView();
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < GetDoc()->GetSpzFrmFmts()->Count(); ++i )
1201cdf0e10cSrcweir         {
1202cdf0e10cSrcweir             const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i];
1203cdf0e10cSrcweir             SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1204cdf0e10cSrcweir             if ((FLY_AT_PAGE == aAnchor.GetAnchorId()) &&
1205cdf0e10cSrcweir                     aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage)
1206cdf0e10cSrcweir             {
1207cdf0e10cSrcweir                 aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1);
1208cdf0e10cSrcweir             }
1209cdf0e10cSrcweir             else
1210cdf0e10cSrcweir                 continue;
1211cdf0e10cSrcweir             rToFill.GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1212cdf0e10cSrcweir         }
1213cdf0e10cSrcweir     }
1214cdf0e10cSrcweir     GetDoc()->UnlockExpFlds();
1215cdf0e10cSrcweir     GetDoc()->UpdateFlds(NULL, false);
1216cdf0e10cSrcweir     Pop(sal_False);
1217cdf0e10cSrcweir     EndAllAction();
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir     return sal_True;
1220cdf0e10cSrcweir }
1221cdf0e10cSrcweir 
GetDrawObjGraphic(sal_uLong nFmt,Graphic & rGrf) const1222cdf0e10cSrcweir sal_Bool SwFEShell::GetDrawObjGraphic( sal_uLong nFmt, Graphic& rGrf ) const
1223cdf0e10cSrcweir {
1224cdf0e10cSrcweir 	ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
1225cdf0e10cSrcweir 	const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1226cdf0e10cSrcweir 	sal_Bool bConvert = sal_True;
1227cdf0e10cSrcweir 	if( rMrkList.GetMarkCount() )
1228cdf0e10cSrcweir 	{
1229cdf0e10cSrcweir 		if( rMrkList.GetMarkCount() == 1 &&
1230cdf0e10cSrcweir 			rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) )
1231cdf0e10cSrcweir 		{
1232cdf0e10cSrcweir 			// Rahmen selektiert
1233cdf0e10cSrcweir 			if( CNT_GRF == GetCntType() )
1234cdf0e10cSrcweir 			{
1235cdf0e10cSrcweir                 // --> OD 2005-02-09 #119353# - robust
1236cdf0e10cSrcweir                 const Graphic* pGrf( GetGraphic() );
1237cdf0e10cSrcweir                 if ( pGrf )
1238cdf0e10cSrcweir                 {
1239cdf0e10cSrcweir                     Graphic aGrf( *pGrf );
1240cdf0e10cSrcweir                     if( SOT_FORMAT_GDIMETAFILE == nFmt )
1241cdf0e10cSrcweir                     {
1242cdf0e10cSrcweir                         if( GRAPHIC_BITMAP != aGrf.GetType() )
1243cdf0e10cSrcweir                         {
1244cdf0e10cSrcweir                             rGrf = aGrf;
1245cdf0e10cSrcweir                             bConvert = sal_False;
1246cdf0e10cSrcweir                         }
1247cdf0e10cSrcweir                         else if( GetWin() )
1248cdf0e10cSrcweir                         {
1249cdf0e10cSrcweir                             Size aSz;
1250cdf0e10cSrcweir                             Point aPt;
1251cdf0e10cSrcweir                             GetGrfSize( aSz );
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir                             VirtualDevice aVirtDev;
1254cdf0e10cSrcweir                             aVirtDev.EnableOutput( sal_False );
1255cdf0e10cSrcweir 
1256cdf0e10cSrcweir                             MapMode aTmp( GetWin()->GetMapMode() );
1257cdf0e10cSrcweir                             aTmp.SetOrigin( aPt );
1258cdf0e10cSrcweir                             aVirtDev.SetMapMode( aTmp );
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir                             GDIMetaFile aMtf;
1261cdf0e10cSrcweir                             aMtf.Record( &aVirtDev );
1262cdf0e10cSrcweir                             aGrf.Draw( &aVirtDev, aPt, aSz );
1263cdf0e10cSrcweir                             aMtf.Stop();
1264cdf0e10cSrcweir                             aMtf.SetPrefMapMode( aTmp );
1265cdf0e10cSrcweir                             aMtf.SetPrefSize( aSz );
1266cdf0e10cSrcweir                             rGrf = aMtf;
1267cdf0e10cSrcweir                         }
1268cdf0e10cSrcweir                     }
1269cdf0e10cSrcweir                     else if( GRAPHIC_BITMAP == aGrf.GetType() )
1270cdf0e10cSrcweir                     {
1271cdf0e10cSrcweir                         rGrf = aGrf;
1272cdf0e10cSrcweir                         bConvert = sal_False;
1273cdf0e10cSrcweir                     }
1274cdf0e10cSrcweir                     else
1275cdf0e10cSrcweir                     {
1276cdf0e10cSrcweir                         //fix(23806): Nicht die Originalgroesse, sondern die
1277cdf0e10cSrcweir                         //aktuelle. Anderfalls kann es passieren, dass z.B. bei
1278cdf0e10cSrcweir                         //Vektorgrafiken mal eben zig MB angefordert werden.
1279cdf0e10cSrcweir                         const Size aSz( FindFlyFrm()->Prt().SSize() );
1280cdf0e10cSrcweir                         VirtualDevice aVirtDev( *GetWin() );
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir                         MapMode aTmp( MAP_TWIP );
1283cdf0e10cSrcweir                         aVirtDev.SetMapMode( aTmp );
1284cdf0e10cSrcweir                         if( aVirtDev.SetOutputSize( aSz ) )
1285cdf0e10cSrcweir                         {
1286cdf0e10cSrcweir                             aGrf.Draw( &aVirtDev, Point(), aSz );
1287cdf0e10cSrcweir                             rGrf = aVirtDev.GetBitmap( Point(), aSz );
1288cdf0e10cSrcweir                         }
1289cdf0e10cSrcweir                         else
1290cdf0e10cSrcweir                         {
1291cdf0e10cSrcweir                             rGrf = aGrf;
1292cdf0e10cSrcweir                             bConvert = sal_False;
1293cdf0e10cSrcweir                         }
1294cdf0e10cSrcweir                     }
1295cdf0e10cSrcweir                 }
1296cdf0e10cSrcweir                 // <--
1297cdf0e10cSrcweir 			}
1298cdf0e10cSrcweir 		}
1299cdf0e10cSrcweir 		else if( SOT_FORMAT_GDIMETAFILE == nFmt )
1300bb18ee55SArmin Le Grand 			rGrf = Imp()->GetDrawView()->GetMarkedObjMetaFile();
1301a206ee71SArmin Le Grand 		else if( SOT_FORMAT_BITMAP == nFmt || SOT_FORMATSTR_ID_PNG == nFmt )
1302bb18ee55SArmin Le Grand 			rGrf = Imp()->GetDrawView()->GetMarkedObjBitmapEx();
1303cdf0e10cSrcweir 	}
1304cdf0e10cSrcweir 	return bConvert;
1305cdf0e10cSrcweir }
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir // --> OD 2005-08-03 #i50824#
1308cdf0e10cSrcweir // --> OD 2006-03-01 #b6382898#
1309cdf0e10cSrcweir // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
lcl_ConvertSdrOle2ObjsToSdrGrafObjs(SdrModel * _pModel)1310cdf0e10cSrcweir void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel )
1311cdf0e10cSrcweir {
1312cdf0e10cSrcweir     for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum )
1313cdf0e10cSrcweir     {
1314cdf0e10cSrcweir         // setup object iterator in order to iterate through all objects
1315cdf0e10cSrcweir         // including objects in group objects, but exclusive group objects.
1316cdf0e10cSrcweir         SdrObjListIter aIter(*(_pModel->GetPage( nPgNum )));
1317cdf0e10cSrcweir         while( aIter.IsMore() )
1318cdf0e10cSrcweir         {
1319cdf0e10cSrcweir             SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
1320cdf0e10cSrcweir             if( pOle2Obj )
1321cdf0e10cSrcweir             {
1322cdf0e10cSrcweir                 // found an ole2 shape
1323cdf0e10cSrcweir                 SdrObjList* pObjList = pOle2Obj->GetObjList();
1324cdf0e10cSrcweir 
1325cdf0e10cSrcweir                 // get its graphic
1326cdf0e10cSrcweir                 Graphic aGraphic;
1327cdf0e10cSrcweir                 pOle2Obj->Connect();
1328cdf0e10cSrcweir                 Graphic* pGraphic = pOle2Obj->GetGraphic();
1329cdf0e10cSrcweir                 if( pGraphic )
1330cdf0e10cSrcweir                     aGraphic = *pGraphic;
1331cdf0e10cSrcweir                 pOle2Obj->Disconnect();
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir                 // create new graphic shape with the ole graphic and shape size
1334cdf0e10cSrcweir                 SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() );
1335cdf0e10cSrcweir                 // apply layer of ole2 shape at graphic shape
1336cdf0e10cSrcweir                 pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
1337cdf0e10cSrcweir 
1338cdf0e10cSrcweir                 // replace ole2 shape with the new graphic object and delete the ol2 shape
1339cdf0e10cSrcweir                 SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() );
1340cdf0e10cSrcweir                 SdrObject::Free( pRemovedObject );
1341cdf0e10cSrcweir             }
1342cdf0e10cSrcweir         }
1343cdf0e10cSrcweir     }
1344cdf0e10cSrcweir }
1345cdf0e10cSrcweir // <--
Paste(SvStream & rStrm,sal_uInt16 nAction,const Point * pPt)1346cdf0e10cSrcweir void SwFEShell::Paste( SvStream& rStrm, sal_uInt16 nAction, const Point* pPt )
1347cdf0e10cSrcweir {
1348cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1349cdf0e10cSrcweir 	StartAllAction();
1350cdf0e10cSrcweir 	StartUndo();
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir 	SvtPathOptions aPathOpt;
1353cdf0e10cSrcweir 	FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(),
1354cdf0e10cSrcweir 											0, GetDoc()->GetDocShell() );
1355cdf0e10cSrcweir 	pModel->GetItemPool().FreezeIdRanges();
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir 	rStrm.Seek(0);
1358cdf0e10cSrcweir 
1359cdf0e10cSrcweir     uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) );
1360cdf0e10cSrcweir 	SvxDrawingLayerImport( pModel, xInputStream );
1361cdf0e10cSrcweir 
1362cdf0e10cSrcweir 	if ( !Imp()->HasDrawView() )
1363cdf0e10cSrcweir 		Imp()->MakeDrawView();
1364cdf0e10cSrcweir 
1365cdf0e10cSrcweir 	Point aPos( pPt ? *pPt : GetCharRect().Pos() );
1366cdf0e10cSrcweir 	SdrView *pView = Imp()->GetDrawView();
1367cdf0e10cSrcweir 
1368cdf0e10cSrcweir 	//Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren.
1369cdf0e10cSrcweir 	if( pModel->GetPageCount() > 0 &&
1370cdf0e10cSrcweir         1 == pModel->GetPage(0)->GetObjCount() &&
1371cdf0e10cSrcweir 		1 == pView->GetMarkedObjectList().GetMarkCount() )
1372cdf0e10cSrcweir 	{
1373cdf0e10cSrcweir         // OD 10.07.2003 #110742# - replace a marked 'virtual' drawing object
1374cdf0e10cSrcweir         // by its corresponding 'master' drawing object in the mark list.
1375cdf0e10cSrcweir         SwDrawView::ReplaceMarkedDrawVirtObjs( *pView );
1376cdf0e10cSrcweir 
1377cdf0e10cSrcweir         SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0);
1378cdf0e10cSrcweir 		SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj();
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir 		if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) )
1381cdf0e10cSrcweir 			nAction = SW_PASTESDR_REPLACE;
1382cdf0e10cSrcweir 
1383cdf0e10cSrcweir 		switch( nAction )
1384cdf0e10cSrcweir 		{
1385cdf0e10cSrcweir 		case SW_PASTESDR_REPLACE:
1386cdf0e10cSrcweir 			{
1387cdf0e10cSrcweir 				const SwFrmFmt* pFmt(0);
1388cdf0e10cSrcweir 				const SwFrm* pAnchor(0);
1389cdf0e10cSrcweir 				if( pOldObj->ISA(SwVirtFlyDrawObj) )
1390cdf0e10cSrcweir 				{
1391cdf0e10cSrcweir 					pFmt = FindFrmFmt( pOldObj );
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir 					Point aNullPt;
1394cdf0e10cSrcweir 					SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt );
1395cdf0e10cSrcweir                     pAnchor = pFlyFrm->GetAnchorFrm();
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir 					if( pAnchor->FindFooterOrHeader() )
1398cdf0e10cSrcweir 					{
1399cdf0e10cSrcweir 						// wenn TextRahmen in der Kopf/Fusszeile steht, dann
1400cdf0e10cSrcweir 						// nicht ersetzen, sondern nur einfuegen
1401cdf0e10cSrcweir 						nAction = SW_PASTESDR_INSERT;
1402cdf0e10cSrcweir 						break;
1403cdf0e10cSrcweir 					}
1404cdf0e10cSrcweir 				}
1405cdf0e10cSrcweir 
1406cdf0e10cSrcweir 				SdrObject* pNewObj = pClpObj->Clone();
1407cdf0e10cSrcweir 				Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() );
1408cdf0e10cSrcweir 				Size aOldObjSize( aOldObjRect.GetSize() );
1409cdf0e10cSrcweir 				Rectangle aNewRect( pNewObj->GetCurrentBoundRect() );
1410cdf0e10cSrcweir 				Size aNewSize( aNewRect.GetSize() );
1411cdf0e10cSrcweir 
1412cdf0e10cSrcweir 				Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() );
1413cdf0e10cSrcweir 				Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height());
1414cdf0e10cSrcweir 				pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight);
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir 				Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft();
1417cdf0e10cSrcweir 				pNewObj->NbcMove(Size(aVec.X(), aVec.Y()));
1418cdf0e10cSrcweir 
1419cdf0e10cSrcweir                 if( pNewObj->ISA( SdrUnoObj ) )
1420cdf0e10cSrcweir                     pNewObj->SetLayer( GetDoc()->GetControlsId() );
1421cdf0e10cSrcweir                 else if( pOldObj->ISA( SdrUnoObj ) )
1422cdf0e10cSrcweir                     pNewObj->SetLayer( GetDoc()->GetHeavenId() );
1423cdf0e10cSrcweir                 else
1424cdf0e10cSrcweir                     pNewObj->SetLayer( pOldObj->GetLayer() );
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir 				if( pOldObj->ISA(SwVirtFlyDrawObj) )
1427cdf0e10cSrcweir 				{
1428cdf0e10cSrcweir 					// Attribute sichern und dam SdrObject setzen
1429cdf0e10cSrcweir 					SfxItemSet aFrmSet( pDoc->GetAttrPool(),
1430cdf0e10cSrcweir 											RES_SURROUND, RES_ANCHOR );
1431cdf0e10cSrcweir 					aFrmSet.Set( pFmt->GetAttrSet() );
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir 					Point aNullPt;
1434cdf0e10cSrcweir 					if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() )
1435cdf0e10cSrcweir 					{
1436cdf0e10cSrcweir 						const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor;
1437cdf0e10cSrcweir 						do {
1438cdf0e10cSrcweir 							pTmp = pTmp->FindMaster();
1439cdf0e10cSrcweir 							ASSERT( pTmp, "Where's my Master?" );
1440cdf0e10cSrcweir 						} while( pTmp->IsFollow() );
1441cdf0e10cSrcweir 						pAnchor = pTmp;
1442cdf0e10cSrcweir 					}
1443cdf0e10cSrcweir 					if( pOldObj->ISA( SdrCaptionObj ))
1444cdf0e10cSrcweir 						aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos();
1445cdf0e10cSrcweir 					else
1446cdf0e10cSrcweir 						aNullPt = aOldObjRect.TopLeft();
1447cdf0e10cSrcweir 
1448cdf0e10cSrcweir                     Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) );
1449cdf0e10cSrcweir                     // OD 2004-04-05 #i26791# - direct positioning of Writer
1450cdf0e10cSrcweir                     // fly frame object for <SwDoc::Insert(..)>
1451cdf0e10cSrcweir                     pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor );
1452cdf0e10cSrcweir                     pNewObj->NbcSetAnchorPos( aNewAnchor );
1453cdf0e10cSrcweir 
1454cdf0e10cSrcweir                     pOldObj->GetOrdNum();
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir 					DelSelectedObj();
1457cdf0e10cSrcweir 
1458*5222b95bSOliver-Rainer Wittmann 					pFmt = GetDoc()->InsertDrawObj( *GetCrsr(), *pNewObj, aFrmSet );
1459cdf0e10cSrcweir 				}
1460cdf0e10cSrcweir 				else
146152f1c2eeSArmin Le Grand                 {
146252f1c2eeSArmin Le Grand                     // #123922#  for handling MasterObject and virtual ones correctly, SW
146352f1c2eeSArmin Le Grand                     // wants us to call ReplaceObject at the page, but that also
146452f1c2eeSArmin Le Grand                     // triggers the same assertion (I tried it), so stay at the view method
146552f1c2eeSArmin Le Grand                     pView->ReplaceObjectAtView(pOldObj, *Imp()->GetPageView(), pNewObj);
146652f1c2eeSArmin Le Grand                 }
1467cdf0e10cSrcweir 			}
1468cdf0e10cSrcweir 			break;
1469cdf0e10cSrcweir 
1470cdf0e10cSrcweir 		case SW_PASTESDR_SETATTR:
1471cdf0e10cSrcweir 			{
1472cdf0e10cSrcweir 				SfxItemSet aSet( GetAttrPool() );
14731cd65da9SArmin Le Grand                 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pClpObj);
14741cd65da9SArmin Le Grand 
14751cd65da9SArmin Le Grand                 if(pSdrGrafObj)
14761cd65da9SArmin Le Grand                 {
14771cd65da9SArmin Le Grand                     SdrObject* pTarget = 0;
14781cd65da9SArmin Le Grand 
14791cd65da9SArmin Le Grand                     if(0 != pView->GetMarkedObjectList().GetMarkCount())
14801cd65da9SArmin Le Grand                     {
14811cd65da9SArmin Le Grand                         // try to get target (if it's at least one, take first)
14821cd65da9SArmin Le Grand                         SdrMark* pMark = pView->GetMarkedObjectList().GetMark(0);
14831cd65da9SArmin Le Grand 
14841cd65da9SArmin Le Grand                         if(pMark)
14851cd65da9SArmin Le Grand                         {
14861cd65da9SArmin Le Grand                             pTarget = pMark->GetMarkedSdrObj();
14871cd65da9SArmin Le Grand                         }
14881cd65da9SArmin Le Grand                     }
14891cd65da9SArmin Le Grand 
14901cd65da9SArmin Le Grand                     if(pTarget)
14911cd65da9SArmin Le Grand                     {
14921cd65da9SArmin Le Grand                         // copy ItemSet from target
14931cd65da9SArmin Le Grand                         aSet.Set(pTarget->GetMergedItemSet());
14941cd65da9SArmin Le Grand                     }
14951cd65da9SArmin Le Grand 
14961cd65da9SArmin Le Grand                     // for SdrGrafObj, use the graphic as fill style argument
14971cd65da9SArmin Le Grand                     const Graphic& rGraphic = pSdrGrafObj->GetGraphic();
14981cd65da9SArmin Le Grand 
14991cd65da9SArmin Le Grand                     if(GRAPHIC_NONE != rGraphic.GetType() && GRAPHIC_DEFAULT != rGraphic.GetType())
15001cd65da9SArmin Le Grand                     {
15011cd65da9SArmin Le Grand                         aSet.Put(XFillBitmapItem(String(), rGraphic));
15021cd65da9SArmin Le Grand                         aSet.Put(XFillStyleItem(XFILL_BITMAP));
15031cd65da9SArmin Le Grand                     }
15041cd65da9SArmin Le Grand                 }
15051cd65da9SArmin Le Grand                 else
15061cd65da9SArmin Le Grand                 {
15071cd65da9SArmin Le Grand                     aSet.Put(pClpObj->GetMergedItemSet());
15081cd65da9SArmin Le Grand                 }
15091cd65da9SArmin Le Grand 
1510cdf0e10cSrcweir 				pView->SetAttributes( aSet, sal_False );
1511cdf0e10cSrcweir 			}
1512cdf0e10cSrcweir 			break;
1513cdf0e10cSrcweir 
1514cdf0e10cSrcweir 		default:
1515cdf0e10cSrcweir 			nAction = SW_PASTESDR_INSERT;
1516cdf0e10cSrcweir 			break;
1517cdf0e10cSrcweir 		}
1518cdf0e10cSrcweir 	}
1519cdf0e10cSrcweir 	else
1520cdf0e10cSrcweir 		nAction = SW_PASTESDR_INSERT;
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir 	if( SW_PASTESDR_INSERT == nAction )
1523cdf0e10cSrcweir     {
1524cdf0e10cSrcweir         ::sw::DrawUndoGuard drawUndoGuard(GetDoc()->GetIDocumentUndoRedo());
1525cdf0e10cSrcweir 
1526cdf0e10cSrcweir         sal_Bool bDesignMode = pView->IsDesignMode();
1527cdf0e10cSrcweir         if( !bDesignMode )
1528cdf0e10cSrcweir             pView->SetDesignMode( sal_True );
1529cdf0e10cSrcweir 
1530cdf0e10cSrcweir         // --> OD 2005-08-03 #i50824#
1531cdf0e10cSrcweir         // --> OD 2006-03-01 #b6382898#
1532cdf0e10cSrcweir         // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1533cdf0e10cSrcweir         lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel );
1534cdf0e10cSrcweir         // <--
1535cdf0e10cSrcweir         pView->Paste( *pModel, aPos );
1536cdf0e10cSrcweir 
1537cdf0e10cSrcweir 		sal_uLong nCnt = pView->GetMarkedObjectList().GetMarkCount();
1538cdf0e10cSrcweir 		if( nCnt )
1539cdf0e10cSrcweir 		{
1540cdf0e10cSrcweir 			const Point aNull( 0, 0 );
1541cdf0e10cSrcweir 			for( sal_uLong i=0; i < nCnt; ++i )
1542cdf0e10cSrcweir 			{
1543cdf0e10cSrcweir 				SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
1544cdf0e10cSrcweir 				pObj->ImpSetAnchorPos( aNull );
1545cdf0e10cSrcweir 			}
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir 			pView->SetCurrentObj( OBJ_GRUP, SdrInventor );
1548cdf0e10cSrcweir 			if ( nCnt > 1 )
1549cdf0e10cSrcweir 				pView->GroupMarked();
1550cdf0e10cSrcweir 			SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1551cdf0e10cSrcweir             if( pObj->ISA( SdrUnoObj ) )
1552cdf0e10cSrcweir             {
1553cdf0e10cSrcweir                 pObj->SetLayer( GetDoc()->GetControlsId() );
1554cdf0e10cSrcweir                 bDesignMode = sal_True;
1555cdf0e10cSrcweir             }
1556cdf0e10cSrcweir             else
1557cdf0e10cSrcweir                 pObj->SetLayer( GetDoc()->GetHeavenId() );
1558cdf0e10cSrcweir 			const Rectangle &rSnap = pObj->GetSnapRect();
1559cdf0e10cSrcweir 			const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 );
1560cdf0e10cSrcweir 			pView->MoveMarkedObj( aDiff );
1561cdf0e10cSrcweir 			ImpEndCreate();
1562cdf0e10cSrcweir             if( !bDesignMode )
1563cdf0e10cSrcweir                 pView->SetDesignMode( sal_False );
1564cdf0e10cSrcweir 		}
1565cdf0e10cSrcweir 	}
1566cdf0e10cSrcweir 	EndUndo();
1567cdf0e10cSrcweir 	EndAllAction();
1568cdf0e10cSrcweir 	delete pModel;
1569cdf0e10cSrcweir }
1570cdf0e10cSrcweir 
Paste(const Graphic & rGrf,const String & rURL)157152f1c2eeSArmin Le Grand bool SwFEShell::Paste( const Graphic &rGrf, const String& rURL )
1572cdf0e10cSrcweir {
157352f1c2eeSArmin Le Grand     SET_CURR_SHELL( this );
157452f1c2eeSArmin Le Grand     SdrObject* pObj = 0;
157552f1c2eeSArmin Le Grand     SdrView *pView = Imp()->GetDrawView();
1576cdf0e10cSrcweir 
157752f1c2eeSArmin Le Grand     sal_Bool bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() &&
157852f1c2eeSArmin Le Grand         (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() &&
157952f1c2eeSArmin Le Grand         !pObj->ISA( SdrOle2Obj );
1580cdf0e10cSrcweir 
158152f1c2eeSArmin Le Grand     if( bRet && pObj )
158252f1c2eeSArmin Le Grand     {
158352f1c2eeSArmin Le Grand         // #123922# added code to handle the two cases of SdrGrafObj and a fillable, non-
158452f1c2eeSArmin Le Grand         // OLE object in focus
158552f1c2eeSArmin Le Grand         SdrObject* pResult = pObj;
158670d3707aSArmin Le Grand 
158752f1c2eeSArmin Le Grand         if(dynamic_cast< SdrGrafObj* >(pObj))
158852f1c2eeSArmin Le Grand         {
158952f1c2eeSArmin Le Grand             SdrGrafObj* pNewGrafObj = (SdrGrafObj*)pObj->Clone();
159052f1c2eeSArmin Le Grand 
159152f1c2eeSArmin Le Grand             pNewGrafObj->SetGraphic(rGrf);
159252f1c2eeSArmin Le Grand 
159352f1c2eeSArmin Le Grand             // #123922#  for handling MasterObject and virtual ones correctly, SW
159452f1c2eeSArmin Le Grand             // wants us to call ReplaceObject at the page, but that also
159552f1c2eeSArmin Le Grand             // triggers the same assertion (I tried it), so stay at the view method
159652f1c2eeSArmin Le Grand             pView->ReplaceObjectAtView(pObj, *pView->GetSdrPageView(), pNewGrafObj);
159752f1c2eeSArmin Le Grand 
159852f1c2eeSArmin Le Grand             // set in all cases - the Clone() will have copied an existing link (!)
159952f1c2eeSArmin Le Grand             pNewGrafObj->SetGraphicLink(rURL, String());
160052f1c2eeSArmin Le Grand 
160152f1c2eeSArmin Le Grand             pResult = pNewGrafObj;
160252f1c2eeSArmin Le Grand         }
160352f1c2eeSArmin Le Grand         else
160452f1c2eeSArmin Le Grand         {
160552f1c2eeSArmin Le Grand             pView->AddUndo(new SdrUndoAttrObj(*pObj));
160652f1c2eeSArmin Le Grand 
160752f1c2eeSArmin Le Grand             SfxItemSet aSet(pView->GetModel()->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP);
160852f1c2eeSArmin Le Grand 
160952f1c2eeSArmin Le Grand             aSet.Put(XFillStyleItem(XFILL_BITMAP));
161052f1c2eeSArmin Le Grand             aSet.Put(XFillBitmapItem(String(), rGrf));
161152f1c2eeSArmin Le Grand             pObj->SetMergedItemSetAndBroadcast(aSet);
161252f1c2eeSArmin Le Grand         }
161352f1c2eeSArmin Le Grand 
161452f1c2eeSArmin Le Grand         // we are done; mark the modified/new object
161552f1c2eeSArmin Le Grand         pView->MarkObj(pResult, pView->GetSdrPageView());
161652f1c2eeSArmin Le Grand     }
161752f1c2eeSArmin Le Grand 
161852f1c2eeSArmin Le Grand     return bRet;
1619cdf0e10cSrcweir }
1620