update dev300-m58
[ooovba.git] / sw / source / core / frmedt / fecopy.cxx
blobbc2467e74cfebef654f99dcf696460928589e081
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 #ifdef WIN
38 #define NEEDED_BY_FESHVIEW
39 #endif
41 #ifndef _GRAPH_HXX
42 #include <vcl/graph.hxx>
43 #endif
44 #include <sot/formats.hxx>
45 #include <sot/storage.hxx>
46 #include <svtools/pathoptions.hxx>
47 #include <sfx2/dispatch.hxx>
48 #include <sfx2/viewsh.hxx>
49 #include <svx/xexch.hxx>
50 #include <svx/xflasit.hxx>
51 #include <svx/xfillit0.hxx>
52 #include <svx/xflclit.hxx>
53 #include <svx/brshitem.hxx>
54 #include <svx/svdocapt.hxx>
55 #include <svx/svdouno.hxx>
56 #include <svx/xfillit.hxx>
57 #include <svx/svdpage.hxx>
58 #include <svx/svdogrp.hxx>
59 #include <svx/xoutbmp.hxx>
60 #include <svx/svdoole2.hxx>
61 #ifndef _FM_FMMODEL_HXX
62 #include <svx/fmmodel.hxx>
63 #endif
64 #include <svx/unomodel.hxx>
65 // --> OD 2005-08-03 #i50824#
66 #include <svx/svditer.hxx>
67 // <--
68 // --> OD 2006-03-01 #b6382898#
69 #include <svx/svdograf.hxx>
70 // <--
71 #include <unotools/streamwrap.hxx>
72 #include <fmtanchr.hxx>
73 #include <fmtcntnt.hxx>
74 #include <fmtornt.hxx>
75 #include <fmtflcnt.hxx>
76 #include <frmfmt.hxx>
77 #include <docary.hxx>
78 #include <txtfrm.hxx>
79 #include <txtflcnt.hxx>
80 #include <fesh.hxx>
81 #include <doc.hxx>
82 #include <rootfrm.hxx>
83 #include <ndtxt.hxx>
84 #include <pam.hxx>
85 #include <tblsel.hxx>
86 #include <swtable.hxx>
87 #include <flyfrm.hxx>
88 #include <pagefrm.hxx>
89 #include <fldbas.hxx>
90 #include <edimp.hxx>
91 #include <swundo.hxx>
92 #include <viewimp.hxx>
93 #include <dview.hxx>
94 #include <dcontact.hxx>
95 #include <dflyobj.hxx>
96 #ifndef _DOCSH_HXX
97 #include <docsh.hxx>
98 #endif
99 #include <pagedesc.hxx>
100 #include <mvsave.hxx>
101 #include <vcl/virdev.hxx>
104 using namespace ::com::sun::star;
106 /*************************************************************************
108 |* SwFEShell::Copy() Copy fuer das Interne Clipboard.
109 |* Kopiert alle Selektionen in das Clipboard.
111 |* Ersterstellung JP ??
112 |* Letzte Aenderung MA 22. Feb. 95
114 |*************************************************************************/
116 BOOL SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt )
118 ASSERT( pClpDoc, "kein Clipboard-Dokument" );
120 pClpDoc->DoUndo( FALSE ); // immer auf FALSE !!
122 // steht noch Inhalt im ClpDocument, dann muss dieser geloescht werden
123 SwNodeIndex aSttIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
124 SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
125 if( !pTxtNd || pTxtNd->GetTxt().Len() ||
126 aSttIdx.GetIndex()+1 != pClpDoc->GetNodes().GetEndOfContent().GetIndex() )
128 pClpDoc->GetNodes().Delete( aSttIdx,
129 pClpDoc->GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
130 pTxtNd = pClpDoc->GetNodes().MakeTxtNode( aSttIdx,
131 (SwTxtFmtColl*)pClpDoc->GetDfltTxtFmtColl() );
132 aSttIdx--;
135 // stehen noch FlyFrames rum, loesche auch diese
136 for( USHORT n = 0; n < pClpDoc->GetSpzFrmFmts()->Count(); ++n )
138 SwFlyFrmFmt* pFly = (SwFlyFrmFmt*)(*pClpDoc->GetSpzFrmFmts())[n];
139 pClpDoc->DelLayoutFmt( pFly );
141 pClpDoc->GCFieldTypes(); // loesche die FieldTypes
143 // wurde ein String uebergeben, so kopiere diesen in das Clipboard-
144 // Dokument. Somit kann auch der Calculator das interne Clipboard
145 // benutzen.
146 if( pNewClpTxt )
148 pTxtNd->Insert( *pNewClpTxt, SwIndex( pTxtNd ) );
149 return TRUE; // das wars.
152 pClpDoc->LockExpFlds();
153 pClpDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
154 BOOL bRet;
156 // soll ein FlyFrame kopiert werden ?
157 if( IsFrmSelected() )
159 // hole das FlyFormat
160 SwFlyFrm* pFly = FindFlyFrm();
161 SwFrmFmt* pFlyFmt = pFly->GetFmt();
162 SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
164 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
165 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
166 FLY_AT_FLY == aAnchor.GetAnchorId() ||
167 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
169 SwPosition aPos( aSttIdx );
170 if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
171 aPos.nContent.Assign( pTxtNd, 0 );
172 aAnchor.SetAnchor( &aPos );
174 pFlyFmt = pClpDoc->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
176 // sorge dafuer das das "RootFmt" als erstes im SpzArray-steht
177 // (Es wurden ggf. Flys in Flys kopiert.
178 SwSpzFrmFmts& rSpzFrmFmts = *(SwSpzFrmFmts*)pClpDoc->GetSpzFrmFmts();
179 if( rSpzFrmFmts[ 0 ] != pFlyFmt )
181 USHORT nPos = rSpzFrmFmts.GetPos( pFlyFmt );
182 ASSERT( nPos != USHRT_MAX, "Fly steht nicht im Spz-Array" );
184 rSpzFrmFmts.Remove( nPos );
185 rSpzFrmFmts.Insert( pFlyFmt, 0 );
188 if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
190 // JP 13.02.99 Bug 61863: wenn eine Rahmenselektion ins Clipboard
191 // gestellt wird, so muss beim Pasten auch wieder
192 // eine solche vorgefunden werden. Also muss im Node
193 // das kopierte TextAttribut wieder entfernt werden,
194 // sonst wird es als TextSelektion erkannt
195 const SwIndex& rIdx = pFlyFmt->GetAnchor().GetCntntAnchor()->nContent;
196 SwTxtFlyCnt* pTxtFly = (SwTxtFlyCnt*)pTxtNd->GetTxtAttr(
197 rIdx, RES_TXTATR_FLYCNT );
198 if( pTxtFly )
200 ((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 );
201 pTxtNd->Erase( rIdx, 1 );
204 bRet = TRUE;
206 else if ( IsObjSelected() )
208 SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 ));
209 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
210 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
212 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
214 if( Imp()->GetDrawView()->IsGroupEntered() ||
215 ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
217 SfxItemSet aSet( pClpDoc->GetAttrPool(), aFrmFmtSetRange );
219 SwFmtAnchor aAnchor( FLY_AT_CNTNT );
220 aAnchor.SetAnchor( &aPos );
221 aSet.Put( aAnchor );
223 SdrObject* pNew = pClpDoc->CloneSdrObj( *pObj, FALSE, TRUE );
225 SwPaM aTemp(aPos);
226 pClpDoc->Insert(aTemp, *pNew, &aSet, NULL);
228 else
230 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
231 SwFrmFmt *pFmt = pContact->GetFmt();
232 SwFmtAnchor aAnchor( pFmt->GetAnchor() );
233 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
234 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
235 FLY_AT_FLY == aAnchor.GetAnchorId() ||
236 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
238 aAnchor.SetAnchor( &aPos );
241 pClpDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
244 bRet = TRUE;
246 else
247 bRet = _CopySelToDoc( pClpDoc, 0 ); // kopiere die Selectionen
249 pClpDoc->SetRedlineMode_intern((RedlineMode_t)0 );
250 pClpDoc->UnlockExpFlds();
251 if( !pClpDoc->IsExpFldsLocked() )
252 pClpDoc->UpdateExpFlds(NULL, true);
254 return bRet;
257 const Point &lcl_FindBasePos( const SwFrm *pFrm, const Point &rPt )
259 const SwFrm *pF = pFrm;
260 while ( pF && !pF->Frm().IsInside( rPt ) )
262 if ( pF->IsCntntFrm() )
263 pF = ((SwCntntFrm*)pF)->GetFollow();
264 else
265 pF = 0;
267 if ( pF )
268 return pF->Frm().Pos();
269 else
270 return pFrm->Frm().Pos();
273 BOOL lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly,
274 const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor,
275 Point& rNewPos, BOOL bCheckFlyRecur )
277 BOOL bRet = TRUE;
278 rAnchor.SetAnchor( &rPos );
279 SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->GetFrm( &rInsPt, 0, FALSE );
280 SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm();
281 if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( *pTmpFly ) )
282 bRet = FALSE;
283 else if ( FLY_AT_FLY == rAnchor.GetAnchorId() )
285 if( pTmpFly )
287 const SwNodeIndex& rIdx = *pTmpFly->GetFmt()->GetCntnt().GetCntntIdx();
288 SwPosition aPos( rIdx );
289 rAnchor.SetAnchor( &aPos );
290 rNewPos = pTmpFly->Frm().Pos();
292 else
294 rAnchor.SetType( FLY_PAGE );
295 rAnchor.SetPageNum( rDestShell.GetPageNumber( rInsPt ) );
296 const SwFrm *pPg = pTmpFrm->FindPageFrm();
297 rNewPos = pPg->Frm().Pos();
300 else
301 rNewPos = ::lcl_FindBasePos( pTmpFrm, rInsPt );
302 return bRet;
305 BOOL SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt,
306 const Point& rInsPt, BOOL bIsMove, BOOL bSelectInsert )
308 BOOL bRet = TRUE;
310 //Die Liste muss kopiert werden, weil unten die neuen Objekte
311 //selektiert werden.
312 const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() );
313 ULONG nMarkCount = aMrkList.GetMarkCount();
314 if( !pDestShell->Imp()->GetDrawView() )
315 // sollte mal eine erzeugt werden
316 pDestShell->MakeDrawView();
317 else if( bSelectInsert )
318 pDestShell->Imp()->GetDrawView()->UnmarkAll();
320 SdrPageView *pDestPgView = pDestShell->Imp()->GetPageView(),
321 *pSrcPgView = Imp()->GetPageView();
322 SwDrawView *pDestDrwView = pDestShell->Imp()->GetDrawView(),
323 *pSrcDrwView = Imp()->GetDrawView();
324 SwDoc* pDestDoc = pDestShell->GetDoc();
326 Size aSiz( rInsPt.X() - rSttPt.X(), rInsPt.Y() - rSttPt.Y() );
327 for( USHORT i = 0; i < nMarkCount; ++i )
329 SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
331 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
332 SwFrmFmt *pFmt = pContact->GetFmt();
333 const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
335 BOOL bInsWithFmt = TRUE;
337 if( pDestDrwView->IsGroupEntered() )
339 // in die Gruppe einfuegen, wenns aus einer betretenen Gruppe
340 // kommt oder das Object nicht zeichengebunden ist
341 if( pSrcDrwView->IsGroupEntered() ||
342 FLY_IN_CNTNT != rAnchor.GetAnchorId() )
345 SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
346 GetDoc() == pDestDoc, FALSE );
347 pNew->NbcMove( aSiz );
348 pDestDrwView->InsertObjectAtView( pNew, *pDestPgView );
349 bInsWithFmt = FALSE;
353 if( bInsWithFmt )
355 SwFmtAnchor aAnchor( rAnchor );
356 Point aNewAnch;
358 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
359 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
360 FLY_AT_FLY == aAnchor.GetAnchorId() ||
361 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
363 if ( this == pDestShell )
365 //gleiche Shell? Dann erfrage die Position an der
366 //uebergebenen DokumentPosition
367 SwPosition aPos( *GetCrsr()->GetPoint() );
368 Point aPt( rInsPt );
369 aPt -= rSttPt - pObj->GetSnapRect().TopLeft();
370 SwCrsrMoveState aState( MV_SETONLYTEXT );
371 GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
372 const SwNode *pNd;
373 if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
374 bRet = FALSE;
375 else
376 bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt,
377 *pDestShell, aAnchor, aNewAnch, FALSE );
379 else
381 SwPaM *pCrsr = pDestShell->GetCrsr();
382 if( pCrsr->GetNode()->IsNoTxtNode() )
383 bRet = FALSE;
384 else
385 bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(),
386 *pCrsr->GetNode(), 0, rInsPt,
387 *pDestShell, aAnchor,
388 aNewAnch, FALSE );
391 else if( FLY_PAGE == aAnchor.GetAnchorId() )
393 aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
394 const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
395 const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
396 if ( pPg )
397 aNewAnch = pPg->Frm().Pos();
400 if( bRet )
402 if( pSrcDrwView->IsGroupEntered() ||
403 ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
405 SfxItemSet aSet( pDestDoc->GetAttrPool(),aFrmFmtSetRange);
406 aSet.Put( aAnchor );
407 SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
408 GetDoc() == pDestDoc, TRUE );
409 pFmt = pDestDoc->Insert( *pDestShell->GetCrsr(),
410 *pNew, &aSet, NULL );
412 else
413 pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
415 //Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind.
416 if ( pFmt )
418 SdrObject* pNew = pFmt->FindSdrObject();
419 if( FLY_IN_CNTNT != aAnchor.GetAnchorId() )
421 Point aPos( rInsPt );
422 aPos -= aNewAnch;
423 aPos -= rSttPt - pObj->GetSnapRect().TopLeft();
424 // OD 2004-04-05 #i26791# - change attributes instead of
425 // direct positioning
426 pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
427 pFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
428 // --> OD 2005-04-15 #i47455# - notify draw frame format
429 // that position attributes are already set.
430 if ( pFmt->ISA(SwDrawFrmFmt) )
432 static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet();
434 // <--
436 if( bSelectInsert )
437 pDestDrwView->MarkObj( pNew, pDestPgView );
443 if ( bIsMove && bRet )
445 if( pDestShell == this )
447 const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() );
448 pSrcDrwView->UnmarkAll();
450 ULONG nMrkCnt = aMrkList.GetMarkCount();
451 USHORT i;
452 for ( i = 0; i < nMrkCnt; ++i )
454 SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
455 pSrcDrwView->MarkObj( pObj, pSrcPgView );
457 DelSelectedObj();
458 nMrkCnt = aList.GetMarkCount();
459 for ( i = 0; i < nMrkCnt; ++i )
461 SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj();
462 pSrcDrwView->MarkObj( pObj, pSrcPgView );
465 else
466 DelSelectedObj();
469 return bRet;
472 BOOL SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
473 const Point& rInsPt, BOOL bIsMove, BOOL bSelectInsert )
475 BOOL bRet = FALSE;
477 ASSERT( pDestShell, "Copy ohne DestShell." );
478 ASSERT( this == pDestShell || !pDestShell->IsObjSelected(),
479 "Dest-Shell darf nie im Obj-Modus sein" );
481 SET_CURR_SHELL( pDestShell );
483 pDestShell->StartAllAction();
484 pDestShell->GetDoc()->LockExpFlds();
486 // Referenzen sollen verschoben werden.
487 BOOL bCopyIsMove = pDoc->IsCopyIsMove();
488 if( bIsMove )
489 // am Doc ein Flag setzen, damit in den TextNodes
490 pDoc->SetCopyIsMove( TRUE );
492 RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode();
493 pDestShell->GetDoc()->SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES));
495 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
496 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
497 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
498 // besorgt)
499 SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD );
501 if( IsFrmSelected() )
503 SwFlyFrm* pFly = FindFlyFrm();
504 SwFrmFmt* pFlyFmt = pFly->GetFmt();
505 SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
506 bRet = TRUE;
507 Point aNewAnch;
509 if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
510 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
511 FLY_AT_FLY == aAnchor.GetAnchorId() ||
512 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
514 if ( this == pDestShell )
516 // gleiche Shell? Dann erfrage die Position an der
517 // uebergebenen DokumentPosition
518 SwPosition aPos( *GetCrsr()->GetPoint() );
519 Point aPt( rInsPt );
520 aPt -= rSttPt - pFly->Frm().Pos();
521 SwCrsrMoveState aState( MV_SETONLYTEXT );
522 GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
523 const SwNode *pNd;
524 if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
525 bRet = FALSE;
526 else
527 { //Nicht in sich selbst kopieren
528 const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
529 if ( aPos.nNode > *pTmp && aPos.nNode <
530 pTmp->GetNode().EndOfSectionIndex() )
532 bRet = FALSE;
534 else
535 bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
536 *pDestShell, aAnchor, aNewAnch, TRUE );
539 else
541 const SwPaM *pCrsr = pDestShell->GetCrsr();
542 if( pCrsr->GetNode()->IsNoTxtNode() )
543 bRet = FALSE;
544 else
545 bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(),
546 pFly, rInsPt, *pDestShell, aAnchor,
547 aNewAnch, GetDoc() == pDestShell->GetDoc());
550 else if( FLY_PAGE == aAnchor.GetAnchorId() )
552 aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
553 const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
554 const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
555 if ( pPg )
556 aNewAnch = pPg->Frm().Pos();
558 else {
559 ASSERT( !this, "was fuer ein Anchor ist es denn?" );
562 if( bRet )
564 SwFrmFmt *pOldFmt = pFlyFmt;
565 pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
567 if( FLY_IN_CNTNT != aAnchor.GetAnchorId() )
569 Point aPos( rInsPt );
570 aPos -= aNewAnch;
571 aPos -= rSttPt - pFly->Frm().Pos();
572 pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
573 pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
576 const Point aPt( pDestShell->GetCrsrDocPos() );
578 if( bIsMove )
579 GetDoc()->DelLayoutFmt( pOldFmt );
581 // nur selektieren wenn es in der gleichen Shell verschoben/
582 // kopiert wird
583 if( bSelectInsert )
585 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, FALSE );
586 if( pFlyFrm )
588 //JP 12.05.98: sollte das nicht im SelectFlyFrm stehen???
589 pDestShell->Imp()->GetDrawView()->UnmarkAll();
590 pDestShell->SelectFlyFrm( *pFlyFrm, TRUE );
594 if( this != pDestShell && !pDestShell->HasShFcs() )
595 pDestShell->Imp()->GetDrawView()->hideMarkHandles();
598 else if ( IsObjSelected() )
599 bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert );
600 else if( IsTableMode() )
602 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
603 // von der Originalen an und kopiere die selectierten Boxen.
604 // Die Groessen werden prozentual korrigiert.
606 // lasse ueber das Layout die Boxen suchen
607 const SwTableNode* pTblNd;
608 SwSelBoxes aBoxes;
609 GetTblSel( *this, aBoxes );
610 if( aBoxes.Count() &&
611 0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) )
613 SwPosition* pDstPos = 0;
614 if( this == pDestShell )
616 // gleiche Shell? Dann erzeuge einen Crsr an der
617 // uebergebenen DokumentPosition
618 pDstPos = new SwPosition( *GetCrsr()->GetPoint() );
619 Point aPt( rInsPt );
620 GetLayout()->GetCrsrOfst( pDstPos, aPt );
621 if( !pDstPos->nNode.GetNode().IsNoTxtNode() )
622 bRet = TRUE;
624 else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
626 pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
627 bRet = TRUE;
630 if( bRet )
632 if( GetDoc() == pDestShell->GetDoc() )
633 ParkTblCrsr();
635 bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0,
636 bIsMove && this == pDestShell &&
637 aBoxes.Count() == pTblNd->GetTable().
638 GetTabSortBoxes().Count(),
639 this != pDestShell );
641 if( this != pDestShell )
642 *pDestShell->GetCrsr()->GetPoint() = *pDstPos;
644 // wieder alle geparkten Crsr erzeugen?
645 if( GetDoc() == pDestShell->GetDoc() )
646 GetCrsr();
648 // JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte
649 // Cursor auf die EinfuegePos. positioniert wird
650 if( this == pDestShell )
651 GetCrsrDocPos() = rInsPt;
653 delete pDstPos;
656 else
658 bRet = TRUE;
659 if( this == pDestShell )
661 // gleiche Shell? Dann erfrage die Position an der
662 // uebergebenen DokumentPosition
663 SwPosition aPos( *GetCrsr()->GetPoint() );
664 Point aPt( rInsPt );
665 GetLayout()->GetCrsrOfst( &aPos, aPt );
666 bRet = !aPos.nNode.GetNode().IsNoTxtNode();
668 else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
669 bRet = FALSE;
671 if( bRet )
672 bRet = 0 != SwEditShell::Copy( pDestShell );
675 pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode );
676 pDoc->SetCopyIsMove( bCopyIsMove );
678 // wurden neue Tabellenformeln eingefuegt ?
679 if( pTblFldTyp->GetDepends() )
681 // alte Actions beenden; die Tabellen-Frames werden angelegt und
682 // eine SSelection kann erzeugt werden
683 USHORT nActCnt;
684 for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt )
685 pDestShell->EndAllAction();
687 for( ; nActCnt; --nActCnt )
688 pDestShell->StartAllAction();
690 pDestShell->GetDoc()->UnlockExpFlds();
691 pDestShell->GetDoc()->UpdateFlds(NULL, false);
693 pDestShell->EndAllAction();
694 return bRet;
697 /*************************************************************************
699 |* SwFEShell::Paste() Paste fuer das Interne Clipboard.
700 |* Kopiert den Inhalt vom Clipboard in das Dokument.
702 |* Ersterstellung JP ??
703 |* Letzte Aenderung MA 22. Feb. 95
705 |*************************************************************************/
707 namespace {
708 typedef boost::shared_ptr<SwPaM> PaMPtr;
709 typedef boost::shared_ptr<SwPosition> PositionPtr;
710 typedef std::pair< PaMPtr, PositionPtr > Insertion;
713 BOOL SwFEShell::Paste( SwDoc* pClpDoc, BOOL bIncludingPageFrames )
715 SET_CURR_SHELL( this );
716 ASSERT( pClpDoc, "kein Clipboard-Dokument" );
717 const USHORT nStartPageNumber = GetPhyPageNum();
718 // dann bis zum Ende vom Nodes Array
719 SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
720 SwPaM aCpyPam( aIdx ); //DocStart
722 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
723 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
724 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
725 // besorgt)
726 SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
728 SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode();
729 if( !pSrcNd ) // TabellenNode ?
730 { // nicht ueberspringen!!
731 SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode();
732 if( pCNd )
733 aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 );
734 else if( !aCpyPam.Move( fnMoveForward, fnGoNode ))
735 aCpyPam.Move( fnMoveBackward, fnGoNode );
738 aCpyPam.SetMark();
739 aCpyPam.Move( fnMoveForward, fnGoDoc );
741 BOOL bRet = TRUE, bDelTbl = TRUE;
742 StartAllAction();
743 GetDoc()->StartUndo( UNDO_INSGLOSSARY, NULL );
744 GetDoc()->LockExpFlds();
746 // When the clipboard content has been created by a rectangular selection
747 // the pasting is more sophisticated:
748 // every paragraph will be inserted into another position.
749 // The first positions are given by the actual cursor ring,
750 // if there are more text portions to insert than cursor in this ring,
751 // the additional insert positions will be created by moving the last
752 // cursor position into the next line (like pressing the cursor down key)
753 if( pClpDoc->IsColumnSelection() && !IsTableMode() )
755 // Creation of the list of insert positions
756 std::list< Insertion > aCopyList;
757 // The number of text portions of the rectangular selection
758 const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex()
759 - aCpyPam.GetMark()->nNode.GetIndex();
760 sal_uInt32 nCount = nSelCount;
761 SwNodeIndex aClpIdx( aIdx );
762 SwPaM* pStartCursor = GetCrsr();
763 SwPaM* pCurrCrsr = pStartCursor;
764 sal_uInt32 nCursorCount = pStartCursor->numberOf();
765 // If the target selection is a multi-selection, often the last and first
766 // cursor of the ring points to identical document positions. Then
767 // we should avoid double insertion of text portions...
768 while( nCursorCount > 1 && *pCurrCrsr->GetPoint() ==
769 *(dynamic_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) )
771 --nCursorCount;
772 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
773 pStartCursor = pCurrCrsr;
775 SwPosition aStartPos( *pStartCursor->GetPoint() );
776 SwPosition aInsertPos( aStartPos ); // first insertion position
777 bool bCompletePara = false;
778 USHORT nMove = 0;
779 while( nCount )
781 --nCount;
782 ASSERT( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" )
783 if( aIdx.GetNode().GetCntntNode() ) // robust
785 Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ),
786 PositionPtr( new SwPosition( aInsertPos ) ) );
787 ++aIdx;
788 aInsertion.first->SetMark();
789 if( pStartCursor == pCurrCrsr->GetNext() )
790 { // Now we have to look for insertion positions...
791 if( !nMove ) // Annotate the last given insert position
792 aStartPos = aInsertPos;
793 SwCursor aCrsr( aStartPos, 0, false);
794 // Check if we find another insert position by moving
795 // down the last given position
796 if( aCrsr.UpDown( FALSE, ++nMove, 0, 0 ) )
797 aInsertPos = *aCrsr.GetPoint();
798 else // if there is no paragraph we have to create it
799 bCompletePara = nCount > 0;
800 nCursorCount = 0;
802 else // as long as we find more insert positions in the cursor ring
803 { // we'll take them
804 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
805 aInsertPos = *pCurrCrsr->GetPoint();
806 --nCursorCount;
808 // If there are no more paragraphs e.g. at the end of a document,
809 // we insert complete paragraphs instead of text portions
810 if( bCompletePara )
811 aInsertion.first->GetPoint()->nNode = aIdx;
812 else
813 aInsertion.first->GetPoint()->nContent =
814 aInsertion.first->GetCntntNode()->Len();
815 aCopyList.push_back( aInsertion );
817 // If there are no text portions left but there are some more
818 // cursor positions to fill we have to restart with the first
819 // text portion
820 if( !nCount && nCursorCount )
822 nCount = std::min( nSelCount, nCursorCount );
823 aIdx = aClpIdx; // Start of clipboard content
826 std::list< Insertion >::const_iterator pCurr = aCopyList.begin();
827 std::list< Insertion >::const_iterator pEnd = aCopyList.end();
828 while( pCurr != pEnd )
830 SwPosition& rInsPos = *pCurr->second;
831 SwPaM& rCopy = *pCurr->first;
832 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
833 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() &&
834 rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode )
836 // if more than one node will be copied into a cell
837 // the box attributes have to be removed
838 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
841 SwNodeIndex aIndexBefore(rInsPos.nNode);
842 aIndexBefore--;
843 pClpDoc->Copy( rCopy, rInsPos, false );
845 aIndexBefore++;
846 SwPaM aPaM(SwPosition(aIndexBefore, 0),
847 SwPosition(rInsPos.nNode, 0));
848 aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
851 SaveTblBoxCntnt( &rInsPos );
852 ++pCurr;
855 else
857 FOREACHPAM_START(this)
859 if( pSrcNd &&
860 0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode )))
862 SwPosition aDestPos( *PCURCRSR->GetPoint() );
864 BOOL bParkTblCrsr = FALSE;
865 const SwStartNode* pSttNd = PCURCRSR->GetNode()->FindTableBoxStartNode();
867 // TABLE IN TABLE: Tabelle in Tabelle kopieren
868 // lasse ueber das Layout die Boxen suchen
869 SwSelBoxes aBoxes;
870 if( IsTableMode() ) // Tabellen-Selecktion ??
872 GetTblSel( *this, aBoxes );
873 ParkTblCrsr();
874 bParkTblCrsr = TRUE;
876 else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR &&
877 ( !pSrcNd->GetTable().IsTblComplex() ||
878 pDestNd->GetTable().IsNewModel() ) )
880 // dann die Tabelle "relativ" kopieren
881 SwTableBox* pBox = pDestNd->GetTable().GetTblBox(
882 pSttNd->GetIndex() );
883 ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
884 aBoxes.Insert( pBox );
887 SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode());
888 if( !bParkTblCrsr )
890 // erstmal aus der gesamten Tabelle raus
891 // ????? was ist mit Tabelle alleine im Rahmen ???????
892 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
893 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
894 // #i59539: Don't remove all redline
895 ::PaMCorrAbs( SwNodeIndex( *pDestNd ),
896 SwNodeIndex( *pDestNd->EndOfSectionNode() ),
897 aPos );
900 bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
901 FALSE, FALSE );
903 if( bParkTblCrsr )
904 GetCrsr();
905 else
907 // und wieder in die Box zurueck
908 aNdIdx = *pSttNd;
909 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
910 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
911 // #i59539: Don't remove all redline
912 ::PaMCorrAbs( PCURCRSR->GetPoint()->nNode, aPos );
915 break; // aus der "while"-Schleife heraus
917 else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() &&
918 pClpDoc->GetSpzFrmFmts()->Count() )
920 // so langsam sollte mal eine DrawView erzeugt werden
921 if( !Imp()->GetDrawView() )
922 MakeDrawView();
924 for ( USHORT i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
926 BOOL bInsWithFmt = TRUE;
927 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
929 if( Imp()->GetDrawView()->IsGroupEntered() &&
930 RES_DRAWFRMFMT == rCpyFmt.Which() &&
931 FLY_IN_CNTNT != rCpyFmt.GetAnchor().GetAnchorId() )
933 const SdrObject* pSdrObj = rCpyFmt.FindSdrObject();
934 if( pSdrObj )
936 SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj,
937 FALSE, FALSE );
939 // Insert object sets any anchor position to 0.
940 // Therefore we calculate the absolute position here
941 // and after the insert the anchor of the object
942 // is set to the anchor of the group object.
943 Rectangle aSnapRect = pNew->GetSnapRect();
944 if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() )
946 const Point aPoint( 0, 0 );
947 // OD 2004-04-05 #i26791# - direct drawing object
948 // positioning for group members
949 pNew->NbcSetAnchorPos( aPoint );
950 pNew->NbcSetSnapRect( aSnapRect );
953 Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() );
955 Point aGrpAnchor( 0, 0 );
956 SdrObjList* pList = pNew->GetObjList();
957 if ( pList )
959 SdrObject* pOwner = pList->GetOwnerObj();
960 if ( pOwner )
962 SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner);
963 aGrpAnchor = pThisGroup->GetAnchorPos();
967 // OD 2004-04-05 #i26791# - direct drawing object
968 // positioning for group members
969 pNew->NbcSetAnchorPos( aGrpAnchor );
970 pNew->SetSnapRect( aSnapRect );
972 bInsWithFmt = FALSE;
976 if( bInsWithFmt )
978 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
979 if( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
980 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
981 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
983 SwPosition* pPos = PCURCRSR->GetPoint();
984 // #108784# allow shapes (no controls) in header/footer
985 if( RES_DRAWFRMFMT == rCpyFmt.Which() &&
986 GetDoc()->IsInHeaderFooter( pPos->nNode ) &&
987 CheckControlLayer( rCpyFmt.FindSdrObject() ) )
988 continue;
990 aAnchor.SetAnchor( pPos );
992 else if( FLY_PAGE == aAnchor.GetAnchorId() )
994 aAnchor.SetPageNum( GetPhyPageNum() );
996 else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
998 Point aPt;
999 lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(),
1000 0, aPt, *this, aAnchor, aPt, FALSE );
1003 SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1005 if( pNew )
1007 if( RES_FLYFRMFMT == pNew->Which() )
1009 const Point aPt( GetCrsrDocPos() );
1010 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)->
1011 GetFrm( &aPt, FALSE );
1012 if( pFlyFrm )
1013 SelectFlyFrm( *pFlyFrm, TRUE );
1014 // immer nur den ersten Fly-Frame nehmen; die anderen
1015 // wurden ueber Fly in Fly ins ClipBoard kopiert !
1016 break;
1018 else
1020 ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format.");
1021 // --> OD 2005-09-01 #i52780# - drawing object has
1022 // to be made visible on paste.
1024 SwDrawContact* pContact =
1025 static_cast<SwDrawContact*>(pNew->FindContactObj());
1026 pContact->MoveObjToVisibleLayer( pContact->GetMaster() );
1028 // <--
1029 SdrObject *pObj = pNew->FindSdrObject();
1030 SwDrawView *pDV = Imp()->GetDrawView();
1031 pDV->MarkObj( pObj, pDV->GetSdrPageView() );
1032 // --> OD 2005-04-15 #i47455# - notify draw frame format
1033 // that position attributes are already set.
1034 if ( pNew->ISA(SwDrawFrmFmt) )
1036 static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet();
1038 // <--
1044 else
1046 if( bDelTbl && IsTableMode() )
1048 SwEditShell::Delete();
1049 bDelTbl = FALSE;
1052 SwPosition& rInsPos = *PCURCRSR->GetPoint();
1053 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().
1054 FindTableBoxStartNode();
1055 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() -
1056 pBoxNd->GetIndex() &&
1057 aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode )
1059 // es wird mehr als 1 Node in die akt. Box kopiert. Dann
1060 // muessen die BoxAttribute aber entfernt werden.
1061 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
1063 //find out if the clipboard document starts with a table
1064 bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
1065 SwPosition aInsertPosition( rInsPos );
1068 SwNodeIndex aIndexBefore(rInsPos.nNode);
1070 aIndexBefore--;
1072 pClpDoc->Copy( aCpyPam, rInsPos, false );
1075 aIndexBefore++;
1076 SwPaM aPaM(SwPosition(aIndexBefore, 0),
1077 SwPosition(rInsPos.nNode, 0));
1079 aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
1083 SaveTblBoxCntnt( &rInsPos );
1084 if(bIncludingPageFrames && bStartWithTable)
1086 //remove the paragraph in front of the table
1087 SwPaM aPara(aInsertPosition);
1088 GetDoc()->DelFullPara(aPara);
1090 //additionally copy page bound frames
1091 if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->Count() )
1093 // create a draw view if necessary
1094 if( !Imp()->GetDrawView() )
1095 MakeDrawView();
1097 for ( USHORT i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
1099 BOOL bInsWithFmt = TRUE;
1100 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
1101 if( bInsWithFmt )
1103 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1104 if( FLY_PAGE == aAnchor.GetAnchorId() )
1106 aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
1108 else
1109 continue;
1110 GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1116 FOREACHPAM_END()
1119 GetDoc()->EndUndo( UNDO_INSGLOSSARY, NULL );
1121 // wurden neue Tabellenformeln eingefuegt ?
1122 if( pTblFldTyp->GetDepends() )
1124 // alte Actions beenden; die Tabellen-Frames werden angelegt und
1125 // eine Selection kann erzeugt werden
1126 USHORT nActCnt;
1127 for( nActCnt = 0; ActionPend(); ++nActCnt )
1128 EndAllAction();
1130 for( ; nActCnt; --nActCnt )
1131 StartAllAction();
1133 GetDoc()->UnlockExpFlds();
1134 GetDoc()->UpdateFlds(NULL, false);
1135 EndAllAction();
1137 return bRet;
1140 /*-- 14.06.2004 13:31:17---------------------------------------------------
1142 -----------------------------------------------------------------------*/
1143 BOOL SwFEShell::PastePages( SwFEShell& rToFill, USHORT nStartPage, USHORT nEndPage)
1145 Push();
1146 if(!GotoPage(nStartPage))
1148 Pop(sal_False);
1149 return FALSE;
1151 MovePage( fnPageCurr, fnPageStart );
1152 SwPaM aCpyPam( *GetCrsr()->GetPoint() );
1153 String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName();
1154 SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, TRUE );
1155 if( pDesc )
1156 rToFill.ChgCurPageDesc( *pDesc );
1158 if(!GotoPage(nEndPage))
1160 Pop(sal_False);
1161 return FALSE;
1163 //if the page starts with a table a paragraph has to be inserted before
1164 SwNode* pTableNode = aCpyPam.GetNode()->FindTableNode();
1165 if(pTableNode)
1167 //insert a paragraph
1168 StartUndo(UNDO_INSERT);
1169 SwNodeIndex aTblIdx( *pTableNode, -1 );
1170 SwPosition aBefore(aTblIdx);
1171 if(GetDoc()->AppendTxtNode( aBefore ))
1173 SwPaM aTmp(aBefore);
1174 aCpyPam = aTmp;
1176 EndUndo(UNDO_INSERT);
1179 MovePage( fnPageCurr, fnPageEnd );
1180 aCpyPam.SetMark();
1181 *aCpyPam.GetMark() = *GetCrsr()->GetPoint();
1183 SET_CURR_SHELL( this );
1185 StartAllAction();
1186 GetDoc()->LockExpFlds();
1187 SetSelection(aCpyPam);
1188 // copy the text of the selection
1189 SwEditShell::Copy(&rToFill);
1191 if(pTableNode)
1193 //remove the inserted paragraph
1194 Undo();
1195 //remove the paragraph in the second doc, too
1196 SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 );
1197 SwPaM aPara( aIdx ); //DocStart
1198 rToFill.GetDoc()->DelFullPara(aPara);
1200 // now the page bound objects
1201 //additionally copy page bound frames
1202 if( GetDoc()->GetSpzFrmFmts()->Count() )
1204 // create a draw view if necessary
1205 if( !rToFill.Imp()->GetDrawView() )
1206 rToFill.MakeDrawView();
1208 for ( USHORT i = 0; i < GetDoc()->GetSpzFrmFmts()->Count(); ++i )
1210 const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i];
1211 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1212 if( FLY_PAGE == aAnchor.GetAnchorId() &&
1213 aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage)
1215 aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1);
1217 else
1218 continue;
1219 rToFill.GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1222 GetDoc()->UnlockExpFlds();
1223 GetDoc()->UpdateFlds(NULL, false);
1224 Pop(sal_False);
1225 EndAllAction();
1227 return TRUE;
1230 BOOL SwFEShell::GetDrawObjGraphic( ULONG nFmt, Graphic& rGrf ) const
1232 ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
1233 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1234 BOOL bConvert = TRUE;
1235 if( rMrkList.GetMarkCount() )
1237 if( rMrkList.GetMarkCount() == 1 &&
1238 rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) )
1240 // Rahmen selektiert
1241 if( CNT_GRF == GetCntType() )
1243 // --> OD 2005-02-09 #119353# - robust
1244 const Graphic* pGrf( GetGraphic() );
1245 if ( pGrf )
1247 Graphic aGrf( *pGrf );
1248 if( SOT_FORMAT_GDIMETAFILE == nFmt )
1250 if( GRAPHIC_BITMAP != aGrf.GetType() )
1252 rGrf = aGrf;
1253 bConvert = FALSE;
1255 else if( GetWin() )
1257 Size aSz;
1258 Point aPt;
1259 GetGrfSize( aSz );
1261 VirtualDevice aVirtDev;
1262 aVirtDev.EnableOutput( FALSE );
1264 MapMode aTmp( GetWin()->GetMapMode() );
1265 aTmp.SetOrigin( aPt );
1266 aVirtDev.SetMapMode( aTmp );
1268 GDIMetaFile aMtf;
1269 aMtf.Record( &aVirtDev );
1270 aGrf.Draw( &aVirtDev, aPt, aSz );
1271 aMtf.Stop();
1272 aMtf.SetPrefMapMode( aTmp );
1273 aMtf.SetPrefSize( aSz );
1274 rGrf = aMtf;
1277 else if( GRAPHIC_BITMAP == aGrf.GetType() )
1279 rGrf = aGrf;
1280 bConvert = FALSE;
1282 else
1284 //fix(23806): Nicht die Originalgroesse, sondern die
1285 //aktuelle. Anderfalls kann es passieren, dass z.B. bei
1286 //Vektorgrafiken mal eben zig MB angefordert werden.
1287 const Size aSz( FindFlyFrm()->Prt().SSize() );
1288 VirtualDevice aVirtDev( *GetWin() );
1290 MapMode aTmp( MAP_TWIP );
1291 aVirtDev.SetMapMode( aTmp );
1292 if( aVirtDev.SetOutputSize( aSz ) )
1294 aGrf.Draw( &aVirtDev, Point(), aSz );
1295 rGrf = aVirtDev.GetBitmap( Point(), aSz );
1297 else
1299 rGrf = aGrf;
1300 bConvert = FALSE;
1304 // <--
1307 else if( SOT_FORMAT_GDIMETAFILE == nFmt )
1308 rGrf = Imp()->GetDrawView()->GetAllMarkedMetaFile();
1309 else if( SOT_FORMAT_BITMAP == nFmt )
1310 rGrf = Imp()->GetDrawView()->GetAllMarkedBitmap();
1312 return bConvert;
1315 // --> OD 2005-08-03 #i50824#
1316 // --> OD 2006-03-01 #b6382898#
1317 // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1318 void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel )
1320 for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum )
1322 // setup object iterator in order to iterate through all objects
1323 // including objects in group objects, but exclusive group objects.
1324 SdrObjListIter aIter(*(_pModel->GetPage( nPgNum )));
1325 while( aIter.IsMore() )
1327 SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
1328 if( pOle2Obj )
1330 // found an ole2 shape
1331 SdrObjList* pObjList = pOle2Obj->GetObjList();
1333 // get its graphic
1334 Graphic aGraphic;
1335 pOle2Obj->Connect();
1336 Graphic* pGraphic = pOle2Obj->GetGraphic();
1337 if( pGraphic )
1338 aGraphic = *pGraphic;
1339 pOle2Obj->Disconnect();
1341 // create new graphic shape with the ole graphic and shape size
1342 SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() );
1343 // apply layer of ole2 shape at graphic shape
1344 pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
1346 // replace ole2 shape with the new graphic object and delete the ol2 shape
1347 SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() );
1348 SdrObject::Free( pRemovedObject );
1353 // <--
1354 void SwFEShell::Paste( SvStream& rStrm, USHORT nAction, const Point* pPt )
1356 SET_CURR_SHELL( this );
1357 StartAllAction();
1358 StartUndo();
1360 SvtPathOptions aPathOpt;
1361 FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(),
1362 0, GetDoc()->GetDocShell() );
1363 pModel->GetItemPool().FreezeIdRanges();
1365 rStrm.Seek(0);
1367 uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) );
1368 SvxDrawingLayerImport( pModel, xInputStream );
1370 if ( !Imp()->HasDrawView() )
1371 Imp()->MakeDrawView();
1373 Point aPos( pPt ? *pPt : GetCharRect().Pos() );
1374 SdrView *pView = Imp()->GetDrawView();
1376 //Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren.
1377 if( pModel->GetPageCount() > 0 &&
1378 1 == pModel->GetPage(0)->GetObjCount() &&
1379 1 == pView->GetMarkedObjectList().GetMarkCount() )
1381 // OD 10.07.2003 #110742# - replace a marked 'virtual' drawing object
1382 // by its corresponding 'master' drawing object in the mark list.
1383 SwDrawView::ReplaceMarkedDrawVirtObjs( *pView );
1385 SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0);
1386 SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj();
1388 if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) )
1389 nAction = SW_PASTESDR_REPLACE;
1391 switch( nAction )
1393 case SW_PASTESDR_REPLACE:
1395 const SwFrmFmt* pFmt(0);
1396 const SwFrm* pAnchor(0);
1397 if( pOldObj->ISA(SwVirtFlyDrawObj) )
1399 pFmt = FindFrmFmt( pOldObj );
1401 Point aNullPt;
1402 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt );
1403 pAnchor = pFlyFrm->GetAnchorFrm();
1405 if( pAnchor->FindFooterOrHeader() )
1407 // wenn TextRahmen in der Kopf/Fusszeile steht, dann
1408 // nicht ersetzen, sondern nur einfuegen
1409 nAction = SW_PASTESDR_INSERT;
1410 break;
1414 SdrObject* pNewObj = pClpObj->Clone();
1415 Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() );
1416 Size aOldObjSize( aOldObjRect.GetSize() );
1417 Rectangle aNewRect( pNewObj->GetCurrentBoundRect() );
1418 Size aNewSize( aNewRect.GetSize() );
1420 Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() );
1421 Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height());
1422 pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight);
1424 Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft();
1425 pNewObj->NbcMove(Size(aVec.X(), aVec.Y()));
1427 if( pNewObj->ISA( SdrUnoObj ) )
1428 pNewObj->SetLayer( GetDoc()->GetControlsId() );
1429 else if( pOldObj->ISA( SdrUnoObj ) )
1430 pNewObj->SetLayer( GetDoc()->GetHeavenId() );
1431 else
1432 pNewObj->SetLayer( pOldObj->GetLayer() );
1434 if( pOldObj->ISA(SwVirtFlyDrawObj) )
1436 // Attribute sichern und dam SdrObject setzen
1437 SfxItemSet aFrmSet( pDoc->GetAttrPool(),
1438 RES_SURROUND, RES_ANCHOR );
1439 aFrmSet.Set( pFmt->GetAttrSet() );
1441 Point aNullPt;
1442 if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() )
1444 const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor;
1445 do {
1446 pTmp = pTmp->FindMaster();
1447 ASSERT( pTmp, "Where's my Master?" );
1448 } while( pTmp->IsFollow() );
1449 pAnchor = pTmp;
1451 if( pOldObj->ISA( SdrCaptionObj ))
1452 aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos();
1453 else
1454 aNullPt = aOldObjRect.TopLeft();
1456 Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) );
1457 // OD 2004-04-05 #i26791# - direct positioning of Writer
1458 // fly frame object for <SwDoc::Insert(..)>
1459 pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor );
1460 pNewObj->NbcSetAnchorPos( aNewAnchor );
1462 pOldObj->GetOrdNum();
1464 DelSelectedObj();
1466 pFmt = GetDoc()->Insert( *GetCrsr(), *pNewObj, &aFrmSet, NULL );
1468 else
1469 pView->ReplaceObjectAtView( pOldObj, *Imp()->GetPageView(), pNewObj, TRUE );
1471 break;
1473 case SW_PASTESDR_SETATTR:
1475 SfxItemSet aSet( GetAttrPool() );
1476 aSet.Put(pClpObj->GetMergedItemSet());
1477 pView->SetAttributes( aSet, FALSE );
1479 break;
1481 default:
1482 nAction = SW_PASTESDR_INSERT;
1483 break;
1486 else
1487 nAction = SW_PASTESDR_INSERT;
1489 if( SW_PASTESDR_INSERT == nAction )
1491 GetDoc()->SetNoDrawUndoObj( TRUE );
1493 sal_Bool bDesignMode = pView->IsDesignMode();
1494 if( !bDesignMode )
1495 pView->SetDesignMode( sal_True );
1497 // --> OD 2005-08-03 #i50824#
1498 // --> OD 2006-03-01 #b6382898#
1499 // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
1500 lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel );
1501 // <--
1502 pView->Paste( *pModel, aPos );
1504 ULONG nCnt = pView->GetMarkedObjectList().GetMarkCount();
1505 if( nCnt )
1507 const Point aNull( 0, 0 );
1508 for( ULONG i=0; i < nCnt; ++i )
1510 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
1511 pObj->ImpSetAnchorPos( aNull );
1514 pView->SetCurrentObj( OBJ_GRUP, SdrInventor );
1515 if ( nCnt > 1 )
1516 pView->GroupMarked();
1517 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1518 if( pObj->ISA( SdrUnoObj ) )
1520 pObj->SetLayer( GetDoc()->GetControlsId() );
1521 bDesignMode = sal_True;
1523 else
1524 pObj->SetLayer( GetDoc()->GetHeavenId() );
1525 const Rectangle &rSnap = pObj->GetSnapRect();
1526 const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 );
1527 pView->MoveMarkedObj( aDiff );
1528 ImpEndCreate();
1529 if( !bDesignMode )
1530 pView->SetDesignMode( sal_False );
1532 GetDoc()->SetNoDrawUndoObj( FALSE );
1534 EndUndo();
1535 EndAllAction();
1536 delete pModel;
1539 BOOL SwFEShell::Paste( const Graphic &rGrf )
1541 SET_CURR_SHELL( this );
1542 SdrObject* pObj;
1543 SdrView *pView = Imp()->GetDrawView();
1545 BOOL bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() &&
1546 (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() &&
1547 !pObj->ISA( SdrOle2Obj );
1549 if( bRet )
1551 XOBitmap aXOBitmap( rGrf.GetBitmap() );
1552 SfxItemSet aSet( GetAttrPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP );
1553 aSet.Put( XFillStyleItem( XFILL_BITMAP ));
1554 aSet.Put( XFillBitmapItem( aEmptyStr, aXOBitmap ));
1555 pView->SetAttributes( aSet, FALSE );
1557 return bRet;