diff options
Diffstat (limited to 'sw/source/core/crsr/trvlfnfl.cxx')
-rw-r--r-- | sw/source/core/crsr/trvlfnfl.cxx | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/sw/source/core/crsr/trvlfnfl.cxx b/sw/source/core/crsr/trvlfnfl.cxx new file mode 100644 index 000000000000..3edf3718eabe --- /dev/null +++ b/sw/source/core/crsr/trvlfnfl.cxx @@ -0,0 +1,359 @@ +/************************************************************************* + * + * 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 <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> +#include <crsrsh.hxx> +#include <doc.hxx> +#include <pagefrm.hxx> +#include <cntfrm.hxx> +#include <ftnfrm.hxx> +#include <viewimp.hxx> +#include <swcrsr.hxx> +#include <dflyobj.hxx> +#include <ndtxt.hxx> +#include <flyfrm.hxx> +#include <txtfrm.hxx> +#include <txtftn.hxx> +#include <ftnidx.hxx> +#include <viscrs.hxx> +#include <callnk.hxx> + +BOOL SwCrsrShell::CallCrsrFN( FNCrsr fnCrsr ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCursor* pCrsr = getShellCrsr( true ); + BOOL bRet = (pCrsr->*fnCrsr)(); + if( bRet ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + return bRet; +} + +BOOL SwCursor::GotoFtnTxt() +{ + // springe aus dem Content zur Fussnote + BOOL bRet = FALSE; + SwTxtNode* pTxtNd = GetPoint()->nNode.GetNode().GetTxtNode(); + + SwTxtAttr *const pFtn( (pTxtNd) + ? pTxtNd->GetTxtAttrForCharAt( + GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN) + : 0); + if (pFtn) + { + SwCrsrSaveState aSaveState( *this ); + GetPoint()->nNode = *((SwTxtFtn*)pFtn)->GetStartNode(); + + SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( + &GetPoint()->nNode, + TRUE, !IsReadOnlyAvailable() ); + if( pCNd ) + { + GetPoint()->nContent.Assign( pCNd, 0 ); + bRet = !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | + nsSwCursorSelOverFlags::SELOVER_TOGGLE ); + } + } + return bRet; +} + +BOOL SwCrsrShell::GotoFtnTxt() +{ + BOOL bRet = CallCrsrFN( &SwCursor::GotoFtnTxt ); + if( !bRet ) + { + SwTxtNode* pTxtNd = _GetCrsr() ? + _GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode() : NULL; + if( pTxtNd ) + { + const SwFrm *pFrm = pTxtNd->GetFrm( &_GetCrsr()->GetSttPos(), + _GetCrsr()->Start() ); + const SwFtnBossFrm* pFtnBoss; + sal_Bool bSkip = pFrm && pFrm->IsInFtn(); + while( pFrm && 0 != ( pFtnBoss = pFrm->FindFtnBossFrm() ) ) + { + if( 0 != ( pFrm = pFtnBoss->FindFtnCont() ) ) + { + if( bSkip ) + bSkip = sal_False; + else + { + const SwCntntFrm* pCnt = static_cast<const SwLayoutFrm*> + (pFrm)->ContainsCntnt(); + if( pCnt ) + { + const SwCntntNode* pNode = pCnt->GetNode(); + _GetCrsr()->GetPoint()->nNode = *pNode; + _GetCrsr()->GetPoint()->nContent.Assign( + const_cast<SwCntntNode*>(pNode), + static_cast<const SwTxtFrm*>(pCnt)->GetOfst() ); + UpdateCrsr( SwCrsrShell::SCROLLWIN | + SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); + bRet = sal_True; + break; + } + } + } + if( pFtnBoss->GetNext() && !pFtnBoss->IsPageFrm() ) + pFrm = pFtnBoss->GetNext(); + else + pFrm = pFtnBoss->GetUpper(); + } + } + } + return bRet; +} + + +BOOL SwCursor::GotoFtnAnchor() +{ + // springe aus der Fussnote zum Anker + const SwNode* pSttNd = GetNode()->FindFootnoteStartNode(); + if( pSttNd ) + { + // durchsuche alle Fussnoten im Dokument nach diesem StartIndex + const SwTxtFtn* pTxtFtn; + const SwFtnIdxs& rFtnArr = pSttNd->GetDoc()->GetFtnIdxs(); + for( USHORT n = 0; n < rFtnArr.Count(); ++n ) + if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() && + pSttNd == &pTxtFtn->GetStartNode()->GetNode() ) + { + SwCrsrSaveState aSaveState( *this ); + + SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode(); + + GetPoint()->nNode = rTNd; + GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() ); + + return !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | + nsSwCursorSelOverFlags::SELOVER_TOGGLE ); + } + } + return FALSE; +} + +BOOL SwCrsrShell::GotoFtnAnchor() +{ + // springe aus der Fussnote zum Anker + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + BOOL bRet = pCurCrsr->GotoFtnAnchor(); + if( bRet ) + { + // BUG 5996: Tabellen-Kopfzeile sonderbehandeln + pCurCrsr->GetPtPos() = Point(); + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + return bRet; +} + +inline sal_Bool CmpLE( const SwTxtFtn& rFtn, ULONG nNd, xub_StrLen nCnt ) +{ + ULONG nTNd = rFtn.GetTxtNode().GetIndex(); + return nTNd < nNd || ( nTNd == nNd && *rFtn.GetStart() <= nCnt ); +} +inline sal_Bool CmpL( const SwTxtFtn& rFtn, ULONG nNd, xub_StrLen nCnt ) +{ + ULONG nTNd = rFtn.GetTxtNode().GetIndex(); + return nTNd < nNd || ( nTNd == nNd && *rFtn.GetStart() < nCnt ); +} + +BOOL SwCursor::GotoNextFtnAnchor() +{ + const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs(); + const SwTxtFtn* pTxtFtn = 0; + USHORT nPos; + + if( rFtnArr.SeekEntry( GetPoint()->nNode, &nPos )) + { + // es gibt eine Fussnote mit dem Index, suche also die + // naechstgelegene + if( nPos < rFtnArr.Count() ) + { + ULONG nNdPos = GetPoint()->nNode.GetIndex(); + xub_StrLen nCntPos = GetPoint()->nContent.GetIndex(); + + pTxtFtn = rFtnArr[ nPos ]; + // suche vorewaerts zur naechsten + if( CmpLE( *pTxtFtn, nNdPos, nCntPos ) ) + { + pTxtFtn = 0; + for( ++nPos; nPos < rFtnArr.Count(); ++nPos ) + { + pTxtFtn = rFtnArr[ nPos ]; + if( !CmpLE( *pTxtFtn, nNdPos, nCntPos ) ) + break; // gefunden + pTxtFtn = 0; + } + } + else if( nPos ) + { + // suche rueckwaerts zur vorherigen + pTxtFtn = 0; + while( nPos ) + { + pTxtFtn = rFtnArr[ --nPos ]; + if( CmpLE( *pTxtFtn, nNdPos, nCntPos ) ) + { + pTxtFtn = rFtnArr[ ++nPos ]; + break; // gefunden + } +// pTxtFtn = 0; + } + } + } + } + else if( nPos < rFtnArr.Count() ) + pTxtFtn = rFtnArr[ nPos ]; + + BOOL bRet = 0 != pTxtFtn; + if( bRet ) + { + SwCrsrSaveState aSaveState( *this ); + + SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode(); + GetPoint()->nNode = rTNd; + GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() ); + bRet = !IsSelOvr(); + } + return bRet; +} + +BOOL SwCursor::GotoPrevFtnAnchor() +{ + const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs(); + const SwTxtFtn* pTxtFtn = 0; + USHORT nPos; + + if( rFtnArr.SeekEntry( GetPoint()->nNode, &nPos ) ) + { + // es gibt eine Fussnote mit dem Index, suche also die + // naechstgelegene + ULONG nNdPos = GetPoint()->nNode.GetIndex(); + xub_StrLen nCntPos = GetPoint()->nContent.GetIndex(); + + pTxtFtn = rFtnArr[ nPos ]; + // suche vorwaerts zur naechsten + if( CmpL( *pTxtFtn, nNdPos, nCntPos )) + { + for( ++nPos; nPos < rFtnArr.Count(); ++nPos ) + { + pTxtFtn = rFtnArr[ nPos ]; + if( !CmpL( *pTxtFtn, nNdPos, nCntPos ) ) + { + pTxtFtn = rFtnArr[ nPos-1 ]; + break; + } + } + } + else if( nPos ) + { + // suche rueckwaerts zur vorherigen + pTxtFtn = 0; + while( nPos ) + { + pTxtFtn = rFtnArr[ --nPos ]; + if( CmpL( *pTxtFtn, nNdPos, nCntPos )) + break; // gefunden + pTxtFtn = 0; + } + } + else + pTxtFtn = 0; + } + else if( nPos ) + pTxtFtn = rFtnArr[ nPos-1 ]; + + BOOL bRet = 0 != pTxtFtn; + if( bRet ) + { + SwCrsrSaveState aSaveState( *this ); + + SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode(); + GetPoint()->nNode = rTNd; + GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() ); + bRet = !IsSelOvr(); + } + return bRet; +} + +BOOL SwCrsrShell::GotoNextFtnAnchor() +{ + return CallCrsrFN( &SwCursor::GotoNextFtnAnchor ); +} + +BOOL SwCrsrShell::GotoPrevFtnAnchor() +{ + return CallCrsrFN( &SwCursor::GotoPrevFtnAnchor ); +} + +// springe aus dem Rahmen zum Anker + + +BOOL SwCrsrShell::GotoFlyAnchor() +{ + SET_CURR_SHELL( this ); + const SwFrm* pFrm = GetCurrFrm(); + do { + pFrm = pFrm->GetUpper(); + } while( pFrm && !pFrm->IsFlyFrm() ); + + if( !pFrm ) // ist kein FlyFrame + return FALSE; + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + + // springe in den BodyFrame, der am naechsten vom Fly liegt + SwRect aTmpRect( aCharRect ); + if( !pFrm->Frm().IsInside( aTmpRect )) + aTmpRect = pFrm->Frm(); + Point aPt( aTmpRect.Left(), aTmpRect.Top() + + ( aTmpRect.Bottom() - aTmpRect.Top() ) / 2 ); + aPt.X() = aPt.X() > (pFrm->Frm().Left() + (pFrm->Frm().SSize().Width() / 2 )) + ? pFrm->Frm().Right() + : pFrm->Frm().Left(); + + const SwPageFrm* pPageFrm = pFrm->FindPageFrm(); + const SwCntntFrm* pFndFrm = pPageFrm->GetCntntPos( aPt, FALSE, TRUE ); + pFndFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + + BOOL bRet = !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + return bRet; +} + + + + |