Update ooo320-m1
[ooovba.git] / sw / source / core / frmedt / fecopy.cxx
blobbc66235cde08b97b6d88801de06e1951e88a446c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fecopy.cxx,v $
10 * $Revision: 1.53 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
37 #include <vcl/graph.hxx>
38 #include <sot/formats.hxx>
39 #include <sot/storage.hxx>
40 #include <svtools/pathoptions.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/viewsh.hxx>
43 #include <svx/xexch.hxx>
44 #include <svx/xflasit.hxx>
45 #include <svx/xfillit0.hxx>
46 #include <svx/xflclit.hxx>
47 #include <svx/brshitem.hxx>
48 #include <svx/svdocapt.hxx>
49 #include <svx/svdouno.hxx>
50 #include <svx/xfillit.hxx>
51 #include <svx/svdpage.hxx>
52 #include <svx/svdogrp.hxx>
53 #include <svx/xoutbmp.hxx>
54 #include <svx/svdoole2.hxx>
55 #include <svx/fmmodel.hxx>
56 #include <svx/unomodel.hxx>
57 // --> OD 2005-08-03 #i50824#
58 #include <svx/svditer.hxx>
59 // <--
60 // --> OD 2006-03-01 #b6382898#
61 #include <svx/svdograf.hxx>
62 // <--
63 #include <unotools/streamwrap.hxx>
64 #include <fmtanchr.hxx>
65 #include <fmtcntnt.hxx>
66 #include <fmtornt.hxx>
67 #include <fmtflcnt.hxx>
68 #include <frmfmt.hxx>
69 #include <docary.hxx>
70 #include <txtfrm.hxx>
71 #include <txtflcnt.hxx>
72 #include <fesh.hxx>
73 #include <doc.hxx>
74 #include <rootfrm.hxx>
75 #include <ndtxt.hxx>
76 #include <pam.hxx>
77 #include <tblsel.hxx>
78 #include <swtable.hxx>
79 #include <flyfrm.hxx>
80 #include <pagefrm.hxx>
81 #include <fldbas.hxx>
82 #include <edimp.hxx>
83 #include <swundo.hxx>
84 #include <viewimp.hxx>
85 #include <dview.hxx>
86 #include <dcontact.hxx>
87 #include <dflyobj.hxx>
88 #include <docsh.hxx>
89 #include <pagedesc.hxx>
90 #include <mvsave.hxx>
91 #include <vcl/virdev.hxx>
94 using namespace ::com::sun::star;
96 /*************************************************************************
98 |* SwFEShell::Copy() Copy fuer das Interne Clipboard.
99 |* Kopiert alle Selektionen in das Clipboard.
101 |* Ersterstellung JP ??
102 |* Letzte Aenderung MA 22. Feb. 95
104 |*************************************************************************/
106 BOOL SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt )
108 ASSERT( pClpDoc, "kein Clipboard-Dokument" );
110 pClpDoc->DoUndo( FALSE ); // immer auf FALSE !!
112 // steht noch Inhalt im ClpDocument, dann muss dieser geloescht werden
113 SwNodeIndex aSttIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
114 SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
115 if( !pTxtNd || pTxtNd->GetTxt().Len() ||
116 aSttIdx.GetIndex()+1 != pClpDoc->GetNodes().GetEndOfContent().GetIndex() )
118 pClpDoc->GetNodes().Delete( aSttIdx,
119 pClpDoc->GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
120 pTxtNd = pClpDoc->GetNodes().MakeTxtNode( aSttIdx,
121 (SwTxtFmtColl*)pClpDoc->GetDfltTxtFmtColl() );
122 aSttIdx--;
125 // stehen noch FlyFrames rum, loesche auch diese
126 for( USHORT n = 0; n < pClpDoc->GetSpzFrmFmts()->Count(); ++n )
128 SwFlyFrmFmt* pFly = (SwFlyFrmFmt*)(*pClpDoc->GetSpzFrmFmts())[n];
129 pClpDoc->DelLayoutFmt( pFly );
131 pClpDoc->GCFieldTypes(); // loesche die FieldTypes
133 // wurde ein String uebergeben, so kopiere diesen in das Clipboard-
134 // Dokument. Somit kann auch der Calculator das interne Clipboard
135 // benutzen.
136 if( pNewClpTxt )
138 pTxtNd->InsertText( *pNewClpTxt, SwIndex( pTxtNd ) );
139 return TRUE; // das wars.
142 pClpDoc->LockExpFlds();
143 pClpDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
144 BOOL bRet;
146 // soll ein FlyFrame kopiert werden ?
147 if( IsFrmSelected() )
149 // hole das FlyFormat
150 SwFlyFrm* pFly = FindFlyFrm();
151 SwFrmFmt* pFlyFmt = pFly->GetFmt();
152 SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
154 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
155 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
156 FLY_AT_FLY == aAnchor.GetAnchorId() ||
157 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
159 SwPosition aPos( aSttIdx );
160 if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
161 aPos.nContent.Assign( pTxtNd, 0 );
162 aAnchor.SetAnchor( &aPos );
164 pFlyFmt = pClpDoc->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
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 )
171 USHORT nPos = rSpzFrmFmts.GetPos( pFlyFmt );
172 ASSERT( nPos != USHRT_MAX, "Fly steht nicht im Spz-Array" );
174 rSpzFrmFmts.Remove( nPos );
175 rSpzFrmFmts.Insert( pFlyFmt, 0 );
178 if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
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* pTxtFly = (SwTxtFlyCnt*)pTxtNd->GetTxtAttr(
187 rIdx, RES_TXTATR_FLYCNT );
188 if( pTxtFly )
190 ((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 );
191 pTxtNd->EraseText( rIdx, 1 );
194 bRet = TRUE;
196 else if ( IsObjSelected() )
198 SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 ));
199 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
200 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
202 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
204 if( Imp()->GetDrawView()->IsGroupEntered() ||
205 ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
207 SfxItemSet aSet( pClpDoc->GetAttrPool(), aFrmFmtSetRange );
209 SwFmtAnchor aAnchor( FLY_AT_CNTNT );
210 aAnchor.SetAnchor( &aPos );
211 aSet.Put( aAnchor );
213 SdrObject* pNew = pClpDoc->CloneSdrObj( *pObj, FALSE, TRUE );
215 SwPaM aTemp(aPos);
216 pClpDoc->Insert(aTemp, *pNew, &aSet, NULL);
218 else
220 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
221 SwFrmFmt *pFmt = pContact->GetFmt();
222 SwFmtAnchor aAnchor( pFmt->GetAnchor() );
223 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
224 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
225 FLY_AT_FLY == aAnchor.GetAnchorId() ||
226 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
228 aAnchor.SetAnchor( &aPos );
231 pClpDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
234 bRet = TRUE;
236 else
237 bRet = _CopySelToDoc( pClpDoc, 0 ); // kopiere die Selectionen
239 pClpDoc->SetRedlineMode_intern((RedlineMode_t)0 );
240 pClpDoc->UnlockExpFlds();
241 if( !pClpDoc->IsExpFldsLocked() )
242 pClpDoc->UpdateExpFlds(NULL, true);
244 return bRet;
247 const Point &lcl_FindBasePos( const SwFrm *pFrm, const Point &rPt )
249 const SwFrm *pF = pFrm;
250 while ( pF && !pF->Frm().IsInside( rPt ) )
252 if ( pF->IsCntntFrm() )
253 pF = ((SwCntntFrm*)pF)->GetFollow();
254 else
255 pF = 0;
257 if ( pF )
258 return pF->Frm().Pos();
259 else
260 return pFrm->Frm().Pos();
263 BOOL lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly,
264 const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor,
265 Point& rNewPos, BOOL bCheckFlyRecur )
267 BOOL bRet = TRUE;
268 rAnchor.SetAnchor( &rPos );
269 SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->GetFrm( &rInsPt, 0, FALSE );
270 SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm();
271 if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( *pTmpFly ) )
272 bRet = FALSE;
273 else if ( FLY_AT_FLY == rAnchor.GetAnchorId() )
275 if( pTmpFly )
277 const SwNodeIndex& rIdx = *pTmpFly->GetFmt()->GetCntnt().GetCntntIdx();
278 SwPosition aPos( rIdx );
279 rAnchor.SetAnchor( &aPos );
280 rNewPos = pTmpFly->Frm().Pos();
282 else
284 rAnchor.SetType( FLY_PAGE );
285 rAnchor.SetPageNum( rDestShell.GetPageNumber( rInsPt ) );
286 const SwFrm *pPg = pTmpFrm->FindPageFrm();
287 rNewPos = pPg->Frm().Pos();
290 else
291 rNewPos = ::lcl_FindBasePos( pTmpFrm, rInsPt );
292 return bRet;
295 BOOL SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt,
296 const Point& rInsPt, BOOL bIsMove, BOOL bSelectInsert )
298 BOOL bRet = TRUE;
300 //Die Liste muss kopiert werden, weil unten die neuen Objekte
301 //selektiert werden.
302 const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() );
303 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();
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();
316 Size aSiz( rInsPt.X() - rSttPt.X(), rInsPt.Y() - rSttPt.Y() );
317 for( USHORT i = 0; i < nMarkCount; ++i )
319 SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
321 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
322 SwFrmFmt *pFmt = pContact->GetFmt();
323 const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
325 BOOL bInsWithFmt = TRUE;
327 if( pDestDrwView->IsGroupEntered() )
329 // in die Gruppe einfuegen, wenns aus einer betretenen Gruppe
330 // kommt oder das Object nicht zeichengebunden ist
331 if( pSrcDrwView->IsGroupEntered() ||
332 FLY_IN_CNTNT != rAnchor.GetAnchorId() )
335 SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
336 GetDoc() == pDestDoc, FALSE );
337 pNew->NbcMove( aSiz );
338 pDestDrwView->InsertObjectAtView( pNew, *pDestPgView );
339 bInsWithFmt = FALSE;
343 if( bInsWithFmt )
345 SwFmtAnchor aAnchor( rAnchor );
346 Point aNewAnch;
348 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
349 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
350 FLY_AT_FLY == aAnchor.GetAnchorId() ||
351 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
353 if ( this == pDestShell )
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 = FALSE;
365 else
366 bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt,
367 *pDestShell, aAnchor, aNewAnch, FALSE );
369 else
371 SwPaM *pCrsr = pDestShell->GetCrsr();
372 if( pCrsr->GetNode()->IsNoTxtNode() )
373 bRet = FALSE;
374 else
375 bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(),
376 *pCrsr->GetNode(), 0, rInsPt,
377 *pDestShell, aAnchor,
378 aNewAnch, FALSE );
381 else if( FLY_PAGE == aAnchor.GetAnchorId() )
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();
390 if( bRet )
392 if( pSrcDrwView->IsGroupEntered() ||
393 ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
395 SfxItemSet aSet( pDestDoc->GetAttrPool(),aFrmFmtSetRange);
396 aSet.Put( aAnchor );
397 SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
398 GetDoc() == pDestDoc, TRUE );
399 pFmt = pDestDoc->Insert( *pDestShell->GetCrsr(),
400 *pNew, &aSet, NULL );
402 else
403 pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
405 //Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind.
406 if ( pFmt )
408 SdrObject* pNew = pFmt->FindSdrObject();
409 if( FLY_IN_CNTNT != aAnchor.GetAnchorId() )
411 Point aPos( rInsPt );
412 aPos -= aNewAnch;
413 aPos -= rSttPt - pObj->GetSnapRect().TopLeft();
414 // OD 2004-04-05 #i26791# - change attributes instead of
415 // direct positioning
416 pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
417 pFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
418 // --> OD 2005-04-15 #i47455# - notify draw frame format
419 // that position attributes are already set.
420 if ( pFmt->ISA(SwDrawFrmFmt) )
422 static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet();
424 // <--
426 if( bSelectInsert )
427 pDestDrwView->MarkObj( pNew, pDestPgView );
433 if ( bIsMove && bRet )
435 if( pDestShell == this )
437 const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() );
438 pSrcDrwView->UnmarkAll();
440 ULONG nMrkCnt = aMrkList.GetMarkCount();
441 USHORT i;
442 for ( i = 0; i < nMrkCnt; ++i )
444 SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
445 pSrcDrwView->MarkObj( pObj, pSrcPgView );
447 DelSelectedObj();
448 nMrkCnt = aList.GetMarkCount();
449 for ( i = 0; i < nMrkCnt; ++i )
451 SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj();
452 pSrcDrwView->MarkObj( pObj, pSrcPgView );
455 else
456 DelSelectedObj();
459 return bRet;
462 BOOL SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
463 const Point& rInsPt, BOOL bIsMove, BOOL bSelectInsert )
465 BOOL bRet = FALSE;
467 ASSERT( pDestShell, "Copy ohne DestShell." );
468 ASSERT( this == pDestShell || !pDestShell->IsObjSelected(),
469 "Dest-Shell darf nie im Obj-Modus sein" );
471 SET_CURR_SHELL( pDestShell );
473 pDestShell->StartAllAction();
474 pDestShell->GetDoc()->LockExpFlds();
476 // Referenzen sollen verschoben werden.
477 BOOL bCopyIsMove = pDoc->IsCopyIsMove();
478 if( bIsMove )
479 // am Doc ein Flag setzen, damit in den TextNodes
480 pDoc->SetCopyIsMove( TRUE );
482 RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode();
483 pDestShell->GetDoc()->SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES));
485 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
486 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
487 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
488 // besorgt)
489 SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD );
491 if( IsFrmSelected() )
493 SwFlyFrm* pFly = FindFlyFrm();
494 SwFrmFmt* pFlyFmt = pFly->GetFmt();
495 SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
496 bRet = TRUE;
497 Point aNewAnch;
499 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
500 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
501 FLY_AT_FLY == aAnchor.GetAnchorId() ||
502 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
504 if ( this == pDestShell )
506 // gleiche Shell? Dann erfrage die Position an der
507 // uebergebenen DokumentPosition
508 SwPosition aPos( *GetCrsr()->GetPoint() );
509 Point aPt( rInsPt );
510 aPt -= rSttPt - pFly->Frm().Pos();
511 SwCrsrMoveState aState( MV_SETONLYTEXT );
512 GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
513 const SwNode *pNd;
514 if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
515 bRet = FALSE;
516 else
517 { //Nicht in sich selbst kopieren
518 const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
519 if ( aPos.nNode > *pTmp && aPos.nNode <
520 pTmp->GetNode().EndOfSectionIndex() )
522 bRet = FALSE;
524 else
525 bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
526 *pDestShell, aAnchor, aNewAnch, TRUE );
529 else
531 const SwPaM *pCrsr = pDestShell->GetCrsr();
532 if( pCrsr->GetNode()->IsNoTxtNode() )
533 bRet = FALSE;
534 else
535 bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(),
536 pFly, rInsPt, *pDestShell, aAnchor,
537 aNewAnch, GetDoc() == pDestShell->GetDoc());
540 else if( FLY_PAGE == aAnchor.GetAnchorId() )
542 aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
543 const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
544 const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
545 if ( pPg )
546 aNewAnch = pPg->Frm().Pos();
548 else {
549 ASSERT( !this, "was fuer ein Anchor ist es denn?" );
552 if( bRet )
554 SwFrmFmt *pOldFmt = pFlyFmt;
555 pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
557 if( FLY_IN_CNTNT != aAnchor.GetAnchorId() )
559 Point aPos( rInsPt );
560 aPos -= aNewAnch;
561 aPos -= rSttPt - pFly->Frm().Pos();
562 pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
563 pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
566 const Point aPt( pDestShell->GetCrsrDocPos() );
568 if( bIsMove )
569 GetDoc()->DelLayoutFmt( pOldFmt );
571 // nur selektieren wenn es in der gleichen Shell verschoben/
572 // kopiert wird
573 if( bSelectInsert )
575 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, FALSE );
576 if( pFlyFrm )
578 //JP 12.05.98: sollte das nicht im SelectFlyFrm stehen???
579 pDestShell->Imp()->GetDrawView()->UnmarkAll();
580 pDestShell->SelectFlyFrm( *pFlyFrm, TRUE );
584 if( this != pDestShell && !pDestShell->HasShFcs() )
585 pDestShell->Imp()->GetDrawView()->hideMarkHandles();
588 else if ( IsObjSelected() )
589 bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert );
590 else if( IsTableMode() )
592 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
593 // von der Originalen an und kopiere die selectierten Boxen.
594 // Die Groessen werden prozentual korrigiert.
596 // lasse ueber das Layout die Boxen suchen
597 const SwTableNode* pTblNd;
598 SwSelBoxes aBoxes;
599 GetTblSel( *this, aBoxes );
600 if( aBoxes.Count() &&
601 0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) )
603 SwPosition* pDstPos = 0;
604 if( this == pDestShell )
606 // gleiche Shell? Dann erzeuge einen Crsr an der
607 // uebergebenen DokumentPosition
608 pDstPos = new SwPosition( *GetCrsr()->GetPoint() );
609 Point aPt( rInsPt );
610 GetLayout()->GetCrsrOfst( pDstPos, aPt );
611 if( !pDstPos->nNode.GetNode().IsNoTxtNode() )
612 bRet = TRUE;
614 else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
616 pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
617 bRet = TRUE;
620 if( bRet )
622 if( GetDoc() == pDestShell->GetDoc() )
623 ParkTblCrsr();
625 bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0,
626 bIsMove && this == pDestShell &&
627 aBoxes.Count() == pTblNd->GetTable().
628 GetTabSortBoxes().Count(),
629 this != pDestShell );
631 if( this != pDestShell )
632 *pDestShell->GetCrsr()->GetPoint() = *pDstPos;
634 // wieder alle geparkten Crsr erzeugen?
635 if( GetDoc() == pDestShell->GetDoc() )
636 GetCrsr();
638 // JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte
639 // Cursor auf die EinfuegePos. positioniert wird
640 if( this == pDestShell )
641 GetCrsrDocPos() = rInsPt;
643 delete pDstPos;
646 else
648 bRet = TRUE;
649 if( this == pDestShell )
651 // gleiche Shell? Dann erfrage die Position an der
652 // uebergebenen DokumentPosition
653 SwPosition aPos( *GetCrsr()->GetPoint() );
654 Point aPt( rInsPt );
655 GetLayout()->GetCrsrOfst( &aPos, aPt );
656 bRet = !aPos.nNode.GetNode().IsNoTxtNode();
658 else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
659 bRet = FALSE;
661 if( bRet )
662 bRet = 0 != SwEditShell::Copy( pDestShell );
665 pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode );
666 pDoc->SetCopyIsMove( bCopyIsMove );
668 // wurden neue Tabellenformeln eingefuegt ?
669 if( pTblFldTyp->GetDepends() )
671 // alte Actions beenden; die Tabellen-Frames werden angelegt und
672 // eine SSelection kann erzeugt werden
673 USHORT nActCnt;
674 for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt )
675 pDestShell->EndAllAction();
677 for( ; nActCnt; --nActCnt )
678 pDestShell->StartAllAction();
680 pDestShell->GetDoc()->UnlockExpFlds();
681 pDestShell->GetDoc()->UpdateFlds(NULL, false);
683 pDestShell->EndAllAction();
684 return bRet;
687 /*************************************************************************
689 |* SwFEShell::Paste() Paste fuer das Interne Clipboard.
690 |* Kopiert den Inhalt vom Clipboard in das Dokument.
692 |* Ersterstellung JP ??
693 |* Letzte Aenderung MA 22. Feb. 95
695 |*************************************************************************/
697 namespace {
698 typedef boost::shared_ptr<SwPaM> PaMPtr;
699 typedef boost::shared_ptr<SwPosition> PositionPtr;
700 typedef std::pair< PaMPtr, PositionPtr > Insertion;
703 BOOL SwFEShell::Paste( SwDoc* pClpDoc, BOOL bIncludingPageFrames )
705 SET_CURR_SHELL( this );
706 ASSERT( pClpDoc, "kein Clipboard-Dokument" );
707 const USHORT nStartPageNumber = GetPhyPageNum();
708 // dann bis zum Ende vom Nodes Array
709 SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
710 SwPaM aCpyPam( aIdx ); //DocStart
712 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
713 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
714 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
715 // besorgt)
716 SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
718 SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode();
719 if( !pSrcNd ) // TabellenNode ?
720 { // nicht ueberspringen!!
721 SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode();
722 if( pCNd )
723 aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 );
724 else if( !aCpyPam.Move( fnMoveForward, fnGoNode ))
725 aCpyPam.Move( fnMoveBackward, fnGoNode );
728 aCpyPam.SetMark();
729 aCpyPam.Move( fnMoveForward, fnGoDoc );
731 BOOL bRet = TRUE, bDelTbl = TRUE;
732 StartAllAction();
733 GetDoc()->StartUndo( UNDO_INSGLOSSARY, NULL );
734 GetDoc()->LockExpFlds();
736 // When the clipboard content has been created by a rectangular selection
737 // the pasting is more sophisticated:
738 // every paragraph will be inserted into another position.
739 // The first positions are given by the actual cursor ring,
740 // if there are more text portions to insert than cursor in this ring,
741 // the additional insert positions will be created by moving the last
742 // cursor position into the next line (like pressing the cursor down key)
743 if( pClpDoc->IsColumnSelection() && !IsTableMode() )
745 // Creation of the list of insert positions
746 std::list< Insertion > aCopyList;
747 // The number of text portions of the rectangular selection
748 const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex()
749 - aCpyPam.GetMark()->nNode.GetIndex();
750 sal_uInt32 nCount = nSelCount;
751 SwNodeIndex aClpIdx( aIdx );
752 SwPaM* pStartCursor = GetCrsr();
753 SwPaM* pCurrCrsr = pStartCursor;
754 sal_uInt32 nCursorCount = pStartCursor->numberOf();
755 // If the target selection is a multi-selection, often the last and first
756 // cursor of the ring points to identical document positions. Then
757 // we should avoid double insertion of text portions...
758 while( nCursorCount > 1 && *pCurrCrsr->GetPoint() ==
759 *(dynamic_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) )
761 --nCursorCount;
762 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
763 pStartCursor = pCurrCrsr;
765 SwPosition aStartPos( *pStartCursor->GetPoint() );
766 SwPosition aInsertPos( aStartPos ); // first insertion position
767 bool bCompletePara = false;
768 USHORT nMove = 0;
769 while( nCount )
771 --nCount;
772 ASSERT( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" )
773 if( aIdx.GetNode().GetCntntNode() ) // robust
775 Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ),
776 PositionPtr( new SwPosition( aInsertPos ) ) );
777 ++aIdx;
778 aInsertion.first->SetMark();
779 if( pStartCursor == pCurrCrsr->GetNext() )
780 { // Now we have to look for insertion positions...
781 if( !nMove ) // Annotate the last given insert position
782 aStartPos = aInsertPos;
783 SwCursor aCrsr( aStartPos, 0, false);
784 // Check if we find another insert position by moving
785 // down the last given position
786 if( aCrsr.UpDown( FALSE, ++nMove, 0, 0 ) )
787 aInsertPos = *aCrsr.GetPoint();
788 else // if there is no paragraph we have to create it
789 bCompletePara = nCount > 0;
790 nCursorCount = 0;
792 else // as long as we find more insert positions in the cursor ring
793 { // we'll take them
794 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
795 aInsertPos = *pCurrCrsr->GetPoint();
796 --nCursorCount;
798 // If there are no more paragraphs e.g. at the end of a document,
799 // we insert complete paragraphs instead of text portions
800 if( bCompletePara )
801 aInsertion.first->GetPoint()->nNode = aIdx;
802 else
803 aInsertion.first->GetPoint()->nContent =
804 aInsertion.first->GetCntntNode()->Len();
805 aCopyList.push_back( aInsertion );
807 // If there are no text portions left but there are some more
808 // cursor positions to fill we have to restart with the first
809 // text portion
810 if( !nCount && nCursorCount )
812 nCount = std::min( nSelCount, nCursorCount );
813 aIdx = aClpIdx; // Start of clipboard content
816 std::list< Insertion >::const_iterator pCurr = aCopyList.begin();
817 std::list< Insertion >::const_iterator pEnd = aCopyList.end();
818 while( pCurr != pEnd )
820 SwPosition& rInsPos = *pCurr->second;
821 SwPaM& rCopy = *pCurr->first;
822 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
823 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() &&
824 rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode )
826 // if more than one node will be copied into a cell
827 // the box attributes have to be removed
828 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
831 SwNodeIndex aIndexBefore(rInsPos.nNode);
832 aIndexBefore--;
833 pClpDoc->CopyRange( rCopy, rInsPos, false );
835 aIndexBefore++;
836 SwPaM aPaM(SwPosition(aIndexBefore, 0),
837 SwPosition(rInsPos.nNode, 0));
838 aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
841 SaveTblBoxCntnt( &rInsPos );
842 ++pCurr;
845 else
847 FOREACHPAM_START(this)
849 if( pSrcNd &&
850 0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode )))
852 SwPosition aDestPos( *PCURCRSR->GetPoint() );
854 BOOL bParkTblCrsr = FALSE;
855 const SwStartNode* pSttNd = PCURCRSR->GetNode()->FindTableBoxStartNode();
857 // TABLE IN TABLE: Tabelle in Tabelle kopieren
858 // lasse ueber das Layout die Boxen suchen
859 SwSelBoxes aBoxes;
860 if( IsTableMode() ) // Tabellen-Selecktion ??
862 GetTblSel( *this, aBoxes );
863 ParkTblCrsr();
864 bParkTblCrsr = TRUE;
866 else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR &&
867 ( !pSrcNd->GetTable().IsTblComplex() ||
868 pDestNd->GetTable().IsNewModel() ) )
870 // dann die Tabelle "relativ" kopieren
871 SwTableBox* pBox = pDestNd->GetTable().GetTblBox(
872 pSttNd->GetIndex() );
873 ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
874 aBoxes.Insert( pBox );
877 SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode());
878 if( !bParkTblCrsr )
880 // erstmal aus der gesamten Tabelle raus
881 // ????? was ist mit Tabelle alleine im Rahmen ???????
882 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
883 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
884 // #i59539: Don't remove all redline
885 ::PaMCorrAbs( SwNodeIndex( *pDestNd ),
886 SwNodeIndex( *pDestNd->EndOfSectionNode() ),
887 aPos );
890 bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
891 FALSE, FALSE );
893 if( bParkTblCrsr )
894 GetCrsr();
895 else
897 // und wieder in die Box zurueck
898 aNdIdx = *pSttNd;
899 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
900 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
901 // #i59539: Don't remove all redline
902 ::PaMCorrAbs( PCURCRSR->GetPoint()->nNode, aPos );
905 break; // aus der "while"-Schleife heraus
907 else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() &&
908 pClpDoc->GetSpzFrmFmts()->Count() )
910 // so langsam sollte mal eine DrawView erzeugt werden
911 if( !Imp()->GetDrawView() )
912 MakeDrawView();
914 for ( USHORT i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
916 BOOL bInsWithFmt = TRUE;
917 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
919 if( Imp()->GetDrawView()->IsGroupEntered() &&
920 RES_DRAWFRMFMT == rCpyFmt.Which() &&
921 FLY_IN_CNTNT != rCpyFmt.GetAnchor().GetAnchorId() )
923 const SdrObject* pSdrObj = rCpyFmt.FindSdrObject();
924 if( pSdrObj )
926 SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj,
927 FALSE, FALSE );
929 // Insert object sets any anchor position to 0.
930 // Therefore we calculate the absolute position here
931 // and after the insert the anchor of the object
932 // is set to the anchor of the group object.
933 Rectangle aSnapRect = pNew->GetSnapRect();
934 if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() )
936 const Point aPoint( 0, 0 );
937 // OD 2004-04-05 #i26791# - direct drawing object
938 // positioning for group members
939 pNew->NbcSetAnchorPos( aPoint );
940 pNew->NbcSetSnapRect( aSnapRect );
943 Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() );
945 Point aGrpAnchor( 0, 0 );
946 SdrObjList* pList = pNew->GetObjList();
947 if ( pList )
949 SdrObject* pOwner = pList->GetOwnerObj();
950 if ( pOwner )
952 SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner);
953 aGrpAnchor = pThisGroup->GetAnchorPos();
957 // OD 2004-04-05 #i26791# - direct drawing object
958 // positioning for group members
959 pNew->NbcSetAnchorPos( aGrpAnchor );
960 pNew->SetSnapRect( aSnapRect );
962 bInsWithFmt = FALSE;
966 if( bInsWithFmt )
968 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
969 if( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
970 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
971 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
973 SwPosition* pPos = PCURCRSR->GetPoint();
974 // #108784# allow shapes (no controls) in header/footer
975 if( RES_DRAWFRMFMT == rCpyFmt.Which() &&
976 GetDoc()->IsInHeaderFooter( pPos->nNode ) &&
977 CheckControlLayer( rCpyFmt.FindSdrObject() ) )
978 continue;
980 aAnchor.SetAnchor( pPos );
982 else if( FLY_PAGE == aAnchor.GetAnchorId() )
984 aAnchor.SetPageNum( GetPhyPageNum() );
986 else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
988 Point aPt;
989 lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(),
990 0, aPt, *this, aAnchor, aPt, FALSE );
993 SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
995 if( pNew )
997 if( RES_FLYFRMFMT == pNew->Which() )
999 const Point aPt( GetCrsrDocPos() );
1000 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)->
1001 GetFrm( &aPt, FALSE );
1002 if( pFlyFrm )
1003 SelectFlyFrm( *pFlyFrm, TRUE );
1004 // immer nur den ersten Fly-Frame nehmen; die anderen
1005 // wurden ueber Fly in Fly ins ClipBoard kopiert !
1006 break;
1008 else
1010 ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format.");
1011 // --> OD 2005-09-01 #i52780# - drawing object has
1012 // to be made visible on paste.
1014 SwDrawContact* pContact =
1015 static_cast<SwDrawContact*>(pNew->FindContactObj());
1016 pContact->MoveObjToVisibleLayer( pContact->GetMaster() );
1018 // <--
1019 SdrObject *pObj = pNew->FindSdrObject();
1020 SwDrawView *pDV = Imp()->GetDrawView();
1021 pDV->MarkObj( pObj, pDV->GetSdrPageView() );
1022 // --> OD 2005-04-15 #i47455# - notify draw frame format
1023 // that position attributes are already set.
1024 if ( pNew->ISA(SwDrawFrmFmt) )
1026 static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet();
1028 // <--
1034 else
1036 if( bDelTbl && IsTableMode() )
1038 SwEditShell::Delete();
1039 bDelTbl = FALSE;
1042 SwPosition& rInsPos = *PCURCRSR->GetPoint();
1043 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().
1044 FindTableBoxStartNode();
1045 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() -
1046 pBoxNd->GetIndex() &&
1047 aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode )
1049 // es wird mehr als 1 Node in die akt. Box kopiert. Dann
1050 // muessen die BoxAttribute aber entfernt werden.
1051 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
1053 //find out if the clipboard document starts with a table
1054 bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
1055 SwPosition aInsertPosition( rInsPos );
1058 SwNodeIndex aIndexBefore(rInsPos.nNode);
1060 aIndexBefore--;
1062 pClpDoc->CopyRange( aCpyPam, rInsPos, false );
1065 aIndexBefore++;
1066 SwPaM aPaM(SwPosition(aIndexBefore, 0),
1067 SwPosition(rInsPos.nNode, 0));
1069 aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
1073 SaveTblBoxCntnt( &rInsPos );
1074 if(bIncludingPageFrames && bStartWithTable)
1076 //remove the paragraph in front of the table
1077 SwPaM aPara(aInsertPosition);
1078 GetDoc()->DelFullPara(aPara);
1080 //additionally copy page bound frames
1081 if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->Count() )
1083 // create a draw view if necessary
1084 if( !Imp()->GetDrawView() )
1085 MakeDrawView();
1087 for ( USHORT i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
1089 BOOL bInsWithFmt = TRUE;
1090 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
1091 if( bInsWithFmt )
1093 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1094 if( FLY_PAGE == aAnchor.GetAnchorId() )
1096 aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
1098 else
1099 continue;
1100 GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1106 FOREACHPAM_END()
1109 GetDoc()->EndUndo( UNDO_INSGLOSSARY, NULL );
1111 // wurden neue Tabellenformeln eingefuegt ?
1112 if( pTblFldTyp->GetDepends() )
1114 // alte Actions beenden; die Tabellen-Frames werden angelegt und
1115 // eine Selection kann erzeugt werden
1116 USHORT nActCnt;
1117 for( nActCnt = 0; ActionPend(); ++nActCnt )
1118 EndAllAction();
1120 for( ; nActCnt; --nActCnt )
1121 StartAllAction();
1123 GetDoc()->UnlockExpFlds();
1124 GetDoc()->UpdateFlds(NULL, false);
1125 EndAllAction();
1127 return bRet;
1130 /*-- 14.06.2004 13:31:17---------------------------------------------------
1132 -----------------------------------------------------------------------*/
1133 BOOL SwFEShell::PastePages( SwFEShell& rToFill, USHORT nStartPage, USHORT nEndPage)
1135 Push();
1136 if(!GotoPage(nStartPage))
1138 Pop(sal_False);
1139 return FALSE;
1141 MovePage( fnPageCurr, fnPageStart );
1142 SwPaM aCpyPam( *GetCrsr()->GetPoint() );
1143 String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName();
1144 SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, TRUE );
1145 if( pDesc )
1146 rToFill.ChgCurPageDesc( *pDesc );
1148 if(!GotoPage(nEndPage))
1150 Pop(sal_False);
1151 return FALSE;
1153 //if the page starts with a table a paragraph has to be inserted before
1154 SwNode* pTableNode = aCpyPam.GetNode()->FindTableNode();
1155 if(pTableNode)
1157 //insert a paragraph
1158 StartUndo(UNDO_INSERT);
1159 SwNodeIndex aTblIdx( *pTableNode, -1 );
1160 SwPosition aBefore(aTblIdx);
1161 if(GetDoc()->AppendTxtNode( aBefore ))
1163 SwPaM aTmp(aBefore);
1164 aCpyPam = aTmp;
1166 EndUndo(UNDO_INSERT);
1169 MovePage( fnPageCurr, fnPageEnd );
1170 aCpyPam.SetMark();
1171 *aCpyPam.GetMark() = *GetCrsr()->GetPoint();
1173 SET_CURR_SHELL( this );
1175 StartAllAction();
1176 GetDoc()->LockExpFlds();
1177 SetSelection(aCpyPam);
1178 // copy the text of the selection
1179 SwEditShell::Copy(&rToFill);
1181 if(pTableNode)
1183 //remove the inserted paragraph
1184 Undo();
1185 //remove the paragraph in the second doc, too
1186 SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 );
1187 SwPaM aPara( aIdx ); //DocStart
1188 rToFill.GetDoc()->DelFullPara(aPara);
1190 // now the page bound objects
1191 //additionally copy page bound frames
1192 if( GetDoc()->GetSpzFrmFmts()->Count() )
1194 // create a draw view if necessary
1195 if( !rToFill.Imp()->GetDrawView() )
1196 rToFill.MakeDrawView();
1198 for ( USHORT i = 0; i < GetDoc()->GetSpzFrmFmts()->Count(); ++i )
1200 const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i];
1201 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1202 if( FLY_PAGE == aAnchor.GetAnchorId() &&
1203 aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage)
1205 aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1);
1207 else
1208 continue;
1209 rToFill.GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1212 GetDoc()->UnlockExpFlds();
1213 GetDoc()->UpdateFlds(NULL, false);
1214 Pop(sal_False);
1215 EndAllAction();
1217 return TRUE;
1220 BOOL SwFEShell::GetDrawObjGraphic( ULONG nFmt, Graphic& rGrf ) const
1222 ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
1223 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1224 BOOL bConvert = TRUE;
1225 if( rMrkList.GetMarkCount() )
1227 if( rMrkList.GetMarkCount() == 1 &&
1228 rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) )
1230 // Rahmen selektiert
1231 if( CNT_GRF == GetCntType() )
1233 // --> OD 2005-02-09 #119353# - robust
1234 const Graphic* pGrf( GetGraphic() );
1235 if ( pGrf )
1237 Graphic aGrf( *pGrf );
1238 if( SOT_FORMAT_GDIMETAFILE == nFmt )
1240 if( GRAPHIC_BITMAP != aGrf.GetType() )
1242 rGrf = aGrf;
1243 bConvert = FALSE;
1245 else if( GetWin() )
1247 Size aSz;
1248 Point aPt;
1249 GetGrfSize( aSz );
1251 VirtualDevice aVirtDev;
1252 aVirtDev.EnableOutput( FALSE );
1254 MapMode aTmp( GetWin()->GetMapMode() );
1255 aTmp.SetOrigin( aPt );
1256 aVirtDev.SetMapMode( aTmp );
1258 GDIMetaFile aMtf;
1259 aMtf.Record( &aVirtDev );
1260 aGrf.Draw( &aVirtDev, aPt, aSz );
1261 aMtf.Stop();
1262 aMtf.SetPrefMapMode( aTmp );
1263 aMtf.SetPrefSize( aSz );
1264 rGrf = aMtf;
1267 else if( GRAPHIC_BITMAP == aGrf.GetType() )
1269 rGrf = aGrf;
1270 bConvert = FALSE;
1272 else
1274 //fix(23806): Nicht die Originalgroesse, sondern die
1275 //aktuelle. Anderfalls kann es passieren, dass z.B. bei
1276 //Vektorgrafiken mal eben zig MB angefordert werden.
1277 const Size aSz( FindFlyFrm()->Prt().SSize() );
1278 VirtualDevice aVirtDev( *GetWin() );
1280 MapMode aTmp( MAP_TWIP );
1281 aVirtDev.SetMapMode( aTmp );
1282 if( aVirtDev.SetOutputSize( aSz ) )
1284 aGrf.Draw( &aVirtDev, Point(), aSz );
1285 rGrf = aVirtDev.GetBitmap( Point(), aSz );
1287 else
1289 rGrf = aGrf;
1290 bConvert = FALSE;
1294 // <--
1297 else if( SOT_FORMAT_GDIMETAFILE == nFmt )
1298 rGrf = Imp()->GetDrawView()->GetAllMarkedMetaFile();
1299 else if( SOT_FORMAT_BITMAP == nFmt )
1300 rGrf = Imp()->GetDrawView()->GetAllMarkedBitmap();
1302 return bConvert;
1305 // --> OD 2005-08-03 #i50824#
1306 // --> OD 2006-03-01 #b6382898#
1307 // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1308 void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel )
1310 for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum )
1312 // setup object iterator in order to iterate through all objects
1313 // including objects in group objects, but exclusive group objects.
1314 SdrObjListIter aIter(*(_pModel->GetPage( nPgNum )));
1315 while( aIter.IsMore() )
1317 SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
1318 if( pOle2Obj )
1320 // found an ole2 shape
1321 SdrObjList* pObjList = pOle2Obj->GetObjList();
1323 // get its graphic
1324 Graphic aGraphic;
1325 pOle2Obj->Connect();
1326 Graphic* pGraphic = pOle2Obj->GetGraphic();
1327 if( pGraphic )
1328 aGraphic = *pGraphic;
1329 pOle2Obj->Disconnect();
1331 // create new graphic shape with the ole graphic and shape size
1332 SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() );
1333 // apply layer of ole2 shape at graphic shape
1334 pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
1336 // replace ole2 shape with the new graphic object and delete the ol2 shape
1337 SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() );
1338 SdrObject::Free( pRemovedObject );
1343 // <--
1344 void SwFEShell::Paste( SvStream& rStrm, USHORT nAction, const Point* pPt )
1346 SET_CURR_SHELL( this );
1347 StartAllAction();
1348 StartUndo();
1350 SvtPathOptions aPathOpt;
1351 FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(),
1352 0, GetDoc()->GetDocShell() );
1353 pModel->GetItemPool().FreezeIdRanges();
1355 rStrm.Seek(0);
1357 uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) );
1358 SvxDrawingLayerImport( pModel, xInputStream );
1360 if ( !Imp()->HasDrawView() )
1361 Imp()->MakeDrawView();
1363 Point aPos( pPt ? *pPt : GetCharRect().Pos() );
1364 SdrView *pView = Imp()->GetDrawView();
1366 //Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren.
1367 if( pModel->GetPageCount() > 0 &&
1368 1 == pModel->GetPage(0)->GetObjCount() &&
1369 1 == pView->GetMarkedObjectList().GetMarkCount() )
1371 // OD 10.07.2003 #110742# - replace a marked 'virtual' drawing object
1372 // by its corresponding 'master' drawing object in the mark list.
1373 SwDrawView::ReplaceMarkedDrawVirtObjs( *pView );
1375 SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0);
1376 SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj();
1378 if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) )
1379 nAction = SW_PASTESDR_REPLACE;
1381 switch( nAction )
1383 case SW_PASTESDR_REPLACE:
1385 const SwFrmFmt* pFmt(0);
1386 const SwFrm* pAnchor(0);
1387 if( pOldObj->ISA(SwVirtFlyDrawObj) )
1389 pFmt = FindFrmFmt( pOldObj );
1391 Point aNullPt;
1392 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt );
1393 pAnchor = pFlyFrm->GetAnchorFrm();
1395 if( pAnchor->FindFooterOrHeader() )
1397 // wenn TextRahmen in der Kopf/Fusszeile steht, dann
1398 // nicht ersetzen, sondern nur einfuegen
1399 nAction = SW_PASTESDR_INSERT;
1400 break;
1404 SdrObject* pNewObj = pClpObj->Clone();
1405 Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() );
1406 Size aOldObjSize( aOldObjRect.GetSize() );
1407 Rectangle aNewRect( pNewObj->GetCurrentBoundRect() );
1408 Size aNewSize( aNewRect.GetSize() );
1410 Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() );
1411 Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height());
1412 pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight);
1414 Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft();
1415 pNewObj->NbcMove(Size(aVec.X(), aVec.Y()));
1417 if( pNewObj->ISA( SdrUnoObj ) )
1418 pNewObj->SetLayer( GetDoc()->GetControlsId() );
1419 else if( pOldObj->ISA( SdrUnoObj ) )
1420 pNewObj->SetLayer( GetDoc()->GetHeavenId() );
1421 else
1422 pNewObj->SetLayer( pOldObj->GetLayer() );
1424 if( pOldObj->ISA(SwVirtFlyDrawObj) )
1426 // Attribute sichern und dam SdrObject setzen
1427 SfxItemSet aFrmSet( pDoc->GetAttrPool(),
1428 RES_SURROUND, RES_ANCHOR );
1429 aFrmSet.Set( pFmt->GetAttrSet() );
1431 Point aNullPt;
1432 if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() )
1434 const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor;
1435 do {
1436 pTmp = pTmp->FindMaster();
1437 ASSERT( pTmp, "Where's my Master?" );
1438 } while( pTmp->IsFollow() );
1439 pAnchor = pTmp;
1441 if( pOldObj->ISA( SdrCaptionObj ))
1442 aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos();
1443 else
1444 aNullPt = aOldObjRect.TopLeft();
1446 Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) );
1447 // OD 2004-04-05 #i26791# - direct positioning of Writer
1448 // fly frame object for <SwDoc::Insert(..)>
1449 pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor );
1450 pNewObj->NbcSetAnchorPos( aNewAnchor );
1452 pOldObj->GetOrdNum();
1454 DelSelectedObj();
1456 pFmt = GetDoc()->Insert( *GetCrsr(), *pNewObj, &aFrmSet, NULL );
1458 else
1459 pView->ReplaceObjectAtView( pOldObj, *Imp()->GetPageView(), pNewObj, TRUE );
1461 break;
1463 case SW_PASTESDR_SETATTR:
1465 SfxItemSet aSet( GetAttrPool() );
1466 aSet.Put(pClpObj->GetMergedItemSet());
1467 pView->SetAttributes( aSet, FALSE );
1469 break;
1471 default:
1472 nAction = SW_PASTESDR_INSERT;
1473 break;
1476 else
1477 nAction = SW_PASTESDR_INSERT;
1479 if( SW_PASTESDR_INSERT == nAction )
1481 GetDoc()->SetNoDrawUndoObj( TRUE );
1483 sal_Bool bDesignMode = pView->IsDesignMode();
1484 if( !bDesignMode )
1485 pView->SetDesignMode( sal_True );
1487 // --> OD 2005-08-03 #i50824#
1488 // --> OD 2006-03-01 #b6382898#
1489 // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1490 lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel );
1491 // <--
1492 pView->Paste( *pModel, aPos );
1494 ULONG nCnt = pView->GetMarkedObjectList().GetMarkCount();
1495 if( nCnt )
1497 const Point aNull( 0, 0 );
1498 for( ULONG i=0; i < nCnt; ++i )
1500 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
1501 pObj->ImpSetAnchorPos( aNull );
1504 pView->SetCurrentObj( OBJ_GRUP, SdrInventor );
1505 if ( nCnt > 1 )
1506 pView->GroupMarked();
1507 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1508 if( pObj->ISA( SdrUnoObj ) )
1510 pObj->SetLayer( GetDoc()->GetControlsId() );
1511 bDesignMode = sal_True;
1513 else
1514 pObj->SetLayer( GetDoc()->GetHeavenId() );
1515 const Rectangle &rSnap = pObj->GetSnapRect();
1516 const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 );
1517 pView->MoveMarkedObj( aDiff );
1518 ImpEndCreate();
1519 if( !bDesignMode )
1520 pView->SetDesignMode( sal_False );
1522 GetDoc()->SetNoDrawUndoObj( FALSE );
1524 EndUndo();
1525 EndAllAction();
1526 delete pModel;
1529 BOOL SwFEShell::Paste( const Graphic &rGrf )
1531 SET_CURR_SHELL( this );
1532 SdrObject* pObj;
1533 SdrView *pView = Imp()->GetDrawView();
1535 BOOL bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() &&
1536 (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() &&
1537 !pObj->ISA( SdrOle2Obj );
1539 if( bRet )
1541 XOBitmap aXOBitmap( rGrf.GetBitmap() );
1542 SfxItemSet aSet( GetAttrPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP );
1543 aSet.Put( XFillStyleItem( XFILL_BITMAP ));
1544 aSet.Put( XFillBitmapItem( aEmptyStr, aXOBitmap ));
1545 pView->SetAttributes( aSet, FALSE );
1547 return bRet;