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