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