Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / crsr / trvlfnfl.cxx
blob369e6041340f27d5411cab586b009c13e4991008
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <crsrsh.hxx>
21 #include <doc.hxx>
22 #include <pagefrm.hxx>
23 #include <cntfrm.hxx>
24 #include <ftnfrm.hxx>
25 #include <swcrsr.hxx>
26 #include <ndtxt.hxx>
27 #include <txtfrm.hxx>
28 #include <txtftn.hxx>
29 #include <ftnidx.hxx>
30 #include <viscrs.hxx>
31 #include "callnk.hxx"
32 #include <svx/srchdlg.hxx>
33 #include <wrtsh.hxx>
35 bool SwCursorShell::CallCursorShellFN( FNCursorShell fnCursor )
37 if (SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(this))
38 pWrtSh->addCurrentPosition();
40 SwCallLink aLk( *this ); // watch Cursor-Moves
41 bool bRet = (this->*fnCursor)();
42 if( bRet )
43 UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE |
44 SwCursorShell::READONLY );
45 return bRet;
48 bool SwCursorShell::CallCursorFN( FNCursor fnCursor )
50 if (SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(this))
51 pWrtSh->addCurrentPosition();
53 SwCallLink aLk( *this ); // watch Cursor-Moves
54 SwCursor* pCursor = getShellCursor( true );
55 bool bRet = (pCursor->*fnCursor)();
56 if( bRet )
57 UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE |
58 SwCursorShell::READONLY );
59 return bRet;
62 bool SwCursor::GotoFootnoteText()
64 // jump from content to footnote
65 bool bRet = false;
66 SwTextNode* pTextNd = GetPoint()->GetNode().GetTextNode();
68 SwTextAttr *const pFootnote( pTextNd
69 ? pTextNd->GetTextAttrForCharAt(
70 GetPoint()->GetContentIndex(), RES_TXTATR_FTN)
71 : nullptr);
72 if (pFootnote)
74 SwCursorSaveState aSaveState( *this );
75 GetPoint()->Assign( *static_cast<SwTextFootnote*>(pFootnote)->GetStartNode() );
77 SwContentNode* pCNd = GetDoc().GetNodes().GoNextSection(
78 GetPoint(),
79 true, !IsReadOnlyAvailable() );
80 if( pCNd )
82 bRet = !IsSelOvr( SwCursorSelOverFlags::CheckNodeSection |
83 SwCursorSelOverFlags::Toggle );
86 return bRet;
89 bool SwCursorShell::GotoFootnoteText()
91 bool bRet = CallCursorFN( &SwCursor::GotoFootnoteText );
92 if( !bRet )
94 SwTextNode* pTextNd = GetCursor_() ?
95 GetCursor_()->GetPoint()->GetNode().GetTextNode() : nullptr;
96 if( pTextNd )
98 std::pair<Point, bool> const tmp(GetCursor_()->GetSttPos(), true);
99 const SwFrame *pFrame = pTextNd->getLayoutFrame( GetLayout(),
100 GetCursor_()->Start(), &tmp);
101 const SwFootnoteBossFrame* pFootnoteBoss;
102 bool bSkip = pFrame && pFrame->IsInFootnote();
103 while( pFrame )
105 pFootnoteBoss = pFrame->FindFootnoteBossFrame();
106 if (!pFootnoteBoss)
107 break;
108 pFrame = pFootnoteBoss->FindFootnoteCont();
109 if( pFrame )
111 if( bSkip )
112 bSkip = false;
113 else
115 const SwContentFrame* pCnt = static_cast<const SwLayoutFrame*>
116 (pFrame)->ContainsContent();
117 if( pCnt )
119 SwTextFrame const*const pTF(
120 static_cast<const SwTextFrame*>(pCnt));
121 *GetCursor_()->GetPoint() =
122 pTF->MapViewToModelPos(pTF->GetOffset());
123 UpdateCursor( SwCursorShell::SCROLLWIN |
124 SwCursorShell::CHKRANGE | SwCursorShell::READONLY );
125 bRet = true;
126 break;
130 if( pFootnoteBoss->GetNext() && !pFootnoteBoss->IsPageFrame() )
131 pFrame = pFootnoteBoss->GetNext();
132 else
133 pFrame = pFootnoteBoss->GetUpper();
137 return bRet;
140 bool SwCursor::GotoFootnoteAnchor()
142 // jump from footnote to anchor
143 const SwNode* pSttNd = GetPointNode().FindFootnoteStartNode();
144 if( pSttNd )
146 // search in all footnotes in document for this StartIndex
147 const SwFootnoteIdxs& rFootnoteArr = pSttNd->GetDoc().GetFootnoteIdxs();
148 for( size_t n = 0; n < rFootnoteArr.size(); ++n )
150 const SwTextFootnote* pTextFootnote = rFootnoteArr[ n ];
151 if( nullptr != pTextFootnote->GetStartNode() &&
152 pSttNd == &pTextFootnote->GetStartNode()->GetNode() )
154 SwCursorSaveState aSaveState( *this );
156 SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
157 GetPoint()->Assign( rTNd, pTextFootnote->GetStart() );
159 return !IsSelOvr( SwCursorSelOverFlags::CheckNodeSection |
160 SwCursorSelOverFlags::Toggle );
164 return false;
167 bool SwCursorShell::GotoFootnoteAnchor()
169 if (SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(this))
170 pWrtSh->addCurrentPosition();
172 // jump from footnote to anchor
173 SwCallLink aLk( *this ); // watch Cursor-Moves
174 bool bRet = m_pCurrentCursor->GotoFootnoteAnchor();
175 if( bRet )
177 // special treatment for table header row
178 m_pCurrentCursor->GetPtPos() = Point();
179 UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE |
180 SwCursorShell::READONLY );
182 return bRet;
185 static bool CmpLE( const SwTextFootnote& rFootnote, SwNodeOffset nNd, sal_Int32 nCnt )
187 const SwNodeOffset nTNd = rFootnote.GetTextNode().GetIndex();
188 return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() <= nCnt );
191 static bool CmpL( const SwTextFootnote& rFootnote, SwNodeOffset nNd, sal_Int32 nCnt )
193 const SwNodeOffset nTNd = rFootnote.GetTextNode().GetIndex();
194 return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() < nCnt );
197 bool SwCursor::GotoNextFootnoteAnchor()
199 const SwFootnoteIdxs& rFootnoteArr = GetDoc().GetFootnoteIdxs();
200 const SwTextFootnote* pTextFootnote = nullptr;
201 size_t nPos = 0;
203 if( rFootnoteArr.empty() )
205 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
206 return false;
209 if( rFootnoteArr.SeekEntry( GetPoint()->GetNode(), &nPos ))
211 // there is a footnote with this index, so search also for the next one
212 if( nPos < rFootnoteArr.size() )
214 SwNodeOffset nNdPos = GetPoint()->GetNodeIndex();
215 const sal_Int32 nCntPos = GetPoint()->GetContentIndex();
217 pTextFootnote = rFootnoteArr[ nPos ];
218 // search forwards
219 if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
221 pTextFootnote = nullptr;
222 for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
224 pTextFootnote = rFootnoteArr[ nPos ];
225 if( !CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
226 break; // found
227 pTextFootnote = nullptr;
230 else if( nPos )
232 // search backwards
233 pTextFootnote = nullptr;
234 while( nPos )
236 pTextFootnote = rFootnoteArr[ --nPos ];
237 if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
239 pTextFootnote = rFootnoteArr[ ++nPos ];
240 break; // found
246 else if( nPos < rFootnoteArr.size() )
247 pTextFootnote = rFootnoteArr[ nPos ];
249 if (pTextFootnote == nullptr)
251 pTextFootnote = rFootnoteArr[ 0 ];
252 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
254 else
255 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
257 bool bRet = nullptr != pTextFootnote;
258 if( bRet )
260 SwCursorSaveState aSaveState( *this );
262 SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
263 GetPoint()->Assign( rTNd, pTextFootnote->GetStart() );
264 bRet = !IsSelOvr();
266 return bRet;
269 bool SwCursor::GotoPrevFootnoteAnchor()
271 const SwFootnoteIdxs& rFootnoteArr = GetDoc().GetFootnoteIdxs();
272 const SwTextFootnote* pTextFootnote = nullptr;
273 size_t nPos = 0;
275 if( rFootnoteArr.empty() )
277 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
278 return false;
281 if( rFootnoteArr.SeekEntry( GetPoint()->GetNode(), &nPos ) )
283 // there is a footnote with this index, so search also for the next one
284 SwNodeOffset nNdPos = GetPoint()->GetNodeIndex();
285 const sal_Int32 nCntPos = GetPoint()->GetContentIndex();
287 pTextFootnote = rFootnoteArr[ nPos ];
288 // search forwards
289 if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
291 for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
293 pTextFootnote = rFootnoteArr[ nPos ];
294 if( !CmpL( *pTextFootnote, nNdPos, nCntPos ) )
296 pTextFootnote = rFootnoteArr[ nPos-1 ];
297 break;
301 else if( nPos )
303 // search backwards
304 pTextFootnote = nullptr;
305 while( nPos )
307 pTextFootnote = rFootnoteArr[ --nPos ];
308 if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
309 break; // found
310 pTextFootnote = nullptr;
313 else
314 pTextFootnote = nullptr;
316 else if( nPos )
317 pTextFootnote = rFootnoteArr[ nPos-1 ];
319 if( pTextFootnote == nullptr )
321 pTextFootnote = rFootnoteArr[ rFootnoteArr.size() - 1 ];
322 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
324 else
325 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
327 bool bRet = nullptr != pTextFootnote;
328 if( bRet )
330 SwCursorSaveState aSaveState( *this );
332 SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
333 GetPoint()->Assign( rTNd, pTextFootnote->GetStart() );
334 bRet = !IsSelOvr();
336 return bRet;
339 bool SwCursorShell::GotoNextFootnoteAnchor()
341 return CallCursorFN( &SwCursor::GotoNextFootnoteAnchor );
344 bool SwCursorShell::GotoPrevFootnoteAnchor()
346 return CallCursorFN( &SwCursor::GotoPrevFootnoteAnchor );
349 /// jump from border to anchor
350 void SwCursorShell::GotoFlyAnchor()
352 CurrShell aCurr( this );
353 const SwFrame* pFrame = GetCurrFrame();
354 do {
355 pFrame = pFrame->GetUpper();
356 } while( pFrame && !pFrame->IsFlyFrame() );
358 if( !pFrame ) // no FlyFrame
359 return;
361 SwCallLink aLk( *this ); // watch Cursor-Moves
362 SwCursorSaveState aSaveState( *m_pCurrentCursor );
364 // jump in BodyFrame closest to FlyFrame
365 SwRect aTmpRect( m_aCharRect );
366 if( !pFrame->getFrameArea().Contains( aTmpRect ))
367 aTmpRect = pFrame->getFrameArea();
368 Point aPt( aTmpRect.Left(), aTmpRect.Top() +
369 ( aTmpRect.Bottom() - aTmpRect.Top() ) / 2 );
370 aPt.setX(aPt.getX() > (pFrame->getFrameArea().Left() + (pFrame->getFrameArea().SSize().Width() / 2 ))
371 ? pFrame->getFrameArea().Right()
372 : pFrame->getFrameArea().Left());
374 const SwPageFrame* pPageFrame = pFrame->FindPageFrame();
375 const SwContentFrame* pFndFrame = pPageFrame->GetContentPos( aPt, false, true );
376 pFndFrame->GetModelPositionForViewPoint( m_pCurrentCursor->GetPoint(), aPt );
378 bool bRet = !m_pCurrentCursor->IsInProtectTable() && !m_pCurrentCursor->IsSelOvr();
379 if( bRet )
380 UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE |
381 SwCursorShell::READONLY );
384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */