xref: /aoo42x/main/sw/source/core/frmedt/fecopy.cxx (revision 870262e3)
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 #include <svx/svdundo.hxx>
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 
Copy(SwDoc * pClpDoc,const String * pNewClpTxt)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->InsertDrawObj(aTemp, *pNew, aSet );
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 
lcl_FindBasePos(const SwFrm * pFrm,const Point & rPt)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 
lcl_SetAnchor(const SwPosition & rPos,const SwNode & rNd,SwFlyFrm * pFly,const Point & rInsPt,SwFEShell & rDestShell,SwFmtAnchor & rAnchor,Point & rNewPos,sal_Bool bCheckFlyRecur)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 
CopyDrawSel(SwFEShell * pDestShell,const Point & rSttPt,const Point & rInsPt,sal_Bool bIsMove,sal_Bool bSelectInsert)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->InsertDrawObj( *pDestShell->GetCrsr(), *pNew, aSet );
400 				}
401 				else
402                     pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
403 
404 				//Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind.
405 				if ( pFmt )
406 				{
407                     SdrObject* pNew = pFmt->FindSdrObject();
408                     if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
409                     {
410 						Point aPos( rInsPt );
411 						aPos -= aNewAnch;
412 						aPos -= rSttPt - pObj->GetSnapRect().TopLeft();
413                         // OD 2004-04-05 #i26791# - change attributes instead of
414                         // direct positioning
415                         pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
416                         pFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
417                         // --> OD 2005-04-15 #i47455# - notify draw frame format
418                         // that position attributes are already set.
419                         if ( pFmt->ISA(SwDrawFrmFmt) )
420                         {
421                             static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet();
422                         }
423                         // <--
424                     }
425 					if( bSelectInsert )
426 						pDestDrwView->MarkObj( pNew, pDestPgView );
427 				}
428 			}
429 		}
430 	}
431 
432 	if ( bIsMove && bRet )
433 	{
434 		if( pDestShell == this )
435 		{
436 			const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() );
437 			pSrcDrwView->UnmarkAll();
438 
439             sal_uLong nMrkCnt = aMrkList.GetMarkCount();
440 			sal_uInt16 i;
441             for ( i = 0; i < nMrkCnt; ++i )
442 			{
443 				SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
444 				pSrcDrwView->MarkObj( pObj, pSrcPgView );
445 			}
446 			DelSelectedObj();
447             nMrkCnt = aList.GetMarkCount();
448             for ( i = 0; i < nMrkCnt; ++i )
449 			{
450 				SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj();
451 				pSrcDrwView->MarkObj( pObj, pSrcPgView );
452 			}
453 		}
454 		else
455 			DelSelectedObj();
456 	}
457 
458 	return bRet;
459 }
460 
Copy(SwFEShell * pDestShell,const Point & rSttPt,const Point & rInsPt,sal_Bool bIsMove,sal_Bool bSelectInsert)461 sal_Bool SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
462 					const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert )
463 {
464 	sal_Bool bRet = sal_False;
465 
466 	ASSERT( pDestShell, "Copy ohne DestShell." );
467 	ASSERT( this == pDestShell || !pDestShell->IsObjSelected(),
468 			"Dest-Shell darf nie im Obj-Modus sein" );
469 
470 	SET_CURR_SHELL( pDestShell );
471 
472 	pDestShell->StartAllAction();
473 	pDestShell->GetDoc()->LockExpFlds();
474 
475 	// Referenzen sollen verschoben werden.
476 	sal_Bool bCopyIsMove = pDoc->IsCopyIsMove();
477 	if( bIsMove )
478 		// am Doc ein Flag setzen, damit in den TextNodes
479 		pDoc->SetCopyIsMove( sal_True );
480 
481 	RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode();
482 	pDestShell->GetDoc()->SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES));
483 
484 	// sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
485 	// angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
486 	// kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
487 	// besorgt)
488 	SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD );
489 
490 	if( IsFrmSelected() )
491 	{
492 		SwFlyFrm* pFly = FindFlyFrm();
493 		SwFrmFmt* pFlyFmt = pFly->GetFmt();
494 		SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
495 		bRet = sal_True;
496 		Point aNewAnch;
497 
498         if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
499             (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
500             (FLY_AT_FLY  == aAnchor.GetAnchorId()) ||
501             (FLY_AS_CHAR == aAnchor.GetAnchorId()))
502         {
503 			if ( this == pDestShell )
504 			{
505 				// gleiche Shell? Dann erfrage die Position an der
506 				// uebergebenen DokumentPosition
507 				SwPosition aPos( *GetCrsr()->GetPoint() );
508 				Point aPt( rInsPt );
509 				aPt -= rSttPt - pFly->Frm().Pos();
510 				SwCrsrMoveState aState( MV_SETONLYTEXT );
511 				GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
512 				const SwNode *pNd;
513 				if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
514 					bRet = sal_False;
515 				else
516 				{	//Nicht in sich selbst kopieren
517 					const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
518 					if ( aPos.nNode > *pTmp && aPos.nNode <
519 						pTmp->GetNode().EndOfSectionIndex() )
520 					{
521 						bRet = sal_False;
522 					}
523 					else
524 						bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
525 										*pDestShell, aAnchor, aNewAnch, sal_True );
526 				}
527 			}
528 			else
529 			{
530 				const SwPaM *pCrsr = pDestShell->GetCrsr();
531 				if( pCrsr->GetNode()->IsNoTxtNode() )
532 					bRet = sal_False;
533 				else
534 					bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(),
535 											pFly, rInsPt, *pDestShell, aAnchor,
536 									aNewAnch, GetDoc() == pDestShell->GetDoc());
537 			}
538 		}
539         else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
540         {
541 			aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
542             const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
543             const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
544             if ( pPg )
545                 aNewAnch = pPg->Frm().Pos();
546         }
547 		else {
548 			ASSERT( sal_False, "what kind of anchor is it?" );
549         }
550 
551 		if( bRet )
552 		{
553 			SwFrmFmt *pOldFmt = pFlyFmt;
554             pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
555 
556             if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
557             {
558 				Point aPos( rInsPt );
559 				aPos -= aNewAnch;
560 				aPos -= rSttPt - pFly->Frm().Pos();
561                 pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
562                 pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
563 			}
564 
565 			const Point aPt( pDestShell->GetCrsrDocPos() );
566 
567 			if( bIsMove )
568 				GetDoc()->DelLayoutFmt( pOldFmt );
569 
570 			// nur selektieren wenn es in der gleichen Shell verschoben/
571 			//	kopiert wird
572 			if( bSelectInsert )
573 			{
574 				SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, sal_False );
575 				if( pFlyFrm )
576 				{
577 					//JP 12.05.98: sollte das nicht im SelectFlyFrm stehen???
578 					pDestShell->Imp()->GetDrawView()->UnmarkAll();
579 					pDestShell->SelectFlyFrm( *pFlyFrm, sal_True );
580 				}
581 			}
582 
583 			if( this != pDestShell && !pDestShell->HasShFcs() )
584 				pDestShell->Imp()->GetDrawView()->hideMarkHandles();
585 		}
586 	}
587 	else if ( IsObjSelected() )
588 		bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert );
589 	else if( IsTableMode() )
590 	{
591 		// kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
592 		// von der Originalen an und kopiere die selectierten Boxen.
593 		// Die Groessen werden prozentual korrigiert.
594 
595 		// lasse ueber das Layout die Boxen suchen
596 		const SwTableNode* pTblNd;
597 		SwSelBoxes aBoxes;
598 		GetTblSel( *this, aBoxes );
599 		if( aBoxes.Count() &&
600 			0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) )
601 		{
602 			SwPosition* pDstPos = 0;
603 			if( this == pDestShell )
604 			{
605 				// gleiche Shell? Dann erzeuge einen Crsr an der
606 				// uebergebenen DokumentPosition
607 				pDstPos = new SwPosition( *GetCrsr()->GetPoint() );
608 				Point aPt( rInsPt );
609 				GetLayout()->GetCrsrOfst( pDstPos, aPt );
610 				if( !pDstPos->nNode.GetNode().IsNoTxtNode() )
611 					bRet = sal_True;
612 			}
613 			else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
614 			{
615 				pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
616 				bRet = sal_True;
617 			}
618 
619 			if( bRet )
620 			{
621 				if( GetDoc() == pDestShell->GetDoc() )
622 					ParkTblCrsr();
623 
624 				bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0,
625 										bIsMove && this == pDestShell &&
626 										aBoxes.Count() == pTblNd->GetTable().
627 										GetTabSortBoxes().Count(),
628 										this != pDestShell );
629 
630 				if( this != pDestShell )
631 					*pDestShell->GetCrsr()->GetPoint() = *pDstPos;
632 
633 				// wieder alle geparkten Crsr erzeugen?
634 				if( GetDoc() == pDestShell->GetDoc() )
635 					GetCrsr();
636 
637 				// JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte
638 				//				Cursor auf die EinfuegePos. positioniert wird
639 				if( this == pDestShell )
640 					GetCrsrDocPos() = rInsPt;
641 			}
642 			delete pDstPos;
643 		}
644 	}
645 	else
646 	{
647 		bRet = sal_True;
648 		if( this == pDestShell )
649 		{
650 			// gleiche Shell? Dann erfrage die Position an der
651 			// uebergebenen DokumentPosition
652 			SwPosition aPos( *GetCrsr()->GetPoint() );
653 			Point aPt( rInsPt );
654 			GetLayout()->GetCrsrOfst( &aPos, aPt );
655 			bRet = !aPos.nNode.GetNode().IsNoTxtNode();
656 		}
657 		else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
658 			bRet = sal_False;
659 
660 		if( bRet )
661 			bRet = 0 != SwEditShell::Copy( pDestShell );
662 	}
663 
664 	pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode );
665 	pDoc->SetCopyIsMove( bCopyIsMove );
666 
667 	// wurden neue Tabellenformeln eingefuegt ?
668 	if( pTblFldTyp->GetDepends() )
669 	{
670 		// alte Actions beenden; die Tabellen-Frames werden angelegt und
671 		// eine SSelection kann erzeugt werden
672 		sal_uInt16 nActCnt;
673 		for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt )
674 			pDestShell->EndAllAction();
675 
676 		for( ; nActCnt; --nActCnt )
677 			pDestShell->StartAllAction();
678 	}
679 	pDestShell->GetDoc()->UnlockExpFlds();
680 	pDestShell->GetDoc()->UpdateFlds(NULL, false);
681 
682 	pDestShell->EndAllAction();
683 	return bRet;
684 }
685 
686 /*************************************************************************
687 |*
688 |*	SwFEShell::Paste()	Paste fuer das Interne Clipboard.
689 |*		Kopiert den Inhalt vom Clipboard in das Dokument.
690 |*
691 |*	Ersterstellung		JP ??
692 |*	Letzte Aenderung	MA 22. Feb. 95
693 |
694 |*************************************************************************/
695 
696 namespace {
697     typedef boost::shared_ptr<SwPaM> PaMPtr;
698     typedef boost::shared_ptr<SwPosition> PositionPtr;
699     typedef std::pair< PaMPtr, PositionPtr > Insertion;
700 }
701 
Paste(SwDoc * pClpDoc,sal_Bool bIncludingPageFrames)702 sal_Bool SwFEShell::Paste( SwDoc* pClpDoc, sal_Bool bIncludingPageFrames )
703 {
704 	SET_CURR_SHELL( this );
705 	ASSERT( pClpDoc, "kein Clipboard-Dokument"	);
706     const sal_uInt16 nStartPageNumber = GetPhyPageNum();
707 	// dann bis zum Ende vom Nodes Array
708 	SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
709 	SwPaM aCpyPam( aIdx ); //DocStart
710 
711 	// sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
712 	// angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
713 	// kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
714 	// besorgt)
715 	SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
716 
717 	SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode();
718 	if( !pSrcNd )								// TabellenNode ?
719 	{											// nicht ueberspringen!!
720 		SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode();
721 		if( pCNd )
722 			aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 );
723 		else if( !aCpyPam.Move( fnMoveForward, fnGoNode ))
724 			aCpyPam.Move( fnMoveBackward, fnGoNode );
725 	}
726 
727 	aCpyPam.SetMark();
728 	aCpyPam.Move( fnMoveForward, fnGoDoc );
729 
730 	sal_Bool bRet = sal_True, bDelTbl = sal_True;
731 	StartAllAction();
732     GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
733 	GetDoc()->LockExpFlds();
734 
735     // When the clipboard content has been created by a rectangular selection
736     // the pasting is more sophisticated:
737     // every paragraph will be inserted into another position.
738     // The first positions are given by the actual cursor ring,
739     // if there are more text portions to insert than cursor in this ring,
740     // the additional insert positions will be created by moving the last
741     // cursor position into the next line (like pressing the cursor down key)
742     if( pClpDoc->IsColumnSelection() && !IsTableMode() )
743     {
744         // Creation of the list of insert positions
745         std::list< Insertion > aCopyList;
746         // The number of text portions of the rectangular selection
747         const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex()
748                        - aCpyPam.GetMark()->nNode.GetIndex();
749         sal_uInt32 nCount = nSelCount;
750         SwNodeIndex aClpIdx( aIdx );
751         SwPaM* pStartCursor = GetCrsr();
752         SwPaM* pCurrCrsr = pStartCursor;
753         sal_uInt32 nCursorCount = pStartCursor->numberOf();
754         // If the target selection is a multi-selection, often the last and first
755         // cursor of the ring points to identical document positions. Then
756         // we should avoid double insertion of text portions...
757         while( nCursorCount > 1 && *pCurrCrsr->GetPoint() ==
758             *(dynamic_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) )
759         {
760             --nCursorCount;
761             pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
762             pStartCursor = pCurrCrsr;
763         }
764         SwPosition aStartPos( *pStartCursor->GetPoint() );
765         SwPosition aInsertPos( aStartPos ); // first insertion position
766         bool bCompletePara = false;
767         sal_uInt16 nMove = 0;
768         while( nCount )
769         {
770             --nCount;
771             ASSERT( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" )
772             if( aIdx.GetNode().GetCntntNode() ) // robust
773             {
774                 Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ),
775                     PositionPtr( new SwPosition( aInsertPos ) ) );
776                 ++aIdx;
777                 aInsertion.first->SetMark();
778                 if( pStartCursor == pCurrCrsr->GetNext() )
779                 {   // Now we have to look for insertion positions...
780                     if( !nMove ) // Annotate the last given insert position
781                         aStartPos = aInsertPos;
782                     SwCursor aCrsr( aStartPos, 0, false);
783                     // Check if we find another insert position by moving
784                     // down the last given position
785                     if( aCrsr.UpDown( sal_False, ++nMove, 0, 0 ) )
786                         aInsertPos = *aCrsr.GetPoint();
787                     else // if there is no paragraph we have to create it
788                         bCompletePara = nCount > 0;
789                     nCursorCount = 0;
790                 }
791                 else // as long as we find more insert positions in the cursor ring
792                 {    // we'll take them
793                     pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
794                     aInsertPos = *pCurrCrsr->GetPoint();
795                     --nCursorCount;
796                 }
797                 // If there are no more paragraphs e.g. at the end of a document,
798                 // we insert complete paragraphs instead of text portions
799                 if( bCompletePara )
800                     aInsertion.first->GetPoint()->nNode = aIdx;
801                 else
802                     aInsertion.first->GetPoint()->nContent =
803                         aInsertion.first->GetCntntNode()->Len();
804                 aCopyList.push_back( aInsertion );
805             }
806             // If there are no text portions left but there are some more
807             // cursor positions to fill we have to restart with the first
808             // text portion
809             if( !nCount && nCursorCount )
810             {
811                 nCount = std::min( nSelCount, nCursorCount );
812                 aIdx = aClpIdx; // Start of clipboard content
813             }
814         }
815         std::list< Insertion >::const_iterator pCurr = aCopyList.begin();
816         std::list< Insertion >::const_iterator pEnd = aCopyList.end();
817         while( pCurr != pEnd )
818         {
819             SwPosition& rInsPos = *pCurr->second;
820             SwPaM& rCopy = *pCurr->first;
821             const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
822             if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() &&
823                 rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode )
824             {
825                 // if more than one node will be copied into a cell
826                 // the box attributes have to be removed
827                 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
828             }
829             {
830                 SwNodeIndex aIndexBefore(rInsPos.nNode);
831                 aIndexBefore--;
832                 pClpDoc->CopyRange( rCopy, rInsPos, false );
833                 {
834                     aIndexBefore++;
835                     SwPaM aPaM(SwPosition(aIndexBefore),
836                                SwPosition(rInsPos.nNode));
837                     aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
838                 }
839             }
840             SaveTblBoxCntnt( &rInsPos );
841             ++pCurr;
842         }
843     }
844     else
845     {
846         FOREACHPAM_START(this)
847 
848         if( pSrcNd &&
849 			0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode )))
850 		{
851 			SwPosition aDestPos( *PCURCRSR->GetPoint() );
852 
853 			sal_Bool bParkTblCrsr = sal_False;
854 			const SwStartNode* pSttNd =  PCURCRSR->GetNode()->FindTableBoxStartNode();
855 
856             // TABLE IN TABLE: Tabelle in Tabelle kopieren
857 			// lasse ueber das Layout die Boxen suchen
858 			SwSelBoxes aBoxes;
859 			if( IsTableMode() )		// Tabellen-Selecktion ??
860 			{
861 				GetTblSel( *this, aBoxes );
862 				ParkTblCrsr();
863 				bParkTblCrsr = sal_True;
864 			}
865 			else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR &&
866 				     ( !pSrcNd->GetTable().IsTblComplex() ||
867                        pDestNd->GetTable().IsNewModel() ) )
868 			{
869 				// dann die Tabelle "relativ" kopieren
870 				SwTableBox* pBox = pDestNd->GetTable().GetTblBox(
871 										pSttNd->GetIndex() );
872 				ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
873 				aBoxes.Insert( pBox );
874 			}
875 
876 			SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode());
877 			if( !bParkTblCrsr )
878 			{
879 				// erstmal aus der gesamten Tabelle raus
880 // ????? was ist mit Tabelle alleine im Rahmen ???????
881 				SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
882 				SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
883                 // #i59539: Don't remove all redline
884                 SwPaM const tmpPaM(*pDestNd, *pDestNd->EndOfSectionNode());
885                 ::PaMCorrAbs(tmpPaM, aPos);
886 			}
887 
888 			bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
889 											sal_False, sal_False );
890 
891 			if( bParkTblCrsr )
892 				GetCrsr();
893 			else
894 			{
895 				// und wieder in die Box zurueck
896 				aNdIdx = *pSttNd;
897 				SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
898 				SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
899                 // #i59539: Don't remove all redline
900                 SwNode & rNode(PCURCRSR->GetPoint()->nNode.GetNode());
901                 SwCntntNode *const pCntntNode( rNode.GetCntntNode() );
902                 SwPaM const tmpPam(rNode, 0,
903                                    rNode, (pCntntNode) ? pCntntNode->Len() : 0);
904                 ::PaMCorrAbs(tmpPam, aPos);
905 			}
906 
907 			break;		// aus der "while"-Schleife heraus
908 		}
909         else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() &&
910 				 pClpDoc->GetSpzFrmFmts()->Count() )
911 		{
912 			// so langsam sollte mal eine DrawView erzeugt werden
913 			if( !Imp()->GetDrawView() )
914 				MakeDrawView();
915 
916             for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
917 			{
918 				sal_Bool bInsWithFmt = sal_True;
919 				const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
920 
921 				if( Imp()->GetDrawView()->IsGroupEntered() &&
922 					RES_DRAWFRMFMT == rCpyFmt.Which() &&
923                     (FLY_AS_CHAR != rCpyFmt.GetAnchor().GetAnchorId()) )
924                 {
925 					const SdrObject* pSdrObj = rCpyFmt.FindSdrObject();
926 					if( pSdrObj )
927 					{
928 						SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj,
929 															sal_False, sal_False );
930 
931                         // Insert object sets any anchor position to 0.
932                         // Therefore we calculate the absolute position here
933                         // and after the insert the anchor of the object
934                         // is set to the anchor of the group object.
935                         Rectangle aSnapRect = pNew->GetSnapRect();
936                         if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() )
937                         {
938                             const Point aPoint( 0, 0 );
939                             // OD 2004-04-05 #i26791# - direct drawing object
940                             // positioning for group members
941                             pNew->NbcSetAnchorPos( aPoint );
942                             pNew->NbcSetSnapRect( aSnapRect );
943                         }
944 
945 						Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() );
946 
947                         Point aGrpAnchor( 0, 0 );
948                         SdrObjList* pList = pNew->GetObjList();
949                         if ( pList )
950                         {
951                             SdrObject* pOwner = pList->GetOwnerObj();
952                             if ( pOwner )
953                             {
954                                 SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner);
955                                 aGrpAnchor = pThisGroup->GetAnchorPos();
956                             }
957                         }
958 
959                         // OD 2004-04-05 #i26791# - direct drawing object
960                         // positioning for group members
961                         pNew->NbcSetAnchorPos( aGrpAnchor );
962                         pNew->SetSnapRect( aSnapRect );
963 
964 						bInsWithFmt = sal_False;
965 					}
966 				}
967 
968 				if( bInsWithFmt  )
969 				{
970 					SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
971                     if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
972                         (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
973                         (FLY_AS_CHAR == aAnchor.GetAnchorId()))
974                     {
975 						SwPosition* pPos = PCURCRSR->GetPoint();
976                         // #108784# allow shapes (no controls) in header/footer
977                         if( RES_DRAWFRMFMT == rCpyFmt.Which() &&
978                             GetDoc()->IsInHeaderFooter( pPos->nNode ) &&
979                             CheckControlLayer( rCpyFmt.FindSdrObject() ) )
980                             continue;
981 
982 						aAnchor.SetAnchor( pPos );
983                     }
984                     else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
985                     {
986 						aAnchor.SetPageNum( GetPhyPageNum() );
987 					}
988 					else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
989 					{
990 						Point aPt;
991 						lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(),
992 										0, aPt, *this, aAnchor, aPt, sal_False );
993 					}
994 
995                     SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
996 
997 					if( pNew )
998 					{
999 						if( RES_FLYFRMFMT == pNew->Which() )
1000 						{
1001 							const Point aPt( GetCrsrDocPos() );
1002 							SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)->
1003 														GetFrm( &aPt, sal_False );
1004 							if( pFlyFrm )
1005 								SelectFlyFrm( *pFlyFrm, sal_True );
1006 							// immer nur den ersten Fly-Frame nehmen; die anderen
1007 							// wurden ueber Fly in Fly ins ClipBoard kopiert !
1008 							break;
1009 						}
1010 						else
1011 						{
1012 							ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format.");
1013                             // --> OD 2005-09-01 #i52780# - drawing object has
1014                             // to be made visible on paste.
1015                             {
1016                                 SwDrawContact* pContact =
1017                                     static_cast<SwDrawContact*>(pNew->FindContactObj());
1018                                 pContact->MoveObjToVisibleLayer( pContact->GetMaster() );
1019                             }
1020                             // <--
1021                             SdrObject *pObj = pNew->FindSdrObject();
1022 							SwDrawView  *pDV = Imp()->GetDrawView();
1023 							pDV->MarkObj( pObj, pDV->GetSdrPageView() );
1024                             // --> OD 2005-04-15 #i47455# - notify draw frame format
1025                             // that position attributes are already set.
1026                             if ( pNew->ISA(SwDrawFrmFmt) )
1027                             {
1028                                 static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet();
1029                             }
1030                             // <--
1031 						}
1032 					}
1033 				}
1034 			}
1035 		}
1036 		else
1037 		{
1038 			if( bDelTbl && IsTableMode() )
1039 			{
1040 				SwEditShell::Delete();
1041 				bDelTbl = sal_False;
1042 			}
1043 
1044 			SwPosition& rInsPos = *PCURCRSR->GetPoint();
1045 			const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().
1046 													FindTableBoxStartNode();
1047 			if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() -
1048 								pBoxNd->GetIndex() &&
1049 				aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode )
1050 			{
1051 				// es wird mehr als 1 Node in die akt. Box kopiert. Dann
1052 				// muessen die BoxAttribute aber entfernt werden.
1053 				GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
1054 			}
1055             //find out if the clipboard document starts with a table
1056             bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
1057             SwPosition aInsertPosition( rInsPos );
1058 
1059             {
1060                 SwNodeIndex aIndexBefore(rInsPos.nNode);
1061 
1062                 aIndexBefore--;
1063 
1064                 pClpDoc->CopyRange( aCpyPam, rInsPos, false );
1065 
1066                 {
1067                     aIndexBefore++;
1068                     SwPaM aPaM(SwPosition(aIndexBefore),
1069                                SwPosition(rInsPos.nNode));
1070 
1071                     aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
1072                 }
1073             }
1074 
1075 			SaveTblBoxCntnt( &rInsPos );
1076             if(bIncludingPageFrames && bStartWithTable)
1077             {
1078                 //remove the paragraph in front of the table
1079                 SwPaM aPara(aInsertPosition);
1080                 GetDoc()->DelFullPara(aPara);
1081             }
1082             //additionally copy page bound frames
1083             if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->Count() )
1084             {
1085                 // create a draw view if necessary
1086                 if( !Imp()->GetDrawView() )
1087                     MakeDrawView();
1088 
1089                 for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
1090                 {
1091                     sal_Bool bInsWithFmt = sal_True;
1092                     const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
1093                     if( bInsWithFmt  )
1094                     {
1095                         SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1096                         if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
1097                         {
1098                             aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
1099                         }
1100                         else
1101                             continue;
1102                         GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1103                     }
1104                 }
1105             }
1106 		}
1107 
1108         FOREACHPAM_END()
1109     }
1110 
1111     GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
1112 
1113 	// wurden neue Tabellenformeln eingefuegt ?
1114 	if( pTblFldTyp->GetDepends() )
1115 	{
1116 		// alte Actions beenden; die Tabellen-Frames werden angelegt und
1117 		// eine Selection kann erzeugt werden
1118 		sal_uInt16 nActCnt;
1119 		for( nActCnt = 0; ActionPend(); ++nActCnt )
1120 			EndAllAction();
1121 
1122 		for( ; nActCnt; --nActCnt )
1123 			StartAllAction();
1124 	}
1125 	GetDoc()->UnlockExpFlds();
1126 	GetDoc()->UpdateFlds(NULL, false);
1127 	EndAllAction();
1128 
1129 	return bRet;
1130 }
1131 
1132 /*-- 14.06.2004 13:31:17---------------------------------------------------
1133 
1134   -----------------------------------------------------------------------*/
PastePages(SwFEShell & rToFill,sal_uInt16 nStartPage,sal_uInt16 nEndPage)1135 sal_Bool SwFEShell::PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage)
1136 {
1137     Push();
1138     if(!GotoPage(nStartPage))
1139     {
1140         Pop(sal_False);
1141         return sal_False;
1142     }
1143     MovePage( fnPageCurr, fnPageStart );
1144     SwPaM aCpyPam( *GetCrsr()->GetPoint() );
1145     String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName();
1146     SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, sal_True );
1147     if( pDesc )
1148         rToFill.ChgCurPageDesc( *pDesc );
1149 
1150     if(!GotoPage(nEndPage))
1151     {
1152         Pop(sal_False);
1153         return sal_False;
1154     }
1155     //if the page starts with a table a paragraph has to be inserted before
1156     SwNode* pTableNode = aCpyPam.GetNode()->FindTableNode();
1157     if(pTableNode)
1158     {
1159         //insert a paragraph
1160         StartUndo(UNDO_INSERT);
1161         SwNodeIndex aTblIdx(  *pTableNode, -1 );
1162         SwPosition aBefore(aTblIdx);
1163         if(GetDoc()->AppendTxtNode( aBefore ))
1164         {
1165             SwPaM aTmp(aBefore);
1166             aCpyPam = aTmp;
1167         }
1168         EndUndo(UNDO_INSERT);
1169     }
1170 
1171     MovePage( fnPageCurr, fnPageEnd );
1172     aCpyPam.SetMark();
1173     *aCpyPam.GetMark() = *GetCrsr()->GetPoint();
1174 
1175     SET_CURR_SHELL( this );
1176 
1177     StartAllAction();
1178     GetDoc()->LockExpFlds();
1179     SetSelection(aCpyPam);
1180     // copy the text of the selection
1181     SwEditShell::Copy(&rToFill);
1182 
1183     if(pTableNode)
1184     {
1185         //remove the inserted paragraph
1186         Undo();
1187         //remove the paragraph in the second doc, too
1188 	    SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 );
1189 	    SwPaM aPara( aIdx ); //DocStart
1190         rToFill.GetDoc()->DelFullPara(aPara);
1191     }
1192     // now the page bound objects
1193     //additionally copy page bound frames
1194     if( GetDoc()->GetSpzFrmFmts()->Count() )
1195     {
1196         // create a draw view if necessary
1197         if( !rToFill.Imp()->GetDrawView() )
1198             rToFill.MakeDrawView();
1199 
1200         for ( sal_uInt16 i = 0; i < GetDoc()->GetSpzFrmFmts()->Count(); ++i )
1201         {
1202             const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i];
1203             SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1204             if ((FLY_AT_PAGE == aAnchor.GetAnchorId()) &&
1205                     aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage)
1206             {
1207                 aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1);
1208             }
1209             else
1210                 continue;
1211             rToFill.GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1212         }
1213     }
1214     GetDoc()->UnlockExpFlds();
1215     GetDoc()->UpdateFlds(NULL, false);
1216     Pop(sal_False);
1217     EndAllAction();
1218 
1219     return sal_True;
1220 }
1221 
GetDrawObjGraphic(sal_uLong nFmt,Graphic & rGrf) const1222 sal_Bool SwFEShell::GetDrawObjGraphic( sal_uLong nFmt, Graphic& rGrf ) const
1223 {
1224 	ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
1225 	const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1226 	sal_Bool bConvert = sal_True;
1227 	if( rMrkList.GetMarkCount() )
1228 	{
1229 		if( rMrkList.GetMarkCount() == 1 &&
1230 			rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) )
1231 		{
1232 			// Rahmen selektiert
1233 			if( CNT_GRF == GetCntType() )
1234 			{
1235                 // --> OD 2005-02-09 #119353# - robust
1236                 const Graphic* pGrf( GetGraphic() );
1237                 if ( pGrf )
1238                 {
1239                     Graphic aGrf( *pGrf );
1240                     if( SOT_FORMAT_GDIMETAFILE == nFmt )
1241                     {
1242                         if( GRAPHIC_BITMAP != aGrf.GetType() )
1243                         {
1244                             rGrf = aGrf;
1245                             bConvert = sal_False;
1246                         }
1247                         else if( GetWin() )
1248                         {
1249                             Size aSz;
1250                             Point aPt;
1251                             GetGrfSize( aSz );
1252 
1253                             VirtualDevice aVirtDev;
1254                             aVirtDev.EnableOutput( sal_False );
1255 
1256                             MapMode aTmp( GetWin()->GetMapMode() );
1257                             aTmp.SetOrigin( aPt );
1258                             aVirtDev.SetMapMode( aTmp );
1259 
1260                             GDIMetaFile aMtf;
1261                             aMtf.Record( &aVirtDev );
1262                             aGrf.Draw( &aVirtDev, aPt, aSz );
1263                             aMtf.Stop();
1264                             aMtf.SetPrefMapMode( aTmp );
1265                             aMtf.SetPrefSize( aSz );
1266                             rGrf = aMtf;
1267                         }
1268                     }
1269                     else if( GRAPHIC_BITMAP == aGrf.GetType() )
1270                     {
1271                         rGrf = aGrf;
1272                         bConvert = sal_False;
1273                     }
1274                     else
1275                     {
1276                         //fix(23806): Nicht die Originalgroesse, sondern die
1277                         //aktuelle. Anderfalls kann es passieren, dass z.B. bei
1278                         //Vektorgrafiken mal eben zig MB angefordert werden.
1279                         const Size aSz( FindFlyFrm()->Prt().SSize() );
1280                         VirtualDevice aVirtDev( *GetWin() );
1281 
1282                         MapMode aTmp( MAP_TWIP );
1283                         aVirtDev.SetMapMode( aTmp );
1284                         if( aVirtDev.SetOutputSize( aSz ) )
1285                         {
1286                             aGrf.Draw( &aVirtDev, Point(), aSz );
1287                             rGrf = aVirtDev.GetBitmap( Point(), aSz );
1288                         }
1289                         else
1290                         {
1291                             rGrf = aGrf;
1292                             bConvert = sal_False;
1293                         }
1294                     }
1295                 }
1296                 // <--
1297 			}
1298 		}
1299 		else if( SOT_FORMAT_GDIMETAFILE == nFmt )
1300 			rGrf = Imp()->GetDrawView()->GetMarkedObjMetaFile();
1301 		else if( SOT_FORMAT_BITMAP == nFmt || SOT_FORMATSTR_ID_PNG == nFmt )
1302 			rGrf = Imp()->GetDrawView()->GetMarkedObjBitmapEx();
1303 	}
1304 	return bConvert;
1305 }
1306 
1307 // --> OD 2005-08-03 #i50824#
1308 // --> OD 2006-03-01 #b6382898#
1309 // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
lcl_ConvertSdrOle2ObjsToSdrGrafObjs(SdrModel * _pModel)1310 void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel )
1311 {
1312     for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum )
1313     {
1314         // setup object iterator in order to iterate through all objects
1315         // including objects in group objects, but exclusive group objects.
1316         SdrObjListIter aIter(*(_pModel->GetPage( nPgNum )));
1317         while( aIter.IsMore() )
1318         {
1319             SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
1320             if( pOle2Obj )
1321             {
1322                 // found an ole2 shape
1323                 SdrObjList* pObjList = pOle2Obj->GetObjList();
1324 
1325                 // get its graphic
1326                 Graphic aGraphic;
1327                 pOle2Obj->Connect();
1328                 Graphic* pGraphic = pOle2Obj->GetGraphic();
1329                 if( pGraphic )
1330                     aGraphic = *pGraphic;
1331                 pOle2Obj->Disconnect();
1332 
1333                 // create new graphic shape with the ole graphic and shape size
1334                 SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() );
1335                 // apply layer of ole2 shape at graphic shape
1336                 pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
1337 
1338                 // replace ole2 shape with the new graphic object and delete the ol2 shape
1339                 SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() );
1340                 SdrObject::Free( pRemovedObject );
1341             }
1342         }
1343     }
1344 }
1345 // <--
Paste(SvStream & rStrm,sal_uInt16 nAction,const Point * pPt)1346 void SwFEShell::Paste( SvStream& rStrm, sal_uInt16 nAction, const Point* pPt )
1347 {
1348 	SET_CURR_SHELL( this );
1349 	StartAllAction();
1350 	StartUndo();
1351 
1352 	SvtPathOptions aPathOpt;
1353 	FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(),
1354 											0, GetDoc()->GetDocShell() );
1355 	pModel->GetItemPool().FreezeIdRanges();
1356 
1357 	rStrm.Seek(0);
1358 
1359     uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) );
1360 	SvxDrawingLayerImport( pModel, xInputStream );
1361 
1362 	if ( !Imp()->HasDrawView() )
1363 		Imp()->MakeDrawView();
1364 
1365 	Point aPos( pPt ? *pPt : GetCharRect().Pos() );
1366 	SdrView *pView = Imp()->GetDrawView();
1367 
1368 	//Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren.
1369 	if( pModel->GetPageCount() > 0 &&
1370         1 == pModel->GetPage(0)->GetObjCount() &&
1371 		1 == pView->GetMarkedObjectList().GetMarkCount() )
1372 	{
1373         // OD 10.07.2003 #110742# - replace a marked 'virtual' drawing object
1374         // by its corresponding 'master' drawing object in the mark list.
1375         SwDrawView::ReplaceMarkedDrawVirtObjs( *pView );
1376 
1377         SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0);
1378 		SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj();
1379 
1380 		if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) )
1381 			nAction = SW_PASTESDR_REPLACE;
1382 
1383 		switch( nAction )
1384 		{
1385 		case SW_PASTESDR_REPLACE:
1386 			{
1387 				const SwFrmFmt* pFmt(0);
1388 				const SwFrm* pAnchor(0);
1389 				if( pOldObj->ISA(SwVirtFlyDrawObj) )
1390 				{
1391 					pFmt = FindFrmFmt( pOldObj );
1392 
1393 					Point aNullPt;
1394 					SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt );
1395                     pAnchor = pFlyFrm->GetAnchorFrm();
1396 
1397 					if( pAnchor->FindFooterOrHeader() )
1398 					{
1399 						// wenn TextRahmen in der Kopf/Fusszeile steht, dann
1400 						// nicht ersetzen, sondern nur einfuegen
1401 						nAction = SW_PASTESDR_INSERT;
1402 						break;
1403 					}
1404 				}
1405 
1406 				SdrObject* pNewObj = pClpObj->Clone();
1407 				Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() );
1408 				Size aOldObjSize( aOldObjRect.GetSize() );
1409 				Rectangle aNewRect( pNewObj->GetCurrentBoundRect() );
1410 				Size aNewSize( aNewRect.GetSize() );
1411 
1412 				Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() );
1413 				Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height());
1414 				pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight);
1415 
1416 				Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft();
1417 				pNewObj->NbcMove(Size(aVec.X(), aVec.Y()));
1418 
1419                 if( pNewObj->ISA( SdrUnoObj ) )
1420                     pNewObj->SetLayer( GetDoc()->GetControlsId() );
1421                 else if( pOldObj->ISA( SdrUnoObj ) )
1422                     pNewObj->SetLayer( GetDoc()->GetHeavenId() );
1423                 else
1424                     pNewObj->SetLayer( pOldObj->GetLayer() );
1425 
1426 				if( pOldObj->ISA(SwVirtFlyDrawObj) )
1427 				{
1428 					// Attribute sichern und dam SdrObject setzen
1429 					SfxItemSet aFrmSet( pDoc->GetAttrPool(),
1430 											RES_SURROUND, RES_ANCHOR );
1431 					aFrmSet.Set( pFmt->GetAttrSet() );
1432 
1433 					Point aNullPt;
1434 					if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() )
1435 					{
1436 						const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor;
1437 						do {
1438 							pTmp = pTmp->FindMaster();
1439 							ASSERT( pTmp, "Where's my Master?" );
1440 						} while( pTmp->IsFollow() );
1441 						pAnchor = pTmp;
1442 					}
1443 					if( pOldObj->ISA( SdrCaptionObj ))
1444 						aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos();
1445 					else
1446 						aNullPt = aOldObjRect.TopLeft();
1447 
1448                     Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) );
1449                     // OD 2004-04-05 #i26791# - direct positioning of Writer
1450                     // fly frame object for <SwDoc::Insert(..)>
1451                     pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor );
1452                     pNewObj->NbcSetAnchorPos( aNewAnchor );
1453 
1454                     pOldObj->GetOrdNum();
1455 
1456 					DelSelectedObj();
1457 
1458 					pFmt = GetDoc()->InsertDrawObj( *GetCrsr(), *pNewObj, aFrmSet );
1459 				}
1460 				else
1461                 {
1462                     // #123922#  for handling MasterObject and virtual ones correctly, SW
1463                     // wants us to call ReplaceObject at the page, but that also
1464                     // triggers the same assertion (I tried it), so stay at the view method
1465                     pView->ReplaceObjectAtView(pOldObj, *Imp()->GetPageView(), pNewObj);
1466                 }
1467 			}
1468 			break;
1469 
1470 		case SW_PASTESDR_SETATTR:
1471 			{
1472 				SfxItemSet aSet( GetAttrPool() );
1473                 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pClpObj);
1474 
1475                 if(pSdrGrafObj)
1476                 {
1477                     SdrObject* pTarget = 0;
1478 
1479                     if(0 != pView->GetMarkedObjectList().GetMarkCount())
1480                     {
1481                         // try to get target (if it's at least one, take first)
1482                         SdrMark* pMark = pView->GetMarkedObjectList().GetMark(0);
1483 
1484                         if(pMark)
1485                         {
1486                             pTarget = pMark->GetMarkedSdrObj();
1487                         }
1488                     }
1489 
1490                     if(pTarget)
1491                     {
1492                         // copy ItemSet from target
1493                         aSet.Set(pTarget->GetMergedItemSet());
1494                     }
1495 
1496                     // for SdrGrafObj, use the graphic as fill style argument
1497                     const Graphic& rGraphic = pSdrGrafObj->GetGraphic();
1498 
1499                     if(GRAPHIC_NONE != rGraphic.GetType() && GRAPHIC_DEFAULT != rGraphic.GetType())
1500                     {
1501                         aSet.Put(XFillBitmapItem(String(), rGraphic));
1502                         aSet.Put(XFillStyleItem(XFILL_BITMAP));
1503                     }
1504                 }
1505                 else
1506                 {
1507                     aSet.Put(pClpObj->GetMergedItemSet());
1508                 }
1509 
1510 				pView->SetAttributes( aSet, sal_False );
1511 			}
1512 			break;
1513 
1514 		default:
1515 			nAction = SW_PASTESDR_INSERT;
1516 			break;
1517 		}
1518 	}
1519 	else
1520 		nAction = SW_PASTESDR_INSERT;
1521 
1522 	if( SW_PASTESDR_INSERT == nAction )
1523     {
1524         ::sw::DrawUndoGuard drawUndoGuard(GetDoc()->GetIDocumentUndoRedo());
1525 
1526         sal_Bool bDesignMode = pView->IsDesignMode();
1527         if( !bDesignMode )
1528             pView->SetDesignMode( sal_True );
1529 
1530         // --> OD 2005-08-03 #i50824#
1531         // --> OD 2006-03-01 #b6382898#
1532         // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1533         lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel );
1534         // <--
1535         pView->Paste( *pModel, aPos );
1536 
1537 		sal_uLong nCnt = pView->GetMarkedObjectList().GetMarkCount();
1538 		if( nCnt )
1539 		{
1540 			const Point aNull( 0, 0 );
1541 			for( sal_uLong i=0; i < nCnt; ++i )
1542 			{
1543 				SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
1544 				pObj->ImpSetAnchorPos( aNull );
1545 			}
1546 
1547 			pView->SetCurrentObj( OBJ_GRUP, SdrInventor );
1548 			if ( nCnt > 1 )
1549 				pView->GroupMarked();
1550 			SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1551             if( pObj->ISA( SdrUnoObj ) )
1552             {
1553                 pObj->SetLayer( GetDoc()->GetControlsId() );
1554                 bDesignMode = sal_True;
1555             }
1556             else
1557                 pObj->SetLayer( GetDoc()->GetHeavenId() );
1558 			const Rectangle &rSnap = pObj->GetSnapRect();
1559 			const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 );
1560 			pView->MoveMarkedObj( aDiff );
1561 			ImpEndCreate();
1562             if( !bDesignMode )
1563                 pView->SetDesignMode( sal_False );
1564 		}
1565 	}
1566 	EndUndo();
1567 	EndAllAction();
1568 	delete pModel;
1569 }
1570 
Paste(const Graphic & rGrf,const String & rURL)1571 bool SwFEShell::Paste( const Graphic &rGrf, const String& rURL )
1572 {
1573     SET_CURR_SHELL( this );
1574     SdrObject* pObj = 0;
1575     SdrView *pView = Imp()->GetDrawView();
1576 
1577     sal_Bool bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() &&
1578         (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() &&
1579         !pObj->ISA( SdrOle2Obj );
1580 
1581     if( bRet && pObj )
1582     {
1583         // #123922# added code to handle the two cases of SdrGrafObj and a fillable, non-
1584         // OLE object in focus
1585         SdrObject* pResult = pObj;
1586 
1587         if(dynamic_cast< SdrGrafObj* >(pObj))
1588         {
1589             SdrGrafObj* pNewGrafObj = (SdrGrafObj*)pObj->Clone();
1590 
1591             pNewGrafObj->SetGraphic(rGrf);
1592 
1593             // #123922#  for handling MasterObject and virtual ones correctly, SW
1594             // wants us to call ReplaceObject at the page, but that also
1595             // triggers the same assertion (I tried it), so stay at the view method
1596             pView->ReplaceObjectAtView(pObj, *pView->GetSdrPageView(), pNewGrafObj);
1597 
1598             // set in all cases - the Clone() will have copied an existing link (!)
1599             pNewGrafObj->SetGraphicLink(rURL, String());
1600 
1601             pResult = pNewGrafObj;
1602         }
1603         else
1604         {
1605             pView->AddUndo(new SdrUndoAttrObj(*pObj));
1606 
1607             SfxItemSet aSet(pView->GetModel()->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP);
1608 
1609             aSet.Put(XFillStyleItem(XFILL_BITMAP));
1610             aSet.Put(XFillBitmapItem(String(), rGrf));
1611             pObj->SetMergedItemSetAndBroadcast(aSet);
1612         }
1613 
1614         // we are done; mark the modified/new object
1615         pView->MarkObj(pResult, pView->GetSdrPageView());
1616     }
1617 
1618     return bRet;
1619 }
1620