Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / crsr / trvlreg.cxx
blob6ae638bd040ae5752969eecd6a534e8c164d3c13
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 = pNd->GetNodes().GoNextSection( &aIdx,
77 true, !bInReadOnly );
78 if( !pCNd )
80 --aIdx;
81 continue;
83 rCurrentCursor.GetPoint()->SetContent( 0 );
85 else
87 aIdx = *pNd->EndOfSectionNode();
88 SwContentNode* pCNd = SwNodes::GoPrevSection( &aIdx,
89 true, !bInReadOnly );
90 if( !pCNd )
92 aIdx.Assign( *pNd, - 1 );
93 continue;
95 rCurrentCursor.GetPoint()->SetContent( pCNd->Len() );
97 rCurrentCursor.GetPoint()->Assign( aIdx );
98 return true;
100 } while( true );
102 // the flow is such that it is not possible to get here
103 return false;
106 bool GotoNextRegion( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosRegion,
107 bool bInReadOnly )
109 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
110 SwNodeIndex aIdx( rCurrentCursor.GetPoint()->GetNode() );
111 SwSectionNode* pNd = aIdx.GetNode().FindSectionNode();
112 if( pNd )
113 aIdx.Assign( *pNd->EndOfSectionNode(), - 1 );
115 SwNodeIndex aOldIdx = aIdx;
116 SwNodeOffset nEndCount = aIdx.GetNode().GetNodes().Count() - 1;
117 do {
118 while( aIdx.GetIndex() < nEndCount )
120 pNd = aIdx.GetNode().GetSectionNode();
121 if (pNd)
122 break;
123 ++aIdx;
124 if ( aIdx == aOldIdx )
126 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
127 return false;
131 if ( aIdx.GetIndex() == nEndCount )
133 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
134 aIdx = SwNodeOffset(0);
135 continue;
138 assert( pNd ); // coverity, should never be nullptr
140 if( pNd->GetSection().IsHiddenFlag() ||
141 ( !bInReadOnly &&
142 pNd->GetSection().IsProtectFlag() ))
144 // skip protected or hidden ones
145 aIdx.Assign( *pNd->EndOfSectionNode(), +1 );
146 continue;
148 else if( &fnPosRegion == &fnMoveForward )
150 aIdx = *pNd;
151 SwContentNode* pCNd = pNd->GetNodes().GoNextSection( &aIdx,
152 true, !bInReadOnly );
153 if( !pCNd )
155 aIdx.Assign( *pNd->EndOfSectionNode(), +1 );
156 continue;
158 rCurrentCursor.GetPoint()->SetContent( 0 );
160 else
162 aIdx = *pNd->EndOfSectionNode();
163 SwContentNode* pCNd = SwNodes::GoPrevSection( &aIdx,
164 true, !bInReadOnly );
165 if( !pCNd )
167 ++aIdx;
168 continue;
170 rCurrentCursor.GetPoint()->SetContent( pCNd->Len() );
172 rCurrentCursor.GetPoint()->Assign( aIdx );
173 return true;
175 } while( true );
177 // the flow is such that it is not possible to get here
178 return false;
181 bool GotoCurrRegionAndSkip( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosRegion,
182 bool bInReadOnly )
184 SwNode& rCurrNd = rCurrentCursor.GetPointNode();
185 SwSectionNode* pNd = rCurrNd.FindSectionNode();
186 if( !pNd )
187 return false;
189 SwPosition* pPos = rCurrentCursor.GetPoint();
190 const sal_Int32 nCurrCnt = pPos->GetContentIndex();
191 bool bMoveBackward = &fnPosRegion == &fnMoveBackward;
193 do {
194 SwContentNode* pCNd;
195 if( bMoveBackward ) // to the end of the section
197 SwNodeIndex aIdx( *pNd->EndOfSectionNode() );
198 pCNd = SwNodes::GoPrevSection( &aIdx, true, !bInReadOnly );
199 if( !pCNd )
200 return false;
201 pPos->Assign( aIdx );
203 else
205 SwNodeIndex aIdx( *pNd );
206 pCNd = pNd->GetNodes().GoNextSection( &aIdx, true, !bInReadOnly );
207 if( !pCNd )
208 return false;
209 pPos->Assign( aIdx );
212 pPos->SetContent( bMoveBackward ? pCNd->Len() : 0 );
214 if( &pPos->GetNode() != &rCurrNd ||
215 pPos->GetContentIndex() != nCurrCnt )
216 // there was a change
217 return true;
219 // try also the parent of this section
220 SwSection* pParent = pNd->GetSection().GetParent();
221 pNd = pParent ? pParent->GetFormat()->GetSectionNode() : nullptr;
222 } while( pNd );
223 return false;
226 bool SwCursor::MoveRegion( SwWhichRegion fnWhichRegion, SwMoveFnCollection const & fnPosRegion )
228 SwCursorSaveState aSaveState( *this );
229 return !dynamic_cast<SwTableCursor*>(this) &&
230 (*fnWhichRegion)( *this, fnPosRegion, IsReadOnlyAvailable() ) &&
231 !IsSelOvr() &&
232 (GetPoint()->GetNodeIndex() != m_vSavePos.back().nNode ||
233 GetPoint()->GetContentIndex() != m_vSavePos.back().nContent);
236 bool SwCursorShell::MoveRegion( SwWhichRegion fnWhichRegion, SwMoveFnCollection const & fnPosRegion )
238 SwCallLink aLk( *this ); // watch Cursor-Moves;call Link if needed
239 bool bRet = !m_pTableCursor && m_pCurrentCursor->MoveRegion( fnWhichRegion, fnPosRegion );
240 if( bRet )
241 UpdateCursor();
242 return bRet;
245 bool SwCursor::GotoRegion( std::u16string_view rName )
247 bool bRet = false;
248 const SwSectionFormats& rFormats = GetDoc().GetSections();
249 for( SwSectionFormats::size_type n = rFormats.size(); n; )
251 const SwSectionFormat* pFormat = rFormats[ --n ];
252 const SwSection* pSect = pFormat->GetSection();
253 if( pSect && pSect->GetSectionName() == rName )
255 const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
256 if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() )
258 // area in normal nodes array
259 SwCursorSaveState aSaveState( *this );
261 GetPoint()->Assign( *pIdx );
262 Move( fnMoveForward, GoInContent );
263 bRet = !IsSelOvr();
267 return bRet;
270 bool SwCursorShell::GotoRegion( std::u16string_view rName )
272 SwCallLink aLk( *this ); // watch Cursor-Moves;call Link if needed
273 bool bRet = !m_pTableCursor && m_pCurrentCursor->GotoRegion( rName );
274 if( bRet )
275 UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE |
276 SwCursorShell::READONLY );
277 return bRet;
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */