xref: /trunk/main/sw/source/core/crsr/trvlreg.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <crsrsh.hxx>
33 #include <doc.hxx>
34 #include <swcrsr.hxx>
35 #include <docary.hxx>
36 #include <fmtcntnt.hxx>
37 #include <viscrs.hxx>
38 #include <callnk.hxx>
39 #include <pamtyp.hxx>
40 #include <section.hxx>
41 
42 
43 
44 sal_Bool GotoPrevRegion( SwPaM& rCurCrsr, SwPosRegion fnPosRegion,
45                         sal_Bool bInReadOnly )
46 {
47     SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode );
48     SwSectionNode* pNd = aIdx.GetNode().FindSectionNode();
49     if( pNd )
50         aIdx.Assign( *pNd, - 1 );
51 
52     do {
53         while( aIdx.GetIndex() &&
54             0 == ( pNd = aIdx.GetNode().StartOfSectionNode()->GetSectionNode()) )
55             aIdx--;
56 
57         if( pNd )       // gibt einen weiteren SectionNode ?
58         {
59             if( pNd->GetSection().IsHiddenFlag() ||
60                 ( !bInReadOnly &&
61                   pNd->GetSection().IsProtectFlag() ))
62             {
63                 // geschuetzte/versteckte ueberspringen wir
64                 aIdx.Assign( *pNd, - 1 );
65             }
66             else if( fnPosRegion == fnMoveForward )
67             {
68                 aIdx = *pNd;
69                 SwCntntNode* pCNd = pNd->GetNodes().GoNextSection( &aIdx,
70                                                 sal_True, !bInReadOnly );
71                 if( !pCNd )
72                 {
73                     aIdx--;
74                     continue;
75                 }
76                 rCurCrsr.GetPoint()->nContent.Assign( pCNd, 0 );
77             }
78             else
79             {
80                 aIdx = *pNd->EndOfSectionNode();
81                 SwCntntNode* pCNd = pNd->GetNodes().GoPrevSection( &aIdx,
82                                                 sal_True, !bInReadOnly );
83                 if( !pCNd )
84                 {
85                     aIdx.Assign( *pNd, - 1 );
86                     continue;
87                 }
88                 rCurCrsr.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
89             }
90 
91             rCurCrsr.GetPoint()->nNode = aIdx;
92             return sal_True;
93         }
94     } while( pNd );
95     return sal_False;
96 }
97 
98 
99 sal_Bool GotoNextRegion( SwPaM& rCurCrsr, SwPosRegion fnPosRegion,
100                         sal_Bool bInReadOnly )
101 {
102     SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode );
103     SwSectionNode* pNd = aIdx.GetNode().FindSectionNode();
104     if( pNd )
105         aIdx.Assign( *pNd->EndOfSectionNode(), - 1 );
106 
107     sal_uLong nEndCount = aIdx.GetNode().GetNodes().Count()-1;
108     do {
109         while( aIdx.GetIndex() < nEndCount &&
110                 0 == ( pNd = aIdx.GetNode().GetSectionNode()) )
111             aIdx++;
112 
113         if( pNd )       // gibt einen weiteren SectionNode ?
114         {
115             if( pNd->GetSection().IsHiddenFlag() ||
116                 ( !bInReadOnly &&
117                   pNd->GetSection().IsProtectFlag() ))
118             {
119                 // geschuetzte/versteckte ueberspringen wir
120                 aIdx.Assign( *pNd->EndOfSectionNode(), +1 );
121             }
122             else if( fnPosRegion == fnMoveForward )
123             {
124                 aIdx = *pNd;
125                 SwCntntNode* pCNd = pNd->GetNodes().GoNextSection( &aIdx,
126                                                 sal_True, !bInReadOnly );
127                 if( !pCNd )
128                 {
129                     aIdx.Assign( *pNd->EndOfSectionNode(), +1 );
130                     continue;
131                 }
132                 rCurCrsr.GetPoint()->nContent.Assign( pCNd, 0 );
133             }
134             else
135             {
136                 aIdx = *pNd->EndOfSectionNode();
137                 SwCntntNode* pCNd = pNd->GetNodes().GoPrevSection( &aIdx,
138                                                 sal_True, !bInReadOnly );
139                 if( !pCNd )
140                 {
141                     aIdx++;
142                     continue;
143                 }
144                 rCurCrsr.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
145             }
146 
147             rCurCrsr.GetPoint()->nNode = aIdx;
148             return sal_True;
149         }
150     } while( pNd );
151     return sal_False;
152 }
153 
154 
155 sal_Bool GotoCurrRegion( SwPaM& rCurCrsr, SwPosRegion fnPosRegion,
156                         sal_Bool bInReadOnly )
157 {
158     SwSectionNode* pNd = rCurCrsr.GetNode()->FindSectionNode();
159     if( !pNd )
160         return sal_False;
161 
162     SwPosition* pPos = rCurCrsr.GetPoint();
163     sal_Bool bMoveBackward = fnPosRegion == fnMoveBackward;
164 
165     SwCntntNode* pCNd;
166     if( bMoveBackward )
167     {
168         SwNodeIndex aIdx( *pNd->EndOfSectionNode() );
169         pCNd = pNd->GetNodes().GoPrevSection( &aIdx, sal_True, !bInReadOnly );
170     }
171     else
172     {
173         SwNodeIndex aIdx( *pNd );
174         pCNd = pNd->GetNodes().GoNextSection( &aIdx, sal_True, !bInReadOnly );
175     }
176 
177     if( pCNd )
178     {
179         pPos->nNode = *pCNd;
180         xub_StrLen nTmpPos = bMoveBackward ? pCNd->Len() : 0;
181         pPos->nContent.Assign( pCNd, nTmpPos );
182     }
183     return 0 != pCNd;
184 }
185 
186 
187 sal_Bool GotoCurrRegionAndSkip( SwPaM& rCurCrsr, SwPosRegion fnPosRegion,
188                                 sal_Bool bInReadOnly )
189 {
190     SwNode* pCurrNd = rCurCrsr.GetNode();
191     SwSectionNode* pNd = pCurrNd->FindSectionNode();
192     if( !pNd )
193         return sal_False;
194 
195     SwPosition* pPos = rCurCrsr.GetPoint();
196     xub_StrLen nCurrCnt = pPos->nContent.GetIndex();
197     sal_Bool bMoveBackward = fnPosRegion == fnMoveBackward;
198 
199     do {
200         SwCntntNode* pCNd;
201         if( bMoveBackward ) // ans Ende vom Bereich
202         {
203             SwNodeIndex aIdx( *pNd->EndOfSectionNode() );
204             pCNd = pNd->GetNodes().GoPrevSection( &aIdx, sal_True, !bInReadOnly );
205             if( !pCNd )
206                 return sal_False;
207             pPos->nNode = aIdx;
208         }
209         else
210         {
211             SwNodeIndex aIdx( *pNd );
212             pCNd = pNd->GetNodes().GoNextSection( &aIdx, sal_True, !bInReadOnly );
213             if( !pCNd )
214                 return sal_False;
215             pPos->nNode = aIdx;
216         }
217 
218         xub_StrLen nTmpPos = bMoveBackward ? pCNd->Len() : 0;
219         pPos->nContent.Assign( pCNd, nTmpPos );
220 
221         if( &pPos->nNode.GetNode() != pCurrNd ||
222             pPos->nContent.GetIndex() != nCurrCnt )
223             // es gab eine Veraenderung
224             return sal_True;
225 
226         // dann versuche mal den "Parent" dieser Section
227         SwSection* pParent = pNd->GetSection().GetParent();
228         pNd = pParent ? pParent->GetFmt()->GetSectionNode() : 0;
229     } while( pNd );
230     return sal_False;
231 }
232 
233 
234 
235 sal_Bool SwCursor::MoveRegion( SwWhichRegion fnWhichRegion, SwPosRegion fnPosRegion )
236 {
237     SwCrsrSaveState aSaveState( *this );
238     return !dynamic_cast<SwTableCursor*>(this) &&
239             (*fnWhichRegion)( *this, fnPosRegion, IsReadOnlyAvailable()  ) &&
240             !IsSelOvr() &&
241             ( GetPoint()->nNode.GetIndex() != pSavePos->nNode ||
242                 GetPoint()->nContent.GetIndex() != pSavePos->nCntnt );
243 }
244 
245 sal_Bool SwCrsrShell::MoveRegion( SwWhichRegion fnWhichRegion, SwPosRegion fnPosRegion )
246 {
247     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
248     sal_Bool bRet = !pTblCrsr && pCurCrsr->MoveRegion( fnWhichRegion, fnPosRegion );
249     if( bRet )
250         UpdateCrsr();
251     return bRet;
252 }
253 
254 
255 sal_Bool SwCursor::GotoRegion( const String& rName )
256 {
257     sal_Bool bRet = sal_False;
258     const SwSectionFmts& rFmts = GetDoc()->GetSections();
259     for( sal_uInt16 n = rFmts.Count(); n; )
260     {
261         const SwSectionFmt* pFmt = rFmts[ --n ];
262         const SwNodeIndex* pIdx;
263         const SwSection* pSect;
264         if( 0 != ( pSect = pFmt->GetSection() ) &&
265             pSect->GetSectionName() == rName &&
266             0 != ( pIdx = pFmt->GetCntnt().GetCntntIdx() ) &&
267             pIdx->GetNode().GetNodes().IsDocNodes() )
268         {
269             // ein Bereich im normalen NodesArr
270             SwCrsrSaveState aSaveState( *this );
271 
272             GetPoint()->nNode = *pIdx;
273             Move( fnMoveForward, fnGoCntnt );
274             bRet = !IsSelOvr();
275         }
276     }
277     return bRet;
278 }
279 
280 sal_Bool SwCrsrShell::GotoRegion( const String& rName )
281 {
282     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
283     sal_Bool bRet = !pTblCrsr && pCurCrsr->GotoRegion( rName );
284     if( bRet )
285         UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
286                     SwCrsrShell::READONLY ); // und den akt. Updaten
287     return bRet;
288 }
289 
290 
291 
292