Add a comment to clarify what kind of inputs the class handles
[LibreOffice.git] / sw / source / core / crsr / trvlreg.cxx
blob1bcc4e81ea33fc07226ed57e63e86a1835b8fc24
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 <swcrsr.hxx>
23 #include <docary.hxx>
24 #include <fmtcntnt.hxx>
25 #include <viscrs.hxx>
26 #include "callnk.hxx"
27 #include <pamtyp.hxx>
28 #include <section.hxx>
29 #include <svx/srchdlg.hxx>
31 bool GotoPrevRegion( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosRegion,
32 bool bInReadOnly )
34 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
35 SwNodeIndex aIdx( rCurrentCursor.GetPoint()->GetNode() );
36 SwSectionNode* pNd = aIdx.GetNode().FindSectionNode();
37 if( pNd )
38 aIdx.Assign( *pNd, -1 );
40 SwNodeIndex aOldIdx = aIdx;
41 SwNodeOffset nLastNd(rCurrentCursor.GetDoc().GetNodes().Count() - 1);
42 do {
43 while( aIdx.GetIndex() )
45 pNd = aIdx.GetNode().StartOfSectionNode()->GetSectionNode();
46 if (pNd)
47 break;
48 --aIdx;
49 if ( aIdx == aOldIdx )
51 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
52 return false;
56 if ( !aIdx.GetIndex() )
58 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
59 aIdx = nLastNd;
60 continue;
63 assert( pNd ); // coverity, should never be nullptr
65 if( pNd->GetSection().IsHiddenFlag() ||
66 ( !bInReadOnly &&
67 pNd->GetSection().IsProtectFlag() ))
69 // skip protected or hidden ones
70 aIdx.Assign( *pNd, - 1 );
71 continue;
73 else if( &fnPosRegion == &fnMoveForward )
75 aIdx = *pNd;
76 SwContentNode* pCNd = SwNodes::GoNextSection(&aIdx, true, !bInReadOnly);
77 if( !pCNd )
79 --aIdx;
80 continue;
82 rCurrentCursor.GetPoint()->SetContent( 0 );
84 else
86 aIdx = *pNd->EndOfSectionNode();
87 SwContentNode* pCNd = SwNodes::GoPrevSection( &aIdx,
88 true, !bInReadOnly );
89 if( !pCNd )
91 aIdx.Assign( *pNd, - 1 );
92 continue;
94 rCurrentCursor.GetPoint()->SetContent( pCNd->Len() );
96 rCurrentCursor.GetPoint()->Assign( aIdx );
97 return true;
99 } while( true );
101 // the flow is such that it is not possible to get here
102 return false;
105 bool GotoNextRegion( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosRegion,
106 bool bInReadOnly )
108 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
109 SwNodeIndex aIdx( rCurrentCursor.GetPoint()->GetNode() );
110 SwSectionNode* pNd = aIdx.GetNode().FindSectionNode();
111 if( pNd )
112 aIdx.Assign( *pNd->EndOfSectionNode(), - 1 );
114 SwNodeIndex aOldIdx = aIdx;
115 SwNodeOffset nEndCount = aIdx.GetNode().GetNodes().Count() - 1;
116 do {
117 while( aIdx.GetIndex() < nEndCount )
119 pNd = aIdx.GetNode().GetSectionNode();
120 if (pNd)
121 break;
122 ++aIdx;
123 if ( aIdx == aOldIdx )
125 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
126 return false;
130 if ( aIdx.GetIndex() == nEndCount )
132 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
133 aIdx = SwNodeOffset(0);
134 continue;
137 assert( pNd ); // coverity, should never be nullptr
139 if( pNd->GetSection().IsHiddenFlag() ||
140 ( !bInReadOnly &&
141 pNd->GetSection().IsProtectFlag() ))
143 // skip protected or hidden ones
144 aIdx.Assign( *pNd->EndOfSectionNode(), +1 );
145 continue;
147 else if( &fnPosRegion == &fnMoveForward )
149 aIdx = *pNd;
150 SwContentNode* pCNd = SwNodes::GoNextSection(&aIdx, true, !bInReadOnly);
151 if( !pCNd )
153 aIdx.Assign( *pNd->EndOfSectionNode(), +1 );
154 continue;
156 rCurrentCursor.GetPoint()->SetContent( 0 );
158 else
160 aIdx = *pNd->EndOfSectionNode();
161 SwContentNode* pCNd = SwNodes::GoPrevSection( &aIdx,
162 true, !bInReadOnly );
163 if( !pCNd )
165 ++aIdx;
166 continue;
168 rCurrentCursor.GetPoint()->SetContent( pCNd->Len() );
170 rCurrentCursor.GetPoint()->Assign( aIdx );
171 return true;
173 } while( true );
175 // the flow is such that it is not possible to get here
176 return false;
179 bool GotoCurrRegionAndSkip( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosRegion,
180 bool bInReadOnly )
182 SwNode& rCurrNd = rCurrentCursor.GetPointNode();
183 SwSectionNode* pNd = rCurrNd.FindSectionNode();
184 if( !pNd )
185 return false;
187 SwPosition* pPos = rCurrentCursor.GetPoint();
188 const sal_Int32 nCurrCnt = pPos->GetContentIndex();
189 bool bMoveBackward = &fnPosRegion == &fnMoveBackward;
191 do {
192 SwContentNode* pCNd;
193 if( bMoveBackward ) // to the end of the section
195 SwNodeIndex aIdx( *pNd->EndOfSectionNode() );
196 pCNd = SwNodes::GoPrevSection( &aIdx, true, !bInReadOnly );
197 if( !pCNd )
198 return false;
199 pPos->Assign( aIdx );
201 else
203 SwNodeIndex aIdx( *pNd );
204 pCNd = SwNodes::GoNextSection(&aIdx, true, !bInReadOnly);
205 if( !pCNd )
206 return false;
207 pPos->Assign( aIdx );
210 pPos->SetContent( bMoveBackward ? pCNd->Len() : 0 );
212 if( &pPos->GetNode() != &rCurrNd ||
213 pPos->GetContentIndex() != nCurrCnt )
214 // there was a change
215 return true;
217 // try also the parent of this section
218 SwSection* pParent = pNd->GetSection().GetParent();
219 pNd = pParent ? pParent->GetFormat()->GetSectionNode() : nullptr;
220 } while( pNd );
221 return false;
224 bool SwCursor::MoveRegion( SwWhichRegion fnWhichRegion, SwMoveFnCollection const & fnPosRegion )
226 SwCursorSaveState aSaveState( *this );
227 return !dynamic_cast<SwTableCursor*>(this) &&
228 (*fnWhichRegion)( *this, fnPosRegion, IsReadOnlyAvailable() ) &&
229 !IsSelOvr() &&
230 (GetPoint()->GetNodeIndex() != m_vSavePos.back().nNode ||
231 GetPoint()->GetContentIndex() != m_vSavePos.back().nContent);
234 bool SwCursorShell::MoveRegion( SwWhichRegion fnWhichRegion, SwMoveFnCollection const & fnPosRegion )
236 SwCallLink aLk( *this ); // watch Cursor-Moves;call Link if needed
237 bool bRet = !m_pTableCursor && m_pCurrentCursor->MoveRegion( fnWhichRegion, fnPosRegion );
238 if( bRet )
239 UpdateCursor();
240 return bRet;
243 bool SwCursor::GotoRegion( std::u16string_view rName )
245 bool bRet = false;
246 const SwSectionFormats& rFormats = GetDoc().GetSections();
247 for( SwSectionFormats::size_type n = rFormats.size(); n; )
249 const SwSectionFormat* pFormat = rFormats[ --n ];
250 const SwSection* pSect = pFormat->GetSection();
251 if( pSect && pSect->GetSectionName() == rName )
253 const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
254 if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() )
256 // area in normal nodes array
257 SwCursorSaveState aSaveState( *this );
259 GetPoint()->Assign( *pIdx );
260 Move( fnMoveForward, GoInContent );
261 bRet = !IsSelOvr();
265 return bRet;
268 bool SwCursorShell::GotoRegion( std::u16string_view rName )
270 SwCallLink aLk( *this ); // watch Cursor-Moves;call Link if needed
271 bool bRet = !m_pTableCursor && m_pCurrentCursor->GotoRegion( rName );
272 if( bRet )
273 UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE |
274 SwCursorShell::READONLY );
275 return bRet;
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */