/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 (pFrm)->ContainsCntnt(); if( pCnt ) { const SwCntntNode* pNode = pCnt->GetNode(); _GetCrsr()->GetPoint()->nNode = *pNode; _GetCrsr()->GetPoint()->nContent.Assign( const_cast(pNode), static_cast(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; }