xref: /AOO41X/main/sw/source/core/frmedt/fecopy.cxx (revision 5222b95b3ede3af7a8a07cdec672334a798315fa)
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( !this, "was fuer ein Anchor ist es denn?" );
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