xref: /trunk/main/sw/source/core/crsr/crstrvl.cxx (revision 870262e3)
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>
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>
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
GotoNextNum()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 
GotoPrevNum()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 
GotoHeaderTxt()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 
GotoFooterTxt()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 
SetCrsrInHdFt(sal_uInt16 nDescNo,sal_Bool bInHeader)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 
GotoNextTOXBase(const String * pName)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 
GotoPrevTOXBase(const String * pName)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 
GotoTOXMarkBase()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
GotoNxtPrvTblFormula(sal_Bool bNext,sal_Bool bOnlyErrors)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
GotoNxtPrvTOXMark(sal_Bool bNext)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 
GotoTOXMark(const SwTOXMark & rStart,SwTOXSearch eDir)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 
lcl_MakeFldLst(_SetGetExpFlds & rLst,const SwFieldType & rFldType,const bool bInReadOnly,const bool bChkInpFlag=false)621 void lcl_MakeFldLst(
622     _SetGetExpFlds& rLst,
623     const SwFieldType& rFldType,
624     const bool bInReadOnly,
625     const bool bChkInpFlag = false )
626 {
627     // es muss immer der 1. Frame gesucht werden
628     Point aPt;
629     SwTxtFld* pTxtFld = NULL;
630     SwIterator<SwFmtFld,SwFieldType> aIter(rFldType);
631     for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
632     {
633         pTxtFld = pFmtFld->GetTxtFld();
634         if ( pTxtFld != NULL
635              && ( !bChkInpFlag
636                   || ((SwSetExpField*)pTxtFld->GetFmtFld().GetField())->GetInputFlag() ) )
637         {
638             const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
639             const SwCntntFrm* pCFrm =
640                 rTxtNode.getLayoutFrm( rTxtNode.GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False );
641             if ( pCFrm != NULL
642                  && ( bInReadOnly || !pCFrm->IsProtected() ) )
643             {
644                 _SetGetExpFld* pNew = new _SetGetExpFld( SwNodeIndex( rTxtNode ), pTxtFld );
645                 pNew->SetBodyPos( *pCFrm );
646                 rLst.Insert( pNew );
647             }
648         }
649     }
650 }
651 
652 
MoveFldType(const SwFieldType * pFldType,const bool bNext,const sal_uInt16 nResType,const bool bAddSetExpressionFldsToInputFlds)653 sal_Bool SwCrsrShell::MoveFldType(
654     const SwFieldType* pFldType,
655     const bool bNext,
656     const sal_uInt16 nResType,
657     const bool bAddSetExpressionFldsToInputFlds )
658 {
659     // sortierte Liste aller Felder
660     _SetGetExpFlds aSrtLst( 64 );
661 
662     if ( pFldType )
663     {
664         if( RES_INPUTFLD != pFldType->Which() && !pFldType->GetDepends() )
665         {
666             return sal_False;
667         }
668 
669         // Modify-Object gefunden, trage alle Felder ins Array ein
670         ::lcl_MakeFldLst( aSrtLst, *pFldType, ( IsReadOnlyAvailable() ? true : false ) );
671 
672         if( RES_INPUTFLD == pFldType->Which() && bAddSetExpressionFldsToInputFlds )
673         {
674             // es gibt noch versteckte InputFelder in den SetExp. Feldern
675             const SwFldTypes& rFldTypes = *pDoc->GetFldTypes();
676             const sal_uInt16 nSize = rFldTypes.Count();
677             for( sal_uInt16 i=0; i < nSize; ++i )
678             {
679                 pFldType = rFldTypes[ i ];
680                 if ( RES_SETEXPFLD == pFldType->Which() )
681                 {
682                     ::lcl_MakeFldLst( aSrtLst, *pFldType, ( IsReadOnlyAvailable() ? true : false ), true );
683                 }
684             }
685         }
686     }
687     else
688     {
689         const SwFldTypes& rFldTypes = *pDoc->GetFldTypes();
690         const sal_uInt16 nSize = rFldTypes.Count();
691         for( sal_uInt16 i=0; i < nSize; ++i )
692         {
693             pFldType = rFldTypes[ i ];
694             if( nResType == pFldType->Which() )
695             {
696                 ::lcl_MakeFldLst( aSrtLst, *pFldType, ( IsReadOnlyAvailable() ? true : false ) );
697             }
698         }
699     }
700 
701 	// keine Felder gefunden?
702 	if( !aSrtLst.Count() )
703 		return sal_False;
704 
705 	sal_uInt16 nPos;
706 	SwCursor* pCrsr = getShellCrsr( true );
707 	{
708 		// JP 19.08.98: es muss immer ueber das Feld gesucht werden, damit
709 		//				auch immer das richtige gefunden wird, wenn welche in
710 		//				Rahmen stehen, die in einem Absatz verankert sind,
711 		//				in dem ein Feld steht - siehe auch Bug 55247
712 		const SwPosition& rPos = *pCrsr->GetPoint();
713 
714 		SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
715 		ASSERT( pTNd, "Wo ist mein CntntNode?" );
716 
717         SwTxtFld * pTxtFld = pTNd->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true );
718         const bool bDelFld = ( pTxtFld == NULL );
719         if( bDelFld )
720         {
721             // create dummy for the search
722             SwFmtFld* pFmtFld = new SwFmtFld( SwDateTimeField(
723                 (SwDateTimeFieldType*)pDoc->GetSysFldType( RES_DATETIMEFLD ) ) );
724 
725             pTxtFld = new SwTxtFld( *pFmtFld, rPos.nContent.GetIndex(), pDoc->IsClipBoard() );
726             pTxtFld->ChgTxtNode( pTNd );
727         }
728 
729         SwIndex aSearchIdx( rPos.nContent );
730         if ( !bDelFld && pTxtFld->HasContent() )
731         {
732             aSearchIdx = *(pTxtFld->GetStart());
733         }
734         _SetGetExpFld aSrch( rPos.nNode, pTxtFld, &aSearchIdx );
735         if( rPos.nNode.GetIndex() < pDoc->GetNodes().GetEndOfExtras().GetIndex() )
736         {
737             // auch beim Einsammeln wird nur der erste Frame benutzt!
738             Point aPt;
739             aSrch.SetBodyPos( *pTNd->getLayoutFrm( GetLayout(), &aPt, &rPos, sal_False ) );
740         }
741 
742         sal_Bool bFound = aSrtLst.Seek_Entry( &aSrch, &nPos );
743         if( bDelFld )
744         {
745             delete (SwFmtFld*)&pTxtFld->GetAttr();
746             delete pTxtFld;
747         }
748 
749         if( bFound )		// stehe auf einem ?
750         {
751             if( bNext )
752             {
753                 if( ++nPos >= aSrtLst.Count() )
754                     return sal_False;					// schon am Ende
755             }
756             else if( !nPos-- )
757                 return sal_False;	  	// weiter nach vorne geht nicht
758         }
759         else if( bNext ? nPos >= aSrtLst.Count() : !nPos--)
760         {
761             return sal_False;
762         }
763     }
764     const _SetGetExpFld& rFnd = **( aSrtLst.GetData() + nPos );
765 
766 
767 	SET_CURR_SHELL( this );
768 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
769 	SwCrsrSaveState aSaveState( *pCrsr );
770 
771 	rFnd.GetPosOfContent( *pCrsr->GetPoint() );
772     sal_Bool bRet = !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
773                                      nsSwCursorSelOverFlags::SELOVER_TOGGLE );
774 	if( bRet )
775 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
776 	return bRet;
777 }
778 
779 
GotoFld(const SwFmtFld & rFld)780 sal_Bool SwCrsrShell::GotoFld( const SwFmtFld& rFld )
781 {
782 	sal_Bool bRet = sal_False;
783 	if( rFld.GetTxtFld() )
784 	{
785 		SET_CURR_SHELL( this );
786 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
787 
788 		SwCursor* pCrsr = getShellCrsr( true );
789 		SwCrsrSaveState aSaveState( *pCrsr );
790 
791 		SwTxtNode* pTNd = (SwTxtNode*)rFld.GetTxtFld()->GetpTxtNode();
792 		pCrsr->GetPoint()->nNode = *pTNd;
793 		pCrsr->GetPoint()->nContent.Assign( pTNd, *rFld.GetTxtFld()->GetStart() );
794 
795 		bRet = !pCrsr->IsSelOvr();
796 		if( bRet )
797 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
798 	}
799 	return bRet;
800 }
801 
802 
GetTxtFldAtPos(const SwPosition * pPos,const bool bIncludeInputFldAtStart) const803 SwTxtFld * SwCrsrShell::GetTxtFldAtPos(
804     const SwPosition* pPos,
805     const bool bIncludeInputFldAtStart ) const
806 {
807     SwTxtFld* pTxtFld = NULL;
808 
809     SwTxtNode * const pNode = pPos->nNode.GetNode().GetTxtNode();
810     if ( pNode != NULL )
811     {
812         pTxtFld = pNode->GetFldTxtAttrAt( pPos->nContent.GetIndex(), bIncludeInputFldAtStart );
813     }
814 
815     return pTxtFld;
816 }
817 
818 
GetFieldAtCrsr(const SwPaM * pCrsr,const bool bIncludeInputFldAtStart) const819 SwField* SwCrsrShell::GetFieldAtCrsr(
820     const SwPaM* pCrsr,
821     const bool bIncludeInputFldAtStart ) const
822 {
823     SwField* pFieldAtCrsr = NULL;
824 
825     SwTxtFld* pTxtFld = GetTxtFldAtPos( pCrsr->Start(), bIncludeInputFldAtStart );
826     if ( pTxtFld != NULL
827         && pCrsr->Start()->nNode == pCrsr->End()->nNode )
828     {
829         const xub_StrLen nTxtFldLength =
830             pTxtFld->End() != NULL
831             ? *(pTxtFld->End()) - *(pTxtFld->GetStart())
832             : 1;
833         if ( ( pCrsr->End()->nContent.GetIndex() - pCrsr->Start()->nContent.GetIndex() ) <= nTxtFldLength )
834         {
835             pFieldAtCrsr = (SwField*)pTxtFld->GetFmtFld().GetField();
836         }
837     }
838 
839     return pFieldAtCrsr;
840 }
841 
842 
GetCurFld(const bool bIncludeInputFldAtStart) const843 SwField* SwCrsrShell::GetCurFld( const bool bIncludeInputFldAtStart ) const
844 {
845     SwPaM* pCrsr = GetCrsr();
846     if ( pCrsr->GetNext() != pCrsr )
847     {
848         // multi selection not handled.
849         return NULL;
850     }
851 
852     SwField* pCurFld = GetFieldAtCrsr( pCrsr, bIncludeInputFldAtStart );;
853     if ( pCurFld != NULL
854          && RES_TABLEFLD == pCurFld->GetTyp()->Which() )
855     {
856         // TabellenFormel ? wandel internen in externen Namen um
857         const SwTableNode* pTblNd = IsCrsrInTbl();
858         ((SwTblField*)pCurFld)->PtrToBoxNm( pTblNd ? &pTblNd->GetTable() : 0 );
859     }
860 
861     return pCurFld;
862 }
863 
864 
CrsrInsideInputFld() const865 bool SwCrsrShell::CrsrInsideInputFld() const
866 {
867     bool bCrsrInsideInputFld = false;
868 
869     const SwPaM* pCrsr = GetCrsr();
870     const SwPaM* pFirst = pCrsr;
871     do
872     {
873         bCrsrInsideInputFld = dynamic_cast<const SwInputField*>(GetFieldAtCrsr( pCrsr, false )) != NULL;
874 
875         pCrsr = static_cast<SwPaM*>(pCrsr->GetNext());
876     } while ( !bCrsrInsideInputFld
877               && pCrsr != pFirst );
878 
879     return bCrsrInsideInputFld;
880 }
881 
882 
PosInsideInputFld(const SwPosition & rPos) const883 bool SwCrsrShell::PosInsideInputFld( const SwPosition& rPos ) const
884 {
885     return dynamic_cast<const SwTxtInputFld*>(GetTxtFldAtPos( &rPos, false )) != NULL;
886 }
887 
888 
DocPtInsideInputFld(const Point & rDocPt) const889 bool SwCrsrShell::DocPtInsideInputFld( const Point& rDocPt ) const
890 {
891     SwPosition aPos( *(GetCrsr()->Start()) );
892     Point aDocPt( rDocPt );
893     if ( GetLayout()->GetCrsrOfst( &aPos, aDocPt ) )
894     {
895         return PosInsideInputFld( aPos );
896     }
897     return false;
898 }
899 
900 
StartOfInputFldAtPos(const SwPosition & rPos) const901 xub_StrLen SwCrsrShell::StartOfInputFldAtPos( const SwPosition& rPos ) const
902 {
903     const SwTxtInputFld* pTxtInputFld = dynamic_cast<const SwTxtInputFld*>(GetTxtFldAtPos( &rPos, true ));
904     if ( pTxtInputFld == NULL )
905     {
906         ASSERT( false, "<SwEditShell::StartOfInputFldAtPos(..)> - no Input Field at given position" );
907         return 0;
908     }
909     return *(pTxtInputFld->GetStart());
910 }
911 
912 
EndOfInputFldAtPos(const SwPosition & rPos) const913 xub_StrLen SwCrsrShell::EndOfInputFldAtPos( const SwPosition& rPos ) const
914 {
915     const SwTxtInputFld* pTxtInputFld = dynamic_cast<const SwTxtInputFld*>(GetTxtFldAtPos( &rPos, true ));
916     if ( pTxtInputFld == NULL )
917     {
918         ASSERT( false, "<SwEditShell::EndOfInputFldAtPos(..)> - no Input Field at given position" );
919         return 0;
920     }
921     return *(pTxtInputFld->End());
922 }
923 
924 
GotoOutline(sal_uInt16 nIdx)925 void SwCrsrShell::GotoOutline( sal_uInt16 nIdx )
926 {
927 	SwCursor* pCrsr = getShellCrsr( true );
928 
929 	SET_CURR_SHELL( this );
930 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
931 	SwCrsrSaveState aSaveState( *pCrsr );
932 
933 	const SwNodes& rNds = GetDoc()->GetNodes();
934 	SwTxtNode* pTxtNd = (SwTxtNode*)rNds.GetOutLineNds()[ nIdx ]->GetTxtNode();
935 	pCrsr->GetPoint()->nNode = *pTxtNd;
936 	pCrsr->GetPoint()->nContent.Assign( pTxtNd, 0 );
937 
938 	if( !pCrsr->IsSelOvr() )
939 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
940 }
941 
942 
GotoOutline(const String & rName)943 sal_Bool SwCrsrShell::GotoOutline( const String& rName )
944 {
945 	SwCursor* pCrsr = getShellCrsr( true );
946 
947 	SET_CURR_SHELL( this );
948 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
949 	SwCrsrSaveState aSaveState( *pCrsr );
950 
951 	sal_Bool bRet = sal_False;
952 	if( pDoc->GotoOutline( *pCrsr->GetPoint(), rName ) && !pCrsr->IsSelOvr() )
953 	{
954 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
955 		bRet = sal_True;
956 	}
957 	return bRet;
958 }
959 
960 
961 
GotoNextOutline()962 sal_Bool SwCrsrShell::GotoNextOutline()			// naechster Node mit Outline-Num.
963 {
964 	SwCursor* pCrsr = getShellCrsr( true );
965 	const SwNodes& rNds = GetDoc()->GetNodes();
966 
967 	SwNode* pNd = pCrsr->GetNode();
968 	sal_uInt16 nPos;
969 	if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos ))
970 		++nPos;
971 
972 	if( nPos == rNds.GetOutLineNds().Count() )
973 		return sal_False;
974 
975 	pNd = rNds.GetOutLineNds()[ nPos ];
976 
977 	SET_CURR_SHELL( this );
978 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
979 	SwCrsrSaveState aSaveState( *pCrsr );
980 	pCrsr->GetPoint()->nNode = *pNd;
981 	pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 );
982 
983 	sal_Bool bRet = !pCrsr->IsSelOvr();
984 	if( bRet )
985 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
986 	return bRet;
987 }
988 
989 
GotoPrevOutline()990 sal_Bool SwCrsrShell::GotoPrevOutline()			// vorheriger Node mit Outline-Num.
991 {
992 	SwCursor* pCrsr = getShellCrsr( true );
993 	const SwNodes& rNds = GetDoc()->GetNodes();
994 
995 	SwNode* pNd = pCrsr->GetNode();
996 	sal_uInt16 nPos;
997 	rNds.GetOutLineNds().Seek_Entry( pNd, &nPos );
998 
999 	sal_Bool bRet = sal_False;
1000 	if( nPos )
1001 	{
1002 		--nPos;	// davor
1003 
1004 		pNd = rNds.GetOutLineNds()[ nPos ];
1005 		if( pNd->GetIndex() > pCrsr->GetPoint()->nNode.GetIndex() )
1006 			return sal_False;
1007 
1008 		SET_CURR_SHELL( this );
1009 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1010 		SwCrsrSaveState aSaveState( *pCrsr );
1011 		pCrsr->GetPoint()->nNode = *pNd;
1012 		pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 );
1013 
1014 		bRet = !pCrsr->IsSelOvr();
1015 		if( bRet )
1016 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1017 	}
1018 	return bRet;
1019 }
1020 
1021 
1022 	// suche die "Outline-Position" vom vorherigen Outline-Node mit dem
1023 	// Level.
GetOutlinePos(sal_uInt8 nLevel)1024 sal_uInt16 SwCrsrShell::GetOutlinePos( sal_uInt8 nLevel )
1025 {
1026 	SwPaM* pCrsr = getShellCrsr( true );
1027 	const SwNodes& rNds = GetDoc()->GetNodes();
1028 
1029 	SwNode* pNd = pCrsr->GetNode();
1030 	sal_uInt16 nPos;
1031 	if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos ))
1032 		nPos++;			// steht auf der Position, fuers while zum Naechsten
1033 
1034 	while( nPos-- )		// immer den davor testen !
1035 	{
1036 		pNd = rNds.GetOutLineNds()[ nPos ];
1037 
1038 		//if( ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() <= nLevel )//#outline level,zhaojianwei
1039 		if( ((SwTxtNode*)pNd)->GetAttrOutlineLevel()-1 <= nLevel )//<-end,zhaojianwei
1040 			return nPos;
1041 
1042 	}
1043 	return USHRT_MAX;		// davor keiner mehr also Ende
1044 }
1045 
1046 
MakeOutlineSel(sal_uInt16 nSttPos,sal_uInt16 nEndPos,sal_Bool bWithChilds)1047 sal_Bool SwCrsrShell::MakeOutlineSel( sal_uInt16 nSttPos, sal_uInt16 nEndPos,
1048 									sal_Bool bWithChilds )
1049 {
1050 	const SwNodes& rNds = GetDoc()->GetNodes();
1051 	const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1052 	if( !rOutlNds.Count() )		// wie jetzt ???
1053 		return sal_False;
1054 
1055 	SET_CURR_SHELL( this );
1056 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1057 
1058 	if( nSttPos > nEndPos )			// sollte jemand das vertauscht haben?
1059 	{
1060 		ASSERT( sal_False, "Start > End Position in the array" );
1061 		sal_uInt16 nTmp = nSttPos;
1062 		nSttPos = nEndPos;
1063 		nEndPos = nTmp;
1064 	}
1065 
1066 	SwNode* pSttNd = rOutlNds[ nSttPos ];
1067 	SwNode* pEndNd = rOutlNds[ nEndPos ];
1068 
1069 	if( bWithChilds )
1070 	{
1071 		//sal_uInt8 nLevel = pEndNd->GetTxtNode()->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
1072         const int nLevel = pEndNd->GetTxtNode()->GetAttrOutlineLevel()-1;//<-end.zhaojianwei
1073 		for( ++nEndPos; nEndPos < rOutlNds.Count(); ++nEndPos )
1074 		{
1075 			pEndNd = rOutlNds[ nEndPos ];
1076 			//sal_uInt8 nNxtLevel = pEndNd->GetTxtNode()->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
1077             const int nNxtLevel = pEndNd->GetTxtNode()->GetAttrOutlineLevel()-1;//<-end,zhaojianwei
1078 			if( nNxtLevel <= nLevel )
1079 				break;			// EndPos steht jetzt auf dem naechsten
1080 		}
1081 	}
1082 	// ohne Childs, dann aber zumindest auf den naechsten
1083 	else if( ++nEndPos < rOutlNds.Count() )
1084 		pEndNd = rOutlNds[ nEndPos ];
1085 
1086 	if( nEndPos == rOutlNds.Count() )		// kein Ende gefunden
1087 		pEndNd = &rNds.GetEndOfContent();
1088 
1089 	KillPams();
1090 
1091 	SwCrsrSaveState aSaveState( *pCurCrsr );
1092 
1093 	// Jetzt das Ende ans Ende vom voherigen ContentNode setzen
1094 	pCurCrsr->GetPoint()->nNode = *pSttNd;
1095 	pCurCrsr->GetPoint()->nContent.Assign( pSttNd->GetCntntNode(), 0 );
1096 	pCurCrsr->SetMark();
1097 	pCurCrsr->GetPoint()->nNode = *pEndNd;
1098 	pCurCrsr->Move( fnMoveBackward, fnGoNode );		// ans Ende vom Vorgaenger
1099 
1100 	// und schon ist alles selektiert
1101 	sal_Bool bRet = !pCurCrsr->IsSelOvr();
1102 	if( bRet )
1103 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1104 	return bRet;
1105 }
1106 
1107 
1108 // springe zu dieser Refmark
GotoRefMark(const String & rRefMark,sal_uInt16 nSubType,sal_uInt16 nSeqNo)1109 sal_Bool SwCrsrShell::GotoRefMark( const String& rRefMark, sal_uInt16 nSubType,
1110 									sal_uInt16 nSeqNo )
1111 {
1112 	SET_CURR_SHELL( this );
1113 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1114 	SwCrsrSaveState aSaveState( *pCurCrsr );
1115 
1116 	sal_uInt16 nPos;
1117 	SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( GetDoc(), rRefMark,
1118 													nSubType, nSeqNo, &nPos );
1119 	if( pTxtNd && pTxtNd->GetNodes().IsDocNodes() )
1120 	{
1121 		pCurCrsr->GetPoint()->nNode = *pTxtNd;
1122 		pCurCrsr->GetPoint()->nContent.Assign( pTxtNd, nPos );
1123 
1124 		if( !pCurCrsr->IsSelOvr() )
1125 		{
1126 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1127 			return sal_True;
1128 		}
1129 	}
1130 	return sal_False;
1131 }
1132 
IsPageAtPos(const Point & rPt) const1133 sal_Bool SwCrsrShell::IsPageAtPos( const Point &rPt ) const
1134 {
1135     if( GetLayout() )
1136         return 0 != GetLayout()->GetPageAtPos( rPt );
1137     return sal_False;
1138 }
1139 
GetContentAtPos(const Point & rPt,SwContentAtPos & rCntntAtPos,sal_Bool bSetCrsr,SwRect * pFldRect)1140 sal_Bool SwCrsrShell::GetContentAtPos( const Point& rPt,
1141                                    SwContentAtPos& rCntntAtPos,
1142                                    sal_Bool bSetCrsr,
1143                                    SwRect* pFldRect )
1144 {
1145     SET_CURR_SHELL( this );
1146     sal_Bool bRet = sal_False;
1147 
1148     if( !IsTableMode() )
1149     {
1150         Point aPt( rPt );
1151         SwPosition aPos( *pCurCrsr->GetPoint() );
1152 
1153         SwTxtNode* pTxtNd;
1154         SwCntntFrm *pFrm(0);
1155         SwTxtAttr* pTxtAttr;
1156         SwCrsrMoveState aTmpState;
1157         aTmpState.bFieldInfo = sal_True;
1158         aTmpState.bExactOnly = !( SwContentAtPos::SW_OUTLINE & rCntntAtPos.eCntntAtPos );
1159         aTmpState.bCntntCheck = (SwContentAtPos::SW_CONTENT_CHECK & rCntntAtPos.eCntntAtPos) ?  sal_True : sal_False;
1160         aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1161 
1162         SwSpecialPos aSpecialPos;
1163         aTmpState.pSpecialPos = ( SwContentAtPos::SW_SMARTTAG & rCntntAtPos.eCntntAtPos ) ?
1164                                 &aSpecialPos : 0;
1165 
1166         const sal_Bool bCrsrFoundExact = GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState );
1167         pTxtNd = aPos.nNode.GetNode().GetTxtNode();
1168 
1169         const SwNodes& rNds = GetDoc()->GetNodes();
1170         if( pTxtNd
1171             && SwContentAtPos::SW_OUTLINE & rCntntAtPos.eCntntAtPos
1172             && rNds.GetOutLineNds().Count() )
1173         {
1174             const SwTxtNode* pONd = pTxtNd->FindOutlineNodeOfLevel( MAXLEVEL-1);
1175             if( pONd )
1176             {
1177                 rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_OUTLINE;
1178                 rCntntAtPos.sStr = pONd->GetExpandTxt( 0, STRING_LEN, true );
1179                 bRet = sal_True;
1180             }
1181         }
1182         else if ( SwContentAtPos::SW_CONTENT_CHECK & rCntntAtPos.eCntntAtPos
1183                   && bCrsrFoundExact )
1184         {
1185             bRet = sal_True;
1186         }
1187         else if( pTxtNd
1188                  && SwContentAtPos::SW_NUMLABEL & rCntntAtPos.eCntntAtPos)
1189         {
1190             bRet = aTmpState.bInNumPortion;
1191             rCntntAtPos.aFnd.pNode = pTxtNd;
1192 
1193             Size aSizeLogic(aTmpState.nInNumPostionOffset, 0);
1194             Size aSizePixel = GetWin()->LogicToPixel(aSizeLogic);
1195             rCntntAtPos.nDist = aSizePixel.Width();
1196         }
1197         else if( bCrsrFoundExact && pTxtNd )
1198         {
1199             if( !aTmpState.bPosCorr )
1200             {
1201                 if ( !bRet
1202                      && SwContentAtPos::SW_SMARTTAG & rCntntAtPos.eCntntAtPos
1203                      && !aTmpState.bFtnNoInfo )
1204                 {
1205                     const SwWrongList* pSmartTagList = pTxtNd->GetSmartTags();
1206                     xub_StrLen nCurrent = aPos.nContent.GetIndex();
1207                     xub_StrLen nBegin = nCurrent;
1208                     xub_StrLen nLen = 1;
1209 
1210                     if ( pSmartTagList && pSmartTagList->InWrongWord( nCurrent, nLen ) && !pTxtNd->IsSymbol(nBegin) )
1211                     {
1212                         const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
1213                         const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
1214                         if ( pSubList )
1215                         {
1216                             nCurrent = aTmpState.pSpecialPos->nCharOfst;
1217 
1218                             if ( pSubList->InWrongWord( nCurrent, nLen ) )
1219                                 bRet = sal_True;
1220                         }
1221                         else
1222                             bRet = sal_True;
1223 
1224                         if( bRet && bSetCrsr )
1225                         {
1226                             SwCrsrSaveState aSaveState( *pCurCrsr );
1227                             SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1228                             pCurCrsr->DeleteMark();
1229                             *pCurCrsr->GetPoint() = aPos;
1230                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE) )
1231                                 bRet = sal_False;
1232                             else
1233                                 UpdateCrsr();
1234                         }
1235                         if( bRet )
1236                         {
1237                             rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_SMARTTAG;
1238 
1239                             if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1240                                 pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1241                         }
1242                     }
1243                 }
1244 
1245                 if ( !bRet
1246                      && ( SwContentAtPos::SW_FIELD | SwContentAtPos::SW_CLICKFIELD ) & rCntntAtPos.eCntntAtPos
1247                      && !aTmpState.bFtnNoInfo )
1248                 {
1249                     pTxtAttr = pTxtNd->GetFldTxtAttrAt( aPos.nContent.GetIndex() );
1250                     const SwField* pFld = pTxtAttr != NULL
1251                                           ? pTxtAttr->GetFmtFld().GetField()
1252                                           : 0;
1253                     if ( SwContentAtPos::SW_CLICKFIELD & rCntntAtPos.eCntntAtPos
1254                          && pFld && !pFld->HasClickHdl() )
1255                     {
1256                         pFld = 0;
1257                     }
1258 
1259                     if ( pFld )
1260                     {
1261                         if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1262                             pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1263 
1264                         if( bSetCrsr )
1265                         {
1266                             SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1267                             SwCrsrSaveState aSaveState( *pCurCrsr );
1268                             pCurCrsr->DeleteMark();
1269                             *pCurCrsr->GetPoint() = aPos;
1270                             if( pCurCrsr->IsSelOvr() )
1271                             {
1272                                 // Click-Felder in geschuetzten Bereichen zulassen
1273                                 // Nur Platzhalter geht nicht!
1274                                 if( SwContentAtPos::SW_FIELD & rCntntAtPos.eCntntAtPos
1275                                     || RES_JUMPEDITFLD == pFld->Which() )
1276                                     pFld = 0;
1277                             }
1278                             else
1279                                 UpdateCrsr();
1280                         }
1281                         else if( RES_TABLEFLD == pFld->Which() &&
1282                             ((SwTblField*)pFld)->IsIntrnlName() )
1283                         {
1284                             // erzeuge aus der internen (fuer CORE)
1285                             // die externe (fuer UI) Formel
1286                             const SwTableNode* pTblNd = pTxtNd->FindTableNode();
1287                             if( pTblNd )		// steht in einer Tabelle
1288                                 ((SwTblField*)pFld)->PtrToBoxNm( &pTblNd->GetTable() );
1289                         }
1290                     }
1291 
1292                     if( pFld )
1293                     {
1294                         rCntntAtPos.aFnd.pFld = pFld;
1295                         rCntntAtPos.pFndTxtAttr = pTxtAttr;
1296                         rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FIELD;
1297                         bRet = sal_True;
1298                     }
1299                 }
1300 
1301                 if( !bRet && SwContentAtPos::SW_FORMCTRL & rCntntAtPos.eCntntAtPos )
1302                 {
1303                     IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess( );
1304                     sw::mark::IFieldmark* pFldBookmark = pMarksAccess->getFieldmarkFor( aPos );
1305                     if( bCrsrFoundExact && pTxtNd && pFldBookmark) {
1306                         rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FORMCTRL;
1307                         rCntntAtPos.aFnd.pFldmark = pFldBookmark;
1308                         bRet=sal_True;
1309                     }
1310                 }
1311 
1312                 if( !bRet && SwContentAtPos::SW_FTN & rCntntAtPos.eCntntAtPos )
1313                 {
1314                     if( aTmpState.bFtnNoInfo )
1315                     {
1316                         // stehe ueber dem Zeichen der Fussnote (??)
1317                         bRet = sal_True;
1318                         if( bSetCrsr )
1319                         {
1320                             *pCurCrsr->GetPoint() = aPos;
1321                             if( !GotoFtnAnchor() )
1322                                 bRet = sal_False;
1323                         }
1324                         if( bRet )
1325                             rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN;
1326                     }
1327                     else if ( 0 != ( pTxtAttr = pTxtNd->GetTxtAttrForCharAt(
1328                         aPos.nContent.GetIndex(), RES_TXTATR_FTN )) )
1329                     {
1330                         bRet = sal_True;
1331                         if( bSetCrsr )
1332                         {
1333                             SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
1334                             SwCrsrSaveState aSaveState( *pCurCrsr );
1335                             pCurCrsr->GetPoint()->nNode = *((SwTxtFtn*)pTxtAttr)->GetStartNode();
1336                             SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection(
1337                                 &pCurCrsr->GetPoint()->nNode,
1338                                 sal_True, !IsReadOnlyAvailable() );
1339 
1340                             if( pCNd )
1341                             {
1342                                 pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
1343                                 if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1344                                     nsSwCursorSelOverFlags::SELOVER_TOGGLE ))
1345                                     bRet = sal_False;
1346                                 else
1347                                     UpdateCrsr();
1348                             }
1349                             else
1350                                 bRet = sal_False;
1351                         }
1352 
1353                         if( bRet )
1354                         {
1355                             rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN;
1356                             rCntntAtPos.pFndTxtAttr = pTxtAttr;
1357                             rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr();
1358 
1359                             if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1360                                 pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1361                         }
1362                     }
1363                 }
1364 
1365                 if( !bRet
1366                     && ( SwContentAtPos::SW_TOXMARK | SwContentAtPos::SW_REFMARK ) & rCntntAtPos.eCntntAtPos
1367                     && !aTmpState.bFtnNoInfo )
1368                 {
1369                     pTxtAttr = 0;
1370                     if( SwContentAtPos::SW_TOXMARK & rCntntAtPos.eCntntAtPos )
1371                     {
1372                         ::std::vector<SwTxtAttr *> const marks(
1373                             pTxtNd->GetTxtAttrsAt(
1374                                aPos.nContent.GetIndex(), RES_TXTATR_TOXMARK));
1375                         if (marks.size())
1376                         {   // hmm... can only return 1 here
1377                             pTxtAttr = *marks.begin();
1378                         }
1379                     }
1380 
1381                     if( !pTxtAttr &&
1382                         SwContentAtPos::SW_REFMARK & rCntntAtPos.eCntntAtPos )
1383                     {
1384                         ::std::vector<SwTxtAttr *> const marks(
1385                             pTxtNd->GetTxtAttrsAt(
1386                                aPos.nContent.GetIndex(), RES_TXTATR_REFMARK));
1387                         if (marks.size())
1388                         {   // hmm... can only return 1 here
1389                             pTxtAttr = *marks.begin();
1390                         }
1391                     }
1392 
1393                     if( pTxtAttr )
1394                     {
1395                         bRet = sal_True;
1396                         if( bSetCrsr )
1397                         {
1398                             SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
1399                             SwCrsrSaveState aSaveState( *pCurCrsr );
1400                             pCurCrsr->DeleteMark();
1401                             *pCurCrsr->GetPoint() = aPos;
1402                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE ) )
1403                                 bRet = sal_False;
1404                             else
1405                                 UpdateCrsr();
1406                         }
1407 
1408                         if( bRet )
1409                         {
1410                             const xub_StrLen* pEnd = pTxtAttr->End();
1411                             if( pEnd )
1412                                 rCntntAtPos.sStr =
1413                                     pTxtNd->GetExpandTxt( *pTxtAttr->GetStart(), *pEnd - *pTxtAttr->GetStart() );
1414                             else if( RES_TXTATR_TOXMARK == pTxtAttr->Which())
1415                                 rCntntAtPos.sStr =
1416                                     pTxtAttr->GetTOXMark().GetAlternativeText();
1417 
1418                             rCntntAtPos.eCntntAtPos =
1419                                 RES_TXTATR_TOXMARK == pTxtAttr->Which()
1420                                 ? SwContentAtPos::SW_TOXMARK
1421                                 : SwContentAtPos::SW_REFMARK;
1422                             rCntntAtPos.pFndTxtAttr = pTxtAttr;
1423                             rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr();
1424 
1425                             if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1426                                 pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1427                         }
1428                     }
1429                 }
1430 
1431                 if ( !bRet
1432                      && SwContentAtPos::SW_INETATTR & rCntntAtPos.eCntntAtPos
1433                      && !aTmpState.bFtnNoInfo )
1434                 {
1435                     pTxtAttr = pTxtNd->GetTxtAttrAt(
1436                             aPos.nContent.GetIndex(), RES_TXTATR_INETFMT);
1437                     // nur INetAttrs mit URLs "erkennen"
1438                     if( pTxtAttr && pTxtAttr->GetINetFmt().GetValue().Len() )
1439                     {
1440                         bRet = sal_True;
1441                         if( bSetCrsr )
1442                         {
1443                             SwCrsrSaveState aSaveState( *pCurCrsr );
1444                             SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1445                             pCurCrsr->DeleteMark();
1446                             *pCurCrsr->GetPoint() = aPos;
1447                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1448                                 nsSwCursorSelOverFlags::SELOVER_TOGGLE) )
1449                                 bRet = sal_False;
1450                             else
1451                                 UpdateCrsr();
1452                         }
1453                         if( bRet )
1454                         {
1455                             rCntntAtPos.sStr = pTxtNd->GetExpandTxt(
1456                                 *pTxtAttr->GetStart(),
1457                                 *pTxtAttr->GetEnd() - *pTxtAttr->GetStart() );
1458 
1459                             rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr();
1460                             rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_INETATTR;
1461                             rCntntAtPos.pFndTxtAttr = pTxtAttr;
1462 
1463                             if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1464                                 pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1465                         }
1466                     }
1467                 }
1468 
1469                 if( !bRet && SwContentAtPos::SW_REDLINE & rCntntAtPos.eCntntAtPos )
1470                 {
1471                     const SwRedline* pRedl = GetDoc()->GetRedline(aPos, NULL);
1472                     if( pRedl )
1473                     {
1474                         rCntntAtPos.aFnd.pRedl = pRedl;
1475                         rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE;
1476                         rCntntAtPos.pFndTxtAttr = 0;
1477                         bRet = sal_True;
1478 
1479                         if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) )
1480                             pFrm->GetCharRect( *pFldRect, aPos, &aTmpState );
1481                     }
1482                 }
1483             }
1484 
1485             if( !bRet
1486                  && ( SwContentAtPos::SW_TABLEBOXFML & rCntntAtPos.eCntntAtPos
1487 #ifdef DBG_UTIL
1488                       || SwContentAtPos::SW_TABLEBOXVALUE & rCntntAtPos.eCntntAtPos
1489 #endif
1490                 ) )
1491             {
1492                 const SwTableNode* pTblNd;
1493                 const SwTableBox* pBox;
1494                 const SwStartNode* pSttNd = pTxtNd->FindTableBoxStartNode();
1495                 const SfxPoolItem* pItem;
1496                 if( pSttNd && 0 != ( pTblNd = pTxtNd->FindTableNode()) &&
1497                     0 != ( pBox = pTblNd->GetTable().GetTblBox(
1498                     pSttNd->GetIndex() )) &&
1499 #ifdef DBG_UTIL
1500                     ( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
1501                     RES_BOXATR_FORMULA, sal_False, &pItem )	||
1502                     SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
1503                     RES_BOXATR_VALUE, sal_False, &pItem ))
1504 #else
1505                     SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
1506                     RES_BOXATR_FORMULA, sal_False, &pItem )
1507 #endif
1508                     )
1509                 {
1510                     SwFrm* pF = pTxtNd->getLayoutFrm( GetLayout(), &aPt );
1511                     if( pF )
1512                     {
1513                         // dann aber den CellFrame
1514                         pFrm = (SwCntntFrm*)pF;
1515                         while( pF && !pF->IsCellFrm() )
1516                             pF = pF->GetUpper();
1517                     }
1518 
1519                     // es wurde ein
1520                     if( aTmpState.bPosCorr )
1521                     {
1522                         if( pF && !pF->Frm().IsInside( aPt ))
1523                             pF = 0;
1524                     }
1525                     else if( !pF )
1526                         pF = pFrm;
1527 
1528                     if( pF )			// nur dann ist es gueltig!!
1529                     {
1530                         // erzeuge aus der internen (fuer CORE)
1531                         // die externe (fuer UI) Formel
1532                         rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXFML;
1533 #ifdef DBG_UTIL
1534                         if( RES_BOXATR_VALUE == pItem->Which() )
1535                             rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXVALUE;
1536                         else
1537 #endif
1538                             ((SwTblBoxFormula*)pItem)->PtrToBoxNm( &pTblNd->GetTable() );
1539 
1540                         bRet = sal_True;
1541                         if( bSetCrsr )
1542                         {
1543                             SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
1544                             SwCrsrSaveState aSaveState( *pCurCrsr );
1545                             *pCurCrsr->GetPoint() = aPos;
1546                             if( pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
1547                                 nsSwCursorSelOverFlags::SELOVER_TOGGLE) )
1548                                 bRet = sal_False;
1549                             else
1550                                 UpdateCrsr();
1551                         }
1552 
1553                         if( bRet )
1554                         {
1555                             if( pFldRect )
1556                             {
1557                                 *pFldRect = pF->Prt();
1558                                 *pFldRect += pF->Frm().Pos();
1559                             }
1560                             rCntntAtPos.pFndTxtAttr = 0;
1561                             rCntntAtPos.aFnd.pAttr = pItem;
1562                         }
1563                     }
1564                 }
1565             }
1566 
1567 #ifdef DBG_UTIL
1568             if( !bRet && SwContentAtPos::SW_CURR_ATTRS & rCntntAtPos.eCntntAtPos )
1569             {
1570                 xub_StrLen n = aPos.nContent.GetIndex();
1571                 SfxItemSet aSet( GetDoc()->GetAttrPool(), POOLATTR_BEGIN,
1572                     POOLATTR_END - 1 );
1573                 if( pTxtNd->GetpSwpHints() )
1574                 {
1575                     for( sal_uInt16 i = 0; i < pTxtNd->GetSwpHints().Count(); ++i )
1576                     {
1577                         const SwTxtAttr* pHt = pTxtNd->GetSwpHints()[i];
1578                         xub_StrLen nAttrStart = *pHt->GetStart();
1579                         if( nAttrStart > n ) 		// ueber den Bereich hinaus
1580                             break;
1581 
1582                         if( 0 != pHt->End() && (
1583                             ( nAttrStart < n &&
1584                             ( pHt->DontExpand() ? n < *pHt->End()
1585                             : n <= *pHt->End() )) ||
1586                             ( n == nAttrStart &&
1587                             ( nAttrStart == *pHt->End() || !n ))) )
1588                         {
1589                             aSet.Put( pHt->GetAttr() );
1590                         }
1591                     }
1592                     if( pTxtNd->HasSwAttrSet() &&
1593                         pTxtNd->GetpSwAttrSet()->Count() )
1594                     {
1595                         SfxItemSet aFmtSet( pTxtNd->GetSwAttrSet() );
1596                         // aus dem Format-Set alle entfernen, die im TextSet auch gesetzt sind
1597                         aFmtSet.Differentiate( aSet );
1598                         // jetzt alle zusammen "mergen"
1599                         aSet.Put( aFmtSet );
1600                     }
1601                 }
1602                 else
1603                     pTxtNd->SwCntntNode::GetAttr( aSet );
1604 
1605                 rCntntAtPos.sStr.AssignAscii(
1606                     RTL_CONSTASCII_STRINGPARAM( "Pos: (" ));
1607                 rCntntAtPos.sStr += String::CreateFromInt32( aPos.nNode.GetIndex());
1608                 rCntntAtPos.sStr += ':';
1609                 rCntntAtPos.sStr += String::CreateFromInt32( aPos.nContent.GetIndex());
1610                 rCntntAtPos.sStr += ')';
1611                 rCntntAtPos.sStr.AppendAscii(
1612                     RTL_CONSTASCII_STRINGPARAM( "\nAbs.Vorl.: " ));
1613                 rCntntAtPos.sStr += pTxtNd->GetFmtColl()->GetName();
1614                 if( pTxtNd->GetCondFmtColl() )
1615                     rCntntAtPos.sStr.AppendAscii(
1616                     RTL_CONSTASCII_STRINGPARAM( "\nBed.Vorl.: " ))
1617                     += pTxtNd->GetCondFmtColl()->GetName();
1618 
1619                 if( aSet.Count() )
1620                 {
1621                     String sAttrs;
1622                     SfxItemIter aIter( aSet );
1623                     const SfxPoolItem* pItem = aIter.FirstItem();
1624                     while( sal_True )
1625                     {
1626                         if( !IsInvalidItem( pItem ))
1627                         {
1628                             String aStr;
1629                             GetDoc()->GetAttrPool().GetPresentation( *pItem,
1630                                 SFX_ITEM_PRESENTATION_COMPLETE,
1631                                 SFX_MAPUNIT_CM, aStr );
1632                             if( sAttrs.Len() )
1633                                 sAttrs.AppendAscii(
1634                                 RTL_CONSTASCII_STRINGPARAM( ", " ));
1635                             sAttrs += aStr;
1636                         }
1637                         if( aIter.IsAtEnd() )
1638                             break;
1639                         pItem = aIter.NextItem();
1640                     }
1641                     if( sAttrs.Len() )
1642                     {
1643                         if( rCntntAtPos.sStr.Len() )
1644                             rCntntAtPos.sStr += '\n';
1645                         rCntntAtPos.sStr.AppendAscii(
1646                             RTL_CONSTASCII_STRINGPARAM( "Attr: " ) )
1647                             += sAttrs;
1648                     }
1649                 }
1650                 bRet = sal_True;
1651                 rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_CURR_ATTRS;
1652             }
1653 #endif
1654         }
1655     }
1656 
1657     if( !bRet )
1658     {
1659         rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_NOTHING;
1660         rCntntAtPos.aFnd.pFld = 0;
1661     }
1662     return bRet;
1663 }
1664 
GetPostItFieldAtCursor() const1665 const SwPostItField* SwCrsrShell::GetPostItFieldAtCursor() const
1666 {
1667     const SwPostItField* pPostItFld = 0;
1668 
1669     if ( !IsTableMode() )
1670     {
1671         const SwPosition* pCursorPos = _GetCrsr()->GetPoint();
1672         const SwTxtNode* pTxtNd = pCursorPos->nNode.GetNode().GetTxtNode();
1673         if ( pTxtNd )
1674         {
1675             SwTxtAttr* pTxtAttr = pTxtNd->GetFldTxtAttrAt( pCursorPos->nContent.GetIndex() );
1676             const SwField* pFld = pTxtAttr != NULL ? pTxtAttr->GetFmtFld().GetField() : 0;
1677             if ( pFld && pFld->Which()== RES_POSTITFLD )
1678             {
1679                 pPostItFld = static_cast<const SwPostItField*>(pFld);
1680             }
1681         }
1682     }
1683 
1684     return pPostItFld;
1685 }
1686 
1687 // befindet sich der Node in einem geschuetzten Bereich?
IsInProtectSect() const1688 sal_Bool SwContentAtPos::IsInProtectSect() const
1689 {
1690 	const SwTxtNode* pNd = 0;
1691 	if( pFndTxtAttr )
1692 	{
1693 		switch( eCntntAtPos )
1694 		{
1695 		case SW_FIELD:
1696 		case SW_CLICKFIELD:
1697 			pNd = ((SwTxtFld*)pFndTxtAttr)->GetpTxtNode();
1698 			break;
1699 
1700 		case SW_FTN:
1701 			pNd = &((SwTxtFtn*)pFndTxtAttr)->GetTxtNode();
1702 			break;
1703 
1704 		case SW_INETATTR:
1705 			pNd = ((SwTxtINetFmt*)pFndTxtAttr)->GetpTxtNode();
1706 			break;
1707 
1708 		default:
1709 			break;
1710 		}
1711 	}
1712 
1713 	const SwCntntFrm* pFrm;
1714 	return pNd && ( pNd->IsInProtectSect() ||
1715 					( 0 != ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), 0,0,sal_False)) &&
1716 						pFrm->IsProtected() ));
1717 }
1718 
IsInRTLText() const1719 bool SwContentAtPos::IsInRTLText()const
1720 {
1721     bool bRet = false;
1722     const SwTxtNode* pNd = 0;
1723     if (pFndTxtAttr && (eCntntAtPos == SW_FTN))
1724     {
1725         const SwTxtFtn* pTxtFtn = static_cast<const SwTxtFtn*>(pFndTxtAttr);
1726         if(pTxtFtn->GetStartNode())
1727         {
1728             SwStartNode* pSttNd = pTxtFtn->GetStartNode()->GetNode().GetStartNode();
1729             SwPaM aTemp( *pSttNd );
1730             aTemp.Move(fnMoveForward, fnGoNode);
1731             SwCntntNode* pCntntNode = aTemp.GetCntntNode();
1732             if(pCntntNode && pCntntNode->IsTxtNode())
1733                 pNd = static_cast<SwTxtNode*>(pCntntNode);
1734         }
1735     }
1736     if(pNd)
1737     {
1738         SwIterator<SwTxtFrm,SwTxtNode> aIter(*pNd);
1739         SwTxtFrm* pTmpFrm = aIter.First();
1740         while( pTmpFrm )
1741         {
1742                 if ( !pTmpFrm->IsFollow())
1743                 {
1744                     bRet = pTmpFrm->IsRightToLeft();
1745                     break;
1746                 }
1747             pTmpFrm = aIter.Next();
1748         }
1749     }
1750     return bRet;
1751 }
1752 
1753 
SelectTxt(const xub_StrLen nStart,const xub_StrLen nEnd)1754 sal_Bool SwCrsrShell::SelectTxt( const xub_StrLen nStart,
1755                                  const xub_StrLen nEnd )
1756 {
1757     SET_CURR_SHELL( this );
1758     sal_Bool bRet = sal_False;
1759 
1760     SwCallLink aLk( *this );
1761     SwCrsrSaveState aSaveState( *pCurCrsr );
1762 
1763     SwPosition& rPos = *pCurCrsr->GetPoint();
1764     pCurCrsr->DeleteMark();
1765     rPos.nContent = nStart;
1766     pCurCrsr->SetMark();
1767     rPos.nContent = nEnd;
1768 
1769     if( !pCurCrsr->IsSelOvr() )
1770     {
1771         UpdateCrsr();
1772         bRet = sal_True;
1773     }
1774 
1775     return bRet;
1776 }
1777 
1778 
SelectTxtAttr(sal_uInt16 nWhich,sal_Bool bExpand,const SwTxtAttr * pTxtAttr)1779 sal_Bool SwCrsrShell::SelectTxtAttr( sal_uInt16 nWhich,
1780                                      sal_Bool bExpand,
1781                                      const SwTxtAttr* pTxtAttr )
1782 {
1783     SET_CURR_SHELL( this );
1784     sal_Bool bRet = sal_False;
1785 
1786     if( !IsTableMode() )
1787     {
1788         if( !pTxtAttr )
1789         {
1790             SwPosition& rPos = *pCurCrsr->GetPoint();
1791             SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
1792             pTxtAttr = (pTxtNd)
1793                 ? pTxtNd->GetTxtAttrAt(rPos.nContent.GetIndex(),
1794                         static_cast<RES_TXTATR>(nWhich),
1795                         (bExpand) ? SwTxtNode::EXPAND : SwTxtNode::DEFAULT)
1796                 : 0;
1797         }
1798 
1799         if( pTxtAttr )
1800         {
1801             const xub_StrLen* pEnd = pTxtAttr->End();
1802             bRet = SelectTxt( *pTxtAttr->GetStart(), ( pEnd ? *pEnd : *pTxtAttr->GetStart() + 1 ) );
1803         }
1804     }
1805     return bRet;
1806 }
1807 
1808 
GotoINetAttr(const SwTxtINetFmt & rAttr)1809 sal_Bool SwCrsrShell::GotoINetAttr( const SwTxtINetFmt& rAttr )
1810 {
1811 	sal_Bool bRet = sal_False;
1812 	if( rAttr.GetpTxtNode() )
1813 	{
1814 		SwCursor* pCrsr = getShellCrsr( true );
1815 
1816 		SET_CURR_SHELL( this );
1817 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1818 		SwCrsrSaveState aSaveState( *pCrsr );
1819 
1820 		pCrsr->GetPoint()->nNode = *rAttr.GetpTxtNode();
1821 		pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)rAttr.GetpTxtNode(),
1822 											*rAttr.GetStart() );
1823 		bRet = !pCrsr->IsSelOvr();
1824 		if( bRet )
1825 			UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1826 	}
1827 	return bRet;
1828 }
1829 
1830 
FindINetAttr(const String & rName) const1831 const SwFmtINetFmt* SwCrsrShell::FindINetAttr( const String& rName ) const
1832 {
1833 	return pDoc->FindINetAttr( rName );
1834 }
1835 
GetShadowCrsrPos(const Point & rPt,SwFillMode eFillMode,SwRect & rRect,sal_Int16 & rOrient)1836 sal_Bool SwCrsrShell::GetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode,
1837                                 SwRect& rRect, sal_Int16& rOrient )
1838 {
1839 
1840 	SET_CURR_SHELL( this );
1841 	sal_Bool bRet = sal_False;
1842 
1843     if (!IsTableMode() && !HasSelection()
1844         && GetDoc()->GetIDocumentUndoRedo().DoesUndo())
1845     {
1846 		Point aPt( rPt );
1847 		SwPosition aPos( *pCurCrsr->GetPoint() );
1848 
1849 		SwFillCrsrPos aFPos( eFillMode );
1850 		SwCrsrMoveState aTmpState( &aFPos );
1851 
1852 		if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) &&
1853 			!aPos.nNode.GetNode().IsProtect())
1854 		{
1855 			// Start-Position im geschuetzten Bereich?
1856 			rRect = aFPos.aCrsr;
1857 			rOrient = aFPos.eOrient;
1858 			bRet = sal_True;
1859 		}
1860 	}
1861 	return bRet;
1862 }
1863 
SetShadowCrsrPos(const Point & rPt,SwFillMode eFillMode)1864 sal_Bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode )
1865 {
1866 	SET_CURR_SHELL( this );
1867 	sal_Bool bRet = sal_False;
1868 
1869     if (!IsTableMode() && !HasSelection()
1870         && GetDoc()->GetIDocumentUndoRedo().DoesUndo())
1871 	{
1872 		Point aPt( rPt );
1873 		SwPosition aPos( *pCurCrsr->GetPoint() );
1874 
1875 		SwFillCrsrPos aFPos( eFillMode );
1876 		SwCrsrMoveState aTmpState( &aFPos );
1877 
1878 		if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) )
1879 		{
1880 			SwCallLink aLk( *this );        // Crsr-Moves ueberwachen
1881 			StartAction();
1882 
1883 			SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
1884             SwUndoId nUndoId = UNDO_INS_FROM_SHADOWCRSR;
1885 			// Werden nur die Absatzattribute Adjust oder LRSpace gesetzt,
1886 			// dann sollte der naechste Aufruf die NICHT wieder entfernen.
1887 			if( 0 == aFPos.nParaCnt + aFPos.nColumnCnt &&
1888 				( FILL_INDENT == aFPos.eMode ||
1889                   ( text::HoriOrientation::NONE != aFPos.eOrient &&
1890 					0 == aFPos.nTabCnt + aFPos.nSpaceCnt )) &&
1891 				pCNd && pCNd->Len() )
1892                 nUndoId = UNDO_EMPTY;
1893 
1894             GetDoc()->GetIDocumentUndoRedo().StartUndo( nUndoId, NULL );
1895 
1896 			SwTxtFmtColl* pNextFmt = 0;
1897 			SwTxtNode* pTNd = pCNd->GetTxtNode();
1898 			if( pTNd )
1899 				pNextFmt = &pTNd->GetTxtColl()->GetNextTxtFmtColl();
1900 
1901 			const SwSectionNode* pSectNd = pCNd->FindSectionNode();
1902 			if( pSectNd && aFPos.nParaCnt )
1903 			{
1904 				SwNodeIndex aEnd( aPos.nNode, 1 );
1905 				while( aEnd.GetNode().IsEndNode() &&
1906 						(const SwNode*)&aEnd.GetNode() !=
1907 						pSectNd->EndOfSectionNode() )
1908 					aEnd++;
1909 
1910 				if( aEnd.GetNode().IsEndNode() &&
1911 					pCNd->Len() == aPos.nContent.GetIndex() )
1912 					aPos.nNode = *pSectNd->EndOfSectionNode();
1913 			}
1914 
1915 			for( sal_uInt16 n = 0; n < aFPos.nParaCnt + aFPos.nColumnCnt; ++n )
1916 			{
1917 				GetDoc()->AppendTxtNode( aPos );
1918 				if( !n && pNextFmt )
1919 				{
1920 					*pCurCrsr->GetPoint() = aPos;
1921                     GetDoc()->SetTxtFmtColl( *pCurCrsr, pNextFmt, false );
1922 					//JP 04.11.97: erstmal keine Folgevorlage der
1923 					//				Folgevorlage beachten
1924 					// pNextFmt = pNextFmt->GetNextTxtFmtColl();
1925 				}
1926 				if( n < aFPos.nColumnCnt )
1927 				{
1928 					*pCurCrsr->GetPoint() = aPos;
1929                     GetDoc()->InsertPoolItem( *pCurCrsr,
1930                             SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0);
1931 				}
1932 			}
1933 
1934 			*pCurCrsr->GetPoint() = aPos;
1935 			switch( aFPos.eMode )
1936 			{
1937 			case FILL_INDENT:
1938 				if( 0 != (pCNd = aPos.nNode.GetNode().GetCntntNode() ))
1939 				{
1940 					SfxItemSet aSet( GetDoc()->GetAttrPool(),
1941 									RES_LR_SPACE, RES_LR_SPACE,
1942 									RES_PARATR_ADJUST, RES_PARATR_ADJUST,
1943 									0 );
1944 					SvxLRSpaceItem aLR( (SvxLRSpaceItem&)
1945 										pCNd->GetAttr( RES_LR_SPACE ) );
1946 					aLR.SetTxtLeft( aFPos.nTabCnt );
1947 					aLR.SetTxtFirstLineOfst( 0 );
1948 					aSet.Put( aLR );
1949 
1950 					const SvxAdjustItem& rAdj = (SvxAdjustItem&)pCNd->
1951 										GetAttr( RES_PARATR_ADJUST );
1952 					if( SVX_ADJUST_LEFT != rAdj.GetAdjust() )
1953                         aSet.Put( SvxAdjustItem( SVX_ADJUST_LEFT, RES_PARATR_ADJUST ) );
1954 
1955                     GetDoc()->InsertItemSet( *pCurCrsr, aSet, 0 );
1956                 }
1957 				else {
1958 					ASSERT( sal_False, "where is my CntntNode?" );
1959                 }
1960 				break;
1961 
1962 			case FILL_TAB:
1963 			case FILL_SPACE:
1964 				{
1965 					String sInsert;
1966 					if( aFPos.nTabCnt )
1967 						sInsert.Fill( aFPos.nTabCnt, '\t' );
1968 					if( aFPos.nSpaceCnt )
1969 					{
1970 						String sSpace;
1971 						sSpace.Fill( aFPos.nSpaceCnt );
1972 						sInsert += sSpace;
1973 					}
1974 					if( sInsert.Len() )
1975                     {
1976                         GetDoc()->InsertString( *pCurCrsr, sInsert );
1977                     }
1978 				}
1979 				// kein break - Ausrichtung muss noch gesetzt werden
1980 			case FILL_MARGIN:
1981                 if( text::HoriOrientation::NONE != aFPos.eOrient )
1982 				{
1983                     SvxAdjustItem aAdj( SVX_ADJUST_LEFT, RES_PARATR_ADJUST );
1984 					switch( aFPos.eOrient )
1985 					{
1986                     case text::HoriOrientation::CENTER:
1987 						aAdj.SetAdjust( SVX_ADJUST_CENTER );
1988 						break;
1989                     case text::HoriOrientation::RIGHT:
1990 						aAdj.SetAdjust( SVX_ADJUST_RIGHT );
1991 						break;
1992 					default:
1993 						break;
1994 					}
1995                     GetDoc()->InsertPoolItem( *pCurCrsr, aAdj, 0 );
1996 				}
1997 				break;
1998 			}
1999 
2000             GetDoc()->GetIDocumentUndoRedo().EndUndo( nUndoId, NULL );
2001 			EndAction();
2002 
2003 			bRet = sal_True;
2004 		}
2005 	}
2006 	return bRet;
2007 }
2008 
SelNextRedline()2009 const SwRedline* SwCrsrShell::SelNextRedline()
2010 {
2011 	const SwRedline* pFnd = 0;
2012 	if( !IsTableMode() )
2013 	{
2014 		SET_CURR_SHELL( this );
2015 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
2016 		SwCrsrSaveState aSaveState( *pCurCrsr );
2017 
2018 		pFnd = GetDoc()->SelNextRedline( *pCurCrsr );
2019 		if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
2020 			UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
2021 		else
2022 			pFnd = 0;
2023 	}
2024 	return pFnd;
2025 }
2026 
SelPrevRedline()2027 const SwRedline* SwCrsrShell::SelPrevRedline()
2028 {
2029 	const SwRedline* pFnd = 0;
2030 	if( !IsTableMode() )
2031 	{
2032 		SET_CURR_SHELL( this );
2033 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
2034 		SwCrsrSaveState aSaveState( *pCurCrsr );
2035 
2036 		pFnd = GetDoc()->SelPrevRedline( *pCurCrsr );
2037 		if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
2038 			UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
2039 		else
2040 			pFnd = 0;
2041 	}
2042 	return pFnd;
2043 }
2044 
_GotoRedline(sal_uInt16 nArrPos,sal_Bool bSelect)2045 const SwRedline* SwCrsrShell::_GotoRedline( sal_uInt16 nArrPos, sal_Bool bSelect )
2046 {
2047 	const SwRedline* pFnd = 0;
2048 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
2049 	SwCrsrSaveState aSaveState( *pCurCrsr );
2050 
2051 	pFnd = GetDoc()->GetRedlineTbl()[ nArrPos ];
2052 	if( pFnd )
2053 	{
2054 		*pCurCrsr->GetPoint() = *pFnd->Start();
2055 
2056 		SwCntntNode* pCNd;
2057 		SwNodeIndex* pIdx = &pCurCrsr->GetPoint()->nNode;
2058 		if( !pIdx->GetNode().IsCntntNode() &&
2059 			0 != ( pCNd = GetDoc()->GetNodes().GoNextSection( pIdx,
2060 									sal_True, IsReadOnlyAvailable() )) )
2061 		{
2062 			if( *pIdx <= pFnd->End()->nNode )
2063 				pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
2064 			else
2065 				pFnd = 0;
2066 		}
2067 
2068 		if( pFnd && bSelect )
2069 		{
2070 			pCurCrsr->SetMark();
2071 			if( nsRedlineType_t::REDLINE_FMTCOLL == pFnd->GetType() )
2072 			{
2073 				pCNd = pIdx->GetNode().GetCntntNode();
2074 				pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
2075 				pCurCrsr->GetMark()->nContent.Assign( pCNd, 0 );
2076 			}
2077 			else
2078 				*pCurCrsr->GetPoint() = *pFnd->End();
2079 
2080 			pIdx = &pCurCrsr->GetPoint()->nNode;
2081 			if( !pIdx->GetNode().IsCntntNode() &&
2082 				0 != ( pCNd = GetDoc()->GetNodes().GoPrevSection( pIdx,
2083 											sal_True, IsReadOnlyAvailable() )) )
2084 			{
2085 				if( *pIdx >= pCurCrsr->GetMark()->nNode )
2086 					pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
2087 				else
2088 					pFnd = 0;
2089 			}
2090 		}
2091 
2092 		if( !pFnd )
2093 		{
2094 			pCurCrsr->DeleteMark();
2095 			pCurCrsr->RestoreSavePos();
2096 		}
2097 		else if( bSelect && *pCurCrsr->GetMark() == *pCurCrsr->GetPoint() )
2098 			pCurCrsr->DeleteMark();
2099 
2100 		if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
2101 			UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE
2102 						| SwCrsrShell::READONLY );
2103 		else
2104 		{
2105 			pFnd = 0;
2106 			if( bSelect )
2107 				pCurCrsr->DeleteMark();
2108 		}
2109 	}
2110 	return pFnd;
2111 }
2112 
GotoRedline(sal_uInt16 nArrPos,sal_Bool bSelect)2113 const SwRedline* SwCrsrShell::GotoRedline( sal_uInt16 nArrPos, sal_Bool bSelect )
2114 {
2115 	const SwRedline* pFnd = 0;
2116 	if( !IsTableMode() )
2117 	{
2118 		SET_CURR_SHELL( this );
2119 
2120 		const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl();
2121 		const SwRedline* pTmp = rTbl[ nArrPos ];
2122 		sal_uInt16 nSeqNo = pTmp->GetSeqNo();
2123 		if( nSeqNo && bSelect )
2124 		{
2125 			sal_Bool bCheck = sal_False;
2126 			int nLoopCnt = 2;
2127 			sal_uInt16 nArrSavPos = nArrPos;
2128 
2129 			do {
2130 				pTmp = _GotoRedline( nArrPos, sal_True );
2131 
2132 				if( !pFnd )
2133 					pFnd = pTmp;
2134 
2135 				if( pTmp && bCheck )
2136 				{
2137 					// checke auf Ueberlappungen. Das kann durch
2138 					// FmtColl-Redlines kommen, die auf den gesamten Absatz
2139 					// aus gedehnt werden.
2140 
2141                     SwPaM* pCur = pCurCrsr;
2142                     SwPaM* pNextPam = (SwPaM*)pCur->GetNext();
2143 					SwPosition* pCStt = pCur->Start(), *pCEnd = pCur->End();
2144                     while( pCur != pNextPam )
2145 					{
2146                         const SwPosition *pNStt = pNextPam->Start(),
2147                                          *pNEnd = pNextPam->End();
2148 
2149 						sal_Bool bDel = sal_True;
2150 						switch( ::ComparePosition( *pCStt, *pCEnd,
2151 												   *pNStt, *pNEnd ))
2152 						{
2153 						case POS_INSIDE:	// Pos1 liegt vollstaendig in Pos2
2154 							if( !pCur->HasMark() )
2155 							{
2156 								pCur->SetMark();
2157 								*pCur->GetMark() = *pNStt;
2158 							}
2159 							else
2160 								*pCStt = *pNStt;
2161 							*pCEnd = *pNEnd;
2162 							break;
2163 
2164 						case POS_OUTSIDE:	// Pos2 liegt vollstaendig in Pos1
2165 						case POS_EQUAL:		// Pos1 ist genauso gross wie Pos2
2166 							break;
2167 
2168 						case POS_OVERLAP_BEFORE:		// Pos1 ueberlappt Pos2 am Anfang
2169 							if( !pCur->HasMark() )
2170 								pCur->SetMark();
2171 							*pCEnd = *pNEnd;
2172 							break;
2173 						case POS_OVERLAP_BEHIND: 		// Pos1 ueberlappt Pos2 am Ende
2174 							if( !pCur->HasMark() )
2175 							{
2176 								pCur->SetMark();
2177 								*pCur->GetMark() = *pNStt;
2178 							}
2179 							else
2180 								*pCStt = *pNStt;
2181 							break;
2182 
2183 						default:
2184 							bDel = sal_False;
2185 						}
2186 
2187 						if( bDel )
2188 						{
2189 							// den brauchen wir nicht mehr
2190                             SwPaM* pPrevPam = (SwPaM*)pNextPam->GetPrev();
2191                             delete pNextPam;
2192                             pNextPam = pPrevPam;
2193 						}
2194                         pNextPam = (SwPaM*)pNextPam->GetNext();
2195 					}
2196 				}
2197 
2198 				sal_uInt16 nFndPos = 2 == nLoopCnt
2199 									? rTbl.FindNextOfSeqNo( nArrPos )
2200 									: rTbl.FindPrevOfSeqNo( nArrPos );
2201 				if( USHRT_MAX != nFndPos ||
2202 					( 0 != ( --nLoopCnt ) && USHRT_MAX != (
2203 							nFndPos = rTbl.FindPrevOfSeqNo( nArrSavPos ))) )
2204 				{
2205 					if( pTmp )
2206 					{
2207 						// neuen Cursor erzeugen
2208 						CreateCrsr();
2209 						bCheck = sal_True;
2210 					}
2211 					nArrPos = nFndPos;
2212 				}
2213 				else
2214 					nLoopCnt = 0;
2215 
2216 			} while( nLoopCnt );
2217 		}
2218 		else
2219 			pFnd = _GotoRedline( nArrPos, bSelect );
2220 	}
2221 	return pFnd;
2222 }
2223 
2224 
SelectNxtPrvHyperlink(sal_Bool bNext)2225 sal_Bool SwCrsrShell::SelectNxtPrvHyperlink( sal_Bool bNext )
2226 {
2227 	SwNodes& rNds = GetDoc()->GetNodes();
2228 	const SwNode* pBodyEndNd = &rNds.GetEndOfContent();
2229     const SwNode* pBodySttNd = pBodyEndNd->StartOfSectionNode();
2230 	sal_uLong nBodySttNdIdx = pBodySttNd->GetIndex();
2231 	Point aPt;
2232 
2233 	_SetGetExpFld aCmpPos( SwPosition( bNext ? *pBodyEndNd : *pBodySttNd ) );
2234 	_SetGetExpFld aCurPos( bNext ? *pCurCrsr->End() : *pCurCrsr->Start() );
2235 	if( aCurPos.GetNode() < nBodySttNdIdx )
2236 	{
2237 		const SwCntntNode* pCNd = aCurPos.GetNodeFromCntnt()->GetCntntNode();
2238 		SwCntntFrm* pFrm;
2239 		if( pCNd && 0 != ( pFrm = pCNd->getLayoutFrm( GetLayout(), &aPt )) )
2240 			aCurPos.SetBodyPos( *pFrm );
2241 	}
2242 
2243 	// check first all the hyperlink fields
2244 	{
2245 		const SwTxtNode* pTxtNd;
2246 		const SwCharFmts* pFmts = GetDoc()->GetCharFmts();
2247 		for( sal_uInt16 n = pFmts->Count(); 1 < n; )
2248 		{
2249 			SwIterator<SwTxtINetFmt,SwCharFmt> aIter(*(*pFmts)[--n]);
2250 
2251 			for( SwTxtINetFmt* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() )
2252 				if( 0 != ( pTxtNd = pFnd->GetpTxtNode()) &&
2253 					pTxtNd->GetNodes().IsDocNodes() )
2254 				{
2255 					SwTxtINetFmt& rAttr = *pFnd;
2256 					SwPosition aTmpPos( *pTxtNd );
2257 					_SetGetExpFld aPos( aTmpPos.nNode, rAttr );
2258 					SwCntntFrm* pFrm;
2259 					if( pTxtNd->GetIndex() < nBodySttNdIdx &&
2260 						0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt )) )
2261 						aPos.SetBodyPos( *pFrm );
2262 
2263 					if( bNext
2264 						? ( aPos < aCmpPos && aCurPos < aPos )
2265 						: ( aCmpPos < aPos && aPos < aCurPos ))
2266 					{
2267 						String sTxt( pTxtNd->GetExpandTxt( *rAttr.GetStart(),
2268 										*rAttr.GetEnd() - *rAttr.GetStart() ) );
2269 
2270 						sTxt.EraseAllChars( 0x0a );
2271 						sTxt.EraseLeadingChars().EraseTrailingChars();
2272 
2273 						if( sTxt.Len() )
2274 							aCmpPos = aPos;
2275 					}
2276 				}
2277 		}
2278 	}
2279 	// then check all the Flys with a URL or imapge map
2280 	{
2281 		const SwSpzFrmFmts* pFmts = GetDoc()->GetSpzFrmFmts();
2282 		for( sal_uInt16 n = 0, nEnd = pFmts->Count(); n < nEnd; ++n )
2283 		{
2284 			SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)(*pFmts)[ n ];
2285 			const SwFmtURL& rURLItem = pFmt->GetURL();
2286 			if( rURLItem.GetMap() || rURLItem.GetURL().Len() )
2287 			{
2288 				SwFlyFrm* pFly = pFmt->GetFrm( &aPt, sal_False );
2289 				SwPosition aTmpPos( *pBodySttNd );
2290 				if( pFly &&
2291 					GetBodyTxtNode( *GetDoc(), aTmpPos, *pFly->GetLower() ) )
2292 				{
2293 					_SetGetExpFld aPos( *pFmt, &aTmpPos );
2294 
2295 					if( bNext
2296 							? ( aPos < aCmpPos && aCurPos < aPos )
2297 							: ( aCmpPos < aPos && aPos < aCurPos ))
2298 						aCmpPos = aPos;
2299 				}
2300 			}
2301 		}
2302 	}
2303 
2304 	// found any URL ?
2305 	sal_Bool bRet = sal_False;
2306 	const SwTxtINetFmt* pFndAttr = aCmpPos.GetINetFmt();
2307 	const SwFlyFrmFmt* pFndFmt = aCmpPos.GetFlyFmt();
2308 	if( pFndAttr || pFndFmt )
2309 	{
2310 		SET_CURR_SHELL( this );
2311 		SwCallLink aLk( *this );
2312 
2313 		// find a text attribute ?
2314 		if( pFndAttr )
2315 		{
2316 			SwCrsrSaveState aSaveState( *pCurCrsr );
2317 
2318 			aCmpPos.GetPosOfContent( *pCurCrsr->GetPoint() );
2319 			pCurCrsr->DeleteMark();
2320 			pCurCrsr->SetMark();
2321 			pCurCrsr->GetPoint()->nContent = *pFndAttr->End();
2322 
2323 			if( !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() )
2324 			{
2325 				UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|
2326 									SwCrsrShell::READONLY );
2327 				bRet = sal_True;
2328 			}
2329 		}
2330 		// find a draw object ?
2331 		else if( RES_DRAWFRMFMT == pFndFmt->Which() )
2332 		{
2333 			const SdrObject* pSObj = pFndFmt->FindSdrObject();
2334 			((SwFEShell*)this)->SelectObj( pSObj->GetCurrentBoundRect().Center() );
2335 			MakeSelVisible();
2336 			bRet = sal_True;
2337 		}
2338 		else		// then is it a fly
2339 		{
2340 			SwFlyFrm* pFly = pFndFmt->GetFrm(&aPt, sal_False );
2341 			if( pFly )
2342 			{
2343 				((SwFEShell*)this)->SelectFlyFrm( *pFly, sal_True );
2344 				MakeSelVisible();
2345 				bRet = sal_True;
2346 			}
2347 		}
2348 	}
2349 	return bRet;
2350 }
2351 
2352