summaryrefslogtreecommitdiff
path: root/sw/source/core/frmedt
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/frmedt')
-rw-r--r--sw/source/core/frmedt/fecopy.cxx1551
-rw-r--r--sw/source/core/frmedt/fedesc.cxx291
-rw-r--r--sw/source/core/frmedt/fefly1.cxx2156
-rw-r--r--sw/source/core/frmedt/feflyole.cxx150
-rw-r--r--sw/source/core/frmedt/feshview.cxx3237
-rw-r--r--sw/source/core/frmedt/fetab.cxx2593
-rw-r--r--sw/source/core/frmedt/fews.cxx1296
-rw-r--r--sw/source/core/frmedt/makefile.mk76
-rw-r--r--sw/source/core/frmedt/tblsel.cxx2728
9 files changed, 14078 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..9fe5c9a22204
--- /dev/null
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -0,0 +1,1551 @@
+/*************************************************************************
+ *
+ * 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 <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
+|
+|*************************************************************************/
+
+BOOL SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt )
+{
+ ASSERT( pClpDoc, "kein Clipboard-Dokument" );
+
+ pClpDoc->DoUndo( FALSE ); // immer auf 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( USHORT 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 TRUE; // das wars.
+ }
+
+ pClpDoc->LockExpFlds();
+ pClpDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
+ 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 )
+ {
+ USHORT 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 = TRUE;
+ }
+ else if ( IsObjSelected() )
+ {
+ SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 ));
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT 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, FALSE, 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 = 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();
+}
+
+BOOL lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly,
+ const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor,
+ Point& rNewPos, BOOL bCheckFlyRecur )
+{
+ BOOL bRet = TRUE;
+ rAnchor.SetAnchor( &rPos );
+ SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->GetFrm( &rInsPt, 0, FALSE );
+ SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm();
+ if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( *pTmpFly ) )
+ {
+ bRet = 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;
+}
+
+BOOL SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt,
+ const Point& rInsPt, BOOL bIsMove, BOOL bSelectInsert )
+{
+ BOOL bRet = TRUE;
+
+ //Die Liste muss kopiert werden, weil unten die neuen Objekte
+ //selektiert werden.
+ const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() );
+ 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( USHORT 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();
+
+ BOOL bInsWithFmt = 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, FALSE );
+ pNew->NbcMove( aSiz );
+ pDestDrwView->InsertObjectAtView( pNew, *pDestPgView );
+ bInsWithFmt = 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 = FALSE;
+ else
+ bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt,
+ *pDestShell, aAnchor, aNewAnch, FALSE );
+ }
+ else
+ {
+ SwPaM *pCrsr = pDestShell->GetCrsr();
+ if( pCrsr->GetNode()->IsNoTxtNode() )
+ bRet = FALSE;
+ else
+ bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(),
+ *pCrsr->GetNode(), 0, rInsPt,
+ *pDestShell, aAnchor,
+ aNewAnch, 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, 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();
+
+ ULONG nMrkCnt = aMrkList.GetMarkCount();
+ USHORT 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;
+}
+
+BOOL SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
+ const Point& rInsPt, BOOL bIsMove, BOOL bSelectInsert )
+{
+ BOOL bRet = 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.
+ BOOL bCopyIsMove = pDoc->IsCopyIsMove();
+ if( bIsMove )
+ // am Doc ein Flag setzen, damit in den TextNodes
+ pDoc->SetCopyIsMove( 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 = 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 = FALSE;
+ else
+ { //Nicht in sich selbst kopieren
+ const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
+ if ( aPos.nNode > *pTmp && aPos.nNode <
+ pTmp->GetNode().EndOfSectionIndex() )
+ {
+ bRet = FALSE;
+ }
+ else
+ bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
+ *pDestShell, aAnchor, aNewAnch, TRUE );
+ }
+ }
+ else
+ {
+ const SwPaM *pCrsr = pDestShell->GetCrsr();
+ if( pCrsr->GetNode()->IsNoTxtNode() )
+ bRet = 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, FALSE );
+ if( pFlyFrm )
+ {
+ //JP 12.05.98: sollte das nicht im SelectFlyFrm stehen???
+ pDestShell->Imp()->GetDrawView()->UnmarkAll();
+ pDestShell->SelectFlyFrm( *pFlyFrm, 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 = TRUE;
+ }
+ else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
+ {
+ pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
+ bRet = 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 = 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 = 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
+ USHORT 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;
+}
+
+BOOL SwFEShell::Paste( SwDoc* pClpDoc, BOOL bIncludingPageFrames )
+{
+ SET_CURR_SHELL( this );
+ ASSERT( pClpDoc, "kein Clipboard-Dokument" );
+ const USHORT 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 );
+
+ BOOL bRet = TRUE, bDelTbl = TRUE;
+ StartAllAction();
+ GetDoc()->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;
+ USHORT 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( 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() );
+
+ BOOL bParkTblCrsr = 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 = 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
+ ::PaMCorrAbs( SwNodeIndex( *pDestNd ),
+ SwNodeIndex( *pDestNd->EndOfSectionNode() ),
+ aPos );
+ }
+
+ bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
+ FALSE, 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
+ ::PaMCorrAbs( PCURCRSR->GetPoint()->nNode, 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 ( USHORT i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
+ {
+ BOOL bInsWithFmt = 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,
+ FALSE, 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 = 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, 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, FALSE );
+ if( pFlyFrm )
+ SelectFlyFrm( *pFlyFrm, 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 = 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 ( USHORT i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
+ {
+ BOOL bInsWithFmt = 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()->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
+ USHORT 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---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+BOOL SwFEShell::PastePages( SwFEShell& rToFill, USHORT nStartPage, USHORT nEndPage)
+{
+ Push();
+ if(!GotoPage(nStartPage))
+ {
+ Pop(sal_False);
+ return FALSE;
+ }
+ MovePage( fnPageCurr, fnPageStart );
+ SwPaM aCpyPam( *GetCrsr()->GetPoint() );
+ String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName();
+ SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, TRUE );
+ if( pDesc )
+ rToFill.ChgCurPageDesc( *pDesc );
+
+ if(!GotoPage(nEndPage))
+ {
+ Pop(sal_False);
+ return 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 ( USHORT 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 TRUE;
+}
+
+BOOL SwFEShell::GetDrawObjGraphic( ULONG nFmt, Graphic& rGrf ) const
+{
+ ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ BOOL bConvert = 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 = FALSE;
+ }
+ else if( GetWin() )
+ {
+ Size aSz;
+ Point aPt;
+ GetGrfSize( aSz );
+
+ VirtualDevice aVirtDev;
+ aVirtDev.EnableOutput( 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 = 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 = 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, USHORT 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, TRUE );
+ }
+ break;
+
+ case SW_PASTESDR_SETATTR:
+ {
+ SfxItemSet aSet( GetAttrPool() );
+ aSet.Put(pClpObj->GetMergedItemSet());
+ pView->SetAttributes( aSet, FALSE );
+ }
+ break;
+
+ default:
+ nAction = SW_PASTESDR_INSERT;
+ break;
+ }
+ }
+ else
+ nAction = SW_PASTESDR_INSERT;
+
+ if( SW_PASTESDR_INSERT == nAction )
+ {
+ GetDoc()->SetNoDrawUndoObj( TRUE );
+
+ 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 );
+
+ ULONG nCnt = pView->GetMarkedObjectList().GetMarkCount();
+ if( nCnt )
+ {
+ const Point aNull( 0, 0 );
+ for( 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 );
+ }
+ GetDoc()->SetNoDrawUndoObj( FALSE );
+ }
+ EndUndo();
+ EndAllAction();
+ delete pModel;
+}
+
+BOOL SwFEShell::Paste( const Graphic &rGrf )
+{
+ SET_CURR_SHELL( this );
+ SdrObject* pObj;
+ SdrView *pView = Imp()->GetDrawView();
+
+ 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, FALSE );
+ }
+ return bRet;
+}
diff --git a/sw/source/core/frmedt/fedesc.cxx b/sw/source/core/frmedt/fedesc.cxx
new file mode 100644
index 000000000000..fe73c36016a0
--- /dev/null
+++ b/sw/source/core/frmedt/fedesc.cxx
@@ -0,0 +1,291 @@
+/*************************************************************************
+ *
+ * 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 <tools/ref.hxx>
+#include <fesh.hxx>
+#include <doc.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <cntfrm.hxx>
+#include <pam.hxx>
+#include <fmtpdsc.hxx>
+#include <pagedesc.hxx>
+#include <tabfrm.hxx>
+#include <edimp.hxx>
+#include <SwStyleNameMapper.hxx>
+/*************************************************************************
+|*
+|* SwFEShell::GetPageDescCnt()
+|*
+|* Ersterstellung MA 25. Jan. 93
+|* Letzte Aenderung MA 25. Jan. 93
+|*
+|*************************************************************************/
+
+USHORT SwFEShell::GetPageDescCnt() const
+{
+ return GetDoc()->GetPageDescCnt();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::ChgCurPageDesc()
+|*
+|* Ersterstellung ST ??
+|* Letzte Aenderung MA 01. Aug. 94
+|*
+|*************************************************************************/
+
+void SwFEShell::ChgCurPageDesc( const SwPageDesc& rDesc )
+{
+#ifdef DBG_UTIL
+ //Die SS veraendert keinen PageDesc, sondern setzt nur das Attribut.
+ //Der Pagedesc muss im Dokument vorhanden sein!
+ BOOL bFound = FALSE;
+ for ( USHORT nTst = 0; nTst < GetPageDescCnt(); ++nTst )
+ if ( &rDesc == &GetPageDesc( nTst ) )
+ bFound = TRUE;
+ ASSERT( bFound, "ChgCurPageDesc mit ungueltigem Descriptor." );
+#endif
+
+ StartAllAction();
+
+ SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
+ const SwFrm *pFlow = 0;
+ USHORT nPageNmOffset = 0;
+
+ ASSERT( !GetCrsr()->HasMark(), "ChgCurPageDesc nur ohne Selektion!");
+
+ SET_CURR_SHELL( this );
+ while ( pPage )
+ {
+ pFlow = pPage->FindFirstBodyCntnt();
+ if ( pFlow )
+ {
+ if ( pFlow->IsInTab() )
+ pFlow = pFlow->FindTabFrm();
+ const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+ if( rPgDesc.GetPageDesc() )
+ {
+ // wir haben ihn den Schlingel
+ nPageNmOffset = rPgDesc.GetNumOffset();
+ break;
+ }
+ }
+ pPage = (SwPageFrm*) pPage->GetPrev();
+ }
+ if ( !pPage )
+ {
+ pPage = (SwPageFrm*) (GetLayout()->Lower());
+ pFlow = pPage->FindFirstBodyCntnt();
+ if ( !pFlow )
+ {
+ pPage = (SwPageFrm*)pPage->GetNext();
+ pFlow = pPage->FindFirstBodyCntnt();
+ ASSERT( pFlow, "Dokuemnt ohne Inhalt?!?" );
+ }
+ }
+
+ // Seitennummer mitnehmen
+ SwFmtPageDesc aNew( &rDesc );
+ aNew.SetNumOffset( nPageNmOffset );
+
+ if ( pFlow->IsInTab() )
+ GetDoc()->SetAttr( aNew, *(SwFmt*)pFlow->FindTabFrm()->GetFmt() );
+ else
+ {
+ SwPaM aPaM( *((SwCntntFrm*)pFlow)->GetNode() );
+ GetDoc()->InsertPoolItem( aPaM, aNew, 0 );
+ }
+ EndAllActionAndCall();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::ChgPageDesc()
+|*
+|* Ersterstellung MA 25. Jan. 93
+|* Letzte Aenderung MA 24. Jan. 95
+|*
+|*************************************************************************/
+
+void SwFEShell::ChgPageDesc( USHORT i, const SwPageDesc &rChged )
+{
+ StartAllAction();
+ SET_CURR_SHELL( this );
+ //Fix i64842: because Undo has a very special way to handle header/footer content
+ // we have to copy the page descriptor before calling ChgPageDesc.
+ const sal_Bool bDoesUndo( GetDoc()->DoesUndo() );
+ SwPageDesc aDesc( rChged );
+ GetDoc()->DoUndo( sal_False );
+ GetDoc()->CopyPageDesc(rChged, aDesc);
+ GetDoc()->DoUndo( bDoesUndo );
+ GetDoc()->ChgPageDesc( i, aDesc );
+ EndAllActionAndCall();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetPageDesc(), GetCurPageDesc()
+|*
+|* Ersterstellung MA 25. Jan. 93
+|* Letzte Aenderung MA 23. Apr. 93
+|
+|*************************************************************************/
+
+const SwPageDesc& SwFEShell::GetPageDesc( USHORT i ) const
+{
+ return const_cast<const SwDoc *>(GetDoc())->GetPageDesc( i );
+}
+
+SwPageDesc* SwFEShell::FindPageDescByName( const String& rName,
+ BOOL bGetFromPool,
+ USHORT* pPos )
+{
+ SwPageDesc* pDesc = GetDoc()->FindPageDescByName( rName, pPos );
+ if( !pDesc && bGetFromPool )
+ {
+ USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( rName, nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC );
+ if( USHRT_MAX != nPoolId &&
+ 0 != (pDesc = GetDoc()->GetPageDescFromPool( nPoolId ))
+ && pPos )
+ // werden immer hinten angehaengt
+ *pPos = GetDoc()->GetPageDescCnt() - 1 ;
+ }
+ return pDesc;
+}
+
+USHORT SwFEShell::GetMousePageDesc( const Point &rPt ) const
+{
+ if( GetLayout() )
+ {
+ const SwPageFrm* pPage =
+ static_cast<const SwPageFrm*>( GetLayout()->Lower() );
+ if( pPage )
+ {
+ while( pPage->GetNext() && rPt.Y() > pPage->Frm().Bottom() )
+ pPage = static_cast<const SwPageFrm*>( pPage->GetNext() );
+ SwDoc *pMyDoc = GetDoc();
+ for ( USHORT i = 0; i < GetDoc()->GetPageDescCnt(); ++i )
+ {
+ if ( pPage->GetPageDesc() == &const_cast<const SwDoc *>(pMyDoc)
+ ->GetPageDesc(i) )
+ return i;
+ }
+ }
+ }
+ return 0;
+}
+
+USHORT SwFEShell::GetCurPageDesc( const BOOL bCalcFrm ) const
+{
+ const SwFrm *pFrm = GetCurrFrm( bCalcFrm );
+ if ( pFrm )
+ {
+ const SwPageFrm *pPage = pFrm->FindPageFrm();
+ if ( pPage )
+ {
+ SwDoc *pMyDoc = GetDoc();
+ for ( USHORT i = 0; i < GetDoc()->GetPageDescCnt(); ++i )
+ {
+ if ( pPage->GetPageDesc() == &const_cast<const SwDoc *>(pMyDoc)
+ ->GetPageDesc(i) )
+ return i;
+ }
+ }
+ }
+ return 0;
+}
+
+// if inside all selection only one PageDesc, return this.
+// Otherwise return 0 pointer
+const SwPageDesc* SwFEShell::GetSelectedPageDescs() const
+{
+ const SwCntntNode* pCNd;
+ const SwFrm* pMkFrm, *pPtFrm;
+ const SwPageDesc* pFnd, *pRetDesc = (SwPageDesc*)0xffffffff;
+ const Point aNulPt;
+
+ FOREACHPAM_START(this)
+
+ if( 0 != (pCNd = PCURCRSR->GetCntntNode() ) &&
+ 0 != ( pPtFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
+ pPtFrm = pPtFrm->FindPageFrm();
+ else
+ pPtFrm = 0;
+
+ if( PCURCRSR->HasMark() &&
+ 0 != (pCNd = PCURCRSR->GetCntntNode( FALSE ) ) &&
+ 0 != ( pMkFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
+ pMkFrm = pMkFrm->FindPageFrm();
+ else
+ pMkFrm = pPtFrm;
+
+
+ if( !pMkFrm || !pPtFrm )
+ pFnd = 0;
+ else if( pMkFrm == pPtFrm )
+ pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
+ else
+ {
+ // swap pointer if PtFrm before MkFrm
+ if( ((SwPageFrm*)pMkFrm)->GetPhyPageNum() >
+ ((SwPageFrm*)pPtFrm)->GetPhyPageNum() )
+ {
+ const SwFrm* pTmp = pMkFrm; pMkFrm = pPtFrm; pPtFrm = pTmp;
+ }
+
+ // now check from MkFrm to PtFrm for equal PageDescs
+ pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
+ while( pFnd && pMkFrm != pPtFrm )
+ {
+ pMkFrm = pMkFrm->GetNext();
+ if( !pMkFrm || pFnd != ((SwPageFrm*)pMkFrm)->GetPageDesc() )
+ pFnd = 0;
+ }
+ }
+
+ if( (SwPageDesc*)0xffffffff == pRetDesc )
+ pRetDesc = pFnd;
+ else if( pFnd != pRetDesc )
+ {
+ pRetDesc = 0;
+ break;
+ }
+
+ FOREACHPAM_END()
+
+ return pRetDesc;
+}
+
+
+
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
new file mode 100644
index 000000000000..0dc721a62f12
--- /dev/null
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -0,0 +1,2156 @@
+/*************************************************************************
+ *
+ * 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 <svl/itemiter.hxx>
+#include <svtools/imapobj.hxx>
+#include <svtools/soerr.hxx>
+#include <editeng/protitem.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/fmglob.hxx>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <fmtanchr.hxx>
+#include <txtflcnt.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtornt.hxx>
+#include <fmtflcnt.hxx>
+#include <fmturl.hxx>
+#include <fmtclds.hxx>
+#include <fmtfsize.hxx>
+#include <docary.hxx>
+#include <fesh.hxx>
+#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <cntfrm.hxx>
+#include <txtfrm.hxx>
+#include <viewimp.hxx>
+#include <viscrs.hxx>
+#include <doc.hxx>
+#include <dview.hxx>
+#include <dflyobj.hxx>
+#include <dcontact.hxx>
+#include <frmfmt.hxx>
+#include <flyfrm.hxx>
+#include <ndtxt.hxx>
+#include <edimp.hxx>
+#include <swtable.hxx>
+#include <mvsave.hxx> // Strukturen zum Sichern beim Move/Delete
+#include <ndgrf.hxx>
+#include <flyfrms.hxx>
+#include <flypos.hxx>
+#include <fldbas.hxx>
+#include <fmtfld.hxx>
+#include <swundo.hxx>
+// --> OD 2006-03-06 #125892#
+#include <HandleAnchorNodeChg.hxx>
+// <--
+#include <frmatr.hxx>
+// --> OD 2009-12-29 #i89920#
+#include <fmtsrnd.hxx>
+#include <editeng/opaqitem.hxx>
+// <--
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+
+//Zum anmelden von Flys in Flys in ...
+//definiert in layout/frmtool.cxx
+void RegistFlys( SwPageFrm*, const SwLayoutFrm* );
+
+/***********************************************************************
+#* Class : SwDoc
+#* Methode : UseSpzLayoutFmt
+#* Beschreibung: Anhand des Request werden zu dem Format entsprechende
+#* Aenderungen an den Spezifischen Layouts vorgenommen.
+#* Datum : MA 23. Sep. 92
+#* Update : JP 09.03.98
+#***********************************************************************/
+
+sal_Bool lcl_SetNewFlyPos( const SwNode& rNode, SwFmtAnchor& rAnchor,
+ const Point& rPt )
+{
+ sal_Bool bRet = sal_False;
+ const SwStartNode* pStNode = rNode.FindFlyStartNode();
+ if( pStNode )
+ {
+ SwPosition aPos( *pStNode );
+ rAnchor.SetAnchor( &aPos );
+ bRet = sal_True;
+ }
+ else
+ {
+ const SwCntntNode *pCntNd = rNode.GetCntntNode();
+ const SwCntntFrm* pCFrm = pCntNd ? pCntNd->GetFrm( &rPt, 0, sal_False ) : 0;
+ const SwPageFrm *pPg = pCFrm ? pCFrm->FindPageFrm() : 0;
+
+ rAnchor.SetPageNum( pPg ? pPg->GetPhyPageNum() : 1 );
+ rAnchor.SetType( FLY_AT_PAGE );
+ }
+ return bRet;
+}
+
+BOOL lcl_FindAnchorPos( SwDoc& rDoc, const Point& rPt, const SwFrm& rFrm,
+ SfxItemSet& rSet )
+{
+ BOOL bRet = TRUE;
+ SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
+ RndStdIds nNew = aNewAnch.GetAnchorId();
+ const SwFrm *pNewAnch;
+
+ //Neuen Anker ermitteln
+ Point aTmpPnt( rPt );
+ switch( nNew )
+ {
+ case FLY_AS_CHAR: // sollte der nicht auch mit hinein?
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR: // LAYER_IMPL
+ {
+ //Ausgehend von der linken oberen Ecke des Fly den
+ //dichtesten CntntFrm suchen.
+ const SwFrm* pFrm = rFrm.IsFlyFrm() ? ((SwFlyFrm&)rFrm).GetAnchorFrm()
+ : &rFrm;
+ pNewAnch = ::FindAnchor( pFrm, aTmpPnt );
+ if( pNewAnch->IsProtected() )
+ {
+ bRet = FALSE;
+ break;
+ }
+
+ SwPosition aPos( *((SwCntntFrm*)pNewAnch)->GetNode() );
+ if ((FLY_AT_CHAR == nNew) || (FLY_AS_CHAR == nNew))
+ {
+ // es muss ein TextNode gefunden werden, denn nur in diesen
+ // ist ein Inhaltsgebundene Frames zu verankern
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ aTmpPnt.X() -= 1; //nicht im Fly landen!!
+ if( !pNewAnch->GetCrsrOfst( &aPos, aTmpPnt, &aState ) )
+ {
+ SwCntntNode* pCNd = ((SwCntntFrm*)pNewAnch)->GetNode();
+ if( pNewAnch->Frm().Bottom() < aTmpPnt.Y() )
+ pCNd->MakeStartIndex( &aPos.nContent );
+ else
+ pCNd->MakeEndIndex( &aPos.nContent );
+ }
+ }
+ aNewAnch.SetAnchor( &aPos );
+ }
+ break;
+
+ case FLY_AT_FLY: // LAYER_IMPL
+ {
+ //Ausgehend von der linken oberen Ecke des Fly den
+ //dichtesten SwFlyFrm suchen.
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ SwPosition aPos( rDoc.GetNodes() );
+ aTmpPnt.X() -= 1; //nicht im Fly landen!!
+ rDoc.GetRootFrm()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
+ pNewAnch = ::FindAnchor(
+ aPos.nNode.GetNode().GetCntntNode()->GetFrm( 0, 0, sal_False ),
+ aTmpPnt )->FindFlyFrm();
+
+ if( pNewAnch && &rFrm != pNewAnch && !pNewAnch->IsProtected() )
+ {
+ aPos.nNode = *((SwFlyFrm*)pNewAnch)->GetFmt()->GetCntnt().
+ GetCntntIdx();
+ aNewAnch.SetAnchor( &aPos );
+ break;
+ }
+ }
+
+ aNewAnch.SetType( nNew = FLY_AT_PAGE );
+ // no break
+
+ case FLY_AT_PAGE:
+ pNewAnch = rFrm.FindPageFrm();
+ aNewAnch.SetPageNum( pNewAnch->GetPhyPageNum() );
+ break;
+
+ default:
+ ASSERT( !&rDoc, "Falsche ID fuer neuen Anker." );
+ }
+
+ rSet.Put( aNewAnch );
+ return bRet;
+}
+
+//
+//! also used in unoframe.cxx
+//
+sal_Bool lcl_ChkAndSetNewAnchor( const SwFlyFrm& rFly, SfxItemSet& rSet )
+{
+ const SwFrmFmt& rFmt = *rFly.GetFmt();
+ const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
+ const RndStdIds nOld = rOldAnch.GetAnchorId();
+
+ RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId();
+
+ if( nOld == nNew )
+ return sal_False;
+
+ SwDoc* pDoc = (SwDoc*)rFmt.GetDoc();
+
+#ifdef DBG_UTIL
+ ASSERT( !(nNew == FLY_AT_PAGE &&
+ (FLY_AT_PARA==nOld || FLY_AT_CHAR==nOld || FLY_AS_CHAR==nOld ) &&
+ pDoc->IsInHeaderFooter( rOldAnch.GetCntntAnchor()->nNode )),
+ "Unerlaubter Ankerwechsel in Head/Foot." );
+#endif
+
+ return ::lcl_FindAnchorPos( *pDoc, rFly.Frm().Pos(), rFly, rSet );
+}
+
+void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, sal_Bool bNew )
+{
+ SET_CURR_SHELL( this );
+
+ // Wenn es ein neuer Rahmen ist, so soll er selektiert sein.
+ // !!Rahmen immer selektieren, wenn sie nicht selektiert sind.
+ // - Es kann ein neuer 'alter' sein weil der Anker gewechselt wurde.
+ // - 'alte' Rahmen sind vorher immer selektiert denn sonst wird nix
+ // an ihnen veraendert.
+ // Der Rahmen darf nicht per Dokumentposition selektiert werden, weil er
+ // auf jedenfall selektiert sein muss!
+ SwViewImp *pImpl = Imp();
+ if( GetWin() && (bNew || !pImpl->GetDrawView()->AreObjectsMarked()) )
+ {
+ ASSERT( rFrm.IsFlyFrm(), "SelectFlyFrm will einen Fly" );
+
+ //Wenn der Fly bereits selektiert ist gibt es hier ja wohl nichts
+ //zu tun.
+ if ( FindFlyFrm() == &rFrm )
+ return;
+
+ //Damit der Anker ueberhaupt noch gepaintet wird.
+ if( rFrm.IsFlyInCntFrm() && rFrm.GetAnchorFrm() )
+ rFrm.GetAnchorFrm()->SetCompletePaint();
+
+ // --> OD 2004-06-11 #i28701# - no format at all.
+// //Hier wurde immer kalkuliert. Leider ist der Sonderfall Fly in Fly mit
+// //Spalten u.U. sehr kritisch wenn der innenliegende zuerst formatiert
+// //wird. Um kein Risiko einzugehen entschaerfen wir nur diesen Sonderfall.
+// if( !rFrm.GetAnchorFrm()->IsInFly() )
+// rFrm.Calc();
+
+ if( pImpl->GetDrawView()->AreObjectsMarked() )
+ pImpl->GetDrawView()->UnmarkAll();
+
+ pImpl->GetDrawView()->MarkObj( rFrm.GetVirtDrawObj(),
+ pImpl->GetPageView(), sal_False, sal_False );
+ KillPams();
+ ClearMark();
+ SelFlyGrabCrsr();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::FindFlyFrm()
+|*
+|* Beschreibung Liefert den Fly wenn einer Selektiert ist.
+|* Ersterstellung MA 03. Nov. 92
+|* Letzte Aenderung MA 05. Mar. 96
+|*
+*************************************************************************/
+
+SwFlyFrm *SwFEShell::FindFlyFrm() const
+{
+ if ( Imp()->HasDrawView() )
+ {
+ // Ein Fly ist genau dann erreichbar, wenn er selektiert ist.
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ if( rMrkList.GetMarkCount() != 1 )
+ return 0;
+
+ SdrObject *pO = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ return pO->ISA(SwVirtFlyDrawObj) ? ((SwVirtFlyDrawObj*)pO)->GetFlyFrm() : 0;
+ }
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::IsFlyInFly()
+|*
+|* Beschreibung Liefert sal_True, wenn der aktuelle Fly an einem anderen
+|* verankert werden koennte (also innerhalb ist)
+|* Ersterstellung AMA 11. Sep. 97
+|* Letzte Aenderung AMA 14. Jan. 98
+|*
+*************************************************************************/
+
+const SwFrmFmt* SwFEShell::IsFlyInFly()
+{
+ SET_CURR_SHELL( this );
+
+ if ( !Imp()->HasDrawView() )
+ return NULL;
+
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ if ( !rMrkList.GetMarkCount() )
+ {
+ SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+ if( !pCntnt )
+ return NULL;
+ SwFlyFrm *pFly = pCntnt->FindFlyFrm();
+ if ( !pFly )
+ return NULL;
+ return pFly->GetFmt();
+ }
+ else if ( rMrkList.GetMarkCount() != 1 ||
+ !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
+ return NULL;
+
+ SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+
+ SwFrmFmt *pFmt = FindFrmFmt( pObj );
+ if( pFmt && FLY_AT_FLY == pFmt->GetAnchor().GetAnchorId() )
+ {
+ const SwFrm* pFly = pObj->ISA(SwVirtFlyDrawObj) ?
+ ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetAnchorFrm() :
+ ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj );
+ ASSERT( pFly, "IsFlyInFly: Where's my anchor?" );
+ ASSERT( pFly->IsFlyFrm(), "IsFlyInFly: Funny anchor!" );
+ return ((SwFlyFrm*)pFly)->GetFmt();
+ }
+
+ Point aTmpPos = pObj->GetCurrentBoundRect().TopLeft();
+
+ SwFrm *pTxtFrm;
+ {
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ SwNodeIndex aSwNodeIndex( GetDoc()->GetNodes() );
+ SwPosition aPos( aSwNodeIndex );
+ Point aPoint( aTmpPos );
+ aPoint.X() -= 1; //nicht im Fly landen!!
+ GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
+ // OD 01.07.2003 #108784# - determine text frame by left-top-corner
+ // of object
+ //pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->GetFrm( 0, 0, sal_False );
+ pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aTmpPos, 0, sal_False );
+ }
+ const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aTmpPos );
+ const SwFlyFrm *pFly = pTmp->FindFlyFrm();
+ if( pFly )
+ return pFly->GetFmt();
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::SetFlyPos
+|*
+|* Ersterstellung MA 14. Jan. 93
+|* Letzte Aenderung MA 14. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::SetFlyPos( const Point& rAbsPos )
+{
+ SET_CURR_SHELL( this );
+
+ //Bezugspunkt in Dokumentkoordinaten bestimmen
+ SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+ if( !pCntnt )
+ return;
+ SwFlyFrm *pFly = pCntnt->FindFlyFrm();
+ if ( !pFly )
+ return;
+
+ //SwSaveHdl aSaveX( Imp() );
+
+ //Bei Absatzgebundenen Flys muss ausgehend von der absoluten
+ //Position ein neuer Anker gesetzt werden. Anker und neue RelPos werden
+ //vom Fly selbst berechnet und gesetzt.
+ if ( pFly->IsFlyAtCntFrm() )
+ ((SwFlyAtCntFrm*)pFly)->SetAbsPos( rAbsPos );
+ else
+ {
+ const SwFrm *pAnch = pFly->GetAnchorFrm();
+ // --> OD 2004-06-11 #i28701# - no format here
+// pAnch->Calc();
+ Point aOrient( pAnch->Frm().Pos() );
+
+ if ( pFly->IsFlyInCntFrm() )
+ aOrient.X() = rAbsPos.X();
+
+ //RelPos errechnen.
+ aOrient.X() = rAbsPos.X() - aOrient.X();
+ aOrient.Y() = rAbsPos.Y() - aOrient.Y();
+ pFly->ChgRelPos( aOrient );
+ }
+ // --> OD 2004-06-11 #i28701# - no format here
+// pFly->Calc();
+ CallChgLnk(); // rufe das AttrChangeNotify auf der UI-Seite.
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::FindAnchorPos
+|*
+|* Ersterstellung AMA 24. Sep. 97
+|* Letzte Aenderung AMA 24. Sep. 97
+|*
+*************************************************************************/
+
+Point SwFEShell::FindAnchorPos( const Point& rAbsPos, sal_Bool bMoveIt )
+{
+ Point aRet;
+
+ SET_CURR_SHELL( this );
+
+ if ( !Imp()->HasDrawView() )
+ return aRet;
+
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ if ( rMrkList.GetMarkCount() != 1 ||
+ !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
+ return aRet;
+
+ SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ // --> OD 2004-07-16 #i28701#
+ SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
+ SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
+ RndStdIds nAnchorId = rFmt.GetAnchor().GetAnchorId();
+
+ if ( FLY_AS_CHAR == nAnchorId )
+ return aRet;
+
+ sal_Bool bFlyFrame = pObj->ISA(SwVirtFlyDrawObj);
+
+ SwFlyFrm* pFly = 0L;
+ const SwFrm* pOldAnch;
+ const SwFrm* pFooterOrHeader = NULL;
+
+ if( bFlyFrame )
+ {
+ //Bezugspunkt in Dokumentkoordinaten bestimmen
+ SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+ if( !pCntnt )
+ return aRet;
+ pFly = pCntnt->FindFlyFrm();
+ if ( !pFly )
+ return aRet;
+ pOldAnch = pFly->GetAnchorFrm();
+ if( !pOldAnch )
+ return aRet;
+ if ( FLY_AT_PAGE != nAnchorId )
+ {
+ pFooterOrHeader = pCntnt->FindFooterOrHeader();
+ }
+ }
+ // OD 26.06.2003 #108784# - set <pFooterOrHeader> also for drawing
+ // objects, but not for control objects.
+ // Necessary for moving 'anchor symbol' at the user interface inside header/footer.
+ else if ( !::CheckControlLayer( pObj ) )
+ {
+ SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+ if( !pCntnt )
+ return aRet;
+ pFooterOrHeader = pCntnt->FindFooterOrHeader();
+ }
+
+ //Ausgehend von der linken oberen Ecke des Fly den
+ //dichtesten SwFlyFrm suchen.
+ SwCntntFrm *pTxtFrm;
+ {
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ SwPosition aPos( GetDoc()->GetNodes().GetEndOfExtras() );
+ Point aTmpPnt( rAbsPos );
+ GetLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
+ pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->GetFrm(0,&aPos,FALSE );
+ }
+ const SwFrm *pNewAnch;
+ if( pTxtFrm )
+ {
+ if ( FLY_AT_PAGE == nAnchorId )
+ {
+ pNewAnch = pTxtFrm->FindPageFrm();
+ }
+ else
+ {
+ pNewAnch = ::FindAnchor( pTxtFrm, rAbsPos );
+
+ if( FLY_AT_FLY == nAnchorId ) // LAYER_IMPL
+ {
+ pNewAnch = pNewAnch->FindFlyFrm();
+ }
+ }
+ }
+ else
+ pNewAnch = 0;
+
+ if( pNewAnch && !pNewAnch->IsProtected() )
+ {
+ const SwFlyFrm* pCheck = bFlyFrame ? pNewAnch->FindFlyFrm() : 0;
+ // Falls wir innerhalb eines Rahmens landen, muss sichergestellt werden,
+ // dass der Rahmen nicht in seinem eigenen Inhalt landet!
+ while( pCheck )
+ {
+ if( pCheck == pFly )
+ break;
+ const SwFrm *pTmp = pCheck->GetAnchorFrm();
+ pCheck = pTmp ? pTmp->FindFlyFrm() : NULL;
+ }
+ // Es darf nicht aus einer Kopf-/Fusszeile in einen anderen Bereich
+ // gewechselt werden, es darf nicht in eine Kopf-/Fusszeile hinein-
+ // gewechselt werden.
+ if( !pCheck &&
+ pFooterOrHeader == pNewAnch->FindFooterOrHeader() )
+ {
+ aRet = pNewAnch->GetFrmAnchorPos( ::HasWrap( pObj ) );
+
+ if ( bMoveIt || (nAnchorId == FLY_AT_CHAR) )
+ {
+ SwFmtAnchor aAnch( rFmt.GetAnchor() );
+ switch ( nAnchorId )
+ {
+ case FLY_AT_PARA:
+ {
+ SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
+ pPos->nNode = *pTxtFrm->GetNode();
+ pPos->nContent.Assign(0,0);
+ break;
+ }
+ case FLY_AT_PAGE:
+ {
+ aAnch.SetPageNum( ((const SwPageFrm*)pNewAnch)->
+ GetPhyPageNum() );
+ break;
+ }
+ case FLY_AT_FLY:
+ {
+ SwPosition aPos( *((SwFlyFrm*)pNewAnch)->GetFmt()->
+ GetCntnt().GetCntntIdx() );
+ aAnch.SetAnchor( &aPos );
+ break;
+ }
+ case FLY_AT_CHAR:
+ {
+ SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
+ Point aTmpPnt( rAbsPos );
+ if( pTxtFrm->GetCrsrOfst( pPos, aTmpPnt, NULL ) )
+ {
+ SwRect aTmpRect;
+ pTxtFrm->GetCharRect( aTmpRect, *pPos );
+ aRet = aTmpRect.Pos();
+ }
+ else
+ {
+ pPos->nNode = *pTxtFrm->GetNode();
+ pPos->nContent.Assign(0,0);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if( bMoveIt )
+ {
+ StartAllAction();
+ // --> OD 2006-02-28 #125892#
+ // handle change of anchor node:
+ // if count of the anchor frame also change, the fly frames have to be
+ // re-created. Thus, delete all fly frames except the <this> before the
+ // anchor attribute is change and re-create them afterwards.
+ {
+ SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
+ SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) );
+ if ( pFlyFrmFmt )
+ {
+ pHandleAnchorNodeChg =
+ new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch );
+ }
+ rFmt.GetDoc()->SetAttr( aAnch, rFmt );
+ delete pHandleAnchorNodeChg;
+ }
+ // <--
+ // --> OD 2004-06-24 #i28701# - no call of method
+ // <CheckCharRectAndTopOfLine()> for to-character anchored
+ // Writer fly frame needed. This method call can cause a
+ // format of the anchor frame, which is no longer intended.
+ // Instead clear the anchor character rectangle and
+ // the top of line values for all to-character anchored objects.
+ pAnchoredObj->ClearCharRectAndTopOfLine();
+ // <--
+ EndAllAction();
+ }
+ }
+
+ SwRect aTmpRect( aRet, rAbsPos );
+ if( aTmpRect.HasArea() )
+ MakeVisible( aTmpRect );
+#ifdef DBG_UTIL
+ //TODO: That doesn't seem to be intended
+ if( Color(COL_TRANSPARENT) != GetOut()->GetLineColor() )
+ {
+ ASSERT( FALSE, "Hey, Joe: Where's my Null Pen?" );
+ GetOut()->SetLineColor( Color(COL_TRANSPARENT) );
+ }
+#endif
+ }
+ }
+
+ return aRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : NewFlyFrm
+#* Beschreibung:
+#* Datum : MA 03. Nov. 92
+#* Update : JP 11. Aug. 93
+#***********************************************************************/
+
+const SwFrmFmt *SwFEShell::NewFlyFrm( const SfxItemSet& rSet, sal_Bool bAnchValid,
+ SwFrmFmt *pParent )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ SwPaM* pCrsr = GetCrsr();
+ const Point aPt( GetCrsrDocPos() );
+
+ SwSelBoxes aBoxes;
+ sal_Bool bMoveCntnt = sal_True;
+ if( IsTableMode() )
+ {
+ GetTblSel( *this, aBoxes );
+ if( aBoxes.Count() )
+ {
+ // die Crsr muessen noch aus dem Loeschbereich entfernt
+ // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+ // Dokument-Position werden sie dann immer an die alte
+ // Position gesetzt.
+ ParkCrsr( SwNodeIndex( *aBoxes[0]->GetSttNd() ));
+
+ // --> FME 2005-12-01 #i127787# pCurCrsr will be deleted in ParkCrsr,
+ // we better get the current pCurCrsr instead of working with the
+ // deleted one:
+ pCrsr = GetCrsr();
+ // <--
+
+// KillPams();
+ }
+ else
+ bMoveCntnt = sal_False;
+ }
+ else if( !pCrsr->HasMark() && pCrsr->GetNext() == pCrsr )
+ bMoveCntnt = sal_False;
+
+ const SwPosition& rPos = *pCrsr->Start();
+
+ SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR );
+ RndStdIds eRndId = rAnch.GetAnchorId();
+ switch( eRndId )
+ {
+ case FLY_AT_PAGE:
+ if( !rAnch.GetPageNum() ) //HotFix: Bug in UpdateByExample
+ rAnch.SetPageNum( 1 );
+ break;
+
+ case FLY_AT_FLY:
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR:
+ case FLY_AS_CHAR:
+ if( !bAnchValid )
+ {
+ if( FLY_AT_FLY != eRndId )
+ {
+ rAnch.SetAnchor( &rPos );
+ }
+ else if( lcl_SetNewFlyPos( rPos.nNode.GetNode(), rAnch, aPt ) )
+ {
+ eRndId = FLY_AT_PAGE;
+ }
+ }
+ break;
+
+ default:
+ ASSERT( !this, "Was sollte das fuer ein Fly werden?" )
+ break;
+ }
+
+ SwFlyFrmFmt *pRet;
+ if( bMoveCntnt )
+ {
+ GetDoc()->StartUndo( UNDO_INSLAYFMT, NULL );
+ SwFmtAnchor* pOldAnchor = 0;
+ sal_Bool bHOriChgd = sal_False, bVOriChgd = sal_False;
+ SwFmtVertOrient aOldV;
+ SwFmtHoriOrient aOldH;
+
+ if ( FLY_AT_PAGE != eRndId )
+ {
+ // erstmal als mit Seitenbindung, Absatz/Zeichenbindung erst wenn
+ // alles verschoben ist. Dann ist die Position gueltig!
+ // JP 13.05.98: ggfs. auch noch die Hori/Vert-Orientierung
+ // umsetzen, damit diese beim Umanker NICHT
+ // korrigiert wird
+ pOldAnchor = new SwFmtAnchor( rAnch );
+ const_cast<SfxItemSet&>(rSet).Put( SwFmtAnchor( FLY_AT_PAGE, 1 ) );
+
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rSet.GetItemState( RES_HORI_ORIENT, sal_False, &pItem )
+ && text::HoriOrientation::NONE == ((SwFmtHoriOrient*)pItem)->GetHoriOrient() )
+ {
+ bHOriChgd = sal_True;
+ aOldH = *((SwFmtHoriOrient*)pItem);
+ ((SfxItemSet&)rSet).Put( SwFmtHoriOrient( 0, text::HoriOrientation::LEFT ) );
+ }
+ if( SFX_ITEM_SET == rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem )
+ && text::VertOrientation::NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() )
+ {
+ bVOriChgd = sal_True;
+ aOldV = *((SwFmtVertOrient*)pItem);
+ ((SfxItemSet&)rSet).Put( SwFmtVertOrient( 0, text::VertOrientation::TOP ) );
+ }
+ }
+
+ pRet = GetDoc()->MakeFlyAndMove( *pCrsr, rSet, &aBoxes, pParent );
+
+ KillPams();
+
+ if( pOldAnchor )
+ {
+ if( pRet )
+ {
+ // neue Position bestimmen
+ //JP 24.03.97: immer ueber die Seitenbindung gehen - der
+ // chaos::Anchor darf nie im verschobenen Bereich
+ // liegen
+ pRet->DelFrms();
+
+ const SwFrm* pAnch = ::FindAnchor( GetLayout(), aPt, sal_False );
+ SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
+ if ( FLY_AS_CHAR == eRndId )
+ {
+ aPos.nContent.Assign( ((SwCntntFrm*)pAnch)->GetNode(), 0 );
+ }
+ pOldAnchor->SetAnchor( &aPos );
+
+ // das verschieben von TabelleSelektion ist noch nicht
+ // Undofaehig - also darf das UmAnkern auch nicht
+ // aufgezeichnet werden.
+ sal_Bool bDoesUndo = GetDoc()->DoesUndo();
+ if( bDoesUndo && UNDO_INSLAYFMT == GetDoc()->GetUndoIds(NULL, NULL) )
+ GetDoc()->DoUndo( sal_False );
+
+ ((SfxItemSet&)rSet).Put( *pOldAnchor );
+
+ if( bHOriChgd )
+ ((SfxItemSet&)rSet).Put( aOldH );
+ if( bVOriChgd )
+ ((SfxItemSet&)rSet).Put( aOldV );
+
+ GetDoc()->SetFlyFrmAttr( *pRet, (SfxItemSet&)rSet );
+ GetDoc()->DoUndo( bDoesUndo );
+ }
+ delete pOldAnchor;
+ }
+ GetDoc()->EndUndo( UNDO_INSLAYFMT, NULL );
+ }
+ else
+ /* #109161# If called from a shell try to propagate an
+ existing adjust item from rPos to the content node of the
+ new frame. */
+ pRet = GetDoc()->MakeFlySection( eRndId, &rPos, &rSet, pParent, TRUE );
+
+ if( pRet )
+ {
+ SwFlyFrm* pFrm = pRet->GetFrm( &aPt );
+ if( pFrm )
+ SelectFlyFrm( *pFrm, sal_True );
+ else
+ {
+ GetLayout()->SetAssertFlyPages();
+ pRet = 0;
+ }
+ }
+ EndAllActionAndCall();
+
+ return pRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : Insert
+#* Datum : ??
+#* Update : MA 12. Sep. 94
+#***********************************************************************/
+
+void SwFEShell::Insert( const String& rGrfName, const String& rFltName,
+ const Graphic* pGraphic,
+ const SfxItemSet* pFlyAttrSet,
+ const SfxItemSet* pGrfAttrSet,
+ SwFrmFmt* pFrmFmt )
+{
+ SwFlyFrmFmt* pFmt = 0;
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ SwShellCrsr *pStartCursor = dynamic_cast<SwShellCrsr*>(this->GetSwCrsr());
+ SwShellCrsr *pCursor = pStartCursor;
+ do {
+
+ // Anker noch nicht oder unvollstaendig gesetzt ?
+ if( pFlyAttrSet )
+ {
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pFlyAttrSet->GetItemState( RES_ANCHOR, sal_False,
+ &pItem ) )
+ {
+ SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
+ switch( pAnchor->GetAnchorId())
+ {
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR: // LAYER_IMPL
+ case FLY_AS_CHAR:
+ if( !pAnchor->GetCntntAnchor() )
+ {
+ pAnchor->SetAnchor( pCursor->GetPoint() );
+ }
+ break;
+ case FLY_AT_FLY:
+ if( !pAnchor->GetCntntAnchor() )
+ {
+ lcl_SetNewFlyPos( *pCursor->GetNode(),
+ *pAnchor, GetCrsrDocPos() );
+ }
+ break;
+ case FLY_AT_PAGE:
+ if( !pAnchor->GetPageNum() )
+ {
+ pAnchor->SetPageNum( pCursor->GetPageNum(
+ sal_True, &pCursor->GetPtPos() ) );
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ }
+ pFmt = GetDoc()->Insert(*pCursor, rGrfName,
+ rFltName, pGraphic,
+ pFlyAttrSet,
+ pGrfAttrSet, pFrmFmt );
+ ASSERT( pFmt, "Doc->Insert(notxt) failed." );
+
+ } while( (pCursor = dynamic_cast<SwShellCrsr*>(pCursor->GetNext()))
+ != pStartCursor );
+
+ EndAllAction();
+
+ if( pFmt )
+ {
+ const Point aPt( GetCrsrDocPos() );
+ SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
+
+ if( pFrm )
+ SelectFlyFrm( *pFrm, sal_True );
+ else
+ GetLayout()->SetAssertFlyPages();
+ }
+}
+
+SwFlyFrmFmt* SwFEShell::InsertObject( const svt::EmbeddedObjectRef& xObj,
+ const SfxItemSet* pFlyAttrSet,
+ const SfxItemSet* pGrfAttrSet,
+ SwFrmFmt* pFrmFmt )
+{
+ SwFlyFrmFmt* pFmt = 0;
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ FOREACHPAM_START( this )
+ pFmt = GetDoc()->Insert(*PCURCRSR, xObj,
+ pFlyAttrSet, pGrfAttrSet, pFrmFmt );
+ ASSERT( pFmt, "Doc->Insert(notxt) failed." );
+
+ FOREACHPAM_END()
+ EndAllAction();
+
+ if( pFmt )
+ {
+ const Point aPt( GetCrsrDocPos() );
+ SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
+
+ if( pFrm )
+ SelectFlyFrm( *pFrm, sal_True );
+ else
+ GetLayout()->SetAssertFlyPages();
+ }
+
+ return pFmt;
+}
+
+
+void SwFEShell::InsertDrawObj( SdrObject& rDrawObj,
+ const Point& rInsertPosition )
+{
+ SET_CURR_SHELL( this );
+
+ SfxItemSet rFlyAttrSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
+ rFlyAttrSet.Put( SwFmtAnchor( FLY_AT_PARA ));
+ // --> OD 2009-12-29 #i89920#
+ rFlyAttrSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
+ rDrawObj.SetLayer( getIDocumentDrawModelAccess()->GetHeavenId() );
+ // <--
+
+ // find anchor position
+ SwPaM aPam( pDoc->GetNodes() );
+ {
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ Point aTmpPt( rInsertPosition );
+ getIDocumentLayoutAccess()->GetRootFrm()->GetCrsrOfst( aPam.GetPoint(), aTmpPt, &aState );
+ const SwFrm* pFrm = aPam.GetCntntNode()->GetFrm( 0, 0, sal_False );
+ const Point aRelPos( rInsertPosition.X() - pFrm->Frm().Left(),
+ rInsertPosition.Y() - pFrm->Frm().Top() );
+ rDrawObj.SetRelativePos( aRelPos );
+ ::lcl_FindAnchorPos( *GetDoc(), rInsertPosition, *pFrm, rFlyAttrSet );
+ }
+ // insert drawing object into the document creating a new <SwDrawFrmFmt> instance
+ SwDrawFrmFmt* pFmt = GetDoc()->Insert( aPam, rDrawObj, &rFlyAttrSet, 0 );
+
+ // move object to visible layer
+ SwContact* pContact = static_cast<SwContact*>(rDrawObj.GetUserCall());
+ if ( pContact )
+ {
+ pContact->MoveObjToVisibleLayer( &rDrawObj );
+ }
+
+ if ( pFmt )
+ {
+ // select drawing object
+ Imp()->GetDrawView()->MarkObj( &rDrawObj, Imp()->GetPageView(),
+ sal_False, sal_False );
+ }
+ else
+ {
+ GetLayout()->SetAssertFlyPages();
+ }
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : GetPageObjs
+#* Datum : ??
+#* Update : MA 11. Jan. 95
+#***********************************************************************/
+
+void SwFEShell::GetPageObjs( SvPtrarr& rFillArr )
+{
+ if( rFillArr.Count() )
+ rFillArr.Remove( 0, rFillArr.Count() );
+
+ const SwFrmFmt* pFmt;
+ for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->Count(); ++n )
+ {
+ pFmt = (const SwFrmFmt*)(*pDoc->GetSpzFrmFmts())[n];
+ if (FLY_AT_PAGE == pFmt->GetAnchor().GetAnchorId())
+ {
+ rFillArr.Insert( (VoidPtr)pFmt, rFillArr.Count() );
+ }
+ }
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : SetPageFlysNewPage
+#* Datum : ??
+#* Update : MA 14. Feb. 95
+#***********************************************************************/
+
+void SwFEShell::SetPageObjsNewPage( SvPtrarr& rFillArr, int nOffset )
+{
+ if( !rFillArr.Count() || !nOffset )
+ return;
+
+ StartAllAction();
+ StartUndo();
+
+ SwFrmFmt* pFmt;
+ long nNewPage;
+ SwRootFrm* pTmpRootFrm = getIDocumentLayoutAccess()->GetRootFrm();
+ sal_uInt16 nMaxPage = pTmpRootFrm->GetPageNum();
+ sal_Bool bTmpAssert = sal_False;
+ for( sal_uInt16 n = 0; n < rFillArr.Count(); ++n )
+ {
+ pFmt = (SwFrmFmt*)rFillArr[n];
+ if( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( pFmt ))
+ {
+ // FlyFmt ist noch gueltig, also behandeln
+ SwFmtAnchor aNewAnchor( pFmt->GetAnchor() );
+ if ((FLY_AT_PAGE != aNewAnchor.GetAnchorId()) ||
+ 0 >= ( nNewPage = aNewAnchor.GetPageNum() + nOffset ) )
+ // chaos::Anchor wurde veraendert oder ungueltige SeitenNummer,
+ // also nicht veraendern !!
+ continue;
+
+ if( sal_uInt16(nNewPage) > nMaxPage )
+ {
+ if ( RES_DRAWFRMFMT == pFmt->Which() )
+ {
+ SwContact *pCon = pFmt->FindContactObj();
+ if( pCon )
+ ((SwDrawContact*)pCon)->DisconnectFromLayout();
+ }
+ else
+ pFmt->DelFrms();
+ bTmpAssert = sal_True;
+ }
+ aNewAnchor.SetPageNum( sal_uInt16(nNewPage) );
+ pDoc->SetAttr( aNewAnchor, *pFmt );
+ }
+ }
+
+ if( bTmpAssert )
+ pTmpRootFrm->SetAssertFlyPages();
+
+ EndUndo();
+ EndAllAction();
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : GetFlyFrmAttr
+#* Beschreibung: Alle Attribute in dem 'Koerbchen' werden mit den
+#* Attributen des aktuellen FlyFrms gefuellt.
+#* Sind Attribute nicht zu fuellen weil fehl am Platz oder
+#* uneindeutig (Mehrfachtselektionen) so werden sie entfernt.
+#* Datum : MA 03. Nov. 92
+#* Update : MA 03. Feb. 94
+#***********************************************************************/
+
+sal_Bool SwFEShell::GetFlyFrmAttr( SfxItemSet &rSet ) const
+{
+ SwFlyFrm *pFly = FindFlyFrm();
+ if ( !pFly )
+ {
+ // --> OD 2006-11-08 #139670# - make code robust
+ SwFrm* pCurrFrm( GetCurrFrm() );
+ if ( !pCurrFrm )
+ {
+ ASSERT( false,
+ "<SwFEShell::GetFlyFrmAttr(..)> - missing current frame. This is a serious defect, please inform OD." );
+ return sal_False;
+ }
+ // <--
+ pFly = GetCurrFrm()->FindFlyFrm();
+ if ( !pFly )
+ {
+ ASSERT( !this, "GetFlyFrmAttr, no Fly selected." );
+ return sal_False;
+ }
+ }
+
+ SET_CURR_SHELL( (ViewShell*)this );
+
+ if( !rSet.Set( pFly->GetFmt()->GetAttrSet(), sal_True ) )
+ return sal_False;
+
+ //Und die Attribute durchschaufeln. Unerlaubte Attribute entfernen, dann
+ //alle restlichen Attribute besorgen und eintragen.
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False, &pItem ) )
+ {
+ SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
+ RndStdIds eType = pAnchor->GetAnchorId();
+
+ if ( FLY_AT_PAGE != eType )
+ {
+ // OD 12.11.2003 #i22341# - content anchor of anchor item is needed.
+ // Thus, don't overwrite anchor item by default contructed anchor item.
+ //rSet.Put( SwFmtAnchor( eType ) );
+ if ( FLY_AS_CHAR == eType )
+ {
+ rSet.ClearItem( RES_OPAQUE );
+ rSet.ClearItem( RES_SURROUND );
+ }
+ }
+ }
+ rSet.SetParent( pFly->GetFmt()->GetAttrSet().GetParent() );
+ //JP 11.02.97: Bug #35894#: die Attribute MUESSEN entfern werden!
+ rSet.ClearItem( RES_FILL_ORDER );
+ rSet.ClearItem( RES_CNTNT );
+ //MA: Ersteinmal entfernen (Template by example usw.)
+ rSet.ClearItem( RES_CHAIN );
+ return sal_True;
+}
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : SetFlyFrmAttr
+#* Beschreibung: Die Attribute des aktuellen Flys aendern sich.
+#* Datum : MA 03. Nov. 92
+#* Update : MA 01. Aug. 95
+#***********************************************************************/
+
+sal_Bool SwFEShell::SetFlyFrmAttr( SfxItemSet& rSet )
+{
+ SET_CURR_SHELL( this );
+ sal_Bool bRet = sal_False;
+
+ if( rSet.Count() )
+ {
+ SwFlyFrm *pFly = FindFlyFrm();
+ if( !pFly )
+ {
+ ASSERT( GetCurrFrm(), "Crsr in parking zone" );
+ pFly = GetCurrFrm()->FindFlyFrm();
+ ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." );
+ }
+ if( pFly )
+ {
+ StartAllAction();
+ const Point aPt( pFly->Frm().Pos() );
+
+ if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False ))
+ ::lcl_ChkAndSetNewAnchor( *pFly, rSet );
+ SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
+
+ if( GetDoc()->SetFlyFrmAttr( *pFlyFmt, rSet ))
+ {
+ bRet = sal_True;
+ SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt );
+ if( pFrm )
+ SelectFlyFrm( *pFrm, sal_True );
+ else
+ GetLayout()->SetAssertFlyPages();
+ }
+
+ EndAllActionAndCall();
+ }
+ }
+ return bRet;
+}
+/*-- 30.03.2004 15:05:07---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+sal_Bool SwFEShell::SetDrawingAttr( SfxItemSet& rSet )
+{
+ sal_Bool bRet = sal_False;
+ SET_CURR_SHELL( this );
+ if ( !rSet.Count() ||
+ !Imp()->HasDrawView() )
+ return bRet;
+
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ if ( rMrkList.GetMarkCount() != 1 )
+ return bRet;
+
+ StartUndo();
+ SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ SwFrmFmt *pFmt = FindFrmFmt( pObj );
+ StartAllAction();
+ if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False ))
+ {
+ RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId();
+ if ( nNew != pFmt->GetAnchor().GetAnchorId() )
+ {
+ ChgAnchor( nNew );
+ // --> OD 2004-06-17 #i26791# - clear anchor attribute in item set,
+ // because method <ChgAnchor(..)> takes care of it.
+ rSet.ClearItem( RES_ANCHOR );
+ }
+ }
+
+ if( GetDoc()->SetFlyFrmAttr( *pFmt, rSet ))
+ {
+ bRet = sal_True;
+ Point aTmp;
+ SelectObj( aTmp, 0, pObj );
+ }
+ EndAllActionAndCall();
+ EndUndo();
+ return bRet;
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : ResetFlyFrmAttr
+#* Beschreibung: Das gewuenschte Attribut oder die im Set befindlichen
+#* werden zurueckgesetzt.
+#* Datum : MA 14. Mar. 97
+#* Update : MA 14. Mar. 97
+#***********************************************************************/
+
+sal_Bool SwFEShell::ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet )
+{
+ sal_Bool bRet = sal_False;
+
+ if( RES_ANCHOR != nWhich && RES_CHAIN != nWhich && RES_CNTNT != nWhich )
+ {
+ SET_CURR_SHELL( this );
+
+ SwFlyFrm *pFly = FindFlyFrm();
+ if( !pFly )
+ {
+ ASSERT( GetCurrFrm(), "Crsr in parking zone" );
+ pFly = GetCurrFrm()->FindFlyFrm();
+ ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." );
+ }
+
+ if( pFly )
+ {
+ StartAllAction();
+
+ if( pSet )
+ {
+ SfxItemIter aIter( *pSet );
+ const SfxPoolItem* pItem = aIter.FirstItem();
+ while( pItem )
+ {
+ if( !IsInvalidItem( pItem ) &&
+ RES_ANCHOR != ( nWhich = pItem->Which() ) &&
+ RES_CHAIN != nWhich && RES_CNTNT != nWhich )
+ pFly->GetFmt()->ResetFmtAttr( nWhich );
+ pItem = aIter.NextItem();
+ }
+ }
+ else
+ pFly->GetFmt()->ResetFmtAttr( nWhich );
+
+ bRet = sal_True;
+ EndAllActionAndCall();
+ GetDoc()->SetModified();
+ }
+ }
+ return bRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : GetCurFrmFmt
+#* Beschreibung: liefert wenn Rahmen, dann Rahmenvorlage, sonst 0
+#* Datum : ST 04. Jun. 93
+#* Update :
+#***********************************************************************/
+
+SwFrmFmt* SwFEShell::GetCurFrmFmt() const
+{
+ SwFrmFmt* pRet = 0;
+ SwLayoutFrm *pFly = FindFlyFrm();
+ if( pFly && ( pRet = (SwFrmFmt*)pFly->GetFmt()->DerivedFrom() ) ==
+ GetDoc()->GetDfltFrmFmt() )
+ pRet = 0;
+ return pRet;
+}
+
+/******************************************************************************
+ * Methode : void SwFEShell::SetFrmFmt(SwFrmFmt *pNewFmt)
+ * Beschreibung:
+ * Erstellt : OK 14.04.94 15:40
+ * Aenderung : MA 23. Apr. 97
+ ******************************************************************************/
+
+void SwFEShell::SetFrmFmt( SwFrmFmt *pNewFmt, sal_Bool bKeepOrient, Point* pDocPos )
+{
+ SwFlyFrm *pFly = 0;
+ if(pDocPos)
+ {
+ const SwFrmFmt* pFmt = GetFmtFromObj( *pDocPos );
+
+ if(PTR_CAST(SwFlyFrmFmt, pFmt))
+ pFly = ((SwFlyFrmFmt*)pFmt)->GetFrm();
+ }
+ else
+ pFly = FindFlyFrm();
+ ASSERT( pFly, "SetFrmFmt: kein Frame" );
+ if( pFly )
+ {
+ StartAllAction();
+ SET_CURR_SHELL( this );
+
+ SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
+ const Point aPt( pFly->Frm().Pos() );
+
+ SfxItemSet* pSet = 0;
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pNewFmt->GetItemState( RES_ANCHOR, sal_False, &pItem ))
+ {
+ pSet = new SfxItemSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
+ pSet->Put( *pItem );
+ if( !::lcl_ChkAndSetNewAnchor( *pFly, *pSet ))
+ delete pSet, pSet = 0;
+ }
+
+ if( GetDoc()->SetFrmFmtToFly( *pFlyFmt, *pNewFmt, pSet, bKeepOrient ))
+ {
+ SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt );
+ if( pFrm )
+ SelectFlyFrm( *pFrm, sal_True );
+ else
+ GetLayout()->SetAssertFlyPages();
+ }
+ if( pSet )
+ delete pSet;
+
+ EndAllActionAndCall();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetFlyFrmFmt()
+|*
+|* Ersterstellung OK 23.06.93 13:15
+|* Letzte Aenderung OK 23.06.93 13:15
+|*
+*************************************************************************/
+
+const SwFrmFmt* SwFEShell::GetFlyFrmFmt() const
+{
+ const SwFlyFrm* pFly = FindFlyFrm();
+ if ( !pFly )
+ {
+ SwFrm* pCurrFrm = GetCurrFrm();
+ pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0;
+ }
+ if( pFly )
+ return pFly->GetFmt();
+ return 0;
+}
+
+SwFrmFmt* SwFEShell::GetFlyFrmFmt()
+{
+ SwFlyFrm* pFly = FindFlyFrm();
+ if ( !pFly )
+ {
+ SwFrm* pCurrFrm = GetCurrFrm();
+ pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0;
+ }
+ if( pFly )
+ return pFly->GetFmt();
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetFlyRect()
+|*
+|* Ersterstellung AMA 6. Mae. 97
+|* Letzte Aenderung AMA 6. Mae. 97
+|*
+*************************************************************************/
+
+SwRect SwFEShell::GetFlyRect() const
+{
+ SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+ SwFlyFrm *pFly = pCntnt ? pCntnt->FindFlyFrm() : 0;
+ if ( !pFly )
+ {
+ SwRect aRect;
+ return aRect;
+ }
+ else
+ return pFly->Frm();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetObjRect()
+|*
+|* Ersterstellung MA 22. Aug. 93
+|* Letzte Aenderung MA 11. Jan. 95
+|*
+*************************************************************************/
+
+SwRect SwFEShell::GetObjRect() const
+{
+ if( Imp()->HasDrawView() )
+ return Imp()->GetDrawView()->GetAllMarkedRect();
+ else
+ {
+ SwRect aRect;
+ return aRect;
+ }
+}
+
+void SwFEShell::SetObjRect( const SwRect& rRect )
+{
+ if ( Imp()->HasDrawView() )
+ {
+ Imp()->GetDrawView()->SetAllMarkedRect( rRect.SVRect() );
+ CallChgLnk(); // rufe das AttrChangeNotify auf der UI-Seite.
+ }
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : RequestObjectResize()
+#* Datum : MA 10. Feb. 95
+#* Update : MA 13. Jul. 95
+#***********************************************************************/
+
+Size SwFEShell::RequestObjectResize( const SwRect &rRect, const uno::Reference < embed::XEmbeddedObject >& xObj )
+{
+ Size aResult;
+
+ SwFlyFrm *pFly = FindFlyFrm( xObj );
+ if ( !pFly )
+ {
+ aResult = rRect.SSize();
+ return aResult;
+ }
+
+ aResult = pFly->Prt().SSize();
+
+ sal_Bool bPosProt = pFly->GetFmt()->GetProtect().IsPosProtected();
+ sal_Bool bSizeProt = pFly->GetFmt()->GetProtect().IsSizeProtected();
+
+ StartAllAction();
+
+ //MA wir lassen den Fly nicht Clippen, damit die Ole-Server mit
+ //beliebigen Wuenschen kommen koennen. Die Formatierung uebernimmt das
+ //Clippen. Die richtige Darstellung wird per Scalierung erledigt.
+ //Die Scalierung wird von SwNoTxtFrm::Format durch einen Aufruf von
+ //SwWrtShell::CalcAndSetScale() erledigt.
+ if ( rRect.SSize() != pFly->Prt().SSize() && !bSizeProt )
+ {
+ Size aSz( rRect.SSize() );
+
+ //JP 28.02.2001: Task 74707 - ask for fly in fly with automatic size
+ //
+ const SwFrm* pAnchor;
+ const SwTxtNode* pTNd;
+ const SwpHints* pHts;
+ const SwFmtFrmSize& rFrmSz = pFly->GetFmt()->GetFrmSize();
+ if( bCheckForOLEInCaption &&
+ 0 != rFrmSz.GetWidthPercent() &&
+ 0 != (pAnchor = pFly->GetAnchorFrm()) &&
+ pAnchor->IsTxtFrm() &&
+ !pAnchor->GetNext() && !pAnchor->GetPrev() &&
+ pAnchor->GetUpper()->IsFlyFrm() &&
+ 0 != ( pTNd = ((SwTxtFrm*)pAnchor)->GetNode()->GetTxtNode()) &&
+ 0 != ( pHts = pTNd->GetpSwpHints() ))
+ {
+ // search for a sequence field:
+ const SfxPoolItem* pItem;
+ for( USHORT n = 0, nEnd = pHts->Count(); n < nEnd; ++n )
+ if( RES_TXTATR_FIELD == ( pItem =
+ &(*pHts)[ n ]->GetAttr())->Which() &&
+ TYP_SEQFLD == ((SwFmtFld*)pItem)->GetFld()->GetTypeId() )
+ {
+ // sequence field found
+ SwFlyFrm* pChgFly = (SwFlyFrm*)pAnchor->GetUpper();
+ // calculate the changed size:
+ // width must change, height can change
+ Size aNewSz( aSz.Width() + pChgFly->Frm().Width() -
+ pFly->Prt().Width(), aSz.Height() );
+
+ SwFrmFmt *pFmt = pChgFly->GetFmt();
+ SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() );
+ aFrmSz.SetWidth( aNewSz.Width() );
+ if( ATT_MIN_SIZE != aFrmSz.GetHeightSizeType() )
+ {
+ aNewSz.Height() += pChgFly->Frm().Height() -
+ pFly->Prt().Height();
+ if( Abs( aNewSz.Height() - pChgFly->Frm().Height()) > 1 )
+ aFrmSz.SetHeight( aNewSz.Height() );
+ }
+ // uebers Doc fuers Undo!
+ pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt );
+ break;
+ }
+ }
+
+ // set the new Size at the fly themself
+ if ( pFly->Prt().Height() > 0 && pFly->Prt().Width() > 0 )
+ {
+ aSz.Width() += pFly->Frm().Width() - pFly->Prt().Width();
+ aSz.Height()+= pFly->Frm().Height()- pFly->Prt().Height();
+ }
+ aResult = pFly->ChgSize( aSz );
+
+ //Wenn sich das Objekt aendert ist die Kontur hoechstwahrscheinlich daneben.
+ ASSERT( pFly->Lower()->IsNoTxtFrm(), "Request ohne NoTxt" );
+ SwNoTxtNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetNoTxtNode();
+ ASSERT( pNd, "Request ohne Node" );
+ pNd->SetContour( 0 );
+ ClrContourCache();
+ }
+
+ //Wenn nur die Size angepasst werden soll, so wird eine Pos mit
+ //ausgezeichneten Werten transportiert.
+ Point aPt( pFly->Prt().Pos() );
+ aPt += pFly->Frm().Pos();
+ if ( rRect.Top() != LONG_MIN && rRect.Pos() != aPt && !bPosProt )
+ {
+ aPt = rRect.Pos();
+ aPt.X() -= pFly->Prt().Left();
+ aPt.Y() -= pFly->Prt().Top();
+ //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein
+ //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly
+ //selbst berechnet und gesetzt.
+ if( pFly->IsFlyAtCntFrm() )
+ ((SwFlyAtCntFrm*)pFly)->SetAbsPos( aPt );
+ else
+ {
+ const SwFrmFmt *pFmt = pFly->GetFmt();
+ const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+ const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
+ const long lXDiff = aPt.X() - pFly->Frm().Left();
+ const long lYDiff = aPt.Y() - pFly->Frm().Top();
+ const Point aTmp( rHori.GetPos() + lXDiff,
+ rVert.GetPos() + lYDiff );
+ pFly->ChgRelPos( aTmp );
+ }
+ }
+ EndAllAction();
+
+ return aResult;
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : WizzardFindCurFrmFmt
+#* Datum : JP 31.07.95
+#* Update : JP 31.07.95
+#***********************************************************************/
+
+SwFrmFmt* SwFEShell::WizzardGetFly()
+{
+ // mal nicht uebers Layout den Fly suchen. Dann kann auch ohne gueltiges
+ // Layout ein Rahmen geloescht werden. ( z.B.: fuer die Wizard's )
+ SwSpzFrmFmts& rSpzArr = *pDoc->GetSpzFrmFmts();
+ sal_uInt16 nCnt = rSpzArr.Count();
+ if( nCnt )
+ {
+ SwNodeIndex& rCrsrNd = GetCrsr()->GetPoint()->nNode;
+ if( rCrsrNd.GetIndex() > pDoc->GetNodes().GetEndOfExtras().GetIndex() )
+ // Cusor steht im Body-Bereich!
+ return 0;
+
+ for( sal_uInt16 n = 0; n < nCnt; ++n )
+ {
+ SwFrmFmt* pFmt = rSpzArr[ n ];
+ const SwNodeIndex* pIdx = pFmt->GetCntnt( sal_False ).GetCntntIdx();
+ SwStartNode* pSttNd;
+ if( pIdx &&
+ 0 != ( pSttNd = pIdx->GetNode().GetStartNode() ) &&
+ pSttNd->GetIndex() < rCrsrNd.GetIndex() &&
+ rCrsrNd.GetIndex() < pSttNd->EndOfSectionIndex() )
+ {
+ // gefunden: also raus damit
+ return pFmt;
+ }
+ }
+ }
+ return 0;
+}
+
+void SwFEShell::SetFlyName( const String& rName )
+{
+ SwLayoutFrm *pFly = FindFlyFrm();
+ if( pFly )
+ GetDoc()->SetFlyName( *(SwFlyFrmFmt*)pFly->GetFmt(), rName );
+ else {
+ ASSERT( !this, "kein FlyFrame selektiert" )
+ }
+}
+
+const String& SwFEShell::GetFlyName() const
+{
+ SwLayoutFrm *pFly = FindFlyFrm();
+ if( pFly )
+ return pFly->GetFmt()->GetName();
+
+ ASSERT( !this, "kein FlyFrame selektiert" )
+ return aEmptyStr;
+}
+
+
+String SwFEShell::GetUniqueGrfName() const
+{
+ return GetDoc()->GetUniqueGrfName();
+}
+
+const SwFrmFmt* SwFEShell::IsURLGrfAtPos( const Point& rPt, String* pURL,
+ String *pTargetFrameName,
+ String *pDescription ) const
+{
+ if( !Imp()->HasDrawView() )
+ return 0;
+
+ SdrObject* pObj;
+ SdrPageView* pPV;
+ const SwFrmFmt* pRet = 0;
+ SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+ sal_uInt16 nOld = pDView->GetHitTolerancePixel();
+ pDView->SetHitTolerancePixel( 2 );
+
+ if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV,SDRSEARCH_PICKMACRO ) &&
+ pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+ const SwFmtURL &rURL = pFly->GetFmt()->GetURL();
+ if( rURL.GetURL().Len() || rURL.GetMap() )
+ {
+ BOOL bSetTargetFrameName = pTargetFrameName != 0;
+ BOOL bSetDescription = pDescription != 0;
+ if ( rURL.GetMap() )
+ {
+ IMapObject *pObject = pFly->GetFmt()->GetIMapObject( rPt, pFly );
+ if ( pObject && pObject->GetURL().Len() )
+ {
+ if( pURL )
+ *pURL = pObject->GetURL();
+ if ( bSetTargetFrameName && pObject->GetTarget().Len() )
+ {
+ bSetTargetFrameName = sal_False;
+ *pTargetFrameName = pObject->GetTarget();
+ }
+ if ( bSetDescription )
+ {
+ bSetDescription = sal_False;
+ *pDescription = pObject->GetAltText();
+ }
+ pRet = pFly->GetFmt();
+ }
+ }
+ else
+ {
+ if( pURL )
+ {
+ *pURL = rURL.GetURL();
+ if( rURL.IsServerMap() )
+ {
+ // dann die rel. Pixel Position anhaengen !!
+ Point aPt( rPt );
+ aPt -= pFly->Frm().Pos();
+ // ohne MapMode-Offset, ohne Offset, o ... !!!!!
+ aPt = GetOut()->LogicToPixel(
+ aPt, MapMode( MAP_TWIP ) );
+ ((( *pURL += '?' ) += String::CreateFromInt32( aPt.X() ))
+ += ',' ) += String::CreateFromInt32(aPt.Y() );
+ }
+ }
+ pRet = pFly->GetFmt();
+ }
+ if ( bSetTargetFrameName )
+ *pTargetFrameName = rURL.GetTargetFrameName();
+ if ( bSetDescription )
+ *pDescription = pFly->GetFmt()->GetName();
+ }
+ }
+ pDView->SetHitTolerancePixel( nOld );
+ return pRet;
+}
+
+const Graphic *SwFEShell::GetGrfAtPos( const Point &rPt,
+ String &rName, sal_Bool &rbLink ) const
+{
+ if( !Imp()->HasDrawView() )
+ return 0;
+
+ SdrObject* pObj;
+ SdrPageView* pPV;
+ SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+ if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV ) && pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+ if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+ {
+ SwGrfNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode();
+ if ( pNd )
+ {
+ if ( pNd->IsGrfLink() )
+ {
+ //Halbfertige Grafik?
+ ::sfx2::SvLinkSource* pLnkObj = pNd->GetLink()->GetObj();
+ if( pLnkObj && pLnkObj->IsPending() )
+ return 0;
+ rbLink = sal_True;
+ }
+
+ pNd->GetFileFilterNms( &rName, 0 );
+ if ( !rName.Len() )
+ rName = pFly->GetFmt()->GetName();
+ pNd->SwapIn( sal_True );
+ return &pNd->GetGrf();
+ }
+ }
+ }
+ return 0;
+}
+
+
+const SwFrmFmt* SwFEShell::GetFmtFromObj( const Point& rPt, SwRect** pRectToFill ) const
+{
+ SwFrmFmt* pRet = 0;
+
+ if( Imp()->HasDrawView() )
+ {
+ SdrObject* pObj;
+ SdrPageView* pPView;
+
+ SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+ sal_uInt16 nOld = pDView->GetHitTolerancePixel();
+ // Tattergrenze fuer Drawing-SS
+ pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
+
+ if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
+ {
+ // dann teste mal was es ist:
+ if ( pObj->ISA(SwVirtFlyDrawObj) )
+ pRet = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
+ else if ( pObj->GetUserCall() ) //nicht fuer Gruppenobjekte
+ pRet = ((SwDrawContact*)pObj->GetUserCall())->GetFmt();
+ if(pRet && pRectToFill)
+ **pRectToFill = pObj->GetCurrentBoundRect();
+ }
+ pDView->SetHitTolerancePixel( nOld );
+ }
+ return pRet;
+}
+
+// returns a format too, if the point is over the text of any fly
+const SwFrmFmt* SwFEShell::GetFmtFromAnyObj( const Point& rPt ) const
+{
+ const SwFrmFmt* pRet = GetFmtFromObj( rPt );
+ if( !pRet || RES_FLYFRMFMT == pRet->Which() )
+ {
+ SwPosition aPos( *GetCrsr()->GetPoint() );
+ Point aPt( rPt );
+ GetLayout()->GetCrsrOfst( &aPos, aPt );
+ SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
+ SwFrm* pFrm = pNd->GetFrm( &rPt )->FindFlyFrm();
+ pRet = pFrm ? ((SwLayoutFrm*)pFrm)->GetFmt() : 0;
+ }
+ return pRet;
+}
+
+ObjCntType SwFEShell::GetObjCntType( const SdrObject& rObj ) const
+{
+ ObjCntType eType = OBJCNT_NONE;
+
+ // OD 23.06.2003 #108784# - investigate 'master' drawing object, if method
+ // is called for a 'virtual' drawing object.
+ const SdrObject* pInvestigatedObj;
+ if ( rObj.ISA(SwDrawVirtObj) )
+ {
+ const SwDrawVirtObj* pDrawVirtObj = static_cast<const SwDrawVirtObj*>(&rObj);
+ pInvestigatedObj = &(pDrawVirtObj->GetReferencedObj());
+ }
+ else
+ {
+ pInvestigatedObj = &rObj;
+ }
+
+ if( FmFormInventor == pInvestigatedObj->GetObjInventor() )
+ {
+ eType = OBJCNT_CONTROL;
+ uno::Reference< awt::XControlModel > xModel =
+ ((SdrUnoObj&)(*pInvestigatedObj)).GetUnoControlModel();
+ if( xModel.is() )
+ {
+ uno::Any aVal;
+ OUString sName = OUString::createFromAscii("ButtonType");
+ uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY);
+
+ uno::Reference< beans::XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
+ if(xInfo->hasPropertyByName( sName ))
+ {
+ beans::Property xProperty = xInfo->getPropertyByName( sName );
+ aVal = xSet->getPropertyValue( sName );
+ if( aVal.getValue() && form::FormButtonType_URL == *((form::FormButtonType*)aVal.getValue()) )
+ eType = OBJCNT_URLBUTTON;
+ }
+ }
+ }
+ else if( pInvestigatedObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj&)(*pInvestigatedObj)).GetFlyFrm();
+ if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+ {
+ if ( ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode() )
+ eType = OBJCNT_GRF;
+ else
+ eType = OBJCNT_OLE;
+ }
+ else
+ eType = OBJCNT_FLY;
+ }
+ else if ( pInvestigatedObj->ISA( SdrObjGroup ) )
+ {
+ SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(GetUserCall( pInvestigatedObj ) ) );
+ if ( !pDrawContact )
+ {
+ ASSERT( false,
+ "<SwFEShell::GetObjCntType(..)> - missing draw contact object" );
+ eType = OBJCNT_NONE;
+ }
+ else
+ {
+ SwFrmFmt* pFrmFmt( pDrawContact->GetFmt() );
+ if ( !pFrmFmt )
+ {
+ ASSERT( false,
+ "<SwFEShell::GetObjCntType(..)> - missing frame format" );
+ eType = OBJCNT_NONE;
+ }
+ else if ( FLY_AS_CHAR != pFrmFmt->GetAnchor().GetAnchorId() )
+ {
+ eType = OBJCNT_GROUPOBJ;
+ }
+ }
+ }
+ else
+ eType = OBJCNT_SIMPLE;
+ return eType;
+}
+
+ObjCntType SwFEShell::GetObjCntType( const Point &rPt, SdrObject *&rpObj ) const
+{
+ ObjCntType eType = OBJCNT_NONE;
+
+ if( Imp()->HasDrawView() )
+ {
+ SdrObject* pObj;
+ SdrPageView* pPView;
+
+ SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+ sal_uInt16 nOld = pDView->GetHitTolerancePixel();
+ // Tattergrenze fuer Drawing-SS
+ pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
+
+ if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
+ eType = GetObjCntType( *(rpObj = pObj) );
+
+ pDView->SetHitTolerancePixel( nOld );
+ }
+ return eType;
+}
+
+ObjCntType SwFEShell::GetObjCntTypeOfSelection( SdrObject** ppObj ) const
+{
+ ObjCntType eType = OBJCNT_NONE;
+
+ if( Imp()->HasDrawView() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for( sal_uInt32 i = 0, nE = rMrkList.GetMarkCount(); i < nE; ++i )
+ {
+ SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ ObjCntType eTmp = GetObjCntType( *pObj );
+ if( !i )
+ {
+ eType = eTmp;
+ if( ppObj ) *ppObj = pObj;
+ }
+ else if( eTmp != eType )
+ {
+ eType = OBJCNT_DONTCARE;
+ // einmal DontCare, immer DontCare!
+ break;
+ }
+ }
+ }
+ return eType;
+}
+
+
+sal_Bool SwFEShell::ReplaceSdrObj( const String& rGrfName, const String& rFltName,
+ const Graphic* pGrf )
+{
+ SET_CURR_SHELL( this );
+
+ sal_Bool bRet = sal_False;
+ const SdrMarkList *pMrkList;
+ if( Imp()->HasDrawView() && 1 ==
+ ( pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount() )
+ {
+ SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ SwFrmFmt *pFmt = FindFrmFmt( pObj );
+
+ // Attribute sichern und dann an der Grafik setzen
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ pFmt->GetAttrSet().GetRanges() );
+ aFrmSet.Set( pFmt->GetAttrSet() );
+
+ // Groesse und Position setzen ??
+ if( !pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ // dann mal los:
+ const Rectangle &rBound = pObj->GetSnapRect();
+ Point aRelPos( pObj->GetRelativePos() );
+
+ const long nWidth = rBound.Right() - rBound.Left();
+ const long nHeight= rBound.Bottom() - rBound.Top();
+ aFrmSet.Put( SwFmtFrmSize( ATT_MIN_SIZE,
+ Max( nWidth, long(MINFLY) ),
+ Max( nHeight, long(MINFLY) )));
+
+ if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_HORI_ORIENT ))
+ aFrmSet.Put( SwFmtHoriOrient( aRelPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
+
+ if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_VERT_ORIENT ))
+ aFrmSet.Put( SwFmtVertOrient( aRelPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ));
+
+ }
+
+ pObj->GetOrdNum();
+
+ StartAllAction();
+ StartUndo();
+
+ // das "Sdr-Object" loeschen und dafuer die Grafik einfuegen
+ DelSelectedObj();
+
+ pFmt = GetDoc()->Insert( *GetCrsr(), rGrfName, rFltName, pGrf, &aFrmSet, NULL, NULL );
+
+ // die Ordnungsnummer (Z-Order) noch uebertragen
+ // JP 04.07.98: klappt aber nicht richtig!
+ //SdrObject* pNewObj = ::FindSdrObject( pFmt );
+ //pNewObj->SetOrdNum( nOrdNum );
+
+ EndUndo();
+ EndAllAction();
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+static USHORT SwFmtGetPageNum(const SwFlyFrmFmt * pFmt)
+{
+ ASSERT(pFmt != NULL, "invalid argument");
+
+ SwFlyFrm * pFrm = pFmt->GetFrm();
+
+ USHORT aResult;
+
+ if (pFrm != NULL)
+ aResult = pFrm->GetPhyPageNum();
+ else
+ aResult = pFmt->GetAnchor().GetPageNum();
+
+ return aResult;
+}
+
+#include <fmtcnct.hxx>
+
+void SwFEShell::GetConnectableFrmFmts(SwFrmFmt & rFmt,
+ const String & rReference,
+ BOOL bSuccessors,
+ ::std::vector< String > & aPrevPageVec,
+ ::std::vector< String > & aThisPageVec,
+ ::std::vector< String > & aNextPageVec,
+ ::std::vector< String > & aRestVec)
+{
+ StartAction();
+
+ SwFmtChain rChain = rFmt.GetChain();
+ SwFrmFmt * pOldChainNext = (SwFrmFmt *) rChain.GetNext();
+ SwFrmFmt * pOldChainPrev = (SwFrmFmt *) rChain.GetPrev();
+
+ if (pOldChainNext)
+ pDoc->Unchain(rFmt);
+
+ if (pOldChainPrev)
+ pDoc->Unchain(*pOldChainPrev);
+
+ sal_uInt16 nCnt = pDoc->GetFlyCount(FLYCNTTYPE_FRM);
+
+ /* potential successors resp. predecessors */
+ ::std::vector< const SwFrmFmt * > aTmpSpzArray;
+
+ (SwFrmFmt *) pDoc->FindFlyByName(rReference);
+
+ for (sal_uInt16 n = 0; n < nCnt; n++)
+ {
+ const SwFrmFmt & rFmt1 = *(pDoc->GetFlyNum(n, FLYCNTTYPE_FRM));
+
+ /*
+ pFmt is a potential successor of rFmt if it is chainable after
+ rFmt.
+
+ pFmt is a potential predecessor of rFmt if rFmt is chainable
+ after pFmt.
+ */
+
+ int nChainState;
+
+ if (bSuccessors)
+ nChainState = pDoc->Chainable(rFmt, rFmt1);
+ else
+ nChainState = pDoc->Chainable(rFmt1, rFmt);
+
+ if (nChainState == SW_CHAIN_OK)
+ {
+ aTmpSpzArray.push_back(&rFmt1);
+
+ }
+
+ }
+
+ if (aTmpSpzArray.size() > 0)
+ {
+ aPrevPageVec.clear();
+ aThisPageVec.clear();
+ aNextPageVec.clear();
+ aRestVec.clear();
+
+ /* number of page rFmt resides on */
+ USHORT nPageNum = SwFmtGetPageNum((SwFlyFrmFmt *) &rFmt);
+
+ ::std::vector< const SwFrmFmt * >::const_iterator aIt;
+
+ for (aIt = aTmpSpzArray.begin(); aIt != aTmpSpzArray.end(); aIt++)
+ {
+ String aString = (*aIt)->GetName();
+
+ /* rFmt is not a vaild successor or predecessor of
+ itself */
+ if (aString != rReference && aString != rFmt.GetName())
+ {
+ USHORT nNum1 =
+ SwFmtGetPageNum((SwFlyFrmFmt *) *aIt);
+
+ if (nNum1 == nPageNum -1)
+ aPrevPageVec.push_back(aString);
+ else if (nNum1 == nPageNum)
+ aThisPageVec.push_back(aString);
+ else if (nNum1 == nPageNum + 1)
+ aNextPageVec.push_back(aString);
+ else
+ aRestVec.push_back(aString);
+ }
+ }
+
+ }
+
+ if (pOldChainNext)
+ pDoc->Chain(rFmt, *pOldChainNext);
+
+ if (pOldChainPrev)
+ pDoc->Chain(*pOldChainPrev, rFmt);
+
+ EndAction();
+}
+
+// --> OD 2009-07-13 #i73249#
+const String SwFEShell::GetObjTitle() const
+{
+ String aTitle;
+
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
+ if ( pMrkList->GetMarkCount() == 1 )
+ {
+ const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ const SwFrmFmt* pFmt = FindFrmFmt( pObj );
+ if ( pFmt->Which() == RES_FLYFRMFMT )
+ {
+ aTitle = dynamic_cast<const SwFlyFrmFmt*>(pFmt)->GetObjTitle();
+ }
+ else
+ {
+ aTitle = pObj->GetTitle();
+ }
+ }
+ }
+
+ return aTitle;
+}
+
+void SwFEShell::SetObjTitle( const String& rTitle )
+{
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
+ if ( pMrkList->GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ SwFrmFmt* pFmt = FindFrmFmt( pObj );
+ if ( pFmt->Which() == RES_FLYFRMFMT )
+ {
+ GetDoc()->SetFlyFrmTitle( *(dynamic_cast<SwFlyFrmFmt*>(pFmt)),
+ rTitle );
+ }
+ else
+ {
+ pObj->SetTitle( rTitle );
+ }
+ }
+ }
+}
+
+const String SwFEShell::GetObjDescription() const
+{
+ String aDescription;
+
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
+ if ( pMrkList->GetMarkCount() == 1 )
+ {
+ const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ const SwFrmFmt* pFmt = FindFrmFmt( pObj );
+ if ( pFmt->Which() == RES_FLYFRMFMT )
+ {
+ aDescription = dynamic_cast<const SwFlyFrmFmt*>(pFmt)->GetObjDescription();
+ }
+ else
+ {
+ aDescription = pObj->GetDescription();
+ }
+ }
+ }
+
+ return aDescription;
+}
+
+void SwFEShell::SetObjDescription( const String& rDescription )
+{
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
+ if ( pMrkList->GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ SwFrmFmt* pFmt = FindFrmFmt( pObj );
+ if ( pFmt->Which() == RES_FLYFRMFMT )
+ {
+ GetDoc()->SetFlyFrmDescription( *(dynamic_cast<SwFlyFrmFmt*>(pFmt)),
+ rDescription );
+ }
+ else
+ {
+ pObj->SetDescription( rDescription );
+ }
+ }
+ }
+}
+// <--
diff --git a/sw/source/core/frmedt/feflyole.cxx b/sw/source/core/frmedt/feflyole.cxx
new file mode 100644
index 000000000000..070a031e83d3
--- /dev/null
+++ b/sw/source/core/frmedt/feflyole.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/embed/EmbedStates.hpp>
+
+#ifndef _SFX_CLIENTSH_HXX
+#include <sfx2/ipclient.hxx>
+#endif
+#include <sfx2/viewsh.hxx>
+#include <sfx2/app.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <sot/exchange.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtanchr.hxx>
+#include <fesh.hxx>
+#include <cntfrm.hxx>
+#include <frmfmt.hxx>
+#include <flyfrm.hxx>
+#include <pam.hxx>
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <notxtfrm.hxx>
+#include <ndole.hxx>
+#include <swcli.hxx>
+
+using namespace com::sun::star;
+
+SwFlyFrm *SwFEShell::FindFlyFrm( const uno::Reference < embed::XEmbeddedObject >& xObj ) const
+{
+ SwFlyFrm *pFly = FindFlyFrm();
+ if ( pFly && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+ {
+ SwOLENode *pNd = ((SwNoTxtFrm*)pFly->Lower())->GetNode()->GetOLENode();
+ if ( !pNd || pNd->GetOLEObj().GetOleRef() != xObj )
+ pFly = 0;
+ }
+ else
+ pFly = 0;
+
+ if ( !pFly )
+ {
+ //Kein Fly oder der falsche selektiert. Ergo muessen wir leider suchen.
+ BOOL bExist = FALSE;
+ SwStartNode *pStNd;
+ ULONG nSttIdx = GetNodes().GetEndOfAutotext().StartOfSectionIndex() + 1,
+ nEndIdx = GetNodes().GetEndOfAutotext().GetIndex();
+ while( nSttIdx < nEndIdx &&
+ 0 != (pStNd = GetNodes()[ nSttIdx ]->GetStartNode()) )
+ {
+ SwNode *pNd = GetNodes()[ nSttIdx+1 ];
+ if ( pNd->IsOLENode() &&
+ ((SwOLENode*)pNd)->GetOLEObj().GetOleRef() == xObj )
+ {
+ bExist = TRUE;
+ SwFrm *pFrm = ((SwOLENode*)pNd)->GetFrm();
+ if ( pFrm )
+ pFly = pFrm->FindFlyFrm();
+ break;
+ }
+ nSttIdx = pStNd->EndOfSectionIndex() + 1;
+ }
+
+ ASSERT( bExist, "OLE-Object unknown and FlyFrm not found." );
+ }
+ return pFly;
+}
+
+
+String SwFEShell::GetUniqueOLEName() const
+{
+ return GetDoc()->GetUniqueOLEName();
+}
+
+
+String SwFEShell::GetUniqueFrameName() const
+{
+ return GetDoc()->GetUniqueFrameName();
+}
+
+
+void SwFEShell::MakeObjVisible( const uno::Reference < embed::XEmbeddedObject >& xObj ) const
+{
+ SwFlyFrm *pFly = FindFlyFrm( xObj );
+ if ( pFly )
+ {
+ SwRect aTmp( pFly->Prt() );
+ aTmp += pFly->Frm().Pos();
+ if ( !aTmp.IsOver( VisArea() ) )
+ {
+ ((SwFEShell*)this)->StartAction();
+ ((SwFEShell*)this)->MakeVisible( aTmp );
+ ((SwFEShell*)this)->EndAction();
+ }
+ }
+}
+
+BOOL SwFEShell::FinishOLEObj() // Server wird beendet
+{
+ SfxInPlaceClient* pIPClient = GetSfxViewShell()->GetIPClient();
+ if ( !pIPClient )
+ return FALSE;
+
+ BOOL bRet = pIPClient->IsObjectInPlaceActive();
+ if( bRet )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = pIPClient->GetObject();
+ if( CNT_OLE == GetCntType() )
+ ClearAutomaticContour();
+
+ if( ((SwOleClient*)pIPClient)->IsCheckForOLEInCaption() !=
+ IsCheckForOLEInCaption() )
+ SetCheckForOLEInCaption( !IsCheckForOLEInCaption() );
+
+ // leave UIActive state
+ pIPClient->DeactivateObject();
+ }
+ return bRet;
+}
+
+
+
+
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
new file mode 100644
index 000000000000..f334ddcaee2f
--- /dev/null
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -0,0 +1,3237 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/embed/EmbedMisc.hpp>
+#include "hintids.hxx"
+
+#include <svx/sdrobjectfilter.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/sxciaitm.hxx>
+#include <svx/xfillit.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/app.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/protitem.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+
+#ifndef _POOLFMT_HRC
+#include <poolfmt.hrc> // fuer InitFldTypes
+#endif
+#include <frmfmt.hxx>
+#include <frmatr.hxx>
+#include <fmtfsize.hxx>
+#include <fmtanchr.hxx>
+#include <fmtornt.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtflcnt.hxx>
+#include <fmtcnct.hxx>
+#include <docary.hxx>
+#include <tblsel.hxx>
+#include <swtable.hxx>
+#include <flyfrms.hxx>
+#include "fesh.hxx"
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "sectfrm.hxx"
+#include "doc.hxx"
+#include "dview.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "viewimp.hxx"
+#include "flyfrm.hxx"
+#include "pam.hxx"
+#include "ndole.hxx"
+#include "ndgrf.hxx"
+#include "ndtxt.hxx"
+#include "viewopt.hxx" // fuer GetHTMLMode
+#include "swundo.hxx"
+#include "notxtfrm.hxx"
+#include "txtfrm.hxx"
+#include "txatbase.hxx"
+#include "mdiexp.hxx" // fuer Update der Statuszeile bei drag
+// OD 2004-05-24 #i28701#
+#include <sortedobjs.hxx>
+// --> OD 2006-03-06 #125892#
+#include <HandleAnchorNodeChg.hxx>
+// <--
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#define SCROLLVAL 75
+
+using namespace com::sun::star;
+
+//Tattergrenze fuer Drawing-SS
+#define MINMOVE ((USHORT)GetOut()->PixelToLogic(Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width())
+
+SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh )
+{
+ if ( !pLst )
+ pLst = pSh->HasDrawView() ? &pSh->Imp()->GetDrawView()->GetMarkedObjectList():0;
+
+ if ( pLst && pLst->GetMarkCount() == 1 )
+ {
+ SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
+ if ( pO->ISA(SwVirtFlyDrawObj) )
+ return ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+ }
+ return 0;
+}
+
+void lcl_GrabCursor( SwFEShell* pSh, SwFlyFrm* pOldSelFly)
+{
+ const SwFrmFmt *pFlyFmt = pSh->SelFlyGrabCrsr();
+ if( pFlyFmt && !pSh->ActionPend() &&
+ (!pOldSelFly || pOldSelFly->GetFmt() != pFlyFmt) )
+ {
+ // dann das evt. gesetzte Macro rufen
+ pSh->GetFlyMacroLnk().Call( (void*)pFlyFmt );
+extern BOOL bNoInterrupt; // in swapp.cxx
+ // wir in dem Makro ein Dialog gestartet, dann kommt das
+ // MouseButtonUp zu diesem und nicht zu uns. Dadurch ist
+ // Flag bei uns immer gesetzt und schaltet nie die auf die
+ // entsp. Shell um !!!!!!!
+ bNoInterrupt = FALSE;
+ }
+ else if( !pFlyFmt || RES_DRAWFRMFMT == pFlyFmt->Which() )
+ {
+ // --> OD 2007-07-25 #136039#
+ // assure consistent cursor
+ pSh->KillPams();
+ pSh->ClearMark();
+ // <--
+ pSh->SetCrsr( pSh->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), TRUE);
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::SelectObj()
+|*
+|* Ersterstellung MA 16. Nov. 92
+|* Letzte Aenderung MA 22. Oct. 96
+|*
+*************************************************************************/
+
+BOOL SwFEShell::SelectObj( const Point& rPt, BYTE nFlag, SdrObject *pObj )
+{
+ SwDrawView *pDView = Imp()->GetDrawView();
+ if(!pDView)
+ return sal_False;
+ SET_CURR_SHELL( this );
+ StartAction(); //Aktion ist Notwendig, damit nicht mehrere
+ //AttrChgdNotify (etwa durch Unmark->MarkListHasChgd)
+ //durchkommen
+
+ const SdrMarkList &rMrkList = pDView->GetMarkedObjectList();
+ const BOOL bHadSelection = rMrkList.GetMarkCount() ? TRUE : FALSE;
+ const BOOL bAddSelect = 0 != (SW_ADD_SELECT & nFlag);
+ const BOOL bEnterGroup = 0 != (SW_ENTER_GROUP & nFlag);
+ SwFlyFrm* pOldSelFly = 0;
+ const Point aOldPos( pDView->GetAllMarkedRect().TopLeft() );
+
+ if( bHadSelection )
+ {
+ //Unmark rufen wenn !bAddSelect oder wenn ein Fly selektiert ist.
+ BOOL bUnmark = !bAddSelect;
+
+ if ( rMrkList.GetMarkCount() == 1 )
+ {
+ //Wenn ein Fly selektiert ist, so muss er erst deselektiert werden.
+ pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
+ if ( pOldSelFly )
+ {
+ const USHORT nType = GetCntType();
+ if( nType != CNT_TXT || (SW_LEAVE_FRAME & nFlag) ||
+ ( pOldSelFly->GetFmt()->GetProtect().IsCntntProtected()
+ && !IsReadOnlyAvailable() ))
+ {
+ //Wenn ein Fly deselektiert wird, der Grafik, Ole o.ae.
+ //enthaelt, so muss der Crsr aus diesem entfernt werden.
+ //Desgleichen wenn ein Fly mit geschuetztem Inhalt deselektiert
+ //wird. Der Einfachheit halber wire der Crsr 'grad so neben die
+ //linke obere Ecke gesetzt.
+ Point aPt( pOldSelFly->Frm().Pos() );
+ aPt.X() -= 1;
+ BOOL bUnLockView = !IsViewLocked();
+ LockView( TRUE );
+ SetCrsr( aPt, TRUE );
+ if( bUnLockView )
+ LockView( FALSE );
+ }
+ if ( nType & CNT_GRF &&
+ ((SwNoTxtFrm*)pOldSelFly->Lower())->HasAnimation() )
+ {
+ GetWin()->Invalidate( pOldSelFly->Frm().SVRect() );
+ }
+ bUnmark = TRUE;
+ }
+ }
+ if ( bUnmark )
+ pDView->UnmarkAll();
+ }
+ else
+ {
+ KillPams();
+ ClearMark();
+ }
+
+ if ( pObj )
+ {
+ ASSERT( !bEnterGroup, "SW_ENTER_GROUP is not supported" );
+ pDView->MarkObj( pObj, Imp()->GetPageView() );
+ }
+ else
+ {
+ pDView->MarkObj( rPt, MINMOVE, bAddSelect, bEnterGroup );
+ }
+
+ const BOOL bRet = 0 != rMrkList.GetMarkCount();
+
+ if ( rMrkList.GetMarkCount() > 1 )
+ {
+ //Ganz dumm ist es, wenn Zeichenobjekte Selektiert waren und
+ //nun ein Fly hinzuselektiert wird.
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pTmpObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ BOOL bForget = pTmpObj->ISA(SwVirtFlyDrawObj);
+ if( bForget )
+ {
+ pDView->UnmarkAll();
+ pDView->MarkObj( pTmpObj, Imp()->GetPageView(), bAddSelect, bEnterGroup );
+ break;
+ }
+ }
+ }
+
+ if ( bRet )
+ {
+ ::lcl_GrabCursor(this, pOldSelFly);
+ if ( GetCntType() & CNT_GRF )
+ {
+ const SwFlyFrm *pTmp = GetFlyFromMarked( &rMrkList, this );
+ ASSERT( pTmp, "Graphic without Fly" );
+ if ( ((SwNoTxtFrm*)pTmp->Lower())->HasAnimation() )
+ ((SwNoTxtFrm*)pTmp->Lower())->StopAnimation( GetOut() );
+ }
+ }
+ else if ( !pOldSelFly && bHadSelection )
+ SetCrsr( aOldPos, TRUE);
+
+ if( bRet || !bHadSelection )
+ CallChgLnk();
+
+ // update der Statuszeile
+ ::FrameNotify( this, bRet ? FLY_DRAG_START : FLY_DRAG_END );
+
+ EndAction();
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* sal_Bool SwFEShell::MoveAnchor( USHORT nDir )
+|*
+|* Created AMA 05/28/2002
+|* Last modify AMA 05/30/2002
+|*
+|* Description: MoveAnchor( nDir ) looked for an another Anchor for
+|* the selected drawing object (or fly frame) in the given direction.
+|* An object "as character" doesn't moves anyway.
+|* A page bounded object could move to the previous/next page with up/down,
+|* an object bounded "at paragraph" moves to the previous/next paragraph, too.
+|* An object bounded "at character" moves to the previous/next paragraph
+|* with up/down and to the previous/next character with left/right.
+|* If the anchor for at paragraph/character bounded objects has vertical or
+|* right_to_left text direction, the directions for up/down/left/right will
+|* interpreted accordingly.
+|* An object bounded "at fly" takes the center of the actual anchor and looks
+|* for the nearest fly frame in the given direction.
+|*
+*************************************************************************/
+
+#define LESS_X( aPt1, aPt2, bOld ) ( aPt1.X() < aPt2.X() || \
+ ( aPt1.X() == aPt2.X() && ( aPt1.Y() < aPt2.Y() || \
+ ( aPt1.Y() == aPt2.Y() && bOld ) ) ) )
+#define LESS_Y( aPt1, aPt2, bOld ) ( aPt1.Y() < aPt2.Y() || \
+ ( aPt1.Y() == aPt2.Y() && ( aPt1.X() < aPt2.X() || \
+ ( aPt1.X() == aPt2.X() && bOld ) ) ) )
+
+sal_Bool SwFEShell::MoveAnchor( USHORT nDir )
+{
+ const SdrMarkList* pMrkList;
+ if( !Imp()->GetDrawView() ||
+ 0 == (pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList()) ||
+ 1 != pMrkList->GetMarkCount())
+ return sal_False;
+ SwFrm* pOld;
+ SwFlyFrm* pFly = NULL;
+ SdrObject *pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ if( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+ pOld = pFly->AnchorFrm();
+ }
+ else
+ pOld = ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj );
+ sal_Bool bRet = sal_False;
+ if( pOld )
+ {
+ SwFrm* pNew = pOld;
+ // --> OD 2004-07-16 #i28701#
+ SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
+ SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
+ SwFmtAnchor aAnch( rFmt.GetAnchor() );
+ RndStdIds nAnchorId = aAnch.GetAnchorId();
+ if ( FLY_AS_CHAR == nAnchorId )
+ return sal_False;
+ if( pOld->IsVertical() )
+ {
+ if( pOld->IsTxtFrm() )
+ {
+ switch( nDir ) {
+ case SW_MOVE_UP: nDir = SW_MOVE_LEFT; break;
+ case SW_MOVE_DOWN: nDir = SW_MOVE_RIGHT; break;
+ case SW_MOVE_LEFT: nDir = SW_MOVE_DOWN; break;
+ case SW_MOVE_RIGHT: nDir = SW_MOVE_UP; break;
+ }
+ if( pOld->IsRightToLeft() )
+ {
+ if( nDir == SW_MOVE_LEFT )
+ nDir = SW_MOVE_RIGHT;
+ else if( nDir == SW_MOVE_RIGHT )
+ nDir = SW_MOVE_LEFT;
+ }
+ }
+ }
+ switch ( nAnchorId ) {
+ case FLY_AT_PAGE:
+ {
+ ASSERT( pOld->IsPageFrm(), "Wrong anchor, page exspected." );
+ if( SW_MOVE_UP == nDir )
+ pNew = pOld->GetPrev();
+ else if( SW_MOVE_DOWN == nDir )
+ pNew = pOld->GetNext();
+ if( pNew && pNew != pOld )
+ {
+ aAnch.SetPageNum( ((SwPageFrm*)pNew)->GetPhyPageNum() );
+ bRet = sal_True;
+ }
+ break;
+ }
+ case FLY_AT_CHAR:
+ {
+ ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
+ if( SW_MOVE_LEFT == nDir || SW_MOVE_RIGHT == nDir )
+ {
+ SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)pOld)->GetTxtNode();
+ xub_StrLen nAct = pPos->nContent.GetIndex();
+ if( SW_MOVE_LEFT == nDir )
+ {
+ bRet = sal_True;
+ if( nAct )
+ {
+ --nAct;
+ pPos->nContent.Assign( pTxtNd, nAct );
+ }
+ else
+ nDir = SW_MOVE_UP;
+ }
+ else
+ {
+ xub_StrLen nMax =
+ ((SwTxtFrm*)pOld)->GetTxtNode()->GetTxt().Len();
+ if( nAct < nMax )
+ {
+ ++nAct;
+ bRet = sal_True;
+ pPos->nContent.Assign( pTxtNd, nAct );
+ }
+ else
+ nDir = SW_MOVE_DOWN;
+ }
+ }
+ } // no break!
+ case FLY_AT_PARA:
+ {
+ ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
+ if( SW_MOVE_UP == nDir )
+ pNew = pOld->FindPrev();
+ else if( SW_MOVE_DOWN == nDir )
+ pNew = pOld->FindNext();
+ if( pNew && pNew != pOld && pNew->IsCntntFrm() )
+ {
+ SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)pNew)->GetTxtNode();
+ pPos->nNode = *pTxtNd;
+ xub_StrLen nTmp = 0;
+ if( bRet )
+ {
+ nTmp = ((SwTxtFrm*)pNew)->GetTxtNode()->GetTxt().Len();
+ if( nTmp )
+ --nTmp;
+ }
+ pPos->nContent.Assign( pTxtNd, nTmp );
+ bRet = sal_True;
+ }
+ else if( SW_MOVE_UP == nDir || SW_MOVE_DOWN == nDir )
+ bRet = sal_False;
+ break;
+ }
+ case FLY_AT_FLY:
+ {
+ ASSERT( pOld->IsFlyFrm(), "Wrong anchor, fly frame exspected.");
+ SwPageFrm* pPage = pOld->FindPageFrm();
+ ASSERT( pPage, "Where's my page?" );
+ SwFlyFrm* pNewFly = NULL;
+ if( pPage->GetSortedObjs() )
+ {
+ int i;
+ sal_Bool bOld = sal_False;
+ Point aCenter( pOld->Frm().Left() + pOld->Frm().Width()/2,
+ pOld->Frm().Top() + pOld->Frm().Height()/2 );
+ Point aBest;
+ for( i = 0; (USHORT)i<pPage->GetSortedObjs()->Count(); ++i )
+ {
+ SwAnchoredObject* pAnchObj =
+ (*pPage->GetSortedObjs())[i];
+ if( pAnchObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(pAnchObj);
+ if( pTmp == pOld )
+ bOld = sal_True;
+ else
+ {
+ const SwFlyFrm* pCheck = pFly ? pTmp : 0;
+ while( pCheck )
+ {
+ if( pCheck == pFly )
+ break;
+ const SwFrm *pNxt = pCheck->GetAnchorFrm();
+ pCheck = pNxt ? pNxt->FindFlyFrm() : NULL;
+ }
+ if( pCheck || pTmp->IsProtected() )
+ continue;
+ Point aNew( pTmp->Frm().Left() +
+ pTmp->Frm().Width()/2,
+ pTmp->Frm().Top() +
+ pTmp->Frm().Height()/2 );
+ sal_Bool bAccept = sal_False;
+ switch( nDir ) {
+ case SW_MOVE_RIGHT:
+ {
+ bAccept = LESS_X( aCenter, aNew, bOld )
+ && ( !pNewFly ||
+ LESS_X( aNew, aBest, sal_False ) );
+ break;
+ }
+ case SW_MOVE_LEFT:
+ {
+ bAccept = LESS_X( aNew, aCenter, !bOld )
+ && ( !pNewFly ||
+ LESS_X( aBest, aNew, sal_True ) );
+ break;
+ }
+ case SW_MOVE_UP:
+ {
+ bAccept = LESS_Y( aNew, aCenter, !bOld )
+ && ( !pNewFly ||
+ LESS_Y( aBest, aNew, sal_True ) );
+ break;
+ }
+ case SW_MOVE_DOWN:
+ {
+ bAccept = LESS_Y( aCenter, aNew, bOld )
+ && ( !pNewFly ||
+ LESS_Y( aNew, aBest, sal_False ) );
+ break;
+ }
+ }
+ if( bAccept )
+ {
+ pNewFly = pTmp;
+ aBest = aNew;
+ }
+ }
+ }
+ }
+ }
+
+ if( pNewFly )
+ {
+ SwPosition aPos( *pNewFly->GetFmt()->
+ GetCntnt().GetCntntIdx());
+ aAnch.SetAnchor( &aPos );
+ bRet = sal_True;
+ }
+ break;
+ }
+ default: break;
+ }
+ if( bRet )
+ {
+ StartAllAction();
+ // --> OD 2006-02-28 #125892#
+ // handle change of anchor node:
+ // if count of the anchor frame also change, the fly frames have to be
+ // re-created. Thus, delete all fly frames except the <this> before the
+ // anchor attribute is change and re-create them afterwards.
+ {
+ SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
+ SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) );
+ if ( pFlyFrmFmt )
+ {
+ pHandleAnchorNodeChg =
+ new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch );
+ }
+ rFmt.GetDoc()->SetAttr( aAnch, rFmt );
+ delete pHandleAnchorNodeChg;
+ }
+ // <--
+ // --> OD 2004-06-24 #i28701# - no call of method
+ // <CheckCharRectAndTopOfLine()> for to-character anchored
+ // Writer fly frame needed. This method call can cause a
+ // format of the anchor frame, which is no longer intended.
+ // Instead clear the anchor character rectangle and
+ // the top of line values for all to-character anchored objects.
+ pAnchoredObj->ClearCharRectAndTopOfLine();
+ EndAllAction();
+ }
+ }
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetSelFrmType()
+|*
+|* Ersterstellung MA 12. Jan. 93
+|* Letzte Aenderung JP 19.03.96
+|*
+*************************************************************************/
+
+const SdrMarkList* SwFEShell::_GetMarkList() const
+{
+ const SdrMarkList* pMarkList = NULL;
+ if( Imp()->GetDrawView() != NULL )
+ pMarkList = &Imp()->GetDrawView()->GetMarkedObjectList();
+ return pMarkList;
+}
+
+USHORT SwFEShell::GetSelFrmType() const
+{
+ USHORT eType;
+
+ // get marked frame list, and check if anything is selected
+ const SdrMarkList* pMarkList = _GetMarkList();
+ if( pMarkList == NULL || pMarkList->GetMarkCount() == 0 )
+ eType = FRMTYPE_NONE;
+ else
+ {
+ // obtain marked item as fly frame; if no fly frame, it must
+ // be a draw object
+ const SwFlyFrm* pFly = ::GetFlyFromMarked(pMarkList, (ViewShell*)this);
+ if ( pFly != NULL )
+ {
+ if( pFly->IsFlyLayFrm() )
+ eType = FRMTYPE_FLY_FREE;
+ else if( pFly->IsFlyAtCntFrm() )
+ eType = FRMTYPE_FLY_ATCNT;
+ else
+ {
+ ASSERT( pFly->IsFlyInCntFrm(), "Neuer Rahmentyp?" );
+ eType = FRMTYPE_FLY_INCNT;
+ }
+ }
+ else
+ eType = FRMTYPE_DRAWOBJ;
+ }
+
+ return eType;
+}
+
+// #108784# does the draw selection contain a control?
+bool SwFEShell::IsSelContainsControl() const
+{
+ bool bRet = false;
+
+ // basically, copy the mechanism from GetSelFrmType(), but call
+ // CheckControl... if you get a drawing object
+ const SdrMarkList* pMarkList = _GetMarkList();
+ if( pMarkList != NULL && pMarkList->GetMarkCount() == 1 )
+ {
+ // if we have one marked object, get the SdrObject and check
+ // whether it contains a control
+ const SdrObject* pSdrObject = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
+ bRet = ::CheckControlLayer( pSdrObject );
+ }
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::Scroll()
+|*
+|* Ersterstellung MA 20. Dec. 94
+|* Letzte Aenderung MA 27. Jul. 95
+|*
+*************************************************************************/
+
+void SwFEShell::ScrollTo( const Point &rPt )
+{
+ const SwRect aRect( rPt, rPt );
+ if ( IsScrollMDI( this, aRect ) &&
+ (!Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ||
+ Imp()->IsDragPossible( rPt )) )
+ {
+ //SwSaveHdl aSave( Imp() );
+ ScrollMDI( this, aRect, SCROLLVAL, SCROLLVAL );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::SetDragMode()
+|*
+|* Ersterstellung MA 30. Jan. 95
+|* Letzte Aenderung MA 30. Jan. 95
+|*
+*************************************************************************/
+
+void SwFEShell::SetDragMode( UINT16 eDragMode )
+{
+ if ( Imp()->HasDrawView() )
+ Imp()->GetDrawView()->SetDragMode( (SdrDragMode)eDragMode );
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::BeginDrag()
+|*
+|* Ersterstellung MS 10.06.92
+|* Letzte Aenderung MA 13. Mar. 96
+|*
+*************************************************************************/
+
+long SwFEShell::BeginDrag( const Point* pPt, BOOL )
+{
+ SdrView *pView = Imp()->GetDrawView();
+ if ( pView && pView->AreObjectsMarked() )
+ {
+ delete pChainFrom; delete pChainTo; pChainFrom = pChainTo = 0;
+ SdrHdl* pHdl = pView->PickHandle( *pPt );
+ pView->BegDragObj( *pPt, 0 /*GetWin()*/, pHdl );
+ ::FrameNotify( this, FLY_DRAG );
+ return 1;
+ }
+ return 0;
+}
+/*************************************************************************
+|*
+|* SwFEShell::Drag()
+|*
+|* Ersterstellung MS 10.06.92
+|* Letzte Aenderung MA 13. Mar. 96
+|*
+*************************************************************************/
+
+long SwFEShell::Drag( const Point *pPt, BOOL )
+{
+ ASSERT( Imp()->HasDrawView(), "Drag without DrawView?" );
+ if ( Imp()->GetDrawView()->IsDragObj() )
+ {
+ ScrollTo( *pPt );
+ Imp()->GetDrawView()->MovDragObj( *pPt );
+ Imp()->GetDrawView()->ShowDragAnchor();
+ ::FrameNotify( this, FLY_DRAG );
+ return 1;
+ }
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::EndDrag()
+|*
+|* Ersterstellung MS 10.06.92
+|* Letzte Aenderung MA 13. Mar. 96
+|*
+*************************************************************************/
+
+long SwFEShell::EndDrag( const Point *, BOOL )
+{
+ ASSERT( Imp()->HasDrawView(), "EndDrag without DrawView?" );
+ SdrView *pView = Imp()->GetDrawView();
+ if ( pView->IsDragObj() )
+ {
+ //Start-/EndActions nur an der ViewShell aufsetzen
+ ViewShell *pSh = this;
+ do {
+ pSh->StartAction();
+ } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
+
+ StartUndo( UNDO_START );
+
+ //#50778# Bug im Draging: Im StartAction wird ein HideShowXor gerufen.
+ //Im EndDragObj() wird dies unsinniger und faelschlicherweise wieder
+ //Rueckgaengig gemacht. Um Konsistenz herzustellen muessen wir das
+ //Xor also wieder zur Anzeige bringen.
+
+ // Reanimation from the hack #50778 to fix bug #97057
+ // May be not the best solution, but the one with lowest risc at the moment.
+ //pView->ShowShownXor( GetOut() );
+
+ pView->EndDragObj();
+ // JP 18.08.95: DrawUndo-Action auf FlyFrames werden nicht gespeichert
+ // Die Fly aendern das Flag
+ GetDoc()->SetNoDrawUndoObj( FALSE );
+ ChgAnchor( 0, TRUE );
+
+ EndUndo( UNDO_END );
+
+ do {
+ pSh->EndAction();
+ if( pSh->IsA( TYPE( SwCrsrShell ) ) )
+ ((SwCrsrShell*)pSh)->CallChgLnk();
+ } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
+
+ GetDoc()->SetModified();
+ ::FrameNotify( this, FLY_DRAG );
+ return 1;
+ }
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::BreakDrag()
+|*
+|* Ersterstellung OM 02. Okt. 95
+|* Letzte Aenderung OM 02. Okt. 95
+|*
+*************************************************************************/
+
+void SwFEShell::BreakDrag()
+{
+ ASSERT( Imp()->HasDrawView(), "BreakDrag without DrawView?" );
+ if ( Imp()->GetDrawView()->IsDragObj() )
+ Imp()->GetDrawView()->BrkDragObj();
+ SetChainMarker();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::SelFlyGrabCrsr()
+|*
+|* Beschreibung Wenn ein Fly selektiert ist, zieht er den Crsr in
+|* den ersten CntntFrm
+|* Ersterstellung MA 11. Dec. 92
+|* Letzte Aenderung MA 07. Oct. 96
+|*
+*************************************************************************/
+
+const SwFrmFmt* SwFEShell::SelFlyGrabCrsr()
+{
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
+
+ if( pFly )
+ {
+ // --> OD 2004-06-11 #i28701# - no format here
+// pFly->GetAnchorFrm()->Calc();
+ SwCntntFrm *pCFrm = pFly->ContainsCntnt();
+ if ( pCFrm )
+ {
+ SwCntntNode *pCNode = pCFrm->GetNode();
+ // --> OD 2007-07-25 #126039#
+ // assure, that the cursor is consistent.
+ KillPams();
+ ClearMark();
+ // <--
+ SwPaM *pCrsr = GetCrsr();
+
+ pCrsr->GetPoint()->nNode = *pCNode;
+ pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
+
+ SwRect& rChrRect = (SwRect&)GetCharRect();
+ rChrRect = pFly->Prt();
+ rChrRect.Pos() += pFly->Frm().Pos();
+ GetCrsrDocPos() = rChrRect.Pos();
+ }
+ return pFly->GetFmt();
+ }
+ }
+ return 0;
+}
+
+
+/*************************************************************************
+|*
+|* SwFEShell::SelectionToTop(), SelectionToBottom()
+|*
+|* Beschreibung Selektion nach oben/unten (Z-Order)
+|*
+|* Ersterstellung MA 05. Nov. 92
+|* Letzte Aenderung MA 03. Jun. 96
+|*
+*************************************************************************/
+
+void lcl_NotifyNeighbours( const SdrMarkList *pLst )
+{
+ //Die Regeln fuer die Ausweichmanoever haben sich veraendert.
+ //1. Die Umgebung des Fly und aller innenliegenden muss benachrichtigt
+ // werden.
+ //2. Der Inhalt des Rahmen selbst muss benachrichtigt werden.
+ //3. Rahmen die dem Rahmen ausweichen bzw. wichen muessen benachrichtigt werden.
+ //4. Auch Zeichenobjekte koennen Rahmen verdraengen
+
+ for( USHORT j = 0; j < pLst->GetMarkCount(); ++j )
+ {
+ SwPageFrm *pPage;
+ BOOL bCheckNeighbours = FALSE;
+ sal_Int16 aHori = text::HoriOrientation::NONE;
+ SwRect aRect;
+ SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
+ if ( pO->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+
+ const SwFmtHoriOrient &rHori = pFly->GetFmt()->GetHoriOrient();
+ aHori = rHori.GetHoriOrient();
+ if( text::HoriOrientation::NONE != aHori && text::HoriOrientation::CENTER != aHori &&
+ pFly->IsFlyAtCntFrm() )
+ {
+ bCheckNeighbours = TRUE;
+ pFly->InvalidatePos();
+ pFly->Frm().Pos().Y() += 1;
+ }
+
+ pPage = pFly->FindPageFrm();
+ aRect = pFly->Frm();
+ }
+ else
+ {
+ SwFrm* pAnch = ( (SwDrawContact*)GetUserCall(pO) )->GetAnchorFrm( pO );
+ if( !pAnch )
+ continue;
+ pPage = pAnch->FindPageFrm();
+ // --> OD 2006-08-15 #i68520# - naming changed
+ aRect = GetBoundRectOfAnchoredObj( pO );
+ // <--
+ }
+
+ sal_uInt32 nCount = pPage->GetSortedObjs() ? pPage->GetSortedObjs()->Count() : 0;
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ SwAnchoredObject* pAnchoredObj = (*pPage->GetSortedObjs())[i];
+ if ( !pAnchoredObj->ISA(SwFlyFrm) )
+ continue;
+
+ SwFlyFrm* pAct = static_cast<SwFlyFrm*>(pAnchoredObj);
+ SwRect aTmpCalcPnt( pAct->Prt() );
+ aTmpCalcPnt += pAct->Frm().Pos();
+ if ( aRect.IsOver( aTmpCalcPnt ) )
+ {
+ SwCntntFrm *pCnt = pAct->ContainsCntnt();
+ while ( pCnt )
+ {
+ aTmpCalcPnt = pCnt->Prt();
+ aTmpCalcPnt += pCnt->Frm().Pos();
+ if ( aRect.IsOver( aTmpCalcPnt ) )
+ ((SwFrm*)pCnt)->Prepare( PREP_FLY_ATTR_CHG );
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+ }
+ if ( bCheckNeighbours && pAct->IsFlyAtCntFrm() )
+ {
+ const SwFmtHoriOrient &rH = pAct->GetFmt()->GetHoriOrient();
+ if ( rH.GetHoriOrient() == aHori &&
+ pAct->Frm().Top() <= aRect.Bottom() &&
+ pAct->Frm().Bottom() >= aRect.Top() )
+ {
+ pAct->InvalidatePos();
+ pAct->Frm().Pos().Y() += 1;
+ }
+ }
+ }
+ }
+}
+
+void SwFEShell::SelectionToTop( BOOL bTop )
+{
+ ASSERT( Imp()->HasDrawView(), "SelectionToTop without DrawView?" );
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
+
+ SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
+ if ( pFly && pFly->IsFlyInCntFrm() )
+ return;
+
+ StartAllAction();
+ if ( bTop )
+ Imp()->GetDrawView()->PutMarkedToTop();
+ else
+ Imp()->GetDrawView()->MovMarkedToTop();
+ ::lcl_NotifyNeighbours( &rMrkList );
+ GetDoc()->SetModified();
+ EndAllAction();
+}
+
+void SwFEShell::SelectionToBottom( BOOL bBottom )
+{
+ ASSERT( Imp()->HasDrawView(), "SelectionToBottom without DrawView?" );
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
+
+ SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
+ if ( pFly && pFly->IsFlyInCntFrm() )
+ return;
+
+ StartAllAction();
+ if ( bBottom )
+ Imp()->GetDrawView()->PutMarkedToBtm();
+ else
+ Imp()->GetDrawView()->MovMarkedToBtm();
+ ::lcl_NotifyNeighbours( &rMrkList );
+ GetDoc()->SetModified();
+ EndAllAction();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetLayerId()
+|*
+|* Beschreibung Objekt ueber/unter dem Dokument?
+|* 2 Controls, 1 Heaven, 0 Hell, -1 Uneindeutig
+|* Ersterstellung MA 20. Dec. 94
+|* Letzte Aenderung MA 20. Dec. 94
+|*
+*************************************************************************/
+
+short SwFEShell::GetLayerId() const
+{
+ short nRet = SHRT_MAX;
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if ( nRet == SHRT_MAX )
+ nRet = pObj->GetLayer();
+ else if ( nRet != pObj->GetLayer() )
+ {
+ nRet = -1;
+ break;
+ }
+ }
+ }
+ if ( nRet == SHRT_MAX )
+ nRet = -1;
+ return nRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::SelectionToHeaven(), SelectionToHell()
+|*
+|* Beschreibung Objekt ueber/unter dem Dokument
+|* Ersterstellung MA 20. Dec. 94
+|* Letzte Aenderung AMA 04. Jun. 98
+|*
+*************************************************************************/
+// OD 25.06.2003 #108784#
+// Note: only visible objects can be marked. Thus, objects with invisible
+// layer IDs have not to be considered.
+// If <SwFEShell> exists, layout exists!!
+void SwFEShell::ChangeOpaque( SdrLayerID nLayerId )
+{
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
+ // OD 25.06.2003 #108784# - correct type of <nControls>
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ // OD 21.08.2003 #i18447# - no change of layer for controls
+ // or group objects containing controls.
+ // --> OD 2010-09-14 #i113730#
+ // consider that a member of a drawing group has been selected.
+ const SwContact* pContact = ::GetUserCall( pObj );
+ ASSERT( pContact && pContact->GetMaster(), "<SwFEShell::ChangeOpaque(..)> - missing contact or missing master object at contact!" );
+ const bool bControlObj = ( pContact && pContact->GetMaster() )
+ ? ::CheckControlLayer( pContact->GetMaster() )
+ : ::CheckControlLayer( pObj );
+ // <--
+ if ( !bControlObj && pObj->GetLayer() != nLayerId )
+ {
+ pObj->SetLayer( nLayerId );
+ InvalidateWindows( SwRect( pObj->GetCurrentBoundRect() ) );
+ if ( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFmt *pFmt = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
+ SvxOpaqueItem aOpa( pFmt->GetOpaque() );
+ aOpa.SetValue( nLayerId == pIDDMA->GetHellId() );
+ pFmt->SetFmtAttr( aOpa );
+ }
+ }
+ }
+ GetDoc()->SetModified();
+ }
+}
+
+void SwFEShell::SelectionToHeaven()
+{
+ ChangeOpaque( getIDocumentDrawModelAccess()->GetHeavenId() );
+}
+
+void SwFEShell::SelectionToHell()
+{
+ ChangeOpaque( getIDocumentDrawModelAccess()->GetHellId() );
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::IsObjSelected(), IsFrmSelected()
+|*
+|* Ersterstellung MA 16. Nov. 92
+|* Letzte Aenderung MA 17. Jan. 95
+|*
+*************************************************************************/
+
+USHORT SwFEShell::IsObjSelected() const
+{
+ if ( IsFrmSelected() || !Imp()->HasDrawView() )
+ return 0;
+ else
+ return USHORT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() );
+}
+
+BOOL SwFEShell::IsFrmSelected() const
+{
+ if ( !Imp()->HasDrawView() )
+ return FALSE;
+ else
+ return 0 != ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
+ (ViewShell*)this );
+}
+
+sal_Bool SwFEShell::IsObjSelected( const SdrObject& rObj ) const
+{
+ if ( IsFrmSelected() || !Imp()->HasDrawView() )
+ return sal_False;
+ else
+ return Imp()->GetDrawView()
+ ->IsObjMarked( const_cast< SdrObject * >( &rObj ) );
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::EndTextEdit()
+|*
+|* Ersterstellung MA 19. Feb. 96
+|* Letzte Aenderung MA 19. Feb. 96
+|*
+*************************************************************************/
+
+void SwFEShell::EndTextEdit()
+{
+ //Beenden des TextEditModus. Wenn gewuenscht (default wenn das Objekt
+ //keinen Text mehr enthaelt und keine Attribute traegt) wird das
+ //Objekt gel�scht. Alle anderen markierten Objekte bleiben erhalten.
+
+ ASSERT( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(),
+ "EndTextEdit an no Object" );
+
+ StartAllAction();
+ SdrView *pView = Imp()->GetDrawView();
+ SdrObject *pObj = pView->GetTextEditObject();
+ SdrObjUserCall* pUserCall;
+ if( 0 != ( pUserCall = GetUserCall(pObj) ) )
+ {
+ SdrObject *pTmp = ((SwContact*)pUserCall)->GetMaster();
+ if( !pTmp )
+ pTmp = pObj;
+ pUserCall->Changed( *pTmp, SDRUSERCALL_RESIZE, pTmp->GetLastBoundRect() );
+ }
+ if ( !pObj->GetUpGroup() )
+ {
+ if ( SDRENDTEXTEDIT_SHOULDBEDELETED == pView->SdrEndTextEdit(sal_True) )
+ {
+ if ( pView->GetMarkedObjectList().GetMarkCount() > 1 )
+ {
+ {
+ SdrMarkList aSave( pView->GetMarkedObjectList() );
+ aSave.DeleteMark( aSave.FindObject( pObj ) );
+ if ( aSave.GetMarkCount() )
+ {
+ pView->UnmarkAll();
+ pView->MarkObj( pObj, Imp()->GetPageView() );
+ }
+ DelSelectedObj();
+ if ( aSave.GetMarkCount() )
+ {
+ for ( USHORT i = 0; i < aSave.GetMarkCount(); ++i )
+ pView->MarkObj( aSave.GetMark( i )->GetMarkedSdrObj(),
+ Imp()->GetPageView() );
+ }
+ }
+ }
+ else
+ DelSelectedObj();
+ }
+ }
+ else
+ pView->SdrEndTextEdit();
+ EndAllAction();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::IsInsideSelectedObj()
+|*
+|* Ersterstellung MA 16. Nov. 92
+|* Letzte Aenderung MA 08. Nov. 96
+|*
+*************************************************************************/
+
+int SwFEShell::IsInsideSelectedObj( const Point &rPt )
+{
+ if( Imp()->HasDrawView() )
+ {
+ SwDrawView *pDView = Imp()->GetDrawView();
+
+ if( pDView->GetMarkedObjectList().GetMarkCount() &&
+ pDView->IsMarkedObjHit( rPt ) )
+ {
+ return SDRHIT_OBJECT;
+ }
+ }
+ return SDRHIT_NONE;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::IsObjSelectable()
+|*
+|* Ersterstellung MA 16. Nov. 92
+|* Letzte Aenderung MA 02. Feb. 95
+|*
+*************************************************************************/
+
+bool SwFEShell::IsObjSelectable( const Point& rPt )
+{
+ SET_CURR_SHELL(this);
+#ifdef OLD
+ if( Imp()->HasDrawView() )
+ return Imp()->GetDrawView()->PickSomething( rPt, MINMOVE );
+ return 0;
+#else
+ SwDrawView *pDView = Imp()->GetDrawView();
+ bool bRet = false;
+ if( pDView )
+ {
+ SdrObject* pObj;
+ SdrPageView* pPV;
+ USHORT nOld = pDView->GetHitTolerancePixel();
+ pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
+
+ bRet = 0 != pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE );
+ pDView->SetHitTolerancePixel( nOld );
+ }
+ return bRet;
+#endif
+}
+
+// #107513#
+// Test if there is a object at that position and if it should be selected.
+sal_Bool SwFEShell::ShouldObjectBeSelected(const Point& rPt)
+{
+ SET_CURR_SHELL(this);
+ SwDrawView *pDrawView = Imp()->GetDrawView();
+ sal_Bool bRet(sal_False);
+
+ if(pDrawView)
+ {
+ SdrObject* pObj;
+ SdrPageView* pPV;
+ sal_uInt16 nOld(pDrawView->GetHitTolerancePixel());
+
+ pDrawView->SetHitTolerancePixel(pDrawView->GetMarkHdlSizePixel()/2);
+ bRet = pDrawView->PickObj(rPt, pDrawView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE);
+ pDrawView->SetHitTolerancePixel(nOld);
+
+ if ( bRet && pObj )
+ {
+ const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
+ // --> OD 2009-12-30 #i89920#
+ // Do not select object in background which is overlapping this text
+ // at the given position.
+ bool bObjInBackground( false );
+ {
+ if ( pObj->GetLayer() == pIDDMA->GetHellId() )
+ {
+ const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
+ const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
+ const SwFmtSurround& rSurround = rFmt.GetSurround();
+ if ( rSurround.GetSurround() == SURROUND_THROUGHT )
+ {
+ bObjInBackground = true;
+ }
+ }
+ }
+ if ( bObjInBackground )
+ {
+ const SwPageFrm* pPageFrm = GetLayout()->GetPageAtPos( rPt );
+ if( pPageFrm )
+ {
+ const SwCntntFrm* pCntntFrm( pPageFrm->ContainsCntnt() );
+ while ( pCntntFrm )
+ {
+ if ( pCntntFrm->UnionFrm().IsInside( rPt ) )
+ {
+ const SwTxtFrm* pTxtFrm =
+ dynamic_cast<const SwTxtFrm*>(pCntntFrm);
+ if ( pTxtFrm )
+ {
+ SwPosition* pPos =
+ new SwPosition( *(pTxtFrm->GetTxtNode()) );
+ Point aTmpPt( rPt );
+ if ( pTxtFrm->GetKeyCrsrOfst( pPos, aTmpPt ) )
+ {
+ SwRect aCursorCharRect;
+ if ( pTxtFrm->GetCharRect( aCursorCharRect, *pPos ) )
+ {
+ if ( aCursorCharRect.IsOver( SwRect( pObj->GetLastBoundRect() ) ) )
+ {
+ bRet = sal_False;
+ }
+ }
+ }
+ }
+ else
+ {
+ bRet = sal_False;
+ }
+ break;
+ }
+
+ pCntntFrm = pCntntFrm->GetNextCntntFrm();
+ }
+ }
+ }
+ // <--
+
+ if ( bRet )
+ {
+ const SdrPage* pPage = pIDDMA->GetDrawModel()->GetPage(0);
+ for(sal_uInt32 a(pObj->GetOrdNum() + 1); bRet && a < pPage->GetObjCount(); a++)
+ {
+ SdrObject *pCandidate = pPage->GetObj(a);
+
+ if (pCandidate->ISA(SwVirtFlyDrawObj) &&
+ ( (SwVirtFlyDrawObj*)pCandidate)->GetCurrentBoundRect().IsInside(rPt) )
+ {
+ bRet = sal_False;
+ }
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GotoObj()
+|*
+|* Beschreibung Wenn ein Obj selektiert ist, gehen wir von dessen
+|* TopLeft aus, andernfalls von der Mitte des aktuellen CharRects.
+|* Ersterstellung MA 01. Jun. 95
+|* Letzte Aenderung MA 30. Apr. 96
+|*
+*************************************************************************/
+/* -----------------23.09.98 10:29-------------------
+ * Beinhaltet das Objekt ein Control oder Gruppen,
+ * die nur aus Controls bestehen
+ * --------------------------------------------------*/
+BOOL lcl_IsControlGroup( const SdrObject *pObj )
+{
+ BOOL bRet = FALSE;
+ if(pObj->ISA(SdrUnoObj))
+ bRet = TRUE;
+ else if( pObj->ISA( SdrObjGroup ) )
+ {
+ bRet = TRUE;
+ const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
+ for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
+ if( !::lcl_IsControlGroup( pLst->GetObj( i ) ) )
+ return FALSE;
+ }
+ return bRet;
+}
+
+namespace
+{
+ class MarkableObjectsOnly : public ::svx::ISdrObjectFilter
+ {
+ public:
+ MarkableObjectsOnly( SdrPageView* i_pPV )
+ :m_pPV( i_pPV )
+ {
+ }
+
+ virtual bool includeObject( const SdrObject& i_rObject ) const
+ {
+ return m_pPV && m_pPV->GetView().IsObjMarkable( const_cast< SdrObject* >( &i_rObject ), m_pPV );
+ }
+
+ private:
+ SdrPageView* m_pPV;
+ };
+}
+
+const SdrObject* SwFEShell::GetBestObject( BOOL bNext, USHORT /*GOTOOBJ_...*/ eType, BOOL bFlat, const ::svx::ISdrObjectFilter* pFilter )
+{
+ if( !Imp()->HasDrawView() )
+ return NULL;
+
+ const SdrObject *pBest = 0,
+ *pTop = 0;
+
+ const long nTmp = bNext ? LONG_MAX : 0;
+ Point aBestPos( nTmp, nTmp );
+ Point aTopPos( nTmp, nTmp );
+ Point aCurPos;
+ Point aPos;
+ BOOL bNoDraw = 0 == (GOTOOBJ_DRAW_ANY & eType);
+ BOOL bNoFly = 0 == (GOTOOBJ_FLY_ANY & eType);
+
+ if( !bNoFly && bNoDraw )
+ {
+ SwFlyFrm *pFly = GetCurrFrm( FALSE )->FindFlyFrm();
+ if( pFly )
+ pBest = pFly->GetVirtDrawObj();
+ }
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ SdrPageView* pPV = Imp()->GetDrawView()->GetSdrPageView();
+
+ MarkableObjectsOnly aDefaultFilter( pPV );
+ if ( !pFilter )
+ pFilter = &aDefaultFilter;
+
+ if( !pBest || rMrkList.GetMarkCount() == 1 )
+ {
+ // Ausgangspunkt bestimmen.
+ SdrObjList* pList = NULL;
+ if ( rMrkList.GetMarkCount() )
+ {
+ const SdrObject* pStartObj = rMrkList.GetMark(0)->GetMarkedSdrObj();
+ if( pStartObj->ISA(SwVirtFlyDrawObj) )
+ aPos = ((SwVirtFlyDrawObj*)pStartObj)->GetFlyFrm()->Frm().Pos();
+ else
+ aPos = pStartObj->GetSnapRect().TopLeft();
+
+ // If an object inside a group is selected, we want to
+ // iterate over the group members.
+ if ( ! pStartObj->GetUserCall() )
+ pList = pStartObj->GetObjList();
+ }
+ else
+ {
+ // If no object is selected, we check if we just entered a group.
+ // In this case we want to iterate over the group members.
+ aPos = GetCharRect().Center();
+ const SdrObject* pStartObj = pPV ? pPV->GetAktGroup() : 0;
+ if ( pStartObj && pStartObj->ISA( SdrObjGroup ) )
+ pList = pStartObj->GetSubList();
+ }
+
+ if ( ! pList )
+ {
+ // Here we are if
+ // A No object has been selected and no group has been entered or
+ // B An object has been selected and it is not inside a group
+ pList = getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 );
+ }
+
+
+ ASSERT( pList, "No object list to iterate" )
+
+ SdrObjListIter aObjIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS );
+ while ( aObjIter.IsMore() )
+ {
+ SdrObject* pObj = aObjIter.Next();
+ BOOL bFlyFrm = pObj->ISA(SwVirtFlyDrawObj);
+ if( ( bNoFly && bFlyFrm ) ||
+ ( bNoDraw && !bFlyFrm ) ||
+ ( eType == GOTOOBJ_DRAW_SIMPLE && lcl_IsControlGroup( pObj ) ) ||
+ ( eType == GOTOOBJ_DRAW_CONTROL && !lcl_IsControlGroup( pObj ) ) ||
+ ( pFilter && !pFilter->includeObject( *pObj ) ) )
+ continue;
+ if( bFlyFrm )
+ {
+ SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pObj;
+ SwFlyFrm *pFly = pO->GetFlyFrm();
+ if( GOTOOBJ_FLY_ANY != ( GOTOOBJ_FLY_ANY & eType ) )
+ {
+ switch ( eType )
+ {
+ case GOTOOBJ_FLY_FRM:
+ if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+ continue;
+ break;
+ case GOTOOBJ_FLY_GRF:
+ if ( pFly->Lower() &&
+ (pFly->Lower()->IsLayoutFrm() ||
+ !((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode()))
+ continue;
+ break;
+ case GOTOOBJ_FLY_OLE:
+ if ( pFly->Lower() &&
+ (pFly->Lower()->IsLayoutFrm() ||
+ !((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode()))
+ continue;
+ break;
+ }
+ }
+ aCurPos = pFly->Frm().Pos();
+ }
+ else
+ aCurPos = pObj->GetCurrentBoundRect().TopLeft();
+
+ // Sonderfall wenn ein anderes Obj auf selber Y steht.
+ if( aCurPos != aPos && // nur wenn ich es nicht selber bin
+ aCurPos.Y() == aPos.Y() && // ist die Y Position gleich
+ (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir
+ (aCurPos.X() < aPos.X())) ) // " reverse
+ {
+ aBestPos = Point( nTmp, nTmp );
+ SdrObjListIter aTmpIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS );
+ while ( aTmpIter.IsMore() )
+ {
+ SdrObject* pTmpObj = aTmpIter.Next();
+ bFlyFrm = pTmpObj->ISA(SwVirtFlyDrawObj);
+ if( ( bNoFly && bFlyFrm ) || ( bNoDraw && !bFlyFrm ) )
+ continue;
+ if( bFlyFrm )
+ {
+ SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pTmpObj;
+ aCurPos = pO->GetFlyFrm()->Frm().Pos();
+ }
+ else
+ aCurPos = pTmpObj->GetCurrentBoundRect().TopLeft();
+
+ if( aCurPos != aPos && aCurPos.Y() == aPos.Y() &&
+ (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir
+ (aCurPos.X() < aPos.X())) && // " reverse
+ (bNext? (aCurPos.X() < aBestPos.X()) : // besser als Beste
+ (aCurPos.X() > aBestPos.X())) ) // " reverse
+ {
+ aBestPos = aCurPos;
+ pBest = pTmpObj;
+ }
+ }
+ break;
+ }
+
+ if( (bNext? (aPos.Y() < aCurPos.Y()) : // nur unter mir
+ (aPos.Y() > aCurPos.Y())) && // " reverse
+ (bNext? (aBestPos.Y() > aCurPos.Y()) : // naeher drunter
+ (aBestPos.Y() < aCurPos.Y())) || // " reverse
+ (aBestPos.Y() == aCurPos.Y() &&
+ (bNext? (aBestPos.X() > aCurPos.X()) : // weiter links
+ (aBestPos.X() < aCurPos.X())))) // " reverse
+
+ {
+ aBestPos = aCurPos;
+ pBest = pObj;
+ }
+
+ if( (bNext? (aTopPos.Y() > aCurPos.Y()) : // hoeher als Beste
+ (aTopPos.Y() < aCurPos.Y())) || // " reverse
+ (aTopPos.Y() == aCurPos.Y() &&
+ (bNext? (aTopPos.X() > aCurPos.X()) : // weiter links
+ (aTopPos.X() < aCurPos.X())))) // " reverse
+ {
+ aTopPos = aCurPos;
+ pTop = pObj;
+ }
+ }
+ // leider nichts gefunden
+ if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) )
+ pBest = pTop;
+ }
+
+ return pBest;
+}
+
+BOOL SwFEShell::GotoObj( BOOL bNext, USHORT /*GOTOOBJ_...*/ eType )
+{
+ const SdrObject* pBest = GetBestObject( bNext, eType );
+
+ if ( !pBest )
+ return FALSE;
+
+ BOOL bFlyFrm = pBest->ISA(SwVirtFlyDrawObj);
+ if( bFlyFrm )
+ {
+ SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pBest;
+ const SwRect& rFrm = pO->GetFlyFrm()->Frm();
+ SelectObj( rFrm.Pos(), 0, (SdrObject*)pBest );
+ if( !ActionPend() )
+ MakeVisible( rFrm );
+ }
+ else
+ {
+ SelectObj( Point(), 0, (SdrObject*)pBest );
+ if( !ActionPend() )
+ MakeVisible( pBest->GetCurrentBoundRect() );
+ }
+ CallChgLnk();
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::BeginCreate()
+|*
+|* Ersterstellung MA 20. Dec. 94
+|* Letzte Aenderung MA 21. Mar. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::BeginCreate( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, const Point &rPos )
+{
+ BOOL bRet = FALSE;
+
+ if ( !Imp()->HasDrawView() )
+ Imp()->MakeDrawView();
+
+ if ( GetPageNumber( rPos ) )
+ {
+ Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind );
+ if ( eSdrObjectKind == OBJ_CAPTION )
+ bRet = Imp()->GetDrawView()->BegCreateCaptionObj(
+ rPos, Size( lMinBorder - MINFLY, lMinBorder - MINFLY ),
+ GetOut() );
+ else
+ bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
+ }
+ if ( bRet )
+ {
+ ::FrameNotify( this, FLY_DRAG_START );
+ }
+ return bRet;
+}
+
+BOOL SwFEShell::BeginCreate( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, UINT32 eObjInventor,
+ const Point &rPos )
+{
+ BOOL bRet = FALSE;
+
+ if ( !Imp()->HasDrawView() )
+ Imp()->MakeDrawView();
+
+ if ( GetPageNumber( rPos ) )
+ {
+ Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind, eObjInventor );
+ bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
+ }
+ if ( bRet )
+ ::FrameNotify( this, FLY_DRAG_START );
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::MoveCreate()
+|*
+|* Ersterstellung MA 20. Dec. 94
+|* Letzte Aenderung MA 24. Jan. 95
+|*
+*************************************************************************/
+
+void SwFEShell::MoveCreate( const Point &rPos )
+{
+ ASSERT( Imp()->HasDrawView(), "MoveCreate without DrawView?" );
+ if ( GetPageNumber( rPos ) )
+ {
+ ScrollTo( rPos );
+ Imp()->GetDrawView()->MovCreateObj( rPos );
+ ::FrameNotify( this, FLY_DRAG );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::EndCreate(), ImpEndCreate()
+|*
+|* Ersterstellung MA 20. Dec. 94
+|* Letzte Aenderung MA 14. Oct. 96
+|*
+*************************************************************************/
+
+BOOL SwFEShell::EndCreate( UINT16 eSdrCreateCmd )
+{
+ // JP 18.08.95: Damit das Undo-Object aus der DrawEngine nicht bei uns
+ // gespeichert wird, (wir erzeugen ein eigenes Undo-Object!) hier kurz
+ // das Undo abschalten
+ ASSERT( Imp()->HasDrawView(), "EndCreate without DrawView?" );
+ if( !Imp()->GetDrawView()->IsGroupEntered() )
+ GetDoc()->SetNoDrawUndoObj( TRUE );
+ BOOL bCreate = Imp()->GetDrawView()->EndCreateObj(
+ SdrCreateCmd( eSdrCreateCmd ) );
+ GetDoc()->SetNoDrawUndoObj( FALSE );
+
+ if ( !bCreate )
+ {
+ ::FrameNotify( this, FLY_DRAG_END );
+ return FALSE;
+ }
+
+ if ( (SdrCreateCmd)eSdrCreateCmd == SDRCREATE_NEXTPOINT )
+ {
+ ::FrameNotify( this, FLY_DRAG );
+ return TRUE;
+ }
+ return ImpEndCreate();
+}
+
+
+BOOL SwFEShell::ImpEndCreate()
+{
+ ASSERT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1,
+ "Neues Object nicht selektiert." );
+
+ SdrObject& rSdrObj = *Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+
+ if( rSdrObj.GetSnapRect().IsEmpty() )
+ {
+ //JP 10.04.95: das Object vergessen wir lieber, fuerht nur
+ // zu Problemen
+ Imp()->GetDrawView()->DeleteMarked();
+ Imp()->GetDrawView()->UnmarkAll();
+ ::FrameNotify( this, FLY_DRAG_END );
+ return FALSE;
+ }
+
+ if( rSdrObj.GetUpGroup() )
+ {
+ Point aTmpPos( rSdrObj.GetSnapRect().TopLeft() );
+ Point aNewAnchor( rSdrObj.GetUpGroup()->GetAnchorPos() );
+ // OD 2004-04-05 #i26791# - direct object positioning for group members
+ rSdrObj.NbcSetRelativePos( aTmpPos - aNewAnchor );
+ rSdrObj.NbcSetAnchorPos( aNewAnchor );
+ ::FrameNotify( this, FLY_DRAG );
+ return TRUE;
+ }
+
+ LockPaint();
+ StartAllAction();
+
+ Imp()->GetDrawView()->UnmarkAll();
+
+ const Rectangle &rBound = rSdrObj.GetSnapRect();
+ Point aPt( rBound.TopRight() );
+
+ //Fremde Identifier sollen in den Default laufen.
+ //Ueberschneidungen sind moeglich!!
+ UINT16 nIdent = SdrInventor == rSdrObj.GetObjInventor()
+ ? rSdrObj.GetObjIdentifier()
+ : 0xFFFF;
+
+ //Default fuer Controls ist Zeichengebunden, Absatzgebunden sonst.
+ SwFmtAnchor aAnch;
+ const SwFrm *pAnch = 0;
+ BOOL bCharBound = FALSE;
+ if( rSdrObj.ISA( SdrUnoObj ) )
+ {
+ SwPosition aPos( GetDoc()->GetNodes() );
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ Point aPoint( aPt.X(), aPt.Y() + rBound.GetHeight()/2 );
+ getIDocumentLayoutAccess()->GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState );
+
+ //JP 22.01.99: Zeichenbindung ist im ReadnOnly-Inhalt nicht erlaubt
+ if( !aPos.nNode.GetNode().IsProtect() )
+ {
+ pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, &aPos );
+ SwRect aTmp;
+ pAnch->GetCharRect( aTmp, aPos );
+
+ //Der Crsr darf nicht zu weit entfernt sein.
+ bCharBound = TRUE;
+ Rectangle aRect( aTmp.SVRect() );
+ aRect.Left() -= MM50*2;
+ aRect.Top() -= MM50*2;
+ aRect.Right() += MM50*2;
+ aRect.Bottom()+= MM50*2;
+
+ if( !aRect.IsOver( rBound ) && !::GetHtmlMode( GetDoc()->GetDocShell() ))
+ bCharBound = FALSE;
+
+ //Bindung in Kopf-/Fusszeilen ist ebenfalls nicht erlaubt.
+ if( bCharBound )
+ bCharBound = !GetDoc()->IsInHeaderFooter( aPos.nNode );
+
+ if( bCharBound )
+ {
+ aAnch.SetType( FLY_AS_CHAR );
+ aAnch.SetAnchor( &aPos );
+ }
+ }
+ }
+
+ if( !bCharBound )
+ {
+ // OD 16.05.2003 #108784# - allow native drawing objects in header/footer.
+ // Thus, set <bBodyOnly> to <false> for these objects using value
+ // of <nIdent> - value <0xFFFF> indicates control objects, which aren't
+ // allowed in header/footer.
+ //bool bBodyOnly = OBJ_NONE != nIdent;
+ bool bBodyOnly = 0xFFFF == nIdent;
+ bool bAtPage = false;
+ const SwFrm* pPage = 0;
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ Point aPoint( aPt );
+ SwPosition aPos( GetDoc()->GetNodes() );
+ GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
+
+ //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
+ if( aPos.nNode.GetNode().IsProtect() )
+ // dann darf er nur seitengebunden sein. Oder sollte man
+ // die naechste nicht READONLY Position suchen?
+ bAtPage = true;
+
+ pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, 0, FALSE );
+
+ if( !bAtPage )
+ {
+ const SwFlyFrm *pTmp = pAnch->FindFlyFrm();
+ if( pTmp )
+ {
+ const SwFrm* pTmpFrm = pAnch;
+ SwRect aBound( rBound );
+ while( pTmp )
+ {
+ if( pTmp->Frm().IsInside( aBound ) )
+ {
+ if( !bBodyOnly || !pTmp->FindFooterOrHeader() )
+ pPage = pTmpFrm;
+ break;
+ }
+ pTmp = pTmp->GetAnchorFrm()
+ ? pTmp->GetAnchorFrm()->FindFlyFrm()
+ : 0;
+ pTmpFrm = pTmp;
+ }
+ }
+
+ if( !pPage )
+ pPage = pAnch->FindPageFrm();
+
+ // immer ueber FindAnchor gehen, damit der Frame immer an den
+ // davorgehen gebunden wird. Beim GetCrsOfst kann man auch zum
+ // nachfolgenden kommen. DAS IST FALSCH
+ pAnch = ::FindAnchor( pPage, aPt, bBodyOnly );
+ aPos.nNode = *((SwCntntFrm*)pAnch)->GetNode();
+
+ //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
+ if( aPos.nNode.GetNode().IsProtect() )
+ // dann darf er nur seitengebunden sein. Oder sollte man
+ // die naechste nicht READONLY Position suchen?
+ bAtPage = true;
+ else
+ {
+ aAnch.SetType( FLY_AT_PARA );
+ aAnch.SetAnchor( &aPos );
+ }
+ }
+
+ if( bAtPage )
+ {
+ pPage = pAnch->FindPageFrm();
+
+ aAnch.SetType( FLY_AT_PAGE );
+ aAnch.SetPageNum( pPage->GetPhyPageNum() );
+ pAnch = pPage; // die Page wird jetzt zum Anker
+ }
+ }
+
+ SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_SURROUND, RES_ANCHOR, 0 );
+ aSet.Put( aAnch );
+
+ // OD 2004-03-30 #i26791# - determine relative object position
+ SwTwips nXOffset;
+ SwTwips nYOffset = rBound.Top() - pAnch->Frm().Top();
+ {
+ if( pAnch->IsVertical() )
+ {
+ nXOffset = nYOffset;
+ nYOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
+ }
+ else if( pAnch->IsRightToLeft() )
+ nXOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
+ else
+ nXOffset = rBound.Left() - pAnch->Frm().Left();
+ if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
+ {
+ SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
+ do {
+ pTmp = pTmp->FindMaster();
+ ASSERT( pTmp, "Where's my Master?" );
+ // OD 2004-03-30 #i26791# - correction: add frame area height
+ // of master frames.
+ nYOffset += pTmp->IsVertical() ?
+ pTmp->Frm().Width() : pTmp->Frm().Height();
+ } while ( pTmp->IsFollow() );
+ }
+ }
+
+ if( OBJ_NONE == nIdent )
+ {
+ //Bei OBJ_NONE wird ein Fly eingefuegt.
+ const long nWidth = rBound.Right() - rBound.Left();
+ const long nHeight= rBound.Bottom() - rBound.Top();
+ aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, Max( nWidth, long(MINFLY) ),
+ Max( nHeight, long(MINFLY) )));
+
+ SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
+ SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
+ aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) );
+ aSet.Put( aHori );
+ aSet.Put( aVert );
+
+ //Schnell noch das Rechteck merken
+ const SwRect aFlyRect( rBound );
+
+ //Erzeugtes Object wegwerfen, so kann der Fly am elegentesten
+ //ueber vorhandene SS erzeugt werden.
+ GetDoc()->SetNoDrawUndoObj( TRUE ); // siehe oben
+ // --> OD 2005-08-08 #i52858# - method name changed
+ SdrPage *pPg = getIDocumentDrawModelAccess()->GetOrCreateDrawModel()->GetPage( 0 );
+ // <--
+ if( !pPg )
+ {
+ SdrModel* pTmpSdrModel = getIDocumentDrawModelAccess()->GetDrawModel();
+ pPg = pTmpSdrModel->AllocPage( FALSE );
+ pTmpSdrModel->InsertPage( pPg );
+ }
+ pPg->RecalcObjOrdNums();
+ SdrObject* pRemovedObject = pPg->RemoveObject( rSdrObj.GetOrdNumDirect() );
+ SdrObject::Free( pRemovedObject );
+ GetDoc()->SetNoDrawUndoObj( FALSE );
+
+ SwFlyFrm* pFlyFrm;
+ if( NewFlyFrm( aSet, TRUE ) &&
+ ::GetHtmlMode( GetDoc()->GetDocShell() ) &&
+ 0 != ( pFlyFrm = FindFlyFrm() ))
+ {
+ SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT );
+ //Horizontale Ausrichtung:
+ const BOOL bLeftFrm = aFlyRect.Left() <
+ pAnch->Frm().Left() + pAnch->Prt().Left(),
+ bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
+ pAnch->Frm().Left() + pAnch->Prt().Width()/2;
+ if( bLeftFrm || bLeftPrt )
+ {
+ aHori.SetHoriOrient( text::HoriOrientation::LEFT );
+ aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
+ }
+ else
+ {
+ const BOOL bRightFrm = aFlyRect.Left() >
+ pAnch->Frm().Left() + pAnch->Prt().Width();
+ aHori.SetHoriOrient( text::HoriOrientation::RIGHT );
+ aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
+ }
+ aHtmlSet.Put( aHori );
+ aVert.SetVertOrient( text::VertOrientation::TOP );
+ aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA );
+ aHtmlSet.Put( aVert );
+
+ GetDoc()->SetAttr( aHtmlSet, *pFlyFrm->GetFmt() );
+ }
+ }
+ else
+ {
+ Point aRelNullPt;
+ if( OBJ_CAPTION == nIdent )
+ aRelNullPt = ((SdrCaptionObj&)rSdrObj).GetTailPos();
+ else
+ aRelNullPt = rBound.TopLeft();
+
+ aSet.Put( aAnch );
+ aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
+ // OD 2004-03-30 #i26791# - set horizontal position
+ SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
+ aSet.Put( aHori );
+ // OD 2004-03-30 #i26791# - set vertical position
+ if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
+ {
+ SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
+ do {
+ pTmp = pTmp->FindMaster();
+ ASSERT( pTmp, "Where's my Master?" );
+ nYOffset += pTmp->IsVertical() ?
+ pTmp->Prt().Width() : pTmp->Prt().Height();
+ } while ( pTmp->IsFollow() );
+ }
+ SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
+ aSet.Put( aVert );
+ SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet );
+ // --> OD 2004-10-25 #i36010# - set layout direction of the position
+ pFmt->SetPositionLayoutDir(
+ text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
+ // <--
+ // --> OD 2005-03-11 #i44344#, #i44681# - positioning attributes already set
+ pFmt->PosAttrSet();
+ // <--
+
+ SwDrawContact *pContact = new SwDrawContact( pFmt, &rSdrObj );
+ // --> OD 2004-11-22 #i35635#
+ pContact->MoveObjToVisibleLayer( &rSdrObj );
+ // <--
+ if( bCharBound )
+ {
+ ASSERT( aAnch.GetAnchorId() == FLY_AS_CHAR, "wrong AnchorType" );
+ SwTxtNode *pNd = aAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
+ SwFmtFlyCnt aFmt( pFmt );
+ pNd->InsertItem(aFmt,
+ aAnch.GetCntntAnchor()->nContent.GetIndex(), 0 );
+ SwFmtVertOrient aVertical( pFmt->GetVertOrient() );
+ aVertical.SetVertOrient( text::VertOrientation::LINE_CENTER );
+ pFmt->SetFmtAttr( aVertical );
+ }
+ if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
+ {
+ SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
+ do {
+ pTmp = pTmp->FindMaster();
+ ASSERT( pTmp, "Where's my Master?" );
+ } while( pTmp->IsFollow() );
+ pAnch = pTmp;
+ }
+
+ pContact->ConnectToLayout();
+
+ // OD 25.06.2003 #108784# - mark object at frame the object is inserted at.
+ {
+ SdrObject* pMarkObj = pContact->GetDrawObjectByAnchorFrm( *pAnch );
+ if ( pMarkObj )
+ {
+ Imp()->GetDrawView()->MarkObj( pMarkObj, Imp()->GetPageView(),
+ FALSE, FALSE );
+ }
+ else
+ {
+ Imp()->GetDrawView()->MarkObj( &rSdrObj, Imp()->GetPageView(),
+ FALSE, FALSE );
+ }
+ }
+ }
+
+ GetDoc()->SetModified();
+
+ KillPams();
+ EndAllActionAndCall();
+ UnlockPaint();
+ return TRUE;
+}
+
+
+/*************************************************************************
+|*
+|* SwFEShell::BreakCreate()
+|*
+|* Ersterstellung MA 20. Dec. 94
+|* Letzte Aenderung MA 09. Jan. 95
+|*
+*************************************************************************/
+
+void SwFEShell::BreakCreate()
+{
+ ASSERT( Imp()->HasDrawView(), "BreakCreate without DrawView?" );
+ Imp()->GetDrawView()->BrkCreateObj();
+ ::FrameNotify( this, FLY_DRAG_END );
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::IsDrawCreate()
+|*
+|* Ersterstellung OM 16. Mar. 95
+|* Letzte Aenderung OM 16. Mar. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::IsDrawCreate() const
+{
+ return Imp()->HasDrawView() ? Imp()->GetDrawView()->IsCreateObj() : FALSE;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::BeginMark()
+|*
+|* Ersterstellung OM 07. Feb. 95
+|* Letzte Aenderung OM 07. Feb. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::BeginMark( const Point &rPos )
+{
+ if ( !Imp()->HasDrawView() )
+ Imp()->MakeDrawView();
+
+ if ( GetPageNumber( rPos ) )
+ {
+ SwDrawView* pDView = Imp()->GetDrawView();
+
+ if (pDView->HasMarkablePoints())
+ return pDView->BegMarkPoints( rPos );
+ else
+ return pDView->BegMarkObj( rPos );
+ }
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::MoveMark()
+|*
+|* Ersterstellung OM 07. Feb. 95
+|* Letzte Aenderung OM 07. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::MoveMark( const Point &rPos )
+{
+ ASSERT( Imp()->HasDrawView(), "MoveMark without DrawView?" );
+
+ if ( GetPageNumber( rPos ) )
+ {
+ ScrollTo( rPos );
+ SwDrawView* pDView = Imp()->GetDrawView();
+// Imp()->GetDrawView()->MovMarkObj( rPos );
+
+ if (pDView->IsInsObjPoint())
+ pDView->MovInsObjPoint( rPos );
+ else if (pDView->IsMarkPoints())
+ pDView->MovMarkPoints( rPos );
+ else
+ pDView->MovAction( rPos );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::EndMark()
+|*
+|* Ersterstellung OM 07. Feb. 95
+|* Letzte Aenderung MA 08. Feb. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::EndMark()
+{
+ BOOL bRet = FALSE;
+ ASSERT( Imp()->HasDrawView(), "EndMark without DrawView?" );
+
+ if (Imp()->GetDrawView()->IsMarkObj())
+ {
+ bRet = Imp()->GetDrawView()->EndMarkObj();
+
+ if ( bRet )
+ {
+ BOOL bShowHdl = FALSE;
+ SwDrawView* pDView = Imp()->GetDrawView();
+ //Rahmen werden auf diese Art nicht Selektiert, es sein denn es
+ //ist nur ein Rahmen.
+ SdrMarkList &rMrkList = (SdrMarkList&)pDView->GetMarkedObjectList();
+ SwFlyFrm* pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
+
+ if ( rMrkList.GetMarkCount() > 1 )
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ if ( !bShowHdl )
+ {
+ //HMHpDView->HideMarkHdl();
+ bShowHdl = TRUE;
+ }
+ rMrkList.DeleteMark( i );
+ --i; //keinen auslassen.
+ }
+ }
+
+ if( bShowHdl )
+ {
+ pDView->MarkListHasChanged();
+ pDView->AdjustMarkHdl();
+ //HMHpDView->ShowMarkHdl();
+ }
+
+ if ( rMrkList.GetMarkCount() )
+ ::lcl_GrabCursor(this, pOldSelFly);
+ else
+ bRet = FALSE;
+ }
+ if ( bRet )
+ ::FrameNotify( this, FLY_DRAG_START );
+ }
+ else
+ {
+ if (Imp()->GetDrawView()->IsMarkPoints())
+ bRet = Imp()->GetDrawView()->EndMarkPoints();
+ }
+
+ SetChainMarker();
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::BreakSelect()
+|*
+|* Ersterstellung OM 07. Feb. 95
+|* Letzte Aenderung OM 07. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::BreakMark()
+{
+ ASSERT( Imp()->HasDrawView(), "BreakMark without DrawView?" );
+ Imp()->GetDrawView()->BrkMarkObj();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetAnchorId()
+|*
+|* Ersterstellung MA 30. Jan. 95
+|* Letzte Aenderung MA 30. Jan. 95
+|*
+*************************************************************************/
+
+short SwFEShell::GetAnchorId() const
+{
+ short nRet = SHRT_MAX;
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if ( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ nRet = -1;
+ break;
+ }
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+ short nId = static_cast<short>(pContact->GetFmt()->GetAnchor().GetAnchorId());
+ if ( nRet == SHRT_MAX )
+ nRet = nId;
+ else if ( nRet != nId )
+ {
+ nRet = -1;
+ break;
+ }
+ }
+ }
+ if ( nRet == SHRT_MAX )
+ nRet = -1;
+ return nRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::ChgAnchor()
+|*
+|* Ersterstellung MA 10. Jan. 95
+|* Letzte Aenderung MA 30. May. 96
+|*
+*************************************************************************/
+
+void SwFEShell::ChgAnchor( int eAnchorId, BOOL bSameOnly, BOOL bPosCorr )
+{
+ ASSERT( Imp()->HasDrawView(), "ChgAnchor without DrawView?" );
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ if( rMrkList.GetMarkCount() &&
+ !rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() )
+ {
+ StartAllAction();
+
+ if( GetDoc()->ChgAnchor( rMrkList, (RndStdIds)eAnchorId, bSameOnly, bPosCorr ))
+ Imp()->GetDrawView()->UnmarkAll();
+
+ EndAllAction();
+
+ ::FrameNotify( this, FLY_DRAG );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::DelSelectedObj()
+|*
+|* Ersterstellung MA 03. Nov. 92
+|* Letzte Aenderung MA 14. Nov. 95
+|*
+*************************************************************************/
+
+void SwFEShell::DelSelectedObj()
+{
+ ASSERT( Imp()->HasDrawView(), "DelSelectedObj(), no DrawView available" );
+ if ( Imp()->HasDrawView() )
+ {
+ StartAllAction();
+ Imp()->GetDrawView()->DeleteMarked();
+ EndAllAction();
+ ::FrameNotify( this, FLY_DRAG_END );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetObjSize(), GetAnchorObjDiff()
+|*
+|* Beschreibung Fuer die Statuszeile zum Erfragen der aktuellen
+|* Verhaeltnisse
+|* Ersterstellung MA 25. Apr. 95
+|* Letzte Aenderung MA 25. Apr. 95
+|*
+*************************************************************************/
+
+Size SwFEShell::GetObjSize() const
+{
+ Rectangle aRect;
+ if ( Imp()->HasDrawView() )
+ {
+ if ( Imp()->GetDrawView()->IsAction() )
+ Imp()->GetDrawView()->TakeActionRect( aRect );
+ else
+ aRect = Imp()->GetDrawView()->GetAllMarkedRect();
+ }
+ return aRect.GetSize();
+}
+
+Point SwFEShell::GetAnchorObjDiff() const
+{
+ const SdrView *pView = Imp()->GetDrawView();
+ ASSERT( pView, "GetAnchorObjDiff without DrawView?" );
+
+ Rectangle aRect;
+ if ( Imp()->GetDrawView()->IsAction() )
+ Imp()->GetDrawView()->TakeActionRect( aRect );
+ else
+ aRect = Imp()->GetDrawView()->GetAllMarkedRect();
+
+ Point aRet( aRect.TopLeft() );
+
+ if ( IsFrmSelected() )
+ {
+ SwFlyFrm *pFly = FindFlyFrm();
+ aRet -= pFly->GetAnchorFrm()->Frm().Pos();
+ }
+ else
+ {
+ const SdrObject *pObj = pView->GetMarkedObjectList().GetMarkCount() == 1 ?
+ pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj() : 0;
+ if ( pObj )
+ aRet -= pObj->GetAnchorPos();
+ }
+
+ return aRet;
+}
+
+Point SwFEShell::GetObjAbsPos() const
+{
+ ASSERT( Imp()->GetDrawView(), "GetObjAbsPos() without DrawView?" );
+ return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft();
+}
+
+
+
+/*************************************************************************
+|*
+|* SwFEShell::IsGroupSelected()
+|*
+|* Ersterstellung MA 30. Jan. 95
+|* Letzte Aenderung MA 30. May. 96
+|*
+*************************************************************************/
+
+BOOL SwFEShell::IsGroupSelected()
+{
+ if ( IsObjSelected() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ // OD 30.06.2003 #108784# - consider 'virtual' drawing objects.
+ // Thus, use corresponding method instead of checking type.
+ if ( pObj->IsGroupObject() &&
+ // --> FME 2004-12-08 #i38505# No ungroup allowed for 3d objects
+ !pObj->Is3DObj() &&
+ // <--
+ FLY_AS_CHAR != ((SwDrawContact*)GetUserCall(pObj))->
+ GetFmt()->GetAnchor().GetAnchorId() )
+ {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+// OD 27.06.2003 #108784# - change return type.
+// OD 27.06.2003 #108784# - adjustments for drawing objects in header/footer:
+// allow group, only if all selected objects are in the same header/footer
+// or not in header/footer.
+bool SwFEShell::IsGroupAllowed() const
+{
+ bool bIsGroupAllowed = false;
+ if ( IsObjSelected() > 1 )
+ {
+ bIsGroupAllowed = true;
+ const SdrObject* pUpGroup = 0L;
+ const SwFrm* pHeaderFooterFrm = 0L;
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT i = 0; bIsGroupAllowed && i < rMrkList.GetMarkCount(); ++i )
+ {
+ const SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if ( i )
+ bIsGroupAllowed = pObj->GetUpGroup() == pUpGroup;
+ else
+ pUpGroup = pObj->GetUpGroup();
+
+ if ( bIsGroupAllowed )
+ {
+ SwFrmFmt* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject*>(pObj) ) );
+ if ( !pFrmFmt )
+ {
+ ASSERT( false,
+ "<SwFEShell::IsGroupAllowed()> - missing frame format" );
+ bIsGroupAllowed = false;
+ }
+ else if ( FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() )
+ {
+ bIsGroupAllowed = false;
+ }
+ }
+
+ // OD 27.06.2003 #108784# - check, if all selected objects are in the
+ // same header/footer or not in header/footer.
+ if ( bIsGroupAllowed )
+ {
+ const SwFrm* pAnchorFrm = 0L;
+ if ( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ const SwFlyFrm* pFlyFrm =
+ static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
+ if ( pFlyFrm )
+ {
+ pAnchorFrm = pFlyFrm->GetAnchorFrm();
+ }
+ }
+ else
+ {
+ SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
+ if ( pDrawContact )
+ {
+ pAnchorFrm = pDrawContact->GetAnchorFrm( pObj );
+ }
+ }
+ if ( pAnchorFrm )
+ {
+ if ( i )
+ {
+ bIsGroupAllowed =
+ ( pAnchorFrm->FindFooterOrHeader() == pHeaderFooterFrm );
+ }
+ else
+ {
+ pHeaderFooterFrm = pAnchorFrm->FindFooterOrHeader();
+ }
+ }
+ }
+
+ }
+ }
+
+ return bIsGroupAllowed;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GroupSelection()
+|*
+|* Beschreibung Die Gruppe bekommt den Anker und das Contactobjekt
+|* des ersten in der Selektion
+|* Ersterstellung MA 30. Jan. 95
+|* Letzte Aenderung MA 23. Apr. 95
+|*
+*************************************************************************/
+
+void SwFEShell::GroupSelection()
+{
+ if ( IsGroupAllowed() )
+ {
+ StartAllAction();
+ StartUndo( UNDO_START );
+
+ GetDoc()->GroupSelection( *Imp()->GetDrawView() );
+
+ EndUndo( UNDO_END );
+ EndAllAction();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::UnGroupSelection()
+|*
+|* Beschreibung Die Einzelobjekte bekommen eine Kopie vom Anker und
+|* Contactobjekt der Gruppe.
+|* Ersterstellung MA 30. Jan. 95
+|* Letzte Aenderung MA 01. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::UnGroupSelection()
+{
+ if ( IsGroupSelected() )
+ {
+ StartAllAction();
+ StartUndo( UNDO_START );
+
+ GetDoc()->UnGroupSelection( *Imp()->GetDrawView() );
+
+ EndUndo( UNDO_END );
+ EndAllAction();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::MirrorSelection()
+|*
+|* Ersterstellung MA 06. Aug. 95
+|* Letzte Aenderung MA 06. Aug. 95
+|*
+*************************************************************************/
+
+void SwFEShell::MirrorSelection( BOOL bHorizontal )
+{
+ SdrView *pView = Imp()->GetDrawView();
+ if ( IsObjSelected() && pView->IsMirrorAllowed() )
+ {
+ if ( bHorizontal )
+ pView->MirrorAllMarkedHorizontal();
+ else
+ pView->MirrorAllMarkedVertical();
+ }
+}
+
+// springe zum benannten Rahmen (Grafik/OLE)
+
+BOOL SwFEShell::GotoFly( const String& rName, FlyCntType eType, BOOL bSelFrm )
+{
+ BOOL bRet = FALSE;
+static BYTE __READONLY_DATA aChkArr[ 4 ] = {
+ /* FLYCNTTYPE_ALL */ 0,
+ /* FLYCNTTYPE_FRM */ ND_TEXTNODE,
+ /* FLYCNTTYPE_GRF */ ND_GRFNODE,
+ /* FLYCNTTYPE_OLE */ ND_OLENODE
+ };
+
+ const SwFlyFrmFmt* pFlyFmt = pDoc->FindFlyByName( rName, aChkArr[ eType]);
+ if( pFlyFmt )
+ {
+ SET_CURR_SHELL( this );
+
+ SwClientIter aIter( *(SwModify*)pFlyFmt );
+ SwFlyFrm* pFrm = (SwFlyFrm*)aIter.First( TYPE( SwFlyFrm ));
+ if( pFrm )
+ {
+ ASSERT( pFrm->IsFlyFrm(), "Wrong FrmType" );
+ if( bSelFrm )
+ {
+ SelectObj( pFrm->Frm().Pos(), 0, ((SwFlyFrm*)pFrm)->GetVirtDrawObj() );
+ if( !ActionPend() )
+ MakeVisible( pFrm->Frm() );
+ }
+ else
+ {
+ // --> OD 2004-06-11 #i28701# - no format here
+// pFrm->GetAnchorFrm()->Calc();
+ SwCntntFrm *pCFrm = pFrm->ContainsCntnt();
+ if ( pCFrm )
+ {
+ SwCntntNode *pCNode = pCFrm->GetNode();
+ ClearMark();
+ SwPaM* pCrsr = GetCrsr();
+
+ pCrsr->GetPoint()->nNode = *pCNode;
+ pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
+
+ SwRect& rChrRect = (SwRect&)GetCharRect();
+ rChrRect = pFrm->Prt();
+ rChrRect.Pos() += pFrm->Frm().Pos();
+ GetCrsrDocPos() = rChrRect.Pos();
+ }
+ }
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+}
+
+USHORT SwFEShell::GetFlyCount( FlyCntType eType ) const
+{
+ return GetDoc()->GetFlyCount(eType);
+}
+
+
+const SwFrmFmt* SwFEShell::GetFlyNum(USHORT nIdx, FlyCntType eType ) const
+{
+ return GetDoc()->GetFlyNum(nIdx, eType );
+}
+
+// zeige das akt. selektierte "Object" an
+void SwFEShell::MakeSelVisible()
+{
+ if( Imp()->HasDrawView() &&
+ Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )
+ {
+ MakeVisible( Imp()->GetDrawView()->GetAllMarkedRect() );
+ }
+ else
+ SwCrsrShell::MakeSelVisible();
+}
+
+
+//Welcher Schutz ist am selektierten Objekt gesetzt?
+BYTE SwFEShell::IsSelObjProtected( USHORT eType ) const
+{
+ int nChk = 0;
+ const bool bParent = (eType & FLYPROTECT_PARENT);
+ if( Imp()->HasDrawView() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for( ULONG i = rMrkList.GetMarkCount(); i; )
+ {
+ SdrObject *pObj = rMrkList.GetMark( --i )->GetMarkedSdrObj();
+ if( !bParent )
+ {
+ nChk |= ( pObj->IsMoveProtect() ? FLYPROTECT_POS : 0 ) |
+ ( pObj->IsResizeProtect()? FLYPROTECT_SIZE : 0 );
+
+ if( FLYPROTECT_CONTENT & eType && pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+ if ( pFly->GetFmt()->GetProtect().IsCntntProtected() )
+ nChk |= FLYPROTECT_CONTENT;
+
+ if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+ {
+ SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode();
+ if ( pNd )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = pNd->GetOLEObj().GetOleRef();
+
+ // TODO/LATER: use correct aspect
+ if ( xObj.is() &&
+ embed::EmbedMisc::EMBED_NEVERRESIZE & xObj->getStatus( embed::Aspects::MSOLE_CONTENT ) )
+ {
+ nChk |= FLYPROTECT_SIZE;
+ nChk |= FLYPROTECT_FIXED;
+ }
+ }
+ }
+ }
+ nChk &= eType;
+ if( nChk == eType )
+ return static_cast<BYTE>(eType);
+ }
+ const SwFrm* pAnch;
+ if( pObj->ISA(SwVirtFlyDrawObj) )
+ pAnch = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchorFrm();
+ else
+ {
+ SwDrawContact* pTmp = (SwDrawContact*)GetUserCall(pObj);
+ pAnch = pTmp ? pTmp->GetAnchorFrm( pObj ) : NULL;
+ }
+ if( pAnch && pAnch->IsProtected() )
+ return static_cast<BYTE>(eType);
+ }
+ }
+ return static_cast<BYTE>(nChk);
+}
+
+BOOL SwFEShell::GetObjAttr( SfxItemSet &rSet ) const
+{
+ if ( !IsObjSelected() )
+ return FALSE;
+
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+ // --> OD 2007-07-24 #143008# - make code robust
+ ASSERT( pContact, "<SwFEShell::GetObjAttr(..)> - missing <pContact> - please inform OD." );
+ if ( pContact )
+ {
+ if ( i )
+ rSet.MergeValues( pContact->GetFmt()->GetAttrSet() );
+ else
+ rSet.Put( pContact->GetFmt()->GetAttrSet() );
+ }
+ // <--
+ }
+ return TRUE;
+}
+
+BOOL SwFEShell::SetObjAttr( const SfxItemSet& rSet )
+{
+ SET_CURR_SHELL( this );
+
+ if ( !rSet.Count() )
+ { ASSERT( !this, "SetObjAttr, empty set." );
+ return FALSE;
+ }
+
+ StartAllAction();
+ StartUndo( UNDO_INSATTR );
+
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+ GetDoc()->SetAttr( rSet, *pContact->GetFmt() );
+ }
+
+ EndUndo( UNDO_INSATTR );
+ EndAllActionAndCall();
+ GetDoc()->SetModified();
+ return TRUE;
+}
+
+BOOL SwFEShell::IsAlignPossible() const
+{
+ USHORT nCnt;
+ if ( 0 < (nCnt = IsObjSelected()) )
+ {
+ BOOL bRet = TRUE;
+ if ( nCnt == 1 )
+ {
+ SdrObject *pO = Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+ SwDrawContact *pC = (SwDrawContact*)GetUserCall(pO);
+ //only as character bound drawings can be aligned
+ bRet = (pC->GetFmt()->GetAnchor().GetAnchorId() == FLY_AS_CHAR);
+ }
+ if ( bRet )
+ return Imp()->GetDrawView()->IsAlignPossible();
+ }
+ return FALSE;
+}
+
+
+//Temporaerer Fix bis SS von JOE da ist
+void SwFEShell::CheckUnboundObjects()
+{
+ SET_CURR_SHELL( this );
+
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if ( !GetUserCall(pObj) )
+ {
+ const Rectangle &rBound = pObj->GetSnapRect();
+ const Point aPt( rBound.TopLeft() );
+ const SwFrm *pPage = GetLayout()->Lower();
+ const SwFrm *pLast = pPage;
+ while ( pPage && !pPage->Frm().IsInside( aPt ) )
+ {
+ if ( aPt.Y() > pPage->Frm().Bottom() )
+ pLast = pPage;
+ pPage = pPage->GetNext();
+ }
+ if ( !pPage )
+ pPage = pLast;
+ ASSERT( pPage, "Page not found." );
+
+ //Fremde Identifier sollen in den Default laufen.
+ //Ueberschneidungen sind moeglich!!
+ UINT16 nIdent =
+ Imp()->GetDrawView()->GetCurrentObjInventor() == SdrInventor ?
+ Imp()->GetDrawView()->GetCurrentObjIdentifier() : 0xFFFF;
+
+ SwFmtAnchor aAnch;
+ const SwFrm *pAnch = 0;
+ {
+ pAnch = ::FindAnchor( pPage, aPt, TRUE );
+ SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
+ aAnch.SetType( FLY_AT_PARA );
+ aAnch.SetAnchor( &aPos );
+ ((SwRect&)GetCharRect()).Pos() = aPt;
+ }
+
+ //Erst hier die Action, damit das GetCharRect aktuelle Werte liefert.
+ StartAllAction();
+
+ SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_SURROUND, RES_ANCHOR, 0 );
+ aSet.Put( aAnch );
+
+ Point aRelNullPt;
+
+ if( OBJ_CAPTION == nIdent )
+ aRelNullPt = ((SdrCaptionObj*)pObj)->GetTailPos();
+ else
+ aRelNullPt = rBound.TopLeft();
+
+ aSet.Put( aAnch );
+ aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
+ SwFrmFmt* pFmt = getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet );
+
+ SwDrawContact *pContact = new SwDrawContact(
+ (SwDrawFrmFmt*)pFmt, pObj );
+
+ // --> OD 2004-11-22 #i35635#
+ pContact->MoveObjToVisibleLayer( pObj );
+ // <--
+ pContact->ConnectToLayout();
+
+ EndAllAction();
+ }
+ }
+}
+
+void SwFEShell::SetCalcFieldValueHdl(Outliner* pOutliner)
+{
+ GetDoc()->SetCalcFieldValueHdl(pOutliner);
+}
+
+
+
+int SwFEShell::Chainable( SwRect &rRect, const SwFrmFmt &rSource,
+ const Point &rPt ) const
+{
+ rRect.Clear();
+
+ //Die Source darf noch keinen Follow haben.
+ const SwFmtChain &rChain = rSource.GetChain();
+ if ( rChain.GetNext() )
+ return SW_CHAIN_SOURCE_CHAINED;
+
+ if( Imp()->HasDrawView() )
+ {
+ SdrObject* pObj;
+ SdrPageView* pPView;
+ SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+ const USHORT nOld = pDView->GetHitTolerancePixel();
+ pDView->SetHitTolerancePixel( 0 );
+ if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) &&
+ pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+ rRect = pFly->Frm();
+
+ //Ziel darf natuerlich nicht gleich Source sein und es
+ //darf keine geschlossene Kette entstehen.
+ SwFrmFmt *pFmt = pFly->GetFmt();
+ return GetDoc()->Chainable(rSource, *pFmt);
+ }
+ pDView->SetHitTolerancePixel( nOld );
+ }
+ return SW_CHAIN_NOT_FOUND;
+}
+/* -----------------------------09.08.2002 07:40------------------------------
+
+ ---------------------------------------------------------------------------*/
+int SwFEShell::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest )
+{
+ return GetDoc()->Chain(rSource, rDest);
+}
+
+int SwFEShell::Chain( SwFrmFmt &rSource, const Point &rPt )
+{
+ SwRect aDummy;
+ int nErr = Chainable( aDummy, rSource, rPt );
+ if ( !nErr )
+ {
+ StartAllAction();
+ SdrObject* pObj;
+ SdrPageView* pPView;
+ SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+ const USHORT nOld = pDView->GetHitTolerancePixel();
+ pDView->SetHitTolerancePixel( 0 );
+ pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE );
+ pDView->SetHitTolerancePixel( nOld );
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+
+ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)pFly->GetFmt();
+ GetDoc()->Chain(rSource, *pFmt);
+ EndAllAction();
+ SetChainMarker();
+ }
+ return nErr;
+}
+
+void SwFEShell::Unchain( SwFrmFmt &rFmt )
+{
+ StartAllAction();
+ GetDoc()->Unchain(rFmt);
+ EndAllAction();
+}
+
+
+void SwFEShell::HideChainMarker()
+{
+ if ( pChainFrom )
+ {
+ delete pChainFrom;
+ pChainFrom = 0L;
+ }
+ if ( pChainTo )
+ {
+ delete pChainTo;
+ pChainTo = 0L;
+ }
+}
+
+void SwFEShell::SetChainMarker()
+{
+ BOOL bDelFrom = TRUE,
+ bDelTo = TRUE;
+ if ( IsFrmSelected() )
+ {
+ SwFlyFrm *pFly = FindFlyFrm();
+
+ if ( pFly->GetPrevLink() )
+ {
+ bDelFrom = FALSE;
+ const SwFrm *pPre = pFly->GetPrevLink();
+
+ Point aStart( pPre->Frm().Right(), pPre->Frm().Bottom());
+ Point aEnd(pFly->Frm().Pos());
+
+ if ( !pChainFrom )
+ {
+ pChainFrom = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd );
+ }
+ }
+ if ( pFly->GetNextLink() )
+ {
+ bDelTo = FALSE;
+ const SwFlyFrm *pNxt = pFly->GetNextLink();
+
+ Point aStart( pFly->Frm().Right(), pFly->Frm().Bottom());
+ Point aEnd(pNxt->Frm().Pos());
+
+ if ( !pChainTo )
+ {
+ pChainTo = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd );
+ }
+ }
+ }
+
+ if ( bDelFrom )
+ {
+ delete pChainFrom, pChainFrom = 0;
+ }
+
+ if ( bDelTo )
+ {
+ delete pChainTo, pChainTo = 0;
+ }
+}
+
+long SwFEShell::GetSectionWidth( SwFmt& rFmt ) const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ // Steht der Cursor z.Z. in einem SectionFrm?
+ if( pFrm && pFrm->IsInSct() )
+ {
+ SwSectionFrm* pSect = pFrm->FindSctFrm();
+ do
+ {
+ // Ist es der Gewuenschte?
+ if( pSect->GetRegisteredIn() == &rFmt )
+ return pSect->Frm().Width();
+ // fuer geschachtelte Bereiche
+ pSect = pSect->GetUpper()->FindSctFrm();
+ }
+ while( pSect );
+ }
+ SwClientIter aIter( rFmt );
+ SwClient *pLast = aIter.GoStart();
+ while ( pLast )
+ {
+ if ( pLast->IsA( TYPE(SwFrm) ) )
+ {
+ SwSectionFrm* pSct = (SwSectionFrm*)pLast;
+ if( !pSct->IsFollow() )
+ return pSct->Frm().Width();
+ }
+ pLast = aIter++;
+ }
+ return 0;
+}
+/* -----------------------------2002/06/24 15:07------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwFEShell::CreateDefaultShape( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, const Rectangle& rRect,
+ USHORT nSlotId)
+{
+ SdrView* pDrawView = GetDrawView();
+ SdrModel* pDrawModel = pDrawView->GetModel();
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(
+ SdrInventor, eSdrObjectKind,
+ 0L, pDrawModel);
+
+ if(pObj)
+ {
+ Rectangle aRect(rRect);
+ if(OBJ_CARC == eSdrObjectKind || OBJ_CCUT == eSdrObjectKind)
+ {
+ // force quadratic
+ if(aRect.GetWidth() > aRect.GetHeight())
+ {
+ aRect = Rectangle(
+ Point(aRect.Left() + ((aRect.GetWidth() - aRect.GetHeight()) / 2), aRect.Top()),
+ Size(aRect.GetHeight(), aRect.GetHeight()));
+ }
+ else
+ {
+ aRect = Rectangle(
+ Point(aRect.Left(), aRect.Top() + ((aRect.GetHeight() - aRect.GetWidth()) / 2)),
+ Size(aRect.GetWidth(), aRect.GetWidth()));
+ }
+ }
+ pObj->SetLogicRect(aRect);
+
+ if(pObj->ISA(SdrCircObj))
+ {
+ SfxItemSet aAttr(pDrawModel->GetItemPool());
+ aAttr.Put(SdrCircStartAngleItem(9000));
+ aAttr.Put(SdrCircEndAngleItem(0));
+ pObj->SetMergedItemSet(aAttr);
+ }
+ else if(pObj->ISA(SdrPathObj))
+ {
+ basegfx::B2DPolyPolygon aPoly;
+
+ switch(eSdrObjectKind)
+ {
+ case OBJ_PATHLINE:
+ {
+ basegfx::B2DPolygon aInnerPoly;
+
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
+
+ const basegfx::B2DPoint aCenterBottom(aRect.Center().X(), aRect.Bottom());
+ aInnerPoly.appendBezierSegment(
+ aCenterBottom,
+ aCenterBottom,
+ basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y()));
+
+ const basegfx::B2DPoint aCenterTop(aRect.Center().X(), aRect.Top());
+ aInnerPoly.appendBezierSegment(
+ aCenterTop,
+ aCenterTop,
+ basegfx::B2DPoint(aRect.Right(), aRect.Top()));
+
+ aInnerPoly.setClosed(true);
+ aPoly.append(aInnerPoly);
+ }
+ break;
+ case OBJ_FREELINE:
+ {
+ basegfx::B2DPolygon aInnerPoly;
+
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
+
+ aInnerPoly.appendBezierSegment(
+ basegfx::B2DPoint(aRect.Left(), aRect.Top()),
+ basegfx::B2DPoint(aRect.Center().X(), aRect.Top()),
+ basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y()));
+
+ aInnerPoly.appendBezierSegment(
+ basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()),
+ basegfx::B2DPoint(aRect.Right(), aRect.Bottom()),
+ basegfx::B2DPoint(aRect.Right(), aRect.Top()));
+
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Right(), aRect.Bottom()));
+ aInnerPoly.setClosed(true);
+ aPoly.append(aInnerPoly);
+ }
+ break;
+ case OBJ_POLY:
+ case OBJ_PLIN:
+ {
+ basegfx::B2DPolygon aInnerPoly;
+ sal_Int32 nWdt(aRect.GetWidth());
+ sal_Int32 nHgt(aRect.GetHeight());
+
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 30) / 100, aRect.Top() + (nHgt * 70) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Top() + (nHgt * 15) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 65) / 100, aRect.Top()));
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + nWdt, aRect.Top() + (nHgt * 30) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 50) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 75) / 100));
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Bottom(), aRect.Right()));
+
+ if(OBJ_PLIN == eSdrObjectKind)
+ {
+ aInnerPoly.append(basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()));
+ }
+ else
+ {
+ aInnerPoly.setClosed(true);
+ }
+
+ aPoly.append(aInnerPoly);
+ }
+ break;
+ case OBJ_LINE :
+ {
+ sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
+ basegfx::B2DPolygon aTempPoly;
+ aTempPoly.append(basegfx::B2DPoint(aRect.TopLeft().X(), nYMiddle));
+ aTempPoly.append(basegfx::B2DPoint(aRect.BottomRight().X(), nYMiddle));
+ aPoly.append(aTempPoly);
+ }
+ break;
+ }
+
+ ((SdrPathObj*)pObj)->SetPathPoly(aPoly);
+ }
+ else if(pObj->ISA(SdrCaptionObj))
+ {
+ BOOL bVerticalText = ( SID_DRAW_TEXT_VERTICAL == nSlotId ||
+ SID_DRAW_CAPTION_VERTICAL == nSlotId );
+ ((SdrTextObj*)pObj)->SetVerticalWriting(bVerticalText);
+ if(bVerticalText)
+ {
+ SfxItemSet aSet(pObj->GetMergedItemSet());
+ aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER));
+ aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
+ pObj->SetMergedItemSet(aSet);
+ }
+
+ ((SdrCaptionObj*)pObj)->SetLogicRect(aRect);
+ ((SdrCaptionObj*)pObj)->SetTailPos(
+ aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2));
+ }
+ else if(pObj->ISA(SdrTextObj))
+ {
+ SdrTextObj* pText = (SdrTextObj*)pObj;
+ pText->SetLogicRect(aRect);
+
+ sal_Bool bVertical = (SID_DRAW_TEXT_VERTICAL == nSlotId);
+ sal_Bool bMarquee = (SID_DRAW_TEXT_MARQUEE == nSlotId);
+
+ pText->SetVerticalWriting(bVertical);
+
+ if(bVertical)
+ {
+ SfxItemSet aSet(pDrawModel->GetItemPool());
+ aSet.Put(SdrTextAutoGrowWidthItem(TRUE));
+ aSet.Put(SdrTextAutoGrowHeightItem(FALSE));
+ aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
+ aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
+ pText->SetMergedItemSet(aSet);
+ }
+
+ if(bMarquee)
+ {
+ SfxItemSet aSet(pDrawModel->GetItemPool(), SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST);
+ aSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+ aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
+ aSet.Put( SdrTextAniKindItem( SDRTEXTANI_SLIDE ) );
+ aSet.Put( SdrTextAniDirectionItem( SDRTEXTANI_LEFT ) );
+ aSet.Put( SdrTextAniCountItem( 1 ) );
+ aSet.Put( SdrTextAniAmountItem( (INT16)GetWin()->PixelToLogic(Size(2,1)).Width()) );
+ pObj->SetMergedItemSetAndBroadcast(aSet);
+ }
+ }
+ SdrPageView* pPageView = pDrawView->GetSdrPageView();
+ pDrawView->InsertObjectAtView(pObj, *pPageView);
+ }
+ ImpEndCreate();
+}
+
+/** SwFEShell::GetShapeBackgrd
+
+ OD 02.09.2002 for #102450#:
+ method determines background color of the page the selected drawing
+ object is on and returns this color.
+ If no color is found, because no drawing object is selected or ...,
+ color COL_BLACK (default color on constructing object of class Color)
+ is returned.
+
+ @author OD
+
+ @returns an object of class Color
+*/
+const Color SwFEShell::GetShapeBackgrd() const
+{
+ Color aRetColor;
+
+ // check, if a draw view exists
+ ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!");
+ if( Imp()->GetDrawView() )
+ {
+ // determine list of selected objects
+ const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
+ // check, if exactly one object is selected.
+ ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!");
+ if ( pMrkList->GetMarkCount() == 1)
+ {
+ // get selected object
+ const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ // check, if selected object is a shape (drawing object)
+ ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!");
+ if ( !pSdrObj->ISA(SwVirtFlyDrawObj) )
+ {
+ // determine page frame of the frame the shape is anchored.
+ const SwFrm* pAnchorFrm =
+ static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj );
+ ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!");
+ if ( pAnchorFrm )
+ {
+ const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm();
+ ASSERT( pPageFrm, "inconsistent modell - no page!");
+ if ( pPageFrm )
+ {
+ aRetColor = pPageFrm->GetDrawBackgrdColor();
+ }
+ }
+ }
+ }
+ }
+
+ return aRetColor;
+}
+
+/** Is default horizontal text direction for selected drawing object right-to-left
+
+ OD 09.12.2002 #103045#
+ Because drawing objects only painted for each page only, the default
+ horizontal text direction of a drawing object is given by the corresponding
+ page property.
+
+ @author OD
+
+ @returns boolean, indicating, if the horizontal text direction of the
+ page, the selected drawing object is on, is right-to-left.
+*/
+bool SwFEShell::IsShapeDefaultHoriTextDirR2L() const
+{
+ bool bRet = false;
+
+ // check, if a draw view exists
+ ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!");
+ if( Imp()->GetDrawView() )
+ {
+ // determine list of selected objects
+ const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
+ // check, if exactly one object is selected.
+ ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!");
+ if ( pMrkList->GetMarkCount() == 1)
+ {
+ // get selected object
+ const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
+ // check, if selected object is a shape (drawing object)
+ ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!");
+ if ( !pSdrObj->ISA(SwVirtFlyDrawObj) )
+ {
+ // determine page frame of the frame the shape is anchored.
+ const SwFrm* pAnchorFrm =
+ static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj );
+ ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!");
+ if ( pAnchorFrm )
+ {
+ const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm();
+ ASSERT( pPageFrm, "inconsistent modell - no page!");
+ if ( pPageFrm )
+ {
+ bRet = pPageFrm->IsRightToLeft() ? true : false;
+ }
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+/* -----------------20.03.2003 14:35-----------------
+
+ --------------------------------------------------*/
+Point SwFEShell::GetRelativePagePosition(const Point& rDocPos)
+{
+ Point aRet(-1, -1);
+ const SwFrm *pPage = GetLayout()->Lower();
+ while ( pPage && !pPage->Frm().IsInside( rDocPos ) )
+ {
+ pPage = pPage->GetNext();
+ }
+ if(pPage)
+ {
+ aRet = rDocPos - pPage->Frm().TopLeft();
+ }
+ return aRet;
+}
+
diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx
new file mode 100644
index 000000000000..ad2e077e5d7c
--- /dev/null
+++ b/sw/source/core/frmedt/fetab.cxx
@@ -0,0 +1,2593 @@
+ /*************************************************************************
+ *
+ * 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 <tools/errinf.hxx>
+#include <vcl/svapp.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#ifndef _SVX_SVXIDS_HRC
+#include <svx/svxids.hrc>
+#endif
+#include <editeng/protitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svtools/ruler.hxx>
+#include <swwait.hxx>
+#include <fmtfsize.hxx>
+#include <fmtornt.hxx>
+#include <frmatr.hxx>
+#include <docary.hxx>
+#include <fesh.hxx>
+#include <doc.hxx>
+#include <cntfrm.hxx>
+#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <tabfrm.hxx>
+#include <rowfrm.hxx>
+#include <cellfrm.hxx>
+#include <flyfrm.hxx>
+#include <dflyobj.hxx>
+#include <swtable.hxx>
+#include <swddetbl.hxx>
+#include <ndtxt.hxx>
+#include <calc.hxx>
+#include <tabcol.hxx>
+#include <cellatr.hxx>
+#include <pam.hxx>
+#include <viscrs.hxx>
+#include <tblsel.hxx>
+#include <swtblfmt.hxx>
+#include <swerror.h>
+#include <swundo.hxx>
+#include <frmtool.hxx>
+
+#include <node.hxx> // #i23726#
+// OD 2004-05-24 #i28701#
+#include <sortedobjs.hxx>
+
+using namespace ::com::sun::star;
+
+
+//siehe auch swtable.cxx
+#define COLFUZZY 20L
+
+inline BOOL IsSame( long nA, long nB ) { return Abs(nA-nB) <= COLFUZZY; }
+inline BOOL IsNear( long nA, long nB, long nTolerance ) { return Abs( nA - nB ) <= nTolerance; }
+
+// table column cache
+SwTabCols *pLastCols = 0;
+const SwTable *pColumnCacheLastTable = 0;
+const SwTabFrm *pColumnCacheLastTabFrm = 0;
+const SwFrm *pColumnCacheLastCellFrm = 0;
+
+// table row cache
+SwTabCols *pLastRows = 0;
+const SwTable *pRowCacheLastTable = 0;
+const SwTabFrm *pRowCacheLastTabFrm = 0;
+const SwFrm *pRowCacheLastCellFrm = 0;
+
+
+class TblWait
+{
+ SwWait *pWait;
+public:
+ TblWait( USHORT nCnt, SwFrm *pFrm, SwDocShell &rDocShell, USHORT nCnt2 = 0);
+ ~TblWait() { delete pWait; }
+};
+
+TblWait::TblWait( USHORT nCnt, SwFrm *pFrm, SwDocShell &rDocShell, USHORT nCnt2):
+ pWait( 0 )
+{
+ BOOL bWait = 20 < nCnt || 20 < nCnt2 || (pFrm &&
+ 20 < pFrm->ImplFindTabFrm()->GetTable()->GetTabLines().Count());
+ if( bWait )
+ pWait = new SwWait( rDocShell, TRUE );
+}
+
+
+void SwFEShell::ParkCursorInTab()
+{
+ SwCursor * pSwCrsr = GetSwCrsr();
+
+ ASSERT(pSwCrsr, "no SwCursor");
+
+ SwPosition aStartPos = *pSwCrsr->GetPoint(), aEndPos = aStartPos;
+
+ SwCursor * pTmpCrsr = (SwCursor *) pSwCrsr;
+
+ /* Search least and greatest position in current cursor ring.
+ */
+ do
+ {
+ const SwPosition * pPt = pTmpCrsr->GetPoint(),
+ * pMk = pTmpCrsr->GetMark();
+
+ if (*pPt < aStartPos)
+ aStartPos = *pPt;
+
+ if (*pPt > aEndPos)
+ aEndPos = *pPt;
+
+ if (*pMk < aStartPos)
+ aStartPos = *pMk;
+
+ if (*pMk > aEndPos)
+ aEndPos = *pMk;
+
+ pTmpCrsr = (SwCursor *) pTmpCrsr->GetNext();
+ }
+ while (pTmpCrsr != pSwCrsr);
+
+ KillPams();
+
+ /* @@@ semantic: SwCursor::operator=() is not implemented @@@ */
+
+ /* Set cursor to end of selection to ensure IsLastCellInRow works
+ properly. */
+ {
+ SwCursor aTmpCrsr( aEndPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ }
+
+ /* Move the cursor out of the columns to delete and stay in the
+ same row. If the table has only one column the cursor will
+ stay in the row and the shell will take care of it. */
+ if (IsLastCellInRow())
+ {
+ /* If the cursor is in the last row of the table, first
+ try to move it to the previous cell. If that fails move
+ it to the next cell. */
+
+ {
+ SwCursor aTmpCrsr( aStartPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ }
+
+ if (! pSwCrsr->GoPrevCell())
+ {
+ SwCursor aTmpCrsr( aEndPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ pSwCrsr->GoNextCell();
+ }
+ }
+ else
+ {
+ /* If the cursor is not in the last row of the table, first
+ try to move it to the next cell. If that fails move it
+ to the previous cell. */
+
+ {
+ SwCursor aTmpCrsr( aEndPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ }
+
+ if (! pSwCrsr->GoNextCell())
+ {
+ SwCursor aTmpCrsr( aStartPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ pSwCrsr->GoPrevCell();
+ }
+ }
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : InsertRow(), InsertCol
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+BOOL SwFEShell::InsertRow( USHORT nCnt, BOOL bBehind )
+{
+ // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
+
+ TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+ BOOL bRet = FALSE;
+ if ( aBoxes.Count() )
+ bRet = GetDoc()->InsertRow( aBoxes, nCnt, bBehind );
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+BOOL SwFEShell::InsertCol( USHORT nCnt, BOOL bBehind )
+{
+ // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+
+ if( !CheckSplitCells( *this, nCnt + 1, nsSwTblSearchType::TBLSEARCH_COL ) )
+ {
+ ErrorHandler::HandleError( ERR_TBLINSCOL_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ StartAllAction();
+ // lasse ueber das Layout die Boxen suchen
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
+
+ TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+ BOOL bRet = FALSE;
+ if( aBoxes.Count() )
+ bRet = GetDoc()->InsertCol( aBoxes, nCnt, bBehind );
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : DeleteRow(), DeleteCol()
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+
+/**
+ Determines if the current cursor is in the last row of the table.
+*/
+BOOL SwFEShell::IsLastCellInRow() const
+{
+ SwTabCols aTabCols;
+ GetTabCols( aTabCols );
+ BOOL bResult = FALSE;
+
+ if (IsTableRightToLeft())
+ /* If the table is right-to-left the last row is the most left one. */
+ bResult = 0 == GetCurTabColNum();
+ else
+ /* If the table is left-to-right the last row is the most right one. */
+ bResult = aTabCols.Count() == GetCurTabColNum();
+
+ return bResult;
+}
+
+BOOL SwFEShell::DeleteCol()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
+ if ( aBoxes.Count() )
+ {
+ TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+ // die Crsr muessen noch aus dem Loesch Bereich entfernt
+ // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+ // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+ while( !pFrm->IsCellFrm() )
+ pFrm = pFrm->GetUpper();
+
+ ParkCursorInTab();
+
+ // dann loesche doch die Spalten
+ StartUndo(UNDO_COL_DELETE);
+ bRet = GetDoc()->DeleteRowCol( aBoxes, true );
+ EndUndo(UNDO_COL_DELETE);
+
+ }
+ else
+ bRet = FALSE;
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+BOOL SwFEShell::DeleteRow()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
+
+ if( aBoxes.Count() )
+ {
+ TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+ // die Crsr aus dem Loeschbereich entfernen.
+ // Der Cursor steht danach:
+ // - es folgt noch eine Zeile, in dieser
+ // - vorher steht noch eine Zeile, in dieser
+ // - sonst immer dahinter
+ {
+ SwTableNode* pTblNd = ((SwCntntFrm*)pFrm)->GetNode()->FindTableNode();
+
+ // suche alle Boxen / Lines
+ _FndBox aFndBox( 0, 0 );
+ {
+ _FndPara aPara( aBoxes, &aFndBox );
+ pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+ }
+
+ if( !aFndBox.GetLines().Count() )
+ {
+ EndAllActionAndCall();
+ return FALSE;
+ }
+
+ KillPams();
+
+ _FndBox* pFndBox = &aFndBox;
+ while( 1 == pFndBox->GetLines().Count() &&
+ 1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
+ {
+ _FndBox* pTmp = pFndBox->GetLines()[0]->GetBoxes()[0];
+ if( pTmp->GetBox()->GetSttNd() )
+ break; // das ist sonst zu weit
+ pFndBox = pTmp;
+ }
+
+ SwTableLine* pDelLine = pFndBox->GetLines()[
+ pFndBox->GetLines().Count()-1 ]->GetLine();
+ SwTableBox* pDelBox = pDelLine->GetTabBoxes()[
+ pDelLine->GetTabBoxes().Count() - 1 ];
+ while( !pDelBox->GetSttNd() )
+ {
+ SwTableLine* pLn = pDelBox->GetTabLines()[
+ pDelBox->GetTabLines().Count()-1 ];
+ pDelBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
+ }
+ SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(),
+ pDelBox, TRUE );
+ while( pNextBox &&
+ pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox );
+
+ if( !pNextBox ) // keine nachfolgende? dann die vorhergehende
+ {
+ pDelLine = pFndBox->GetLines()[ 0 ]->GetLine();
+ pDelBox = pDelLine->GetTabBoxes()[ 0 ];
+ while( !pDelBox->GetSttNd() )
+ pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
+ pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(),
+ pDelBox, TRUE );
+ while( pNextBox &&
+ pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox );
+ }
+
+ ULONG nIdx;
+ if( pNextBox ) // dann den Cursor hier hinein
+ nIdx = pNextBox->GetSttIdx() + 1;
+ else // ansonsten hinter die Tabelle
+ nIdx = pTblNd->EndOfSectionIndex() + 1;
+
+ SwNodeIndex aIdx( GetDoc()->GetNodes(), nIdx );
+ SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+ if( !pCNd )
+ pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
+
+ if( pCNd )
+ {
+ SwPaM* pPam = GetCrsr();
+ pPam->GetPoint()->nNode = aIdx;
+ pPam->GetPoint()->nContent.Assign( pCNd, 0 );
+ pPam->SetMark(); // beide wollen etwas davon haben
+ pPam->DeleteMark();
+ }
+ }
+
+ // dann loesche doch die Zeilen
+ StartUndo(UNDO_ROW_DELETE);
+ bRet = GetDoc()->DeleteRowCol( aBoxes );
+ EndUndo(UNDO_ROW_DELETE);
+ }
+ else
+ bRet = FALSE;
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : MergeTab(), SplitTab()
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+
+USHORT SwFEShell::MergeTab()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ USHORT nRet = TBLMERGE_NOSELECTION;
+ if( IsTableMode() )
+ {
+ SwShellTableCrsr* pTableCrsr = GetTableCrsr();
+ const SwTableNode* pTblNd = pTableCrsr->GetNode()->FindTableNode();
+ if( pTblNd->GetTable().ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ }
+ else
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ TblWait( pTableCrsr->GetBoxesCount(), 0, *GetDoc()->GetDocShell(),
+ pTblNd->GetTable().GetTabLines().Count() );
+
+ nRet = GetDoc()->MergeTbl( *pTableCrsr );
+
+ KillPams();
+
+ EndAllActionAndCall();
+ }
+ }
+ return nRet;
+}
+
+BOOL SwFEShell::SplitTab( BOOL bVert, USHORT nCnt, BOOL bSameHeight )
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+
+ if( bVert && !CheckSplitCells( *this, nCnt + 1 ) )
+ {
+ ErrorHandler::HandleError( ERR_TBLSPLIT_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+ StartAllAction();
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes );
+ if( aBoxes.Count() )
+ {
+ TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+ // dann loesche doch die Spalten
+ bRet = GetDoc()->SplitTbl( aBoxes, bVert, nCnt, bSameHeight );
+
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+ }
+ else
+ bRet = FALSE;
+ EndAllActionAndCall();
+ return bRet;
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : _GetTabCols
+#* Datum : MA 30. Nov. 95
+#* Update : MA 08. Jan. 97
+#***********************************************************************/
+void SwFEShell::_GetTabCols( SwTabCols &rToFill, const SwFrm *pBox ) const
+{
+ const SwTabFrm *pTab = pBox->FindTabFrm();
+ if ( pLastCols )
+ {
+ //Paar Kleinigkeiten muessen wir schon noch sicherstellen
+ BOOL bDel = TRUE;
+ if ( pColumnCacheLastTable == pTab->GetTable() )
+ {
+ bDel = FALSE;
+ SWRECTFN( pTab )
+
+ const SwPageFrm* pPage = pTab->FindPageFrm();
+ const ULONG nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() -
+ (pPage->Frm().*fnRect->fnGetLeft)();
+ const ULONG nRightMax = (pTab->Frm().*fnRect->fnGetRight)() -
+ (pPage->Frm().*fnRect->fnGetLeft)();
+
+ if ( pColumnCacheLastTabFrm != pTab )
+ {
+ //Wenn der TabFrm gewechselt hat, brauchen wir bei gleicher
+ //Breite nur ein wenig shiften.
+ SWRECTFNX( pColumnCacheLastTabFrm )
+ if( (pColumnCacheLastTabFrm->Frm().*fnRectX->fnGetWidth)() ==
+ (pTab->Frm().*fnRect->fnGetWidth)() )
+ {
+ pLastCols->SetLeftMin( nLeftMin );
+
+ //ASSERT( bVert ||
+ // pLastCols->GetLeftMin() == (pTab->Frm().*fnRect->fnGetLeft)(),
+ // "GetTabCols: wrong result" )
+
+ pColumnCacheLastTabFrm = pTab;
+ }
+ else
+ bDel = TRUE;
+ }
+
+ if ( !bDel &&
+ pLastCols->GetLeftMin () == (USHORT)nLeftMin &&
+ pLastCols->GetLeft () == (USHORT)(pTab->Prt().*fnRect->fnGetLeft)() &&
+ pLastCols->GetRight () == (USHORT)(pTab->Prt().*fnRect->fnGetRight)()&&
+ pLastCols->GetRightMax() == (USHORT)nRightMax - pLastCols->GetLeftMin() )
+ {
+ if ( pColumnCacheLastCellFrm != pBox )
+ {
+ pTab->GetTable()->GetTabCols( *pLastCols,
+ ((SwCellFrm*)pBox)->GetTabBox(), TRUE);
+ pColumnCacheLastCellFrm = pBox;
+ }
+ rToFill = *pLastCols;
+ }
+ else
+ bDel = TRUE;
+ }
+ if ( bDel )
+ DELETEZ(pLastCols);
+ }
+ if ( !pLastCols )
+ {
+ GetDoc()->GetTabCols( rToFill, 0, (SwCellFrm*)pBox );
+
+ pLastCols = new SwTabCols( rToFill );
+ pColumnCacheLastTable = pTab->GetTable();
+ pColumnCacheLastTabFrm = pTab;
+ pColumnCacheLastCellFrm= pBox;
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ SwTabColsEntry aEntry;
+ for ( USHORT i = 0; i < rToFill.Count(); ++i )
+ {
+ aEntry = rToFill.GetEntry( i );
+ (void)aEntry;
+ }
+#endif
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : _GetTabRows
+#* Datum : FME 2004-01-14
+#* Update :
+#***********************************************************************/
+void SwFEShell::_GetTabRows( SwTabCols &rToFill, const SwFrm *pBox ) const
+{
+ const SwTabFrm *pTab = pBox->FindTabFrm();
+ if ( pLastRows )
+ {
+ //Paar Kleinigkeiten muessen wir schon noch sicherstellen
+ BOOL bDel = TRUE;
+ if ( pRowCacheLastTable == pTab->GetTable() )
+ {
+ bDel = FALSE;
+ SWRECTFN( pTab )
+ const SwPageFrm* pPage = pTab->FindPageFrm();
+ const long nLeftMin = ( bVert ?
+ pTab->GetPrtLeft() - pPage->Frm().Left() :
+ pTab->GetPrtTop() - pPage->Frm().Top() );
+ const long nLeft = bVert ? LONG_MAX : 0;
+ const long nRight = (pTab->Prt().*fnRect->fnGetHeight)();
+ const long nRightMax = bVert ? nRight : LONG_MAX;
+
+ if ( pRowCacheLastTabFrm != pTab ||
+ pRowCacheLastCellFrm != pBox )
+ bDel = TRUE;
+
+ if ( !bDel &&
+ pLastRows->GetLeftMin () == nLeftMin &&
+ pLastRows->GetLeft () == nLeft &&
+ pLastRows->GetRight () == nRight &&
+ pLastRows->GetRightMax() == nRightMax )
+ {
+ rToFill = *pLastRows;
+ }
+ else
+ bDel = TRUE;
+ }
+ if ( bDel )
+ DELETEZ(pLastRows);
+ }
+ if ( !pLastRows )
+ {
+ GetDoc()->GetTabRows( rToFill, 0, (SwCellFrm*)pBox );
+
+ pLastRows = new SwTabCols( rToFill );
+ pRowCacheLastTable = pTab->GetTable();
+ pRowCacheLastTabFrm = pTab;
+ pRowCacheLastCellFrm= pBox;
+ }
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetTabCols(), GetTabCols()
+#* Datum : MA 03. May. 93
+#* Update : MA 18. May. 93
+#***********************************************************************/
+void SwFEShell::SetTabCols( const SwTabCols &rNew, BOOL bCurRowOnly )
+{
+ SwFrm *pBox = GetCurrFrm();
+ if( !pBox || !pBox->IsInTab() )
+ return;
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ do {
+ pBox = pBox->GetUpper();
+ } while ( !pBox->IsCellFrm() );
+
+ GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::GetTabCols( SwTabCols &rToFill ) const
+{
+ const SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return;
+ do
+ { pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+
+ _GetTabCols( rToFill, pFrm );
+}
+
+/*-- 19.01.2004 08:56:42---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::GetTabRows( SwTabCols &rToFill ) const
+{
+ const SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return;
+ do
+ { pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+
+ _GetTabRows( rToFill, pFrm );
+}
+/*-- 19.01.2004 08:56:44---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::SetTabRows( const SwTabCols &rNew, BOOL bCurColOnly )
+{
+ SwFrm *pBox = GetCurrFrm();
+ if( !pBox || !pBox->IsInTab() )
+ return;
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ do {
+ pBox = pBox->GetUpper();
+ } while ( !pBox->IsCellFrm() );
+
+ GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+}
+/*-- 19.01.2004 08:59:45---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::GetMouseTabRows( SwTabCols &rToFill, const Point &rPt ) const
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if ( pBox )
+ _GetTabRows( rToFill, pBox );
+}
+/*-- 19.01.2004 08:59:45---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::SetMouseTabRows( const SwTabCols &rNew, BOOL bCurColOnly, const Point &rPt )
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if( pBox )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+ }
+}
+
+/***********************************************************************
+ * Class : SwFEShell
+ * Methoden : SetRowSplit(), GetRowSplit()
+ * Datum : FME 13.11.2003
+ ***********************************************************************/
+
+void SwFEShell::SetRowSplit( const SwFmtRowSplit& rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowSplit( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::GetRowSplit( SwFmtRowSplit*& rpSz ) const
+{
+ GetDoc()->GetRowSplit( *getShellCrsr( false ), rpSz );
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetRowHeight(), GetRowHeight()
+#* Datum : MA 17. May. 93
+#* Update : JP 29.04.98
+#***********************************************************************/
+
+void SwFEShell::SetRowHeight( const SwFmtFrmSize &rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowHeight( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+/******************************************************************************
+ * SwTwips SwFEShell::GetRowHeight() const
+ ******************************************************************************/
+void SwFEShell::GetRowHeight( SwFmtFrmSize *& rpSz ) const
+{
+ GetDoc()->GetRowHeight( *getShellCrsr( false ), rpSz );
+}
+
+BOOL SwFEShell::BalanceRowHeight( BOOL bTstOnly )
+{
+ SET_CURR_SHELL( this );
+ if( !bTstOnly )
+ StartAllAction();
+ BOOL bRet = GetDoc()->BalanceRowHeight( *getShellCrsr( false ), bTstOnly );
+ if( !bTstOnly )
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/******************************************************************************
+ * void SwFEShell::SetRowBackground()
+ ******************************************************************************/
+void SwFEShell::SetRowBackground( const SvxBrushItem &rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowBackground( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+/******************************************************************************
+ * SwTwips SwFEShell::GetRowBackground() const
+ ******************************************************************************/
+BOOL SwFEShell::GetRowBackground( SvxBrushItem &rToFill ) const
+{
+ return GetDoc()->GetRowBackground( *getShellCrsr( false ), rToFill );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetTabBorders(), GetTabBorders()
+#* Datum : MA 18. May. 93
+#* Update : JP 29.04.98
+#***********************************************************************/
+
+void SwFEShell::SetTabBorders( const SfxItemSet& rSet )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabBorders( *getShellCrsr( false ), rSet );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::SetTabLineStyle( const Color* pColor, BOOL bSetLine,
+ const SvxBorderLine* pBorderLine )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabLineStyle( *getShellCrsr( false ),
+ pColor, bSetLine, pBorderLine );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::GetTabBorders( SfxItemSet& rSet ) const
+{
+ GetDoc()->GetTabBorders( *getShellCrsr( false ), rSet );
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetBoxBackground(), GetBoxBackground()
+#* Datum : MA 01. Jun. 93
+#* Update : MA 03. Jul. 96
+#***********************************************************************/
+void SwFEShell::SetBoxBackground( const SvxBrushItem &rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::GetBoxBackground( SvxBrushItem &rToFill ) const
+{
+ return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetBoxDirection(), GetBoxDirection()
+#* Datum : FME 2004-02-03
+#* Update : FME 2004-02-03
+#***********************************************************************/
+void SwFEShell::SetBoxDirection( const SvxFrameDirectionItem& rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::GetBoxDirection( SvxFrameDirectionItem& rToFill ) const
+{
+ return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetBoxAlign, SetBoxAlign
+#* Datum : MA 18. Dec. 96
+#* Update : JP 29.04.98
+#***********************************************************************/
+void SwFEShell::SetBoxAlign( USHORT nAlign )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetBoxAlign( *getShellCrsr( false ), nAlign );
+ EndAllActionAndCall();
+}
+
+USHORT SwFEShell::GetBoxAlign() const
+{
+ return GetDoc()->GetBoxAlign( *getShellCrsr( false ) );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetTabBackground(), GetTabBackground()
+#* Datum : MA 08. Jul. 96
+#* Update : MA 08. Jul. 96
+#***********************************************************************/
+void SwFEShell::SetTabBackground( const SvxBrushItem &rNew )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return;
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetAttr( rNew, *pFrm->ImplFindTabFrm()->GetFmt() );
+ EndAllAction(); //Kein Call, denn es veraendert sich nichts!
+ GetDoc()->SetModified();
+}
+
+void SwFEShell::GetTabBackground( SvxBrushItem &rToFill ) const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( pFrm && pFrm->IsInTab() )
+ rToFill = pFrm->ImplFindTabFrm()->GetFmt()->GetBackground();
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : HasWholeTabSelection()
+#* Datum : MA 18. May. 93
+#* Update : MA 20. Jul. 93
+#***********************************************************************/
+BOOL SwFEShell::HasWholeTabSelection() const
+{
+ //Ist die ganze Tabelle Selektiert?
+ if ( IsTableMode() )
+ {
+ SwSelBoxes aBoxes;
+ ::GetTblSelCrs( *this, aBoxes );
+ if( aBoxes.Count() )
+ {
+ const SwTableNode *pTblNd = IsCrsrInTbl();
+ return ( pTblNd && aBoxes[0]->GetSttIdx()-1 == pTblNd->
+ EndOfSectionNode()->StartOfSectionIndex() &&
+ aBoxes[aBoxes.Count()-1]->GetSttNd()->EndOfSectionIndex()+1
+ == pTblNd->EndOfSectionIndex() );
+ }
+ }
+ return FALSE;
+}
+
+BOOL SwFEShell::HasBoxSelection() const
+{
+ if(!IsCrsrInTbl())
+ return FALSE;
+ //Ist die ganze Tabelle Selektiert?
+ if( IsTableMode() )
+ return TRUE;
+ SwPaM* pPam = GetCrsr();
+ // leere Boxen gelten auch ohne Selektion als selektiert
+// if( !pPam->HasMark() )
+// return FALSE;
+ BOOL bChg = FALSE;
+ if( pPam->GetPoint() == pPam->End())
+ {
+ bChg = TRUE;
+ pPam->Exchange();
+ }
+ SwNode* pNd;
+ if( pPam->GetPoint()->nNode.GetIndex() -1 ==
+ ( pNd = pPam->GetNode())->StartOfSectionIndex() &&
+ !pPam->GetPoint()->nContent.GetIndex() &&
+ pPam->GetMark()->nNode.GetIndex() + 1 ==
+ pNd->EndOfSectionIndex())
+ {
+ SwNodeIndex aIdx( *pNd->EndOfSectionNode(), -1 );
+ SwCntntNode* pCNd = GetDoc()->GetNodes()[ aIdx ]->GetCntntNode();
+ if( !pCNd )
+ {
+ pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx );
+ ASSERT( pCNd, "kein ContentNode in der Box ??" );
+ }
+ if( pPam->GetMark()->nContent == pCNd->Len() )
+ {
+ if( bChg )
+ pPam->Exchange();
+ return TRUE;
+ }
+ }
+ if( bChg )
+ pPam->Exchange();
+ return FALSE;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : ProtectCells(), UnProtectCells()
+#* Datum : MA 20. Jul. 93
+#* Update : JP 25. Sep. 93
+#***********************************************************************/
+void SwFEShell::ProtectCells()
+{
+ SvxProtectItem aProt( RES_PROTECT );
+ aProt.SetCntntProtect( TRUE );
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ GetDoc()->SetBoxAttr( *getShellCrsr( false ), aProt );
+
+ if( !IsCrsrReadonly() )
+ {
+ if( IsTableMode() )
+ ClearMark();
+ ParkCursorInTab();
+ }
+ EndAllActionAndCall();
+}
+
+// die Tabellenselektion aufheben
+void SwFEShell::UnProtectCells()
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ SwSelBoxes aBoxes;
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if( pFrm )
+ {
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+ }
+
+ if( aBoxes.Count() )
+ GetDoc()->UnProtectCells( aBoxes );
+
+ EndAllActionAndCall();
+}
+
+void SwFEShell::UnProtectTbls()
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->UnProtectTbls( *GetCrsr() );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::HasTblAnyProtection( const String* pTblName,
+ BOOL* pFullTblProtection )
+{
+ return GetDoc()->HasTblAnyProtection( GetCrsr()->GetPoint(), pTblName,
+ pFullTblProtection );
+}
+
+BOOL SwFEShell::CanUnProtectCells() const
+{
+ BOOL bUnProtectAvailable = FALSE;
+ const SwTableNode *pTblNd = IsCrsrInTbl();
+ if( pTblNd && !pTblNd->IsProtect() )
+ {
+ SwSelBoxes aBoxes;
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if( pFrm )
+ {
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+ }
+ if( aBoxes.Count() )
+ bUnProtectAvailable = ::HasProtectedCells( aBoxes );
+ }
+ return bUnProtectAvailable;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : GetRowsToRepeat(), SetRowsToRepeat()
+#***********************************************************************/
+USHORT SwFEShell::GetRowsToRepeat() const
+{
+ const SwFrm *pFrm = GetCurrFrm();
+ const SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0;
+ if( pTab )
+ return pTab->GetTable()->GetRowsToRepeat();
+ return 0;
+}
+
+void SwFEShell::SetRowsToRepeat( USHORT nSet )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0;
+ if( pTab && pTab->GetTable()->GetRowsToRepeat() != nSet )
+ {
+ SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowsToRepeat( *pTab->GetTable(), nSet );
+ EndAllActionAndCall();
+ }
+}
+/*-- 30.06.2004 08:46:35---------------------------------------------------
+ returns the number of rows consecutively selected from top
+ -----------------------------------------------------------------------*/
+USHORT lcl_GetRowNumber( const SwPosition& rPos )
+{
+ USHORT nRet = USHRT_MAX;
+ Point aTmpPt;
+ const SwCntntNode *pNd;
+ const SwCntntFrm *pFrm;
+
+ if( 0 != ( pNd = rPos.nNode.GetNode().GetCntntNode() ))
+ pFrm = pNd->GetFrm( &aTmpPt, &rPos, FALSE );
+ else
+ pFrm = 0;
+
+ if ( pFrm && pFrm->IsInTab() )
+ {
+ const SwFrm* pRow = pFrm->GetUpper();
+ while ( !pRow->GetUpper()->IsTabFrm() )
+ pRow = pRow->GetUpper();
+
+ const SwTabFrm* pTabFrm = (const SwTabFrm*)pRow->GetUpper();
+ const SwTableLine* pTabLine = static_cast<const SwRowFrm*>(pRow)->GetTabLine();
+
+ USHORT nI = 0;
+ while ( nI < pTabFrm->GetTable()->GetTabLines().Count() )
+ {
+ if ( pTabFrm->GetTable()->GetTabLines()[ nI ] == pTabLine )
+ {
+ nRet = nI;
+ break;
+ }
+ ++nI;
+ }
+ }
+
+ return nRet;
+}
+USHORT SwFEShell::GetRowSelectionFromTop() const
+{
+ USHORT nRet = 0;
+ const SwPaM* pPaM = IsTableMode() ? GetTableCrsr() : _GetCrsr();
+ const USHORT nPtLine = lcl_GetRowNumber( *pPaM->GetPoint() );
+
+ if ( !IsTableMode() )
+ {
+ nRet = 0 == nPtLine ? 1 : 0;
+ }
+ else
+ {
+ const USHORT nMkLine = lcl_GetRowNumber( *pPaM->GetMark() );
+
+ if ( ( nPtLine == 0 && nMkLine != USHRT_MAX ) ||
+ ( nMkLine == 0 && nPtLine != USHRT_MAX ) )
+ {
+ nRet = Max( nPtLine, nMkLine ) + 1;
+ }
+ }
+
+ return nRet;
+}
+
+/*
+ * 1. case: bRepeat = true
+ * returns true if the current frame is located inside a table headline in
+ * a follow frame
+ *
+ * 2. case: bRepeat = false
+ * returns true if the current frame is localed inside a table headline OR
+ * inside the first line of a table!!!
+ */
+BOOL SwFEShell::CheckHeadline( bool bRepeat ) const
+{
+ BOOL bRet = FALSE;
+ if ( !IsTableMode() )
+ {
+ SwFrm *pFrm = GetCurrFrm(); // DONE MULTIIHEADER
+ if ( pFrm && pFrm->IsInTab() )
+ {
+ SwTabFrm* pTab = pFrm->FindTabFrm();
+ if ( bRepeat )
+ {
+ bRet = pTab->IsFollow() && pTab->IsInHeadline( *pFrm );
+ }
+ else
+ {
+ bRet = ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pFrm ) ||
+ pTab->IsInHeadline( *pFrm );
+ }
+ }
+ }
+ return bRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : AdjustCellWidth()
+#* Datum : MA 20. Feb. 95
+#* Update : MA 27. Jul. 95
+#***********************************************************************/
+
+void SwFEShell::AdjustCellWidth( BOOL bBalance )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ //WarteCrsr immer einschalten, weil sich im vorraus nicht so recht
+ //ermitteln laesst wieviel Inhalt betroffen ist.
+ TblWait aWait( USHRT_MAX, 0, *GetDoc()->GetDocShell() );
+
+ GetDoc()->AdjustCellWidth( *getShellCrsr( false ), bBalance );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::IsAdjustCellWidthAllowed( BOOL bBalance ) const
+{
+ //Es muss mindestens eine Zelle mit Inhalt in der Selektion enthalten
+ //sein.
+
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ SwSelBoxes aBoxes;
+ ::GetTblSelCrs( *this, aBoxes );
+
+ if ( bBalance )
+ return aBoxes.Count() > 1;
+
+ if ( !aBoxes.Count() )
+ {
+ do
+ { pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+
+ for ( USHORT i = 0; i < aBoxes.Count(); ++i )
+ {
+ SwTableBox *pBox = aBoxes[i];
+ if ( pBox->GetSttNd() )
+ {
+ SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
+ SwTxtNode* pCNd = aIdx.GetNode().GetTxtNode();
+ if( !pCNd )
+ pCNd = (SwTxtNode*)GetDoc()->GetNodes().GoNext( &aIdx );
+
+ while ( pCNd )
+ {
+ if ( pCNd->GetTxt().Len() )
+ return TRUE;
+ ++aIdx;
+ pCNd = GetDoc()->GetNodes()[ aIdx ]->GetTxtNode();
+ }
+ }
+ }
+ return FALSE;
+}
+
+ // AutoFormat fuer die Tabelle/TabellenSelection
+BOOL SwFEShell::SetTableAutoFmt( const SwTableAutoFmt& rNew )
+{
+ SwTableNode *pTblNd = (SwTableNode*)IsCrsrInTbl();
+ if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
+ return FALSE;
+
+ SwSelBoxes aBoxes;
+
+ if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind
+ GetCrsr();
+
+ // gesamte Tabelle oder nur auf die akt. Selektion
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
+ for( USHORT n = 0; n < rTBoxes.Count(); ++n )
+ {
+ SwTableBox* pBox = rTBoxes[ n ];
+ aBoxes.Insert( pBox );
+ }
+ }
+
+ BOOL bRet;
+ if( aBoxes.Count() )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ bRet = GetDoc()->SetTableAutoFmt( aBoxes, rNew );
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+ EndAllActionAndCall();
+ }
+ else
+ bRet = FALSE;
+ return bRet;
+}
+
+BOOL SwFEShell::GetTableAutoFmt( SwTableAutoFmt& rGet )
+{
+ const SwTableNode *pTblNd = IsCrsrInTbl();
+ if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
+ return FALSE;
+
+ SwSelBoxes aBoxes;
+
+ if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind
+ GetCrsr();
+
+ // gesamte Tabelle oder nur auf die akt. Selektion
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
+ for( USHORT n = 0; n < rTBoxes.Count(); ++n )
+ {
+ SwTableBox* pBox = rTBoxes[ n ];
+ aBoxes.Insert( pBox );
+ }
+ }
+
+ return GetDoc()->GetTableAutoFmt( aBoxes, rGet );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : DeleteTblSel()
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+BOOL SwFEShell::DeleteTblSel()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSelCrs( *this, aBoxes );
+ if( aBoxes.Count() )
+ {
+ TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+ // die Crsr muessen noch aus dem Loesch Bereich entfernt
+ // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+ // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+ while( !pFrm->IsCellFrm() )
+ pFrm = pFrm->GetUpper();
+ ParkCrsr( SwNodeIndex( *((SwCellFrm*)pFrm)->GetTabBox()->GetSttNd() ));
+
+ bRet = GetDoc()->DeleteRowCol( aBoxes );
+
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+ }
+ else
+ bRet = FALSE;
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetCurTabColNum()
+|*
+|* Ersterstellung MA 03. Feb. 95
+|* Letzte Aenderung MA 21. May. 95
+|
+|*************************************************************************/
+USHORT SwFEShell::GetCurTabColNum() const
+{
+ //!!!GetCurMouseTabColNum() mitpflegen!!!!
+ USHORT nRet = 0;
+
+ SwFrm *pFrm = GetCurrFrm();
+ ASSERT( pFrm, "Crsr geparkt?" );
+
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ if( pFrm && pFrm->IsInTab() )
+ {
+ do { // JP 26.09.95: warum mit dem CntntFrame und nicht mit
+ // dem CellFrame vergleichen????
+ pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+ SWRECTFN( pFrm )
+
+ const SwPageFrm* pPage = pFrm->FindPageFrm();
+
+ //TabCols besorgen, den nur ueber diese erreichen wir die Position.
+ SwTabCols aTabCols;
+ GetTabCols( aTabCols );
+
+ if( pFrm->FindTabFrm()->IsRightToLeft() )
+ {
+ long nX = (pFrm->Frm().*fnRect->fnGetRight)() - (pPage->Frm().*fnRect->fnGetLeft)();
+
+ const long nRight = aTabCols.GetLeftMin() + aTabCols.GetRight();;
+
+ if ( !::IsSame( nX, nRight ) )
+ {
+ nX = nRight - nX + aTabCols.GetLeft();
+ for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+ if ( ::IsSame( nX, aTabCols[i] ) )
+ {
+ nRet = i + 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ const long nX = (pFrm->Frm().*fnRect->fnGetLeft)() -
+ (pPage->Frm().*fnRect->fnGetLeft)();
+
+ const long nLeft = aTabCols.GetLeftMin();
+
+ if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
+ {
+ for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+ if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
+ {
+ nRet = i + 1;
+ break;
+ }
+ }
+ }
+ }
+ return nRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetBox()
+|*
+|* Ersterstellung MA 22. Jun. 95
+|* Letzte Aenderung MA 21. Nov. 96
+|*
+|*************************************************************************/
+
+const SwFrm *lcl_FindFrmInTab( const SwLayoutFrm *pLay, const Point &rPt, SwTwips nFuzzy )
+{
+ const SwFrm *pFrm = pLay->Lower();
+
+ while( pFrm && pLay->IsAnLower( pFrm ) )
+ {
+ if ( pFrm->Frm().IsNear( rPt, nFuzzy ) )
+ {
+ if ( pFrm->IsLayoutFrm() )
+ {
+ const SwFrm *pTmp = ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, rPt, nFuzzy );
+ if ( pTmp )
+ return pTmp;
+ }
+
+ return pFrm;
+ }
+
+ pFrm = pFrm->FindNext();
+ }
+
+ return 0;
+}
+
+const SwCellFrm *lcl_FindFrm( const SwLayoutFrm *pLay, const Point &rPt,
+ SwTwips nFuzzy, bool* pbRow, bool* pbCol )
+{
+ // bMouseMoveRowCols :
+ // Method is called for
+ // - Moving columns/rows with the mouse or
+ // - Enhanced table selection
+ const bool bMouseMoveRowCols = 0 == pbCol;
+
+ bool bCloseToRow = false;
+ bool bCloseToCol = false;
+
+ const SwFrm *pFrm = pLay->ContainsCntnt();
+ const SwFrm* pRet = 0;
+
+ if ( pFrm )
+ {
+ do
+ {
+ if ( pFrm->IsInTab() )
+ pFrm = ((SwFrm*)pFrm)->ImplFindTabFrm();
+
+ if ( pFrm->IsTabFrm() )
+ {
+ Point aPt( rPt );
+ bool bSearchForFrmInTab = true;
+ SwTwips nTmpFuzzy = nFuzzy;
+
+ if ( !bMouseMoveRowCols )
+ {
+ // We ignore nested tables for the enhanced table selection:
+ while ( pFrm->GetUpper()->IsInTab() )
+ pFrm = pFrm->GetUpper()->FindTabFrm();
+
+ // We first check if the given point is 'close' to the left or top
+ // border of the table frame:
+ ASSERT( pFrm, "Nested table frame without outer table" )
+ SWRECTFN( pFrm )
+ const bool bRTL = pFrm->IsRightToLeft();
+
+ SwRect aTabRect = pFrm->Prt();
+ aTabRect.Pos() += pFrm->Frm().Pos();
+
+ const SwTwips nLeft = bRTL ?
+ (aTabRect.*fnRect->fnGetRight)() :
+ (aTabRect.*fnRect->fnGetLeft)();
+ const SwTwips nTop = (aTabRect.*fnRect->fnGetTop)();
+
+ SwTwips& rPointX = bVert ? aPt.Y() : aPt.X();
+ SwTwips& rPointY = bVert ? aPt.X() : aPt.Y();
+
+ const SwTwips nXDiff = (*fnRect->fnXDiff)( nLeft, rPointX ) * ( bRTL ? (-1) : 1 );
+ const SwTwips nYDiff = (*fnRect->fnYDiff)( nTop, rPointY );
+
+ bCloseToRow = nXDiff >= 0 && nXDiff < nFuzzy;
+ bCloseToCol = nYDiff >= 0 && nYDiff < nFuzzy;
+
+ if ( bCloseToCol && 2 * nYDiff > nFuzzy )
+ {
+ const SwFrm* pPrev = pFrm->GetPrev();
+ if ( pPrev )
+ {
+ SwRect aPrevRect = pPrev->Prt();
+ aPrevRect.Pos() += pPrev->Frm().Pos();
+
+ if( aPrevRect.IsInside( rPt ) )
+ {
+ bCloseToCol = false;
+ }
+ }
+
+ }
+
+ // If we found the point to be 'close' to the left or top border
+ // of the table frame, we adjust the point to be on that border:
+ if ( bCloseToRow && bCloseToCol )
+ aPt = bRTL ? aTabRect.TopRight() : (aTabRect.*fnRect->fnGetPos)();
+ else if ( bCloseToRow )
+ rPointX = nLeft;
+ else if ( bCloseToCol )
+ rPointY = nTop;
+
+ if ( !bCloseToRow && !bCloseToCol )
+ bSearchForFrmInTab = false;
+
+ // Since the point has been adjusted, we call lcl_FindFrmInTab()
+ // with a fuzzy value of 1:
+ nTmpFuzzy = 1;
+ }
+
+ const SwFrm* pTmp = bSearchForFrmInTab ?
+ ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, aPt, nTmpFuzzy ) :
+ 0;
+
+ if ( pTmp )
+ {
+ pFrm = pTmp;
+ break;
+ }
+ }
+ pFrm = pFrm->FindNextCnt();
+
+ } while ( pFrm && pLay->IsAnLower( pFrm ) );
+ }
+
+ if ( pFrm && pFrm->IsInTab() && pLay->IsAnLower( pFrm ) )
+ {
+ do
+ {
+ // We allow mouse drag of table borders within nested tables,
+ // but disallow hotspot selection of nested tables.
+ if ( bMouseMoveRowCols )
+ {
+ // find the next cell frame
+ while ( pFrm && !pFrm->IsCellFrm() )
+ pFrm = pFrm->GetUpper();
+ }
+ else
+ {
+ // find the most upper cell frame:
+ while ( pFrm &&
+ ( !pFrm->IsCellFrm() ||
+ !pFrm->GetUpper()->GetUpper()->IsTabFrm() ||
+ pFrm->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
+ pFrm = pFrm->GetUpper();
+ }
+
+ if ( pFrm ) // Note: this condition should be the same like the while condition!!!
+ {
+ // --> FME 2004-07-30 #i32329# Enhanced table selection
+ // used for hotspot selection of tab/cols/rows
+ if ( !bMouseMoveRowCols )
+ {
+
+ ASSERT( pbCol && pbRow, "pbCol or pbRow missing" )
+
+ if ( bCloseToRow || bCloseToCol )
+ {
+ *pbRow = bCloseToRow;
+ *pbCol = bCloseToCol;
+ pRet = pFrm;
+ break;
+ }
+ }
+ // <--
+ else
+ {
+ // used for mouse move of columns/rows
+ const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
+ SwRect aTabRect = pTabFrm->Prt();
+ aTabRect.Pos() += pTabFrm->Frm().Pos();
+
+ SWRECTFN( pTabFrm )
+
+ const SwTwips nTabTop = (aTabRect.*fnRect->fnGetTop)();
+ const SwTwips nMouseTop = bVert ? rPt.X() : rPt.Y();
+
+ // Do not allow to drag upper table border:
+ if ( !::IsSame( nTabTop, nMouseTop ) )
+ {
+ if ( ::IsSame( pFrm->Frm().Left(), rPt.X() ) ||
+ ::IsSame( pFrm->Frm().Right(),rPt.X() ) )
+ {
+ if ( pbRow ) *pbRow = false;
+ pRet = pFrm;
+ break;
+ }
+ if ( ::IsSame( pFrm->Frm().Top(), rPt.Y() ) ||
+ ::IsSame( pFrm->Frm().Bottom(),rPt.Y() ) )
+ {
+ if ( pbRow ) *pbRow = true;
+ pRet = pFrm;
+ break;
+ }
+ }
+ }
+
+ pFrm = pFrm->GetUpper();
+ }
+ } while ( pFrm );
+ }
+
+ // robust:
+ ASSERT( !pRet || pRet->IsCellFrm(), "lcl_FindFrm() is supposed to find a cell frame!" )
+ return pRet && pRet->IsCellFrm() ? static_cast<const SwCellFrm*>(pRet) : 0;
+}
+
+//
+// pbCol = 0 => Used for moving table rows/cols with mouse
+// pbCol != 0 => Used for selecting table/rows/cols
+//
+#define ENHANCED_TABLE_SELECTION_FUZZY 10
+
+const SwFrm* SwFEShell::GetBox( const Point &rPt, bool* pbRow, bool* pbCol ) const
+{
+ const SwPageFrm *pPage = (SwPageFrm*)GetLayout()->Lower();
+ Window* pOutWin = GetWin();
+ SwTwips nFuzzy = COLFUZZY;
+ if( pOutWin )
+ {
+ // --> FME 2004-07-30 #i32329# Enhanced table selection
+ SwTwips nSize = pbCol ? ENHANCED_TABLE_SELECTION_FUZZY : RULER_MOUSE_MARGINWIDTH;
+ // <--
+ Size aTmp( nSize, nSize );
+ aTmp = pOutWin->PixelToLogic( aTmp );
+ nFuzzy = aTmp.Width();
+ }
+
+ while ( pPage && !pPage->Frm().IsNear( rPt, nFuzzy ) )
+ pPage = (SwPageFrm*)pPage->GetNext();
+
+ const SwCellFrm *pFrm = 0;
+ if ( pPage )
+ {
+ //Per GetCrsrOfst oder GetCntntPos koennen wir hier die Box leider
+ //nicht suchen. Das wuerde zu einem Performance-Zusammenbruch bei
+ //Dokumenten mit vielen Absaetzen/Tabellen auf einer Seite fuehren
+ //(BrowseMode!)
+
+ //Erst die Flys checken.
+ if ( pPage->GetSortedObjs() )
+ {
+ for ( USHORT i = 0; !pFrm && i < pPage->GetSortedObjs()->Count(); ++i )
+ {
+ SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ pFrm = lcl_FindFrm( static_cast<SwFlyFrm*>(pObj),
+ rPt, nFuzzy, pbRow, pbCol );
+ }
+ }
+ }
+ const SwLayoutFrm *pLay = (SwLayoutFrm*)pPage->Lower();
+ while ( pLay && !pFrm )
+ {
+ pFrm = lcl_FindFrm( pLay, rPt, nFuzzy, pbRow, pbCol );
+ pLay = (SwLayoutFrm*)pLay->GetNext();
+ }
+ }
+ return pFrm;
+}
+
+/* Helper function*/
+/* calculated the distance between Point rC and Line Segment (rA, rB) */
+double lcl_DistancePoint2Segment( const Point& rA, const Point& rB, const Point& rC )
+{
+ double nRet = 0;
+
+ const basegfx::B2DVector aBC( rC.X() - rB.X(), rC.Y() - rB.Y() );
+ const basegfx::B2DVector aAB( rB.X() - rA.X(), rB.Y() - rA.Y() );
+ const double nDot1 = aBC.scalar( aAB );
+
+ if ( nDot1 > 0 ) // check outside case 1
+ nRet = aBC.getLength();
+ else
+ {
+ const basegfx::B2DVector aAC( rC.X() - rA.X(), rC.Y() - rA.Y() );
+ const basegfx::B2DVector aBA( rA.X() - rB.X(), rA.Y() - rB.Y() );
+ const double nDot2 = aAC.scalar( aBA );
+
+ if ( nDot2 > 0 ) // check outside case 2
+ nRet = aAC.getLength();
+ else
+ {
+ const double nDiv = aAB.getLength();
+ nRet = nDiv ? aAB.cross( aAC ) / nDiv : 0;
+ }
+ }
+
+ return Abs(nRet);
+}
+
+/* Helper function*/
+Point lcl_ProjectOntoClosestTableFrm( const SwTabFrm& rTab, const Point& rPoint, bool bRowDrag )
+{
+ Point aRet( rPoint );
+ const SwTabFrm* pCurrentTab = &rTab;
+ const bool bVert = pCurrentTab->IsVertical();
+ const bool bRTL = pCurrentTab->IsRightToLeft();
+
+ // Western Layout:
+ // bRowDrag = true => compare to left border of table
+ // bRowDrag = false => compare to top border of table
+
+ // Asian Layout:
+ // bRowDrag = true => compare to right border of table
+ // bRowDrag = false => compare to top border of table
+
+ // RTL Layout:
+ // bRowDrag = true => compare to right border of table
+ // bRowDrag = false => compare to top border of table
+ bool bLeft = false;
+ bool bRight = false;
+
+ if ( bRowDrag )
+ {
+ if ( bVert || bRTL )
+ bRight = true;
+ else
+ bLeft = true;
+ }
+
+ // used to find the minimal distance
+ double nMin = -1;
+ Point aMin1;
+ Point aMin2;
+
+ Point aS1;
+ Point aS2;
+
+ while ( pCurrentTab )
+ {
+ SwRect aTabRect( pCurrentTab->Prt() );
+ aTabRect += pCurrentTab->Frm().Pos();
+
+ if ( bLeft )
+ {
+ // distance to left table border
+ aS1 = aTabRect.TopLeft();
+ aS2 = aTabRect.BottomLeft();
+ }
+ else if ( bRight )
+ {
+ // distance to right table border
+ aS1 = aTabRect.TopRight();
+ aS2 = aTabRect.BottomRight();
+ }
+ else //if ( bTop )
+ {
+ // distance to top table border
+ aS1 = aTabRect.TopLeft();
+ aS2 = aTabRect.TopRight();
+ }
+
+ const double nDist = lcl_DistancePoint2Segment( aS1, aS2, rPoint );
+
+ if ( nDist < nMin || -1 == nMin )
+ {
+ aMin1 = aS1;
+ aMin2 = aS2;
+ nMin = nDist;
+ }
+
+ pCurrentTab = pCurrentTab->GetFollow();
+ }
+
+ // project onto closest line:
+ if ( bLeft || bRight )
+ {
+ aRet.X() = aMin1.X();
+ if ( aRet.Y() > aMin2.Y() )
+ aRet.Y() = aMin2.Y();
+ else if ( aRet.Y() < aMin1.Y() )
+ aRet.Y() = aMin1.Y();
+ }
+ else //if ( bTop )
+ {
+ aRet.Y() = aMin1.Y();
+ if ( aRet.X() > aMin2.X() )
+ aRet.X() = aMin2.X();
+ else if ( aRet.X() < aMin1.X() )
+ aRet.X() = aMin1.X();
+ }
+
+ return aRet;
+}
+
+// --> FME 2004-07-30 #i32329# Enhanced table selection
+bool SwFEShell::SelTblRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
+{
+ bool bRet = false;
+ Point aEndPt;
+ if ( pEnd )
+ aEndPt = *pEnd;
+
+ SwPosition* ppPos[2] = { 0, 0 };
+ Point paPt [2] = { rPt, aEndPt };
+ bool pbRow[2] = { 0, 0 };
+ bool pbCol[2] = { 0, 0 };
+
+ // pEnd is set during dragging.
+ for ( USHORT i = 0; i < ( pEnd ? 2 : 1 ); ++i )
+ {
+ const SwCellFrm* pFrm =
+ static_cast<const SwCellFrm*>(GetBox( paPt[i], &pbRow[i], &pbCol[i] ) );
+
+ if( pFrm )
+ {
+ while( pFrm->Lower() && pFrm->Lower()->IsRowFrm() )
+ pFrm = static_cast<const SwCellFrm*>( static_cast<const SwLayoutFrm*>( pFrm->Lower() )->Lower() );
+ if( pFrm && pFrm->GetTabBox()->GetSttNd() &&
+ pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() )
+ pFrm = 0;
+ }
+
+ if ( pFrm )
+ {
+ const SwCntntFrm* pCntnt = ::GetCellCntnt( *pFrm );
+
+ if ( pCntnt && pCntnt->IsTxtFrm() )
+ {
+ ppPos[i] = new SwPosition( *pCntnt->GetNode() );
+ ppPos[i]->nContent.Assign( const_cast<SwCntntNode*>(pCntnt->GetNode()), 0 );
+
+ // paPt[i] will not be used any longer, now we use it to store
+ // a position inside the content frame
+ paPt[i] = pCntnt->Frm().Center();
+ }
+ }
+
+ // no calculation of end frame if start frame has not been found.
+ if ( 1 == i || !ppPos[0] || !pEnd )
+ break;
+
+ // find 'closest' table frame to pEnd:
+ const SwTabFrm* pCurrentTab = pFrm->FindTabFrm();
+ if ( pCurrentTab->IsFollow() )
+ pCurrentTab = pCurrentTab->FindMaster( true );
+
+ const Point aProjection = lcl_ProjectOntoClosestTableFrm( *pCurrentTab, *pEnd, bRowDrag );
+ paPt[1] = aProjection;
+ }
+
+ if ( ppPos[0] )
+ {
+ SwShellCrsr* pCrsr = _GetCrsr();
+ SwCrsrSaveState aSaveState( *pCrsr );
+ SwPosition aOldPos( *pCrsr->GetPoint() );
+
+ pCrsr->DeleteMark();
+ *pCrsr->GetPoint() = *ppPos[0];
+ pCrsr->GetPtPos() = paPt[0];
+
+ if ( !pCrsr->IsInProtectTable( FALSE, TRUE ) )
+ {
+ bool bNewSelection = true;
+
+ if ( ppPos[1] )
+ {
+ if ( ppPos[1]->nNode.GetNode().StartOfSectionNode() !=
+ aOldPos.nNode.GetNode().StartOfSectionNode() )
+ {
+ pCrsr->SetMark();
+ SwCrsrSaveState aSaveState2( *pCrsr );
+ *pCrsr->GetPoint() = *ppPos[1];
+ pCrsr->GetPtPos() = paPt[1];
+
+ if ( pCrsr->IsInProtectTable( FALSE, FALSE ) )
+ {
+ pCrsr->RestoreSavePos();
+ bNewSelection = false;
+ }
+ }
+ else
+ {
+ pCrsr->RestoreSavePos();
+ bNewSelection = false;
+ }
+ }
+
+ if ( bNewSelection )
+ {
+ // --> FME 2004-10-20 #i35543# SelTblRowCol should remove any existing
+ // table cursor:
+ if ( IsTableMode() )
+ TblCrsrToCursor();
+ // <--
+
+ if ( pbRow[0] && pbCol[0] )
+ bRet = SwCrsrShell::SelTbl();
+ else if ( pbRow[0] )
+ bRet = SwCrsrShell::_SelTblRowOrCol( true, true );
+ else if ( pbCol[0] )
+ bRet = SwCrsrShell::_SelTblRowOrCol( false, true );
+ }
+ else
+ bRet = true;
+ }
+
+ delete ppPos[0];
+ delete ppPos[1];
+ }
+
+ return bRet;
+}
+// <--
+
+
+/*************************************************************************
+|*
+|* SwFEShell::WhichMouseTabCol()
+|*
+|* Ersterstellung MA 22. Jun. 95
+|* Last change AMA 12. Jun. 02
+|
+|*************************************************************************/
+BYTE SwFEShell::WhichMouseTabCol( const Point &rPt ) const
+{
+ BYTE nRet = SW_TABCOL_NONE;
+ bool bRow = false;
+ bool bCol = false;
+ bool bSelect = false;
+
+ // First try: Do we get the row/col move cursor?
+ SwCellFrm* pFrm = (SwCellFrm*)GetBox( rPt, &bRow, 0 );
+
+ if ( !pFrm )
+ {
+ // Second try: Do we get the row/col/tab selection cursor?
+ pFrm = (SwCellFrm*)GetBox( rPt, &bRow, &bCol );
+ bSelect = true;
+ }
+
+ if( pFrm )
+ {
+ while( pFrm->Lower() && pFrm->Lower()->IsRowFrm() )
+ pFrm = (SwCellFrm*)((SwLayoutFrm*)pFrm->Lower())->Lower();
+ if( pFrm && pFrm->GetTabBox()->GetSttNd() &&
+ pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() )
+ pFrm = 0;
+ }
+
+ if( pFrm )
+ {
+ if ( !bSelect )
+ {
+ if ( pFrm->IsVertical() )
+ nRet = bRow ? SW_TABCOL_VERT : SW_TABROW_VERT;
+ else
+ nRet = bRow ? SW_TABROW_HORI : SW_TABCOL_HORI;
+ }
+ else
+ {
+ const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
+ if ( pTabFrm->IsVertical() )
+ {
+ if ( bRow && bCol )
+ {
+ nRet = SW_TABSEL_VERT;
+ }
+ else if ( bRow )
+ {
+ nRet = SW_TABROWSEL_VERT;
+ }
+ else if ( bCol )
+ {
+ nRet = SW_TABCOLSEL_VERT;
+ }
+ }
+ else
+ {
+ if ( bRow && bCol )
+ {
+ nRet = pTabFrm->IsRightToLeft() ?
+ SW_TABSEL_HORI_RTL :
+ SW_TABSEL_HORI;
+ }
+ else if ( bRow )
+ {
+ nRet = pTabFrm->IsRightToLeft() ?
+ SW_TABROWSEL_HORI_RTL :
+ SW_TABROWSEL_HORI;
+ }
+ else if ( bCol )
+ {
+ nRet = SW_TABCOLSEL_HORI;
+ }
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// -> #i23726#
+SwTxtNode * SwFEShell::GetNumRuleNodeAtPos( const Point &rPt)
+{
+ SwTxtNode * pResult = NULL;
+
+ SwContentAtPos aCntntAtPos
+ (SwContentAtPos::SW_NUMLABEL);
+
+ if( GetContentAtPos(rPt, aCntntAtPos) && aCntntAtPos.aFnd.pNode)
+ pResult = aCntntAtPos.aFnd.pNode->GetTxtNode();
+
+ return pResult;
+}
+
+BOOL SwFEShell::IsNumLabel( const Point &rPt, int nMaxOffset )
+{
+ BOOL bResult = FALSE;
+
+ SwContentAtPos aCntntAtPos
+ (SwContentAtPos::SW_NUMLABEL);
+
+ if( GetContentAtPos(rPt, aCntntAtPos))
+ {
+ if ((nMaxOffset >= 0 && aCntntAtPos.nDist <= nMaxOffset) ||
+ (nMaxOffset < 0))
+ bResult = TRUE;
+ }
+
+ return bResult;
+}
+// <- #i23726#
+
+// --> OD 2005-02-21 #i42921#
+bool SwFEShell::IsVerticalModeAtNdAndPos( const SwTxtNode& _rTxtNode,
+ const Point& _rDocPos ) const
+{
+ bool bRet( false );
+
+ const short nTextDir =
+ _rTxtNode.GetTextDirection( SwPosition(_rTxtNode), &_rDocPos );
+ switch ( nTextDir )
+ {
+ case -1:
+ case FRMDIR_HORI_RIGHT_TOP:
+ case FRMDIR_HORI_LEFT_TOP:
+ {
+ bRet = false;
+ }
+ break;
+ case FRMDIR_VERT_TOP_LEFT:
+ case FRMDIR_VERT_TOP_RIGHT:
+ {
+ bRet = true;
+ }
+ break;
+ }
+
+ return bRet;
+}
+// <--
+
+/*************************************************************************
+|*
+|* SwFEShell::GetMouseTabCols()
+|*
+|* Ersterstellung MA 22. Jun. 95
+|* Letzte Aenderung MA 27. Aug. 96
+|
+|*************************************************************************/
+void SwFEShell::GetMouseTabCols( SwTabCols &rToFill, const Point &rPt ) const
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if ( pBox )
+ _GetTabCols( rToFill, pBox );
+}
+
+void SwFEShell::SetMouseTabCols( const SwTabCols &rNew, BOOL bCurRowOnly,
+ const Point &rPt )
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if( pBox )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetMouseColNum(), GetMouseTabColNum()
+|*
+|* Ersterstellung MA 04. Jul. 95
+|* Letzte Aenderung MA 04. Jul. 95
+|
+|*************************************************************************/
+USHORT SwFEShell::GetCurMouseColNum( const Point &rPt,
+ SwGetCurColNumPara* pPara ) const
+{
+ return _GetCurColNum( GetBox( rPt ), pPara );
+}
+
+USHORT SwFEShell::GetCurMouseTabColNum( const Point &rPt ) const
+{
+ //!!!GetCurTabColNum() mitpflegen!!!!
+ USHORT nRet = 0;
+
+ const SwFrm *pFrm = GetBox( rPt );
+ ASSERT( pFrm, "Table not found" );
+ if( pFrm )
+ {
+ const long nX = pFrm->Frm().Left();
+
+ //TabCols besorgen, den nur ueber diese erreichen wir die Position.
+ SwTabCols aTabCols;
+ GetMouseTabCols( aTabCols, rPt );
+
+ const long nLeft = aTabCols.GetLeftMin();
+
+ if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
+ {
+ for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+ if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
+ {
+ nRet = i + 1;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+
+void ClearFEShellTabCols()
+{
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetTblAttr(), SetTblAttr()
+|*
+|* Ersterstellung MA 09. Dec. 96
+|* Letzte Aenderung MA 09. Dec. 96
+|
+|*************************************************************************/
+void SwFEShell::GetTblAttr( SfxItemSet &rSet ) const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( pFrm && pFrm->IsInTab() )
+ rSet.Put( pFrm->ImplFindTabFrm()->GetFmt()->GetAttrSet() );
+}
+
+void SwFEShell::SetTblAttr( const SfxItemSet &rNew )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( pFrm && pFrm->IsInTab() )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ SwTabFrm *pTab = pFrm->FindTabFrm();
+ pTab->GetTable()->SetHTMLTableLayout( 0 );
+ GetDoc()->SetAttr( rNew, *pTab->GetFmt() );
+ GetDoc()->SetModified();
+ EndAllActionAndCall();
+ }
+}
+
+/** move cursor within a table into previous/next row (same column)
+ * @param pShell cursor shell whose cursor is to be moved
+ * @param bUp true: move up, false: move down
+ * @returns true if successful
+ */
+bool lcl_GoTableRow( SwCrsrShell* pShell, bool bUp )
+{
+ ASSERT( pShell != NULL, "need shell" );
+
+ bool bRet = false;
+
+ SwPaM* pPam = pShell->GetCrsr();
+ const SwStartNode* pTableBox = pPam->GetNode()->FindTableBoxStartNode();
+ ASSERT( pTableBox != NULL, "I'm living in a box... NOT!" );
+
+ // move cursor to start node of table box
+ pPam->GetPoint()->nNode = pTableBox->GetIndex();
+ pPam->GetPoint()->nContent.Assign( NULL, 0 );
+ GoInCntnt( *pPam, fnMoveForward );
+
+ // go to beginning end of table box
+ SwPosSection fnPosSect = bUp ? fnSectionStart : fnSectionEnd;
+ pShell->MoveSection( fnSectionCurr, fnPosSect );
+
+ // and go up/down into next content
+ bRet = bUp ? pShell->Up() : pShell->Down();
+
+ return bRet;
+}
+
+ // aender eine Zellenbreite/-Hoehe/Spaltenbreite/Zeilenhoehe
+BOOL SwFEShell::SetColRowWidthHeight( USHORT eType, USHORT nDiff )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType &&
+ pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ do {
+ pFrm = pFrm->GetUpper();
+ } while( !pFrm->IsCellFrm() );
+
+ SwTabFrm *pTab = pFrm->ImplFindTabFrm();
+
+ // sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen
+ // dann muss es jetzt auf absolute umgerechnet werden.
+ const SwFmtFrmSize& rTblFrmSz = pTab->GetFmt()->GetFrmSize();
+ SWRECTFN( pTab )
+ long nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
+ if( TBLVAR_CHGABS == pTab->GetTable()->GetTblChgMode() &&
+ ( eType & nsTblChgWidthHeightType::WH_COL_LEFT || eType & nsTblChgWidthHeightType::WH_COL_RIGHT ) &&
+ text::HoriOrientation::NONE == pTab->GetFmt()->GetHoriOrient().GetHoriOrient() &&
+ nPrtWidth != rTblFrmSz.GetWidth() )
+ {
+ SwFmtFrmSize aSz( rTblFrmSz );
+ aSz.SetWidth( pTab->Prt().Width() );
+ pTab->GetFmt()->SetFmtAttr( aSz );
+ }
+
+ if( (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) ==
+ (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL) )
+ {
+ nDiff = USHORT((pFrm->Frm().*fnRect->fnGetWidth)());
+
+ // we must move the cursor outside the current cell before
+ // deleting the cells.
+ TblChgWidthHeightType eTmp =
+ static_cast<TblChgWidthHeightType>( eType & 0xfff );
+ switch( eTmp )
+ {
+ case nsTblChgWidthHeightType::WH_ROW_TOP:
+ lcl_GoTableRow( this, true );
+ break;
+ case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
+ lcl_GoTableRow( this, false );
+ break;
+ case nsTblChgWidthHeightType::WH_COL_LEFT:
+ GoPrevCell();
+ break;
+ case nsTblChgWidthHeightType::WH_COL_RIGHT:
+ GoNextCell();
+ break;
+ default:
+ break;
+ }
+ }
+
+ SwTwips nLogDiff = nDiff;
+ nLogDiff *= pTab->GetFmt()->GetFrmSize().GetWidth();
+ nLogDiff /= nPrtWidth;
+
+ /** The cells are destroyed in here */
+ BOOL bRet = GetDoc()->SetColRowWidthHeight(
+ *(SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(),
+ eType, nDiff, nLogDiff );
+
+ delete pLastCols, pLastCols = 0;
+ EndAllActionAndCall();
+
+ if( bRet && (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) == nsTblChgWidthHeightType::WH_FLAG_INSDEL )
+ {
+ switch(eType & ~(nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL))
+ {
+ case nsTblChgWidthHeightType::WH_CELL_LEFT:
+ case nsTblChgWidthHeightType::WH_COL_LEFT:
+ GoPrevCell();
+ break;
+
+ case nsTblChgWidthHeightType::WH_CELL_RIGHT:
+ case nsTblChgWidthHeightType::WH_COL_RIGHT:
+ GoNextCell();
+ break;
+
+ case nsTblChgWidthHeightType::WH_CELL_TOP:
+ case nsTblChgWidthHeightType::WH_ROW_TOP:
+ lcl_GoTableRow( this, true );
+ break;
+
+ case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
+ case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
+ lcl_GoTableRow( this, false );
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+BOOL lcl_IsFormulaSelBoxes( const SwTable& rTbl, const SwTblBoxFormula& rFml,
+ SwCellFrms& rCells )
+{
+ SwTblBoxFormula aTmp( rFml );
+ SwSelBoxes aBoxes;
+ for( USHORT nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes ); nSelBoxes; )
+ {
+ SwTableBox* pBox = aBoxes[ --nSelBoxes ];
+ USHORT i;
+ for( i = 0; i < rCells.Count(); ++i )
+ if( rCells[ i ]->GetTabBox() == pBox )
+ break; // gefunden
+
+ if( i == rCells.Count() )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+ // erfrage die Formel fuer die Autosumme
+BOOL SwFEShell::GetAutoSum( String& rFml ) const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ SwTabFrm *pTab = pFrm ? pFrm->ImplFindTabFrm() : 0;
+ if( !pTab )
+ return FALSE;
+
+ rFml = String::CreateFromAscii( sCalc_Sum );
+
+ SwCellFrms aCells;
+ if( ::GetAutoSumSel( *this, aCells ))
+ {
+ USHORT nW = 0, nInsPos = 0;
+ for( USHORT n = aCells.Count(); n; )
+ {
+ SwCellFrm* pCFrm = aCells[ --n ];
+ USHORT nBoxW = pCFrm->GetTabBox()->IsFormulaOrValueBox();
+ if( !nBoxW )
+ break;
+
+ if( !nW )
+ {
+ if( USHRT_MAX == nBoxW )
+ continue; // leere am Anfang ueberspringen
+
+ rFml += '(';
+ nInsPos = rFml.Len();
+
+ // Formeln nur wenn diese Boxen enthalten
+ if( RES_BOXATR_FORMULA == nBoxW &&
+ !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+ GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells))
+ {
+ nW = RES_BOXATR_VALUE;
+ // alle vorhierigen Leere wieder mit aufnehmen !
+ for( USHORT i = aCells.Count(); n+1 < i; )
+ {
+ String sTmp( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "|<" )) );
+ sTmp += aCells[ --i ]->GetTabBox()->GetName();
+ sTmp += '>';
+ rFml.Insert( sTmp, nInsPos );
+ }
+ }
+ else
+ nW = nBoxW;
+ }
+ else if( RES_BOXATR_VALUE == nW )
+ {
+ // values werden gesucht, Value/Formel/Text gefunden -> aufn.
+ if( RES_BOXATR_FORMULA == nBoxW &&
+ ::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+ GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
+ break;
+ else if( USHRT_MAX != nBoxW )
+ rFml.Insert( cListDelim, nInsPos );
+ else
+ break;
+ }
+ else if( RES_BOXATR_FORMULA == nW )
+ {
+ // bei Formeln nur weiter suchen, wenn die akt. Formel auf
+ // alle Boxen verweist, die sich in der Selektion befinden
+ if( RES_BOXATR_FORMULA == nBoxW )
+ {
+ if( !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+ GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
+ {
+ // dann noch mal von vorne und nur die Values!
+
+ nW = RES_BOXATR_VALUE;
+ rFml.Erase( nInsPos );
+ // alle vorhierigen Leere wieder mit aufnehmen !
+ for( USHORT i = aCells.Count(); n+1 < i; )
+ {
+ String sTmp( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "|<" )) );
+ sTmp += aCells[ --i ]->GetTabBox()->GetName();
+ sTmp += '>';
+ rFml.Insert( sTmp, nInsPos );
+ }
+ }
+ else
+ rFml.Insert( cListDelim, nInsPos );
+ }
+ else if( USHRT_MAX == nBoxW )
+ break;
+ else
+ continue; // diese Boxen ignorieren
+ }
+ else
+ // alles andere beendet die Schleife
+// evt. Texte noch zu lassen??
+ break;
+
+ String sTmp( '<' );
+ sTmp += pCFrm->GetTabBox()->GetName();
+ sTmp += '>';
+ rFml.Insert( sTmp, nInsPos );
+ }
+ if( nW )
+ {
+ rFml += ')';
+
+/*
+ // TabellenSelektion erzeugen??
+ SwTblBoxFormula aTmp( rFml );
+ SwSelBoxes aBoxes;
+ for( USHORT nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes );
+ nSelBoxes; )
+ {
+ }
+*/
+ }
+ }
+
+ return TRUE;
+}
+/* -----------------------------22.08.2002 12:50------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwFEShell::IsTableRightToLeft() const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ return pFrm->ImplFindTabFrm()->IsRightToLeft();
+}
+
+/* -----------------------------22.08.2002 12:50------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwFEShell::IsMouseTableRightToLeft(const Point &rPt) const
+{
+ SwFrm *pFrm = (SwFrm *)GetBox( rPt );
+ const SwTabFrm* pTabFrm = pFrm ? pFrm->ImplFindTabFrm() : 0;
+ ASSERT( pTabFrm, "Table not found" );
+ return pTabFrm ? pTabFrm->IsRightToLeft() : FALSE;
+}
+
+/* -----------------------------11.02.2004 12:50------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwFEShell::IsTableVertical() const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ return pFrm->ImplFindTabFrm()->IsVertical();
+}
+
+
+
diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx
new file mode 100644
index 000000000000..02baddd201bd
--- /dev/null
+++ b/sw/source/core/frmedt/fews.cxx
@@ -0,0 +1,1296 @@
+/*************************************************************************
+ *
+ * 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 <tools/list.hxx>
+#include <svx/svdobj.hxx>
+#include <init.hxx>
+#include <fesh.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <cntfrm.hxx>
+#include <doc.hxx>
+#include <frmtool.hxx>
+#include <swtable.hxx>
+#include <viewimp.hxx>
+#include <dview.hxx>
+#include <flyfrm.hxx>
+#include <node.hxx>
+#include <pam.hxx>
+#include <sectfrm.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtcntnt.hxx>
+#include <tabfrm.hxx>
+#include <cellfrm.hxx>
+#include <flyfrms.hxx>
+#include <txtfrm.hxx> // SwTxtFrm
+#include <mdiexp.hxx>
+#include <edimp.hxx>
+#include <pagedesc.hxx>
+#include <fmtanchr.hxx>
+// OD 29.10.2003 #113049#
+#include <environmentofanchoredobject.hxx>
+// OD 12.11.2003 #i22341#
+#include <ndtxt.hxx>
+// OD 27.11.2003 #112045#
+#include <dflyobj.hxx>
+// OD 2004-03-29 #i26791#
+#include <dcontact.hxx>
+
+
+using namespace com::sun::star;
+
+
+TYPEINIT1(SwFEShell,SwEditShell)
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : EndAllActionAndCall()
+#*
+#* Datum : MA 03. May. 93
+#* Update : MA 31. Oct. 95
+#***********************************************************************/
+
+void SwFEShell::EndAllActionAndCall()
+{
+ ViewShell *pTmp = this;
+ do {
+ if( pTmp->IsA( TYPE(SwCrsrShell) ) )
+ {
+ ((SwFEShell*)pTmp)->EndAction();
+ ((SwFEShell*)pTmp)->CallChgLnk();
+ }
+ else
+ pTmp->EndAction();
+ } while( this != ( pTmp = (ViewShell*)pTmp->GetNext() ));
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methode : GetCntntPos
+#* Beschreibung: Ermitteln des Cntnt's der dem Punkt am naechsten liegt
+#* Datum : MA 02. Jun. 92
+#* Update : MA 02. May. 95
+#***********************************************************************/
+
+Point SwFEShell::GetCntntPos( const Point& rPoint, BOOL bNext ) const
+{
+ SET_CURR_SHELL( (ViewShell*)this );
+ return GetLayout()->GetNextPrevCntntPos( rPoint, bNext );
+}
+
+
+const SwRect& SwFEShell::GetAnyCurRect( CurRectType eType, const Point* pPt,
+ const uno::Reference < embed::XEmbeddedObject >& xObj ) const
+{
+ const SwFrm *pFrm = Imp()->HasDrawView()
+ ? ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
+ (ViewShell*)this)
+ : 0;
+
+ if( !pFrm )
+ {
+ if( pPt )
+ {
+ SwPosition aPos( *GetCrsr()->GetPoint() );
+ Point aPt( *pPt );
+ GetLayout()->GetCrsrOfst( &aPos, aPt );
+ SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
+ pFrm = pNd->GetFrm( pPt );
+ }
+ else
+ pFrm = GetCurrFrm();
+ }
+
+ if( !pFrm )
+ return GetLayout()->Frm();
+
+ BOOL bFrm = TRUE;
+ switch ( eType )
+ {
+ case RECT_PAGE_PRT: bFrm = FALSE; /* no break */
+ case RECT_PAGE : pFrm = pFrm->FindPageFrm();
+ break;
+
+ case RECT_PAGE_CALC: pFrm->Calc();
+ pFrm = pFrm->FindPageFrm();
+ pFrm->Calc();
+ break;
+
+ case RECT_FLY_PRT_EMBEDDED: bFrm = FALSE; /* no break */
+ case RECT_FLY_EMBEDDED: pFrm = xObj.is() ? FindFlyFrm( xObj )
+ : pFrm->IsFlyFrm()
+ ? pFrm
+ : pFrm->FindFlyFrm();
+ break;
+
+ case RECT_OUTTABSECTION_PRT:
+ case RECT_OUTTABSECTION : if( pFrm->IsInTab() )
+ pFrm = pFrm->FindTabFrm();
+ else {
+ ASSERT( FALSE, "Missing Table" );
+ }
+ /* KEIN BREAK */
+ case RECT_SECTION_PRT:
+ case RECT_SECTION: if( pFrm->IsInSct() )
+ pFrm = pFrm->FindSctFrm();
+ else {
+ ASSERT( FALSE, "Missing section" );
+ }
+
+ if( RECT_OUTTABSECTION_PRT == eType ||
+ RECT_SECTION_PRT == eType )
+ bFrm = FALSE;
+ break;
+
+ case RECT_HEADERFOOTER_PRT: bFrm = FALSE; /* no break */
+ case RECT_HEADERFOOTER: if( 0 == (pFrm = pFrm->FindFooterOrHeader()) )
+ return GetLayout()->Frm();
+ break;
+
+ case RECT_PAGES_AREA: return GetLayout()->GetPagesArea();
+
+ default: break;
+ }
+ return bFrm ? pFrm->Frm() : pFrm->Prt();
+}
+
+
+USHORT SwFEShell::GetPageNumber( const Point &rPoint ) const
+{
+ const SwFrm *pPage = GetLayout()->Lower();
+ while ( pPage && !pPage->Frm().IsInside( rPoint ) )
+ pPage = pPage->GetNext();
+ if ( pPage )
+ return ((const SwPageFrm*)pPage)->GetPhyPageNum();
+ else
+ return 0;
+}
+
+
+BOOL SwFEShell::GetPageNumber( long nYPos, BOOL bAtCrsrPos, USHORT& rPhyNum, USHORT& rVirtNum, String &rDisplay) const
+{
+ const SwFrm *pPage;
+
+ if ( bAtCrsrPos ) //Seite vom Crsr besorgen
+ {
+ pPage = GetCurrFrm( FALSE );
+ if ( pPage )
+ pPage = pPage->FindPageFrm();
+ }
+ else if ( nYPos > -1 ) //Seite ueber die Positon ermitteln
+ {
+ pPage = GetLayout()->Lower();
+ while( pPage && (pPage->Frm().Bottom() < nYPos ||
+ nYPos < pPage->Frm().Top() ) )
+ pPage = pPage->GetNext();
+ }
+ else //Die erste sichtbare Seite
+ {
+ pPage = Imp()->GetFirstVisPage();
+ if ( pPage && ((SwPageFrm*)pPage)->IsEmptyPage() )
+ pPage = pPage->GetNext();
+ }
+
+ if( pPage )
+ {
+ rPhyNum = ((const SwPageFrm*)pPage)->GetPhyPageNum();
+ rVirtNum = ((const SwPageFrm*)pPage)->GetVirtPageNum();
+ const SvxNumberType& rNum = ((const SwPageFrm*)pPage)->GetPageDesc()->GetNumType();
+ rDisplay = rNum.GetNumStr( rVirtNum );
+ }
+
+ return 0 != pPage;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::IsDirectlyInSection()
+|*
+|* Hack for OS:
+|*
+*************************************************************************/
+
+bool SwFEShell::IsDirectlyInSection() const
+{
+ SwFrm* pFrm = GetCurrFrm( FALSE );
+ return pFrm && pFrm->GetUpper() && pFrm->GetUpper()->IsSctFrm();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetFrmType()
+|*
+|* Ersterstellung MA 12. Jan. 93
+|* Letzte Aenderung AMA 25. Nov. 98
+|*
+*************************************************************************/
+
+USHORT SwFEShell::GetFrmType( const Point *pPt, BOOL bStopAtFly ) const
+{
+ USHORT nReturn = FRMTYPE_NONE;
+ const SwFrm *pFrm;
+ if ( pPt )
+ {
+ SwPosition aPos( *GetCrsr()->GetPoint() );
+ Point aPt( *pPt );
+ GetLayout()->GetCrsrOfst( &aPos, aPt );
+ SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
+ pFrm = pNd->GetFrm( pPt );
+ }
+ else
+ pFrm = GetCurrFrm( FALSE );
+ while ( pFrm )
+ {
+ switch ( pFrm->GetType() )
+ {
+ case FRM_COLUMN: if( pFrm->GetUpper()->IsSctFrm() )
+ {
+ // Check, if isn't not only a single column
+ // from a section with footnotes at the end.
+ if( pFrm->GetNext() || pFrm->GetPrev() )
+ // Sectioncolumns
+ nReturn |= ( nReturn & FRMTYPE_TABLE ) ?
+ FRMTYPE_COLSECTOUTTAB : FRMTYPE_COLSECT;
+ }
+ else // nur Seiten und Rahmenspalten
+ nReturn |= FRMTYPE_COLUMN;
+ break;
+ case FRM_PAGE: nReturn |= FRMTYPE_PAGE;
+ if( ((SwPageFrm*)pFrm)->IsFtnPage() )
+ nReturn |= FRMTYPE_FTNPAGE;
+ break;
+ case FRM_HEADER: nReturn |= FRMTYPE_HEADER; break;
+ case FRM_FOOTER: nReturn |= FRMTYPE_FOOTER; break;
+ case FRM_BODY: if( pFrm->GetUpper()->IsPageFrm() ) // nicht bei ColumnFrms
+ nReturn |= FRMTYPE_BODY;
+ break;
+ case FRM_FTN: nReturn |= FRMTYPE_FOOTNOTE; break;
+ case FRM_FLY: if( ((SwFlyFrm*)pFrm)->IsFlyLayFrm() )
+ nReturn |= FRMTYPE_FLY_FREE;
+ else if ( ((SwFlyFrm*)pFrm)->IsFlyAtCntFrm() )
+ nReturn |= FRMTYPE_FLY_ATCNT;
+ else
+ {
+ ASSERT( ((SwFlyFrm*)pFrm)->IsFlyInCntFrm(),
+ "Neuer Rahmentyp?" );
+ nReturn |= FRMTYPE_FLY_INCNT;
+ }
+ nReturn |= FRMTYPE_FLY_ANY;
+ if( bStopAtFly )
+ return nReturn;
+ break;
+ case FRM_TAB:
+ case FRM_ROW:
+ case FRM_CELL: nReturn |= FRMTYPE_TABLE; break;
+ default: /* do nothing */ break;
+ }
+ if ( pFrm->IsFlyFrm() )
+ pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm();
+ else
+ pFrm = pFrm->GetUpper();
+ }
+ return nReturn;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::ShLooseFcs(), ShGetFcs()
+|*
+|* Ersterstellung MA 10. May. 93
+|* Letzte Aenderung MA 09. Sep. 98
+|*
+*************************************************************************/
+
+void SwFEShell::ShGetFcs( BOOL bUpdate )
+{
+ ::SetShell( this );
+ SwCrsrShell::ShGetFcs( bUpdate );
+
+ if ( HasDrawView() )
+ {
+ Imp()->GetDrawView()->showMarkHandles();
+ if ( Imp()->GetDrawView()->AreObjectsMarked() )
+ FrameNotify( this, FLY_DRAG_START );
+ }
+}
+
+void SwFEShell::ShLooseFcs()
+{
+ SwCrsrShell::ShLooseFcs();
+
+ if ( HasDrawView() && Imp()->GetDrawView()->AreObjectsMarked() )
+ {
+ Imp()->GetDrawView()->hideMarkHandles();
+ FrameNotify( this, FLY_DRAG_END );
+ }
+// ::ResetShell();
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetPhyPageNum()
+|* SwFEShell::GetVirtPageNum()
+|*
+|* Ersterstellung OK 07.07.93 08:20
+|* Letzte Aenderung MA 03. Jan. 94
+|*
+*************************************************************************/
+
+USHORT SwFEShell::GetPhyPageNum()
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if ( pFrm )
+ return pFrm->GetPhyPageNum();
+ return 0;
+}
+
+USHORT SwFEShell::GetVirtPageNum( const BOOL bCalcFrm )
+{
+ SwFrm *pFrm = GetCurrFrm( bCalcFrm );
+ if ( pFrm )
+ return pFrm->GetVirtPageNum();
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* void lcl_SetAPageOffset()
+|* void SwFEShell::SetNewPageOffset()
+|* void SwFEShell::SetPageOffset()
+|* USHORT SwFEShell::GetPageOffset() const
+|*
+|* Ersterstellung OK 07.07.93 08:20
+|* Letzte Aenderung MA 30. Mar. 95
+|*
+*************************************************************************/
+
+void lcl_SetAPageOffset( USHORT nOffset, SwPageFrm* pPage, SwFEShell* pThis )
+{
+ pThis->StartAllAction();
+ ASSERT( pPage->FindFirstBodyCntnt(),
+ "SwFEShell _SetAPageOffset() ohne CntntFrm" );
+
+ SwFmtPageDesc aDesc( pPage->GetPageDesc() );
+ aDesc.SetNumOffset( nOffset );
+
+ SwFrm *pFrm = pThis->GetCurrFrm( FALSE );
+ if ( pFrm->IsInTab() )
+ pThis->GetDoc()->SetAttr( aDesc, *pFrm->FindTabFrm()->GetFmt() );
+ else
+ {
+ pThis->GetDoc()->InsertPoolItem( *pThis->GetCrsr(), aDesc, 0 );
+ }
+
+ pThis->EndAllAction();
+}
+
+void SwFEShell::SetNewPageOffset( USHORT nOffset )
+{
+ GetLayout()->SetVirtPageNum( TRUE );
+ const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
+ lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
+}
+
+void SwFEShell::SetPageOffset( USHORT nOffset )
+{
+ const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
+ const SwRootFrm* pLayout = GetLayout();
+ while ( pPage )
+ {
+ const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
+ if ( pFlow )
+ {
+ if ( pFlow->IsInTab() )
+ pFlow = pFlow->FindTabFrm();
+ const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+ if ( rPgDesc.GetNumOffset() )
+ {
+ pLayout->SetVirtPageNum( TRUE );
+ lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
+ break;
+ }
+ }
+ pPage = (SwPageFrm*)pPage->GetPrev();
+ }
+}
+
+USHORT SwFEShell::GetPageOffset() const
+{
+ const SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
+ while ( pPage )
+ {
+ const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
+ if ( pFlow )
+ {
+ if ( pFlow->IsInTab() )
+ pFlow = pFlow->FindTabFrm();
+ const USHORT nOffset = pFlow->GetAttrSet()->GetPageDesc().GetNumOffset();
+ if ( nOffset )
+ return nOffset;
+ }
+ pPage = (SwPageFrm*)pPage->GetPrev();
+ }
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::InsertLabel()
+|*
+|* Ersterstellung MA 10. Feb. 94
+|* Letzte Aenderung MA 10. Feb. 94
+|*
+*************************************************************************/
+
+void SwFEShell::InsertLabel( const SwLabelType eType, const String &rTxt, const String& rSeparator,
+ const String& rNumberSeparator,
+ const BOOL bBefore, const USHORT nId,
+ const String& rCharacterStyle,
+ const BOOL bCpyBrd )
+{
+ //NodeIndex der CrsrPosition besorgen, den Rest kann das Dokument
+ //selbst erledigen.
+ SwCntntFrm *pCnt = LTYPE_DRAW==eType ? 0 : GetCurrFrm( FALSE );
+ if( LTYPE_DRAW==eType || pCnt )
+ {
+ StartAllAction();
+
+ ULONG nIdx = 0;
+ SwFlyFrmFmt* pFlyFmt = 0;
+ switch( eType )
+ {
+ case LTYPE_OBJECT:
+ case LTYPE_FLY:
+ if( pCnt->IsInFly() )
+ {
+ //Bei Flys den Index auf den StartNode herunterreichen.
+ nIdx = pCnt->FindFlyFrm()->
+ GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
+//warum?? Bug 61913 ParkCrsr( GetCrsr()->GetPoint()->nNode );
+ }
+ break;
+ case LTYPE_TABLE:
+ if( pCnt->IsInTab() )
+ {
+ //Bei Tabellen den Index auf den TblNode herunterreichen.
+ const SwTable& rTbl = *pCnt->FindTabFrm()->GetTable();
+ nIdx = rTbl.GetTabSortBoxes()[ 0 ]
+ ->GetSttNd()->FindTableNode()->GetIndex();
+ }
+ break;
+ case LTYPE_DRAW:
+ if( Imp()->GetDrawView() )
+ {
+ SwDrawView *pDView = Imp()->GetDrawView();
+ const SdrMarkList& rMrkList = pDView->GetMarkedObjectList();
+ StartUndo();
+
+ // OD 27.11.2003 #112045# - copy marked drawing objects to
+ // local list to perform the corresponding action for each object
+ std::vector<SdrObject*> aDrawObjs;
+ {
+ for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject* pDrawObj = rMrkList.GetMark(i)->GetMarkedSdrObj();
+ aDrawObjs.push_back( pDrawObj );
+ }
+ }
+ // loop on marked drawing objects
+ while ( !aDrawObjs.empty() )
+ {
+ SdrObject* pDrawObj = aDrawObjs.back();
+ if ( !pDrawObj->ISA(SwVirtFlyDrawObj) &&
+ !pDrawObj->ISA(SwFlyDrawObj) )
+ {
+ SwFlyFrmFmt *pFmt =
+ GetDoc()->InsertDrawLabel( rTxt, rSeparator, rNumberSeparator, nId, rCharacterStyle, *pDrawObj );
+ if( !pFlyFmt )
+ pFlyFmt = pFmt;
+ }
+
+ aDrawObjs.pop_back();
+ }
+
+ EndUndo();
+ }
+ break;
+ default:
+ ASSERT( !this, "Crsr weder in Tabelle noch in Fly." );
+ }
+
+ if( nIdx )
+ pFlyFmt = GetDoc()->InsertLabel( eType, rTxt, rSeparator, rNumberSeparator, bBefore, nId,
+ nIdx, rCharacterStyle, bCpyBrd );
+
+ SwFlyFrm* pFrm;
+ const Point aPt( GetCrsrDocPos() );
+ if( pFlyFmt && 0 != ( pFrm = pFlyFmt->GetFrm( &aPt )))
+ SelectFlyFrm( *pFrm, TRUE );
+
+ EndAllActionAndCall();
+ }
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : Sort
+#* Datum : ??
+#* Update : ??
+#***********************************************************************/
+
+BOOL SwFEShell::Sort(const SwSortOptions& rOpt)
+{
+ if( !HasSelection() )
+ return FALSE;
+
+ SET_CURR_SHELL( this );
+ BOOL bRet;
+ StartAllAction();
+ if(IsTableMode())
+ {
+ // Tabelle sortieren
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm( FALSE );
+ ASSERT( pFrm->FindTabFrm(), "Crsr nicht in Tabelle." );
+
+ // lasse ueber das Layout die Boxen suchen
+ SwSelBoxes aBoxes;
+ GetTblSel(*this, aBoxes);
+
+ // die Crsr muessen noch aus dem Loesch Bereich entfernt
+ // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+ // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+ while( !pFrm->IsCellFrm() )
+ pFrm = pFrm->GetUpper();
+ {
+ /* #107993# ParkCursor->ParkCursorTab */
+ ParkCursorInTab();
+ }
+
+ // Sorting am Dokument aufrufen
+ bRet = pDoc->SortTbl(aBoxes, rOpt);
+ }
+ else
+ {
+ // Text sortieren und nichts anderes
+ FOREACHPAM_START(this)
+
+ SwPaM* pPam = PCURCRSR;
+
+ SwPosition* pStart = pPam->Start();
+ SwPosition* pEnd = pPam->End();
+
+ SwNodeIndex aPrevIdx( pStart->nNode, -1 );
+ ULONG nOffset = pEnd->nNode.GetIndex() - pStart->nNode.GetIndex();
+ xub_StrLen nCntStt = pStart->nContent.GetIndex();
+
+ // Das Sortieren
+ bRet = pDoc->SortText(*pPam, rOpt);
+
+ // Selektion wieder setzen
+ pPam->DeleteMark();
+ pPam->GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
+ SwCntntNode* pCNd = pPam->GetCntntNode();
+ xub_StrLen nLen = pCNd->Len();
+ if( nLen > nCntStt )
+ nLen = nCntStt;
+ pPam->GetPoint()->nContent.Assign(pCNd, nLen );
+ pPam->SetMark();
+
+ pPam->GetPoint()->nNode += nOffset;
+ pCNd = pPam->GetCntntNode();
+ pPam->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
+
+ FOREACHPAM_END()
+ }
+
+ EndAllAction();
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetCurColNum(), _GetColNum()
+|*
+|* Ersterstellung MA 03. Feb. 95
+|* Letzte Aenderung MA 20. Apr. 95
+|
+|*************************************************************************/
+
+USHORT SwFEShell::_GetCurColNum( const SwFrm *pFrm,
+ SwGetCurColNumPara* pPara ) const
+{
+ USHORT nRet = 0;
+ while ( pFrm )
+ {
+ pFrm = pFrm->GetUpper();
+ if( pFrm && pFrm->IsColumnFrm() )
+ {
+ const SwFrm *pCurFrm = pFrm;
+ do {
+ ++nRet;
+ pFrm = pFrm->GetPrev();
+ } while ( pFrm );
+
+ if( pPara )
+ {
+ // dann suche mal das Format, was diese Spaltigkeit bestimmt
+ pFrm = pCurFrm->GetUpper();
+ while( pFrm )
+ {
+ if( ( FRM_PAGE | FRM_FLY | FRM_SECTION ) & pFrm->GetType() )
+ {
+ pPara->pFrmFmt = ((SwLayoutFrm*)pFrm)->GetFmt();
+ pPara->pPrtRect = &pFrm->Prt();
+ pPara->pFrmRect = &pFrm->Frm();
+ break;
+ }
+ pFrm = pFrm->GetUpper();
+ }
+ if( !pFrm )
+ {
+ pPara->pFrmFmt = 0;
+ pPara->pPrtRect = 0;
+ pPara->pFrmRect = 0;
+ }
+ }
+ break;
+ }
+ }
+ return nRet;
+}
+
+USHORT SwFEShell::GetCurColNum( SwGetCurColNumPara* pPara ) const
+{
+ ASSERT( GetCurrFrm(), "Crsr geparkt?" );
+ return _GetCurColNum( GetCurrFrm(), pPara );
+}
+
+USHORT SwFEShell::GetCurOutColNum( SwGetCurColNumPara* pPara ) const
+{
+ USHORT nRet = 0;
+ SwFrm* pFrm = GetCurrFrm();
+ ASSERT( pFrm, "Crsr geparkt?" );
+ if( pFrm )
+ {
+ pFrm = pFrm->IsInTab() ? (SwFrm*)pFrm->FindTabFrm()
+ : (SwFrm*)pFrm->FindSctFrm();
+ ASSERT( pFrm, "No Tab, no Sect" );
+ if( pFrm )
+ nRet = _GetCurColNum( pFrm, pPara );
+ }
+ return nRet;
+}
+
+SwFEShell::SwFEShell( SwDoc& rDoc, Window *pWindow, const SwViewOption *pOptions )
+ : SwEditShell( rDoc, pWindow, pOptions ),
+ pChainFrom( 0 ), pChainTo( 0 ), bCheckForOLEInCaption( FALSE )
+{
+}
+
+SwFEShell::SwFEShell( SwEditShell& rShell, Window *pWindow )
+ : SwEditShell( rShell, pWindow ),
+ pChainFrom( 0 ), pChainTo( 0 ), bCheckForOLEInCaption( FALSE )
+{
+}
+
+SwFEShell::~SwFEShell()
+{
+ delete pChainFrom;
+ delete pChainTo;
+}
+
+// OD 18.09.2003 #i17567#, #108749#, #110354# - adjustments for allowing
+// negative vertical positions for fly frames anchored to paragraph/to character.
+// OD 06.11.2003 #i22305# - adjustments for option 'Follow text flow'
+// for to frame anchored objects.
+// OD 12.11.2003 #i22341# - adjustments for vertical alignment at top of line
+// for to character anchored objects.
+void SwFEShell::CalcBoundRect( SwRect& _orRect,
+ const RndStdIds _nAnchorId,
+ const sal_Int16 _eHoriRelOrient,
+ const sal_Int16 _eVertRelOrient,
+ const SwPosition* _pToCharCntntPos,
+ const bool _bFollowTextFlow,
+ bool _bMirror,
+ Point* _opRef,
+ Size* _opPercent ) const
+{
+ const SwFrm* pFrm;
+ const SwFlyFrm* pFly;
+ if( _opRef )
+ {
+ pFrm = GetCurrFrm();
+ if( 0 != ( pFly = pFrm->FindFlyFrm() ) )
+ pFrm = pFly->GetAnchorFrm();
+ }
+ else
+ {
+ pFly = FindFlyFrm();
+ pFrm = pFly ? pFly->GetAnchorFrm() : GetCurrFrm();
+ }
+
+ sal_Bool bWrapThrough = sal_False;
+ if ( pFly )
+ {
+ SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)pFly->GetFmt();
+ const SwFmtSurround& rSurround = pFmt->GetSurround();
+ bWrapThrough = rSurround.GetSurround() == SURROUND_THROUGHT;
+ }
+
+ const SwPageFrm* pPage = pFrm->FindPageFrm();
+ _bMirror = _bMirror && !pPage->OnRightPage();
+
+ Point aPos;
+ BOOL bVertic = FALSE;
+ BOOL bRTL = FALSE;
+
+ if ((FLY_AT_PAGE == _nAnchorId) || (FLY_AT_FLY == _nAnchorId)) // LAYER_IMPL
+ {
+ const SwFrm* pTmp = pFrm;
+ // OD 06.11.2003 #i22305#
+ if ((FLY_AT_PAGE == _nAnchorId) ||
+ ((FLY_AT_FLY == _nAnchorId) && !_bFollowTextFlow))
+ {
+ pFrm = pPage;
+ }
+ else
+ {
+ pFrm = pFrm->FindFlyFrm();
+ }
+ if ( !pFrm )
+ pFrm = pTmp;
+ _orRect = pFrm->Frm();
+ SWRECTFN( pFrm )
+ bRTL = pFrm->IsRightToLeft();
+ if ( bRTL )
+ aPos = pFrm->Frm().TopRight();
+ else
+ aPos = (pFrm->Frm().*fnRect->fnGetPos)();
+
+ if( bVert )
+ {
+ bVertic = TRUE;
+ _bMirror = false; // no mirroring in vertical environment
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::PAGE_RIGHT:
+ case text::RelOrientation::FRAME_RIGHT: aPos.Y() += pFrm->Prt().Height();
+ // no break!
+ case text::RelOrientation::PRINT_AREA:
+ case text::RelOrientation::PAGE_PRINT_AREA: aPos.Y() += pFrm->Prt().Top(); break;
+ default: break;
+ }
+ }
+ else if ( _bMirror )
+ {
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::PRINT_AREA:
+ case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Width();
+ // kein break
+ case text::RelOrientation::PAGE_RIGHT:
+ case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
+ default: aPos.X() += pFrm->Frm().Width();
+ }
+ }
+ else if ( bRTL )
+ {
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::PRINT_AREA:
+ case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Width();
+ // kein break!
+ case text::RelOrientation::PAGE_LEFT:
+ case text::RelOrientation::FRAME_LEFT: aPos.X() += pFrm->Prt().Left() -
+ pFrm->Frm().Width(); break;
+ default: break;
+ }
+ }
+ else
+ {
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::PAGE_RIGHT:
+ case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Width();
+ // kein break!
+ case text::RelOrientation::PRINT_AREA:
+ case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Left(); break;
+ default:break;
+ }
+ }
+ // --> OD 2006-12-12 #i67221# - proposed patch
+ if( bVert )
+ {
+ switch ( _eVertRelOrient )
+ {
+ case text::RelOrientation::PRINT_AREA:
+ case text::RelOrientation::PAGE_PRINT_AREA:
+ {
+ aPos.X() -= pFrm->GetRightMargin();
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch ( _eVertRelOrient )
+ {
+ case text::RelOrientation::PRINT_AREA:
+ case text::RelOrientation::PAGE_PRINT_AREA:
+ {
+ if ( pFrm->IsPageFrm() )
+ {
+ aPos.Y() =
+ static_cast<const SwPageFrm*>(pFrm)->PrtWithoutHeaderAndFooter().Top();
+ }
+ else
+ {
+ aPos.Y() += pFrm->Prt().Top();
+ }
+ }
+ break;
+ }
+ }
+ // <--
+ if ( _opPercent )
+ *_opPercent = pFrm->Prt().SSize();
+ }
+ else
+ {
+ const SwFrm* pUpper = ( pFrm->IsPageFrm() || pFrm->IsFlyFrm() ) ?
+ pFrm : pFrm->GetUpper();
+ SWRECTFN( pUpper );
+ if ( _opPercent )
+ *_opPercent = pUpper->Prt().SSize();
+
+ bRTL = pFrm->IsRightToLeft();
+ if ( bRTL )
+ aPos = pFrm->Frm().TopRight();
+ else
+ aPos = (pFrm->Frm().*fnRect->fnGetPos)();
+ // OD 08.09.2003 #i17567#, #108749#, #110354# - allow negative positions
+ // for fly frames anchor to paragraph/to character.
+ if ((_nAnchorId == FLY_AT_PARA) || (_nAnchorId == FLY_AT_CHAR))
+ {
+ // The rectangle, the fly frame can be positioned in, is determined
+ // horizontally by the frame area of the horizontal environment
+ // and vertically by the printing area of the vertical environment,
+ // if the object follows the text flow, or by the frame area of the
+ // vertical environment, if the object doesn't follow the text flow.
+ // OD 29.10.2003 #113049# - new class <SwEnvironmentOfAnchoredObject>
+ objectpositioning::SwEnvironmentOfAnchoredObject aEnvOfObj(
+ _bFollowTextFlow );
+ const SwLayoutFrm& rHoriEnvironLayFrm =
+ aEnvOfObj.GetHoriEnvironmentLayoutFrm( *pFrm );
+ const SwLayoutFrm& rVertEnvironLayFrm =
+ aEnvOfObj.GetVertEnvironmentLayoutFrm( *pFrm );
+ SwRect aHoriEnvironRect( rHoriEnvironLayFrm.Frm() );
+ SwRect aVertEnvironRect;
+ if ( _bFollowTextFlow )
+ {
+ aVertEnvironRect = rVertEnvironLayFrm.Prt();
+ aVertEnvironRect.Pos() += rVertEnvironLayFrm.Frm().Pos();
+ // OD 19.09.2003 #i18732# - adjust vertical 'virtual' anchor position
+ // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
+ // to page areas.
+ if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
+ {
+ if ( bVert )
+ {
+ aPos.X() = aVertEnvironRect.Right();
+ }
+ else
+ {
+ aPos.Y() = aVertEnvironRect.Top();
+ }
+ }
+ }
+ else
+ {
+ ASSERT( rVertEnvironLayFrm.IsPageFrm(),
+ "<SwFEShell::CalcBoundRect(..)> - not following text flow, but vertical environment *not* page!" );
+ aVertEnvironRect = rVertEnvironLayFrm.Frm();
+ // OD 19.09.2003 #i18732# - adjustment vertical 'virtual' anchor position
+ // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
+ // to page areas.
+ if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
+ {
+ if ( bVert )
+ {
+ aPos.X() = aVertEnvironRect.Right();
+ if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
+ {
+ aPos.X() -= rVertEnvironLayFrm.GetRightMargin();
+ }
+ }
+ else
+ {
+ aPos.Y() = aVertEnvironRect.Top();
+ if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
+ {
+ aPos.Y() += rVertEnvironLayFrm.GetTopMargin();
+ // add height of page header
+ const SwFrm* pTmpFrm = rVertEnvironLayFrm.Lower();
+ if ( pTmpFrm->IsHeaderFrm() )
+ {
+ aPos.Y() += pTmpFrm->Frm().Height();
+ }
+ }
+ }
+ }
+ }
+
+ // OD 12.11.2003 #i22341# - adjust vertical 'virtual' anchor position
+ // (<aPos.Y()> respectively <aPos.X()>), if object is anchored to
+ // character and vertical aligned at character or top of line
+ // --> OD 2005-12-29 #125800#
+ // <pFrm>, which is the anchor frame or the proposed anchor frame,
+ // doesn't have to be a text frame (e.g. edit a to-page anchored
+ // fly frame). Thus, assure this.
+ const SwTxtFrm* pTxtFrm( dynamic_cast<const SwTxtFrm*>(pFrm) );
+ if ( pTxtFrm &&
+ (_nAnchorId == FLY_AT_CHAR) &&
+ ( _eVertRelOrient == text::RelOrientation::CHAR ||
+ _eVertRelOrient == text::RelOrientation::TEXT_LINE ) )
+ {
+ SwTwips nTop = 0L;
+ if ( _eVertRelOrient == text::RelOrientation::CHAR )
+ {
+ SwRect aChRect;
+ if ( _pToCharCntntPos )
+ {
+ pTxtFrm->GetAutoPos( aChRect, *_pToCharCntntPos );
+ }
+ else
+ {
+ // No content position provided. Thus, use a default one.
+ SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
+ pTxtFrm->GetAutoPos( aChRect, aDefaultCntntPos );
+ }
+ nTop = (aChRect.*fnRect->fnGetBottom)();
+ }
+ else
+ {
+ if ( _pToCharCntntPos )
+ {
+ pTxtFrm->GetTopOfLine( nTop, *_pToCharCntntPos );
+ }
+ else
+ {
+ // No content position provided. Thus, use a default one.
+ SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
+ pTxtFrm->GetTopOfLine( nTop, aDefaultCntntPos );
+ }
+ }
+ if ( bVert )
+ {
+ aPos.X() = nTop;
+ }
+ else
+ {
+ aPos.Y() = nTop;
+ }
+ }
+
+ // --> OD 2004-10-05 #i26945# - adjust horizontal 'virtual' anchor
+ // position (<aPos.X()> respectively <aPos.Y()>), if object is
+ // anchored to character and horizontal aligned at character.
+ if ( pTxtFrm &&
+ (_nAnchorId == FLY_AT_CHAR) &&
+ _eHoriRelOrient == text::RelOrientation::CHAR )
+ {
+ SwTwips nLeft = 0L;
+ SwRect aChRect;
+ if ( _pToCharCntntPos )
+ {
+ pTxtFrm->GetAutoPos( aChRect, *_pToCharCntntPos );
+ }
+ else
+ {
+ // No content position provided. Thus, use a default one.
+ SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
+ pTxtFrm->GetAutoPos( aChRect, aDefaultCntntPos );
+ }
+ nLeft = (aChRect.*fnRect->fnGetLeft)();
+ if ( bVert )
+ {
+ aPos.Y() = nLeft;
+ }
+ else
+ {
+ aPos.X() = nLeft;
+ }
+ }
+ // <--
+
+ if ( bVert )
+ {
+ _orRect = SwRect( aVertEnvironRect.Left(),
+ aHoriEnvironRect.Top(),
+ aVertEnvironRect.Width(),
+ aHoriEnvironRect.Height() );
+ }
+ else
+ {
+ _orRect = SwRect( aHoriEnvironRect.Left(),
+ aVertEnvironRect.Top(),
+ aHoriEnvironRect.Width(),
+ aVertEnvironRect.Height() );
+ }
+ }
+ else
+ {
+ if( _opRef && pFly && pFly->IsFlyInCntFrm() )
+ *_opRef = ( (SwFlyInCntFrm*)pFly )->GetRefPoint();
+
+ _orRect = pUpper->Frm();
+ if( !pUpper->IsBodyFrm() )
+ {
+ _orRect += pUpper->Prt().Pos();
+ _orRect.SSize( pUpper->Prt().SSize() );
+ if ( pUpper->IsCellFrm() )//MA_FLY_HEIGHT
+ {
+ const SwFrm* pTab = pUpper->FindTabFrm();
+ long nBottom = (pTab->GetUpper()->*fnRect->fnGetPrtBottom)();
+ (_orRect.*fnRect->fnSetBottom)( nBottom );
+ }
+ }
+ // bei zeichengebundenen lieber nur 90% der Hoehe ausnutzen
+ {
+ if( bVert )
+ _orRect.Width( (_orRect.Width()*9)/10 );
+ else
+ _orRect.Height( (_orRect.Height()*9)/10 );
+ }
+ }
+
+ const SwTwips nBaseOfstForFly = ( pFrm->IsTxtFrm() && pFly ) ?
+ ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( !bWrapThrough ) :
+ 0;
+ if( bVert )
+ {
+ bVertic = TRUE;
+ _bMirror = false;
+
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::FRAME_RIGHT: aPos.Y() += pFrm->Prt().Height();
+ aPos += (pFrm->Prt().*fnRect->fnGetPos)();
+ break;
+ case text::RelOrientation::PRINT_AREA: aPos += (pFrm->Prt().*fnRect->fnGetPos)();
+ aPos.Y() += nBaseOfstForFly;
+ break;
+ case text::RelOrientation::PAGE_RIGHT: aPos.Y() = pPage->Frm().Top()
+ + pPage->Prt().Bottom(); break;
+ case text::RelOrientation::PAGE_PRINT_AREA: aPos.Y() = pPage->Frm().Top()
+ + pPage->Prt().Top(); break;
+ case text::RelOrientation::PAGE_LEFT:
+ case text::RelOrientation::PAGE_FRAME: aPos.Y() = pPage->Frm().Top(); break;
+ case text::RelOrientation::FRAME: aPos.Y() += nBaseOfstForFly; break;
+ default: break;
+ }
+ }
+ else if( _bMirror )
+ {
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
+ case text::RelOrientation::FRAME:
+ case text::RelOrientation::FRAME_LEFT: aPos.X() += pFrm->Frm().Width(); break;
+ case text::RelOrientation::PRINT_AREA: aPos.X() += pFrm->Prt().Right(); break;
+ case text::RelOrientation::PAGE_LEFT:
+ case text::RelOrientation::PAGE_FRAME: aPos.X() = pPage->Frm().Right(); break;
+ case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() = pPage->Frm().Left()
+ + pPage->Prt().Left(); break;
+ default: break;
+ }
+ }
+ else if ( bRTL )
+ {
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::FRAME_LEFT:
+ aPos.X() = pFrm->Frm().Left() +
+ pFrm->Prt().Left();
+ break;
+
+ case text::RelOrientation::PRINT_AREA:
+ aPos.X() = pFrm->Frm().Left() + pFrm->Prt().Left() +
+ pFrm->Prt().Width();
+ aPos.X() += nBaseOfstForFly;
+ break;
+
+ case text::RelOrientation::PAGE_LEFT:
+ aPos.X() = pPage->Frm().Left() + pPage->Prt().Left();
+ break;
+
+ case text::RelOrientation::PAGE_PRINT_AREA:
+ aPos.X() = pPage->Frm().Left() + pPage->Prt().Left() +
+ pPage->Prt().Width() ;
+ break;
+
+ case text::RelOrientation::PAGE_RIGHT:
+ case text::RelOrientation::PAGE_FRAME:
+ aPos.X() = pPage->Frm().Right();
+ break;
+
+ case text::RelOrientation::FRAME:
+ aPos.X() += nBaseOfstForFly;
+ break;
+ default: break;
+ }
+ }
+ else
+ {
+ switch ( _eHoriRelOrient )
+ {
+ case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Width();
+ aPos += pFrm->Prt().Pos();
+ break;
+ case text::RelOrientation::PRINT_AREA: aPos += pFrm->Prt().Pos();
+ aPos.X() += nBaseOfstForFly;
+ break;
+ case text::RelOrientation::PAGE_RIGHT: aPos.X() = pPage->Frm().Left()
+ + pPage->Prt().Right(); break;
+ case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() = pPage->Frm().Left()
+ + pPage->Prt().Left(); break;
+ case text::RelOrientation::PAGE_LEFT:
+ case text::RelOrientation::PAGE_FRAME: aPos.X() = pPage->Frm().Left(); break;
+ case text::RelOrientation::FRAME: aPos.X() += nBaseOfstForFly; break;
+ default: break;
+ }
+ }
+
+ }
+ if( !_opRef )
+ {
+ if( bVertic )
+ _orRect.Pos( aPos.X() - _orRect.Width() - _orRect.Left(), _orRect.Top() - aPos.Y() );
+ else if ( bRTL )
+ _orRect.Pos( - ( _orRect.Right() - aPos.X() ), _orRect.Top() - aPos.Y() );
+ else
+ _orRect.Pos( _orRect.Left() - aPos.X(), _orRect.Top() - aPos.Y() );
+ if( _bMirror )
+ _orRect.Pos( -_orRect.Right(), _orRect.Top() );
+ }
+}
+
+Size SwFEShell::GetGraphicDefaultSize() const
+{
+ Size aRet;
+ SwFlyFrm *pFly = FindFlyFrm();
+ if ( pFly )
+ {
+ // --> OD 2004-09-24 #i32951# - due to issue #i28701# no format of a
+ // newly inserted Writer fly frame or its anchor frame is performed
+ // any more. Thus, it could be possible (e.g. on insert of a horizontal
+ // line) that the anchor frame isn't formatted and its printing area
+ // size is (0,0). If this is the case the printing area of the upper
+ // of the anchor frame is taken.
+ const SwFrm* pAnchorFrm = pFly->GetAnchorFrm();
+ aRet = pAnchorFrm->Prt().SSize();
+ if ( aRet.Width() == 0 && aRet.Height() == 0 &&
+ pAnchorFrm->GetUpper() )
+ {
+ aRet = pAnchorFrm->GetUpper()->Prt().SSize();
+ }
+ // <--
+
+ SwRect aBound;
+ CalcBoundRect( aBound, pFly->GetFmt()->GetAnchor().GetAnchorId());
+ if ( pFly->GetAnchorFrm()->IsVertical() )
+ aRet.Width() = aBound.Width();
+ else
+ aRet.Height() = aBound.Height();
+ }
+ return aRet;
+}
+/* -----------------------------12.08.2002 12:51------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwFEShell::IsFrmVertical(BOOL bEnvironment, BOOL& bRTL) const
+{
+ BOOL bVert = FALSE;
+ bRTL = FALSE;
+
+ if ( Imp()->HasDrawView() )
+ {
+ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
+ if( rMrkList.GetMarkCount() != 1 )
+ return bVert;
+
+ SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ // --> OD 2006-01-06 #123831# - make code robust:
+ if ( !pObj )
+ {
+ ASSERT( false,
+ "<SwFEShell::IsFrmVertical(..)> - missing SdrObject instance in marked object list -> This is a serious situation, please inform OD" );
+ return bVert;
+ }
+ // <--
+ // OD 2004-03-29 #i26791#
+ SwContact* pContact = static_cast<SwContact*>(GetUserCall( pObj ));
+ // --> OD 2006-01-06 #123831# - make code robust:
+ if ( !pContact )
+ {
+ ASSERT( false,
+ "<SwFEShell::IsFrmVertical(..)> - missing SwContact instance at marked object -> This is a serious situation, please inform OD" );
+ return bVert;
+ }
+ // <--
+ const SwFrm* pRef = pContact->GetAnchoredObj( pObj )->GetAnchorFrm();
+ // --> OD 2006-01-06 #123831# - make code robust:
+ if ( !pRef )
+ {
+ ASSERT( false,
+ "<SwFEShell::IsFrmVertical(..)> - missing anchor frame at marked object -> This is a serious situation, please inform OD" );
+ return bVert;
+ }
+ // <--
+
+ if ( pObj->ISA(SwVirtFlyDrawObj) && !bEnvironment )
+ pRef = static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
+
+ bVert = pRef->IsVertical();
+ bRTL = pRef->IsRightToLeft();
+ }
+
+ return bVert;
+}
+
+void SwFEShell::MoveObjectIfActive( svt::EmbeddedObjectRef&, const Point& )
+{
+ // does not do anything, only avoids crash if the method is used for wrong shell
+}
+
diff --git a/sw/source/core/frmedt/makefile.mk b/sw/source/core/frmedt/makefile.mk
new file mode 100644
index 000000000000..8b277f899425
--- /dev/null
+++ b/sw/source/core/frmedt/makefile.mk
@@ -0,0 +1,76 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=frmedt
+
+AUTOSEG=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : $(PRJ)$/inc$/swpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/inc$/sw.mk
+
+
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ fecopy.cxx \
+ fedesc.cxx \
+ fefly1.cxx \
+ feflyole.cxx \
+ feshview.cxx \
+ fetab.cxx \
+ fews.cxx \
+ tblsel.cxx
+
+
+
+SLOFILES = $(EXCEPTIONSFILES) \
+ $(SLO)$/fedesc.obj \
+ $(SLO)$/feflyole.obj \
+ $(SLO)$/feshview.obj \
+ $(SLO)$/fetab.obj \
+ $(SLO)$/tblsel.obj
+
+EXCEPTIONSFILES=\
+ $(SLO)$/fecopy.obj \
+ $(SLO)$/fefly1.obj \
+ $(SLO)$/fews.obj
+
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sw/source/core/frmedt/tblsel.cxx b/sw/source/core/frmedt/tblsel.cxx
new file mode 100644
index 000000000000..8cabf285e12b
--- /dev/null
+++ b/sw/source/core/frmedt/tblsel.cxx
@@ -0,0 +1,2728 @@
+/*************************************************************************
+ *
+ * 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 <editeng/boxitem.hxx>
+#include <editeng/protitem.hxx>
+#include <fmtanchr.hxx>
+#include <fmtfsize.hxx>
+#include <frmatr.hxx>
+#include <tblsel.hxx>
+#include <crsrsh.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+#include <pam.hxx>
+#include <ndtxt.hxx>
+#include <ndole.hxx>
+#include <swtable.hxx>
+#include <cntfrm.hxx>
+#include <tabfrm.hxx>
+#include <rowfrm.hxx>
+#include <cellfrm.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <viscrs.hxx>
+#include <swtblfmt.hxx>
+#include <undobj.hxx>
+#include <mvsave.hxx>
+// OD 26.08.2003 #i18103#
+#include <sectfrm.hxx>
+#include <frmtool.hxx>
+
+//siehe auch swtable.cxx
+#define COLFUZZY 20L
+
+// defines, die bestimmen, wie Tabellen Boxen gemergt werden:
+// - 1. alle leeren Zeilen entfernen, alle Boxen werden mit Blank,
+// alle Lines mit ParaBreak getrennt
+// - 2. alle leeren Zeilen und alle leeren Boxen am Anfang und Ende
+// entfernen, alle Boxen werden mit Blank,
+// alle Lines mit ParaBreak getrennt
+// - 3. alle leeren Boxen entfernen, alle Boxen werden mit Blank,
+// alle Lines mit ParaBreak getrennt
+
+#undef DEL_ONLY_EMPTY_LINES
+#undef DEL_EMPTY_BOXES_AT_START_AND_END
+#define DEL_ALL_EMPTY_BOXES
+
+
+_SV_IMPL_SORTAR_ALG( SwSelBoxes, SwTableBoxPtr )
+BOOL SwSelBoxes::Seek_Entry( const SwTableBoxPtr rSrch, USHORT* pFndPos ) const
+{
+ ULONG nIdx = rSrch->GetSttIdx();
+
+ USHORT nO = Count(), nM, nU = 0;
+ if( nO > 0 )
+ {
+ nO--;
+ while( nU <= nO )
+ {
+ nM = nU + ( nO - nU ) / 2;
+ if( (*this)[ nM ]->GetSttNd() == rSrch->GetSttNd() )
+ {
+ if( pFndPos )
+ *pFndPos = nM;
+ return TRUE;
+ }
+ else if( (*this)[ nM ]->GetSttIdx() < nIdx )
+ nU = nM + 1;
+ else if( nM == 0 )
+ {
+ if( pFndPos )
+ *pFndPos = nU;
+ return FALSE;
+ }
+ else
+ nO = nM - 1;
+ }
+ }
+ if( pFndPos )
+ *pFndPos = nU;
+ return FALSE;
+}
+
+
+SV_IMPL_PTRARR( SwCellFrms, SwCellFrm* )
+
+struct _CmpLPt
+{
+ Point aPos;
+ const SwTableBox* pSelBox;
+ BOOL bVert;
+
+ _CmpLPt( const Point& rPt, const SwTableBox* pBox, BOOL bVertical );
+
+ BOOL operator==( const _CmpLPt& rCmp ) const
+ { return X() == rCmp.X() && Y() == rCmp.Y() ? TRUE : FALSE; }
+
+ BOOL operator<( const _CmpLPt& rCmp ) const
+ {
+ if ( bVert )
+ return X() > rCmp.X() || ( X() == rCmp.X() && Y() < rCmp.Y() )
+ ? TRUE : FALSE;
+ else
+ return Y() < rCmp.Y() || ( Y() == rCmp.Y() && X() < rCmp.X() )
+ ? TRUE : FALSE;
+ }
+
+ long X() const { return aPos.X(); }
+ long Y() const { return aPos.Y(); }
+};
+
+
+SV_DECL_VARARR_SORT( _MergePos, _CmpLPt, 0, 40 )
+SV_IMPL_VARARR_SORT( _MergePos, _CmpLPt )
+
+SV_IMPL_PTRARR( _FndBoxes, _FndBox* )
+SV_IMPL_PTRARR( _FndLines, _FndLine* )
+
+
+struct _Sort_CellFrm
+{
+ const SwCellFrm* pFrm;
+
+ _Sort_CellFrm( const SwCellFrm& rCFrm )
+ : pFrm( &rCFrm ) {}
+};
+
+SV_DECL_VARARR( _Sort_CellFrms, _Sort_CellFrm, 16, 16 )
+SV_IMPL_VARARR( _Sort_CellFrms, _Sort_CellFrm )
+
+SV_IMPL_PTRARR( SwChartBoxes, SwTableBoxPtr );
+SV_IMPL_PTRARR( SwChartLines, SwChartBoxes* );
+
+const SwLayoutFrm *lcl_FindCellFrm( const SwLayoutFrm *pLay )
+{
+ while ( pLay && !pLay->IsCellFrm() )
+ pLay = pLay->GetUpper();
+ return pLay;
+}
+
+const SwLayoutFrm *lcl_FindNextCellFrm( const SwLayoutFrm *pLay )
+{
+ //Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche)
+ const SwLayoutFrm *pTmp = pLay;
+ do {
+ pTmp = pTmp->GetNextLayoutLeaf();
+ } while( pLay->IsAnLower( pTmp ) );
+
+ while( pTmp && !pTmp->IsCellFrm() )
+ pTmp = pTmp->GetUpper();
+ return pTmp;
+}
+
+void GetTblSelCrs( const SwCrsrShell &rShell, SwSelBoxes& rBoxes )
+{
+ if( rBoxes.Count() )
+ rBoxes.Remove( USHORT(0), rBoxes.Count() );
+ if( rShell.IsTableMode() && ((SwCrsrShell&)rShell).UpdateTblSelBoxes())
+ rBoxes.Insert( &rShell.GetTableCrsr()->GetBoxes() );
+}
+
+void GetTblSelCrs( const SwTableCursor& rTblCrsr, SwSelBoxes& rBoxes )
+{
+ if( rBoxes.Count() )
+ rBoxes.Remove( USHORT(0), rBoxes.Count() );
+
+ if( rTblCrsr.IsChgd() || !rTblCrsr.GetBoxesCount() )
+ {
+ SwTableCursor* pTCrsr = (SwTableCursor*)&rTblCrsr;
+ pTCrsr->GetDoc()->GetRootFrm()->MakeTblCrsrs( *pTCrsr );
+ }
+
+ if( rTblCrsr.GetBoxesCount() )
+ rBoxes.Insert( &rTblCrsr.GetBoxes() );
+}
+
+void GetTblSel( const SwCrsrShell& rShell, SwSelBoxes& rBoxes,
+ const SwTblSearchType eSearchType )
+{
+ //Start- und Endzelle besorgen und den naechsten fragen.
+ if ( !rShell.IsTableMode() )
+ rShell.GetCrsr();
+
+ GetTblSel( *rShell.getShellCrsr(false), rBoxes, eSearchType );
+}
+
+void GetTblSel( const SwCursor& rCrsr, SwSelBoxes& rBoxes,
+ const SwTblSearchType eSearchType )
+{
+ //Start- und Endzelle besorgen und den naechsten fragen.
+ ASSERT( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( FALSE ),
+ "Tabselection nicht auf Cnt." );
+
+ // Zeilen-Selektion:
+ // teste ob Tabelle komplex ist. Wenn ja, dann immer uebers Layout
+ // die selektierten Boxen zusammen suchen. Andernfalls ueber die
+ // Tabellen-Struktur (fuer Makros !!)
+ const SwCntntNode* pContentNd = rCrsr.GetNode()->GetCntntNode();
+ const SwTableNode* pTblNd = pContentNd ? pContentNd->FindTableNode() : 0;
+ if( pTblNd && pTblNd->GetTable().IsNewModel() )
+ {
+ SwTable::SearchType eSearch;
+ switch( nsSwTblSearchType::TBLSEARCH_COL & eSearchType )
+ {
+ case nsSwTblSearchType::TBLSEARCH_ROW: eSearch = SwTable::SEARCH_ROW; break;
+ case nsSwTblSearchType::TBLSEARCH_COL: eSearch = SwTable::SEARCH_COL; break;
+ default: eSearch = SwTable::SEARCH_NONE; break;
+ }
+ const bool bChkP = 0 != ( nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
+ pTblNd->GetTable().CreateSelection( rCrsr, rBoxes, eSearch, bChkP );
+ return;
+ }
+ if( nsSwTblSearchType::TBLSEARCH_ROW == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) &&
+ pTblNd && !pTblNd->GetTable().IsTblComplex() )
+ {
+ const SwTable& rTbl = pTblNd->GetTable();
+ const SwTableLines& rLines = rTbl.GetTabLines();
+
+ const SwNode* pMarkNode = rCrsr.GetNode( FALSE );
+ const ULONG nMarkSectionStart = pMarkNode->StartOfSectionIndex();
+ const SwTableBox* pMarkBox = rTbl.GetTblBox( nMarkSectionStart );
+
+ ASSERT( pMarkBox, "Point in table, mark outside?" )
+
+ const SwTableLine* pLine = pMarkBox ? pMarkBox->GetUpper() : 0;
+ USHORT nSttPos = rLines.GetPos( pLine );
+ ASSERT( USHRT_MAX != nSttPos, "Wo ist meine Zeile in der Tabelle?" );
+ pLine = rTbl.GetTblBox( rCrsr.GetNode( TRUE )->StartOfSectionIndex() )->GetUpper();
+ USHORT nEndPos = rLines.GetPos( pLine );
+ ASSERT( USHRT_MAX != nEndPos, "Wo ist meine Zeile in der Tabelle?" );
+ // pb: #i20193# if tableintable then nSttPos == nEndPos == USHRT_MAX
+ if ( nSttPos != USHRT_MAX && nEndPos != USHRT_MAX )
+ {
+ if( nEndPos < nSttPos ) // vertauschen
+ {
+ USHORT nTmp = nSttPos; nSttPos = nEndPos; nEndPos = nTmp;
+ }
+
+ int bChkProtected = nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType;
+ for( ; nSttPos <= nEndPos; ++nSttPos )
+ {
+ pLine = rLines[ nSttPos ];
+ for( USHORT n = pLine->GetTabBoxes().Count(); n ; )
+ {
+ SwTableBox* pBox = pLine->GetTabBoxes()[ --n ];
+ // Zellenschutzt beachten ??
+ if( !bChkProtected ||
+ !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ rBoxes.Insert( pBox );
+ }
+ }
+ }
+ }
+ else
+ {
+ Point aPtPos, aMkPos;
+ const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
+ if( pShCrsr )
+ {
+ aPtPos = pShCrsr->GetPtPos();
+ aMkPos = pShCrsr->GetMkPos();
+ }
+ const SwCntntNode *pCntNd = rCrsr.GetCntntNode();
+ const SwLayoutFrm *pStart = pCntNd ?
+ pCntNd->GetFrm( &aPtPos )->GetUpper() : 0;
+ pCntNd = rCrsr.GetCntntNode(FALSE);
+ const SwLayoutFrm *pEnd = pCntNd ?
+ pCntNd->GetFrm( &aMkPos )->GetUpper() : 0;
+ if( pStart && pEnd )
+ GetTblSel( pStart, pEnd, rBoxes, 0, eSearchType );
+ }
+}
+
+void GetTblSel( const SwLayoutFrm* pStart, const SwLayoutFrm* pEnd,
+ SwSelBoxes& rBoxes, SwCellFrms* pCells,
+ const SwTblSearchType eSearchType )
+{
+ // #112697# Robust:
+ const SwTabFrm* pStartTab = pStart->FindTabFrm();
+ if ( !pStartTab )
+ {
+ ASSERT( false, "GetTblSel without start table" )
+ return;
+ }
+
+ int bChkProtected = nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType;
+
+ BOOL bTblIsValid;
+ // --> FME 2006-01-25 #i55421# Reduced value 10
+ int nLoopMax = 10; //JP 28.06.99: max 100 loops - Bug 67292
+ // <--
+ USHORT i;
+
+ do {
+ bTblIsValid = TRUE;
+
+ //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+ SwSelUnions aUnions;
+ ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
+
+ Point aCurrentTopLeft( LONG_MAX, LONG_MAX );
+ Point aCurrentTopRight( 0, LONG_MAX );
+ Point aCurrentBottomLeft( LONG_MAX, 0 );
+ Point aCurrentBottomRight( 0, 0 );
+ const SwCellFrm* pCurrentTopLeftFrm = 0;
+ const SwCellFrm* pCurrentTopRightFrm = 0;
+ const SwCellFrm* pCurrentBottomLeftFrm = 0;
+ const SwCellFrm* pCurrentBottomRightFrm = 0;
+
+ //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+ for( i = 0; i < aUnions.Count() && bTblIsValid; ++i )
+ {
+ SwSelUnion *pUnion = aUnions[i];
+ const SwTabFrm *pTable = pUnion->GetTable();
+ if( !pTable->IsValid() && nLoopMax )
+ {
+ bTblIsValid = FALSE;
+ break;
+ }
+
+ // Skip any repeated headlines in the follow:
+ const SwLayoutFrm* pRow = pTable->IsFollow() ?
+ pTable->GetFirstNonHeadlineRow() :
+ (const SwLayoutFrm*)pTable->Lower();
+
+ while( pRow && bTblIsValid )
+ {
+ if( !pRow->IsValid() && nLoopMax )
+ {
+ bTblIsValid = FALSE;
+ break;
+ }
+
+ if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+ {
+ const SwLayoutFrm *pCell = pRow->FirstCell();
+
+ while( bTblIsValid && pCell && pRow->IsAnLower( pCell ) )
+ {
+ if( !pCell->IsValid() && nLoopMax )
+ {
+ bTblIsValid = FALSE;
+ break;
+ }
+
+ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+ if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+ {
+ SwTableBox* pBox = (SwTableBox*)
+ ((SwCellFrm*)pCell)->GetTabBox();
+ // Zellenschutzt beachten ??
+ if( !bChkProtected ||
+ !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ rBoxes.Insert( pBox );
+
+ if ( pCells )
+ {
+ const Point aTopLeft( pCell->Frm().TopLeft() );
+ const Point aTopRight( pCell->Frm().TopRight() );
+ const Point aBottomLeft( pCell->Frm().BottomLeft() );
+ const Point aBottomRight( pCell->Frm().BottomRight() );
+
+ if ( aTopLeft.Y() < aCurrentTopLeft.Y() ||
+ ( aTopLeft.Y() == aCurrentTopLeft.Y() &&
+ aTopLeft.X() < aCurrentTopLeft.X() ) )
+ {
+ aCurrentTopLeft = aTopLeft;
+ pCurrentTopLeftFrm = static_cast<const SwCellFrm*>( pCell );
+ }
+
+ if ( aTopRight.Y() < aCurrentTopRight.Y() ||
+ ( aTopRight.Y() == aCurrentTopRight.Y() &&
+ aTopRight.X() > aCurrentTopRight.X() ) )
+ {
+ aCurrentTopRight = aTopRight;
+ pCurrentTopRightFrm = static_cast<const SwCellFrm*>( pCell );
+ }
+
+ if ( aBottomLeft.Y() > aCurrentBottomLeft.Y() ||
+ ( aBottomLeft.Y() == aCurrentBottomLeft.Y() &&
+ aBottomLeft.X() < aCurrentBottomLeft.X() ) )
+ {
+ aCurrentBottomLeft = aBottomLeft;
+ pCurrentBottomLeftFrm = static_cast<const SwCellFrm*>( pCell );
+ }
+
+ if ( aBottomRight.Y() > aCurrentBottomRight.Y() ||
+ ( aBottomRight.Y() == aCurrentBottomRight.Y() &&
+ aBottomRight.X() > aCurrentBottomRight.X() ) )
+ {
+ aCurrentBottomRight = aBottomRight;
+ pCurrentBottomRightFrm = static_cast<const SwCellFrm*>( pCell );
+ }
+
+ }
+ }
+ if ( pCell->GetNext() )
+ {
+ pCell = (const SwLayoutFrm*)pCell->GetNext();
+ if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
+ pCell = pCell->FirstCell();
+ }
+ else
+ pCell = ::lcl_FindNextCellFrm( pCell );
+ }
+ }
+ pRow = (const SwLayoutFrm*)pRow->GetNext();
+ }
+ }
+
+ if ( pCells )
+ {
+ pCells->Remove( 0, pCells->Count() );
+ pCells->Insert( pCurrentTopLeftFrm, 0 );
+ pCells->Insert( pCurrentTopRightFrm, 1 );
+ pCells->Insert( pCurrentBottomLeftFrm, 2 );
+ pCells->Insert( pCurrentBottomRightFrm, 3 );
+ }
+
+ if( bTblIsValid )
+ break;
+
+ SwDeletionChecker aDelCheck( pStart );
+
+ // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
+ // und nochmals neu aufsetzen
+ SwTabFrm *pTable = aUnions[0]->GetTable();
+ while( pTable )
+ {
+ if( pTable->IsValid() )
+ pTable->InvalidatePos();
+ pTable->SetONECalcLowers();
+ pTable->Calc();
+ pTable->SetCompletePaint();
+ if( 0 == (pTable = pTable->GetFollow()) )
+ break;
+ }
+
+ // --> FME 2005-10-13 #125337# Make code robust, check if pStart has
+ // been deleted due to the formatting of the table:
+ if ( aDelCheck.HasBeenDeleted() )
+ {
+ ASSERT( false, "Current box has been deleted during GetTblSel()" )
+ break;
+ }
+ // <--
+
+ i = 0;
+ rBoxes.Remove( i, rBoxes.Count() );
+ --nLoopMax;
+
+ } while( TRUE );
+ ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
+}
+
+
+
+BOOL ChkChartSel( const SwNode& rSttNd, const SwNode& rEndNd,
+ SwChartLines* pGetCLines )
+{
+ const SwTableNode* pTNd = rSttNd.FindTableNode();
+ if( !pTNd )
+ return FALSE;
+
+ Point aNullPos;
+ SwNodeIndex aIdx( rSttNd );
+ const SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+ if( !pCNd )
+ pCNd = aIdx.GetNodes().GoNextSection( &aIdx, FALSE, FALSE );
+
+ // #109394# if table is invisible, return
+ // (layout needed for forming table selection further down, so we can't
+ // continue with invisible tables)
+ // OD 07.11.2003 #i22135# - Also the content of the table could be
+ // invisible - e.g. in a hidden section
+ // Robust: check, if content was found (e.g. empty table cells)
+ if ( !pCNd || pCNd->GetFrm() == NULL )
+ return FALSE;
+
+ const SwLayoutFrm *pStart = pCNd ? pCNd->GetFrm( &aNullPos )->GetUpper() : 0;
+ ASSERT( pStart, "ohne Frame geht gar nichts" );
+
+ aIdx = rEndNd;
+ pCNd = aIdx.GetNode().GetCntntNode();
+ if( !pCNd )
+ pCNd = aIdx.GetNodes().GoNextSection( &aIdx, FALSE, FALSE );
+
+ // OD 07.11.2003 #i22135# - Robust: check, if content was found and if it's visible
+ if ( !pCNd || pCNd->GetFrm() == NULL )
+ {
+ return FALSE;
+ }
+
+ const SwLayoutFrm *pEnd = pCNd ? pCNd->GetFrm( &aNullPos )->GetUpper() : 0;
+ ASSERT( pEnd, "ohne Frame geht gar nichts" );
+
+
+ BOOL bTblIsValid, bValidChartSel;
+ // --> FME 2006-01-25 #i55421# Reduced value 10
+ int nLoopMax = 10; //JP 28.06.99: max 100 loops - Bug 67292
+ // <--
+ USHORT i = 0;
+
+ do {
+ bTblIsValid = TRUE;
+ bValidChartSel = TRUE;
+
+ USHORT nRowCells = USHRT_MAX;
+
+ //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+ SwSelUnions aUnions;
+ ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_NO_UNION_CORRECT );
+
+ //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+ for( i = 0; i < aUnions.Count() && bTblIsValid &&
+ bValidChartSel; ++i )
+ {
+ SwSelUnion *pUnion = aUnions[i];
+ const SwTabFrm *pTable = pUnion->GetTable();
+
+ SWRECTFN( pTable )
+ sal_Bool bRTL = pTable->IsRightToLeft();
+
+ if( !pTable->IsValid() && nLoopMax )
+ {
+ bTblIsValid = FALSE;
+ break;
+ }
+
+ _Sort_CellFrms aCellFrms;
+
+ // Skip any repeated headlines in the follow:
+ const SwLayoutFrm* pRow = pTable->IsFollow() ?
+ pTable->GetFirstNonHeadlineRow() :
+ (const SwLayoutFrm*)pTable->Lower();
+
+ while( pRow && bTblIsValid && bValidChartSel )
+ {
+ if( !pRow->IsValid() && nLoopMax )
+ {
+ bTblIsValid = FALSE;
+ break;
+ }
+
+ if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+ {
+ const SwLayoutFrm *pCell = pRow->FirstCell();
+
+ while( bValidChartSel && bTblIsValid && pCell &&
+ pRow->IsAnLower( pCell ) )
+ {
+ if( !pCell->IsValid() && nLoopMax )
+ {
+ bTblIsValid = FALSE;
+ break;
+ }
+
+ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+ const SwRect& rUnion = pUnion->GetUnion(),
+ & rFrmRect = pCell->Frm();
+
+ const long nUnionRight = rUnion.Right();
+ const long nUnionBottom = rUnion.Bottom();
+ const long nFrmRight = rFrmRect.Right();
+ const long nFrmBottom = rFrmRect.Bottom();
+
+ // liegt das FrmRect ausserhalb der Union, kann es
+ // ignoriert werden.
+
+ const long nXFuzzy = bVert ? 0 : 20;
+ const long nYFuzzy = bVert ? 20 : 0;
+
+ if( !( rUnion.Top() + nYFuzzy > nFrmBottom ||
+ nUnionBottom < rFrmRect.Top() + nYFuzzy ||
+ rUnion.Left() + nXFuzzy > nFrmRight ||
+ nUnionRight < rFrmRect.Left() + nXFuzzy ))
+ {
+ // ok, rUnion is _not_ completely outside of rFrmRect
+
+ // wenn es aber nicht komplett in der Union liegt,
+ // dann ist es fuers Chart eine ungueltige
+ // Selektion.
+ if( rUnion.Left() <= rFrmRect.Left() + nXFuzzy &&
+ rFrmRect.Left() <= nUnionRight &&
+ rUnion.Left() <= nFrmRight &&
+ nFrmRight <= nUnionRight + nXFuzzy &&
+ rUnion.Top() <= rFrmRect.Top() + nYFuzzy &&
+ rFrmRect.Top() <= nUnionBottom &&
+ rUnion.Top() <= nFrmBottom &&
+ nFrmBottom <= nUnionBottom+ nYFuzzy )
+
+ aCellFrms.Insert(
+ _Sort_CellFrm( *(SwCellFrm*)pCell ),
+ aCellFrms.Count() );
+ else
+ {
+ bValidChartSel = FALSE;
+ break;
+ }
+ }
+ if ( pCell->GetNext() )
+ {
+ pCell = (const SwLayoutFrm*)pCell->GetNext();
+ if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
+ pCell = pCell->FirstCell();
+ }
+ else
+ pCell = ::lcl_FindNextCellFrm( pCell );
+ }
+ }
+ pRow = (const SwLayoutFrm*)pRow->GetNext();
+ }
+
+ if( !bValidChartSel )
+ break;
+
+ // alle Zellen der (Teil-)Tabelle zusammen. Dann teste mal ob
+ // all huebsch nebeneinander liegen.
+ USHORT n, nEnd, nCellCnt = 0;
+ long nYPos = LONG_MAX;
+ long nXPos = 0;
+ long nHeight = 0;
+
+ for( n = 0, nEnd = aCellFrms.Count(); n < nEnd; ++n )
+ {
+ const _Sort_CellFrm& rCF = aCellFrms[ n ];
+ if( (rCF.pFrm->Frm().*fnRect->fnGetTop)() != nYPos )
+ {
+ // neue Zeile
+ if( n )
+ {
+ if( USHRT_MAX == nRowCells ) // 1. Zeilenwechsel
+ nRowCells = nCellCnt;
+ else if( nRowCells != nCellCnt )
+ {
+ bValidChartSel = FALSE;
+ break;
+ }
+ }
+ nCellCnt = 1;
+ nYPos = (rCF.pFrm->Frm().*fnRect->fnGetTop)();
+ nHeight = (rCF.pFrm->Frm().*fnRect->fnGetHeight)();
+
+ nXPos = bRTL ?
+ (rCF.pFrm->Frm().*fnRect->fnGetLeft)() :
+ (rCF.pFrm->Frm().*fnRect->fnGetRight)();
+ }
+ else if( nXPos == ( bRTL ?
+ (rCF.pFrm->Frm().*fnRect->fnGetRight)() :
+ (rCF.pFrm->Frm().*fnRect->fnGetLeft)() ) &&
+ nHeight == (rCF.pFrm->Frm().*fnRect->fnGetHeight)() )
+ {
+ nXPos += ( bRTL ? (-1) : 1 ) *
+ (rCF.pFrm->Frm().*fnRect->fnGetWidth)();
+ ++nCellCnt;
+ }
+ else
+ {
+ bValidChartSel = FALSE;
+ break;
+ }
+ }
+ if( bValidChartSel )
+ {
+ if( USHRT_MAX == nRowCells )
+ nRowCells = nCellCnt;
+ else if( nRowCells != nCellCnt )
+ bValidChartSel = FALSE;
+ }
+
+ if( bValidChartSel && pGetCLines )
+ {
+ nYPos = LONG_MAX;
+ SwChartBoxes* pBoxes = 0;
+ for( n = 0, nEnd = aCellFrms.Count(); n < nEnd; ++n )
+ {
+ const _Sort_CellFrm& rCF = aCellFrms[ n ];
+ if( (rCF.pFrm->Frm().*fnRect->fnGetTop)() != nYPos )
+ {
+ pBoxes = new SwChartBoxes( 255 < nRowCells
+ ? 255 : (BYTE)nRowCells);
+ pGetCLines->C40_INSERT( SwChartBoxes, pBoxes, pGetCLines->Count() );
+ nYPos = (rCF.pFrm->Frm().*fnRect->fnGetTop)();
+ }
+ SwTableBoxPtr pBox = (SwTableBox*)rCF.pFrm->GetTabBox();
+ pBoxes->Insert( pBox, pBoxes->Count() );
+ }
+ }
+ }
+
+ if( bTblIsValid )
+ break;
+
+ // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
+ // und nochmals neu aufsetzen
+ SwTabFrm *pTable = aUnions[0]->GetTable();
+ for( i = 0; i < aUnions.Count(); ++i )
+ {
+ if( pTable->IsValid() )
+ pTable->InvalidatePos();
+ pTable->SetONECalcLowers();
+ pTable->Calc();
+ pTable->SetCompletePaint();
+ if( 0 == (pTable = pTable->GetFollow()) )
+ break;
+ }
+ --nLoopMax;
+ if( pGetCLines )
+ pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
+ } while( TRUE );
+
+ ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
+
+ if( !bValidChartSel && pGetCLines )
+ pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
+
+ return bValidChartSel;
+}
+
+
+BOOL IsFrmInTblSel( const SwRect& rUnion, const SwFrm* pCell )
+{
+ ASSERT( pCell->IsCellFrm(), "Frame ohne Gazelle" );
+
+ if( pCell->FindTabFrm()->IsVertical() )
+ return ( rUnion.Right() >= pCell->Frm().Right() &&
+ rUnion.Left() <= pCell->Frm().Left() &&
+ (( rUnion.Top() <= pCell->Frm().Top()+20 &&
+ rUnion.Bottom() > pCell->Frm().Top() ) ||
+ ( rUnion.Top() >= pCell->Frm().Top() &&
+ rUnion.Bottom() < pCell->Frm().Bottom() )) ? TRUE : FALSE );
+
+ return (
+ rUnion.Top() <= pCell->Frm().Top() &&
+ rUnion.Bottom() >= pCell->Frm().Bottom() &&
+
+ (( rUnion.Left() <= pCell->Frm().Left()+20 &&
+ rUnion.Right() > pCell->Frm().Left() ) ||
+
+ ( rUnion.Left() >= pCell->Frm().Left() &&
+ rUnion.Right() < pCell->Frm().Right() )) ? TRUE : FALSE );
+}
+
+BOOL GetAutoSumSel( const SwCrsrShell& rShell, SwCellFrms& rBoxes )
+{
+ SwShellCrsr* pCrsr = rShell.pCurCrsr;
+ if ( rShell.IsTableMode() )
+ pCrsr = rShell.pTblCrsr;
+
+ const SwLayoutFrm *pStart = pCrsr->GetCntntNode()->GetFrm(
+ &pCrsr->GetPtPos() )->GetUpper(),
+ *pEnd = pCrsr->GetCntntNode(FALSE)->GetFrm(
+ &pCrsr->GetMkPos() )->GetUpper();
+
+ const SwLayoutFrm* pSttCell = pStart;
+ while( pSttCell && !pSttCell->IsCellFrm() )
+ pSttCell = pSttCell->GetUpper();
+
+ //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+ SwSelUnions aUnions;
+
+ // default erstmal nach oben testen, dann nach links
+ ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_COL );
+
+ BOOL bTstRow = TRUE, bFound = FALSE;
+ USHORT i;
+
+ // 1. teste ob die darueber liegende Box Value/Formel enhaelt:
+ for( i = 0; i < aUnions.Count(); ++i )
+ {
+ SwSelUnion *pUnion = aUnions[i];
+ const SwTabFrm *pTable = pUnion->GetTable();
+
+ // Skip any repeated headlines in the follow:
+ const SwLayoutFrm* pRow = pTable->IsFollow() ?
+ pTable->GetFirstNonHeadlineRow() :
+ (const SwLayoutFrm*)pTable->Lower();
+
+ while( pRow )
+ {
+ if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+ {
+ const SwCellFrm* pUpperCell = 0;
+ const SwLayoutFrm *pCell = pRow->FirstCell();
+
+ while( pCell && pRow->IsAnLower( pCell ) )
+ {
+ if( pCell == pSttCell )
+ {
+ USHORT nWhichId = 0;
+ for( USHORT n = rBoxes.Count(); n; )
+ if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
+ ->GetTabBox()->IsFormulaOrValueBox() ))
+ break;
+
+ // alle Boxen zusammen, nicht mehr die Zeile
+ // pruefen, wenn eine Formel oder Value gefunden wurde
+ bTstRow = 0 == nWhichId || USHRT_MAX == nWhichId;
+ bFound = TRUE;
+ break;
+ }
+
+ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+ if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+ pUpperCell = (SwCellFrm*)pCell;
+
+ if( pCell->GetNext() )
+ {
+ pCell = (const SwLayoutFrm*)pCell->GetNext();
+ if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
+ pCell = pCell->FirstCell();
+ }
+ else
+ pCell = ::lcl_FindNextCellFrm( pCell );
+ }
+
+ if( pUpperCell )
+ rBoxes.Insert( pUpperCell, rBoxes.Count() );
+ }
+ if( bFound )
+ {
+ i = aUnions.Count();
+ break;
+ }
+ pRow = (const SwLayoutFrm*)pRow->GetNext();
+ }
+ }
+
+
+ // 2. teste ob die links liegende Box Value/Formel enhaelt:
+ if( bTstRow )
+ {
+ bFound = FALSE;
+
+ rBoxes.Remove( 0, rBoxes.Count() );
+ aUnions.DeleteAndDestroy( 0, aUnions.Count() );
+ ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_ROW );
+
+ for( i = 0; i < aUnions.Count(); ++i )
+ {
+ SwSelUnion *pUnion = aUnions[i];
+ const SwTabFrm *pTable = pUnion->GetTable();
+
+ // Skip any repeated headlines in the follow:
+ const SwLayoutFrm* pRow = pTable->IsFollow() ?
+ pTable->GetFirstNonHeadlineRow() :
+ (const SwLayoutFrm*)pTable->Lower();
+
+ while( pRow )
+ {
+ if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+ {
+ const SwLayoutFrm *pCell = pRow->FirstCell();
+
+ while( pCell && pRow->IsAnLower( pCell ) )
+ {
+ if( pCell == pSttCell )
+ {
+ USHORT nWhichId = 0;
+ for( USHORT n = rBoxes.Count(); n; )
+ if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
+ ->GetTabBox()->IsFormulaOrValueBox() ))
+ break;
+
+ // alle Boxen zusammen, nicht mehr die Zeile
+ // pruefen, wenn eine Formel oder Value gefunden wurde
+ bFound = 0 != nWhichId && USHRT_MAX != nWhichId;
+ bTstRow = FALSE;
+ break;
+ }
+
+ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+ if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+ {
+ const SwCellFrm* pC = (SwCellFrm*)pCell;
+ rBoxes.Insert( pC, rBoxes.Count() );
+ }
+ if( pCell->GetNext() )
+ {
+ pCell = (const SwLayoutFrm*)pCell->GetNext();
+ if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
+ pCell = pCell->FirstCell();
+ }
+ else
+ pCell = ::lcl_FindNextCellFrm( pCell );
+ }
+ }
+ if( !bTstRow )
+ {
+ i = aUnions.Count();
+ break;
+ }
+
+ pRow = (const SwLayoutFrm*)pRow->GetNext();
+ }
+ }
+ }
+
+ return bFound;
+}
+
+BOOL HasProtectedCells( const SwSelBoxes& rBoxes )
+{
+ BOOL bRet = FALSE;
+ for( USHORT n = 0, nCnt = rBoxes.Count(); n < nCnt; ++n )
+ if( rBoxes[ n ]->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ {
+ bRet = TRUE;
+ break;
+ }
+ return bRet;
+}
+
+
+_CmpLPt::_CmpLPt( const Point& rPt, const SwTableBox* pBox, BOOL bVertical )
+ : aPos( rPt ), pSelBox( pBox ), bVert( bVertical )
+{}
+
+void lcl_InsTblBox( SwTableNode* pTblNd, SwDoc* pDoc, SwTableBox* pBox,
+ USHORT nInsPos, USHORT nCnt = 1 )
+{
+ ASSERT( pBox->GetSttNd(), "Box ohne Start-Node" );
+ SwCntntNode* pCNd = pDoc->GetNodes()[ pBox->GetSttIdx() + 1 ]
+ ->GetCntntNode();
+ if( pCNd && pCNd->IsTxtNode() )
+ pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
+ (SwTableBoxFmt*)pBox->GetFrmFmt(),
+ ((SwTxtNode*)pCNd)->GetTxtColl(),
+ pCNd->GetpSwAttrSet(),
+ nInsPos, nCnt );
+ else
+ pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
+ (SwTableBoxFmt*)pBox->GetFrmFmt(),
+ (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl(), 0,
+ nInsPos, nCnt );
+}
+
+BOOL IsEmptyBox( const SwTableBox& rBox, SwPaM& rPam )
+{
+ rPam.GetPoint()->nNode = *rBox.GetSttNd()->EndOfSectionNode();
+ rPam.Move( fnMoveBackward, fnGoCntnt );
+ rPam.SetMark();
+ rPam.GetPoint()->nNode = *rBox.GetSttNd();
+ rPam.Move( fnMoveForward, fnGoCntnt );
+ BOOL bRet = *rPam.GetMark() == *rPam.GetPoint()
+ && ( rBox.GetSttNd()->GetIndex() + 1 == rPam.GetPoint()->nNode.GetIndex() );
+
+ if( bRet )
+ {
+ // dann teste mal auf absatzgebundenen Flys
+ const SwSpzFrmFmts& rFmts = *rPam.GetDoc()->GetSpzFrmFmts();
+ ULONG nSttIdx = rPam.GetPoint()->nNode.GetIndex(),
+ nEndIdx = rBox.GetSttNd()->EndOfSectionIndex(),
+ nIdx;
+
+ for( USHORT n = 0; n < rFmts.Count(); ++n )
+ {
+ const SwFmtAnchor& rAnchor = rFmts[n]->GetAnchor();
+ const SwPosition* pAPos = rAnchor.GetCntntAnchor();
+ if (pAPos &&
+ ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
+ (FLY_AT_CHAR == rAnchor.GetAnchorId())) &&
+ nSttIdx <= ( nIdx = pAPos->nNode.GetIndex() ) &&
+ nIdx < nEndIdx )
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+ }
+ return bRet;
+}
+
+
+void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes,
+ SwTableBox** ppMergeBox, SwUndoTblMerge* pUndo )
+{
+ if( rBoxes.Count() )
+ rBoxes.Remove( USHORT(0), rBoxes.Count() );
+
+ //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+ ASSERT( rPam.GetCntntNode() && rPam.GetCntntNode( FALSE ),
+ "Tabselection nicht auf Cnt." );
+
+//JP 24.09.96: Merge mit wiederholenden TabellenHeadline funktioniert nicht
+// richtig. Warum nicht Point 0,0 benutzen? Dann ist garantiert,
+// das die 1. Headline mit drin ist.
+// Point aPt( rShell.GetCharRect().Pos() );
+ Point aPt( 0, 0 );
+ const SwLayoutFrm *pStart = rPam.GetCntntNode()->GetFrm(
+ &aPt )->GetUpper(),
+ *pEnd = rPam.GetCntntNode(FALSE)->GetFrm(
+ &aPt )->GetUpper();
+
+ SwSelUnions aUnions;
+ ::MakeSelUnions( aUnions, pStart, pEnd );
+ if( !aUnions.Count() )
+ return;
+
+ const SwTable *pTable = aUnions[0]->GetTable()->GetTable();
+ SwDoc* pDoc = (SwDoc*)pStart->GetFmt()->GetDoc();
+ SwTableNode* pTblNd = (SwTableNode*)pTable->GetTabSortBoxes()[ 0 ]->
+ GetSttNd()->FindTableNode();
+
+ _MergePos aPosArr; // Sort-Array mit den Positionen der Frames
+ long nWidth;
+ SwTableBox* pLastBox = 0;
+
+ SWRECTFN( pStart->GetUpper() )
+
+ for ( USHORT i = 0; i < aUnions.Count(); ++i )
+ {
+ const SwTabFrm *pTabFrm = aUnions[i]->GetTable();
+
+ SwRect &rUnion = aUnions[i]->GetUnion();
+
+ // Skip any repeated headlines in the follow:
+ const SwLayoutFrm* pRow = pTabFrm->IsFollow() ?
+ pTabFrm->GetFirstNonHeadlineRow() :
+ (const SwLayoutFrm*)pTabFrm->Lower();
+
+ while ( pRow )
+ {
+ if ( pRow->Frm().IsOver( rUnion ) )
+ {
+ const SwLayoutFrm *pCell = pRow->FirstCell();
+
+ while ( pCell && pRow->IsAnLower( pCell ) )
+ {
+ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+ // in der vollen Breite ueberlappend ?
+ if( rUnion.Top() <= pCell->Frm().Top() &&
+ rUnion.Bottom() >= pCell->Frm().Bottom() )
+ {
+ SwTableBox* pBox =(SwTableBox*)((SwCellFrm*)pCell)->GetTabBox();
+
+ // nur nach rechts ueberlappend
+ if( ( rUnion.Left() - COLFUZZY ) <= pCell->Frm().Left() &&
+ ( rUnion.Right() - COLFUZZY ) > pCell->Frm().Left() )
+ {
+ if( ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
+ {
+ USHORT nInsPos = pBox->GetUpper()->
+ GetTabBoxes().C40_GETPOS( SwTableBox, pBox )+1;
+ lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos );
+ pBox->ClaimFrmFmt();
+ SwFmtFrmSize aNew(
+ pBox->GetFrmFmt()->GetFrmSize() );
+ nWidth = rUnion.Right() - pCell->Frm().Left();
+ nWidth = nWidth * aNew.GetWidth() /
+ pCell->Frm().Width();
+ long nTmpWidth = aNew.GetWidth() - nWidth;
+ aNew.SetWidth( nWidth );
+ pBox->GetFrmFmt()->SetFmtAttr( aNew );
+ // diese Box ist selektiert
+ pLastBox = pBox;
+ rBoxes.Insert( pBox );
+ aPosArr.Insert(
+ _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
+ pBox, bVert ) );
+
+ pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
+ aNew.SetWidth( nTmpWidth );
+ pBox->ClaimFrmFmt();
+ pBox->GetFrmFmt()->SetFmtAttr( aNew );
+
+ if( pUndo )
+ pUndo->AddNewBox( pBox->GetSttIdx() );
+ }
+ else
+ {
+ // diese Box ist selektiert
+ pLastBox = pBox;
+ rBoxes.Insert( pBox );
+#if OSL_DEBUG_LEVEL > 1
+ Point aInsPoint( (pCell->Frm().*fnRect->fnGetPos)() );
+#endif
+ aPosArr.Insert(
+ _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
+ pBox, bVert ) );
+ }
+ }
+ // oder rechts und links ueberlappend
+ else if( ( rUnion.Left() - COLFUZZY ) >= pCell->Frm().Left() &&
+ ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
+ {
+ USHORT nInsPos = pBox->GetUpper()->GetTabBoxes().
+ C40_GETPOS( SwTableBox, pBox )+1;
+ lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 2 );
+ pBox->ClaimFrmFmt();
+ SwFmtFrmSize aNew(
+ pBox->GetFrmFmt()->GetFrmSize() );
+ long nLeft = rUnion.Left() - pCell->Frm().Left();
+ nLeft = nLeft * aNew.GetWidth() /
+ pCell->Frm().Width();
+ long nRight = pCell->Frm().Right() - rUnion.Right();
+ nRight = nRight * aNew.GetWidth() /
+ pCell->Frm().Width();
+ nWidth = aNew.GetWidth() - nLeft - nRight;
+
+ aNew.SetWidth( nLeft );
+ pBox->GetFrmFmt()->SetFmtAttr( aNew );
+
+ {
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetAttrSet()
+ .GetItemState( RES_BOX, FALSE, &pItem ))
+ {
+ SvxBoxItem aBox( *(SvxBoxItem*)pItem );
+ aBox.SetLine( 0, BOX_LINE_RIGHT );
+ pBox->GetFrmFmt()->SetFmtAttr( aBox );
+ }
+ }
+
+ pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
+ aNew.SetWidth( nWidth );
+ pBox->ClaimFrmFmt();
+ pBox->GetFrmFmt()->SetFmtAttr( aNew );
+
+ if( pUndo )
+ pUndo->AddNewBox( pBox->GetSttIdx() );
+
+ // diese Box ist selektiert
+ pLastBox = pBox;
+ rBoxes.Insert( pBox );
+ aPosArr.Insert(
+ _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
+ pBox, bVert ) );
+
+ pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos+1 ];
+ aNew.SetWidth( nRight );
+ pBox->ClaimFrmFmt();
+ pBox->GetFrmFmt()->SetFmtAttr( aNew );
+
+ if( pUndo )
+ pUndo->AddNewBox( pBox->GetSttIdx() );
+ }
+ // oder reicht die rechte Kante der Box in den
+ // selektierten Bereich?
+ else if( ( pCell->Frm().Right() - COLFUZZY ) < rUnion.Right() &&
+ ( pCell->Frm().Right() - COLFUZZY ) > rUnion.Left() &&
+ ( pCell->Frm().Left() + COLFUZZY ) < rUnion.Left() )
+ {
+ // dann muss eine neue Box einfuegt und die
+ // Breiten angepasst werden
+ USHORT nInsPos = pBox->GetUpper()->GetTabBoxes().
+ C40_GETPOS( SwTableBox, pBox )+1;
+ lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 1 );
+
+ SwFmtFrmSize aNew(pBox->GetFrmFmt()->GetFrmSize() );
+ long nLeft = rUnion.Left() - pCell->Frm().Left(),
+ nRight = pCell->Frm().Right() - rUnion.Left();
+
+ nLeft = nLeft * aNew.GetWidth() /
+ pCell->Frm().Width();
+ nRight = nRight * aNew.GetWidth() /
+ pCell->Frm().Width();
+
+ aNew.SetWidth( nLeft );
+ pBox->ClaimFrmFmt()->SetFmtAttr( aNew );
+
+ // diese Box ist selektiert
+ pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
+ aNew.SetWidth( nRight );
+ pBox->ClaimFrmFmt();
+ pBox->GetFrmFmt()->SetFmtAttr( aNew );
+
+ pLastBox = pBox;
+ rBoxes.Insert( pBox );
+ aPosArr.Insert( _CmpLPt( Point( rUnion.Left(),
+ pCell->Frm().Top()), pBox, bVert ));
+
+ if( pUndo )
+ pUndo->AddNewBox( pBox->GetSttIdx() );
+ }
+ }
+ if ( pCell->GetNext() )
+ {
+ pCell = (const SwLayoutFrm*)pCell->GetNext();
+ // --> FME 2005-11-03 #125288# Check if table cell is not empty
+ if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
+ pCell = pCell->FirstCell();
+ }
+ else
+ pCell = ::lcl_FindNextCellFrm( pCell );
+ }
+ }
+ pRow = (const SwLayoutFrm*)pRow->GetNext();
+ }
+ }
+
+ // keine SSelection / keine gefundenen Boxen
+ if( 1 >= rBoxes.Count() )
+ return;
+
+ // dann suche mal alle Boxen, die nebeneinander liegen, und verbinde
+ // deren Inhalte mit Blanks. Alle untereinander liegende werden als
+ // Absaetze zusammengefasst
+
+ // 1. Loesung: gehe ueber das Array und
+ // alle auf der gleichen Y-Ebene werden mit Blanks getrennt
+ // alle anderen werden als Absaetze getrennt.
+ BOOL bCalcWidth = TRUE;
+ const SwTableBox* pFirstBox = aPosArr[ 0 ].pSelBox;
+
+ // JP 27.03.98: Optimierung - falls die Boxen einer Line leer sind,
+ // dann werden jetzt dafuer keine Blanks und
+ // kein Umbruch mehr eingefuegt.
+ //Block damit SwPaM, SwPosition vom Stack geloescht werden
+ {
+ SwPaM aPam( pDoc->GetNodes() );
+
+#if defined( DEL_ONLY_EMPTY_LINES )
+ nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
+ BOOL bEmptyLine = TRUE;
+ USHORT n, nSttPos = 0;
+
+ for( n = 0; n < aPosArr.Count(); ++n )
+ {
+ const _CmpLPt& rPt = aPosArr[ n ];
+ if( n && aPosArr[ n - 1 ].Y() == rPt.Y() ) // gleiche Ebene ?
+ {
+ if( bEmptyLine && !IsEmptyBox( *rPt.pSelBox, aPam ))
+ bEmptyLine = FALSE;
+ if( bCalcWidth )
+ nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
+ }
+ else
+ {
+ if( bCalcWidth && n )
+ bCalcWidth = FALSE; // eine Zeile fertig
+
+ if( bEmptyLine && nSttPos < n )
+ {
+ // dann ist die gesamte Line leer und braucht
+ // nicht mit Blanks aufgefuellt und als Absatz
+ // eingefuegt werden.
+ if( pUndo )
+ for( USHORT i = nSttPos; i < n; ++i )
+ pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+ aPosArr.Remove( nSttPos, n - nSttPos );
+ n = nSttPos;
+ }
+ else
+ nSttPos = n;
+
+ bEmptyLine = IsEmptyBox( *aPosArr[n].pSelBox, aPam );
+ }
+ }
+ if( bEmptyLine && nSttPos < n )
+ {
+ if( pUndo )
+ for( USHORT i = nSttPos; i < n; ++i )
+ pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+ aPosArr.Remove( nSttPos, n - nSttPos );
+ }
+#elsif defined( DEL_EMPTY_BOXES_AT_START_AND_END )
+
+ nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
+ USHORT n, nSttPos = 0, nSEndPos = 0, nESttPos = 0;
+
+ for( n = 0; n < aPosArr.Count(); ++n )
+ {
+ const _CmpLPt& rPt = aPosArr[ n ];
+ if( n && aPosArr[ n - 1 ].Y() == rPt.Y() ) // gleiche Ebene ?
+ {
+ BOOL bEmptyBox = IsEmptyBox( *rPt.pSelBox, aPam );
+ if( bEmptyBox )
+ {
+ if( nSEndPos == n ) // der Anfang ist leer
+ nESttPos = ++nSEndPos;
+ }
+ else // das Ende kann leer sein
+ nESttPos = n+1;
+
+ if( bCalcWidth )
+ nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
+ }
+ else
+ {
+ if( bCalcWidth && n )
+ bCalcWidth = FALSE; // eine Zeile fertig
+
+ // zuerst die vom Anfang
+ if( nSttPos < nSEndPos )
+ {
+ // dann ist der vorder Teil der Line leer und braucht
+ // nicht mit Blanks aufgefuellt werden.
+ if( pUndo )
+ for( USHORT i = nSttPos; i < nSEndPos; ++i )
+ pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+ USHORT nCnt = nSEndPos - nSttPos;
+ aPosArr.Remove( nSttPos, nCnt );
+ nESttPos -= nCnt;
+ n -= nCnt;
+ }
+
+ if( nESttPos < n )
+ {
+ // dann ist der vorder Teil der Line leer und braucht
+ // nicht mit Blanks aufgefuellt werden.
+ if( pUndo )
+ for( USHORT i = nESttPos; i < n; ++i )
+ pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+ USHORT nCnt = n - nESttPos;
+ aPosArr.Remove( nESttPos, nCnt );
+ n -= nCnt;
+ }
+
+ nSttPos = nSEndPos = nESttPos = n;
+ if( IsEmptyBox( *aPosArr[n].pSelBox, aPam ))
+ ++nSEndPos;
+ else
+ ++nESttPos;
+ }
+ }
+
+ // zuerst die vom Anfang
+ if( nSttPos < nSEndPos )
+ {
+ // dann ist der vorder Teil der Line leer und braucht
+ // nicht mit Blanks aufgefuellt werden.
+ if( pUndo )
+ for( USHORT i = nSttPos; i < nSEndPos; ++i )
+ pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+ USHORT nCnt = nSEndPos - nSttPos;
+ aPosArr.Remove( nSttPos, nCnt );
+ nESttPos -= nCnt;
+ n -= nCnt;
+ }
+ if( nESttPos < n )
+ {
+ // dann ist der vorder Teil der Line leer und braucht
+ // nicht mit Blanks aufgefuellt werden.
+ if( pUndo )
+ for( USHORT i = nESttPos; i < n; ++i )
+ pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+ USHORT nCnt = n - nESttPos;
+ aPosArr.Remove( nESttPos, nCnt );
+ }
+#else
+// DEL_ALL_EMPTY_BOXES
+
+ nWidth = 0;
+ long nY = aPosArr.Count() ?
+ ( bVert ?
+ aPosArr[ 0 ].X() :
+ aPosArr[ 0 ].Y() ) :
+ 0;
+
+ for( USHORT n = 0; n < aPosArr.Count(); ++n )
+ {
+ const _CmpLPt& rPt = aPosArr[ n ];
+ if( bCalcWidth )
+ {
+ if( nY == ( bVert ? rPt.X() : rPt.Y() ) ) // gleiche Ebene ?
+ nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
+ else
+ bCalcWidth = FALSE; // eine Zeile fertig
+ }
+
+ if( IsEmptyBox( *rPt.pSelBox, aPam ) )
+ {
+ if( pUndo )
+ pUndo->SaveCollection( *rPt.pSelBox );
+
+ aPosArr.Remove( n, 1 );
+ --n;
+ }
+ }
+#endif
+ }
+
+ // lege schon mal die neue Box an
+ {
+ SwTableBox* pTmpBox = rBoxes[0];
+ SwTableLine* pInsLine = pTmpBox->GetUpper();
+ USHORT nInsPos = pInsLine->GetTabBoxes().C40_GETPOS( SwTableBox, pTmpBox );
+
+ lcl_InsTblBox( pTblNd, pDoc, pTmpBox, nInsPos );
+ (*ppMergeBox) = pInsLine->GetTabBoxes()[ nInsPos ];
+ pInsLine->GetTabBoxes().Remove( nInsPos ); // wieder austragen
+ (*ppMergeBox)->SetUpper( 0 );
+ (*ppMergeBox)->ClaimFrmFmt();
+
+ // setze die Umrandung: von der 1. Box die linke/obere von der
+ // letzten Box die rechte/untere Kante:
+ if( pLastBox && pFirstBox )
+ {
+ SvxBoxItem aBox( pFirstBox->GetFrmFmt()->GetBox() );
+ const SvxBoxItem& rBox = pLastBox->GetFrmFmt()->GetBox();
+ aBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
+ aBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
+ if( aBox.GetLeft() || aBox.GetTop() ||
+ aBox.GetRight() || aBox.GetBottom() )
+ (*ppMergeBox)->GetFrmFmt()->SetFmtAttr( aBox );
+ }
+ }
+
+ //Block damit SwPaM, SwPosition vom Stack geloescht werden
+ if( aPosArr.Count() )
+ {
+ SwTxtNode* pTxtNd = 0;
+ SwPosition aInsPos( *(*ppMergeBox)->GetSttNd() );
+ SwNodeIndex& rInsPosNd = aInsPos.nNode;
+
+ SwPaM aPam( aInsPos );
+
+ for( USHORT n = 0; n < aPosArr.Count(); ++n )
+ {
+ const _CmpLPt& rPt = aPosArr[ n ];
+ aPam.GetPoint()->nNode.Assign( *rPt.pSelBox->GetSttNd()->
+ EndOfSectionNode(), -1 );
+ SwCntntNode* pCNd = aPam.GetCntntNode();
+ USHORT nL = pCNd ? pCNd->Len() : 0;
+ aPam.GetPoint()->nContent.Assign( pCNd, nL );
+
+ SwNodeIndex aSttNdIdx( *rPt.pSelBox->GetSttNd(), 1 );
+ // ein Node muss in der Box erhalten bleiben (sonst wird beim
+ // Move die gesamte Section geloescht)
+ if( pUndo )
+ pDoc->DoUndo( FALSE );
+ pDoc->AppendTxtNode( *aPam.GetPoint() );
+ if( pUndo )
+ pDoc->DoUndo( TRUE );
+ SwNodeRange aRg( aSttNdIdx, aPam.GetPoint()->nNode );
+ rInsPosNd++;
+ if( pUndo )
+ pUndo->MoveBoxCntnt( pDoc, aRg, rInsPosNd );
+ else
+ {
+ pDoc->MoveNodeRange( aRg, rInsPosNd,
+ IDocumentContentOperations::DOC_MOVEDEFAULT );
+ }
+ // wo steht jetzt aInsPos ??
+
+ if( bCalcWidth )
+ bCalcWidth = FALSE; // eine Zeile fertig
+
+ // den initialen TextNode ueberspringen
+ rInsPosNd.Assign( pDoc->GetNodes(),
+ rInsPosNd.GetNode().EndOfSectionIndex() - 2 );
+ pTxtNd = rInsPosNd.GetNode().GetTxtNode();
+ if( pTxtNd )
+ aInsPos.nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
+ }
+
+ // in der MergeBox sollte jetzt der gesamte Text stehen
+ // loesche jetzt noch den initialen TextNode
+ ASSERT( (*ppMergeBox)->GetSttIdx()+2 <
+ (*ppMergeBox)->GetSttNd()->EndOfSectionIndex(),
+ "leere Box" );
+ SwNodeIndex aIdx( *(*ppMergeBox)->GetSttNd()->EndOfSectionNode(), -1 );
+ pDoc->GetNodes().Delete( aIdx, 1 );
+ }
+
+ // setze die Breite der Box
+ (*ppMergeBox)->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
+ if( pUndo )
+ pUndo->AddNewBox( (*ppMergeBox)->GetSttIdx() );
+}
+
+
+static BOOL lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara );
+
+static BOOL lcl_CheckRow( const _FndLine*& rpFndLine, void* pPara )
+{
+ ((_FndLine*)rpFndLine)->GetBoxes().ForEach( &lcl_CheckCol, pPara );
+ return *(BOOL*)pPara;
+}
+
+static BOOL lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara )
+{
+ if( !rpFndBox->GetBox()->GetSttNd() )
+ {
+ if( rpFndBox->GetLines().Count() !=
+ rpFndBox->GetBox()->GetTabLines().Count() )
+ *((BOOL*)pPara) = FALSE;
+ else
+ ((_FndBox*)rpFndBox)->GetLines().ForEach( &lcl_CheckRow, pPara );
+ }
+ // Box geschuetzt ??
+ else if( rpFndBox->GetBox()->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ *((BOOL*)pPara) = FALSE;
+ return *(BOOL*)pPara;
+}
+
+
+USHORT CheckMergeSel( const SwPaM& rPam )
+{
+ SwSelBoxes aBoxes;
+//JP 24.09.96: Merge mit wiederholenden TabellenHeadline funktioniert nicht
+// richtig. Warum nicht Point 0,0 benutzen? Dann ist garantiert,
+// das die 1. Headline mit drin ist.
+ Point aPt;
+ const SwLayoutFrm *pStart = rPam.GetCntntNode()->GetFrm(
+ &aPt )->GetUpper(),
+ *pEnd = rPam.GetCntntNode(FALSE)->GetFrm(
+ &aPt )->GetUpper();
+ GetTblSel( pStart, pEnd, aBoxes, 0 );
+ return CheckMergeSel( aBoxes );
+}
+
+USHORT CheckMergeSel( const SwSelBoxes& rBoxes )
+{
+ USHORT eRet = TBLMERGE_NOSELECTION;
+ if( rBoxes.Count() )
+ {
+ eRet = TBLMERGE_OK;
+
+ _FndBox aFndBox( 0, 0 );
+ _FndPara aPara( rBoxes, &aFndBox );
+ const SwTableNode* pTblNd = aPara.rBoxes[0]->GetSttNd()->FindTableNode();
+ ((SwTable&)pTblNd->GetTable()).GetTabLines().ForEach(
+ &_FndLineCopyCol, &aPara );
+ if( aFndBox.GetLines().Count() )
+ {
+ BOOL bMergeSelOk = TRUE;
+ _FndBox* pFndBox = &aFndBox;
+ _FndLine* pFndLine = 0;
+ while( pFndBox && 1 == pFndBox->GetLines().Count() )
+ {
+ pFndLine = pFndBox->GetLines()[0];
+ if( 1 == pFndLine->GetBoxes().Count() )
+ pFndBox = pFndLine->GetBoxes()[0];
+ else
+ pFndBox = 0;
+ }
+ if( pFndBox )
+ pFndBox->GetLines().ForEach( &lcl_CheckRow, &bMergeSelOk );
+ else if( pFndLine )
+ pFndLine->GetBoxes().ForEach( &lcl_CheckCol, &bMergeSelOk );
+ if( !bMergeSelOk )
+ eRet = TBLMERGE_TOOCOMPLEX;
+ }
+ else
+ eRet = TBLMERGE_NOSELECTION;
+ }
+ return eRet;
+}
+
+//Ermittelt die von einer Tabellenselektion betroffenen Tabellen und die
+//Union-Rechteckte der Selektionen - auch fuer aufgespaltene Tabellen.
+SV_IMPL_PTRARR( SwSelUnions, SwSelUnion* );
+
+SwTwips lcl_CalcWish( const SwLayoutFrm *pCell, long nWish,
+ const long nAct )
+{
+ const SwLayoutFrm *pTmp = pCell;
+ if ( !nWish )
+ nWish = 1;
+
+ const sal_Bool bRTL = pCell->IsRightToLeft();
+ SwTwips nRet = bRTL ?
+ nAct - pCell->Frm().Width() :
+ 0;
+
+ while ( pTmp )
+ {
+ while ( pTmp->GetPrev() )
+ {
+ pTmp = (SwLayoutFrm*)pTmp->GetPrev();
+ long nTmp = pTmp->GetFmt()->GetFrmSize().GetWidth();
+ nRet += ( bRTL ? ( -1 ) : 1 ) * nTmp * nAct / nWish;
+ }
+ pTmp = pTmp->GetUpper()->GetUpper();
+ if ( pTmp && !pTmp->IsCellFrm() )
+ pTmp = 0;
+ }
+ return nRet;
+}
+
+/* MA: 20. Sep. 93 wird nicht mehr gebraucht.
+static const SwLayoutFrm *GetPrevCell( const SwLayoutFrm *pCell )
+{
+ const SwLayoutFrm *pLay = pCell->GetPrevLayoutLeaf();
+ if ( pLay && pLay->IsLayoutFrm() && !pLay->IsTab() )
+ {
+ //GetPrevLayoutLeaf() liefert ggf. auch die Umgebung einer Tab zurueck
+ //(naehmlich genau dann, wenn die Zelle noch Vorgaenger hat).
+ const SwFrm *pFrm = pLay->Lower();
+ while ( pFrm->GetNext() )
+ pFrm = pFrm->GetNext();
+ pLay = pFrm->IsTabFrm() ? (SwLayoutFrm*)pFrm : 0;
+ }
+ if ( pLay && pLay->IsTabFrm() )
+ {
+ //GetPrevLayoutLeaf() liefert ggf. auch Tabellen zurueck die letzte
+ //Zelle dieser Tabelle ist das das gesuchte Blatt.
+ pLay = ((SwTabFrm*)pLay)->FindLastCntnt()->GetUpper();
+ while ( !pLay->IsCellFrm() )
+ pLay = pLay->GetUpper();
+ }
+ return pLay;
+}
+*/
+
+void lcl_FindStartEndRow( const SwLayoutFrm *&rpStart,
+ const SwLayoutFrm *&rpEnd,
+ const int bChkProtected )
+{
+ //Start an den Anfang seiner Zeile setzen.
+ //End an das Ende seiner Zeile setzen.
+ rpStart = (SwLayoutFrm*)rpStart->GetUpper()->Lower();
+ while ( rpEnd->GetNext() )
+ rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
+
+ SvPtrarr aSttArr( 8, 8 ), aEndArr( 8, 8 );
+ const SwLayoutFrm *pTmp;
+ for( pTmp = rpStart; (FRM_CELL|FRM_ROW) & pTmp->GetType();
+ pTmp = pTmp->GetUpper() )
+ {
+ void* p = (void*)pTmp;
+ aSttArr.Insert( p, 0 );
+ }
+ for( pTmp = rpEnd; (FRM_CELL|FRM_ROW) & pTmp->GetType();
+ pTmp = pTmp->GetUpper() )
+ {
+ void* p = (void*)pTmp;
+ aEndArr.Insert( p, 0 );
+ }
+
+ for( USHORT n = 0; n < aEndArr.Count() && n < aSttArr.Count(); ++n )
+ if( aSttArr[ n ] != aEndArr[ n ] )
+ {
+ // first unequal line or box - all odds are
+ if( n & 1 ) // 1, 3, 5, ... are boxes
+ {
+ rpStart = (SwLayoutFrm*)aSttArr[ n ];
+ rpEnd = (SwLayoutFrm*)aEndArr[ n ];
+ }
+ else // 0, 2, 4, ... are lines
+ {
+ // check if start & end line are the first & last Line of the
+ // box. If not return these cells.
+ // Else the hole line with all Boxes has to be deleted.
+ rpStart = (SwLayoutFrm*)aSttArr[ n+1 ];
+ rpEnd = (SwLayoutFrm*)aEndArr[ n+1 ];
+ if( n )
+ {
+ const SwCellFrm* pCellFrm = (SwCellFrm*)aSttArr[ n-1 ];
+ const SwTableLines& rLns = pCellFrm->
+ GetTabBox()->GetTabLines();
+ if( rLns[ 0 ] == ((SwRowFrm*)aSttArr[ n ])->GetTabLine() &&
+ rLns[ rLns.Count() - 1 ] ==
+ ((SwRowFrm*)aEndArr[ n ])->GetTabLine() )
+ {
+ rpStart = rpEnd = pCellFrm;
+ while ( rpStart->GetPrev() )
+ rpStart = (SwLayoutFrm*)rpStart->GetPrev();
+ while ( rpEnd->GetNext() )
+ rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
+ }
+ }
+ }
+ break;
+ }
+
+ if( !bChkProtected ) // geschuetzte Zellen beachten ?
+ return;
+
+
+ //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
+ while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
+ rpStart = (SwLayoutFrm*)rpStart->GetNext();
+ while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
+ rpEnd = (SwLayoutFrm*)rpEnd->GetPrev();
+}
+
+
+void lcl_FindStartEndCol( const SwLayoutFrm *&rpStart,
+ const SwLayoutFrm *&rpEnd,
+ const int bChkProtected )
+{
+ //Start und End senkrecht bis an den Rand der Tabelle denken; es muss
+ //die Gesamttabelle betrachtet werden, also inklusive Masters und
+ //Follows.
+ //Fuer den Start brauchen wir den Mutter-TabellenFrm.
+ if( !rpStart )
+ return;
+ const SwTabFrm *pOrg = rpStart->FindTabFrm();
+ const SwTabFrm *pTab = pOrg;
+
+ SWRECTFN( pTab )
+
+ sal_Bool bRTL = pTab->IsRightToLeft();
+ const long nTmpWish = pOrg->GetFmt()->GetFrmSize().GetWidth();
+ const long nWish = ( nTmpWish > 0 ) ? nTmpWish : 1;
+
+ while ( pTab->IsFollow() )
+ {
+ const SwFrm *pTmp = pTab->FindPrev();
+ ASSERT( pTmp->IsTabFrm(), "Vorgaenger vom Follow nicht der Master." );
+ pTab = (const SwTabFrm*)pTmp;
+ }
+
+ SwTwips nSX = 0;
+ SwTwips nSX2 = 0;
+
+ if ( pTab->GetTable()->IsNewModel() )
+ {
+ nSX = (rpStart->Frm().*fnRect->fnGetLeft )();
+ nSX2 = (rpStart->Frm().*fnRect->fnGetRight)();
+ }
+ else
+ {
+ const SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
+ nSX = ::lcl_CalcWish( rpStart, nWish, nPrtWidth ) + (pTab->*fnRect->fnGetPrtLeft)();
+ nSX2 = nSX + (rpStart->GetFmt()->GetFrmSize().GetWidth() * nPrtWidth / nWish);
+ }
+
+ const SwLayoutFrm *pTmp = pTab->FirstCell();
+
+ while ( pTmp &&
+ (!pTmp->IsCellFrm() ||
+ ( ( ! bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() < nSX &&
+ (pTmp->Frm().*fnRect->fnGetRight)()< nSX2 ) ||
+ bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() > nSX &&
+ (pTmp->Frm().*fnRect->fnGetRight)()> nSX2 ) ) )
+ pTmp = pTmp->GetNextLayoutLeaf();
+
+ if ( pTmp )
+ rpStart = pTmp;
+
+ pTab = pOrg;
+
+ const SwTabFrm* pLastValidTab = pTab;
+ while ( pTab->GetFollow() )
+ {
+ //
+ // Check if pTab->GetFollow() is a valid follow table:
+ // Only follow tables with at least on non-FollowFlowLine
+ // should be considered.
+ //
+ if ( pTab->HasFollowFlowLine() )
+ {
+ pTab = pTab->GetFollow();
+ const SwFrm* pTmpRow = pTab->GetFirstNonHeadlineRow();
+ if ( pTmpRow && pTmpRow->GetNext() )
+ pLastValidTab = pTab;
+ }
+ else
+ pLastValidTab = pTab = pTab->GetFollow();
+ }
+ pTab = pLastValidTab;
+
+ SwTwips nEX = 0;
+
+ if ( pTab->GetTable()->IsNewModel() )
+ {
+ nEX = (rpEnd->Frm().*fnRect->fnGetLeft )();
+ }
+ else
+ {
+ const SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
+ nEX = ::lcl_CalcWish( rpEnd, nWish, nPrtWidth ) + (pTab->*fnRect->fnGetPrtLeft)();
+ }
+
+ const SwCntntFrm* pLastCntnt = pTab->FindLastCntnt();
+ rpEnd = pLastCntnt ? pLastCntnt->GetUpper() : 0;
+ // --> FME 2006-07-17 #134385# Made code robust. If pTab does not have a lower,
+ // we would crash here.
+ if ( !pLastCntnt ) return;
+ // <--
+
+ while( !rpEnd->IsCellFrm() )
+ rpEnd = rpEnd->GetUpper();
+
+ while ( ( bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() < nEX ) ||
+ ( ! bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX ) )
+ {
+ const SwLayoutFrm* pTmpLeaf = rpEnd->GetPrevLayoutLeaf();
+ if( !pTmpLeaf || !pTab->IsAnLower( pTmpLeaf ) )
+ break;
+ rpEnd = pTmpLeaf;
+ }
+
+ if( !bChkProtected ) // geschuetzte Zellen beachten ?
+ return;
+
+ //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
+ //Also muss ggf. nocheinmal rueckwaerts gesucht werden.
+ while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
+ {
+ const SwLayoutFrm *pTmpLeaf = rpStart;
+ pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
+ while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() > nEX )//erstmal die Zeile ueberspr.
+ pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
+ while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() < nSX &&
+ (pTmpLeaf->Frm().*fnRect->fnGetRight)()< nSX2 )
+ pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
+ const SwTabFrm *pTmpTab = rpStart->FindTabFrm();
+ if ( !pTmpTab->IsAnLower( pTmpLeaf ) )
+ {
+ pTmpTab = pTmpTab->GetFollow();
+ rpStart = pTmpTab->FirstCell();
+ while ( (rpStart->Frm().*fnRect->fnGetLeft)() < nSX &&
+ (rpStart->Frm().*fnRect->fnGetRight)()< nSX2 )
+ rpStart = rpStart->GetNextLayoutLeaf();
+ }
+ else
+ rpStart = pTmpLeaf;
+ }
+ while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
+ {
+ const SwLayoutFrm *pTmpLeaf = rpEnd;
+ pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
+ while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() < nEX )//erstmal die Zeile ueberspr.
+ pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
+ while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() > nEX )
+ pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
+ const SwTabFrm *pTmpTab = rpEnd->FindTabFrm();
+ if ( !pTmpLeaf || !pTmpTab->IsAnLower( pTmpLeaf ) )
+ {
+ pTmpTab = (const SwTabFrm*)pTmpTab->FindPrev();
+ ASSERT( pTmpTab->IsTabFrm(), "Vorgaenger vom Follow nicht der Master.");
+ rpEnd = pTmpTab->FindLastCntnt()->GetUpper();
+ while( !rpEnd->IsCellFrm() )
+ rpEnd = rpEnd->GetUpper();
+ while ( (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX )
+ rpEnd = rpEnd->GetPrevLayoutLeaf();
+ }
+ else
+ rpEnd = pTmpLeaf;
+ }
+}
+
+
+void MakeSelUnions( SwSelUnions& rUnions, const SwLayoutFrm *pStart,
+ const SwLayoutFrm *pEnd, const SwTblSearchType eSearchType )
+{
+ while ( pStart && !pStart->IsCellFrm() )
+ pStart = pStart->GetUpper();
+ while ( pEnd && !pEnd->IsCellFrm() )
+ pEnd = pEnd->GetUpper();
+
+ // #112697# Robust:
+ if ( !pStart || !pEnd )
+ {
+ ASSERT( false, "MakeSelUnions with pStart or pEnd not in CellFrm" )
+ return;
+ }
+
+ const SwTabFrm *pTable = pStart->FindTabFrm();
+ const SwTabFrm *pEndTable = pEnd->FindTabFrm();
+ if( !pTable || !pEndTable )
+ return;
+ BOOL bExchange = FALSE;
+
+ if ( pTable != pEndTable )
+ {
+ if ( !pTable->IsAnFollow( pEndTable ) )
+ {
+ ASSERT( pEndTable->IsAnFollow( pTable ), "Tabkette verknotet." );
+ bExchange = TRUE;
+ }
+ }
+ else
+ {
+ SWRECTFN( pTable )
+ long nSttTop = (pStart->Frm().*fnRect->fnGetTop)();
+ long nEndTop = (pEnd->Frm().*fnRect->fnGetTop)();
+ if( nSttTop == nEndTop )
+ {
+ if( (pStart->Frm().*fnRect->fnGetLeft)() >
+ (pEnd->Frm().*fnRect->fnGetLeft)() )
+ bExchange = TRUE;
+ }
+ else if( bVert == ( nSttTop < nEndTop ) )
+ bExchange = TRUE;
+ }
+ if ( bExchange )
+ {
+ const SwLayoutFrm *pTmp = pStart;
+ pStart = pEnd;
+ pEnd = pTmp;
+ //pTable und pEndTable nicht umsortieren, werden unten neu gesetzt.
+ //MA: 28. Dec. 93 Bug: 5190
+ }
+
+ //Start und End sind jetzt huebsch sortiert, jetzt muessen sie falls
+ //erwuenscht noch versetzt werden.
+ if( nsSwTblSearchType::TBLSEARCH_ROW == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) )
+ ::lcl_FindStartEndRow( pStart, pEnd, nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
+ else if( nsSwTblSearchType::TBLSEARCH_COL == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) )
+ ::lcl_FindStartEndCol( pStart, pEnd, nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
+
+ // --> FME 2006-07-17 #134385# Made code robust.
+ if ( !pEnd ) return;
+ // <--
+
+ //neu besorgen, da sie jetzt verschoben sind. MA: 28. Dec. 93 Bug 5190
+ pTable = pStart->FindTabFrm();
+ pEndTable = pEnd->FindTabFrm();
+
+ const long nStSz = pStart->GetFmt()->GetFrmSize().GetWidth();
+ const long nEdSz = pEnd->GetFmt()->GetFrmSize().GetWidth();
+ const long nWish = Max( 1L, pTable->GetFmt()->GetFrmSize().GetWidth() );
+ while ( pTable )
+ {
+ SWRECTFN( pTable )
+ const long nOfst = (pTable->*fnRect->fnGetPrtLeft)();
+ const long nPrtWidth = (pTable->Prt().*fnRect->fnGetWidth)();
+ long nSt1 = ::lcl_CalcWish( pStart, nWish, nPrtWidth ) + nOfst;
+ long nEd1 = ::lcl_CalcWish( pEnd, nWish, nPrtWidth ) + nOfst;
+
+ if ( nSt1 <= nEd1 )
+ nEd1 += (long)((nEdSz * nPrtWidth) / nWish) - 1;
+ else
+ nSt1 += (long)((nStSz * nPrtWidth) / nWish) - 1;
+
+ long nSt2;
+ long nEd2;
+ if( pTable->IsAnLower( pStart ) )
+ nSt2 = (pStart->Frm().*fnRect->fnGetTop)();
+ else
+ nSt2 = (pTable->Frm().*fnRect->fnGetTop)();
+ if( pTable->IsAnLower( pEnd ) )
+ nEd2 = (pEnd->Frm().*fnRect->fnGetBottom)();
+ else
+ nEd2 = (pTable->Frm().*fnRect->fnGetBottom)();
+ Point aSt, aEd;
+ if( nSt1 > nEd1 )
+ {
+ long nTmp = nSt1;
+ nSt1 = nEd1;
+ nEd1 = nTmp;
+ }
+ if( nSt2 > nEd2 )
+ {
+ long nTmp = nSt2;
+ nSt2 = nEd2;
+ nEd2 = nTmp;
+ }
+ if( bVert )
+ {
+ aSt = Point( nSt2, nSt1 );
+ aEd = Point( nEd2, nEd1 );
+ }
+ else
+ {
+ aSt = Point( nSt1, nSt2 );
+ aEd = Point( nEd1, nEd2 );
+ }
+
+ const Point aDiff( aEd - aSt );
+ SwRect aUnion( aSt, Size( aDiff.X(), aDiff.Y() ) );
+ aUnion.Justify();
+
+ // fuers
+ if( !(nsSwTblSearchType::TBLSEARCH_NO_UNION_CORRECT & eSearchType ))
+ {
+ //Leider ist die Union jetzt mit Rundungsfehlern behaftet und dadurch
+ //wuerden beim Split/Merge fehlertraechtige Umstaende entstehen.
+ //Um dies zu vermeiden werden jetzt fuer die Table die erste und
+ //letzte Zelle innerhalb der Union ermittelt und aus genau deren
+ //Werten wird die Union neu gebildet.
+ const SwLayoutFrm* pRow = pTable->IsFollow() ?
+ pTable->GetFirstNonHeadlineRow() :
+ (const SwLayoutFrm*)pTable->Lower();
+
+ while ( pRow && !pRow->Frm().IsOver( aUnion ) )
+ pRow = (SwLayoutFrm*)pRow->GetNext();
+
+ // --> FME 2004-07-26 #i31976#
+ // A follow flow row may contain emtpy cells. These are not
+ // considered by FirstCell(). Therefore we have to find
+ // the first cell manually:
+ const SwFrm* pTmpCell = 0;
+ if ( pTable->IsFollow() && pRow && pRow->IsInFollowFlowRow() )
+ {
+ const SwFrm* pTmpRow = pRow;
+ while ( pTmpRow && pTmpRow->IsRowFrm() )
+ {
+ pTmpCell = static_cast<const SwRowFrm*>(pTmpRow)->Lower();
+ pTmpRow = static_cast<const SwCellFrm*>(pTmpCell)->Lower();
+ }
+ ASSERT( !pTmpCell || pTmpCell->IsCellFrm(), "Lower of rowframe != cellframe?!" )
+ }
+ // <--
+
+ const SwLayoutFrm* pFirst = pTmpCell ?
+ static_cast<const SwLayoutFrm*>(pTmpCell) :
+ pRow ?
+ pRow->FirstCell() :
+ 0;
+
+ while ( pFirst && !::IsFrmInTblSel( aUnion, pFirst ) )
+ {
+ if ( pFirst->GetNext() )
+ {
+ pFirst = (const SwLayoutFrm*)pFirst->GetNext();
+ if ( pFirst->Lower() && pFirst->Lower()->IsRowFrm() )
+ pFirst = pFirst->FirstCell();
+ }
+ else
+ pFirst = ::lcl_FindNextCellFrm( pFirst );
+ }
+ const SwLayoutFrm* pLast = 0;
+ const SwFrm* pLastCntnt = pTable->FindLastCntnt();
+ if ( pLastCntnt )
+ pLast = ::lcl_FindCellFrm( pLastCntnt->GetUpper() );
+
+ while ( pLast && !::IsFrmInTblSel( aUnion, pLast ) )
+ pLast = ::lcl_FindCellFrm( pLast->GetPrevLayoutLeaf() );
+
+ if ( pFirst && pLast ) //Robust
+ {
+ aUnion = pFirst->Frm();
+ aUnion.Union( pLast->Frm() );
+ }
+ else
+ aUnion.Width( 0 );
+ }
+
+ if( (aUnion.*fnRect->fnGetWidth)() )
+ {
+ SwSelUnion *pTmp = new SwSelUnion( aUnion, (SwTabFrm*)pTable );
+ rUnions.C40_INSERT( SwSelUnion, pTmp, rUnions.Count() );
+ }
+
+ pTable = pTable->GetFollow();
+ if ( pTable != pEndTable && pEndTable->IsAnFollow( pTable ) )
+ pTable = 0;
+ }
+}
+
+BOOL CheckSplitCells( const SwCrsrShell& rShell, USHORT nDiv,
+ const SwTblSearchType eSearchType )
+{
+ if( !rShell.IsTableMode() )
+ rShell.GetCrsr();
+
+ return CheckSplitCells( *rShell.getShellCrsr(false), nDiv, eSearchType );
+}
+
+BOOL CheckSplitCells( const SwCursor& rCrsr, USHORT nDiv,
+ const SwTblSearchType eSearchType )
+{
+ if( 1 >= nDiv )
+ return FALSE;
+
+ USHORT nMinValue = nDiv * MINLAY;
+
+ //Start- und Endzelle besorgen und den naechsten fragen.
+ Point aPtPos, aMkPos;
+ const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
+ if( pShCrsr )
+ {
+ aPtPos = pShCrsr->GetPtPos();
+ aMkPos = pShCrsr->GetMkPos();
+ }
+ const SwLayoutFrm *pStart = rCrsr.GetCntntNode()->GetFrm(
+ &aPtPos )->GetUpper(),
+ *pEnd = rCrsr.GetCntntNode(FALSE)->GetFrm(
+ &aMkPos )->GetUpper();
+
+ SWRECTFN( pStart->GetUpper() )
+
+ //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+ SwSelUnions aUnions;
+
+ ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
+
+ //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+ for ( USHORT i = 0; i < aUnions.Count(); ++i )
+ {
+ SwSelUnion *pUnion = aUnions[i];
+ const SwTabFrm *pTable = pUnion->GetTable();
+
+ // Skip any repeated headlines in the follow:
+ const SwLayoutFrm* pRow = pTable->IsFollow() ?
+ pTable->GetFirstNonHeadlineRow() :
+ (const SwLayoutFrm*)pTable->Lower();
+
+ while ( pRow )
+ {
+ if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+ {
+ const SwLayoutFrm *pCell = pRow->FirstCell();
+
+ while ( pCell && pRow->IsAnLower( pCell ) )
+ {
+ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+ if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+ {
+ if( (pCell->Frm().*fnRect->fnGetWidth)() < nMinValue )
+ return FALSE;
+ }
+
+ if ( pCell->GetNext() )
+ {
+ pCell = (const SwLayoutFrm*)pCell->GetNext();
+ if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
+ pCell = pCell->FirstCell();
+ }
+ else
+ pCell = ::lcl_FindNextCellFrm( pCell );
+ }
+ }
+ pRow = (const SwLayoutFrm*)pRow->GetNext();
+ }
+ }
+ return TRUE;
+}
+
+// -------------------------------------------------------------------
+// Diese Klassen kopieren die aktuelle Tabellen-Selektion (rBoxes)
+// unter Beibehaltung der Tabellen-Struktur in eine eigene Struktur
+// neu: SS zum gezielten Loeschen/Retaurieren des Layouts.
+
+void lcl_InsertRow( SwTableLine &rLine, SwLayoutFrm *pUpper, SwFrm *pSibling )
+{
+ SwRowFrm *pRow = new SwRowFrm( rLine );
+ if ( pUpper->IsTabFrm() && ((SwTabFrm*)pUpper)->IsFollow() )
+ {
+ SwTabFrm* pTabFrm = (SwTabFrm*)pUpper;
+ pTabFrm->FindMaster()->InvalidatePos(); //kann die Zeile vielleicht aufnehmen
+
+ if ( pSibling && pTabFrm->IsInHeadline( *pSibling ) )
+ {
+ // Skip any repeated headlines in the follow:
+ pSibling = pTabFrm->GetFirstNonHeadlineRow();
+ }
+ }
+ pRow->Paste( pUpper, pSibling );
+ pRow->RegistFlys();
+}
+
+
+BOOL _FndBoxCopyCol( const SwTableBox*& rpBox, void* pPara )
+{
+ _FndPara* pFndPara = (_FndPara*)pPara;
+ _FndBox* pFndBox = new _FndBox( (SwTableBox*)rpBox, pFndPara->pFndLine );
+ if( rpBox->GetTabLines().Count() )
+ {
+ _FndPara aPara( *pFndPara, pFndBox );
+ pFndBox->GetBox()->GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+ if( !pFndBox->GetLines().Count() )
+ {
+ delete pFndBox;
+ return TRUE;
+ }
+ }
+ else
+ {
+ SwTableBoxPtr pSrch = (SwTableBoxPtr)rpBox;
+ USHORT nFndPos;
+ if( !pFndPara->rBoxes.Seek_Entry( pSrch, &nFndPos ))
+ {
+ delete pFndBox;
+ return TRUE;
+ }
+ }
+ pFndPara->pFndLine->GetBoxes().C40_INSERT( _FndBox, pFndBox,
+ pFndPara->pFndLine->GetBoxes().Count() );
+ return TRUE;
+}
+
+BOOL _FndLineCopyCol( const SwTableLine*& rpLine, void* pPara )
+{
+ _FndPara* pFndPara = (_FndPara*)pPara;
+ _FndLine* pFndLine = new _FndLine( (SwTableLine*)rpLine, pFndPara->pFndBox );
+ _FndPara aPara( *pFndPara, pFndLine );
+ pFndLine->GetLine()->GetTabBoxes().ForEach( &_FndBoxCopyCol, &aPara );
+ if( pFndLine->GetBoxes().Count() )
+ {
+ pFndPara->pFndBox->GetLines().C40_INSERT( _FndLine, pFndLine,
+ pFndPara->pFndBox->GetLines().Count() );
+ }
+ else
+ delete pFndLine;
+ return TRUE;
+}
+
+void _FndBox::SetTableLines( const SwSelBoxes &rBoxes, const SwTable &rTable )
+{
+ //Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
+ //setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
+ //sind, so bleiben die Pointer eben einfach 0.
+ //Gesucht werden zunachst die Positionen der ersten/letzten betroffenen
+ //Line im Array der SwTable. Damit die 0 fuer 'keine Line' verwand werden
+ //kann werden die Positionen um 1 nach oben versetzt!
+
+ USHORT nStPos = USHRT_MAX;
+ USHORT nEndPos= 0;
+
+ for ( USHORT i = 0; i < rBoxes.Count(); ++i )
+ {
+ SwTableLine *pLine = rBoxes[i]->GetUpper();
+ while ( pLine->GetUpper() )
+ pLine = pLine->GetUpper()->GetUpper();
+ const USHORT nPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLine ) + 1;
+
+ ASSERT( nPos != USHRT_MAX, "TableLine not found." );
+
+ if( nStPos > nPos )
+ nStPos = nPos;
+
+ if( nEndPos < nPos )
+ nEndPos = nPos;
+ }
+ if ( nStPos > 1 )
+ pLineBefore = rTable.GetTabLines()[nStPos - 2];
+ if ( nEndPos < rTable.GetTabLines().Count() )
+ pLineBehind = rTable.GetTabLines()[nEndPos];
+}
+
+void _FndBox::SetTableLines( const SwTable &rTable )
+{
+ // Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
+ // setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
+ // sind, so bleiben die Pointer eben einfach 0.
+ // Die Positionen der ersten/letzten betroffenen Line im Array der
+ // SwTable steht in der FndBox. Damit die 0 fuer 'keine Line' verwand
+ // werdenkann werden die Positionen um 1 nach oben versetzt!
+
+ if( !GetLines().Count() )
+ return;
+
+ SwTableLine* pTmpLine = GetLines()[0]->GetLine();
+ USHORT nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
+ ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
+ if( nPos )
+ pLineBefore = rTable.GetTabLines()[ nPos - 1 ];
+
+ pTmpLine = GetLines()[GetLines().Count()-1]->GetLine();
+ nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
+ ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
+ if( ++nPos < rTable.GetTabLines().Count() )
+ pLineBehind = rTable.GetTabLines()[nPos];
+}
+
+inline void UnsetFollow( SwFlowFrm *pTab )
+{
+ pTab->bIsFollow = FALSE;
+}
+
+void _FndBox::DelFrms( SwTable &rTable )
+{
+ //Alle Lines zwischen pLineBefore und pLineBehind muessen aus dem
+ //Layout ausgeschnitten und geloescht werden.
+ //Entstehen dabei leere Follows so muessen diese vernichtet werden.
+ //Wird ein Master vernichtet, so muss der Follow Master werden.
+ //Ein TabFrm muss immer uebrigbleiben.
+
+ USHORT nStPos = 0;
+ USHORT nEndPos= rTable.GetTabLines().Count() - 1;
+ if( rTable.IsNewModel() && pLineBefore )
+ rTable.CheckRowSpan( pLineBefore, true );
+ if ( pLineBefore )
+ {
+ nStPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBefore );
+ ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ ++nStPos;
+ }
+ if( rTable.IsNewModel() && pLineBehind )
+ rTable.CheckRowSpan( pLineBehind, false );
+ if ( pLineBehind )
+ {
+ nEndPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBehind );
+ ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ --nEndPos;
+ }
+
+ for ( USHORT i = nStPos; i <= nEndPos; ++i)
+ {
+ SwFrmFmt *pFmt = rTable.GetTabLines()[i]->GetFrmFmt();
+ SwClientIter aIter( *pFmt );
+ SwClient* pLast = aIter.GoStart();
+ if( pLast )
+ {
+ do {
+ SwFrm *pFrm = PTR_CAST( SwFrm, pLast );
+ if ( pFrm &&
+ ((SwRowFrm*)pFrm)->GetTabLine() == rTable.GetTabLines()[i] )
+ {
+ BOOL bDel = TRUE;
+ SwTabFrm *pUp = !pFrm->GetPrev() && !pFrm->GetNext() ?
+ (SwTabFrm*)pFrm->GetUpper() : 0;
+ if ( !pUp )
+ {
+ const USHORT nRepeat =
+ ((SwTabFrm*)pFrm->GetUpper())->GetTable()->GetRowsToRepeat();
+ if ( nRepeat > 0 &&
+ ((SwTabFrm*)pFrm->GetUpper())->IsFollow() )
+ {
+ if ( !pFrm->GetNext() )
+ {
+ SwRowFrm* pFirstNonHeadline =
+ ((SwTabFrm*)pFrm->GetUpper())->GetFirstNonHeadlineRow();
+ if ( pFirstNonHeadline == pFrm )
+ {
+ pUp = (SwTabFrm*)pFrm->GetUpper();
+ }
+ }
+ }
+ }
+ if ( pUp )
+ {
+ SwTabFrm *pFollow = pUp->GetFollow();
+ SwTabFrm *pPrev = pUp->IsFollow() ? pUp : 0;
+ if ( pPrev )
+ {
+ SwFrm *pTmp = pPrev->FindPrev();
+ ASSERT( pTmp->IsTabFrm(),
+ "Vorgaenger vom Follow kein Master.");
+ pPrev = (SwTabFrm*)pTmp;
+ }
+ if ( pPrev )
+ {
+ pPrev->SetFollow( pFollow );
+ // --> FME 2006-01-31 #i60340# Do not transfer the
+ // flag from pUp to pPrev. pUp may still have the
+ // flag set although there is not more follow flow
+ // line associated with pUp.
+ pPrev->SetFollowFlowLine( FALSE );
+ // <--
+ }
+ else if ( pFollow )
+ ::UnsetFollow( pFollow );
+
+ //Ein TabellenFrm muss immer stehenbleiben!
+ if ( pPrev || pFollow )
+ {
+ // OD 26.08.2003 #i18103# - if table is in a section,
+ // lock the section, to avoid its delete.
+ {
+ SwSectionFrm* pSctFrm = pUp->FindSctFrm();
+ bool bOldSectLock = false;
+ if ( pSctFrm )
+ {
+ bOldSectLock = pSctFrm->IsColLocked();
+ pSctFrm->ColLock();
+ }
+ pUp->Cut();
+ if ( pSctFrm && !bOldSectLock )
+ {
+ pSctFrm->ColUnlock();
+ }
+ }
+ delete pUp;
+ bDel = FALSE;//Die Row wird mit in den Abgrund
+ //gerissen.
+ }
+ }
+ if ( bDel )
+ {
+ SwFrm* pTabFrm = pFrm->GetUpper();
+ if ( pTabFrm->IsTabFrm() &&
+ !pFrm->GetNext() &&
+ ((SwTabFrm*)pTabFrm)->GetFollow() )
+ {
+ // We do not delete the follow flow line,
+ // this will be done automatically in the
+ // next turn.
+ ((SwTabFrm*)pTabFrm)->SetFollowFlowLine( FALSE );
+ }
+
+ pFrm->Cut();
+ delete pFrm;
+ }
+ }
+ } while( 0 != ( pLast = aIter++ ));
+ }
+ }
+}
+
+BOOL lcl_IsLineOfTblFrm( const SwTabFrm& rTable, const SwFrm& rChk )
+{
+ const SwTabFrm* pTblFrm = rChk.FindTabFrm();
+ if( pTblFrm->IsFollow() )
+ pTblFrm = pTblFrm->FindMaster( true );
+ return &rTable == pTblFrm;
+}
+
+/*
+ * lcl_UpdateRepeatedHeadlines
+ */
+void lcl_UpdateRepeatedHeadlines( SwTabFrm& rTabFrm, bool bCalcLowers )
+{
+ ASSERT( rTabFrm.IsFollow(), "lcl_UpdateRepeatedHeadlines called for non-follow tab" )
+
+ // Delete remaining headlines:
+ SwRowFrm* pLower = 0;
+ while ( 0 != ( pLower = (SwRowFrm*)rTabFrm.Lower() ) && pLower->IsRepeatedHeadline() )
+ {
+ pLower->Cut();
+ delete pLower;
+ }
+
+ // Insert fresh set of headlines:
+ pLower = (SwRowFrm*)rTabFrm.Lower();
+ SwTable& rTable = *rTabFrm.GetTable();
+ const USHORT nRepeat = rTable.GetRowsToRepeat();
+ for ( USHORT nIdx = 0; nIdx < nRepeat; ++nIdx )
+ {
+ SwRowFrm* pHeadline = new SwRowFrm(
+ *rTable.GetTabLines()[ nIdx ] );
+ pHeadline->SetRepeatedHeadline( true );
+ pHeadline->Paste( &rTabFrm, pLower );
+ pHeadline->RegistFlys();
+ }
+
+ if ( bCalcLowers )
+ rTabFrm.SetCalcLowers();
+}
+
+void _FndBox::MakeFrms( SwTable &rTable )
+{
+ //Alle Lines zwischen pLineBefore und pLineBehind muessen im Layout
+ //wieder neu erzeugt werden.
+ //Und Zwar fuer alle Auspraegungen der Tabelle (mehrere z.B. im Kopf/Fuss).
+
+ USHORT nStPos = 0;
+ USHORT nEndPos= rTable.GetTabLines().Count() - 1;
+ if ( pLineBefore )
+ {
+ nStPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBefore );
+ ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ ++nStPos;
+
+ }
+ if ( pLineBehind )
+ {
+ nEndPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBehind );
+ ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ --nEndPos;
+ }
+ //Jetzt die grosse Einfuegeoperation fuer alle Tabllen.
+ SwClientIter aTabIter( *rTable.GetFrmFmt() );
+ for ( SwTabFrm *pTable = (SwTabFrm*)aTabIter.First( TYPE(SwFrm) ); pTable;
+ pTable = (SwTabFrm*)aTabIter.Next() )
+ {
+ if ( !pTable->IsFollow() )
+ {
+ SwFrm *pSibling = 0;
+ SwFrm *pUpperFrm = 0;
+ int i;
+ for ( i = rTable.GetTabLines().Count()-1;
+ i >= 0 && !pSibling; --i )
+ {
+ SwTableLine *pLine = pLineBehind ? pLineBehind :
+ rTable.GetTabLines()[static_cast<USHORT>(i)];
+ SwClientIter aIter( *pLine->GetFrmFmt() );
+ pSibling = (SwFrm*)aIter.First( TYPE(SwFrm) );
+ while ( pSibling && (
+ static_cast<SwRowFrm*>(pSibling)->GetTabLine() != pLine ||
+ !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
+ static_cast<SwRowFrm*>(pSibling)->IsRepeatedHeadline() ||
+ // --> FME 2005-08-24 #i53647# If !pLineBehind,
+ // IsInSplitTableRow() should be checked.
+ ( pLineBehind && pSibling->IsInFollowFlowRow() ) ||
+ (!pLineBehind && pSibling->IsInSplitTableRow() ) ) )
+ // <--
+ {
+ pSibling = (SwFrm*)aIter.Next();
+ }
+ }
+ if ( pSibling )
+ {
+ pUpperFrm = pSibling->GetUpper();
+ if ( !pLineBehind )
+ pSibling = 0;
+ }
+ else
+// ???? oder das der Letzte Follow der Tabelle ????
+ pUpperFrm = pTable;
+
+ for ( i = nStPos; (USHORT)i <= nEndPos; ++i )
+ ::lcl_InsertRow( *rTable.GetTabLines()[static_cast<USHORT>(i)],
+ (SwLayoutFrm*)pUpperFrm, pSibling );
+ if ( pUpperFrm->IsTabFrm() )
+ ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
+ }
+ else if ( rTable.GetRowsToRepeat() > 0 )
+ {
+ // Insert new headlines:
+ lcl_UpdateRepeatedHeadlines( *pTable, true );
+ }
+ }
+}
+
+void _FndBox::MakeNewFrms( SwTable &rTable, const USHORT nNumber,
+ const BOOL bBehind )
+{
+ //Frms fuer neu eingefuege Zeilen erzeugen.
+ //bBehind == TRUE: vor pLineBehind
+ // == FALSE: hinter pLineBefore
+ const USHORT nBfPos = pLineBefore ?
+ rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBefore ) :
+ USHRT_MAX;
+ const USHORT nBhPos = pLineBehind ?
+ rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBehind ) :
+ USHRT_MAX;
+
+ //nNumber: wie oft ist eingefuegt worden.
+ //nCnt: wieviele sind nNumber mal eingefuegt worden.
+
+ const USHORT nCnt =
+ ((nBhPos != USHRT_MAX ? nBhPos : rTable.GetTabLines().Count()) -
+ (nBfPos != USHRT_MAX ? nBfPos + 1 : 0)) / (nNumber + 1);
+
+ //Den Master-TabFrm suchen
+ SwClientIter aTabIter( *rTable.GetFrmFmt() );
+ SwTabFrm *pTable;
+ for ( pTable = (SwTabFrm*)aTabIter.First( TYPE(SwFrm) ); pTable;
+ pTable = (SwTabFrm*)aTabIter.Next() )
+ {
+ if( !pTable->IsFollow() )
+ {
+ SwFrm *pSibling = 0;
+ SwLayoutFrm *pUpperFrm = 0;
+ if ( bBehind )
+ {
+ if ( pLineBehind )
+ {
+ SwClientIter aIter( *pLineBehind->GetFrmFmt() );
+ pSibling = (SwFrm*)aIter.First( TYPE(SwFrm) );
+ while ( pSibling && (
+ // only consider row frames associated with pLineBehind:
+ static_cast<SwRowFrm*>(pSibling)->GetTabLine() != pLineBehind ||
+ // only consider row frames that are in pTables Master-Follow chain:
+ !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
+ // only consider row frames that are not repeated headlines:
+ static_cast<SwRowFrm*>(pSibling)->IsRepeatedHeadline() ||
+ // only consider row frames that are not follow flow rows
+ pSibling->IsInFollowFlowRow() ) )
+ {
+ pSibling = (SwFrm*)aIter.Next();
+ }
+ }
+ if ( pSibling )
+ pUpperFrm = pSibling->GetUpper();
+ else
+ {
+ while( pTable->GetFollow() )
+ pTable = pTable->GetFollow();
+ pUpperFrm = pTable;
+ }
+ const USHORT nMax = nBhPos != USHRT_MAX ?
+ nBhPos : rTable.GetTabLines().Count();
+
+ USHORT i = nBfPos != USHRT_MAX ? nBfPos + 1 + nCnt : nCnt;
+
+ for ( ; i < nMax; ++i )
+ ::lcl_InsertRow( *rTable.GetTabLines()[i], pUpperFrm, pSibling );
+ if ( pUpperFrm->IsTabFrm() )
+ ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
+ }
+ else //davor einfuegen
+ {
+ USHORT i;
+
+ // We are looking for the frame that is behind the row frame
+ // that should be inserted.
+ for ( i = 0; !pSibling; ++i )
+ {
+ SwTableLine* pLine = pLineBefore ? pLineBefore : rTable.GetTabLines()[i];
+
+ SwClientIter aIter( *pLine->GetFrmFmt() );
+ pSibling = (SwFrm*)aIter.First( TYPE(SwFrm) );
+
+ while ( pSibling && (
+ // only consider row frames associated with pLineBefore:
+ static_cast<SwRowFrm*>(pSibling)->GetTabLine() != pLine ||
+ // only consider row frames that are in pTables Master-Follow chain:
+ !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
+ // only consider row frames that are not repeated headlines:
+ static_cast<SwRowFrm*>(pSibling)->IsRepeatedHeadline() ||
+ // 1. case: pLineBefore == 0:
+ // only consider row frames that are not follow flow rows
+ // 2. case: pLineBefore != 0:
+ // only consider row frames that are not split table rows
+ // --> FME 2004-11-23 #i37476# If !pLineBefore,
+ // check IsInFollowFlowRow instead of IsInSplitTableRow.
+ ( ( !pLineBefore && pSibling->IsInFollowFlowRow() ) ||
+ ( pLineBefore && pSibling->IsInSplitTableRow() ) ) ) )
+ // <--
+ {
+ pSibling = (SwFrm*)aIter.Next();
+ }
+ }
+
+ pUpperFrm = pSibling->GetUpper();
+ if ( pLineBefore )
+ pSibling = pSibling->GetNext();
+
+ USHORT nMax = nBhPos != USHRT_MAX ?
+ nBhPos - nCnt :
+ rTable.GetTabLines().Count() - nCnt;
+
+ i = nBfPos != USHRT_MAX ? nBfPos + 1 : 0;
+ for ( ; i < nMax; ++i )
+ ::lcl_InsertRow( *rTable.GetTabLines()[i],
+ pUpperFrm, pSibling );
+ if ( pUpperFrm->IsTabFrm() )
+ ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
+ }
+ }
+ }
+
+ //Die Headlines mussen ggf. auch verarbeitet werden. Um gut arbeitenden
+ //Code nicht zu zerfasern wird hier nochmals iteriert.
+ const USHORT nRowsToRepeat = rTable.GetRowsToRepeat();
+ if ( nRowsToRepeat > 0 &&
+ ( ( !bBehind && ( nBfPos == USHRT_MAX || nBfPos + 1 < nRowsToRepeat ) ) ||
+ ( bBehind && ( ( nBfPos == USHRT_MAX && nRowsToRepeat > 1 ) || nBfPos + 2 < nRowsToRepeat ) ) ) )
+ {
+ for ( pTable = (SwTabFrm*)aTabIter.First( TYPE(SwFrm) ); pTable;
+ pTable = (SwTabFrm*)aTabIter.Next() )
+ {
+ if ( pTable->Lower() )
+ {
+ if ( pTable->IsFollow() )
+ {
+ lcl_UpdateRepeatedHeadlines( *pTable, true );
+ }
+
+ ASSERT( ((SwRowFrm*)pTable->Lower())->GetTabLine() ==
+ rTable.GetTabLines()[0], "MakeNewFrms: Table corruption!" )
+ }
+ }
+ }
+}
+
+BOOL _FndBox::AreLinesToRestore( const SwTable &rTable ) const
+{
+ //Lohnt es sich MakeFrms zu rufen?
+
+ if ( !pLineBefore && !pLineBehind && rTable.GetTabLines().Count() )
+ return TRUE;
+
+ USHORT nBfPos;
+ if(pLineBefore)
+ {
+ const SwTableLine* rLBefore = (const SwTableLine*)pLineBefore;
+ nBfPos = rTable.GetTabLines().GetPos( rLBefore );
+ }
+ else
+ nBfPos = USHRT_MAX;
+
+ USHORT nBhPos;
+ if(pLineBehind)
+ {
+ const SwTableLine* rLBehind = (const SwTableLine*)pLineBehind;
+ nBhPos = rTable.GetTabLines().GetPos( rLBehind );
+ }
+ else
+ nBhPos = USHRT_MAX;
+
+ if ( nBfPos == nBhPos ) //Duerfte eigentlich nie vorkommen.
+ {
+ ASSERT( FALSE, "Table, Loeschen auf keinem Bereich !?!" );
+ return FALSE;
+ }
+
+ if ( rTable.GetRowsToRepeat() > 0 )
+ {
+ // ups. sollte unsere zu wiederholende Kopfzeile geloescht worden
+ // sein??
+ SwClientIter aIter( *rTable.GetFrmFmt() );
+ for( SwTabFrm* pTable = (SwTabFrm*)aIter.First( TYPE( SwFrm ));
+ pTable; pTable = (SwTabFrm*)aIter.Next() )
+ {
+ if( pTable->IsFollow() )
+ {
+ // Insert new headlines:
+ lcl_UpdateRepeatedHeadlines( *pTable, false );
+ }
+ }
+ }
+
+ // Some adjacent lines at the beginning of the table have been deleted:
+ if ( nBfPos == USHRT_MAX && nBhPos == 0 )
+ return FALSE;
+
+ // Some adjacent lines at the end of the table have been deleted:
+ if ( nBhPos == USHRT_MAX && nBfPos == (rTable.GetTabLines().Count() - 1) )
+ return FALSE;
+
+ // Some adjacent lines in the middle of the table have been deleted:
+ if ( nBfPos != USHRT_MAX && nBhPos != USHRT_MAX && (nBfPos + 1) == nBhPos )
+ return FALSE;
+
+ // The structure of the deleted lines is more complex due to split lines.
+ // A call of MakeFrms() is necessary.
+ return TRUE;
+}
+
+