xref: /aoo41x/main/sw/source/core/crsr/crstrvl.cxx (revision c0286415)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <hintids.hxx>
29 #include <svl/itemiter.hxx>
30 #include <editeng/lrspitem.hxx>
31 #include <editeng/adjitem.hxx>
32 #include <editeng/brkitem.hxx>
33 #include <svx/svdobj.hxx>
34 #include <crsrsh.hxx>
35 #include <doc.hxx>
36 #include <IDocumentUndoRedo.hxx>
37 #include <pagefrm.hxx>
38 #include <cntfrm.hxx>
39 #include <rootfrm.hxx>
40 #include <pam.hxx>
41 #include <ndtxt.hxx>
42 #include <fldbas.hxx>
43 #include <swtable.hxx>		// SwTxtFld
44 #include <docary.hxx>
45 #include <txtfld.hxx>
46 #include <fmtfld.hxx>
47 #include <txtftn.hxx>
48 #include <txtinet.hxx>
49 #include <fmtinfmt.hxx>
50 #include <txttxmrk.hxx>
51 #include <frmfmt.hxx>
52 #include <flyfrm.hxx>
53 #include <viscrs.hxx>
54 #include <callnk.hxx>
55 #include <doctxm.hxx>
56 #include <docfld.hxx>
57 #include <expfld.hxx>
58 #include <reffld.hxx>
59 #include <flddat.hxx>       // SwTxtFld
60 #include <cellatr.hxx>
61 #include <swundo.hxx>
62 #include <redline.hxx>
63 #include <fmtcntnt.hxx>
64 #include <fmthdft.hxx>
65 #include <pagedesc.hxx>
66 #include <fesh.hxx>
67 #include <charfmt.hxx>
68 #include <fmturl.hxx>
69 #include "txtfrm.hxx"
70 #include <wrong.hxx>
71 #include <switerator.hxx>
72 #include <vcl/window.hxx>
73 #include <docufld.hxx> // OD 2008-06-19 #i90516#
74 
75 using namespace ::com::sun::star;
76 
77 
78 // zum naechsten/vorhergehenden Punkt auf gleicher Ebene
79 sal_Bool SwCrsrShell::GotoNextNum()
80 {
81 	sal_Bool bRet = GetDoc()->GotoNextNum( *pCurCrsr->GetPoint() );
82 	if( bRet )
83 	{
84 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
85 		SwCrsrSaveState aSaveState( *pCurCrsr );
86 		if( !ActionPend() )
87 		{
88 			SET_CURR_SHELL( this );
89 			// dann versuche den Cursor auf die Position zu setzen,
90 			// auf halber Heohe vom Char-SRectangle
91 			Point aPt( pCurCrsr->GetPtPos() );
92 			SwCntntFrm * pFrm = pCurCrsr->GetCntntNode()->getLayoutFrm( GetLayout(), &aPt,
93 														pCurCrsr->GetPoint() );
94 			pFrm->GetCharRect( aCharRect, *pCurCrsr->GetPoint() );
95 			pFrm->Calc();
96             if( pFrm->IsVertical() )
97             {
98                 aPt.X() = aCharRect.Center().X();
99                 aPt.Y() = pFrm->Frm().Top() + nUpDownX;
100             }
101             else
102             {
103                 aPt.Y() = aCharRect.Center().Y();
104                 aPt.X() = pFrm->Frm().Left() + nUpDownX;
105             }
106 			pFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt );
107             bRet = !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
108                                         nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
109 			if( bRet )
110 				UpdateCrsr(SwCrsrShell::UPDOWN |
111 						SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
112 						SwCrsrShell::READONLY );
113 		}
114 	}
115 	return bRet;
116 }
117 
118 
119 sal_Bool SwCrsrShell::GotoPrevNum()
120 {
121 	sal_Bool bRet = GetDoc()->GotoPrevNum( *pCurCrsr->GetPoint() );
122 	if( bRet )
123 	{
124 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
125 		SwCrsrSaveState aSaveState( *pCurCrsr );
126 		if( !ActionPend() )
127 		{
128 			SET_CURR_SHELL( this );
129 			// dann versuche den Cursor auf die Position zu setzen,
130 			// auf halber Heohe vom Char-SRectangle
131 			Point aPt( pCurCrsr->GetPtPos() );
132 			SwCntntFrm * pFrm = pCurCrsr->GetCntntNode()->getLayoutFrm( GetLayout(), &aPt,
133 														pCurCrsr->GetPoint() );
134 			pFrm->GetCharRect( aCharRect, *pCurCrsr->GetPoint() );
135 			pFrm->Calc();
136             if( pFrm->IsVertical() )
137             {
138                 aPt.X() = aCharRect.Center().X();
139                 aPt.Y() = pFrm->Frm().Top() + nUpDownX;
140             }
141             else
142             {
143                 aPt.Y() = aCharRect.Center().Y();
144                 aPt.X() = pFrm->Frm().Left() + nUpDownX;
145             }
146 			pFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt );
147             bRet = !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
148                                         nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
149 			if( bRet )
150 				UpdateCrsr(SwCrsrShell::UPDOWN |
151 						SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
152 						SwCrsrShell::READONLY );
153 		}
154 	}
155 	return bRet;
156 }
157 
158 // springe aus dem Content zum Header
159 
160 sal_Bool SwCrsrShell::GotoHeaderTxt()
161 {
162 	const SwFrm* pFrm = GetCurrFrm()->FindPageFrm();
163 	while( pFrm && !pFrm->IsHeaderFrm() )
164 		pFrm = pFrm->GetLower();
165 	// Header gefunden, dann suche den 1.Cntnt-Frame
166 	while( pFrm && !pFrm->IsCntntFrm() )
167 		pFrm = pFrm->GetLower();
168 	if( pFrm )
169 	{
170 		SET_CURR_SHELL( this );
171 		// hole den Header-Frame
172 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
173         SwCursor *pTmpCrsr = getShellCrsr( true );
174 		SwCrsrSaveState aSaveState( *pTmpCrsr );
175 		pFrm->Calc();
176 		Point aPt( pFrm->Frm().Pos() + pFrm->Prt().Pos() );
177 		pFrm->GetCrsrOfst( pTmpCrsr->GetPoint(), aPt );
178 		if( !pTmpCrsr->IsSelOvr() )
179 			UpdateCrsr();
180 		else
181 			pFrm = 0;
182 	}
183 	return 0 != pFrm;
184 }
185 
186 
187 // springe aus dem Content zum Footer
188 
189 sal_Bool SwCrsrShell::GotoFooterTxt()
190 {
191 	const SwPageFrm* pFrm = GetCurrFrm()->FindPageFrm();
192 	if( pFrm )
193 	{
194         const SwFrm* pLower = pFrm->GetLastLower();
195 
196 		while( pLower && !pLower->IsFooterFrm() )
197 			pLower = pLower->GetLower();
198 		// Header gefunden, dann suche den 1.Cntnt-Frame
199 		while( pLower && !pLower->IsCntntFrm() )
200 			pLower = pLower->GetLower();
201 
202 		if( pLower )
203 		{
204             SwCursor *pTmpCrsr = getShellCrsr( true );
205             SET_CURR_SHELL( this );
206 			// hole eine Position im Footer
207 			SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
208 			SwCrsrSaveState aSaveState( *pTmpCrsr );
209 			pLower->Calc();
210 			Point aPt( pLower->Frm().Pos() + pLower->Prt().Pos() );
211 			pLower->GetCrsrOfst( pTmpCrsr->GetPoint(), aPt );
212 			if( !pTmpCrsr->IsSelOvr() )
213 				UpdateCrsr();
214 			else
215 				pFrm = 0;
216 		}
217 		else
218 			pFrm = 0;
219 	}
220 	else
221 		pFrm = 0;
222 	return 0 != pFrm;
223 }
224 
225 sal_Bool SwCrsrShell::SetCrsrInHdFt( sal_uInt16 nDescNo, sal_Bool bInHeader )
226 {
227 	sal_Bool bRet = sal_False;
228     SwDoc *pMyDoc = GetDoc();
229 
230 	SET_CURR_SHELL( this );
231 
232 	if( USHRT_MAX == nDescNo )
233 	{
234 		// dann den akt. nehmen
235 		const SwPageFrm* pPage = GetCurrFrm()->FindPageFrm();
236 		if( pPage )
237             for( sal_uInt16 i = 0; i < pMyDoc->GetPageDescCnt(); ++i )
238 				if( pPage->GetPageDesc() ==
239                     &const_cast<const SwDoc *>(pMyDoc)->GetPageDesc( i ) )
240 				{
241 					nDescNo = i;
242 					break;
243 				}
244 	}
245 
246     if( USHRT_MAX != nDescNo && nDescNo < pMyDoc->GetPageDescCnt() )
247 	{
248 		//dann teste mal, ob ueberhaupt das Attribut vorhanden ist.
249         const SwPageDesc& rDesc = const_cast<const SwDoc *>(pMyDoc)
250             ->GetPageDesc( nDescNo );
251 		const SwFmtCntnt* pCnt = 0;
252 		if( bInHeader )
253 		{
254 			// gespiegelte Seiten??? erstmal nicht beachten
255 			const SwFmtHeader& rHd = rDesc.GetMaster().GetHeader();
256 			if( rHd.GetHeaderFmt() )
257 				pCnt = &rHd.GetHeaderFmt()->GetCntnt();
258 		}
259 		else
260 		{
261 			const SwFmtFooter& rFt = rDesc.GetMaster().GetFooter();
262 			if( rFt.GetFooterFmt() )
263 				pCnt = &rFt.GetFooterFmt()->GetCntnt();
264 		}
265 
266 		if( pCnt && pCnt->GetCntntIdx() )
267 		{
268 			SwNodeIndex aIdx( *pCnt->GetCntntIdx(), 1 );
269 			SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
270 			if( !pCNd )
271                 pCNd = pMyDoc->GetNodes().GoNext( &aIdx );
272 
273 			const SwFrm* pFrm;
274 			Point aPt( pCurCrsr->GetPtPos() );
275 
276 			if( pCNd && 0 != ( pFrm = pCNd->getLayoutFrm( GetLayout(), &aPt, 0, sal_False ) ))
277 			{
278 				// dann kann der Cursor ja auch hinein gesetzt werden
279 				SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
280 				SwCrsrSaveState aSaveState( *pCurCrsr );
281 
282 				ClearMark();
283 
284 				SwPosition& rPos = *pCurCrsr->GetPoint();
285 				rPos.nNode = *pCNd;
286 				rPos.nContent.Assign( pCNd, 0 );
287 
288 				bRet = !pCurCrsr->IsSelOvr();
289 				if( bRet )
290 					UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
291 								SwCrsrShell::READONLY );
292 			}
293 		}
294 	}
295 	return bRet;
296 }
297 
298 // springe zum naechsten Verzeichnis
299 
300 sal_Bool SwCrsrShell::GotoNextTOXBase( const String* pName )
301 {
302 	sal_Bool bRet = sal_False;
303 
304 	const SwSectionFmts& rFmts = GetDoc()->GetSections();
305 	SwCntntNode* pFnd = 0;
306 	for( sal_uInt16 n = rFmts.Count(); n; )
307 	{
308 		const SwSection* pSect = rFmts[ --n ]->GetSection();
309 		const SwSectionNode* pSectNd;
310 		if( TOX_CONTENT_SECTION == pSect->GetType() &&
311 			0 != ( pSectNd = pSect->GetFmt()->GetSectionNode() ) &&
312 			 pCurCrsr->GetPoint()->nNode < pSectNd->GetIndex() &&
313 			( !pFnd || pFnd->GetIndex() > pSectNd->GetIndex() ) &&
314 // JP 10.12.96: solange wir nur 3 Typen kennen und UI-seitig keine anderen
315 //				einstellbar sind, muss ueber den Titel gesucht werden!
316 //			( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTypeName() ) &&
317 			( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTOXName() )
318 			)
319 		{
320 			SwNodeIndex aIdx( *pSectNd, 1 );
321 			SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
322 			if( !pCNd )
323 				pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
324 			const SwCntntFrm* pCFrm;
325 			if( pCNd &&
326 				pCNd->EndOfSectionIndex() <= pSectNd->EndOfSectionIndex() &&
327 				0 != ( pCFrm = pCNd->getLayoutFrm( GetLayout() ) ) &&
328 				( IsReadOnlyAvailable() || !pCFrm->IsProtected() ))
329 			{
330 				pFnd = pCNd;
331 			}
332 		}
333 	}
334 	if( pFnd )
335 	{
336 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
337 		SwCrsrSaveState aSaveState( *pCurCrsr );
338 		pCurCrsr->GetPoint()->nNode = *pFnd;
339 		pCurCrsr->GetPoint()->nContent.Assign( pFnd, 0 );
340 		bRet = !pCurCrsr->IsSelOvr();
341 		if( bRet )
342 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
343 	}
344 	return bRet;
345 }
346 
347 // springe zum vorherigen Verzeichnis
348 
349 
350 sal_Bool SwCrsrShell::GotoPrevTOXBase( const String* pName )
351 {
352 	sal_Bool bRet = sal_False;
353 
354 	const SwSectionFmts& rFmts = GetDoc()->GetSections();
355 	SwCntntNode* pFnd = 0;
356 	for( sal_uInt16 n = rFmts.Count(); n; )
357 	{
358 		const SwSection* pSect = rFmts[ --n ]->GetSection();
359 		const SwSectionNode* pSectNd;
360 		if( TOX_CONTENT_SECTION == pSect->GetType() &&
361 			0 != ( pSectNd = pSect->GetFmt()->GetSectionNode() ) &&
362 			pCurCrsr->GetPoint()->nNode > pSectNd->EndOfSectionIndex() &&
363 			( !pFnd || pFnd->GetIndex() < pSectNd->GetIndex() ) &&
364 // JP 10.12.96: solange wir nur 3 Typen kennen und UI-seitig keine anderen
365 //				einstellbar sind, muss ueber den Titel gesucht werden!
366 //			( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTypeName() ) &&
367 			( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTOXName() )
368 			)
369 		{
370 			SwNodeIndex aIdx( *pSectNd, 1 );
371 			SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
372 			if( !pCNd )
373 				pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
374 			const SwCntntFrm* pCFrm;
375 			if( pCNd &&
376 				pCNd->EndOfSectionIndex() <= pSectNd->EndOfSectionIndex() &&
377 				0 != ( pCFrm = pCNd->getLayoutFrm( GetLayout() ) ) &&
378 				( IsReadOnlyAvailable() || !pCFrm->IsProtected() ))
379 			{
380 				pFnd = pCNd;
381 			}
382 		}
383 	}
384 
385 	if( pFnd )
386 	{
387 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
388 		SwCrsrSaveState aSaveState( *pCurCrsr );
389 		pCurCrsr->GetPoint()->nNode = *pFnd;
390 		pCurCrsr->GetPoint()->nContent.Assign( pFnd, 0 );
391 		bRet = !pCurCrsr->IsSelOvr();
392 		if( bRet )
393 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
394 	}
395 	return bRet;
396 }
397 
398 // springe zum Verzeichnis vom TOXMark
399 
400 sal_Bool SwCrsrShell::GotoTOXMarkBase()
401 {
402 	sal_Bool bRet = sal_False;
403 
404 	SwTOXMarks aMarks;
405 	sal_uInt16 nCnt = GetDoc()->GetCurTOXMark( *pCurCrsr->GetPoint(), aMarks );
406 	if( nCnt )
407 	{
408 		// dann nehme den 1. und hole den Verzeichnis-Typ.
409 		// Suche in seiner Abhaengigkeitsliste nach dem eigentlichem
410 		// Verzeichnis
411 		const SwTOXType* pType = aMarks[0]->GetTOXType();
412 		SwIterator<SwTOXBase,SwTOXType> aIter( *pType );
413 		const SwSectionNode* pSectNd;
414 		const SwSectionFmt* pSectFmt;
415 
416 		for( SwTOXBase* pTOX = aIter.First(); pTOX; pTOX = aIter.Next() )
417         {
418 			if( pTOX->ISA( SwTOXBaseSection ) &&
419 				0 != ( pSectFmt = ((SwTOXBaseSection*)pTOX)->GetFmt() ) &&
420 				0 != ( pSectNd = pSectFmt->GetSectionNode() ))
421 			{
422 				SwNodeIndex aIdx( *pSectNd, 1 );
423 				SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
424 				if( !pCNd )
425 					pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
426 				const SwCntntFrm* pCFrm;
427 				if( pCNd &&
428 					pCNd->EndOfSectionIndex() < pSectNd->EndOfSectionIndex() &&
429 					0 != ( pCFrm = pCNd->getLayoutFrm( GetLayout() ) ) &&
430 					( IsReadOnlyAvailable() || !pCFrm->IsProtected() ))
431 				{
432 					SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
433 					SwCrsrSaveState aSaveState( *pCurCrsr );
434 					pCurCrsr->GetPoint()->nNode = *pCNd;
435 					pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
436 					bRet = !pCurCrsr->IsInProtectTable() &&
437 							!pCurCrsr->IsSelOvr();
438 					if( bRet )
439 						UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
440 					break;
441 				}
442 			}
443 	}
444 	}
445 	return bRet;
446 }
447 
448 
449 	// springe zur naechsten (vorherigen) Tabellenformel
450 	// optional auch nur zu kaputten Formeln springen
451 sal_Bool SwCrsrShell::GotoNxtPrvTblFormula( sal_Bool bNext, sal_Bool bOnlyErrors )
452 {
453 	if( IsTableMode() )
454 		return sal_False;
455 
456 	sal_Bool bFnd = sal_False;
457 	SwPosition& rPos = *pCurCrsr->GetPoint();
458 
459 	Point aPt;
460 	SwPosition aFndPos( GetDoc()->GetNodes().GetEndOfContent() );
461 	if( !bNext )
462 		aFndPos.nNode = 0;
463 	_SetGetExpFld aFndGEF( aFndPos ), aCurGEF( rPos );
464 
465 	{
466 		const SwNode* pSttNd = rPos.nNode.GetNode().FindTableBoxStartNode();
467 		if( pSttNd )
468 		{
469 			const SwTableBox* pTBox = pSttNd->FindTableNode()->GetTable().
470 										GetTblBox( pSttNd->GetIndex() );
471 			if( pTBox )
472 				aCurGEF = _SetGetExpFld( *pTBox );
473 		}
474 	}
475 
476 	if( rPos.nNode < GetDoc()->GetNodes().GetEndOfExtras() )
477 		// auch beim Einsammeln wird nur der erste Frame benutzt!
478 		aCurGEF.SetBodyPos( *rPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(),
479 								&aPt, &rPos, sal_False ) );
480 	{
481 		const SfxPoolItem* pItem;
482 		const SwTableBox* pTBox;
483 		sal_uInt32 n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
484 
485 		for( n = 0; n < nMaxItems; ++n )
486 			if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem2(
487 										RES_BOXATR_FORMULA, n ) ) &&
488 				0 != (pTBox = ((SwTblBoxFormula*)pItem)->GetTableBox() ) &&
489 				pTBox->GetSttNd() &&
490 				pTBox->GetSttNd()->GetNodes().IsDocNodes() &&
491 				( !bOnlyErrors ||
492 				  !((SwTblBoxFormula*)pItem)->HasValidBoxes() ) )
493 			{
494 				const SwCntntFrm* pCFrm;
495 				SwNodeIndex aIdx( *pTBox->GetSttNd() );
496 				const SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
497 				if( pCNd && 0 != ( pCFrm = pCNd->getLayoutFrm( GetLayout(), &aPt, 0, sal_False ) ) &&
498 					(IsReadOnlyAvailable() || !pCFrm->IsProtected() ))
499 				{
500 					_SetGetExpFld aCmp( *pTBox );
501 					aCmp.SetBodyPos( *pCFrm );
502 
503 					if( bNext ? ( aCurGEF < aCmp && aCmp < aFndGEF )
504 							  : ( aCmp < aCurGEF && aFndGEF < aCmp ))
505 					{
506 						aFndGEF = aCmp;
507 						bFnd = sal_True;
508 					}
509 				}
510 			}
511 	}
512 
513 	if( bFnd )
514 	{
515 		SET_CURR_SHELL( this );
516 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
517 		SwCrsrSaveState aSaveState( *pCurCrsr );
518 
519 		aFndGEF.GetPosOfContent( rPos );
520 		pCurCrsr->DeleteMark();
521 
522 		bFnd = !pCurCrsr->IsSelOvr();
523 		if( bFnd )
524 			UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
525 						SwCrsrShell::READONLY );
526 	}
527 	return bFnd;
528 }
529 
530 // springe zum naechsten (vorherigen) Verzeichniseintrag
531 sal_Bool SwCrsrShell::GotoNxtPrvTOXMark( sal_Bool bNext )
532 {
533 	if( IsTableMode() )
534 		return sal_False;
535 
536 	sal_Bool bFnd = sal_False;
537 	SwPosition& rPos = *pCurCrsr->GetPoint();
538 
539 	Point aPt;
540 	SwPosition aFndPos( GetDoc()->GetNodes().GetEndOfContent() );
541 	if( !bNext )
542 		aFndPos.nNode = 0;
543 	_SetGetExpFld aFndGEF( aFndPos ), aCurGEF( rPos );
544 
545 	if( rPos.nNode.GetIndex() < GetDoc()->GetNodes().GetEndOfExtras().GetIndex() )
546 		// auch beim Einsammeln wird nur der erste Frame benutzt!
547 		aCurGEF.SetBodyPos( *rPos.nNode.GetNode().
548 						GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, &rPos, sal_False ) );
549 	{
550 		const SfxPoolItem* pItem;
551 		const SwCntntFrm* pCFrm;
552 		const SwTxtNode* pTxtNd;
553 		const SwTxtTOXMark* pTxtTOX;
554 		sal_uInt32 n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK );
555 
556 		for( n = 0; n < nMaxItems; ++n )
557 			if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem2(
558 										RES_TXTATR_TOXMARK, n ) ) &&
559 				0 != (pTxtTOX = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) &&
560 				( pTxtNd = &pTxtTOX->GetTxtNode())->GetNodes().IsDocNodes() &&
561 				0 != ( pCFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt, 0, sal_False )) &&
562 				( IsReadOnlyAvailable() || !pCFrm->IsProtected() ))
563 			{
564 				SwNodeIndex aNdIndex( *pTxtNd );	// UNIX benoetigt dieses Obj.
565 				_SetGetExpFld aCmp( aNdIndex, *pTxtTOX, 0 );
566 				aCmp.SetBodyPos( *pCFrm );
567 
568 				if( bNext ? ( aCurGEF < aCmp && aCmp < aFndGEF )
569 						  : ( aCmp < aCurGEF && aFndGEF < aCmp ))
570 				{
571 					aFndGEF = aCmp;
572 					bFnd = sal_True;
573 				}
574 			}
575 	}
576 
577 	if( bFnd )
578 	{
579 		SET_CURR_SHELL( this );
580 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
581 		SwCrsrSaveState aSaveState( *pCurCrsr );
582 
583 		aFndGEF.GetPosOfContent( rPos );
584 
585 		bFnd = !pCurCrsr->IsSelOvr();
586 		if( bFnd )
587 			UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
588 						SwCrsrShell::READONLY );
589 	}
590 	return bFnd;
591 }
592 
593 /*--------------------------------------------------------------------
594 	 Beschreibung: Traveling zwischen Markierungen
595  --------------------------------------------------------------------*/
596 
597 const SwTOXMark& SwCrsrShell::GotoTOXMark( const SwTOXMark& rStart,
598 											SwTOXSearch eDir )
599 {
600 	SET_CURR_SHELL( this );
601 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
602 	SwCrsrSaveState aSaveState( *pCurCrsr );
603 
604 	const SwTOXMark& rNewMark = GetDoc()->GotoTOXMark( rStart, eDir,
605 													IsReadOnlyAvailable() );
606 	// Position setzen
607 	SwPosition& rPos = *GetCrsr()->GetPoint();
608 	rPos.nNode = rNewMark.GetTxtTOXMark()->GetTxtNode();
609 	rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(),
610 						 *rNewMark.GetTxtTOXMark()->GetStart() );
611 
612 	if( !pCurCrsr->IsSelOvr() )
613 		UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
614 					SwCrsrShell::READONLY );
615 
616 	return rNewMark;
617 }
618 
619 // springe zum naechsten / vorherigen FeldTypen
620 
621 void lcl_MakeFldLst( _SetGetExpFlds& rLst, const SwFieldType& rFldType,
622 						sal_uInt16 nSubType, sal_Bool bInReadOnly,
623 						sal_Bool bChkInpFlag = sal_False )
624 {
625 	// es muss immer der 1. Frame gesucht werden
626 	Point aPt;
627 	SwTxtFld* pTxtFld;
628 	SwIterator<SwFmtFld,SwFieldType> aIter(rFldType);
629 	bool bSubType = nSubType != USHRT_MAX;
630 	for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
631 		if( 0 != ( pTxtFld = pFmtFld->GetTxtFld() ) &&
632 			( !bChkInpFlag || ((SwSetExpField*)pTxtFld->GetFmtFld().GetField())
633 								->GetInputFlag() ) &&
634 			(!bSubType || (pFmtFld->GetField()->GetSubType()
635 								& 0xff ) == nSubType ))
636 		{
637 			SwCntntFrm* pCFrm;
638 			const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
639 			if( 0 != ( pCFrm = rTxtNode.getLayoutFrm( rTxtNode.GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False )) &&
640 				( bInReadOnly || !pCFrm->IsProtected() ))
641 			{
642 				_SetGetExpFld* pNew = new _SetGetExpFld(
643 								SwNodeIndex( rTxtNode ), pTxtFld );
644 				pNew->SetBodyPos( *pCFrm );
645 				rLst.Insert( pNew );
646 			}
647 		}
648 }
649 
650 
651 sal_Bool SwCrsrShell::MoveFldType( const SwFieldType* pFldType, sal_Bool bNext,
652 											sal_uInt16 nSubType, sal_uInt16 nResType )
653 {
654 	// sortierte Liste aller Felder
655 	_SetGetExpFlds aSrtLst( 64 );
656 
657 	if (pFldType)
658 	{
659 		if( RES_INPUTFLD != pFldType->Which() && !pFldType->GetDepends() )
660 			return sal_False;
661 
662 		// Modify-Object gefunden, trage alle Felder ins Array ein
663 		::lcl_MakeFldLst( aSrtLst, *pFldType, nSubType, IsReadOnlyAvailable() );
664 
665 		if( RES_INPUTFLD == pFldType->Which() )
666 		{
667 			// es gibt noch versteckte InputFelder in den SetExp. Feldern
668 			const SwFldTypes& rFldTypes = *pDoc->GetFldTypes();
669 			const sal_uInt16 nSize = rFldTypes.Count();
670 
671 			// Alle Typen abklappern
672 			for( sal_uInt16 i=0; i < nSize; ++i )
673 				if( RES_SETEXPFLD == ( pFldType = rFldTypes[ i ] )->Which() )
674 					::lcl_MakeFldLst( aSrtLst, *pFldType, nSubType,
675 								IsReadOnlyAvailable(), sal_True );
676 		}
677 	}
678 	else
679 	{
680 		const SwFldTypes& rFldTypes = *pDoc->GetFldTypes();
681 		const sal_uInt16 nSize = rFldTypes.Count();
682 
683 		// Alle Typen abklappern
684 		for( sal_uInt16 i=0; i < nSize; ++i )
685 			if( nResType == ( pFldType = rFldTypes[ i ] )->Which() )
686 				::lcl_MakeFldLst( aSrtLst, *pFldType, nSubType,
687 								IsReadOnlyAvailable() );
688 	}
689 
690 	// keine Felder gefunden?
691 	if( !aSrtLst.Count() )
692 		return sal_False;
693 
694 	sal_uInt16 nPos;
695 	SwCursor* pCrsr = getShellCrsr( true );
696 	{
697 		// JP 19.08.98: es muss immer ueber das Feld gesucht werden, damit
698 		//				auch immer das richtige gefunden wird, wenn welche in
699 		//				Rahmen stehen, die in einem Absatz verankert sind,
700 		//				in dem ein Feld steht - siehe auch Bug 55247
701 		const SwPosition& rPos = *pCrsr->GetPoint();
702 
703 		SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
704 		ASSERT( pTNd, "Wo ist mein CntntNode?" );
705 
706         SwTxtFld * pTxtFld = static_cast<SwTxtFld *>(
707             pTNd->GetTxtAttrForCharAt(rPos.nContent.GetIndex(),
708                 RES_TXTATR_FIELD));
709 		sal_Bool bDelFld = 0 == pTxtFld;
710 		if( bDelFld )
711 		{
712 			SwFmtFld* pFmtFld = new SwFmtFld( SwDateTimeField(
713 				(SwDateTimeFieldType*)pDoc->GetSysFldType( RES_DATETIMEFLD ) ) );
714 
715             pTxtFld = new SwTxtFld( *pFmtFld, rPos.nContent.GetIndex() );
716 			pTxtFld->ChgTxtNode( pTNd );
717 		}
718 
719 		_SetGetExpFld aSrch( rPos.nNode, pTxtFld, &rPos.nContent );
720 		if( rPos.nNode.GetIndex() < pDoc->GetNodes().GetEndOfExtras().GetIndex() )
721 		{
722 			// auch beim Einsammeln wird nur der erste Frame benutzt!
723 			Point aPt;
724 			aSrch.SetBodyPos( *pTNd->getLayoutFrm( GetLayout(), &aPt, &rPos, sal_False ) );
725 		}
726 
727 		sal_Bool bFound = aSrtLst.Seek_Entry( &aSrch, &nPos );
728 		if( bDelFld )
729 		{
730 			delete (SwFmtFld*)&pTxtFld->GetAttr();
731 			delete pTxtFld;
732 		}
733 
734 		if( bFound )		// stehe auf einem ?
735 		{
736 			if( bNext )
737 			{
738 				if( ++nPos >= aSrtLst.Count() )
739 					return sal_False;					// schon am Ende
740 			}
741 			else if( !nPos-- )
742 				return sal_False;	  	// weiter nach vorne geht nicht
743 		}
744 		else if( bNext ? nPos >= aSrtLst.Count() : !nPos--)
745 			return sal_False;
746 	}
747 	const _SetGetExpFld& rFnd = **( aSrtLst.GetData() + nPos );
748 
749 
750 	SET_CURR_SHELL( this );
751 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
752 	SwCrsrSaveState aSaveState( *pCrsr );
753 
754 	rFnd.GetPosOfContent( *pCrsr->GetPoint() );
755     sal_Bool bRet = !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
756                                      nsSwCursorSelOverFlags::SELOVER_TOGGLE );
757 	if( bRet )
758 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
759 	return bRet;
760 }
761 
762 
763 sal_Bool SwCrsrShell::GotoFld( const SwFmtFld& rFld )
764 {
765 	sal_Bool bRet = sal_False;
766 	if( rFld.GetTxtFld() )
767 	{
768 		SET_CURR_SHELL( this );
769 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
770 
771 		SwCursor* pCrsr = getShellCrsr( true );
772 		SwCrsrSaveState aSaveState( *pCrsr );
773 
774 		SwTxtNode* pTNd = (SwTxtNode*)rFld.GetTxtFld()->GetpTxtNode();
775 		pCrsr->GetPoint()->nNode = *pTNd;
776 		pCrsr->GetPoint()->nContent.Assign( pTNd, *rFld.GetTxtFld()->GetStart() );
777 
778 		bRet = !pCrsr->IsSelOvr();
779 		if( bRet )
780 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
781 	}
782 	return bRet;
783 }
784 
785 
786 void SwCrsrShell::GotoOutline( sal_uInt16 nIdx )
787 {
788 	SwCursor* pCrsr = getShellCrsr( true );
789 
790 	SET_CURR_SHELL( this );
791 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
792 	SwCrsrSaveState aSaveState( *pCrsr );
793 
794 	const SwNodes& rNds = GetDoc()->GetNodes();
795 	SwTxtNode* pTxtNd = (SwTxtNode*)rNds.GetOutLineNds()[ nIdx ]->GetTxtNode();
796 	pCrsr->GetPoint()->nNode = *pTxtNd;
797 	pCrsr->GetPoint()->nContent.Assign( pTxtNd, 0 );
798 
799 	if( !pCrsr->IsSelOvr() )
800 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
801 }
802 
803 
804 sal_Bool SwCrsrShell::GotoOutline( const String& rName )
805 {
806 	SwCursor* pCrsr = getShellCrsr( true );
807 
808 	SET_CURR_SHELL( this );
809 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
810 	SwCrsrSaveState aSaveState( *pCrsr );
811 
812 	sal_Bool bRet = sal_False;
813 	if( pDoc->GotoOutline( *pCrsr->GetPoint(), rName ) && !pCrsr->IsSelOvr() )
814 	{
815 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
816 		bRet = sal_True;
817 	}
818 	return bRet;
819 }
820 
821 
822 
823 sal_Bool SwCrsrShell::GotoNextOutline()			// naechster Node mit Outline-Num.
824 {
825 	SwCursor* pCrsr = getShellCrsr( true );
826 	const SwNodes& rNds = GetDoc()->GetNodes();
827 
828 	SwNode* pNd = pCrsr->GetNode();
829 	sal_uInt16 nPos;
830 	if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos ))
831 		++nPos;
832 
833 	if( nPos == rNds.GetOutLineNds().Count() )
834 		return sal_False;
835 
836 	pNd = rNds.GetOutLineNds()[ nPos ];
837 
838 	SET_CURR_SHELL( this );
839 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
840 	SwCrsrSaveState aSaveState( *pCrsr );
841 	pCrsr->GetPoint()->nNode = *pNd;
842 	pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 );
843 
844 	sal_Bool bRet = !pCrsr->IsSelOvr();
845 	if( bRet )
846 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
847 	return bRet;
848 }
849 
850 
851 sal_Bool SwCrsrShell::GotoPrevOutline()			// vorheriger Node mit Outline-Num.
852 {
853 	SwCursor* pCrsr = getShellCrsr( true );
854 	const SwNodes& rNds = GetDoc()->GetNodes();
855 
856 	SwNode* pNd = pCrsr->GetNode();
857 	sal_uInt16 nPos;
858 	rNds.GetOutLineNds().Seek_Entry( pNd, &nPos );
859 
860 	sal_Bool bRet = sal_False;
861 	if( nPos )
862 	{
863 		--nPos;	// davor
864 
865 		pNd = rNds.GetOutLineNds()[ nPos ];
866 		if( pNd->GetIndex() > pCrsr->GetPoint()->nNode.GetIndex() )
867 			return sal_False;
868 
869 		SET_CURR_SHELL( this );
870 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
871 		SwCrsrSaveState aSaveState( *pCrsr );
872 		pCrsr->GetPoint()->nNode = *pNd;
873 		pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 );
874 
875 		bRet = !pCrsr->IsSelOvr();
876 		if( bRet )
877 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
878 	}
879 	return bRet;
880 }
881 
882 
883 	// suche die "Outline-Position" vom vorherigen Outline-Node mit dem
884 	// Level.
885 sal_uInt16 SwCrsrShell::GetOutlinePos( sal_uInt8 nLevel )
886 {
887 	SwPaM* pCrsr = getShellCrsr( true );
888 	const SwNodes& rNds = GetDoc()->GetNodes();
889 
890 	SwNode* pNd = pCrsr->GetNode();
891 	sal_uInt16 nPos;
892 	if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos ))
893 		nPos++;			// steht auf der Position, fuers while zum Naechsten
894 
895 	while( nPos-- )		// immer den davor testen !
896 	{
897 		pNd = rNds.GetOutLineNds()[ nPos ];
898 
899 		//if( ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() <= nLevel )//#outline level,zhaojianwei
900 		if( ((SwTxtNode*)pNd)->GetAttrOutlineLevel()-1 <= nLevel )//<-end,zhaojianwei
901 			return nPos;
902 
903 	}
904 	return USHRT_MAX;		// davor keiner mehr also Ende
905 }
906 
907 
908 sal_Bool SwCrsrShell::MakeOutlineSel( sal_uInt16 nSttPos, sal_uInt16 nEndPos,
909 									sal_Bool bWithChilds )
910 {
911 	const SwNodes& rNds = GetDoc()->GetNodes();
912 	const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
913 	if( !rOutlNds.Count() )		// wie jetzt ???
914 		return sal_False;
915 
916 	SET_CURR_SHELL( this );
917 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
918 
919 	if( nSttPos > nEndPos )			// sollte jemand das vertauscht haben?
920 	{
921 		ASSERT( !this, "Start- > Ende-Position im Array" );
922 		sal_uInt16 nTmp = nSttPos;
923 		nSttPos = nEndPos;
924 		nEndPos = nTmp;
925 	}
926 
927 	SwNode* pSttNd = rOutlNds[ nSttPos ];
928 	SwNode* pEndNd = rOutlNds[ nEndPos ];
929 
930 	if( bWithChilds )
931 	{
932 		//sal_uInt8 nLevel = pEndNd->GetTxtNode()->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
933         const int nLevel = pEndNd->GetTxtNode()->GetAttrOutlineLevel()-1;//<-end.zhaojianwei
934 		for( ++nEndPos; nEndPos < rOutlNds.Count(); ++nEndPos )
935 		{
936 			pEndNd = rOutlNds[ nEndPos ];
937 			//sal_uInt8 nNxtLevel = pEndNd->GetTxtNode()->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
938             const int nNxtLevel = pEndNd->GetTxtNode()->GetAttrOutlineLevel()-1;//<-end,zhaojianwei
939 			if( nNxtLevel <= nLevel )
940 				break;			// EndPos steht jetzt auf dem naechsten
941 		}
942 	}
943 	// ohne Childs, dann aber zumindest auf den naechsten
944 	else if( ++nEndPos < rOutlNds.Count() )
945 		pEndNd = rOutlNds[ nEndPos ];
946 
947 	if( nEndPos == rOutlNds.Count() )		// kein Ende gefunden
948 		pEndNd = &rNds.GetEndOfContent();
949 
950 	KillPams();
951 
952 	SwCrsrSaveState aSaveState( *pCurCrsr );
953 
954 	// Jetzt das Ende ans Ende vom voherigen ContentNode setzen
955 	pCurCrsr->GetPoint()->nNode = *pSttNd;
956 	pCurCrsr->GetPoint()->nContent.Assign( pSttNd->GetCntntNode(), 0 );
957 	pCurCrsr->SetMark();
958 	pCurCrsr->GetPoint()->nNode = *pEndNd;
959 	pCurCrsr->Move( fnMoveBackward, fnGoNode );		// ans Ende vom Vorgaenger
960 
961 	// und schon ist alles selektiert
962 	sal_Bool bRet = !pCurCrsr->IsSelOvr();
963 	if( bRet )
964 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
965 	return bRet;
966 }
967 
968 
969 // springe zu dieser Refmark
970 sal_Bool SwCrsrShell::GotoRefMark( const String& rRefMark, sal_uInt16 nSubType,
971 									sal_uInt16 nSeqNo )
972 {
973 	SET_CURR_SHELL( this );
974 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
975 	SwCrsrSaveState aSaveState( *pCurCrsr );
976 
977 	sal_uInt16 nPos;
978 	SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( GetDoc(), rRefMark,
979 													nSubType, nSeqNo, &nPos );
980 	if( pTxtNd && pTxtNd->GetNodes().IsDocNodes() )
981 	{
982 		pCurCrsr->GetPoint()->nNode = *pTxtNd;
983 		pCurCrsr->GetPoint()->nContent.Assign( pTxtNd, nPos );
984 
985 		if( !pCurCrsr->IsSelOvr() )
986 		{
987 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
988 			return sal_True;
989 		}
990 	}
991 	return sal_False;
992 }
993 
994 sal_Bool SwCrsrShell::IsPageAtPos( const Point &rPt ) const
995 {
996     if( GetLayout() )
997         return 0 != GetLayout()->GetPageAtPos( rPt );
998     return sal_False;
999 }
1000 
1001 sal_Bool SwCrsrShell::GetContentAtPos( const Point& rPt,
1002                                    SwContentAtPos& rCntntAtPos,
1003                                    sal_Bool bSetCrsr,
1004                                    SwRect* pFldRect )
1005 {
1006 	SET_CURR_SHELL( this );
1007 	sal_Bool bRet = sal_False;
1008 
1009 	if( !IsTableMode() )
1010 	{
1011 		Point aPt( rPt );
1012 		SwPosition aPos( *pCurCrsr->GetPoint() );
1013 
1014 		SwTxtNode* pTxtNd;
1015 		SwCntntFrm *pFrm(0);
1016 		SwTxtAttr* pTxtAttr;
1017 		SwCrsrMoveState aTmpState;
1018 		aTmpState.bFieldInfo = sal_True;
1019         aTmpState.bExactOnly = !( SwContentAtPos::SW_OUTLINE & rCntntAtPos.eCntntAtPos );
1020         aTmpState.bCntntCheck = (SwContentAtPos::SW_CONTENT_CHECK & rCntntAtPos.eCntntAtPos) ?  sal_True : sal_False;
1021 		aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1022 
1023         SwSpecialPos aSpecialPos;
1024         aTmpState.pSpecialPos = ( SwContentAtPos::SW_SMARTTAG & rCntntAtPos.eCntntAtPos ) ?
1025                                 &aSpecialPos : 0;
1026 
1027         const sal_Bool bCrsrFoundExact = GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState );
1028 		pTxtNd = aPos.nNode.GetNode().GetTxtNode();
1029 
1030 		const SwNodes& rNds = GetDoc()->GetNodes();
1031 		if( pTxtNd && SwContentAtPos::SW_OUTLINE & rCntntAtPos.eCntntAtPos
1032 			&& rNds.GetOutLineNds().Count() )
1033 		{
1034 			const SwTxtNode* pONd = pTxtNd->FindOutlineNodeOfLevel( MAXLEVEL-1);
1035 			if( pONd )
1036 			{
1037 				rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_OUTLINE;
1038                 rCntntAtPos.sStr = pONd->GetExpandTxt( 0, STRING_LEN, true );
1039 				bRet = sal_True;
1040 			}
1041 		}
1042         // --> FME 2005-05-13 #i43742# New function: SW_CONTENT_CHECK
1043         else if ( SwContentAtPos::SW_CONTENT_CHECK & rCntntAtPos.eCntntAtPos &&
1044                   bCrsrFoundExact )
1045         {
1046             bRet = sal_True;
1047         }
1048         // <--
1049         // #i23726#
1050         else if( pTxtNd &&
1051                  SwContentAtPos::SW_NUMLABEL & rCntntAtPos.eCntntAtPos)
1052         {
1053             bRet = aTmpState.bInNumPortion;
1054             rCntntAtPos.aFnd.pNode = pTxtNd;
1055 
1056             Size aSizeLogic(aTmpState.nInNumPostionOffset, 0);
1057             Size aSizePixel = GetWin()->LogicToPixel(aSizeLogic);
1058             rCntntAtPos.nDist = aSizePixel.Width();
1059         }
1060 		else if( bCrsrFoundExact && pTxtNd )
1061 		{
1062 			if( !aTmpState.bPosCorr )
1063 			{
1064 				if( !bRet && SwContentAtPos::SW_SMARTTAG & rCntntAtPos.eCntntAtPos
1065 					&& !aTmpState.bFtnNoInfo )
1066 				{
1067                     const SwWrongList* pSmartTagList = pTxtNd->GetSmartTags();
1068                     xub_StrLen nCurrent = aPos.nContent.GetIndex();
1069                     xub_StrLen nBegin = nCurrent;
1070                     xub_StrLen nLen = 1;
1071 
1072                     if ( pSmartTagList && pSmartTagList->InWrongWord( nCurrent, nLen ) && !pTxtNd->IsSymbol(nBegin) )
1073                     {
1074                         const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
1075                         const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
1076                         if ( pSubList )
1077                         {
1078                             nCurrent = aTmpState.pSpecialPos->nCharOfst;
1079 
1080                             if ( pSubList->InWrongWord( nCurrent, nLen ) )
1081                                 bRet = sal_True;
1082                         }
1083                         else
1084                             bRet = sal_True;
1085 
1086 						if( bRet && bSetCrsr )
1087 						{
1088 							SwCrsrSaveState aSaveState( *pCurCrsr );
1089 							SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1090 							pCurCrsr->DeleteMark();
1091 							*pCurCrsr->GetPoint() = aPos;
1092                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1093                                                     nsSwCursorSelOverFlags::SELOVER_TOGGLE) )
1094 								bRet = sal_False;
1095 							else
1096 								UpdateCrsr();
1097 						}
1098 						if( bRet )
1099 						{
1100 //							rCntntAtPos.sStr = pTxtNd->GetExpandTxt(
1101 //										*pTxtAttr->GetStart(),
1102 //										*pTxtAttr->GetEnd() - *pTxtAttr->GetStart(),
1103 //										sal_False );
1104 
1105 //							rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr();
1106 							rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_SMARTTAG;
1107 //							rCntntAtPos.pFndTxtAttr = pTxtAttr;
1108 
1109 							if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1110 								pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1111 						}
1112                     }
1113                 }
1114 
1115                 if( !bRet && ( SwContentAtPos::SW_FIELD | SwContentAtPos::SW_CLICKFIELD )
1116 					& rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo )
1117                 {
1118                     pTxtAttr = pTxtNd->GetTxtAttrForCharAt(
1119                             aPos.nContent.GetIndex(), RES_TXTATR_FIELD );
1120 					const SwField* pFld = pTxtAttr
1121 											? pTxtAttr->GetFmtFld().GetField()
1122 											: 0;
1123 					if( SwContentAtPos::SW_CLICKFIELD & rCntntAtPos.eCntntAtPos &&
1124 						pFld && !pFld->HasClickHdl() )
1125 						pFld = 0;
1126 
1127 					if( pFld )
1128 					{
1129 						if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1130 							pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1131 
1132 						if( bSetCrsr )
1133 						{
1134 							SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1135 							SwCrsrSaveState aSaveState( *pCurCrsr );
1136 							pCurCrsr->DeleteMark();
1137 							*pCurCrsr->GetPoint() = aPos;
1138 							if( pCurCrsr->IsSelOvr() )
1139 							{
1140 								// Click-Felder in geschuetzten Bereichen zulassen
1141 								// Nur Platzhalter geht nicht!
1142 								if( SwContentAtPos::SW_FIELD & rCntntAtPos.eCntntAtPos
1143 									 || RES_JUMPEDITFLD == pFld->Which() )
1144 									pFld = 0;
1145 							}
1146 							else
1147 								UpdateCrsr();
1148 						}
1149 						else if( RES_TABLEFLD == pFld->Which() &&
1150 								((SwTblField*)pFld)->IsIntrnlName() )
1151 						{
1152 							// erzeuge aus der internen (fuer CORE)
1153 							// die externe (fuer UI) Formel
1154 							const SwTableNode* pTblNd = pTxtNd->FindTableNode();
1155 							if( pTblNd )		// steht in einer Tabelle
1156 								((SwTblField*)pFld)->PtrToBoxNm( &pTblNd->GetTable() );
1157 						}
1158 					}
1159 
1160 					if( pFld )
1161 					{
1162 						rCntntAtPos.aFnd.pFld = pFld;
1163 						rCntntAtPos.pFndTxtAttr = pTxtAttr;
1164 						rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FIELD;
1165 						bRet = sal_True;
1166 					}
1167 				}
1168 
1169 		if( !bRet && SwContentAtPos::SW_FORMCTRL & rCntntAtPos.eCntntAtPos )
1170 		{
1171             IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess( );
1172             sw::mark::IFieldmark* pFldBookmark = pMarksAccess->getFieldmarkFor( aPos );
1173 		    if( bCrsrFoundExact && pTxtNd && pFldBookmark) {
1174 			    rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FORMCTRL;
1175     			rCntntAtPos.aFnd.pFldmark = pFldBookmark;
1176 	    		bRet=sal_True;
1177 		    }
1178 		}
1179 
1180 				if( !bRet && SwContentAtPos::SW_FTN & rCntntAtPos.eCntntAtPos )
1181 				{
1182 					if( aTmpState.bFtnNoInfo )
1183 					{
1184 						// stehe ueber dem Zeichen der Fussnote (??)
1185 						bRet = sal_True;
1186 						if( bSetCrsr )
1187 						{
1188 							*pCurCrsr->GetPoint() = aPos;
1189 							if( !GotoFtnAnchor() )
1190 								bRet = sal_False;
1191 						}
1192 						if( bRet )
1193 							rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN;
1194 					}
1195                     else if ( 0 != ( pTxtAttr = pTxtNd->GetTxtAttrForCharAt(
1196 								aPos.nContent.GetIndex(), RES_TXTATR_FTN )) )
1197 					{
1198 						bRet = sal_True;
1199 						if( bSetCrsr )
1200 						{
1201 							SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
1202 							SwCrsrSaveState aSaveState( *pCurCrsr );
1203 							pCurCrsr->GetPoint()->nNode = *((SwTxtFtn*)pTxtAttr)->GetStartNode();
1204 							SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection(
1205 											&pCurCrsr->GetPoint()->nNode,
1206 											sal_True, !IsReadOnlyAvailable() );
1207 
1208 							if( pCNd )
1209 							{
1210 								pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
1211                                 if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1212                                                         nsSwCursorSelOverFlags::SELOVER_TOGGLE ))
1213 									bRet = sal_False;
1214 								else
1215 									UpdateCrsr();
1216 							}
1217 							else
1218 								bRet = sal_False;
1219 						}
1220 
1221 						if( bRet )
1222 						{
1223 							rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN;
1224 							rCntntAtPos.pFndTxtAttr = pTxtAttr;
1225 							rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr();
1226 
1227 							if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1228 								pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1229 						}
1230 					}
1231 				}
1232 
1233 				if( !bRet && ( SwContentAtPos::SW_TOXMARK |
1234 							   SwContentAtPos::SW_REFMARK ) &
1235 						rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo )
1236 				{
1237 					pTxtAttr = 0;
1238 					if( SwContentAtPos::SW_TOXMARK & rCntntAtPos.eCntntAtPos )
1239                     {
1240                         ::std::vector<SwTxtAttr *> const marks(
1241                             pTxtNd->GetTxtAttrsAt(
1242                                aPos.nContent.GetIndex(), RES_TXTATR_TOXMARK));
1243                         if (marks.size())
1244                         {   // hmm... can only return 1 here
1245                             pTxtAttr = *marks.begin();
1246                         }
1247                     }
1248 
1249 					if( !pTxtAttr &&
1250 						SwContentAtPos::SW_REFMARK & rCntntAtPos.eCntntAtPos )
1251                     {
1252                         ::std::vector<SwTxtAttr *> const marks(
1253                             pTxtNd->GetTxtAttrsAt(
1254                                aPos.nContent.GetIndex(), RES_TXTATR_REFMARK));
1255                         if (marks.size())
1256                         {   // hmm... can only return 1 here
1257                             pTxtAttr = *marks.begin();
1258                         }
1259                     }
1260 
1261 					if( pTxtAttr )
1262 					{
1263 						bRet = sal_True;
1264 						if( bSetCrsr )
1265 						{
1266 							SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
1267 							SwCrsrSaveState aSaveState( *pCurCrsr );
1268 							pCurCrsr->DeleteMark();
1269 							*pCurCrsr->GetPoint() = aPos;
1270                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1271                                                     nsSwCursorSelOverFlags::SELOVER_TOGGLE ) )
1272 								bRet = sal_False;
1273 							else
1274 								UpdateCrsr();
1275 						}
1276 
1277 						if( bRet )
1278 						{
1279 							const xub_StrLen* pEnd = pTxtAttr->GetEnd();
1280 							if( pEnd )
1281 								rCntntAtPos.sStr = pTxtNd->GetExpandTxt(
1282 											*pTxtAttr->GetStart(),
1283                                             *pEnd - *pTxtAttr->GetStart() );
1284 							else if( RES_TXTATR_TOXMARK == pTxtAttr->Which())
1285 								rCntntAtPos.sStr = pTxtAttr->GetTOXMark().
1286 													GetAlternativeText();
1287 
1288 							rCntntAtPos.eCntntAtPos =
1289 								RES_TXTATR_TOXMARK == pTxtAttr->Which()
1290 											? SwContentAtPos::SW_TOXMARK
1291 											: SwContentAtPos::SW_REFMARK;
1292 							rCntntAtPos.pFndTxtAttr = pTxtAttr;
1293 							rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr();
1294 
1295 							if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1296 								pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1297 						}
1298 					}
1299 				}
1300 
1301 				if( !bRet && SwContentAtPos::SW_INETATTR & rCntntAtPos.eCntntAtPos
1302 					&& !aTmpState.bFtnNoInfo )
1303                 {
1304                     pTxtAttr = pTxtNd->GetTxtAttrAt(
1305                             aPos.nContent.GetIndex(), RES_TXTATR_INETFMT);
1306 					// nur INetAttrs mit URLs "erkennen"
1307 					if( pTxtAttr && pTxtAttr->GetINetFmt().GetValue().Len() )
1308 					{
1309 						bRet = sal_True;
1310 						if( bSetCrsr )
1311 						{
1312 							SwCrsrSaveState aSaveState( *pCurCrsr );
1313 							SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1314 							pCurCrsr->DeleteMark();
1315 							*pCurCrsr->GetPoint() = aPos;
1316                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1317                                                     nsSwCursorSelOverFlags::SELOVER_TOGGLE) )
1318 								bRet = sal_False;
1319 							else
1320 								UpdateCrsr();
1321 						}
1322 						if( bRet )
1323 						{
1324 							rCntntAtPos.sStr = pTxtNd->GetExpandTxt(
1325 										*pTxtAttr->GetStart(),
1326                                         *pTxtAttr->GetEnd() - *pTxtAttr->GetStart() );
1327 
1328 							rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr();
1329 							rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_INETATTR;
1330 							rCntntAtPos.pFndTxtAttr = pTxtAttr;
1331 
1332 							if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1333 								pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1334 						}
1335 					}
1336 				}
1337 
1338 				if( !bRet && SwContentAtPos::SW_REDLINE & rCntntAtPos.eCntntAtPos )
1339 				{
1340 					const SwRedline* pRedl = GetDoc()->GetRedline(aPos, NULL);
1341 					if( pRedl )
1342 					{
1343 						rCntntAtPos.aFnd.pRedl = pRedl;
1344 						rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE;
1345 						rCntntAtPos.pFndTxtAttr = 0;
1346 						bRet = sal_True;
1347 
1348 						if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1349 							pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1350 					}
1351 				}
1352 			}
1353 
1354 			if( !bRet && (
1355 				SwContentAtPos::SW_TABLEBOXFML & rCntntAtPos.eCntntAtPos
1356 #ifdef DBG_UTIL
1357 				|| SwContentAtPos::SW_TABLEBOXVALUE & rCntntAtPos.eCntntAtPos
1358 #endif
1359 				))
1360 			{
1361 				const SwTableNode* pTblNd;
1362 				const SwTableBox* pBox;
1363 				const SwStartNode* pSttNd = pTxtNd->FindTableBoxStartNode();
1364 				const SfxPoolItem* pItem;
1365 				if( pSttNd && 0 != ( pTblNd = pTxtNd->FindTableNode()) &&
1366 					0 != ( pBox = pTblNd->GetTable().GetTblBox(
1367 									pSttNd->GetIndex() )) &&
1368 #ifdef DBG_UTIL
1369 					( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
1370 						RES_BOXATR_FORMULA, sal_False, &pItem )	||
1371 					  SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
1372 						RES_BOXATR_VALUE, sal_False, &pItem ))
1373 #else
1374 					SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
1375 						RES_BOXATR_FORMULA, sal_False, &pItem )
1376 #endif
1377 					)
1378 				{
1379 					SwFrm* pF = pTxtNd->getLayoutFrm( GetLayout(), &aPt );
1380 					if( pF )
1381 					{
1382 						// dann aber den CellFrame
1383 						pFrm = (SwCntntFrm*)pF;
1384 						while( pF && !pF->IsCellFrm() )
1385 							pF = pF->GetUpper();
1386 					}
1387 
1388 					// es wurde ein
1389 					if( aTmpState.bPosCorr )
1390 					{
1391 						if( pF && !pF->Frm().IsInside( aPt ))
1392 							pF = 0;
1393 					}
1394 					else if( !pF )
1395 						pF = pFrm;
1396 
1397 					if( pF )			// nur dann ist es gueltig!!
1398 					{
1399 						// erzeuge aus der internen (fuer CORE)
1400 						// die externe (fuer UI) Formel
1401 						rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXFML;
1402 #ifdef DBG_UTIL
1403 						if( RES_BOXATR_VALUE == pItem->Which() )
1404 							rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXVALUE;
1405 						else
1406 #endif
1407 						((SwTblBoxFormula*)pItem)->PtrToBoxNm( &pTblNd->GetTable() );
1408 
1409 						bRet = sal_True;
1410 						if( bSetCrsr )
1411 						{
1412 							SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
1413 							SwCrsrSaveState aSaveState( *pCurCrsr );
1414 							*pCurCrsr->GetPoint() = aPos;
1415                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1416                                                     nsSwCursorSelOverFlags::SELOVER_TOGGLE) )
1417 								bRet = sal_False;
1418 							else
1419 								UpdateCrsr();
1420 						}
1421 
1422 						if( bRet )
1423 						{
1424 							if( pFldRect )
1425 							{
1426 								*pFldRect = pF->Prt();
1427 								*pFldRect += pF->Frm().Pos();
1428 							}
1429 							rCntntAtPos.pFndTxtAttr = 0;
1430 							rCntntAtPos.aFnd.pAttr = pItem;
1431 						}
1432 					}
1433 				}
1434 			}
1435 
1436 #ifdef DBG_UTIL
1437 			if( !bRet && SwContentAtPos::SW_CURR_ATTRS & rCntntAtPos.eCntntAtPos )
1438 			{
1439 				xub_StrLen n = aPos.nContent.GetIndex();
1440 				SfxItemSet aSet( GetDoc()->GetAttrPool(), POOLATTR_BEGIN,
1441 														  POOLATTR_END - 1 );
1442 				if( pTxtNd->GetpSwpHints() )
1443 				{
1444 					for( sal_uInt16 i = 0; i < pTxtNd->GetSwpHints().Count(); ++i )
1445 					{
1446 						const SwTxtAttr* pHt = pTxtNd->GetSwpHints()[i];
1447 						xub_StrLen nAttrStart = *pHt->GetStart();
1448 						if( nAttrStart > n ) 		// ueber den Bereich hinaus
1449 							break;
1450 
1451 						if( 0 != pHt->GetEnd() && (
1452 							( nAttrStart < n &&
1453 								( pHt->DontExpand() ? n < *pHt->GetEnd()
1454 													: n <= *pHt->GetEnd() )) ||
1455 							( n == nAttrStart &&
1456 								( nAttrStart == *pHt->GetEnd() || !n ))) )
1457 						{
1458 							aSet.Put( pHt->GetAttr() );
1459 						}
1460 					}
1461                     if( pTxtNd->HasSwAttrSet() &&
1462                         pTxtNd->GetpSwAttrSet()->Count() )
1463 					{
1464 						SfxItemSet aFmtSet( pTxtNd->GetSwAttrSet() );
1465 						// aus dem Format-Set alle entfernen, die im TextSet auch gesetzt sind
1466 						aFmtSet.Differentiate( aSet );
1467 						// jetzt alle zusammen "mergen"
1468 						aSet.Put( aFmtSet );
1469 					}
1470 				}
1471 				else
1472 					pTxtNd->SwCntntNode::GetAttr( aSet );
1473 
1474 				rCntntAtPos.sStr.AssignAscii(
1475 									RTL_CONSTASCII_STRINGPARAM( "Pos: (" ));
1476 				rCntntAtPos.sStr += String::CreateFromInt32( aPos.nNode.GetIndex());
1477 				rCntntAtPos.sStr += ':';
1478 				rCntntAtPos.sStr += String::CreateFromInt32( aPos.nContent.GetIndex());
1479 				rCntntAtPos.sStr += ')';
1480 				rCntntAtPos.sStr.AppendAscii(
1481 								RTL_CONSTASCII_STRINGPARAM( "\nAbs.Vorl.: " ));
1482 				rCntntAtPos.sStr += pTxtNd->GetFmtColl()->GetName();
1483 				if( pTxtNd->GetCondFmtColl() )
1484 					rCntntAtPos.sStr.AppendAscii(
1485 								RTL_CONSTASCII_STRINGPARAM( "\nBed.Vorl.: " ))
1486 						+= pTxtNd->GetCondFmtColl()->GetName();
1487 
1488 				if( aSet.Count() )
1489 				{
1490 					String sAttrs;
1491 					SfxItemIter aIter( aSet );
1492 					const SfxPoolItem* pItem = aIter.FirstItem();
1493 					while( sal_True )
1494 					{
1495 						if( !IsInvalidItem( pItem ))
1496 						{
1497 							String aStr;
1498 							GetDoc()->GetAttrPool().GetPresentation( *pItem,
1499 											SFX_ITEM_PRESENTATION_COMPLETE,
1500 											SFX_MAPUNIT_CM, aStr );
1501 							if( sAttrs.Len() )
1502 								sAttrs.AppendAscii(
1503 										RTL_CONSTASCII_STRINGPARAM( ", " ));
1504 							sAttrs += aStr;
1505 						}
1506 						if( aIter.IsAtEnd() )
1507 							break;
1508 						pItem = aIter.NextItem();
1509 					}
1510 					if( sAttrs.Len() )
1511 					{
1512 						if( rCntntAtPos.sStr.Len() )
1513 							rCntntAtPos.sStr += '\n';
1514 						rCntntAtPos.sStr.AppendAscii(
1515 								RTL_CONSTASCII_STRINGPARAM( "Attr: " ) )
1516 								+= sAttrs;
1517 					}
1518 				}
1519 				bRet = sal_True;
1520 				rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_CURR_ATTRS;
1521 			}
1522 #endif
1523 		}
1524 	}
1525 
1526 	if( !bRet )
1527 	{
1528 		rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_NOTHING;
1529 		rCntntAtPos.aFnd.pFld = 0;
1530 	}
1531 	return bRet;
1532 }
1533 
1534 // --> OD 2008-06-19 #i90516#
1535 const SwPostItField* SwCrsrShell::GetPostItFieldAtCursor() const
1536 {
1537     const SwPostItField* pPostItFld = 0;
1538 
1539     if ( !IsTableMode() )
1540     {
1541         const SwPosition* pCursorPos = _GetCrsr()->GetPoint();
1542         const SwTxtNode* pTxtNd = pCursorPos->nNode.GetNode().GetTxtNode();
1543         if ( pTxtNd )
1544         {
1545             SwTxtAttr* pTxtAttr = pTxtNd->GetTxtAttrForCharAt(
1546                     pCursorPos->nContent.GetIndex(), RES_TXTATR_FIELD );
1547             const SwField* pFld = pTxtAttr ? pTxtAttr->GetFmtFld().GetField() : 0;
1548             if ( pFld && pFld->Which()== RES_POSTITFLD )
1549             {
1550                 pPostItFld = static_cast<const SwPostItField*>(pFld);
1551             }
1552         }
1553     }
1554 
1555     return pPostItFld;
1556 }
1557 // <--
1558 
1559 // befindet sich der Node in einem geschuetzten Bereich?
1560 sal_Bool SwContentAtPos::IsInProtectSect() const
1561 {
1562 	const SwTxtNode* pNd = 0;
1563 	if( pFndTxtAttr )
1564 	{
1565 		switch( eCntntAtPos )
1566 		{
1567 		case SW_FIELD:
1568 		case SW_CLICKFIELD:
1569 			pNd = ((SwTxtFld*)pFndTxtAttr)->GetpTxtNode();
1570 			break;
1571 
1572 		case SW_FTN:
1573 			pNd = &((SwTxtFtn*)pFndTxtAttr)->GetTxtNode();
1574 			break;
1575 
1576 		case SW_INETATTR:
1577 			pNd = ((SwTxtINetFmt*)pFndTxtAttr)->GetpTxtNode();
1578 			break;
1579 
1580 		default:
1581 			break;
1582 		}
1583 	}
1584 
1585 	const SwCntntFrm* pFrm;
1586 	return pNd && ( pNd->IsInProtectSect() ||
1587 					( 0 != ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), 0,0,sal_False)) &&
1588 						pFrm->IsProtected() ));
1589 }
1590 
1591 bool SwContentAtPos::IsInRTLText()const
1592 {
1593     bool bRet = false;
1594     const SwTxtNode* pNd = 0;
1595     if (pFndTxtAttr && (eCntntAtPos == SW_FTN))
1596     {
1597         const SwTxtFtn* pTxtFtn = static_cast<const SwTxtFtn*>(pFndTxtAttr);
1598         if(pTxtFtn->GetStartNode())
1599         {
1600             SwStartNode* pSttNd = pTxtFtn->GetStartNode()->GetNode().GetStartNode();
1601             SwPaM aTemp( *pSttNd );
1602             aTemp.Move(fnMoveForward, fnGoNode);
1603             SwCntntNode* pCntntNode = aTemp.GetCntntNode();
1604             if(pCntntNode && pCntntNode->IsTxtNode())
1605                 pNd = static_cast<SwTxtNode*>(pCntntNode);
1606         }
1607     }
1608     if(pNd)
1609     {
1610         SwIterator<SwTxtFrm,SwTxtNode> aIter(*pNd);
1611         SwTxtFrm* pTmpFrm = aIter.First();
1612         while( pTmpFrm )
1613         {
1614                 if ( !pTmpFrm->IsFollow())
1615                 {
1616                     bRet = pTmpFrm->IsRightToLeft();
1617                     break;
1618                 }
1619             pTmpFrm = aIter.Next();
1620         }
1621     }
1622     return bRet;
1623 }
1624 
1625 sal_Bool SwCrsrShell::SelectTxtAttr( sal_uInt16 nWhich, sal_Bool bExpand,
1626 									const SwTxtAttr* pTxtAttr )
1627 {
1628 	SET_CURR_SHELL( this );
1629 	sal_Bool bRet = sal_False;
1630 
1631 	if( !IsTableMode() )
1632 	{
1633 		SwPosition& rPos = *pCurCrsr->GetPoint();
1634 		if( !pTxtAttr )
1635 		{
1636 			SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
1637             pTxtAttr = (pTxtNd)
1638                 ? pTxtNd->GetTxtAttrAt(rPos.nContent.GetIndex(),
1639                         static_cast<RES_TXTATR>(nWhich),
1640                         (bExpand) ? SwTxtNode::EXPAND : SwTxtNode::DEFAULT)
1641                 : 0;
1642         }
1643 
1644 		if( pTxtAttr )
1645 		{
1646 			SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
1647 			SwCrsrSaveState aSaveState( *pCurCrsr );
1648 
1649 			pCurCrsr->DeleteMark();
1650 			rPos.nContent = *pTxtAttr->GetStart();
1651 			pCurCrsr->SetMark();
1652 			const xub_StrLen* pEnd = pTxtAttr->GetEnd();
1653 			rPos.nContent = pEnd ? *pEnd : *pTxtAttr->GetStart() + 1;
1654 
1655 			if( !pCurCrsr->IsSelOvr() )
1656 			{
1657 				UpdateCrsr();
1658 				bRet = sal_True;
1659 			}
1660 		}
1661 	}
1662 	return bRet;
1663 }
1664 
1665 
1666 sal_Bool SwCrsrShell::GotoINetAttr( const SwTxtINetFmt& rAttr )
1667 {
1668 	sal_Bool bRet = sal_False;
1669 	if( rAttr.GetpTxtNode() )
1670 	{
1671 		SwCursor* pCrsr = getShellCrsr( true );
1672 
1673 		SET_CURR_SHELL( this );
1674 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1675 		SwCrsrSaveState aSaveState( *pCrsr );
1676 
1677 		pCrsr->GetPoint()->nNode = *rAttr.GetpTxtNode();
1678 		pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)rAttr.GetpTxtNode(),
1679 											*rAttr.GetStart() );
1680 		bRet = !pCrsr->IsSelOvr();
1681 		if( bRet )
1682 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1683 	}
1684 	return bRet;
1685 }
1686 
1687 
1688 const SwFmtINetFmt* SwCrsrShell::FindINetAttr( const String& rName ) const
1689 {
1690 	return pDoc->FindINetAttr( rName );
1691 }
1692 
1693 sal_Bool SwCrsrShell::GetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode,
1694                                 SwRect& rRect, sal_Int16& rOrient )
1695 {
1696 
1697 	SET_CURR_SHELL( this );
1698 	sal_Bool bRet = sal_False;
1699 
1700     if (!IsTableMode() && !HasSelection()
1701         && GetDoc()->GetIDocumentUndoRedo().DoesUndo())
1702     {
1703 		Point aPt( rPt );
1704 		SwPosition aPos( *pCurCrsr->GetPoint() );
1705 
1706 		SwFillCrsrPos aFPos( eFillMode );
1707 		SwCrsrMoveState aTmpState( &aFPos );
1708 
1709 		if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) &&
1710 			!aPos.nNode.GetNode().IsProtect())
1711 		{
1712 			// Start-Position im geschuetzten Bereich?
1713 			rRect = aFPos.aCrsr;
1714 			rOrient = aFPos.eOrient;
1715 			bRet = sal_True;
1716 		}
1717 	}
1718 	return bRet;
1719 }
1720 
1721 sal_Bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode )
1722 {
1723 	SET_CURR_SHELL( this );
1724 	sal_Bool bRet = sal_False;
1725 
1726     if (!IsTableMode() && !HasSelection()
1727         && GetDoc()->GetIDocumentUndoRedo().DoesUndo())
1728 	{
1729 		Point aPt( rPt );
1730 		SwPosition aPos( *pCurCrsr->GetPoint() );
1731 
1732 		SwFillCrsrPos aFPos( eFillMode );
1733 		SwCrsrMoveState aTmpState( &aFPos );
1734 
1735 		if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) )
1736 		{
1737 			SwCallLink aLk( *this );        // Crsr-Moves ueberwachen
1738 			StartAction();
1739 
1740 			SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
1741             SwUndoId nUndoId = UNDO_INS_FROM_SHADOWCRSR;
1742 			// Werden nur die Absatzattribute Adjust oder LRSpace gesetzt,
1743 			// dann sollte der naechste Aufruf die NICHT wieder entfernen.
1744 			if( 0 == aFPos.nParaCnt + aFPos.nColumnCnt &&
1745 				( FILL_INDENT == aFPos.eMode ||
1746                   ( text::HoriOrientation::NONE != aFPos.eOrient &&
1747 					0 == aFPos.nTabCnt + aFPos.nSpaceCnt )) &&
1748 				pCNd && pCNd->Len() )
1749                 nUndoId = UNDO_EMPTY;
1750 
1751             GetDoc()->GetIDocumentUndoRedo().StartUndo( nUndoId, NULL );
1752 
1753 			SwTxtFmtColl* pNextFmt = 0;
1754 			SwTxtNode* pTNd = pCNd->GetTxtNode();
1755 			if( pTNd )
1756 				pNextFmt = &pTNd->GetTxtColl()->GetNextTxtFmtColl();
1757 
1758 			const SwSectionNode* pSectNd = pCNd->FindSectionNode();
1759 			if( pSectNd && aFPos.nParaCnt )
1760 			{
1761 				SwNodeIndex aEnd( aPos.nNode, 1 );
1762 				while( aEnd.GetNode().IsEndNode() &&
1763 						(const SwNode*)&aEnd.GetNode() !=
1764 						pSectNd->EndOfSectionNode() )
1765 					aEnd++;
1766 
1767 				if( aEnd.GetNode().IsEndNode() &&
1768 					pCNd->Len() == aPos.nContent.GetIndex() )
1769 					aPos.nNode = *pSectNd->EndOfSectionNode();
1770 			}
1771 
1772 			for( sal_uInt16 n = 0; n < aFPos.nParaCnt + aFPos.nColumnCnt; ++n )
1773 			{
1774 				GetDoc()->AppendTxtNode( aPos );
1775 				if( !n && pNextFmt )
1776 				{
1777 					*pCurCrsr->GetPoint() = aPos;
1778                     GetDoc()->SetTxtFmtColl( *pCurCrsr, pNextFmt, false );
1779 					//JP 04.11.97: erstmal keine Folgevorlage der
1780 					//				Folgevorlage beachten
1781 					// pNextFmt = pNextFmt->GetNextTxtFmtColl();
1782 				}
1783 				if( n < aFPos.nColumnCnt )
1784 				{
1785 					*pCurCrsr->GetPoint() = aPos;
1786                     GetDoc()->InsertPoolItem( *pCurCrsr,
1787                             SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0);
1788 				}
1789 			}
1790 
1791 			*pCurCrsr->GetPoint() = aPos;
1792 			switch( aFPos.eMode )
1793 			{
1794 			case FILL_INDENT:
1795 				if( 0 != (pCNd = aPos.nNode.GetNode().GetCntntNode() ))
1796 				{
1797 					SfxItemSet aSet( GetDoc()->GetAttrPool(),
1798 									RES_LR_SPACE, RES_LR_SPACE,
1799 									RES_PARATR_ADJUST, RES_PARATR_ADJUST,
1800 									0 );
1801 					SvxLRSpaceItem aLR( (SvxLRSpaceItem&)
1802 										pCNd->GetAttr( RES_LR_SPACE ) );
1803 					aLR.SetTxtLeft( aFPos.nTabCnt );
1804 					aLR.SetTxtFirstLineOfst( 0 );
1805 					aSet.Put( aLR );
1806 
1807 					const SvxAdjustItem& rAdj = (SvxAdjustItem&)pCNd->
1808 										GetAttr( RES_PARATR_ADJUST );
1809 					if( SVX_ADJUST_LEFT != rAdj.GetAdjust() )
1810                         aSet.Put( SvxAdjustItem( SVX_ADJUST_LEFT, RES_PARATR_ADJUST ) );
1811 
1812                     GetDoc()->InsertItemSet( *pCurCrsr, aSet, 0 );
1813                 }
1814 				else {
1815 					ASSERT( !this, "wo ist mein CntntNode?" );
1816                 }
1817 				break;
1818 
1819 			case FILL_TAB:
1820 			case FILL_SPACE:
1821 				{
1822 					String sInsert;
1823 					if( aFPos.nTabCnt )
1824 						sInsert.Fill( aFPos.nTabCnt, '\t' );
1825 					if( aFPos.nSpaceCnt )
1826 					{
1827 						String sSpace;
1828 						sSpace.Fill( aFPos.nSpaceCnt );
1829 						sInsert += sSpace;
1830 					}
1831 					if( sInsert.Len() )
1832                     {
1833                         GetDoc()->InsertString( *pCurCrsr, sInsert );
1834                     }
1835 				}
1836 				// kein break - Ausrichtung muss noch gesetzt werden
1837 			case FILL_MARGIN:
1838                 if( text::HoriOrientation::NONE != aFPos.eOrient )
1839 				{
1840                     SvxAdjustItem aAdj( SVX_ADJUST_LEFT, RES_PARATR_ADJUST );
1841 					switch( aFPos.eOrient )
1842 					{
1843                     case text::HoriOrientation::CENTER:
1844 						aAdj.SetAdjust( SVX_ADJUST_CENTER );
1845 						break;
1846                     case text::HoriOrientation::RIGHT:
1847 						aAdj.SetAdjust( SVX_ADJUST_RIGHT );
1848 						break;
1849 					default:
1850 						break;
1851 					}
1852                     GetDoc()->InsertPoolItem( *pCurCrsr, aAdj, 0 );
1853 				}
1854 				break;
1855 			}
1856 
1857             GetDoc()->GetIDocumentUndoRedo().EndUndo( nUndoId, NULL );
1858 			EndAction();
1859 
1860 			bRet = sal_True;
1861 		}
1862 	}
1863 	return bRet;
1864 }
1865 
1866 const SwRedline* SwCrsrShell::SelNextRedline()
1867 {
1868 	const SwRedline* pFnd = 0;
1869 	if( !IsTableMode() )
1870 	{
1871 		SET_CURR_SHELL( this );
1872 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1873 		SwCrsrSaveState aSaveState( *pCurCrsr );
1874 
1875 		pFnd = GetDoc()->SelNextRedline( *pCurCrsr );
1876 		if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
1877 			UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1878 		else
1879 			pFnd = 0;
1880 	}
1881 	return pFnd;
1882 }
1883 
1884 const SwRedline* SwCrsrShell::SelPrevRedline()
1885 {
1886 	const SwRedline* pFnd = 0;
1887 	if( !IsTableMode() )
1888 	{
1889 		SET_CURR_SHELL( this );
1890 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1891 		SwCrsrSaveState aSaveState( *pCurCrsr );
1892 
1893 		pFnd = GetDoc()->SelPrevRedline( *pCurCrsr );
1894 		if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
1895 			UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1896 		else
1897 			pFnd = 0;
1898 	}
1899 	return pFnd;
1900 }
1901 
1902 const SwRedline* SwCrsrShell::_GotoRedline( sal_uInt16 nArrPos, sal_Bool bSelect )
1903 {
1904 	const SwRedline* pFnd = 0;
1905 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1906 	SwCrsrSaveState aSaveState( *pCurCrsr );
1907 
1908 	pFnd = GetDoc()->GetRedlineTbl()[ nArrPos ];
1909 	if( pFnd )
1910 	{
1911 		*pCurCrsr->GetPoint() = *pFnd->Start();
1912 
1913 		SwCntntNode* pCNd;
1914 		SwNodeIndex* pIdx = &pCurCrsr->GetPoint()->nNode;
1915 		if( !pIdx->GetNode().IsCntntNode() &&
1916 			0 != ( pCNd = GetDoc()->GetNodes().GoNextSection( pIdx,
1917 									sal_True, IsReadOnlyAvailable() )) )
1918 		{
1919 			if( *pIdx <= pFnd->End()->nNode )
1920 				pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
1921 			else
1922 				pFnd = 0;
1923 		}
1924 
1925 		if( pFnd && bSelect )
1926 		{
1927 			pCurCrsr->SetMark();
1928 			if( nsRedlineType_t::REDLINE_FMTCOLL == pFnd->GetType() )
1929 			{
1930 				pCNd = pIdx->GetNode().GetCntntNode();
1931 				pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
1932 				pCurCrsr->GetMark()->nContent.Assign( pCNd, 0 );
1933 			}
1934 			else
1935 				*pCurCrsr->GetPoint() = *pFnd->End();
1936 
1937 			pIdx = &pCurCrsr->GetPoint()->nNode;
1938 			if( !pIdx->GetNode().IsCntntNode() &&
1939 				0 != ( pCNd = GetDoc()->GetNodes().GoPrevSection( pIdx,
1940 											sal_True, IsReadOnlyAvailable() )) )
1941 			{
1942 				if( *pIdx >= pCurCrsr->GetMark()->nNode )
1943 					pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
1944 				else
1945 					pFnd = 0;
1946 			}
1947 		}
1948 
1949 		if( !pFnd )
1950 		{
1951 			pCurCrsr->DeleteMark();
1952 			pCurCrsr->RestoreSavePos();
1953 		}
1954 		else if( bSelect && *pCurCrsr->GetMark() == *pCurCrsr->GetPoint() )
1955 			pCurCrsr->DeleteMark();
1956 
1957 		if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
1958 			UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE
1959 						| SwCrsrShell::READONLY );
1960 		else
1961 		{
1962 			pFnd = 0;
1963 			if( bSelect )
1964 				pCurCrsr->DeleteMark();
1965 		}
1966 	}
1967 	return pFnd;
1968 }
1969 
1970 const SwRedline* SwCrsrShell::GotoRedline( sal_uInt16 nArrPos, sal_Bool bSelect )
1971 {
1972 	const SwRedline* pFnd = 0;
1973 	if( !IsTableMode() )
1974 	{
1975 		SET_CURR_SHELL( this );
1976 
1977 		const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl();
1978 		const SwRedline* pTmp = rTbl[ nArrPos ];
1979 		sal_uInt16 nSeqNo = pTmp->GetSeqNo();
1980 		if( nSeqNo && bSelect )
1981 		{
1982 			sal_Bool bCheck = sal_False;
1983 			int nLoopCnt = 2;
1984 			sal_uInt16 nArrSavPos = nArrPos;
1985 
1986 			do {
1987 				pTmp = _GotoRedline( nArrPos, sal_True );
1988 
1989 				if( !pFnd )
1990 					pFnd = pTmp;
1991 
1992 				if( pTmp && bCheck )
1993 				{
1994 					// checke auf Ueberlappungen. Das kann durch
1995 					// FmtColl-Redlines kommen, die auf den gesamten Absatz
1996 					// aus gedehnt werden.
1997 
1998                     SwPaM* pCur = pCurCrsr;
1999                     SwPaM* pNextPam = (SwPaM*)pCur->GetNext();
2000 					SwPosition* pCStt = pCur->Start(), *pCEnd = pCur->End();
2001                     while( pCur != pNextPam )
2002 					{
2003                         const SwPosition *pNStt = pNextPam->Start(),
2004                                          *pNEnd = pNextPam->End();
2005 
2006 						sal_Bool bDel = sal_True;
2007 						switch( ::ComparePosition( *pCStt, *pCEnd,
2008 												   *pNStt, *pNEnd ))
2009 						{
2010 						case POS_INSIDE:	// Pos1 liegt vollstaendig in Pos2
2011 							if( !pCur->HasMark() )
2012 							{
2013 								pCur->SetMark();
2014 								*pCur->GetMark() = *pNStt;
2015 							}
2016 							else
2017 								*pCStt = *pNStt;
2018 							*pCEnd = *pNEnd;
2019 							break;
2020 
2021 						case POS_OUTSIDE:	// Pos2 liegt vollstaendig in Pos1
2022 						case POS_EQUAL:		// Pos1 ist genauso gross wie Pos2
2023 							break;
2024 
2025 						case POS_OVERLAP_BEFORE:		// Pos1 ueberlappt Pos2 am Anfang
2026 							if( !pCur->HasMark() )
2027 								pCur->SetMark();
2028 							*pCEnd = *pNEnd;
2029 							break;
2030 						case POS_OVERLAP_BEHIND: 		// Pos1 ueberlappt Pos2 am Ende
2031 							if( !pCur->HasMark() )
2032 							{
2033 								pCur->SetMark();
2034 								*pCur->GetMark() = *pNStt;
2035 							}
2036 							else
2037 								*pCStt = *pNStt;
2038 							break;
2039 
2040 						default:
2041 							bDel = sal_False;
2042 						}
2043 
2044 						if( bDel )
2045 						{
2046 							// den brauchen wir nicht mehr
2047                             SwPaM* pPrevPam = (SwPaM*)pNextPam->GetPrev();
2048                             delete pNextPam;
2049                             pNextPam = pPrevPam;
2050 						}
2051                         pNextPam = (SwPaM*)pNextPam->GetNext();
2052 					}
2053 				}
2054 
2055 				sal_uInt16 nFndPos = 2 == nLoopCnt
2056 									? rTbl.FindNextOfSeqNo( nArrPos )
2057 									: rTbl.FindPrevOfSeqNo( nArrPos );
2058 				if( USHRT_MAX != nFndPos ||
2059 					( 0 != ( --nLoopCnt ) && USHRT_MAX != (
2060 							nFndPos = rTbl.FindPrevOfSeqNo( nArrSavPos ))) )
2061 				{
2062 					if( pTmp )
2063 					{
2064 						// neuen Cursor erzeugen
2065 						CreateCrsr();
2066 						bCheck = sal_True;
2067 					}
2068 					nArrPos = nFndPos;
2069 				}
2070 				else
2071 					nLoopCnt = 0;
2072 
2073 			} while( nLoopCnt );
2074 		}
2075 		else
2076 			pFnd = _GotoRedline( nArrPos, bSelect );
2077 	}
2078 	return pFnd;
2079 }
2080 
2081 
2082 sal_Bool SwCrsrShell::SelectNxtPrvHyperlink( sal_Bool bNext )
2083 {
2084 	SwNodes& rNds = GetDoc()->GetNodes();
2085 	const SwNode* pBodyEndNd = &rNds.GetEndOfContent();
2086     const SwNode* pBodySttNd = pBodyEndNd->StartOfSectionNode();
2087 	sal_uLong nBodySttNdIdx = pBodySttNd->GetIndex();
2088 	Point aPt;
2089 
2090 	_SetGetExpFld aCmpPos( SwPosition( bNext ? *pBodyEndNd : *pBodySttNd ) );
2091 	_SetGetExpFld aCurPos( bNext ? *pCurCrsr->End() : *pCurCrsr->Start() );
2092 	if( aCurPos.GetNode() < nBodySttNdIdx )
2093 	{
2094 		const SwCntntNode* pCNd = aCurPos.GetNodeFromCntnt()->GetCntntNode();
2095 		SwCntntFrm* pFrm;
2096 		if( pCNd && 0 != ( pFrm = pCNd->getLayoutFrm( GetLayout(), &aPt )) )
2097 			aCurPos.SetBodyPos( *pFrm );
2098 	}
2099 
2100 	// check first all the hyperlink fields
2101 	{
2102 		const SwTxtNode* pTxtNd;
2103 		const SwCharFmts* pFmts = GetDoc()->GetCharFmts();
2104 		for( sal_uInt16 n = pFmts->Count(); 1 < n; )
2105 		{
2106 			SwIterator<SwTxtINetFmt,SwCharFmt> aIter(*(*pFmts)[--n]);
2107 
2108 			for( SwTxtINetFmt* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() )
2109 				if( 0 != ( pTxtNd = pFnd->GetpTxtNode()) &&
2110 					pTxtNd->GetNodes().IsDocNodes() )
2111 				{
2112 					SwTxtINetFmt& rAttr = *pFnd;
2113 					SwPosition aTmpPos( *pTxtNd );
2114 					_SetGetExpFld aPos( aTmpPos.nNode, rAttr );
2115 					SwCntntFrm* pFrm;
2116 					if( pTxtNd->GetIndex() < nBodySttNdIdx &&
2117 						0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt )) )
2118 						aPos.SetBodyPos( *pFrm );
2119 
2120 					if( bNext
2121 						? ( aPos < aCmpPos && aCurPos < aPos )
2122 						: ( aCmpPos < aPos && aPos < aCurPos ))
2123 					{
2124 						String sTxt( pTxtNd->GetExpandTxt( *rAttr.GetStart(),
2125 										*rAttr.GetEnd() - *rAttr.GetStart() ) );
2126 
2127 						sTxt.EraseAllChars( 0x0a );
2128 						sTxt.EraseLeadingChars().EraseTrailingChars();
2129 
2130 						if( sTxt.Len() )
2131 							aCmpPos = aPos;
2132 					}
2133 				}
2134 		}
2135 	}
2136 	// then check all the Flys with a URL or imapge map
2137 	{
2138 		const SwSpzFrmFmts* pFmts = GetDoc()->GetSpzFrmFmts();
2139 		for( sal_uInt16 n = 0, nEnd = pFmts->Count(); n < nEnd; ++n )
2140 		{
2141 			SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)(*pFmts)[ n ];
2142 			const SwFmtURL& rURLItem = pFmt->GetURL();
2143 			if( rURLItem.GetMap() || rURLItem.GetURL().Len() )
2144 			{
2145 				SwFlyFrm* pFly = pFmt->GetFrm( &aPt, sal_False );
2146 				SwPosition aTmpPos( *pBodySttNd );
2147 				if( pFly &&
2148 					GetBodyTxtNode( *GetDoc(), aTmpPos, *pFly->GetLower() ) )
2149 				{
2150 					_SetGetExpFld aPos( *pFmt, &aTmpPos );
2151 
2152 					if( bNext
2153 							? ( aPos < aCmpPos && aCurPos < aPos )
2154 							: ( aCmpPos < aPos && aPos < aCurPos ))
2155 						aCmpPos = aPos;
2156 				}
2157 			}
2158 		}
2159 	}
2160 
2161 	// found any URL ?
2162 	sal_Bool bRet = sal_False;
2163 	const SwTxtINetFmt* pFndAttr = aCmpPos.GetINetFmt();
2164 	const SwFlyFrmFmt* pFndFmt = aCmpPos.GetFlyFmt();
2165 	if( pFndAttr || pFndFmt )
2166 	{
2167 		SET_CURR_SHELL( this );
2168 		SwCallLink aLk( *this );
2169 
2170 		// find a text attribute ?
2171 		if( pFndAttr )
2172 		{
2173 			SwCrsrSaveState aSaveState( *pCurCrsr );
2174 
2175 			aCmpPos.GetPosOfContent( *pCurCrsr->GetPoint() );
2176 			pCurCrsr->DeleteMark();
2177 			pCurCrsr->SetMark();
2178 			pCurCrsr->GetPoint()->nContent = *pFndAttr->SwTxtAttr::GetEnd();
2179 
2180 			if( !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
2181 			{
2182 				UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|
2183 									SwCrsrShell::READONLY );
2184 				bRet = sal_True;
2185 			}
2186 		}
2187 		// find a draw object ?
2188 		else if( RES_DRAWFRMFMT == pFndFmt->Which() )
2189 		{
2190 			const SdrObject* pSObj = pFndFmt->FindSdrObject();
2191 			((SwFEShell*)this)->SelectObj( pSObj->GetCurrentBoundRect().Center() );
2192 			MakeSelVisible();
2193 			bRet = sal_True;
2194 		}
2195 		else		// then is it a fly
2196 		{
2197 			SwFlyFrm* pFly = pFndFmt->GetFrm(&aPt, sal_False );
2198 			if( pFly )
2199 			{
2200 				((SwFEShell*)this)->SelectFlyFrm( *pFly, sal_True );
2201 				MakeSelVisible();
2202 				bRet = sal_True;
2203 			}
2204 		}
2205 	}
2206 	return bRet;
2207 }
2208 
2209