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