summaryrefslogtreecommitdiff
path: root/sw/source/core/frmedt/fecopy.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/frmedt/fecopy.cxx')
-rw-r--r--sw/source/core/frmedt/fecopy.cxx1554
1 files changed, 1554 insertions, 0 deletions
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
new file mode 100644
index 000000000000..ed851204d1b5
--- /dev/null
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -0,0 +1,1554 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <hintids.hxx>
+
+#include <vcl/graph.hxx>
+#include <sot/formats.hxx>
+#include <sot/storage.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svx/xexch.hxx>
+#include <svx/xflasit.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <editeng/brshitem.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/xfillit.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/xoutbmp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/fmmodel.hxx>
+#include <svx/unomodel.hxx>
+// --> OD 2005-08-03 #i50824#
+#include <svx/svditer.hxx>
+// <--
+// --> OD 2006-03-01 #b6382898#
+#include <svx/svdograf.hxx>
+// <--
+#include <unotools/streamwrap.hxx>
+#include <fmtanchr.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtornt.hxx>
+#include <fmtflcnt.hxx>
+#include <frmfmt.hxx>
+#include <docary.hxx>
+#include <txtfrm.hxx>
+#include <txtflcnt.hxx>
+#include <fesh.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <rootfrm.hxx>
+#include <ndtxt.hxx>
+#include <pam.hxx>
+#include <tblsel.hxx>
+#include <swtable.hxx>
+#include <flyfrm.hxx>
+#include <pagefrm.hxx>
+#include <fldbas.hxx>
+#include <edimp.hxx>
+#include <swundo.hxx>
+#include <viewimp.hxx>
+#include <dview.hxx>
+#include <dcontact.hxx>
+#include <dflyobj.hxx>
+#include <docsh.hxx>
+#include <pagedesc.hxx>
+#include <mvsave.hxx>
+#include <vcl/virdev.hxx>
+
+
+using namespace ::com::sun::star;
+
+/*************************************************************************
+|*
+|* SwFEShell::Copy() Copy fuer das Interne Clipboard.
+|* Kopiert alle Selektionen in das Clipboard.
+|*
+|* Ersterstellung JP ??
+|* Letzte Aenderung MA 22. Feb. 95
+|
+|*************************************************************************/
+
+sal_Bool SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt )
+{
+ ASSERT( pClpDoc, "kein Clipboard-Dokument" );
+
+ pClpDoc->GetIDocumentUndoRedo().DoUndo(false); // always false!
+
+ // steht noch Inhalt im ClpDocument, dann muss dieser geloescht werden
+ SwNodeIndex aSttIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
+ SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
+ if( !pTxtNd || pTxtNd->GetTxt().Len() ||
+ aSttIdx.GetIndex()+1 != pClpDoc->GetNodes().GetEndOfContent().GetIndex() )
+ {
+ pClpDoc->GetNodes().Delete( aSttIdx,
+ pClpDoc->GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
+ pTxtNd = pClpDoc->GetNodes().MakeTxtNode( aSttIdx,
+ (SwTxtFmtColl*)pClpDoc->GetDfltTxtFmtColl() );
+ aSttIdx--;
+ }
+
+ // stehen noch FlyFrames rum, loesche auch diese
+ for( sal_uInt16 n = 0; n < pClpDoc->GetSpzFrmFmts()->Count(); ++n )
+ {
+ SwFlyFrmFmt* pFly = (SwFlyFrmFmt*)(*pClpDoc->GetSpzFrmFmts())[n];
+ pClpDoc->DelLayoutFmt( pFly );
+ }
+ pClpDoc->GCFieldTypes(); // loesche die FieldTypes
+
+ // wurde ein String uebergeben, so kopiere diesen in das Clipboard-
+ // Dokument. Somit kann auch der Calculator das interne Clipboard
+ // benutzen.
+ if( pNewClpTxt )
+ {
+ pTxtNd->InsertText( *pNewClpTxt, SwIndex( pTxtNd ) );
+ return sal_True; // das wars.
+ }
+
+ pClpDoc->LockExpFlds();
+ pClpDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
+ sal_Bool bRet;
+
+ // soll ein FlyFrame kopiert werden ?
+ if( IsFrmSelected() )
+ {
+ // hole das FlyFormat
+ SwFlyFrm* pFly = FindFlyFrm();
+ SwFrmFmt* pFlyFmt = pFly->GetFmt();
+ SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
+
+ if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
+ (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
+ (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
+ (FLY_AS_CHAR == aAnchor.GetAnchorId()))
+ {
+ SwPosition aPos( aSttIdx );
+ if ( FLY_AS_CHAR == aAnchor.GetAnchorId() )
+ {
+ aPos.nContent.Assign( pTxtNd, 0 );
+ }
+ aAnchor.SetAnchor( &aPos );
+ }
+ pFlyFmt = pClpDoc->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
+
+ // sorge dafuer das das "RootFmt" als erstes im SpzArray-steht
+ // (Es wurden ggf. Flys in Flys kopiert.
+ SwSpzFrmFmts& rSpzFrmFmts = *(SwSpzFrmFmts*)pClpDoc->GetSpzFrmFmts();
+ if( rSpzFrmFmts[ 0 ] != pFlyFmt )
+ {
+ sal_uInt16 nPos = rSpzFrmFmts.GetPos( pFlyFmt );
+ ASSERT( nPos != USHRT_MAX, "Fly steht nicht im Spz-Array" );
+
+ rSpzFrmFmts.Remove( nPos );
+ rSpzFrmFmts.Insert( pFlyFmt, 0 );
+ }
+
+ if ( FLY_AS_CHAR == aAnchor.GetAnchorId() )
+ {
+ // JP 13.02.99 Bug 61863: wenn eine Rahmenselektion ins Clipboard
+ // gestellt wird, so muss beim Pasten auch wieder
+ // eine solche vorgefunden werden. Also muss im Node
+ // das kopierte TextAttribut wieder entfernt werden,
+ // sonst wird es als TextSelektion erkannt
+ const SwIndex& rIdx = pFlyFmt->GetAnchor().GetCntntAnchor()->nContent;
+ SwTxtFlyCnt *const pTxtFly = static_cast<SwTxtFlyCnt *>(
+ pTxtNd->GetTxtAttrForCharAt(
+ rIdx.GetIndex(), RES_TXTATR_FLYCNT));
+ if( pTxtFly )
+ {
+ ((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 );
+ pTxtNd->EraseText( rIdx, 1 );
+ }
+ }
+ bRet = sal_True;
+ }
+ else if ( IsObjSelected() )
+ {
+ SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 ));
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+
+ if( Imp()->GetDrawView()->IsGroupEntered() ||
+ ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
+ {
+ SfxItemSet aSet( pClpDoc->GetAttrPool(), aFrmFmtSetRange );
+
+ SwFmtAnchor aAnchor( FLY_AT_PARA );
+ aAnchor.SetAnchor( &aPos );
+ aSet.Put( aAnchor );
+
+ SdrObject *const pNew =
+ pClpDoc->CloneSdrObj( *pObj, sal_False, sal_True );
+
+ SwPaM aTemp(aPos);
+ pClpDoc->Insert(aTemp, *pNew, &aSet, NULL);
+ }
+ else
+ {
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
+ SwFrmFmt *pFmt = pContact->GetFmt();
+ SwFmtAnchor aAnchor( pFmt->GetAnchor() );
+ if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
+ (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
+ (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
+ (FLY_AS_CHAR == aAnchor.GetAnchorId()))
+ {
+ aAnchor.SetAnchor( &aPos );
+ }
+
+ pClpDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
+ }
+ }
+ bRet = sal_True;
+ }
+ else
+ bRet = _CopySelToDoc( pClpDoc, 0 ); // kopiere die Selectionen
+
+ pClpDoc->SetRedlineMode_intern((RedlineMode_t)0 );
+ pClpDoc->UnlockExpFlds();
+ if( !pClpDoc->IsExpFldsLocked() )
+ pClpDoc->UpdateExpFlds(NULL, true);
+
+ return bRet;
+}
+
+const Point &lcl_FindBasePos( const SwFrm *pFrm, const Point &rPt )
+{
+ const SwFrm *pF = pFrm;
+ while ( pF && !pF->Frm().IsInside( rPt ) )
+ {
+ if ( pF->IsCntntFrm() )
+ pF = ((SwCntntFrm*)pF)->GetFollow();
+ else
+ pF = 0;
+ }
+ if ( pF )
+ return pF->Frm().Pos();
+ else
+ return pFrm->Frm().Pos();
+}
+
+sal_Bool lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly,
+ const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor,
+ Point& rNewPos, sal_Bool bCheckFlyRecur )
+{
+ sal_Bool bRet = sal_True;
+ rAnchor.SetAnchor( &rPos );
+ SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->getLayoutFrm( rDestShell.GetLayout(), &rInsPt, 0, sal_False );
+ SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm();
+ if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( *pTmpFly ) )
+ {
+ bRet = sal_False;
+ }
+ else if ( FLY_AT_FLY == rAnchor.GetAnchorId() )
+ {
+ if( pTmpFly )
+ {
+ const SwNodeIndex& rIdx = *pTmpFly->GetFmt()->GetCntnt().GetCntntIdx();
+ SwPosition aPos( rIdx );
+ rAnchor.SetAnchor( &aPos );
+ rNewPos = pTmpFly->Frm().Pos();
+ }
+ else
+ {
+ rAnchor.SetType( FLY_AT_PAGE );
+ rAnchor.SetPageNum( rDestShell.GetPageNumber( rInsPt ) );
+ const SwFrm *pPg = pTmpFrm->FindPageFrm();
+ rNewPos = pPg->Frm().Pos();
+ }
+ }
+ else
+ rNewPos = ::lcl_FindBasePos( pTmpFrm, rInsPt );
+ return bRet;
+}
+
+sal_Bool SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt,
+ const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert )
+{
+ sal_Bool bRet = sal_True;
+
+ //Die Liste muss kopiert werden, weil unten die neuen Objekte
+ //selektiert werden.
+ const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() );
+ sal_uLong nMarkCount = aMrkList.GetMarkCount();
+ if( !pDestShell->Imp()->GetDrawView() )
+ // sollte mal eine erzeugt werden
+ pDestShell->MakeDrawView();
+ else if( bSelectInsert )
+ pDestShell->Imp()->GetDrawView()->UnmarkAll();
+
+ SdrPageView *pDestPgView = pDestShell->Imp()->GetPageView(),
+ *pSrcPgView = Imp()->GetPageView();
+ SwDrawView *pDestDrwView = pDestShell->Imp()->GetDrawView(),
+ *pSrcDrwView = Imp()->GetDrawView();
+ SwDoc* pDestDoc = pDestShell->GetDoc();
+
+ Size aSiz( rInsPt.X() - rSttPt.X(), rInsPt.Y() - rSttPt.Y() );
+ for( sal_uInt16 i = 0; i < nMarkCount; ++i )
+ {
+ SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
+
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
+ SwFrmFmt *pFmt = pContact->GetFmt();
+ const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+
+ sal_Bool bInsWithFmt = sal_True;
+
+ if( pDestDrwView->IsGroupEntered() )
+ {
+ // in die Gruppe einfuegen, wenns aus einer betretenen Gruppe
+ // kommt oder das Object nicht zeichengebunden ist
+ if( pSrcDrwView->IsGroupEntered() ||
+ (FLY_AS_CHAR != rAnchor.GetAnchorId()) )
+
+ {
+ SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
+ GetDoc() == pDestDoc, sal_False );
+ pNew->NbcMove( aSiz );
+ pDestDrwView->InsertObjectAtView( pNew, *pDestPgView );
+ bInsWithFmt = sal_False;
+ }
+ }
+
+ if( bInsWithFmt )
+ {
+ SwFmtAnchor aAnchor( rAnchor );
+ Point aNewAnch;
+
+ if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
+ (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
+ (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
+ (FLY_AS_CHAR == aAnchor.GetAnchorId()))
+ {
+ if ( this == pDestShell )
+ {
+ //gleiche Shell? Dann erfrage die Position an der
+ //uebergebenen DokumentPosition
+ SwPosition aPos( *GetCrsr()->GetPoint() );
+ Point aPt( rInsPt );
+ aPt -= rSttPt - pObj->GetSnapRect().TopLeft();
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
+ const SwNode *pNd;
+ if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
+ bRet = sal_False;
+ else
+ bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt,
+ *pDestShell, aAnchor, aNewAnch, sal_False );
+ }
+ else
+ {
+ SwPaM *pCrsr = pDestShell->GetCrsr();
+ if( pCrsr->GetNode()->IsNoTxtNode() )
+ bRet = sal_False;
+ else
+ bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(),
+ *pCrsr->GetNode(), 0, rInsPt,
+ *pDestShell, aAnchor,
+ aNewAnch, sal_False );
+ }
+ }
+ else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
+ {
+ aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
+ const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
+ const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
+ if ( pPg )
+ aNewAnch = pPg->Frm().Pos();
+ }
+
+ if( bRet )
+ {
+ if( pSrcDrwView->IsGroupEntered() ||
+ ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
+ {
+ SfxItemSet aSet( pDestDoc->GetAttrPool(),aFrmFmtSetRange);
+ aSet.Put( aAnchor );
+ SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
+ GetDoc() == pDestDoc, sal_True );
+ pFmt = pDestDoc->Insert( *pDestShell->GetCrsr(),
+ *pNew, &aSet, NULL );
+ }
+ else
+ pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true );
+
+ //Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind.
+ if ( pFmt )
+ {
+ SdrObject* pNew = pFmt->FindSdrObject();
+ if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
+ {
+ Point aPos( rInsPt );
+ aPos -= aNewAnch;
+ aPos -= rSttPt - pObj->GetSnapRect().TopLeft();
+ // OD 2004-04-05 #i26791# - change attributes instead of
+ // direct positioning
+ pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
+ pFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
+ // --> OD 2005-04-15 #i47455# - notify draw frame format
+ // that position attributes are already set.
+ if ( pFmt->ISA(SwDrawFrmFmt) )
+ {
+ static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet();
+ }
+ // <--
+ }
+ if( bSelectInsert )
+ pDestDrwView->MarkObj( pNew, pDestPgView );
+ }
+ }
+ }
+ }
+
+ if ( bIsMove && bRet )
+ {
+ if( pDestShell == this )
+ {
+ const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() );
+ pSrcDrwView->UnmarkAll();
+
+ sal_uLong nMrkCnt = aMrkList.GetMarkCount();
+ sal_uInt16 i;
+ for ( i = 0; i < nMrkCnt; ++i )
+ {
+ SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
+ pSrcDrwView->MarkObj( pObj, pSrcPgView );
+ }
+ DelSelectedObj();
+ nMrkCnt = aList.GetMarkCount();
+ for ( i = 0; i < nMrkCnt; ++i )
+ {
+ SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj();
+ pSrcDrwView->MarkObj( pObj, pSrcPgView );
+ }
+ }
+ else
+ DelSelectedObj();
+ }
+
+ return bRet;
+}
+
+sal_Bool SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
+ const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert )
+{
+ sal_Bool bRet = sal_False;
+
+ ASSERT( pDestShell, "Copy ohne DestShell." );
+ ASSERT( this == pDestShell || !pDestShell->IsObjSelected(),
+ "Dest-Shell darf nie im Obj-Modus sein" );
+
+ SET_CURR_SHELL( pDestShell );
+
+ pDestShell->StartAllAction();
+ pDestShell->GetDoc()->LockExpFlds();
+
+ // Referenzen sollen verschoben werden.
+ sal_Bool bCopyIsMove = pDoc->IsCopyIsMove();
+ if( bIsMove )
+ // am Doc ein Flag setzen, damit in den TextNodes
+ pDoc->SetCopyIsMove( sal_True );
+
+ RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode();
+ pDestShell->GetDoc()->SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES));
+
+ // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
+ // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
+ // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
+ // besorgt)
+ SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD );
+
+ if( IsFrmSelected() )
+ {
+ SwFlyFrm* pFly = FindFlyFrm();
+ SwFrmFmt* pFlyFmt = pFly->GetFmt();
+ SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
+ bRet = sal_True;
+ Point aNewAnch;
+
+ if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
+ (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
+ (FLY_AT_FLY == aAnchor.GetAnchorId()) ||
+ (FLY_AS_CHAR == aAnchor.GetAnchorId()))
+ {
+ if ( this == pDestShell )
+ {
+ // gleiche Shell? Dann erfrage die Position an der
+ // uebergebenen DokumentPosition
+ SwPosition aPos( *GetCrsr()->GetPoint() );
+ Point aPt( rInsPt );
+ aPt -= rSttPt - pFly->Frm().Pos();
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
+ const SwNode *pNd;
+ if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
+ bRet = sal_False;
+ else
+ { //Nicht in sich selbst kopieren
+ const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
+ if ( aPos.nNode > *pTmp && aPos.nNode <
+ pTmp->GetNode().EndOfSectionIndex() )
+ {
+ bRet = sal_False;
+ }
+ else
+ bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
+ *pDestShell, aAnchor, aNewAnch, sal_True );
+ }
+ }
+ else
+ {
+ const SwPaM *pCrsr = pDestShell->GetCrsr();
+ if( pCrsr->GetNode()->IsNoTxtNode() )
+ bRet = sal_False;
+ else
+ bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(),
+ pFly, rInsPt, *pDestShell, aAnchor,
+ aNewAnch, GetDoc() == pDestShell->GetDoc());
+ }
+ }
+ else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
+ {
+ aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
+ const SwRootFrm* pTmpRoot = pDestShell->GetLayout();
+ const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true );
+ if ( pPg )
+ aNewAnch = pPg->Frm().Pos();
+ }
+ else {
+ ASSERT( !this, "was fuer ein Anchor ist es denn?" );
+ }
+
+ if( bRet )
+ {
+ SwFrmFmt *pOldFmt = pFlyFmt;
+ pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true );
+
+ if ( FLY_AS_CHAR != aAnchor.GetAnchorId() )
+ {
+ Point aPos( rInsPt );
+ aPos -= aNewAnch;
+ aPos -= rSttPt - pFly->Frm().Pos();
+ pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
+ pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
+ }
+
+ const Point aPt( pDestShell->GetCrsrDocPos() );
+
+ if( bIsMove )
+ GetDoc()->DelLayoutFmt( pOldFmt );
+
+ // nur selektieren wenn es in der gleichen Shell verschoben/
+ // kopiert wird
+ if( bSelectInsert )
+ {
+ SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, sal_False );
+ if( pFlyFrm )
+ {
+ //JP 12.05.98: sollte das nicht im SelectFlyFrm stehen???
+ pDestShell->Imp()->GetDrawView()->UnmarkAll();
+ pDestShell->SelectFlyFrm( *pFlyFrm, sal_True );
+ }
+ }
+
+ if( this != pDestShell && !pDestShell->HasShFcs() )
+ pDestShell->Imp()->GetDrawView()->hideMarkHandles();
+ }
+ }
+ else if ( IsObjSelected() )
+ bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert );
+ else if( IsTableMode() )
+ {
+ // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
+ // von der Originalen an und kopiere die selectierten Boxen.
+ // Die Groessen werden prozentual korrigiert.
+
+ // lasse ueber das Layout die Boxen suchen
+ const SwTableNode* pTblNd;
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes );
+ if( aBoxes.Count() &&
+ 0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) )
+ {
+ SwPosition* pDstPos = 0;
+ if( this == pDestShell )
+ {
+ // gleiche Shell? Dann erzeuge einen Crsr an der
+ // uebergebenen DokumentPosition
+ pDstPos = new SwPosition( *GetCrsr()->GetPoint() );
+ Point aPt( rInsPt );
+ GetLayout()->GetCrsrOfst( pDstPos, aPt );
+ if( !pDstPos->nNode.GetNode().IsNoTxtNode() )
+ bRet = sal_True;
+ }
+ else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
+ {
+ pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
+ bRet = sal_True;
+ }
+
+ if( bRet )
+ {
+ if( GetDoc() == pDestShell->GetDoc() )
+ ParkTblCrsr();
+
+ bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0,
+ bIsMove && this == pDestShell &&
+ aBoxes.Count() == pTblNd->GetTable().
+ GetTabSortBoxes().Count(),
+ this != pDestShell );
+
+ if( this != pDestShell )
+ *pDestShell->GetCrsr()->GetPoint() = *pDstPos;
+
+ // wieder alle geparkten Crsr erzeugen?
+ if( GetDoc() == pDestShell->GetDoc() )
+ GetCrsr();
+
+ // JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte
+ // Cursor auf die EinfuegePos. positioniert wird
+ if( this == pDestShell )
+ GetCrsrDocPos() = rInsPt;
+ }
+ delete pDstPos;
+ }
+ }
+ else
+ {
+ bRet = sal_True;
+ if( this == pDestShell )
+ {
+ // gleiche Shell? Dann erfrage die Position an der
+ // uebergebenen DokumentPosition
+ SwPosition aPos( *GetCrsr()->GetPoint() );
+ Point aPt( rInsPt );
+ GetLayout()->GetCrsrOfst( &aPos, aPt );
+ bRet = !aPos.nNode.GetNode().IsNoTxtNode();
+ }
+ else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
+ bRet = sal_False;
+
+ if( bRet )
+ bRet = 0 != SwEditShell::Copy( pDestShell );
+ }
+
+ pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode );
+ pDoc->SetCopyIsMove( bCopyIsMove );
+
+ // wurden neue Tabellenformeln eingefuegt ?
+ if( pTblFldTyp->GetDepends() )
+ {
+ // alte Actions beenden; die Tabellen-Frames werden angelegt und
+ // eine SSelection kann erzeugt werden
+ sal_uInt16 nActCnt;
+ for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt )
+ pDestShell->EndAllAction();
+
+ for( ; nActCnt; --nActCnt )
+ pDestShell->StartAllAction();
+ }
+ pDestShell->GetDoc()->UnlockExpFlds();
+ pDestShell->GetDoc()->UpdateFlds(NULL, false);
+
+ pDestShell->EndAllAction();
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::Paste() Paste fuer das Interne Clipboard.
+|* Kopiert den Inhalt vom Clipboard in das Dokument.
+|*
+|* Ersterstellung JP ??
+|* Letzte Aenderung MA 22. Feb. 95
+|
+|*************************************************************************/
+
+namespace {
+ typedef boost::shared_ptr<SwPaM> PaMPtr;
+ typedef boost::shared_ptr<SwPosition> PositionPtr;
+ typedef std::pair< PaMPtr, PositionPtr > Insertion;
+}
+
+sal_Bool SwFEShell::Paste( SwDoc* pClpDoc, sal_Bool bIncludingPageFrames )
+{
+ SET_CURR_SHELL( this );
+ ASSERT( pClpDoc, "kein Clipboard-Dokument" );
+ const sal_uInt16 nStartPageNumber = GetPhyPageNum();
+ // dann bis zum Ende vom Nodes Array
+ SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
+ SwPaM aCpyPam( aIdx ); //DocStart
+
+ // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
+ // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
+ // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
+ // besorgt)
+ SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
+
+ SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode();
+ if( !pSrcNd ) // TabellenNode ?
+ { // nicht ueberspringen!!
+ SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode();
+ if( pCNd )
+ aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 );
+ else if( !aCpyPam.Move( fnMoveForward, fnGoNode ))
+ aCpyPam.Move( fnMoveBackward, fnGoNode );
+ }
+
+ aCpyPam.SetMark();
+ aCpyPam.Move( fnMoveForward, fnGoDoc );
+
+ sal_Bool bRet = sal_True, bDelTbl = sal_True;
+ StartAllAction();
+ GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
+ GetDoc()->LockExpFlds();
+
+ // When the clipboard content has been created by a rectangular selection
+ // the pasting is more sophisticated:
+ // every paragraph will be inserted into another position.
+ // The first positions are given by the actual cursor ring,
+ // if there are more text portions to insert than cursor in this ring,
+ // the additional insert positions will be created by moving the last
+ // cursor position into the next line (like pressing the cursor down key)
+ if( pClpDoc->IsColumnSelection() && !IsTableMode() )
+ {
+ // Creation of the list of insert positions
+ std::list< Insertion > aCopyList;
+ // The number of text portions of the rectangular selection
+ const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex()
+ - aCpyPam.GetMark()->nNode.GetIndex();
+ sal_uInt32 nCount = nSelCount;
+ SwNodeIndex aClpIdx( aIdx );
+ SwPaM* pStartCursor = GetCrsr();
+ SwPaM* pCurrCrsr = pStartCursor;
+ sal_uInt32 nCursorCount = pStartCursor->numberOf();
+ // If the target selection is a multi-selection, often the last and first
+ // cursor of the ring points to identical document positions. Then
+ // we should avoid double insertion of text portions...
+ while( nCursorCount > 1 && *pCurrCrsr->GetPoint() ==
+ *(dynamic_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) )
+ {
+ --nCursorCount;
+ pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
+ pStartCursor = pCurrCrsr;
+ }
+ SwPosition aStartPos( *pStartCursor->GetPoint() );
+ SwPosition aInsertPos( aStartPos ); // first insertion position
+ bool bCompletePara = false;
+ sal_uInt16 nMove = 0;
+ while( nCount )
+ {
+ --nCount;
+ ASSERT( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" )
+ if( aIdx.GetNode().GetCntntNode() ) // robust
+ {
+ Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ),
+ PositionPtr( new SwPosition( aInsertPos ) ) );
+ ++aIdx;
+ aInsertion.first->SetMark();
+ if( pStartCursor == pCurrCrsr->GetNext() )
+ { // Now we have to look for insertion positions...
+ if( !nMove ) // Annotate the last given insert position
+ aStartPos = aInsertPos;
+ SwCursor aCrsr( aStartPos, 0, false);
+ // Check if we find another insert position by moving
+ // down the last given position
+ if( aCrsr.UpDown( sal_False, ++nMove, 0, 0 ) )
+ aInsertPos = *aCrsr.GetPoint();
+ else // if there is no paragraph we have to create it
+ bCompletePara = nCount > 0;
+ nCursorCount = 0;
+ }
+ else // as long as we find more insert positions in the cursor ring
+ { // we'll take them
+ pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext());
+ aInsertPos = *pCurrCrsr->GetPoint();
+ --nCursorCount;
+ }
+ // If there are no more paragraphs e.g. at the end of a document,
+ // we insert complete paragraphs instead of text portions
+ if( bCompletePara )
+ aInsertion.first->GetPoint()->nNode = aIdx;
+ else
+ aInsertion.first->GetPoint()->nContent =
+ aInsertion.first->GetCntntNode()->Len();
+ aCopyList.push_back( aInsertion );
+ }
+ // If there are no text portions left but there are some more
+ // cursor positions to fill we have to restart with the first
+ // text portion
+ if( !nCount && nCursorCount )
+ {
+ nCount = std::min( nSelCount, nCursorCount );
+ aIdx = aClpIdx; // Start of clipboard content
+ }
+ }
+ std::list< Insertion >::const_iterator pCurr = aCopyList.begin();
+ std::list< Insertion >::const_iterator pEnd = aCopyList.end();
+ while( pCurr != pEnd )
+ {
+ SwPosition& rInsPos = *pCurr->second;
+ SwPaM& rCopy = *pCurr->first;
+ const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
+ if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() &&
+ rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode )
+ {
+ // if more than one node will be copied into a cell
+ // the box attributes have to be removed
+ GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
+ }
+ {
+ SwNodeIndex aIndexBefore(rInsPos.nNode);
+ aIndexBefore--;
+ pClpDoc->CopyRange( rCopy, rInsPos, false );
+ {
+ aIndexBefore++;
+ SwPaM aPaM(SwPosition(aIndexBefore),
+ SwPosition(rInsPos.nNode));
+ aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
+ }
+ }
+ SaveTblBoxCntnt( &rInsPos );
+ ++pCurr;
+ }
+ }
+ else
+ {
+ FOREACHPAM_START(this)
+
+ if( pSrcNd &&
+ 0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode )))
+ {
+ SwPosition aDestPos( *PCURCRSR->GetPoint() );
+
+ sal_Bool bParkTblCrsr = sal_False;
+ const SwStartNode* pSttNd = PCURCRSR->GetNode()->FindTableBoxStartNode();
+
+ // TABLE IN TABLE: Tabelle in Tabelle kopieren
+ // lasse ueber das Layout die Boxen suchen
+ SwSelBoxes aBoxes;
+ if( IsTableMode() ) // Tabellen-Selecktion ??
+ {
+ GetTblSel( *this, aBoxes );
+ ParkTblCrsr();
+ bParkTblCrsr = sal_True;
+ }
+ else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR &&
+ ( !pSrcNd->GetTable().IsTblComplex() ||
+ pDestNd->GetTable().IsNewModel() ) )
+ {
+ // dann die Tabelle "relativ" kopieren
+ SwTableBox* pBox = pDestNd->GetTable().GetTblBox(
+ pSttNd->GetIndex() );
+ ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
+ aBoxes.Insert( pBox );
+ }
+
+ SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode());
+ if( !bParkTblCrsr )
+ {
+ // erstmal aus der gesamten Tabelle raus
+// ????? was ist mit Tabelle alleine im Rahmen ???????
+ SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
+ SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
+ // #i59539: Don't remove all redline
+ SwPaM const tmpPaM(*pDestNd, *pDestNd->EndOfSectionNode());
+ ::PaMCorrAbs(tmpPaM, aPos);
+ }
+
+ bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
+ sal_False, sal_False );
+
+ if( bParkTblCrsr )
+ GetCrsr();
+ else
+ {
+ // und wieder in die Box zurueck
+ aNdIdx = *pSttNd;
+ SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
+ SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
+ // #i59539: Don't remove all redline
+ SwNode & rNode(PCURCRSR->GetPoint()->nNode.GetNode());
+ SwCntntNode *const pCntntNode( rNode.GetCntntNode() );
+ SwPaM const tmpPam(rNode, 0,
+ rNode, (pCntntNode) ? pCntntNode->Len() : 0);
+ ::PaMCorrAbs(tmpPam, aPos);
+ }
+
+ break; // aus der "while"-Schleife heraus
+ }
+ else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() &&
+ pClpDoc->GetSpzFrmFmts()->Count() )
+ {
+ // so langsam sollte mal eine DrawView erzeugt werden
+ if( !Imp()->GetDrawView() )
+ MakeDrawView();
+
+ for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
+ {
+ sal_Bool bInsWithFmt = sal_True;
+ const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
+
+ if( Imp()->GetDrawView()->IsGroupEntered() &&
+ RES_DRAWFRMFMT == rCpyFmt.Which() &&
+ (FLY_AS_CHAR != rCpyFmt.GetAnchor().GetAnchorId()) )
+ {
+ const SdrObject* pSdrObj = rCpyFmt.FindSdrObject();
+ if( pSdrObj )
+ {
+ SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj,
+ sal_False, sal_False );
+
+ // Insert object sets any anchor position to 0.
+ // Therefore we calculate the absolute position here
+ // and after the insert the anchor of the object
+ // is set to the anchor of the group object.
+ Rectangle aSnapRect = pNew->GetSnapRect();
+ if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() )
+ {
+ const Point aPoint( 0, 0 );
+ // OD 2004-04-05 #i26791# - direct drawing object
+ // positioning for group members
+ pNew->NbcSetAnchorPos( aPoint );
+ pNew->NbcSetSnapRect( aSnapRect );
+ }
+
+ Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() );
+
+ Point aGrpAnchor( 0, 0 );
+ SdrObjList* pList = pNew->GetObjList();
+ if ( pList )
+ {
+ SdrObject* pOwner = pList->GetOwnerObj();
+ if ( pOwner )
+ {
+ SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner);
+ aGrpAnchor = pThisGroup->GetAnchorPos();
+ }
+ }
+
+ // OD 2004-04-05 #i26791# - direct drawing object
+ // positioning for group members
+ pNew->NbcSetAnchorPos( aGrpAnchor );
+ pNew->SetSnapRect( aSnapRect );
+
+ bInsWithFmt = sal_False;
+ }
+ }
+
+ if( bInsWithFmt )
+ {
+ SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
+ if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
+ (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
+ (FLY_AS_CHAR == aAnchor.GetAnchorId()))
+ {
+ SwPosition* pPos = PCURCRSR->GetPoint();
+ // #108784# allow shapes (no controls) in header/footer
+ if( RES_DRAWFRMFMT == rCpyFmt.Which() &&
+ GetDoc()->IsInHeaderFooter( pPos->nNode ) &&
+ CheckControlLayer( rCpyFmt.FindSdrObject() ) )
+ continue;
+
+ aAnchor.SetAnchor( pPos );
+ }
+ else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
+ {
+ aAnchor.SetPageNum( GetPhyPageNum() );
+ }
+ else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
+ {
+ Point aPt;
+ lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(),
+ 0, aPt, *this, aAnchor, aPt, sal_False );
+ }
+
+ SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
+
+ if( pNew )
+ {
+ if( RES_FLYFRMFMT == pNew->Which() )
+ {
+ const Point aPt( GetCrsrDocPos() );
+ SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)->
+ GetFrm( &aPt, sal_False );
+ if( pFlyFrm )
+ SelectFlyFrm( *pFlyFrm, sal_True );
+ // immer nur den ersten Fly-Frame nehmen; die anderen
+ // wurden ueber Fly in Fly ins ClipBoard kopiert !
+ break;
+ }
+ else
+ {
+ ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format.");
+ // --> OD 2005-09-01 #i52780# - drawing object has
+ // to be made visible on paste.
+ {
+ SwDrawContact* pContact =
+ static_cast<SwDrawContact*>(pNew->FindContactObj());
+ pContact->MoveObjToVisibleLayer( pContact->GetMaster() );
+ }
+ // <--
+ SdrObject *pObj = pNew->FindSdrObject();
+ SwDrawView *pDV = Imp()->GetDrawView();
+ pDV->MarkObj( pObj, pDV->GetSdrPageView() );
+ // --> OD 2005-04-15 #i47455# - notify draw frame format
+ // that position attributes are already set.
+ if ( pNew->ISA(SwDrawFrmFmt) )
+ {
+ static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet();
+ }
+ // <--
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if( bDelTbl && IsTableMode() )
+ {
+ SwEditShell::Delete();
+ bDelTbl = sal_False;
+ }
+
+ SwPosition& rInsPos = *PCURCRSR->GetPoint();
+ const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().
+ FindTableBoxStartNode();
+ if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() -
+ pBoxNd->GetIndex() &&
+ aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode )
+ {
+ // es wird mehr als 1 Node in die akt. Box kopiert. Dann
+ // muessen die BoxAttribute aber entfernt werden.
+ GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
+ }
+ //find out if the clipboard document starts with a table
+ bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
+ SwPosition aInsertPosition( rInsPos );
+
+ {
+ SwNodeIndex aIndexBefore(rInsPos.nNode);
+
+ aIndexBefore--;
+
+ pClpDoc->CopyRange( aCpyPam, rInsPos, false );
+
+ {
+ aIndexBefore++;
+ SwPaM aPaM(SwPosition(aIndexBefore),
+ SwPosition(rInsPos.nNode));
+
+ aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
+ }
+ }
+
+ SaveTblBoxCntnt( &rInsPos );
+ if(bIncludingPageFrames && bStartWithTable)
+ {
+ //remove the paragraph in front of the table
+ SwPaM aPara(aInsertPosition);
+ GetDoc()->DelFullPara(aPara);
+ }
+ //additionally copy page bound frames
+ if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->Count() )
+ {
+ // create a draw view if necessary
+ if( !Imp()->GetDrawView() )
+ MakeDrawView();
+
+ for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
+ {
+ sal_Bool bInsWithFmt = sal_True;
+ const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
+ if( bInsWithFmt )
+ {
+ SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
+ if ( FLY_AT_PAGE == aAnchor.GetAnchorId() )
+ {
+ aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 );
+ }
+ else
+ continue;
+ GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
+ }
+ }
+ }
+ }
+
+ FOREACHPAM_END()
+ }
+
+ GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
+
+ // wurden neue Tabellenformeln eingefuegt ?
+ if( pTblFldTyp->GetDepends() )
+ {
+ // alte Actions beenden; die Tabellen-Frames werden angelegt und
+ // eine Selection kann erzeugt werden
+ sal_uInt16 nActCnt;
+ for( nActCnt = 0; ActionPend(); ++nActCnt )
+ EndAllAction();
+
+ for( ; nActCnt; --nActCnt )
+ StartAllAction();
+ }
+ GetDoc()->UnlockExpFlds();
+ GetDoc()->UpdateFlds(NULL, false);
+ EndAllAction();
+
+ return bRet;
+}
+
+/*-- 14.06.2004 13:31:17---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+sal_Bool SwFEShell::PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage)
+{
+ Push();
+ if(!GotoPage(nStartPage))
+ {
+ Pop(sal_False);
+ return sal_False;
+ }
+ MovePage( fnPageCurr, fnPageStart );
+ SwPaM aCpyPam( *GetCrsr()->GetPoint() );
+ String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName();
+ SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, sal_True );
+ if( pDesc )
+ rToFill.ChgCurPageDesc( *pDesc );
+
+ if(!GotoPage(nEndPage))
+ {
+ Pop(sal_False);
+ return sal_False;
+ }
+ //if the page starts with a table a paragraph has to be inserted before
+ SwNode* pTableNode = aCpyPam.GetNode()->FindTableNode();
+ if(pTableNode)
+ {
+ //insert a paragraph
+ StartUndo(UNDO_INSERT);
+ SwNodeIndex aTblIdx( *pTableNode, -1 );
+ SwPosition aBefore(aTblIdx);
+ if(GetDoc()->AppendTxtNode( aBefore ))
+ {
+ SwPaM aTmp(aBefore);
+ aCpyPam = aTmp;
+ }
+ EndUndo(UNDO_INSERT);
+ }
+
+ MovePage( fnPageCurr, fnPageEnd );
+ aCpyPam.SetMark();
+ *aCpyPam.GetMark() = *GetCrsr()->GetPoint();
+
+ SET_CURR_SHELL( this );
+
+ StartAllAction();
+ GetDoc()->LockExpFlds();
+ SetSelection(aCpyPam);
+ // copy the text of the selection
+ SwEditShell::Copy(&rToFill);
+
+ if(pTableNode)
+ {
+ //remove the inserted paragraph
+ Undo();
+ //remove the paragraph in the second doc, too
+ SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 );
+ SwPaM aPara( aIdx ); //DocStart
+ rToFill.GetDoc()->DelFullPara(aPara);
+ }
+ // now the page bound objects
+ //additionally copy page bound frames
+ if( GetDoc()->GetSpzFrmFmts()->Count() )
+ {
+ // create a draw view if necessary
+ if( !rToFill.Imp()->GetDrawView() )
+ rToFill.MakeDrawView();
+
+ for ( sal_uInt16 i = 0; i < GetDoc()->GetSpzFrmFmts()->Count(); ++i )
+ {
+ const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i];
+ SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
+ if ((FLY_AT_PAGE == aAnchor.GetAnchorId()) &&
+ aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage)
+ {
+ aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1);
+ }
+ else
+ continue;
+ rToFill.GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
+ }
+ }
+ GetDoc()->UnlockExpFlds();
+ GetDoc()->UpdateFlds(NULL, false);
+ Pop(sal_False);
+ EndAllAction();
+
+ return sal_True;
+}
+
+sal_Bool SwFEShell::GetDrawObjGraphic( sal_uLong nFmt, Graphic& rGrf ) const
+{
+ ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ sal_Bool bConvert = sal_True;
+ if( rMrkList.GetMarkCount() )
+ {
+ if( rMrkList.GetMarkCount() == 1 &&
+ rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) )
+ {
+ // Rahmen selektiert
+ if( CNT_GRF == GetCntType() )
+ {
+ // --> OD 2005-02-09 #119353# - robust
+ const Graphic* pGrf( GetGraphic() );
+ if ( pGrf )
+ {
+ Graphic aGrf( *pGrf );
+ if( SOT_FORMAT_GDIMETAFILE == nFmt )
+ {
+ if( GRAPHIC_BITMAP != aGrf.GetType() )
+ {
+ rGrf = aGrf;
+ bConvert = sal_False;
+ }
+ else if( GetWin() )
+ {
+ Size aSz;
+ Point aPt;
+ GetGrfSize( aSz );
+
+ VirtualDevice aVirtDev;
+ aVirtDev.EnableOutput( sal_False );
+
+ MapMode aTmp( GetWin()->GetMapMode() );
+ aTmp.SetOrigin( aPt );
+ aVirtDev.SetMapMode( aTmp );
+
+ GDIMetaFile aMtf;
+ aMtf.Record( &aVirtDev );
+ aGrf.Draw( &aVirtDev, aPt, aSz );
+ aMtf.Stop();
+ aMtf.SetPrefMapMode( aTmp );
+ aMtf.SetPrefSize( aSz );
+ rGrf = aMtf;
+ }
+ }
+ else if( GRAPHIC_BITMAP == aGrf.GetType() )
+ {
+ rGrf = aGrf;
+ bConvert = sal_False;
+ }
+ else
+ {
+ //fix(23806): Nicht die Originalgroesse, sondern die
+ //aktuelle. Anderfalls kann es passieren, dass z.B. bei
+ //Vektorgrafiken mal eben zig MB angefordert werden.
+ const Size aSz( FindFlyFrm()->Prt().SSize() );
+ VirtualDevice aVirtDev( *GetWin() );
+
+ MapMode aTmp( MAP_TWIP );
+ aVirtDev.SetMapMode( aTmp );
+ if( aVirtDev.SetOutputSize( aSz ) )
+ {
+ aGrf.Draw( &aVirtDev, Point(), aSz );
+ rGrf = aVirtDev.GetBitmap( Point(), aSz );
+ }
+ else
+ {
+ rGrf = aGrf;
+ bConvert = sal_False;
+ }
+ }
+ }
+ // <--
+ }
+ }
+ else if( SOT_FORMAT_GDIMETAFILE == nFmt )
+ rGrf = Imp()->GetDrawView()->GetAllMarkedMetaFile();
+ else if( SOT_FORMAT_BITMAP == nFmt )
+ rGrf = Imp()->GetDrawView()->GetAllMarkedBitmap();
+ }
+ return bConvert;
+}
+
+// --> OD 2005-08-03 #i50824#
+// --> OD 2006-03-01 #b6382898#
+// replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
+void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel )
+{
+ for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum )
+ {
+ // setup object iterator in order to iterate through all objects
+ // including objects in group objects, but exclusive group objects.
+ SdrObjListIter aIter(*(_pModel->GetPage( nPgNum )));
+ while( aIter.IsMore() )
+ {
+ SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() );
+ if( pOle2Obj )
+ {
+ // found an ole2 shape
+ SdrObjList* pObjList = pOle2Obj->GetObjList();
+
+ // get its graphic
+ Graphic aGraphic;
+ pOle2Obj->Connect();
+ Graphic* pGraphic = pOle2Obj->GetGraphic();
+ if( pGraphic )
+ aGraphic = *pGraphic;
+ pOle2Obj->Disconnect();
+
+ // create new graphic shape with the ole graphic and shape size
+ SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() );
+ // apply layer of ole2 shape at graphic shape
+ pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
+
+ // replace ole2 shape with the new graphic object and delete the ol2 shape
+ SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() );
+ SdrObject::Free( pRemovedObject );
+ }
+ }
+ }
+}
+// <--
+void SwFEShell::Paste( SvStream& rStrm, sal_uInt16 nAction, const Point* pPt )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ StartUndo();
+
+ SvtPathOptions aPathOpt;
+ FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(),
+ 0, GetDoc()->GetDocShell() );
+ pModel->GetItemPool().FreezeIdRanges();
+
+ rStrm.Seek(0);
+
+ uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) );
+ SvxDrawingLayerImport( pModel, xInputStream );
+
+ if ( !Imp()->HasDrawView() )
+ Imp()->MakeDrawView();
+
+ Point aPos( pPt ? *pPt : GetCharRect().Pos() );
+ SdrView *pView = Imp()->GetDrawView();
+
+ //Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren.
+ if( pModel->GetPageCount() > 0 &&
+ 1 == pModel->GetPage(0)->GetObjCount() &&
+ 1 == pView->GetMarkedObjectList().GetMarkCount() )
+ {
+ // OD 10.07.2003 #110742# - replace a marked 'virtual' drawing object
+ // by its corresponding 'master' drawing object in the mark list.
+ SwDrawView::ReplaceMarkedDrawVirtObjs( *pView );
+
+ SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0);
+ SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj();
+
+ if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) )
+ nAction = SW_PASTESDR_REPLACE;
+
+ switch( nAction )
+ {
+ case SW_PASTESDR_REPLACE:
+ {
+ const SwFrmFmt* pFmt(0);
+ const SwFrm* pAnchor(0);
+ if( pOldObj->ISA(SwVirtFlyDrawObj) )
+ {
+ pFmt = FindFrmFmt( pOldObj );
+
+ Point aNullPt;
+ SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt );
+ pAnchor = pFlyFrm->GetAnchorFrm();
+
+ if( pAnchor->FindFooterOrHeader() )
+ {
+ // wenn TextRahmen in der Kopf/Fusszeile steht, dann
+ // nicht ersetzen, sondern nur einfuegen
+ nAction = SW_PASTESDR_INSERT;
+ break;
+ }
+ }
+
+ SdrObject* pNewObj = pClpObj->Clone();
+ Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() );
+ Size aOldObjSize( aOldObjRect.GetSize() );
+ Rectangle aNewRect( pNewObj->GetCurrentBoundRect() );
+ Size aNewSize( aNewRect.GetSize() );
+
+ Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() );
+ Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height());
+ pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight);
+
+ Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft();
+ pNewObj->NbcMove(Size(aVec.X(), aVec.Y()));
+
+ if( pNewObj->ISA( SdrUnoObj ) )
+ pNewObj->SetLayer( GetDoc()->GetControlsId() );
+ else if( pOldObj->ISA( SdrUnoObj ) )
+ pNewObj->SetLayer( GetDoc()->GetHeavenId() );
+ else
+ pNewObj->SetLayer( pOldObj->GetLayer() );
+
+ if( pOldObj->ISA(SwVirtFlyDrawObj) )
+ {
+ // Attribute sichern und dam SdrObject setzen
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ RES_SURROUND, RES_ANCHOR );
+ aFrmSet.Set( pFmt->GetAttrSet() );
+
+ Point aNullPt;
+ if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() )
+ {
+ const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor;
+ do {
+ pTmp = pTmp->FindMaster();
+ ASSERT( pTmp, "Where's my Master?" );
+ } while( pTmp->IsFollow() );
+ pAnchor = pTmp;
+ }
+ if( pOldObj->ISA( SdrCaptionObj ))
+ aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos();
+ else
+ aNullPt = aOldObjRect.TopLeft();
+
+ Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) );
+ // OD 2004-04-05 #i26791# - direct positioning of Writer
+ // fly frame object for <SwDoc::Insert(..)>
+ pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor );
+ pNewObj->NbcSetAnchorPos( aNewAnchor );
+
+ pOldObj->GetOrdNum();
+
+ DelSelectedObj();
+
+ pFmt = GetDoc()->Insert( *GetCrsr(), *pNewObj, &aFrmSet, NULL );
+ }
+ else
+ pView->ReplaceObjectAtView( pOldObj, *Imp()->GetPageView(), pNewObj, sal_True );
+ }
+ break;
+
+ case SW_PASTESDR_SETATTR:
+ {
+ SfxItemSet aSet( GetAttrPool() );
+ aSet.Put(pClpObj->GetMergedItemSet());
+ pView->SetAttributes( aSet, sal_False );
+ }
+ break;
+
+ default:
+ nAction = SW_PASTESDR_INSERT;
+ break;
+ }
+ }
+ else
+ nAction = SW_PASTESDR_INSERT;
+
+ if( SW_PASTESDR_INSERT == nAction )
+ {
+ ::sw::DrawUndoGuard drawUndoGuard(GetDoc()->GetIDocumentUndoRedo());
+
+ sal_Bool bDesignMode = pView->IsDesignMode();
+ if( !bDesignMode )
+ pView->SetDesignMode( sal_True );
+
+ // --> OD 2005-08-03 #i50824#
+ // --> OD 2006-03-01 #b6382898#
+ // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs>
+ lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel );
+ // <--
+ pView->Paste( *pModel, aPos );
+
+ sal_uLong nCnt = pView->GetMarkedObjectList().GetMarkCount();
+ if( nCnt )
+ {
+ const Point aNull( 0, 0 );
+ for( sal_uLong i=0; i < nCnt; ++i )
+ {
+ SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
+ pObj->ImpSetAnchorPos( aNull );
+ }
+
+ pView->SetCurrentObj( OBJ_GRUP, SdrInventor );
+ if ( nCnt > 1 )
+ pView->GroupMarked();
+ SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+ if( pObj->ISA( SdrUnoObj ) )
+ {
+ pObj->SetLayer( GetDoc()->GetControlsId() );
+ bDesignMode = sal_True;
+ }
+ else
+ pObj->SetLayer( GetDoc()->GetHeavenId() );
+ const Rectangle &rSnap = pObj->GetSnapRect();
+ const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 );
+ pView->MoveMarkedObj( aDiff );
+ ImpEndCreate();
+ if( !bDesignMode )
+ pView->SetDesignMode( sal_False );
+ }
+ }
+ EndUndo();
+ EndAllAction();
+ delete pModel;
+}
+
+sal_Bool SwFEShell::Paste( const Graphic &rGrf )
+{
+ SET_CURR_SHELL( this );
+ SdrObject* pObj;
+ SdrView *pView = Imp()->GetDrawView();
+
+ sal_Bool bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() &&
+ (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() &&
+ !pObj->ISA( SdrOle2Obj );
+
+ if( bRet )
+ {
+ XOBitmap aXOBitmap( rGrf.GetBitmap() );
+ SfxItemSet aSet( GetAttrPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP );
+ aSet.Put( XFillStyleItem( XFILL_BITMAP ));
+ aSet.Put( XFillBitmapItem( aEmptyStr, aXOBitmap ));
+ pView->SetAttributes( aSet, sal_False );
+ }
+ return bRet;
+}