Update ooo320-m1
[ooovba.git] / sw / source / core / crsr / trvlfnfl.cxx
blob6d02926031a735bc759789afd37fb3434e67ef7d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: trvlfnfl.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <svx/svdmodel.hxx>
36 #include <svx/svdpage.hxx>
37 #include <crsrsh.hxx>
38 #include <doc.hxx>
39 #include <pagefrm.hxx>
40 #include <cntfrm.hxx>
41 #include <ftnfrm.hxx>
42 #include <viewimp.hxx>
43 #include <swcrsr.hxx>
44 #include <dflyobj.hxx>
45 #include <ndtxt.hxx>
46 #include <flyfrm.hxx>
47 #include <txtfrm.hxx>
48 #include <txtftn.hxx>
49 #include <ftnidx.hxx>
50 #include <viscrs.hxx>
51 #include <callnk.hxx>
53 BOOL SwCrsrShell::CallCrsrFN( FNCrsr fnCrsr )
55 SwCallLink aLk( *this ); // Crsr-Moves ueberwachen,
56 SwCursor* pCrsr = getShellCrsr( true );
57 BOOL bRet = (pCrsr->*fnCrsr)();
58 if( bRet )
59 UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
60 SwCrsrShell::READONLY );
61 return bRet;
64 BOOL SwCursor::GotoFtnTxt()
66 // springe aus dem Content zur Fussnote
67 BOOL bRet = FALSE;
68 SwTxtAttr *pFtn;
69 SwTxtNode* pTxtNd = GetPoint()->nNode.GetNode().GetTxtNode();
71 if( pTxtNd && 0 != (
72 pFtn = pTxtNd->GetTxtAttr( GetPoint()->nContent, RES_TXTATR_FTN ) ))
74 SwCrsrSaveState aSaveState( *this );
75 GetPoint()->nNode = *((SwTxtFtn*)pFtn)->GetStartNode();
77 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection(
78 &GetPoint()->nNode,
79 TRUE, !IsReadOnlyAvailable() );
80 if( pCNd )
82 GetPoint()->nContent.Assign( pCNd, 0 );
83 bRet = !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
84 nsSwCursorSelOverFlags::SELOVER_TOGGLE );
87 return bRet;
90 BOOL SwCrsrShell::GotoFtnTxt()
92 BOOL bRet = CallCrsrFN( &SwCursor::GotoFtnTxt );
93 if( !bRet )
95 SwTxtNode* pTxtNd = _GetCrsr() ?
96 _GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode() : NULL;
97 if( pTxtNd )
99 const SwFrm *pFrm = pTxtNd->GetFrm( &_GetCrsr()->GetSttPos(),
100 _GetCrsr()->Start() );
101 const SwFtnBossFrm* pFtnBoss;
102 sal_Bool bSkip = pFrm && pFrm->IsInFtn();
103 while( pFrm && 0 != ( pFtnBoss = pFrm->FindFtnBossFrm() ) )
105 if( 0 != ( pFrm = pFtnBoss->FindFtnCont() ) )
107 if( bSkip )
108 bSkip = sal_False;
109 else
111 const SwCntntFrm* pCnt = static_cast<const SwLayoutFrm*>
112 (pFrm)->ContainsCntnt();
113 if( pCnt )
115 const SwCntntNode* pNode = pCnt->GetNode();
116 _GetCrsr()->GetPoint()->nNode = *pNode;
117 _GetCrsr()->GetPoint()->nContent.Assign(
118 const_cast<SwCntntNode*>(pNode),
119 static_cast<const SwTxtFrm*>(pCnt)->GetOfst() );
120 UpdateCrsr( SwCrsrShell::SCROLLWIN |
121 SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY );
122 bRet = sal_True;
123 break;
127 if( pFtnBoss->GetNext() && !pFtnBoss->IsPageFrm() )
128 pFrm = pFtnBoss->GetNext();
129 else
130 pFrm = pFtnBoss->GetUpper();
134 return bRet;
138 BOOL SwCursor::GotoFtnAnchor()
140 // springe aus der Fussnote zum Anker
141 const SwNode* pSttNd = GetNode()->FindFootnoteStartNode();
142 if( pSttNd )
144 // durchsuche alle Fussnoten im Dokument nach diesem StartIndex
145 const SwTxtFtn* pTxtFtn;
146 const SwFtnIdxs& rFtnArr = pSttNd->GetDoc()->GetFtnIdxs();
147 for( USHORT n = 0; n < rFtnArr.Count(); ++n )
148 if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
149 pSttNd == &pTxtFtn->GetStartNode()->GetNode() )
151 SwCrsrSaveState aSaveState( *this );
153 SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode();
155 GetPoint()->nNode = rTNd;
156 GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() );
158 return !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
159 nsSwCursorSelOverFlags::SELOVER_TOGGLE );
162 return FALSE;
165 BOOL SwCrsrShell::GotoFtnAnchor()
167 // springe aus der Fussnote zum Anker
168 SwCallLink aLk( *this ); // Crsr-Moves ueberwachen,
169 BOOL bRet = pCurCrsr->GotoFtnAnchor();
170 if( bRet )
172 // BUG 5996: Tabellen-Kopfzeile sonderbehandeln
173 pCurCrsr->GetPtPos() = Point();
174 UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
175 SwCrsrShell::READONLY );
177 return bRet;
180 inline sal_Bool CmpLE( const SwTxtFtn& rFtn, ULONG nNd, xub_StrLen nCnt )
182 ULONG nTNd = rFtn.GetTxtNode().GetIndex();
183 return nTNd < nNd || ( nTNd == nNd && *rFtn.GetStart() <= nCnt );
185 inline sal_Bool CmpL( const SwTxtFtn& rFtn, ULONG nNd, xub_StrLen nCnt )
187 ULONG nTNd = rFtn.GetTxtNode().GetIndex();
188 return nTNd < nNd || ( nTNd == nNd && *rFtn.GetStart() < nCnt );
191 BOOL SwCursor::GotoNextFtnAnchor()
193 const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs();
194 const SwTxtFtn* pTxtFtn = 0;
195 USHORT nPos;
197 if( rFtnArr.SeekEntry( GetPoint()->nNode, &nPos ))
199 // es gibt eine Fussnote mit dem Index, suche also die
200 // naechstgelegene
201 if( nPos < rFtnArr.Count() )
203 ULONG nNdPos = GetPoint()->nNode.GetIndex();
204 xub_StrLen nCntPos = GetPoint()->nContent.GetIndex();
206 pTxtFtn = rFtnArr[ nPos ];
207 // suche vorewaerts zur naechsten
208 if( CmpLE( *pTxtFtn, nNdPos, nCntPos ) )
210 pTxtFtn = 0;
211 for( ++nPos; nPos < rFtnArr.Count(); ++nPos )
213 pTxtFtn = rFtnArr[ nPos ];
214 if( !CmpLE( *pTxtFtn, nNdPos, nCntPos ) )
215 break; // gefunden
216 pTxtFtn = 0;
219 else if( nPos )
221 // suche rueckwaerts zur vorherigen
222 pTxtFtn = 0;
223 while( nPos )
225 pTxtFtn = rFtnArr[ --nPos ];
226 if( CmpLE( *pTxtFtn, nNdPos, nCntPos ) )
228 pTxtFtn = rFtnArr[ ++nPos ];
229 break; // gefunden
231 // pTxtFtn = 0;
236 else if( nPos < rFtnArr.Count() )
237 pTxtFtn = rFtnArr[ nPos ];
239 BOOL bRet = 0 != pTxtFtn;
240 if( bRet )
242 SwCrsrSaveState aSaveState( *this );
244 SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode();
245 GetPoint()->nNode = rTNd;
246 GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() );
247 bRet = !IsSelOvr();
249 return bRet;
252 BOOL SwCursor::GotoPrevFtnAnchor()
254 const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs();
255 const SwTxtFtn* pTxtFtn = 0;
256 USHORT nPos;
258 if( rFtnArr.SeekEntry( GetPoint()->nNode, &nPos ) )
260 // es gibt eine Fussnote mit dem Index, suche also die
261 // naechstgelegene
262 ULONG nNdPos = GetPoint()->nNode.GetIndex();
263 xub_StrLen nCntPos = GetPoint()->nContent.GetIndex();
265 pTxtFtn = rFtnArr[ nPos ];
266 // suche vorwaerts zur naechsten
267 if( CmpL( *pTxtFtn, nNdPos, nCntPos ))
269 for( ++nPos; nPos < rFtnArr.Count(); ++nPos )
271 pTxtFtn = rFtnArr[ nPos ];
272 if( !CmpL( *pTxtFtn, nNdPos, nCntPos ) )
274 pTxtFtn = rFtnArr[ nPos-1 ];
275 break;
279 else if( nPos )
281 // suche rueckwaerts zur vorherigen
282 pTxtFtn = 0;
283 while( nPos )
285 pTxtFtn = rFtnArr[ --nPos ];
286 if( CmpL( *pTxtFtn, nNdPos, nCntPos ))
287 break; // gefunden
288 pTxtFtn = 0;
291 else
292 pTxtFtn = 0;
294 else if( nPos )
295 pTxtFtn = rFtnArr[ nPos-1 ];
297 BOOL bRet = 0 != pTxtFtn;
298 if( bRet )
300 SwCrsrSaveState aSaveState( *this );
302 SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode();
303 GetPoint()->nNode = rTNd;
304 GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() );
305 bRet = !IsSelOvr();
307 return bRet;
310 BOOL SwCrsrShell::GotoNextFtnAnchor()
312 return CallCrsrFN( &SwCursor::GotoNextFtnAnchor );
315 BOOL SwCrsrShell::GotoPrevFtnAnchor()
317 return CallCrsrFN( &SwCursor::GotoPrevFtnAnchor );
320 // springe aus dem Rahmen zum Anker
323 BOOL SwCrsrShell::GotoFlyAnchor()
325 SET_CURR_SHELL( this );
326 const SwFrm* pFrm = GetCurrFrm();
327 do {
328 pFrm = pFrm->GetUpper();
329 } while( pFrm && !pFrm->IsFlyFrm() );
331 if( !pFrm ) // ist kein FlyFrame
332 return FALSE;
334 SwCallLink aLk( *this ); // Crsr-Moves ueberwachen,
335 SwCrsrSaveState aSaveState( *pCurCrsr );
337 // springe in den BodyFrame, der am naechsten vom Fly liegt
338 SwRect aTmpRect( aCharRect );
339 if( !pFrm->Frm().IsInside( aTmpRect ))
340 aTmpRect = pFrm->Frm();
341 Point aPt( aTmpRect.Left(), aTmpRect.Top() +
342 ( aTmpRect.Bottom() - aTmpRect.Top() ) / 2 );
343 aPt.X() = aPt.X() > (pFrm->Frm().Left() + (pFrm->Frm().SSize().Width() / 2 ))
344 ? pFrm->Frm().Right()
345 : pFrm->Frm().Left();
347 const SwPageFrm* pPageFrm = pFrm->FindPageFrm();
348 const SwCntntFrm* pFndFrm = pPageFrm->GetCntntPos( aPt, FALSE, TRUE );
349 pFndFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt );
351 BOOL bRet = !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr();
352 if( bRet )
353 UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
354 SwCrsrShell::READONLY );
355 return bRet;