xref: /aoo41x/main/sw/source/core/crsr/crsrsh.cxx (revision 23d8f725)
1efeef26fSAndrew Rist /**************************************************************
2efeef26fSAndrew Rist  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19efeef26fSAndrew Rist  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir #include <com/sun/star/util/SearchOptions.hpp>
27cdf0e10cSrcweir #include <com/sun/star/text/XTextRange.hpp>
28cdf0e10cSrcweir #include <hintids.hxx>
29cdf0e10cSrcweir #include <svx/svdmodel.hxx>
30cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <SwSmartTagMgr.hxx>
33cdf0e10cSrcweir #include <doc.hxx>
34cdf0e10cSrcweir #include <rootfrm.hxx>
35cdf0e10cSrcweir #include <pagefrm.hxx>
36cdf0e10cSrcweir #include <cntfrm.hxx>
37cdf0e10cSrcweir #include <viewimp.hxx>
38cdf0e10cSrcweir #include <pam.hxx>
39cdf0e10cSrcweir #include <swselectionlist.hxx>
40cdf0e10cSrcweir #include <IBlockCursor.hxx>
41cdf0e10cSrcweir #include "BlockCursor.hxx"
42cdf0e10cSrcweir #include <ndtxt.hxx>
43cdf0e10cSrcweir #include <flyfrm.hxx>
44cdf0e10cSrcweir #include <dview.hxx>
45cdf0e10cSrcweir #include <viewopt.hxx>
46cdf0e10cSrcweir #include <frmtool.hxx>
47cdf0e10cSrcweir #include <crsrsh.hxx>
48cdf0e10cSrcweir #include <tabfrm.hxx>
49cdf0e10cSrcweir #include <txtfrm.hxx>
50cdf0e10cSrcweir #include <sectfrm.hxx>
51cdf0e10cSrcweir #include <swtable.hxx>
52cdf0e10cSrcweir #include <callnk.hxx>
53cdf0e10cSrcweir #include <viscrs.hxx>
54cdf0e10cSrcweir #include <section.hxx>
55cdf0e10cSrcweir #include <docsh.hxx>
56cdf0e10cSrcweir #include <scriptinfo.hxx>
57cdf0e10cSrcweir #include <globdoc.hxx>
58cdf0e10cSrcweir #include <pamtyp.hxx>
59cdf0e10cSrcweir #include <mdiexp.hxx>			// ...Percent()
60cdf0e10cSrcweir #include <fmteiro.hxx>
61cdf0e10cSrcweir #include <wrong.hxx> // SMARTTAGS
62cdf0e10cSrcweir #include <unotextrange.hxx> // SMARTTAGS
63cdf0e10cSrcweir #include <vcl/svapp.hxx>
64cdf0e10cSrcweir #include <numrule.hxx>
65cdf0e10cSrcweir #include <IGrammarContact.hxx>
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #include <globals.hrc>
68cdf0e10cSrcweir 
69cdf0e10cSrcweir #include <comcore.hrc>
70cdf0e10cSrcweir 
71cdf0e10cSrcweir using namespace com::sun::star;
72cdf0e10cSrcweir using namespace util;
73cdf0e10cSrcweir 
74cdf0e10cSrcweir TYPEINIT2(SwCrsrShell,ViewShell,SwModify);
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
77cdf0e10cSrcweir // Funktion loescht, alle ueberlappenden Cursor aus einem Cursor-Ring
78cdf0e10cSrcweir void CheckRange( SwCursor* );
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //-----------------------------------------------------------------------
81cdf0e10cSrcweir 
82cdf0e10cSrcweir /*
83cdf0e10cSrcweir  * Ueberpruefe ob der pCurCrsr in einen schon bestehenden Bereich zeigt.
84cdf0e10cSrcweir  * Wenn ja, dann hebe den alten Bereich auf.
85cdf0e10cSrcweir  */
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 
CheckRange(SwCursor * pCurCrsr)88cdf0e10cSrcweir void CheckRange( SwCursor* pCurCrsr )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir 	const SwPosition *pStt = pCurCrsr->Start(),
91cdf0e10cSrcweir 		*pEnd = pCurCrsr->GetPoint() == pStt ? pCurCrsr->GetMark() : pCurCrsr->GetPoint();
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 	SwPaM *pTmpDel = 0,
94cdf0e10cSrcweir 		  *pTmp = (SwPaM*)pCurCrsr->GetNext();
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 	// durchsuche den gesamten Ring
97cdf0e10cSrcweir 	while( pTmp != pCurCrsr )
98cdf0e10cSrcweir 	{
99cdf0e10cSrcweir 		const SwPosition *pTmpStt = pTmp->Start(),
100cdf0e10cSrcweir 						*pTmpEnd = pTmp->GetPoint() == pTmpStt ?
101cdf0e10cSrcweir 										pTmp->GetMark() : pTmp->GetPoint();
102cdf0e10cSrcweir 		if( *pStt <= *pTmpStt )
103cdf0e10cSrcweir 		{
104cdf0e10cSrcweir 			if( *pEnd > *pTmpStt ||
105cdf0e10cSrcweir 				( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
106cdf0e10cSrcweir 				pTmpDel = pTmp;
107cdf0e10cSrcweir 		}
108cdf0e10cSrcweir 		else
109cdf0e10cSrcweir 			if( *pStt < *pTmpEnd )
110cdf0e10cSrcweir 				pTmpDel = pTmp;
111cdf0e10cSrcweir 		/*
112cdf0e10cSrcweir 		 * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich
113cdf0e10cSrcweir 		 * muss der alte Bereich aufgehoben werden.
114cdf0e10cSrcweir 		 * Beim Vergleich ist darauf zu achten, das SPoint nicht mehr zum
115cdf0e10cSrcweir 		 * Bereich gehoert !
116cdf0e10cSrcweir 		 */
117cdf0e10cSrcweir 		pTmp = (SwPaM*)pTmp->GetNext();
118cdf0e10cSrcweir 		if( pTmpDel )
119cdf0e10cSrcweir 		{
120cdf0e10cSrcweir 			delete pTmpDel;         // hebe alten Bereich auf
121cdf0e10cSrcweir 			pTmpDel = 0;
122cdf0e10cSrcweir 		}
123cdf0e10cSrcweir 	}
124cdf0e10cSrcweir }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir // -------------- Methoden von der SwCrsrShell -------------
127cdf0e10cSrcweir 
CreateCrsr()128cdf0e10cSrcweir SwPaM * SwCrsrShell::CreateCrsr()
129cdf0e10cSrcweir {
130cdf0e10cSrcweir 	// Innerhalb der Tabellen-SSelection keinen neuen Crsr anlegen
131cdf0e10cSrcweir 	ASSERT( !IsTableMode(), "in Tabellen SSelection" );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 	// neuen Cursor als Kopie vom akt. und in den Ring aufnehmen
134cdf0e10cSrcweir 	// Verkettung zeigt immer auf den zuerst erzeugten, also vorwaerts
135cdf0e10cSrcweir 	SwShellCrsr* pNew = new SwShellCrsr( *pCurCrsr );
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 	// hier den akt. Pam nur logisch Hiden, weil sonst die Invertierung
138cdf0e10cSrcweir 	// vom kopierten Pam aufgehoben wird !!
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 	// #i75172# to be able to make a complete content swap, i moved this to a method
141cdf0e10cSrcweir 	// pNew->Insert( pCurCrsr, 0 );
142cdf0e10cSrcweir 	// pCurCrsr->Remove( 0, pCurCrsr->Count() );
143cdf0e10cSrcweir 	pNew->swapContent(*pCurCrsr);
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 	pCurCrsr->DeleteMark();
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 	UpdateCrsr( SwCrsrShell::SCROLLWIN );
148cdf0e10cSrcweir //	return pCurCrsr;
149cdf0e10cSrcweir 	return pNew;
150cdf0e10cSrcweir }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir // loesche den aktuellen Cursor und der folgende wird zum Aktuellen
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 
DestroyCrsr()155cdf0e10cSrcweir sal_Bool SwCrsrShell::DestroyCrsr()
156cdf0e10cSrcweir {
157cdf0e10cSrcweir 	// Innerhalb der Tabellen-SSelection keinen neuen Crsr loeschen
158cdf0e10cSrcweir 	ASSERT( !IsTableMode(), "in Tabellen SSelection" );
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	// ist ueberhaupt ein naechtser vorhanden ?
161cdf0e10cSrcweir 	if(pCurCrsr->GetNext() == pCurCrsr)
162cdf0e10cSrcweir 		return sal_False;
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
165cdf0e10cSrcweir     SwCursor* pNextCrsr = (SwCursor*)pCurCrsr->GetNext();
166cdf0e10cSrcweir 	delete pCurCrsr;
167cdf0e10cSrcweir     pCurCrsr = dynamic_cast<SwShellCrsr*>(pNextCrsr);
168cdf0e10cSrcweir 	UpdateCrsr();
169cdf0e10cSrcweir 	return sal_True;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 
CreateNewShellCursor()173cdf0e10cSrcweir SwPaM & SwCrsrShell::CreateNewShellCursor()
174cdf0e10cSrcweir {
175cdf0e10cSrcweir     if (HasSelection())
176cdf0e10cSrcweir     {
177cdf0e10cSrcweir         (void) CreateCrsr(); // n.b. returns old cursor
178cdf0e10cSrcweir     }
179cdf0e10cSrcweir     return *GetCrsr();
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
GetCurrentShellCursor()182cdf0e10cSrcweir SwPaM & SwCrsrShell::GetCurrentShellCursor()
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     return *GetCrsr();
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 
188cdf0e10cSrcweir // gebe den aktuellen zurueck
189cdf0e10cSrcweir 
GetCrsr(sal_Bool bMakeTblCrsr) const190cdf0e10cSrcweir SwPaM* SwCrsrShell::GetCrsr( sal_Bool bMakeTblCrsr ) const
191cdf0e10cSrcweir {
192cdf0e10cSrcweir 	if( pTblCrsr )
193cdf0e10cSrcweir 	{
194cdf0e10cSrcweir 		if( bMakeTblCrsr && pTblCrsr->IsCrsrMovedUpdt() )
195cdf0e10cSrcweir 		{
196cdf0e10cSrcweir 			// geparkte Cursor werden nicht wieder erzeugt
197cdf0e10cSrcweir 			const SwCntntNode* pCNd;
198cdf0e10cSrcweir 			if( pTblCrsr->GetPoint()->nNode.GetIndex() &&
199cdf0e10cSrcweir 				pTblCrsr->GetMark()->nNode.GetIndex() &&
200cdf0e10cSrcweir 				0 != ( pCNd = pTblCrsr->GetCntntNode() ) && pCNd->getLayoutFrm( GetLayout() ) &&
201cdf0e10cSrcweir 				0 != ( pCNd = pTblCrsr->GetCntntNode(sal_False) ) && pCNd->getLayoutFrm( GetLayout() ) )
202cdf0e10cSrcweir 			{
203cdf0e10cSrcweir 				SwShellTableCrsr* pTC = (SwShellTableCrsr*)pTblCrsr;
204cdf0e10cSrcweir 				GetLayout()->MakeTblCrsrs( *pTC );
205cdf0e10cSrcweir 			}
206cdf0e10cSrcweir 		}
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 		if( pTblCrsr->IsChgd() )
209cdf0e10cSrcweir 		{
210cdf0e10cSrcweir             const_cast<SwCrsrShell*>(this)->pCurCrsr =
211cdf0e10cSrcweir                 dynamic_cast<SwShellCrsr*>(pTblCrsr->MakeBoxSels( pCurCrsr ));
212cdf0e10cSrcweir 		}
213cdf0e10cSrcweir 	}
214cdf0e10cSrcweir 	return pCurCrsr;
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 
StartAction()218cdf0e10cSrcweir void SwCrsrShell::StartAction()
219cdf0e10cSrcweir {
220cdf0e10cSrcweir 	if( !ActionPend() )
221cdf0e10cSrcweir 	{
222cdf0e10cSrcweir 		// fuer das Update des Ribbon-Bars merken
223cdf0e10cSrcweir 		const SwNode& rNd = pCurCrsr->GetPoint()->nNode.GetNode();
224cdf0e10cSrcweir 		nAktNode = rNd.GetIndex();
225cdf0e10cSrcweir 		nAktCntnt = pCurCrsr->GetPoint()->nContent.GetIndex();
226cdf0e10cSrcweir 		nAktNdTyp = rNd.GetNodeType();
227cdf0e10cSrcweir         bAktSelection = *pCurCrsr->GetPoint() != *pCurCrsr->GetMark();
228cdf0e10cSrcweir 		if( ND_TEXTNODE & nAktNdTyp )
229cdf0e10cSrcweir 			nLeftFrmPos = SwCallLink::getLayoutFrm( GetLayout(), (SwTxtNode&)rNd, nAktCntnt, sal_True );
230cdf0e10cSrcweir 		else
231cdf0e10cSrcweir 			nLeftFrmPos = 0;
232cdf0e10cSrcweir 	}
233cdf0e10cSrcweir 	ViewShell::StartAction();           // zur ViewShell
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 
EndAction(const sal_Bool bIdleEnd)237cdf0e10cSrcweir void SwCrsrShell::EndAction( const sal_Bool bIdleEnd )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir /*
240cdf0e10cSrcweir //OS: Wird z.B. eine Basic-Action im Hintergrund ausgefuehrt, geht es so nicht
241cdf0e10cSrcweir 	if( !bHasFocus )
242cdf0e10cSrcweir 	{
243cdf0e10cSrcweir 		// hat die Shell nicht den Focus, dann nur das EndAction an
244cdf0e10cSrcweir 		// die ViewShell weitergeben.
245cdf0e10cSrcweir 		ViewShell::EndAction( bIdleEnd );
246cdf0e10cSrcweir 		return;
247cdf0e10cSrcweir 	}
248cdf0e10cSrcweir */
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	sal_Bool bVis = bSVCrsrVis;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	// Idle-Formatierung ?
253cdf0e10cSrcweir 	if( bIdleEnd && Imp()->GetRegion() )
254cdf0e10cSrcweir 	{
255cdf0e10cSrcweir 		pCurCrsr->Hide();
256cdf0e10cSrcweir 
257cdf0e10cSrcweir #ifdef SHOW_IDLE_REGION
258cdf0e10cSrcweir if( GetWin() )
259cdf0e10cSrcweir {
260cdf0e10cSrcweir 	GetWin()->Push();
261cdf0e10cSrcweir 	GetWin()->ChangePen( Pen( Color( COL_YELLOW )));
262cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < aPntReg.Count(); ++n )
263cdf0e10cSrcweir 	{
264cdf0e10cSrcweir 		SwRect aIRect( aPntReg[n] );
265cdf0e10cSrcweir 		GetWin()->DrawRect( aIRect.SVRect() );
266cdf0e10cSrcweir 	}
267cdf0e10cSrcweir 	GetWin()->Pop();
268cdf0e10cSrcweir }
269cdf0e10cSrcweir #endif
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 	}
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 	// vor der letzten Action alle invaliden Numerierungen updaten
274cdf0e10cSrcweir 	if( 1 == nStartAction )
275cdf0e10cSrcweir 		GetDoc()->UpdateNumRule();
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 	// Task: 76923: dont show the cursor in the ViewShell::EndAction() - call.
278cdf0e10cSrcweir 	//				Only the UpdateCrsr shows the cursor.
279cdf0e10cSrcweir 	sal_Bool bSavSVCrsrVis = bSVCrsrVis;
280cdf0e10cSrcweir 	bSVCrsrVis = sal_False;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 	ViewShell::EndAction( bIdleEnd );	//der ViewShell den Vortritt lassen
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 	bSVCrsrVis = bSavSVCrsrVis;
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 	if( ActionPend() )
287cdf0e10cSrcweir 	{
288cdf0e10cSrcweir 		if( bVis )    // auch SV-Cursor wieder anzeigen
289cdf0e10cSrcweir 			pVisCrsr->Show();
290cdf0e10cSrcweir 
291cdf0e10cSrcweir 		// falls noch ein ChgCall vorhanden ist und nur noch die Basic
292cdf0e10cSrcweir 		// Klammerung vorhanden ist, dann rufe ihn. Dadurch wird die interne
293cdf0e10cSrcweir 		// mit der Basic-Klammerung entkoppelt; die Shells werden umgeschaltet
294cdf0e10cSrcweir 		if( !BasicActionPend() )
295cdf0e10cSrcweir 		{
296cdf0e10cSrcweir 			//JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction
297cdf0e10cSrcweir 			//				der Cursor geupdatet werden; um z.B. den
298cdf0e10cSrcweir 			//				TabellenCursor zu erzeugen. Im UpdateCrsr wird
299cdf0e10cSrcweir 			//				das jetzt beruecksichtigt!
300cdf0e10cSrcweir 			UpdateCrsr( SwCrsrShell::CHKRANGE, bIdleEnd );
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 			{
303cdf0e10cSrcweir 				// Crsr-Moves ueberwachen, evt. Link callen
304cdf0e10cSrcweir 				// der DTOR ist das interressante!!
305cdf0e10cSrcweir 				SwCallLink aLk( *this, nAktNode, nAktCntnt, (sal_uInt8)nAktNdTyp,
306cdf0e10cSrcweir 								nLeftFrmPos, bAktSelection );
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 			}
309cdf0e10cSrcweir 			if( bCallChgLnk && bChgCallFlag && aChgLnk.IsSet() )
310cdf0e10cSrcweir 			{
311cdf0e10cSrcweir 				aChgLnk.Call( this );
312cdf0e10cSrcweir 				bChgCallFlag = sal_False;		// Flag zuruecksetzen
313cdf0e10cSrcweir 			}
314cdf0e10cSrcweir 		}
315cdf0e10cSrcweir 		return;
316cdf0e10cSrcweir 	}
317cdf0e10cSrcweir 
318cdf0e10cSrcweir 	sal_uInt16 nParm = SwCrsrShell::CHKRANGE;
319cdf0e10cSrcweir 	if ( !bIdleEnd )
320cdf0e10cSrcweir 		nParm |= SwCrsrShell::SCROLLWIN;
321cdf0e10cSrcweir //    if( !IsViewLocked() )
322cdf0e10cSrcweir 	UpdateCrsr( nParm, bIdleEnd );		// Cursor-Aenderungen anzeigen
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 	{
325cdf0e10cSrcweir 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen,
326cdf0e10cSrcweir 		aLk.nNode = nAktNode;           // evt. Link callen
327cdf0e10cSrcweir 		aLk.nNdTyp = (sal_uInt8)nAktNdTyp;
328cdf0e10cSrcweir 		aLk.nCntnt = nAktCntnt;
329cdf0e10cSrcweir 		aLk.nLeftFrmPos = nLeftFrmPos;
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 		if( !nCrsrMove ||
332cdf0e10cSrcweir 			( 1 == nCrsrMove && bInCMvVisportChgd ) )
333cdf0e10cSrcweir 			ShowCrsrs( bSVCrsrVis ? sal_True : sal_False );    // Cursor & Selektionen wieder anzeigen
334cdf0e10cSrcweir 	}
335cdf0e10cSrcweir 	// falls noch ein ChgCall vorhanden ist, dann rufe ihn
336cdf0e10cSrcweir 	if( bCallChgLnk && bChgCallFlag && aChgLnk.IsSet() )
337cdf0e10cSrcweir 	{
338cdf0e10cSrcweir 		aChgLnk.Call( this );
339cdf0e10cSrcweir 		bChgCallFlag = sal_False;		// Flag zuruecksetzen
340cdf0e10cSrcweir 	}
341cdf0e10cSrcweir }
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 
344cdf0e10cSrcweir #if defined(DBG_UTIL)
345cdf0e10cSrcweir 
SttCrsrMove()346cdf0e10cSrcweir void SwCrsrShell::SttCrsrMove()
347cdf0e10cSrcweir {
348cdf0e10cSrcweir 	ASSERT( nCrsrMove < USHRT_MAX, "To many nested CrsrMoves." );
349cdf0e10cSrcweir 	++nCrsrMove;
350cdf0e10cSrcweir 	StartAction();
351cdf0e10cSrcweir }
352cdf0e10cSrcweir 
EndCrsrMove(const sal_Bool bIdleEnd)353cdf0e10cSrcweir void SwCrsrShell::EndCrsrMove( const sal_Bool bIdleEnd )
354cdf0e10cSrcweir {
355cdf0e10cSrcweir 	ASSERT( nCrsrMove, "EndCrsrMove() ohne SttCrsrMove()." );
356cdf0e10cSrcweir 	EndAction( bIdleEnd );
357cdf0e10cSrcweir 	if( !--nCrsrMove )
358cdf0e10cSrcweir 		bInCMvVisportChgd = sal_False;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir 
361cdf0e10cSrcweir #endif
362cdf0e10cSrcweir 
363cdf0e10cSrcweir 
LeftRight(sal_Bool bLeft,sal_uInt16 nCnt,sal_uInt16 nMode,sal_Bool bVisualAllowed)364cdf0e10cSrcweir sal_Bool SwCrsrShell::LeftRight( sal_Bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
365cdf0e10cSrcweir                                  sal_Bool bVisualAllowed )
366cdf0e10cSrcweir {
367cdf0e10cSrcweir 	if( IsTableMode() )
368cdf0e10cSrcweir 		return bLeft ? GoPrevCell() : GoNextCell();
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
371cdf0e10cSrcweir     sal_Bool bRet = sal_False;
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     // #i27615# Handle cursor in front of label.
374cdf0e10cSrcweir     const SwTxtNode* pTxtNd = 0;
375cdf0e10cSrcweir 
376cdf0e10cSrcweir     if( pBlockCrsr )
377cdf0e10cSrcweir         pBlockCrsr->clearPoints();
378cdf0e10cSrcweir 
379cdf0e10cSrcweir     //
380cdf0e10cSrcweir     // 1. CASE: Cursor is in front of label. A move to the right
381cdf0e10cSrcweir     // will simply reset the bInFrontOfLabel flag:
382cdf0e10cSrcweir     //
383cdf0e10cSrcweir     SwShellCrsr* pShellCrsr = getShellCrsr( true );
384cdf0e10cSrcweir     if ( !bLeft && pShellCrsr->IsInFrontOfLabel() )
385cdf0e10cSrcweir     {
386cdf0e10cSrcweir         SetInFrontOfLabel( sal_False );
387cdf0e10cSrcweir         bRet = sal_True;
388cdf0e10cSrcweir     }
389cdf0e10cSrcweir     //
390cdf0e10cSrcweir     // 2. CASE: Cursor is at beginning of numbered paragraph. A move
391cdf0e10cSrcweir     // to the left will simply set the bInFrontOfLabel flag:
392cdf0e10cSrcweir     //
393cdf0e10cSrcweir     else if ( bLeft && 0 == pShellCrsr->GetPoint()->nContent.GetIndex() &&
394cdf0e10cSrcweir              !pShellCrsr->IsInFrontOfLabel() && !pShellCrsr->HasMark() &&
395cdf0e10cSrcweir              0 != ( pTxtNd = pShellCrsr->GetNode()->GetTxtNode() ) &&
396cdf0e10cSrcweir              pTxtNd->HasVisibleNumberingOrBullet() )
397cdf0e10cSrcweir     {
398cdf0e10cSrcweir         SetInFrontOfLabel( sal_True );
399cdf0e10cSrcweir         bRet = sal_True;
400cdf0e10cSrcweir     }
401cdf0e10cSrcweir     //
402cdf0e10cSrcweir     // 3. CASE: Regular cursor move. Reset the bInFrontOfLabel flag:
403cdf0e10cSrcweir     //
404cdf0e10cSrcweir     else
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         const sal_Bool bSkipHidden = !GetViewOptions()->IsShowHiddenChar();
407cdf0e10cSrcweir         // --> OD 2009-12-30 #i107447#
408cdf0e10cSrcweir         // To avoid loop the reset of <bInFrontOfLabel> flag is no longer
409cdf0e10cSrcweir         // reflected in the return value <bRet>.
410cdf0e10cSrcweir         const bool bResetOfInFrontOfLabel = SetInFrontOfLabel( sal_False );
411cdf0e10cSrcweir         bRet = pShellCrsr->LeftRight( bLeft, nCnt, nMode, bVisualAllowed,
412cdf0e10cSrcweir                                       bSkipHidden, !IsOverwriteCrsr() );
413cdf0e10cSrcweir         if ( !bRet && bLeft && bResetOfInFrontOfLabel )
414cdf0e10cSrcweir         {
415cdf0e10cSrcweir             // undo reset of <bInFrontOfLabel> flag
416cdf0e10cSrcweir             SetInFrontOfLabel( sal_True );
417cdf0e10cSrcweir         }
418cdf0e10cSrcweir         // <--
419cdf0e10cSrcweir     }
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 	if( bRet )
422cdf0e10cSrcweir     {
423cdf0e10cSrcweir 		UpdateCrsr();
424cdf0e10cSrcweir     }
425cdf0e10cSrcweir 	return bRet;
426cdf0e10cSrcweir }
FirePageChangeEvent(sal_uInt16 nOldPage,sal_uInt16 nNewPage)427ca62e2c2SSteve Yin void SwCrsrShell::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
428ca62e2c2SSteve Yin {
429ca62e2c2SSteve Yin #ifdef ACCESSIBLE_LAYOUT
430ca62e2c2SSteve Yin 	if( Imp()->IsAccessible() )
431ca62e2c2SSteve Yin 		Imp()->FirePageChangeEvent( nOldPage, nNewPage );
432ca62e2c2SSteve Yin #endif
433ca62e2c2SSteve Yin }
434ca62e2c2SSteve Yin 
FireColumnChangeEvent(sal_uInt16 nOldColumn,sal_uInt16 nNewColumn)435ca62e2c2SSteve Yin void SwCrsrShell::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
436ca62e2c2SSteve Yin {
437ca62e2c2SSteve Yin #ifdef ACCESSIBLE_LAYOUT
438ca62e2c2SSteve Yin 	if( Imp()->IsAccessible() )
439ca62e2c2SSteve Yin 		Imp()->FireColumnChangeEvent( nOldColumn,  nNewColumn);
440ca62e2c2SSteve Yin #endif
441ca62e2c2SSteve Yin }
442ca62e2c2SSteve Yin 
443ca62e2c2SSteve Yin 
FireSectionChangeEvent(sal_uInt16 nOldSection,sal_uInt16 nNewSection)444ca62e2c2SSteve Yin void SwCrsrShell::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
445ca62e2c2SSteve Yin {
446ca62e2c2SSteve Yin #ifdef ACCESSIBLE_LAYOUT
447ca62e2c2SSteve Yin 	if( Imp()->IsAccessible() )
448ca62e2c2SSteve Yin 		Imp()->FireSectionChangeEvent( nOldSection, nNewSection );
449ca62e2c2SSteve Yin #endif
450ca62e2c2SSteve Yin }
bColumnChange()451ca62e2c2SSteve Yin bool SwCrsrShell::bColumnChange()
452ca62e2c2SSteve Yin {
453ca62e2c2SSteve Yin 
454ca62e2c2SSteve Yin 	SwFrm* pCurrFrm = GetCurrFrm(sal_False);
455ca62e2c2SSteve Yin 
456ca62e2c2SSteve Yin 	if (pCurrFrm == NULL)
457ca62e2c2SSteve Yin 	{
458ca62e2c2SSteve Yin 		return sal_False;
459ca62e2c2SSteve Yin 	}
460ca62e2c2SSteve Yin 
461ca62e2c2SSteve Yin 	SwFrm* pCurrCol=((SwFrm*)pCurrFrm)->FindColFrm();
462ca62e2c2SSteve Yin 
463ca62e2c2SSteve Yin 	while(pCurrCol== NULL && pCurrFrm!=NULL )
464ca62e2c2SSteve Yin 	{
465ca62e2c2SSteve Yin 		SwLayoutFrm* pParent = pCurrFrm->GetUpper();
466ca62e2c2SSteve Yin 		if(pParent!=NULL)
467ca62e2c2SSteve Yin 		{
468ca62e2c2SSteve Yin 			pCurrCol=((SwFrm*)pParent)->FindColFrm();
469ca62e2c2SSteve Yin 			pCurrFrm = (SwFrm*)pParent;
470ca62e2c2SSteve Yin 		}
471ca62e2c2SSteve Yin 		else
472ca62e2c2SSteve Yin 		{
473ca62e2c2SSteve Yin 			break;
474ca62e2c2SSteve Yin 		}
475ca62e2c2SSteve Yin 	}
476ca62e2c2SSteve Yin 	if(oldColFrm == pCurrCol)
477ca62e2c2SSteve Yin 		return sal_False;
478ca62e2c2SSteve Yin 	else
479ca62e2c2SSteve Yin 	{
480ca62e2c2SSteve Yin 		oldColFrm = pCurrCol;
481ca62e2c2SSteve Yin 		return sal_True;
482ca62e2c2SSteve Yin 	}
483ca62e2c2SSteve Yin }
484cdf0e10cSrcweir 
485cdf0e10cSrcweir // --> OD 2008-04-02 #refactorlists#
MarkListLevel(const String & sListId,const int nListLevel)486cdf0e10cSrcweir void SwCrsrShell::MarkListLevel( const String& sListId,
487cdf0e10cSrcweir                                  const int nListLevel )
488cdf0e10cSrcweir {
489cdf0e10cSrcweir     if ( sListId != sMarkedListId ||
490cdf0e10cSrcweir          nListLevel != nMarkedListLevel)
491cdf0e10cSrcweir     {
492cdf0e10cSrcweir         if ( sMarkedListId.Len() > 0 )
493cdf0e10cSrcweir             pDoc->MarkListLevel( sMarkedListId, nMarkedListLevel, sal_False );
494cdf0e10cSrcweir 
495cdf0e10cSrcweir         if ( sListId.Len() > 0 )
496cdf0e10cSrcweir         {
497cdf0e10cSrcweir             pDoc->MarkListLevel( sListId, nListLevel, sal_True );
498cdf0e10cSrcweir         }
499cdf0e10cSrcweir 
500cdf0e10cSrcweir         sMarkedListId = sListId;
501cdf0e10cSrcweir         nMarkedListLevel = nListLevel;
502cdf0e10cSrcweir     }
503cdf0e10cSrcweir }
504cdf0e10cSrcweir 
UpdateMarkedListLevel()505cdf0e10cSrcweir void SwCrsrShell::UpdateMarkedListLevel()
506cdf0e10cSrcweir {
507cdf0e10cSrcweir     SwTxtNode * pTxtNd = _GetCrsr()->GetNode()->GetTxtNode();
508cdf0e10cSrcweir 
509cdf0e10cSrcweir     if ( pTxtNd )
510cdf0e10cSrcweir     {
511cdf0e10cSrcweir         if ( !pTxtNd->IsNumbered() )
512cdf0e10cSrcweir         {
513cdf0e10cSrcweir             pCurCrsr->_SetInFrontOfLabel( sal_False );
514cdf0e10cSrcweir             MarkListLevel( String(), 0 );
515cdf0e10cSrcweir         }
516cdf0e10cSrcweir         else if ( pCurCrsr->IsInFrontOfLabel() )
517cdf0e10cSrcweir         {
518cdf0e10cSrcweir             if ( pTxtNd->IsInList() )
519cdf0e10cSrcweir             {
520cdf0e10cSrcweir                 ASSERT( pTxtNd->GetActualListLevel() >= 0 &&
521cdf0e10cSrcweir                         pTxtNd->GetActualListLevel() < MAXLEVEL, "Which level?")
522cdf0e10cSrcweir                 MarkListLevel( pTxtNd->GetListId(),
523cdf0e10cSrcweir                                pTxtNd->GetActualListLevel() );
524cdf0e10cSrcweir             }
525cdf0e10cSrcweir         }
526cdf0e10cSrcweir         else
527cdf0e10cSrcweir         {
528cdf0e10cSrcweir             MarkListLevel( String(), 0 );
529cdf0e10cSrcweir         }
530cdf0e10cSrcweir     }
531cdf0e10cSrcweir }
532cdf0e10cSrcweir // <--
533cdf0e10cSrcweir 
UpDown(sal_Bool bUp,sal_uInt16 nCnt)534cdf0e10cSrcweir sal_Bool SwCrsrShell::UpDown( sal_Bool bUp, sal_uInt16 nCnt )
535cdf0e10cSrcweir {
536cdf0e10cSrcweir 	SET_CURR_SHELL( this );
537cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 	sal_Bool bTableMode = IsTableMode();
540cdf0e10cSrcweir 	SwShellCrsr* pTmpCrsr = getShellCrsr( true );
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     sal_Bool bRet = pTmpCrsr->UpDown( bUp, nCnt );
543cdf0e10cSrcweir     // --> FME 2005-01-10 #i40019# UpDown should always reset the
544cdf0e10cSrcweir     // bInFrontOfLabel flag:
545cdf0e10cSrcweir     bRet = SetInFrontOfLabel(sal_False) || bRet;
546cdf0e10cSrcweir     // <--
547cdf0e10cSrcweir 
548cdf0e10cSrcweir     if( pBlockCrsr )
549cdf0e10cSrcweir         pBlockCrsr->clearPoints();
550cdf0e10cSrcweir 
551cdf0e10cSrcweir 	if( bRet )
552cdf0e10cSrcweir 	{
553cdf0e10cSrcweir 		eMvState = MV_UPDOWN;		// Status fuers Crsr-Travelling - GetCrsrOfst
554cdf0e10cSrcweir 		if( !ActionPend() )
555cdf0e10cSrcweir 		{
556cdf0e10cSrcweir 			CrsrFlag eUpdtMode = SwCrsrShell::SCROLLWIN;
557cdf0e10cSrcweir 			if( !bTableMode )
558cdf0e10cSrcweir 				eUpdtMode = (CrsrFlag) (eUpdtMode
559cdf0e10cSrcweir 							| SwCrsrShell::UPDOWN | SwCrsrShell::CHKRANGE);
560cdf0e10cSrcweir 			UpdateCrsr( static_cast<sal_uInt16>(eUpdtMode) );
561cdf0e10cSrcweir 		}
562cdf0e10cSrcweir 	}
563cdf0e10cSrcweir 	return bRet;
564cdf0e10cSrcweir }
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 
LRMargin(sal_Bool bLeft,sal_Bool bAPI)567cdf0e10cSrcweir sal_Bool SwCrsrShell::LRMargin( sal_Bool bLeft, sal_Bool bAPI)
568cdf0e10cSrcweir {
569cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
570cdf0e10cSrcweir 	SET_CURR_SHELL( this );
571cdf0e10cSrcweir 	eMvState = MV_LEFTMARGIN;		// Status fuers Crsr-Travelling - GetCrsrOfst
572cdf0e10cSrcweir 
573cdf0e10cSrcweir     const sal_Bool bTableMode = IsTableMode();
574cdf0e10cSrcweir 	SwShellCrsr* pTmpCrsr = getShellCrsr( true );
575cdf0e10cSrcweir 
576cdf0e10cSrcweir     if( pBlockCrsr )
577cdf0e10cSrcweir         pBlockCrsr->clearPoints();
578cdf0e10cSrcweir 
579cdf0e10cSrcweir     const sal_Bool bWasAtLM =
580cdf0e10cSrcweir             ( 0 == _GetCrsr()->GetPoint()->nContent.GetIndex() );
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	sal_Bool bRet = pTmpCrsr->LeftRightMargin( bLeft, bAPI );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir     if ( bLeft && !bTableMode && bRet && bWasAtLM && !_GetCrsr()->HasMark() )
585cdf0e10cSrcweir     {
586cdf0e10cSrcweir         const SwTxtNode * pTxtNd = _GetCrsr()->GetNode()->GetTxtNode();
587cdf0e10cSrcweir         if ( pTxtNd && pTxtNd->HasVisibleNumberingOrBullet() )
588cdf0e10cSrcweir             SetInFrontOfLabel( sal_True );
589cdf0e10cSrcweir     }
590cdf0e10cSrcweir     else if ( !bLeft )
591cdf0e10cSrcweir     {
592cdf0e10cSrcweir         bRet = SetInFrontOfLabel( sal_False ) || bRet;
593cdf0e10cSrcweir     }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 	if( bRet )
596cdf0e10cSrcweir     {
597cdf0e10cSrcweir 		UpdateCrsr();
598cdf0e10cSrcweir     }
599cdf0e10cSrcweir 	return bRet;
600cdf0e10cSrcweir }
601cdf0e10cSrcweir 
IsAtLRMargin(sal_Bool bLeft,sal_Bool bAPI) const602cdf0e10cSrcweir sal_Bool SwCrsrShell::IsAtLRMargin( sal_Bool bLeft, sal_Bool bAPI ) const
603cdf0e10cSrcweir {
604cdf0e10cSrcweir 	const SwShellCrsr* pTmpCrsr = getShellCrsr( true );
605cdf0e10cSrcweir 	return pTmpCrsr->IsAtLeftRightMargin( bLeft, bAPI );
606cdf0e10cSrcweir }
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 
SttEndDoc(sal_Bool bStt)609cdf0e10cSrcweir sal_Bool SwCrsrShell::SttEndDoc( sal_Bool bStt )
610cdf0e10cSrcweir {
611cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
612cdf0e10cSrcweir 
613cdf0e10cSrcweir     SwShellCrsr* pTmpCrsr = pBlockCrsr ? &pBlockCrsr->getShellCrsr() : pCurCrsr;
614cdf0e10cSrcweir 	sal_Bool bRet = pTmpCrsr->SttEndDoc( bStt );
615cdf0e10cSrcweir 	if( bRet )
616cdf0e10cSrcweir 	{
617cdf0e10cSrcweir 		if( bStt )
618cdf0e10cSrcweir 			pTmpCrsr->GetPtPos().Y() = 0;		// expl. 0 setzen (TabellenHeader)
619cdf0e10cSrcweir         if( pBlockCrsr )
620cdf0e10cSrcweir         {
621cdf0e10cSrcweir             pBlockCrsr->clearPoints();
622cdf0e10cSrcweir             RefreshBlockCursor();
623cdf0e10cSrcweir         }
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
626cdf0e10cSrcweir 	}
627cdf0e10cSrcweir 	return bRet;
628cdf0e10cSrcweir }
629cdf0e10cSrcweir 
ExtendedSelectAll()630cdf0e10cSrcweir void SwCrsrShell::ExtendedSelectAll()
631cdf0e10cSrcweir {
632cdf0e10cSrcweir     SwNodes& rNodes = GetDoc()->GetNodes();
633cdf0e10cSrcweir     SwPosition* pPos = pCurCrsr->GetPoint();
634cdf0e10cSrcweir     pPos->nNode = rNodes.GetEndOfPostIts();
635cdf0e10cSrcweir     pPos->nContent.Assign( rNodes.GoNext( &pPos->nNode ), 0 );
636cdf0e10cSrcweir     pPos = pCurCrsr->GetMark();
637cdf0e10cSrcweir     pPos->nNode = rNodes.GetEndOfContent();
638cdf0e10cSrcweir     SwCntntNode* pCNd = rNodes.GoPrevious( &pPos->nNode );
639cdf0e10cSrcweir     pPos->nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
640cdf0e10cSrcweir }
641cdf0e10cSrcweir 
MovePage(SwWhichPage fnWhichPage,SwPosPage fnPosPage)642cdf0e10cSrcweir sal_Bool SwCrsrShell::MovePage( SwWhichPage fnWhichPage, SwPosPage fnPosPage )
643cdf0e10cSrcweir {
644cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
645cdf0e10cSrcweir 
646cdf0e10cSrcweir 	// Springe beim Selektieren nie ueber Section-Grenzen !!
647cdf0e10cSrcweir 	if( !pCurCrsr->HasMark() || !pCurCrsr->IsNoCntnt() )
648cdf0e10cSrcweir 	{
649cdf0e10cSrcweir 		SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
650cdf0e10cSrcweir 		SET_CURR_SHELL( this );
651cdf0e10cSrcweir 
652cdf0e10cSrcweir 		SwCrsrSaveState aSaveState( *pCurCrsr );
653cdf0e10cSrcweir 		Point& rPt = pCurCrsr->GetPtPos();
654cdf0e10cSrcweir 		SwCntntFrm * pFrm = pCurCrsr->GetCntntNode()->
655cdf0e10cSrcweir 							getLayoutFrm( GetLayout(), &rPt, pCurCrsr->GetPoint(), sal_False );
656cdf0e10cSrcweir 		if( pFrm && sal_True == ( bRet = GetFrmInPage( pFrm, fnWhichPage,
657cdf0e10cSrcweir 												fnPosPage, pCurCrsr )  ) &&
658cdf0e10cSrcweir             !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
659cdf0e10cSrcweir                                  nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ))
660cdf0e10cSrcweir 			UpdateCrsr();
661cdf0e10cSrcweir 		else
662cdf0e10cSrcweir 			bRet = sal_False;
663cdf0e10cSrcweir 	}
664cdf0e10cSrcweir 	return bRet;
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 
MovePara(SwWhichPara fnWhichPara,SwPosPara fnPosPara)668cdf0e10cSrcweir sal_Bool SwCrsrShell::MovePara(SwWhichPara fnWhichPara, SwPosPara fnPosPara )
669cdf0e10cSrcweir {
670cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
671cdf0e10cSrcweir     SwCursor* pTmpCrsr = getShellCrsr( true );
672cdf0e10cSrcweir 	sal_Bool bRet = pTmpCrsr->MovePara( fnWhichPara, fnPosPara );
673cdf0e10cSrcweir 	if( bRet )
674cdf0e10cSrcweir 		UpdateCrsr();
675cdf0e10cSrcweir 	return bRet;
676cdf0e10cSrcweir }
677cdf0e10cSrcweir 
678cdf0e10cSrcweir 
MoveSection(SwWhichSection fnWhichSect,SwPosSection fnPosSect)679cdf0e10cSrcweir sal_Bool SwCrsrShell::MoveSection( SwWhichSection fnWhichSect,
680cdf0e10cSrcweir 								SwPosSection fnPosSect)
681cdf0e10cSrcweir {
682cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
683cdf0e10cSrcweir     SwCursor* pTmpCrsr = getShellCrsr( true );
684cdf0e10cSrcweir 	sal_Bool bRet = pTmpCrsr->MoveSection( fnWhichSect, fnPosSect );
685cdf0e10cSrcweir 	if( bRet )
686cdf0e10cSrcweir 		UpdateCrsr();
687cdf0e10cSrcweir 	return bRet;
688cdf0e10cSrcweir 
689cdf0e10cSrcweir }
690cdf0e10cSrcweir 
691cdf0e10cSrcweir 
692cdf0e10cSrcweir // Positionieren des Cursors
693cdf0e10cSrcweir 
694cdf0e10cSrcweir 
lcl_IsInHeaderFooter(const SwNodeIndex & rIdx,Point & rPt)695cdf0e10cSrcweir SwFrm* lcl_IsInHeaderFooter( const SwNodeIndex& rIdx, Point& rPt )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir 	SwFrm* pFrm = 0;
698cdf0e10cSrcweir 	SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode();
699cdf0e10cSrcweir 	if( pCNd )
700cdf0e10cSrcweir 	{
701cdf0e10cSrcweir 		pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &rPt, 0, sal_False )->GetUpper();
702cdf0e10cSrcweir 		while( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() )
703cdf0e10cSrcweir             pFrm = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->AnchorFrm()
704cdf0e10cSrcweir 									: pFrm->GetUpper();
705cdf0e10cSrcweir 	}
706cdf0e10cSrcweir 	return pFrm;
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
IsInHeaderFooter(sal_Bool * pbInHeader) const709cdf0e10cSrcweir sal_Bool SwCrsrShell::IsInHeaderFooter( sal_Bool* pbInHeader ) const
710cdf0e10cSrcweir {
711cdf0e10cSrcweir 	Point aPt;
712cdf0e10cSrcweir 	SwFrm* pFrm = ::lcl_IsInHeaderFooter( pCurCrsr->GetPoint()->nNode, aPt );
713cdf0e10cSrcweir 	if( pFrm && pbInHeader )
714cdf0e10cSrcweir 		*pbInHeader = pFrm->IsHeaderFrm();
715cdf0e10cSrcweir 	return 0 != pFrm;
716cdf0e10cSrcweir }
717cdf0e10cSrcweir 
SetCrsr(const Point & rLPt,sal_Bool bOnlyText,bool bBlock)718cdf0e10cSrcweir int SwCrsrShell::SetCrsr( const Point &rLPt, sal_Bool bOnlyText, bool bBlock )
719cdf0e10cSrcweir {
720cdf0e10cSrcweir 	SET_CURR_SHELL( this );
721cdf0e10cSrcweir 
722cdf0e10cSrcweir 	SwShellCrsr* pCrsr = getShellCrsr( bBlock );
723cdf0e10cSrcweir 	SwPosition aPos( *pCrsr->GetPoint() );
724cdf0e10cSrcweir 	Point aPt( rLPt );
725cdf0e10cSrcweir 	Point & rAktCrsrPt = pCrsr->GetPtPos();
726cdf0e10cSrcweir 	SwCrsrMoveState aTmpState( IsTableMode() ? MV_TBLSEL :
727cdf0e10cSrcweir 									bOnlyText ?  MV_SETONLYTEXT : MV_NONE );
728cdf0e10cSrcweir 	aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
729cdf0e10cSrcweir 
730cdf0e10cSrcweir     SwTxtNode * pTxtNd = pCrsr->GetNode()->GetTxtNode();
731cdf0e10cSrcweir 
732cdf0e10cSrcweir     if ( pTxtNd && !IsTableMode() &&
733cdf0e10cSrcweir         // --> FME 2004-11-25 #i37515# No bInFrontOfLabel during selection
734cdf0e10cSrcweir         !pCrsr->HasMark() &&
735cdf0e10cSrcweir         // <--
736cdf0e10cSrcweir         pTxtNd->HasVisibleNumberingOrBullet() )
737cdf0e10cSrcweir     {
738cdf0e10cSrcweir         aTmpState.bInFrontOfLabel = sal_True; // #i27615#
739cdf0e10cSrcweir     }
740cdf0e10cSrcweir     else
741cdf0e10cSrcweir     {
742cdf0e10cSrcweir         aTmpState.bInFrontOfLabel = sal_False;
743cdf0e10cSrcweir     }
744cdf0e10cSrcweir 
745cdf0e10cSrcweir 	int bRet = CRSR_POSOLD |
746cdf0e10cSrcweir 				( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState )
747cdf0e10cSrcweir 					? 0 : CRSR_POSCHG );
748cdf0e10cSrcweir 
749cdf0e10cSrcweir     const bool bOldInFrontOfLabel = IsInFrontOfLabel();
750cdf0e10cSrcweir     const bool bNewInFrontOfLabel = aTmpState.bInFrontOfLabel;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir     pCrsr->SetCrsrBidiLevel( aTmpState.nCursorBidiLevel );
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 	if( MV_RIGHTMARGIN == aTmpState.eState )
755cdf0e10cSrcweir 		eMvState = MV_RIGHTMARGIN;
756cdf0e10cSrcweir 	// steht neu Pos im Header/Footer ?
757cdf0e10cSrcweir 	SwFrm* pFrm = lcl_IsInHeaderFooter( aPos.nNode, aPt );
758cdf0e10cSrcweir     if( IsTableMode() && !pFrm && aPos.nNode.GetNode().StartOfSectionNode() ==
759cdf0e10cSrcweir         pCrsr->GetPoint()->nNode.GetNode().StartOfSectionNode() )
760cdf0e10cSrcweir 		// gleiche Tabellenzelle und nicht im Header/Footer
761cdf0e10cSrcweir 		// -> zurueck
762cdf0e10cSrcweir 		return bRet;
763cdf0e10cSrcweir 
764cdf0e10cSrcweir     if( pBlockCrsr && bBlock )
765cdf0e10cSrcweir     {
766cdf0e10cSrcweir         pBlockCrsr->setEndPoint( rLPt );
767cdf0e10cSrcweir         if( !pCrsr->HasMark() )
768cdf0e10cSrcweir             pBlockCrsr->setStartPoint( rLPt );
769cdf0e10cSrcweir         else if( !pBlockCrsr->getStartPoint() )
770cdf0e10cSrcweir             pBlockCrsr->setStartPoint( pCrsr->GetMkPos() );
771cdf0e10cSrcweir     }
772cdf0e10cSrcweir 	if( !pCrsr->HasMark() )
773cdf0e10cSrcweir 	{
774cdf0e10cSrcweir 		// steht an der gleichen Position und wenn im Header/Footer,
775cdf0e10cSrcweir 		// dann im gleichen
776cdf0e10cSrcweir 		if( aPos == *pCrsr->GetPoint() &&
777cdf0e10cSrcweir             bOldInFrontOfLabel == bNewInFrontOfLabel )
778cdf0e10cSrcweir 		{
779cdf0e10cSrcweir 			if( pFrm )
780cdf0e10cSrcweir 			{
781cdf0e10cSrcweir 				if( pFrm->Frm().IsInside( rAktCrsrPt ))
782cdf0e10cSrcweir 					return bRet;
783cdf0e10cSrcweir 			}
784cdf0e10cSrcweir 			else if( aPos.nNode.GetNode().IsCntntNode() )
785cdf0e10cSrcweir 			{
786cdf0e10cSrcweir 				// im gleichen Frame gelandet?
787cdf0e10cSrcweir 				SwFrm* pOld = ((SwCntntNode&)aPos.nNode.GetNode()).getLayoutFrm(
788cdf0e10cSrcweir                                 GetLayout(), &aCharRect.Pos(), 0, sal_False );
789cdf0e10cSrcweir 				SwFrm* pNew = ((SwCntntNode&)aPos.nNode.GetNode()).getLayoutFrm(
790cdf0e10cSrcweir                                 GetLayout(), &aPt, 0, sal_False );
791cdf0e10cSrcweir 				if( pNew == pOld )
792cdf0e10cSrcweir 					return bRet;
793cdf0e10cSrcweir 			}
794cdf0e10cSrcweir 		}
795cdf0e10cSrcweir 	}
796cdf0e10cSrcweir 	else
797cdf0e10cSrcweir 	{
798cdf0e10cSrcweir 		// SSelection ueber nicht erlaubte Sections oder wenn im Header/Footer
799cdf0e10cSrcweir 		// dann in verschiedene
800cdf0e10cSrcweir 		if( !CheckNodesRange( aPos.nNode, pCrsr->GetMark()->nNode, sal_True )
801cdf0e10cSrcweir 			|| ( pFrm && !pFrm->Frm().IsInside( pCrsr->GetMkPos() ) ))
802cdf0e10cSrcweir 			return bRet;
803cdf0e10cSrcweir 
804cdf0e10cSrcweir 		// steht an der gleichen Position und nicht im Header/Footer
805cdf0e10cSrcweir 		if( aPos == *pCrsr->GetPoint() )
806cdf0e10cSrcweir 			return bRet;
807cdf0e10cSrcweir 	}
808cdf0e10cSrcweir 
809cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
810cdf0e10cSrcweir 	SwCrsrSaveState aSaveState( *pCrsr );
811cdf0e10cSrcweir 
812cdf0e10cSrcweir 	*pCrsr->GetPoint() = aPos;
813cdf0e10cSrcweir 	rAktCrsrPt = aPt;
814cdf0e10cSrcweir 
815cdf0e10cSrcweir     // --> FME 2005-01-31 #i41424# Only update the marked number levels if necessary
816cdf0e10cSrcweir     // Force update of marked number levels if necessary.
817cdf0e10cSrcweir     if ( bNewInFrontOfLabel || bOldInFrontOfLabel )
818cdf0e10cSrcweir         pCurCrsr->_SetInFrontOfLabel( !bNewInFrontOfLabel );
819cdf0e10cSrcweir     SetInFrontOfLabel( bNewInFrontOfLabel );
820cdf0e10cSrcweir     // <--
821cdf0e10cSrcweir 
822cdf0e10cSrcweir     if( !pCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
823cdf0e10cSrcweir 	{
824cdf0e10cSrcweir         sal_uInt16 nFlag = SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE;
825cdf0e10cSrcweir 		UpdateCrsr( nFlag );
826cdf0e10cSrcweir 		bRet &= ~CRSR_POSOLD;
827cdf0e10cSrcweir 	}
828cdf0e10cSrcweir 	else if( bOnlyText && !pCurCrsr->HasMark() )
829cdf0e10cSrcweir 	{
830cdf0e10cSrcweir 		if( FindValidCntntNode( bOnlyText ) )
831cdf0e10cSrcweir 		{
832cdf0e10cSrcweir 			// Cursor in einen gueltigen Content stellen
833cdf0e10cSrcweir 			if( aPos == *pCrsr->GetPoint() )
834cdf0e10cSrcweir 				bRet = CRSR_POSOLD;
835cdf0e10cSrcweir 			else
836cdf0e10cSrcweir 			{
837cdf0e10cSrcweir 				UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE );
838cdf0e10cSrcweir 				bRet &= ~CRSR_POSOLD;
839cdf0e10cSrcweir 			}
840cdf0e10cSrcweir 		}
841cdf0e10cSrcweir 		else
842cdf0e10cSrcweir 		{
843cdf0e10cSrcweir 			// es gibt keinen gueltigen Inhalt -> Cursor verstecken
844cdf0e10cSrcweir 			pVisCrsr->Hide();       // sichtbaren Cursor immer verstecken
845cdf0e10cSrcweir 			eMvState = MV_NONE;		// Status fuers Crsr-Travelling
846cdf0e10cSrcweir 			bAllProtect = sal_True;
847cdf0e10cSrcweir 			if( GetDoc()->GetDocShell() )
848cdf0e10cSrcweir 			{
849cdf0e10cSrcweir 				GetDoc()->GetDocShell()->SetReadOnlyUI( sal_True );
850cdf0e10cSrcweir 				CallChgLnk();			// UI bescheid sagen!
851cdf0e10cSrcweir 			}
852cdf0e10cSrcweir 		}
853cdf0e10cSrcweir 	}
854cdf0e10cSrcweir 
855cdf0e10cSrcweir 	return bRet;
856cdf0e10cSrcweir }
857cdf0e10cSrcweir 
858cdf0e10cSrcweir 
TblCrsrToCursor()859cdf0e10cSrcweir void SwCrsrShell::TblCrsrToCursor()
860cdf0e10cSrcweir {
861cdf0e10cSrcweir 	ASSERT( pTblCrsr, "TblCrsrToCursor: Why?" );
862cdf0e10cSrcweir 	delete pTblCrsr, pTblCrsr = 0;
863cdf0e10cSrcweir }
864cdf0e10cSrcweir 
BlockCrsrToCrsr()865cdf0e10cSrcweir void SwCrsrShell::BlockCrsrToCrsr()
866cdf0e10cSrcweir {
867cdf0e10cSrcweir 	ASSERT( pBlockCrsr, "BlockCrsrToCrsr: Why?" );
868cdf0e10cSrcweir     if( pBlockCrsr && !HasSelection() )
869cdf0e10cSrcweir     {
870cdf0e10cSrcweir         SwPaM& rPam = pBlockCrsr->getShellCrsr();
871cdf0e10cSrcweir         pCurCrsr->SetMark();
872cdf0e10cSrcweir         *pCurCrsr->GetPoint() = *rPam.GetPoint();
873cdf0e10cSrcweir         if( rPam.HasMark() )
874cdf0e10cSrcweir             *pCurCrsr->GetMark() = *rPam.GetMark();
875cdf0e10cSrcweir         else
876cdf0e10cSrcweir             pCurCrsr->DeleteMark();
877cdf0e10cSrcweir     }
878cdf0e10cSrcweir 	delete pBlockCrsr, pBlockCrsr = 0;
879cdf0e10cSrcweir }
880cdf0e10cSrcweir 
CrsrToBlockCrsr()881cdf0e10cSrcweir void SwCrsrShell::CrsrToBlockCrsr()
882cdf0e10cSrcweir {
883cdf0e10cSrcweir     if( !pBlockCrsr )
884cdf0e10cSrcweir     {
885cdf0e10cSrcweir         SwPosition aPos( *pCurCrsr->GetPoint() );
886cdf0e10cSrcweir         pBlockCrsr = createBlockCursor( *this, aPos );
887cdf0e10cSrcweir         SwShellCrsr &rBlock = pBlockCrsr->getShellCrsr();
888cdf0e10cSrcweir         rBlock.GetPtPos() = pCurCrsr->GetPtPos();
889cdf0e10cSrcweir         if( pCurCrsr->HasMark() )
890cdf0e10cSrcweir         {
891cdf0e10cSrcweir             rBlock.SetMark();
892cdf0e10cSrcweir             *rBlock.GetMark() = *pCurCrsr->GetMark();
893cdf0e10cSrcweir             rBlock.GetMkPos() = pCurCrsr->GetMkPos();
894cdf0e10cSrcweir         }
895cdf0e10cSrcweir     }
896cdf0e10cSrcweir     pBlockCrsr->clearPoints();
897cdf0e10cSrcweir     RefreshBlockCursor();
898cdf0e10cSrcweir }
899cdf0e10cSrcweir 
ClearMark()900cdf0e10cSrcweir void SwCrsrShell::ClearMark()
901cdf0e10cSrcweir {
902cdf0e10cSrcweir 	// ist ueberhaupt ein GetMark gesetzt ?
903cdf0e10cSrcweir 	if( pTblCrsr )
904cdf0e10cSrcweir 	{
905cdf0e10cSrcweir 		while( pCurCrsr->GetNext() != pCurCrsr )
906cdf0e10cSrcweir 			delete pCurCrsr->GetNext();
907cdf0e10cSrcweir 		pTblCrsr->DeleteMark();
908cdf0e10cSrcweir 
909cdf0e10cSrcweir 		if( pCurCrsr->HasMark() )
910cdf0e10cSrcweir 		{
911cdf0e10cSrcweir 			// falls doch nicht alle Indizies richtig verschoben werden
912cdf0e10cSrcweir 			//	(z.B.: Kopf-/Fusszeile loeschen) den Content-Anteil vom
913cdf0e10cSrcweir 			//	Mark aufs Nodes-Array setzen
914cdf0e10cSrcweir 			SwPosition& rPos = *pCurCrsr->GetMark();
915cdf0e10cSrcweir 			rPos.nNode.Assign( pDoc->GetNodes(), 0 );
916cdf0e10cSrcweir 			rPos.nContent.Assign( 0, 0 );
917cdf0e10cSrcweir 			pCurCrsr->DeleteMark();
918cdf0e10cSrcweir 		}
919cdf0e10cSrcweir 
920cdf0e10cSrcweir 		*pCurCrsr->GetPoint() = *pTblCrsr->GetPoint();
921cdf0e10cSrcweir 		pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos();
922cdf0e10cSrcweir 		delete pTblCrsr, pTblCrsr = 0;
923cdf0e10cSrcweir 		pCurCrsr->SwSelPaintRects::Show();
924cdf0e10cSrcweir 	}
925cdf0e10cSrcweir 	else
926cdf0e10cSrcweir 	{
927cdf0e10cSrcweir 		if( !pCurCrsr->HasMark() )
928cdf0e10cSrcweir 			return;
929cdf0e10cSrcweir 		// falls doch nicht alle Indizies richtig verschoben werden
930cdf0e10cSrcweir 		//	(z.B.: Kopf-/Fusszeile loeschen) den Content-Anteil vom
931cdf0e10cSrcweir 		//	Mark aufs Nodes-Array setzen
932cdf0e10cSrcweir 		SwPosition& rPos = *pCurCrsr->GetMark();
933cdf0e10cSrcweir 		rPos.nNode.Assign( pDoc->GetNodes(), 0 );
934cdf0e10cSrcweir 		rPos.nContent.Assign( 0, 0 );
935cdf0e10cSrcweir 		pCurCrsr->DeleteMark();
936cdf0e10cSrcweir 		if( !nCrsrMove )
937cdf0e10cSrcweir 			pCurCrsr->SwSelPaintRects::Show();
938cdf0e10cSrcweir 	}
939cdf0e10cSrcweir }
940cdf0e10cSrcweir 
941cdf0e10cSrcweir 
NormalizePam(sal_Bool bPointFirst)942cdf0e10cSrcweir void SwCrsrShell::NormalizePam(sal_Bool bPointFirst)
943cdf0e10cSrcweir {
944cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
945cdf0e10cSrcweir     pCurCrsr->Normalize(bPointFirst);
946cdf0e10cSrcweir }
947cdf0e10cSrcweir 
SwapPam()948cdf0e10cSrcweir void SwCrsrShell::SwapPam()
949cdf0e10cSrcweir {
950cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
951cdf0e10cSrcweir 	pCurCrsr->Exchange();
952cdf0e10cSrcweir }
953cdf0e10cSrcweir 
954cdf0e10cSrcweir 
955cdf0e10cSrcweir // suche innerhalb der Selektierten-Bereiche nach einer Selektion, die
956cdf0e10cSrcweir // den angebenen SPoint umschliesst
957cdf0e10cSrcweir // Ist das Flag bTstOnly gesetzt, dann wird nur getestet, ob dort eine
958cdf0e10cSrcweir // SSelection besteht; des akt. Cursr wird nicht umgesetzt!
959cdf0e10cSrcweir // Ansonsten wird er auf die gewaehlte SSelection gesetzt.
960cdf0e10cSrcweir 
961cdf0e10cSrcweir 
ChgCurrPam(const Point & rPt,sal_Bool bTstOnly,sal_Bool bTstHit)96269a74367SOliver-Rainer Wittmann sal_Bool SwCrsrShell::ChgCurrPam(
96369a74367SOliver-Rainer Wittmann     const Point & rPt,
96469a74367SOliver-Rainer Wittmann     sal_Bool bTstOnly,
96569a74367SOliver-Rainer Wittmann     sal_Bool bTstHit )
966cdf0e10cSrcweir {
967cdf0e10cSrcweir 	SET_CURR_SHELL( this );
968cdf0e10cSrcweir 
969cdf0e10cSrcweir 	// Pruefe ob der SPoint in einer Tabellen-Selektion liegt
970cdf0e10cSrcweir 	if( bTstOnly && pTblCrsr )
971cdf0e10cSrcweir 		return pTblCrsr->IsInside( rPt );
972cdf0e10cSrcweir 
973cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
974cdf0e10cSrcweir 	// Suche die Position rPt im Dokument
975cdf0e10cSrcweir 	SwPosition aPtPos( *pCurCrsr->GetPoint() );
976cdf0e10cSrcweir 	Point aPt( rPt );
977cdf0e10cSrcweir 
978cdf0e10cSrcweir 	SwCrsrMoveState aTmpState( MV_NONE );
979cdf0e10cSrcweir 	aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
980cdf0e10cSrcweir 	if ( !GetLayout()->GetCrsrOfst( &aPtPos, aPt, &aTmpState ) && bTstHit )
981cdf0e10cSrcweir 		return sal_False;
982cdf0e10cSrcweir 
983cdf0e10cSrcweir 	// suche in allen Selektionen nach dieser Position
984cdf0e10cSrcweir 	SwShellCrsr* pCmp = (SwShellCrsr*)pCurCrsr;        // sicher den Pointer auf Cursor
985cdf0e10cSrcweir 	do {
986cdf0e10cSrcweir 		if( pCmp->HasMark() &&
987cdf0e10cSrcweir 			*pCmp->Start() <= aPtPos && *pCmp->End() > aPtPos )
988cdf0e10cSrcweir 		{
989cdf0e10cSrcweir 			if( bTstOnly || pCurCrsr == pCmp )	   // ist der aktuelle.
990cdf0e10cSrcweir 				return sal_True;         			   // return ohne Update
991cdf0e10cSrcweir 
992cdf0e10cSrcweir 			pCurCrsr = pCmp;
993cdf0e10cSrcweir 			UpdateCrsr();     // Cursor steht schon richtig
994cdf0e10cSrcweir 			return sal_True;
995cdf0e10cSrcweir 		}
996cdf0e10cSrcweir 	} while( pCurCrsr !=
997cdf0e10cSrcweir         ( pCmp = dynamic_cast<SwShellCrsr*>(pCmp->GetNext()) ) );
998cdf0e10cSrcweir 	return sal_False;
999cdf0e10cSrcweir }
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir 
KillPams()1002cdf0e10cSrcweir void SwCrsrShell::KillPams()
1003cdf0e10cSrcweir {
1004cdf0e10cSrcweir 	// keiner zum loeschen vorhanden?
1005cdf0e10cSrcweir 	if( !pTblCrsr && !pBlockCrsr && pCurCrsr->GetNext() == pCurCrsr )
1006cdf0e10cSrcweir 		return;
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir 	while( pCurCrsr->GetNext() != pCurCrsr )
1009cdf0e10cSrcweir 		delete pCurCrsr->GetNext();
1010cdf0e10cSrcweir     pCurCrsr->SetColumnSelection( false );
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir 	if( pTblCrsr )
1013cdf0e10cSrcweir 	{
1014cdf0e10cSrcweir 		// Cursor Ring loeschen
1015cdf0e10cSrcweir 		pCurCrsr->DeleteMark();
1016cdf0e10cSrcweir 		*pCurCrsr->GetPoint() = *pTblCrsr->GetPoint();
1017cdf0e10cSrcweir 		pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos();
1018cdf0e10cSrcweir 		delete pTblCrsr;
1019cdf0e10cSrcweir         pTblCrsr = 0;
1020cdf0e10cSrcweir 	}
1021cdf0e10cSrcweir     else if( pBlockCrsr )
1022cdf0e10cSrcweir 	{
1023cdf0e10cSrcweir 		// delete the ring of cursors
1024cdf0e10cSrcweir 		pCurCrsr->DeleteMark();
1025cdf0e10cSrcweir         SwShellCrsr &rBlock = pBlockCrsr->getShellCrsr();
1026cdf0e10cSrcweir 		*pCurCrsr->GetPoint() = *rBlock.GetPoint();
1027cdf0e10cSrcweir 		pCurCrsr->GetPtPos() = rBlock.GetPtPos();
1028cdf0e10cSrcweir 		rBlock.DeleteMark();
1029cdf0e10cSrcweir         pBlockCrsr->clearPoints();
1030cdf0e10cSrcweir 	}
1031cdf0e10cSrcweir 	UpdateCrsr( SwCrsrShell::SCROLLWIN );
1032cdf0e10cSrcweir }
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir 
CompareCursor(CrsrCompareType eType) const1035cdf0e10cSrcweir int SwCrsrShell::CompareCursor( CrsrCompareType eType ) const
1036cdf0e10cSrcweir {
1037cdf0e10cSrcweir 	int nRet = 0;
1038cdf0e10cSrcweir 	const SwPosition *pFirst = 0, *pSecond = 0;
1039cdf0e10cSrcweir 	const SwPaM *pCur = GetCrsr(), *pStk = pCrsrStk;
1040cdf0e10cSrcweir 	if( CurrPtCurrMk != eType && pStk )
1041cdf0e10cSrcweir 	{
1042cdf0e10cSrcweir 		switch ( eType)
1043cdf0e10cSrcweir 		{
1044cdf0e10cSrcweir 		case StackPtStackMk:
1045cdf0e10cSrcweir 			pFirst = pStk->GetPoint();
1046cdf0e10cSrcweir 			pSecond = pStk->GetMark();
1047cdf0e10cSrcweir 			break;
1048cdf0e10cSrcweir 		case StackPtCurrPt:
1049cdf0e10cSrcweir 			pFirst = pStk->GetPoint();
1050cdf0e10cSrcweir 			pSecond = pCur->GetPoint();
1051cdf0e10cSrcweir 			break;
1052cdf0e10cSrcweir 		case StackPtCurrMk:
1053cdf0e10cSrcweir 			pFirst = pStk->GetPoint();
1054cdf0e10cSrcweir 			pSecond = pCur->GetMark();
1055cdf0e10cSrcweir 			break;
1056cdf0e10cSrcweir 		case StackMkCurrPt:
1057cdf0e10cSrcweir 			pFirst = pStk->GetMark();
1058cdf0e10cSrcweir 			pSecond = pCur->GetPoint();
1059cdf0e10cSrcweir 			break;
1060cdf0e10cSrcweir 		case StackMkCurrMk:
1061cdf0e10cSrcweir 			pFirst = pStk->GetMark();
1062cdf0e10cSrcweir 			pSecond = pStk->GetMark();
1063cdf0e10cSrcweir 			break;
1064cdf0e10cSrcweir 		case CurrPtCurrMk:
1065cdf0e10cSrcweir 			pFirst = pCur->GetPoint();
1066cdf0e10cSrcweir 			pSecond = pCur->GetMark();
1067cdf0e10cSrcweir 			break;
1068cdf0e10cSrcweir 		}
1069cdf0e10cSrcweir 	}
1070cdf0e10cSrcweir 	if( !pFirst || !pSecond )
1071cdf0e10cSrcweir 		nRet = INT_MAX;
1072cdf0e10cSrcweir 	else if( *pFirst < *pSecond )
1073cdf0e10cSrcweir 		nRet = -1;
1074cdf0e10cSrcweir 	else if( *pFirst == *pSecond )
1075cdf0e10cSrcweir 		nRet = 0;
1076cdf0e10cSrcweir 	else
1077cdf0e10cSrcweir 		nRet = 1;
1078cdf0e10cSrcweir 	return nRet;
1079cdf0e10cSrcweir }
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir 
IsSttPara() const1082cdf0e10cSrcweir sal_Bool SwCrsrShell::IsSttPara() const
1083cdf0e10cSrcweir {   return( pCurCrsr->GetPoint()->nContent == 0 ? sal_True : sal_False ); }
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir 
IsEndPara() const1086cdf0e10cSrcweir sal_Bool SwCrsrShell::IsEndPara() const
1087cdf0e10cSrcweir {   return( pCurCrsr->GetPoint()->nContent == pCurCrsr->GetCntntNode()->Len() ? sal_True : sal_False ); }
1088cdf0e10cSrcweir 
1089cdf0e10cSrcweir 
IsInFrontOfLabel() const1090cdf0e10cSrcweir sal_Bool SwCrsrShell::IsInFrontOfLabel() const
1091cdf0e10cSrcweir {
1092cdf0e10cSrcweir     return pCurCrsr->IsInFrontOfLabel();
1093cdf0e10cSrcweir }
1094cdf0e10cSrcweir 
SetInFrontOfLabel(sal_Bool bNew)1095cdf0e10cSrcweir bool SwCrsrShell::SetInFrontOfLabel( sal_Bool bNew )
1096cdf0e10cSrcweir {
1097cdf0e10cSrcweir     if ( bNew != IsInFrontOfLabel() )
1098cdf0e10cSrcweir     {
1099cdf0e10cSrcweir         pCurCrsr->_SetInFrontOfLabel( bNew );
1100cdf0e10cSrcweir         UpdateMarkedListLevel();
1101cdf0e10cSrcweir         return true;
1102cdf0e10cSrcweir     }
1103cdf0e10cSrcweir     return false;
1104cdf0e10cSrcweir }
1105cdf0e10cSrcweir 
GotoPage(sal_uInt16 nPage)1106cdf0e10cSrcweir sal_Bool SwCrsrShell::GotoPage( sal_uInt16 nPage )
1107cdf0e10cSrcweir {
1108cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1109cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1110cdf0e10cSrcweir 	SwCrsrSaveState aSaveState( *pCurCrsr );
1111cdf0e10cSrcweir 	sal_Bool bRet = GetLayout()->SetCurrPage( pCurCrsr, nPage ) &&
1112cdf0e10cSrcweir                     !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
1113cdf0e10cSrcweir                                          nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
1114cdf0e10cSrcweir 	if( bRet )
1115cdf0e10cSrcweir 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
1116cdf0e10cSrcweir 	return bRet;
1117cdf0e10cSrcweir }
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir 
GetPageNum(sal_uInt16 & rnPhyNum,sal_uInt16 & rnVirtNum,sal_Bool bAtCrsrPos,const sal_Bool bCalcFrm)1120cdf0e10cSrcweir void SwCrsrShell::GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum,
1121cdf0e10cSrcweir 							  sal_Bool bAtCrsrPos, const sal_Bool bCalcFrm )
1122cdf0e10cSrcweir {
1123cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1124cdf0e10cSrcweir 	// Seitennummer: die erste sichtbare Seite oder die am Cursor
1125cdf0e10cSrcweir 	const SwCntntFrm* pCFrm;
1126cdf0e10cSrcweir 	const SwPageFrm *pPg = 0;
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir 	if( !bAtCrsrPos || 0 == (pCFrm = GetCurrFrm( bCalcFrm )) ||
1129cdf0e10cSrcweir 					   0 == (pPg   = pCFrm->FindPageFrm()) )
1130cdf0e10cSrcweir 	{
1131cdf0e10cSrcweir 		pPg = Imp()->GetFirstVisPage();
1132cdf0e10cSrcweir 		while( pPg && pPg->IsEmptyPage() )
1133cdf0e10cSrcweir 			pPg = (const SwPageFrm *)pPg->GetNext();
1134cdf0e10cSrcweir 	}
1135cdf0e10cSrcweir 	// Abfrage auf pPg muss fuer den Sonderfall Writerstart mit
1136cdf0e10cSrcweir 	// standard.vor sein.
1137cdf0e10cSrcweir 	rnPhyNum  = pPg? pPg->GetPhyPageNum() : 1;
1138cdf0e10cSrcweir 	rnVirtNum = pPg? pPg->GetVirtPageNum() : 1;
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir 
1141cdf0e10cSrcweir 
GetNextPrevPageNum(sal_Bool bNext)1142cdf0e10cSrcweir sal_uInt16 SwCrsrShell::GetNextPrevPageNum( sal_Bool bNext )
1143cdf0e10cSrcweir {
1144cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir 	// Seitennummer: die erste sichtbare Seite oder die am Cursor
1147cdf0e10cSrcweir 	const SwPageFrm *pPg = Imp()->GetFirstVisPage();
1148cdf0e10cSrcweir 	if( pPg )
1149cdf0e10cSrcweir 	{
1150cdf0e10cSrcweir         const SwTwips nPageTop = pPg->Frm().Top();
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir 		if( bNext )
1153cdf0e10cSrcweir 		{
1154cdf0e10cSrcweir             // go to next view layout row:
1155cdf0e10cSrcweir             do
1156cdf0e10cSrcweir             {
1157cdf0e10cSrcweir                 pPg = (const SwPageFrm *)pPg->GetNext();
1158cdf0e10cSrcweir             }
1159cdf0e10cSrcweir             while( pPg && pPg->Frm().Top() == nPageTop );
1160cdf0e10cSrcweir 
1161cdf0e10cSrcweir             while( pPg && pPg->IsEmptyPage() )
1162cdf0e10cSrcweir                 pPg = (const SwPageFrm *)pPg->GetNext();
1163cdf0e10cSrcweir         }
1164cdf0e10cSrcweir 		else
1165cdf0e10cSrcweir 		{
1166cdf0e10cSrcweir             // go to previous view layout row:
1167cdf0e10cSrcweir             do
1168cdf0e10cSrcweir             {
1169cdf0e10cSrcweir                 pPg = (const SwPageFrm *)pPg->GetPrev();
1170cdf0e10cSrcweir             }
1171cdf0e10cSrcweir             while( pPg && pPg->Frm().Top() == nPageTop );
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir             while( pPg && pPg->IsEmptyPage() )
1174cdf0e10cSrcweir                 pPg = (const SwPageFrm *)pPg->GetPrev();
1175cdf0e10cSrcweir         }
1176cdf0e10cSrcweir 	}
1177cdf0e10cSrcweir 	// Abfrage auf pPg muss fuer den Sonderfall Writerstart mit
1178cdf0e10cSrcweir 	// standard.vor sein.
1179cdf0e10cSrcweir 	return pPg ? pPg->GetPhyPageNum() : USHRT_MAX;
1180cdf0e10cSrcweir }
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir 
GetPageCnt()1183cdf0e10cSrcweir sal_uInt16 SwCrsrShell::GetPageCnt()
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1186cdf0e10cSrcweir 	// gebe die Anzahl der Seiten zurueck
1187cdf0e10cSrcweir 	return GetLayout()->GetPageNum();
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir 
1190cdf0e10cSrcweir // Gehe zur naechsten SSelection
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir 
GoNextCrsr()1193cdf0e10cSrcweir sal_Bool SwCrsrShell::GoNextCrsr()
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir 	// besteht ueberhaupt ein Ring ?
1196cdf0e10cSrcweir 	if( pCurCrsr->GetNext() == pCurCrsr )
1197cdf0e10cSrcweir 		return sal_False;
1198cdf0e10cSrcweir 
1199cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1200cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1201cdf0e10cSrcweir     pCurCrsr = dynamic_cast<SwShellCrsr*>(pCurCrsr->GetNext());
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir 	// Bug 24086: auch alle anderen anzeigen
1204cdf0e10cSrcweir 	if( !ActionPend() )
1205cdf0e10cSrcweir 	{
1206cdf0e10cSrcweir 		UpdateCrsr();
1207cdf0e10cSrcweir 		pCurCrsr->Show();
1208cdf0e10cSrcweir 	}
1209cdf0e10cSrcweir 	return sal_True;
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir // gehe zur vorherigen SSelection
1213cdf0e10cSrcweir 
1214cdf0e10cSrcweir 
GoPrevCrsr()1215cdf0e10cSrcweir sal_Bool SwCrsrShell::GoPrevCrsr()
1216cdf0e10cSrcweir {
1217cdf0e10cSrcweir 	// besteht ueberhaupt ein Ring ?
1218cdf0e10cSrcweir 	if( pCurCrsr->GetNext() == pCurCrsr )
1219cdf0e10cSrcweir 		return sal_False;
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1222cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
1223cdf0e10cSrcweir     pCurCrsr = dynamic_cast<SwShellCrsr*>(pCurCrsr->GetPrev());
1224cdf0e10cSrcweir 
1225cdf0e10cSrcweir 	// Bug 24086: auch alle anderen anzeigen
1226cdf0e10cSrcweir 	if( !ActionPend() )
1227cdf0e10cSrcweir 	{
1228cdf0e10cSrcweir 		UpdateCrsr();
1229cdf0e10cSrcweir 		pCurCrsr->Show();
1230cdf0e10cSrcweir 	}
1231cdf0e10cSrcweir 
1232cdf0e10cSrcweir 	return sal_True;
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir 
1235cdf0e10cSrcweir 
Paint(const Rectangle & rRect)1236cdf0e10cSrcweir void SwCrsrShell::Paint( const Rectangle &rRect)
1237cdf0e10cSrcweir {
1238cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir 	// beim Painten immer alle Cursor ausschalten
1241cdf0e10cSrcweir 	SwRect aRect( rRect );
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir 	sal_Bool bVis = sal_False;
1244cdf0e10cSrcweir 	// ist Cursor sichtbar, dann verstecke den SV-Cursor
1245cdf0e10cSrcweir 	if( pVisCrsr->IsVisible() && !aRect.IsOver( aCharRect ) )	//JP 18.06.97: ???
1246cdf0e10cSrcweir 	{
1247cdf0e10cSrcweir 		bVis = sal_True;
1248cdf0e10cSrcweir 		pVisCrsr->Hide();
1249cdf0e10cSrcweir 	}
1250cdf0e10cSrcweir 
1251cdf0e10cSrcweir 	// Bereich neu painten
1252cdf0e10cSrcweir 	ViewShell::Paint( rRect );
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir 	if( bHasFocus && !bBasicHideCrsr )
1255cdf0e10cSrcweir 	{
1256cdf0e10cSrcweir 		SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
1257cdf0e10cSrcweir //		pAktCrsr->Invalidate( aRect );
1258cdf0e10cSrcweir 		if( !ActionPend() )
1259cdf0e10cSrcweir 		{
1260cdf0e10cSrcweir 			// damit nicht rechts/unten die Raender abgeschnitten werden
1261cdf0e10cSrcweir 			pAktCrsr->Invalidate( VisArea() );
1262cdf0e10cSrcweir 			pAktCrsr->Show();
1263cdf0e10cSrcweir 		}
1264cdf0e10cSrcweir 		else
1265cdf0e10cSrcweir 			pAktCrsr->Invalidate( aRect );
1266cdf0e10cSrcweir 
1267cdf0e10cSrcweir 	}
1268cdf0e10cSrcweir 	if( bSVCrsrVis && bVis )        // auch SV-Cursor wieder anzeigen
1269cdf0e10cSrcweir 		pVisCrsr->Show();
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir 
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir 
VisPortChgd(const SwRect & rRect)1274cdf0e10cSrcweir void SwCrsrShell::VisPortChgd( const SwRect & rRect )
1275cdf0e10cSrcweir {
1276cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1277cdf0e10cSrcweir 	sal_Bool bVis;      // beim Scrollen immer alle Cursor ausschalten
1278cdf0e10cSrcweir 
1279cdf0e10cSrcweir 	// ist Cursor sichtbar, dann verstecke den SV-Cursor
1280cdf0e10cSrcweir 	if( sal_True == ( bVis = pVisCrsr->IsVisible() ))
1281cdf0e10cSrcweir 		pVisCrsr->Hide();
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir 	bVisPortChgd = sal_True;
1284cdf0e10cSrcweir 	aOldRBPos.X() = VisArea().Right();
1285cdf0e10cSrcweir 	aOldRBPos.Y() = VisArea().Bottom();
1286cdf0e10cSrcweir 
1287cdf0e10cSrcweir 	//Damit es es keine Probleme mit dem SV-Cursor gibt, wird in
1288cdf0e10cSrcweir 	//ViewShell::VisPo.. ein Update() auf das Window gerufen.
1289cdf0e10cSrcweir 	//Waehrend des Paintens duerfen aber nun wieder keine Selectionen
1290cdf0e10cSrcweir 	//angezeigt werden, deshalb wird der Aufruf hier geklammert.
1291cdf0e10cSrcweir 	ViewShell::VisPortChgd( rRect );        // Bereich verschieben
1292cdf0e10cSrcweir 
1293cdf0e10cSrcweir /*
1294cdf0e10cSrcweir 	SwRect aRect( rRect );
1295cdf0e10cSrcweir 	if( VisArea().IsOver( aRect ) )
1296cdf0e10cSrcweir 		pCurCrsr->Invalidate( aRect );
1297cdf0e10cSrcweir */
1298cdf0e10cSrcweir 
1299cdf0e10cSrcweir 	if( bSVCrsrVis && bVis )    // auch SV-Cursor wieder anzeigen
1300cdf0e10cSrcweir 		pVisCrsr->Show();
1301cdf0e10cSrcweir 
1302cdf0e10cSrcweir 	if( nCrsrMove )
1303cdf0e10cSrcweir 		bInCMvVisportChgd = sal_True;
1304cdf0e10cSrcweir 
1305cdf0e10cSrcweir 	bVisPortChgd = sal_False;
1306cdf0e10cSrcweir }
1307cdf0e10cSrcweir 
1308cdf0e10cSrcweir // aktualisiere den Crsrs, d.H. setze ihn wieder in den Content.
1309cdf0e10cSrcweir // Das sollte nur aufgerufen werden, wenn der Cursor z.B. beim
1310cdf0e10cSrcweir // Loeschen von Rahmen irgendwohin gesetzt wurde. Die Position
1311cdf0e10cSrcweir // ergibt sich aus seiner aktuellen Position im Layout !!
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir 
UpdateCrsrPos()1314cdf0e10cSrcweir void SwCrsrShell::UpdateCrsrPos()
1315cdf0e10cSrcweir {
1316cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1317cdf0e10cSrcweir 	++nStartAction;
1318cdf0e10cSrcweir     SwShellCrsr* pShellCrsr = getShellCrsr( true );
1319cdf0e10cSrcweir 	Size aOldSz( GetDocSize() );
1320cdf0e10cSrcweir 	SwCntntNode *pCNode = pShellCrsr->GetCntntNode();
1321cdf0e10cSrcweir 	SwCntntFrm  *pFrm = pCNode ?
1322cdf0e10cSrcweir 		pCNode->getLayoutFrm( GetLayout(), &pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), sal_False ) :0;
1323cdf0e10cSrcweir 	if( !pFrm || (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow()) )
1324cdf0e10cSrcweir 	{
1325cdf0e10cSrcweir 		SwCrsrMoveState aTmpState( MV_NONE );
1326cdf0e10cSrcweir 		aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1327cdf0e10cSrcweir 		GetLayout()->GetCrsrOfst( pShellCrsr->GetPoint(), pShellCrsr->GetPtPos(),
1328cdf0e10cSrcweir 									 &aTmpState );
1329cdf0e10cSrcweir 		if( pShellCrsr->HasMark())
1330cdf0e10cSrcweir 			pShellCrsr->DeleteMark();
1331cdf0e10cSrcweir 	}
1332cdf0e10cSrcweir     IGrammarContact *pGrammarContact = GetDoc() ? GetDoc()->getGrammarContact() : 0;
1333cdf0e10cSrcweir     if( pGrammarContact )
1334cdf0e10cSrcweir         pGrammarContact->updateCursorPosition( *pCurCrsr->GetPoint() );
1335cdf0e10cSrcweir 	--nStartAction;
1336cdf0e10cSrcweir 	if( aOldSz != GetDocSize() )
1337cdf0e10cSrcweir         SizeChgNotify();
1338cdf0e10cSrcweir }
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir // JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen
1341cdf0e10cSrcweir //				stehen, so mussen diese daraus verschoben werden
lcl_CheckHiddenSection(SwNodeIndex & rIdx)1342cdf0e10cSrcweir static void lcl_CheckHiddenSection( SwNodeIndex& rIdx )
1343cdf0e10cSrcweir {
1344cdf0e10cSrcweir 	const SwSectionNode* pSectNd = rIdx.GetNode().FindSectionNode();
1345cdf0e10cSrcweir 	if( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
1346cdf0e10cSrcweir 	{
1347cdf0e10cSrcweir 		SwNodeIndex aTmp( *pSectNd );
1348cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1349cdf0e10cSrcweir         const SwNode* pFrmNd =
1350cdf0e10cSrcweir #endif
1351cdf0e10cSrcweir         rIdx.GetNodes().FindPrvNxtFrmNode( aTmp, pSectNd->EndOfSectionNode() );
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1354cdf0e10cSrcweir         (void) pFrmNd;
1355cdf0e10cSrcweir         ASSERT( pFrmNd, "keinen Node mit Frames gefunden" );
1356cdf0e10cSrcweir #endif
1357cdf0e10cSrcweir 		rIdx = aTmp;
1358cdf0e10cSrcweir 	}
1359cdf0e10cSrcweir }
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir // Try to set the cursor to the next visible content node.
lcl_CheckHiddenPara(SwPosition & rPos)1362cdf0e10cSrcweir static void lcl_CheckHiddenPara( SwPosition& rPos )
1363cdf0e10cSrcweir {
1364cdf0e10cSrcweir     SwNodeIndex aTmp( rPos.nNode );
1365cdf0e10cSrcweir     SwTxtNode* pTxtNd = aTmp.GetNode().GetTxtNode();
1366cdf0e10cSrcweir     while( pTxtNd && pTxtNd->HasHiddenCharAttribute( true ) )
1367cdf0e10cSrcweir 	{
1368cdf0e10cSrcweir         SwCntntNode* pCntnt = aTmp.GetNodes().GoNext( &aTmp );
1369cdf0e10cSrcweir         if ( pCntnt && pCntnt->IsTxtNode() )
1370cdf0e10cSrcweir             pTxtNd = (SwTxtNode*)pCntnt;
1371cdf0e10cSrcweir         else
1372cdf0e10cSrcweir             pTxtNd = 0;
1373cdf0e10cSrcweir 	}
1374cdf0e10cSrcweir 
1375cdf0e10cSrcweir     if ( pTxtNd )
1376cdf0e10cSrcweir         rPos = SwPosition( aTmp, SwIndex( pTxtNd, 0 ) );
1377cdf0e10cSrcweir }
1378cdf0e10cSrcweir 
1379cdf0e10cSrcweir // --> OD 2005-12-14 #i27301# - helper class, which notifies the accessibility
1380cdf0e10cSrcweir // about invalid text selections in its destructor
1381cdf0e10cSrcweir class SwNotifyAccAboutInvalidTextSelections
1382cdf0e10cSrcweir {
1383cdf0e10cSrcweir     private:
1384cdf0e10cSrcweir         SwCrsrShell& mrCrsrSh;
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir     public:
SwNotifyAccAboutInvalidTextSelections(SwCrsrShell & _rCrsrSh)1387cdf0e10cSrcweir         SwNotifyAccAboutInvalidTextSelections( SwCrsrShell& _rCrsrSh )
1388cdf0e10cSrcweir             : mrCrsrSh( _rCrsrSh )
1389cdf0e10cSrcweir         {}
1390cdf0e10cSrcweir 
~SwNotifyAccAboutInvalidTextSelections()1391cdf0e10cSrcweir         ~SwNotifyAccAboutInvalidTextSelections()
1392cdf0e10cSrcweir         {
1393cdf0e10cSrcweir             mrCrsrSh.InvalidateAccessibleParaTextSelection();
1394cdf0e10cSrcweir         }
1395cdf0e10cSrcweir };
1396cdf0e10cSrcweir // <--
UpdateCrsr(sal_uInt16 eFlags,sal_Bool bIdleEnd)1397cdf0e10cSrcweir void SwCrsrShell::UpdateCrsr( sal_uInt16 eFlags, sal_Bool bIdleEnd )
1398cdf0e10cSrcweir {
1399cdf0e10cSrcweir 	SET_CURR_SHELL( this );
1400cdf0e10cSrcweir 
1401cdf0e10cSrcweir     ClearUpCrsrs();
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir 	// erfrage den Count fuer die Start-/End-Actions und ob die Shell
1404cdf0e10cSrcweir 	// ueberhaupt den Focus hat
1405cdf0e10cSrcweir //	if( ActionPend() /*|| !bHasFocus*/ )
1406cdf0e10cSrcweir 	//JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction der
1407cdf0e10cSrcweir 	//				Cursor geupdatet werden; um z.B. den TabellenCursor zu
1408cdf0e10cSrcweir 	//				erzeugen. Im EndAction wird jetzt das UpdateCrsr gerufen!
1409cdf0e10cSrcweir 	if( ActionPend() && BasicActionPend() )
1410cdf0e10cSrcweir 	{
1411cdf0e10cSrcweir 		if ( eFlags & SwCrsrShell::READONLY )
1412cdf0e10cSrcweir 			bIgnoreReadonly = sal_True;
1413cdf0e10cSrcweir 		return;             // wenn nicht, dann kein Update !!
1414cdf0e10cSrcweir 	}
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir     SwNotifyAccAboutInvalidTextSelections aInvalidateTextSelections( *this );
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir 	if ( bIgnoreReadonly )
1419cdf0e10cSrcweir 	{
1420cdf0e10cSrcweir 		bIgnoreReadonly = sal_False;
1421cdf0e10cSrcweir 		eFlags |= SwCrsrShell::READONLY;
1422cdf0e10cSrcweir 	}
1423cdf0e10cSrcweir 
1424cdf0e10cSrcweir 	if( eFlags & SwCrsrShell::CHKRANGE )	// alle Cursor-Bewegungen auf
1425cdf0e10cSrcweir 		CheckRange( pCurCrsr );     	// ueberlappende Bereiche testen
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir 	if( !bIdleEnd )
1428cdf0e10cSrcweir 		CheckTblBoxCntnt();
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir 	// steht der akt. Crsr in einer Tabelle und in unterschiedlichen Boxen
1431cdf0e10cSrcweir 	// (oder ist noch TabellenMode), dann gilt der Tabellen Mode
1432cdf0e10cSrcweir 	SwPaM* pTstCrsr = getShellCrsr( true );
1433cdf0e10cSrcweir 	if( pTstCrsr->HasMark() && !pBlockCrsr &&
1434cdf0e10cSrcweir 		pDoc->IsIdxInTbl( pTstCrsr->GetPoint()->nNode ) &&
1435cdf0e10cSrcweir 		  ( pTblCrsr ||
1436cdf0e10cSrcweir             pTstCrsr->GetNode( sal_True )->StartOfSectionNode() !=
1437cdf0e10cSrcweir             pTstCrsr->GetNode( sal_False )->StartOfSectionNode() ) )
1438cdf0e10cSrcweir 	{
1439cdf0e10cSrcweir 		SwShellCrsr* pITmpCrsr = getShellCrsr( true );
1440cdf0e10cSrcweir 		Point aTmpPt( pITmpCrsr->GetPtPos() );
1441cdf0e10cSrcweir 		Point aTmpMk( pITmpCrsr->GetMkPos() );
1442cdf0e10cSrcweir 		SwPosition* pPos = pITmpCrsr->GetPoint();
1443cdf0e10cSrcweir 
1444cdf0e10cSrcweir 		// JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen
1445cdf0e10cSrcweir 		//				stehen, so mussen diese daraus verschoben werden
1446cdf0e10cSrcweir 		lcl_CheckHiddenSection( pPos->nNode );
1447cdf0e10cSrcweir 		lcl_CheckHiddenSection( pITmpCrsr->GetMark()->nNode );
1448cdf0e10cSrcweir 
1449cdf0e10cSrcweir 		// Move cursor out of hidden paragraphs
1450cdf0e10cSrcweir         if ( !GetViewOptions()->IsShowHiddenChar() )
1451cdf0e10cSrcweir         {
1452cdf0e10cSrcweir             lcl_CheckHiddenPara( *pPos );
1453cdf0e10cSrcweir             lcl_CheckHiddenPara( *pITmpCrsr->GetMark() );
1454cdf0e10cSrcweir         }
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir 		SwCntntFrm *pTblFrm = pPos->nNode.GetNode().GetCntntNode()->
1457cdf0e10cSrcweir                               getLayoutFrm( GetLayout(), &aTmpPt, pPos, sal_False );
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir         ASSERT( pTblFrm, "Tabelle Crsr nicht im Content ??" );
1460cdf0e10cSrcweir 
1461cdf0e10cSrcweir         // --> FME 2005-12-02 #126107# Make code robust. The table
1462cdf0e10cSrcweir         // cursor may point to a table in a currently inactive header.
1463cdf0e10cSrcweir         SwTabFrm *pTab = pTblFrm ? pTblFrm->FindTabFrm() : 0;
1464cdf0e10cSrcweir         // <--
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir         if ( pTab && pTab->GetTable()->GetRowsToRepeat() > 0 )
1467cdf0e10cSrcweir         {
1468cdf0e10cSrcweir             // First check if point is in repeated headline:
1469cdf0e10cSrcweir             bool bInRepeatedHeadline = pTab->IsFollow() && pTab->IsInHeadline( *pTblFrm );
1470cdf0e10cSrcweir 
1471cdf0e10cSrcweir             // Second check if mark is in repeated headline:
1472cdf0e10cSrcweir             if ( !bInRepeatedHeadline )
1473cdf0e10cSrcweir             {
1474cdf0e10cSrcweir                 SwCntntFrm* pMarkTblFrm = pITmpCrsr->GetCntntNode( sal_False )->
1475cdf0e10cSrcweir                     getLayoutFrm( GetLayout(), &aTmpMk, pITmpCrsr->GetMark(), sal_False );
1476cdf0e10cSrcweir                 ASSERT( pMarkTblFrm, "Tabelle Crsr nicht im Content ??" );
1477cdf0e10cSrcweir 
1478cdf0e10cSrcweir                 if ( pMarkTblFrm )
1479cdf0e10cSrcweir                 {
1480cdf0e10cSrcweir                     SwTabFrm* pMarkTab = pMarkTblFrm->FindTabFrm();
1481cdf0e10cSrcweir                     ASSERT( pMarkTab, "Tabelle Crsr nicht im Content ??" );
1482cdf0e10cSrcweir 
1483cdf0e10cSrcweir                     // --> FME 2005-11-28 #120360# Make code robust:
1484cdf0e10cSrcweir                     if ( pMarkTab )
1485cdf0e10cSrcweir                     {
1486cdf0e10cSrcweir                         bInRepeatedHeadline = pMarkTab->IsFollow() && pMarkTab->IsInHeadline( *pMarkTblFrm );
1487cdf0e10cSrcweir                     }
1488cdf0e10cSrcweir                     // <--
1489cdf0e10cSrcweir                 }
1490cdf0e10cSrcweir             }
1491cdf0e10cSrcweir 
1492cdf0e10cSrcweir             // No table cursor in repeaded headlines:
1493cdf0e10cSrcweir             if ( bInRepeatedHeadline )
1494cdf0e10cSrcweir             {
1495cdf0e10cSrcweir                 pTblFrm = 0;
1496cdf0e10cSrcweir 
1497cdf0e10cSrcweir                 SwPosSection fnPosSect = *pPos <  *pITmpCrsr->GetMark()
1498cdf0e10cSrcweir                                             ? fnSectionStart
1499cdf0e10cSrcweir                                             : fnSectionEnd;
1500cdf0e10cSrcweir 
1501cdf0e10cSrcweir                 // dann nur innerhalb der Box selektieren
1502cdf0e10cSrcweir                 if( pTblCrsr )
1503cdf0e10cSrcweir                 {
1504cdf0e10cSrcweir                     pCurCrsr->SetMark();
1505cdf0e10cSrcweir                     *pCurCrsr->GetMark() = *pTblCrsr->GetMark();
1506cdf0e10cSrcweir                     pCurCrsr->GetMkPos() = pTblCrsr->GetMkPos();
1507cdf0e10cSrcweir                     pTblCrsr->DeleteMark();
1508cdf0e10cSrcweir                     pTblCrsr->SwSelPaintRects::Hide();
1509cdf0e10cSrcweir                 }
1510cdf0e10cSrcweir 
1511cdf0e10cSrcweir                 *pCurCrsr->GetPoint() = *pCurCrsr->GetMark();
1512cdf0e10cSrcweir                 (*fnSectionCurr)( *pCurCrsr, fnPosSect );
1513cdf0e10cSrcweir             }
1514cdf0e10cSrcweir 		}
1515cdf0e10cSrcweir 
1516cdf0e10cSrcweir 		// wir wollen wirklich eine Tabellen-Selektion
1517cdf0e10cSrcweir 		if( pTab && pTblFrm )
1518cdf0e10cSrcweir 		{
1519cdf0e10cSrcweir 			if( !pTblCrsr )
1520cdf0e10cSrcweir 			{
1521cdf0e10cSrcweir 				pTblCrsr = new SwShellTableCrsr( *this,
1522cdf0e10cSrcweir 								*pCurCrsr->GetMark(), pCurCrsr->GetMkPos(),
1523cdf0e10cSrcweir 								*pPos, aTmpPt );
1524cdf0e10cSrcweir 				pCurCrsr->DeleteMark();
1525cdf0e10cSrcweir 				pCurCrsr->SwSelPaintRects::Hide();
1526cdf0e10cSrcweir 
1527cdf0e10cSrcweir 				CheckTblBoxCntnt();
1528cdf0e10cSrcweir 			}
1529cdf0e10cSrcweir 
1530cdf0e10cSrcweir             SwCrsrMoveState aTmpState( MV_NONE );
1531cdf0e10cSrcweir             aTmpState.bRealHeight = sal_True;
1532cdf0e10cSrcweir             if( !pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint(), &aTmpState ) )
1533cdf0e10cSrcweir             {
1534cdf0e10cSrcweir                 Point aCentrPt( aCharRect.Center() );
1535cdf0e10cSrcweir                 aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1536cdf0e10cSrcweir                 pTblFrm->GetCrsrOfst( pTblCrsr->GetPoint(), aCentrPt, &aTmpState );
1537cdf0e10cSrcweir #ifndef DBG_UTIL
1538cdf0e10cSrcweir                 pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint() );
1539cdf0e10cSrcweir #else
1540cdf0e10cSrcweir                 if ( !pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint() ) )
1541cdf0e10cSrcweir                     ASSERT( !this, "GetCharRect failed." );
1542cdf0e10cSrcweir #endif
1543cdf0e10cSrcweir             }
1544cdf0e10cSrcweir //          ALIGNRECT( aCharRect );
1545cdf0e10cSrcweir 
1546cdf0e10cSrcweir 			pVisCrsr->Hide();       // sichtbaren Cursor immer verstecken
1547cdf0e10cSrcweir 			// Curosr in den sichtbaren Bereich scrollen
1548cdf0e10cSrcweir 			if( (eFlags & SwCrsrShell::SCROLLWIN) &&
1549cdf0e10cSrcweir                 (HasSelection() || eFlags & SwCrsrShell::READONLY ||
1550cdf0e10cSrcweir 				 !IsCrsrReadonly()) )
1551cdf0e10cSrcweir 			{
1552cdf0e10cSrcweir 				SwFrm* pBoxFrm = pTblFrm;
1553cdf0e10cSrcweir 				while( pBoxFrm && !pBoxFrm->IsCellFrm() )
1554cdf0e10cSrcweir 					pBoxFrm = pBoxFrm->GetUpper();
1555cdf0e10cSrcweir 				if( pBoxFrm && pBoxFrm->Frm().HasArea() )
1556cdf0e10cSrcweir 					MakeVisible( pBoxFrm->Frm() );
1557cdf0e10cSrcweir 				else
1558cdf0e10cSrcweir 					MakeVisible( aCharRect );
1559cdf0e10cSrcweir 			}
1560cdf0e10cSrcweir 
1561cdf0e10cSrcweir 			// lasse vom Layout die Crsr in den Boxen erzeugen
1562cdf0e10cSrcweir 			if( pTblCrsr->IsCrsrMovedUpdt() )
1563cdf0e10cSrcweir 				GetLayout()->MakeTblCrsrs( *pTblCrsr );
1564cdf0e10cSrcweir 			if( bHasFocus && !bBasicHideCrsr )
1565cdf0e10cSrcweir 				pTblCrsr->Show();
1566cdf0e10cSrcweir 
1567cdf0e10cSrcweir 			// Cursor-Points auf die neuen Positionen setzen
1568cdf0e10cSrcweir 			pTblCrsr->GetPtPos().X() = aCharRect.Left();
1569cdf0e10cSrcweir 			pTblCrsr->GetPtPos().Y() = aCharRect.Top();
1570cdf0e10cSrcweir 
1571cdf0e10cSrcweir 			if( bSVCrsrVis )
1572cdf0e10cSrcweir 			{
1573cdf0e10cSrcweir 				aCrsrHeight.X() = 0;
1574cdf0e10cSrcweir                 aCrsrHeight.Y() = aTmpState.aRealHeight.Y() < 0 ?
1575cdf0e10cSrcweir                                   -aCharRect.Width() : aCharRect.Height();
1576cdf0e10cSrcweir                 pVisCrsr->Show();           // wieder anzeigen
1577cdf0e10cSrcweir 			}
1578cdf0e10cSrcweir 			eMvState = MV_NONE;		// Status fuers Crsr-Travelling - GetCrsrOfst
1579cdf0e10cSrcweir 			if( pTblFrm && Imp()->IsAccessible() )
1580cdf0e10cSrcweir 				Imp()->InvalidateAccessibleCursorPosition( pTblFrm );
1581cdf0e10cSrcweir 			return;
1582cdf0e10cSrcweir 		}
1583cdf0e10cSrcweir 	}
1584cdf0e10cSrcweir 
1585cdf0e10cSrcweir 	if( pTblCrsr )
1586cdf0e10cSrcweir 	{
1587cdf0e10cSrcweir 		// Cursor Ring loeschen
1588cdf0e10cSrcweir 		while( pCurCrsr->GetNext() != pCurCrsr )
1589cdf0e10cSrcweir 			delete pCurCrsr->GetNext();
1590cdf0e10cSrcweir 		pCurCrsr->DeleteMark();
1591cdf0e10cSrcweir 		*pCurCrsr->GetPoint() = *pTblCrsr->GetPoint();
1592cdf0e10cSrcweir 		pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos();
1593cdf0e10cSrcweir 		delete pTblCrsr, pTblCrsr = 0;
1594cdf0e10cSrcweir 	}
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir 	pVisCrsr->Hide();       // sichtbaren Cursor immer verstecken
1597cdf0e10cSrcweir 
1598cdf0e10cSrcweir 	// sind wir vielleicht in einer geschuetzten/versteckten Section ?
1599cdf0e10cSrcweir 	{
1600cdf0e10cSrcweir         SwShellCrsr* pShellCrsr = getShellCrsr( true );
1601cdf0e10cSrcweir 		sal_Bool bChgState = sal_True;
1602cdf0e10cSrcweir 		const SwSectionNode* pSectNd = pShellCrsr->GetNode()->FindSectionNode();
1603cdf0e10cSrcweir 		if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
1604cdf0e10cSrcweir 			( !IsReadOnlyAvailable() &&
1605cdf0e10cSrcweir               pSectNd->GetSection().IsProtectFlag() &&
1606cdf0e10cSrcweir 			 ( !pDoc->GetDocShell() ||
1607cdf0e10cSrcweir 			   !pDoc->GetDocShell()->IsReadOnly() || bAllProtect )) ) )
1608cdf0e10cSrcweir 		{
1609cdf0e10cSrcweir 			if( !FindValidCntntNode( !HasDrawView() ||
1610cdf0e10cSrcweir 					0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1611cdf0e10cSrcweir 			{
1612cdf0e10cSrcweir 				// alles ist geschuetzt / versteckt -> besonderer Mode
1613cdf0e10cSrcweir 				if( bAllProtect && !IsReadOnlyAvailable() &&
1614cdf0e10cSrcweir                     pSectNd->GetSection().IsProtectFlag() )
1615cdf0e10cSrcweir 					bChgState = sal_False;
1616cdf0e10cSrcweir 				else
1617cdf0e10cSrcweir 				{
1618cdf0e10cSrcweir 					eMvState = MV_NONE;		// Status fuers Crsr-Travelling
1619cdf0e10cSrcweir 					bAllProtect = sal_True;
1620cdf0e10cSrcweir 					if( GetDoc()->GetDocShell() )
1621cdf0e10cSrcweir 					{
1622cdf0e10cSrcweir 						GetDoc()->GetDocShell()->SetReadOnlyUI( sal_True );
1623cdf0e10cSrcweir 						CallChgLnk();		// UI bescheid sagen!
1624cdf0e10cSrcweir 					}
1625cdf0e10cSrcweir 					return;
1626cdf0e10cSrcweir 				}
1627cdf0e10cSrcweir 			}
1628cdf0e10cSrcweir 		}
1629cdf0e10cSrcweir 		if( bChgState )
1630cdf0e10cSrcweir 		{
1631cdf0e10cSrcweir 			sal_Bool bWasAllProtect = bAllProtect;
1632cdf0e10cSrcweir 			bAllProtect = sal_False;
1633cdf0e10cSrcweir 			if( bWasAllProtect && GetDoc()->GetDocShell() &&
1634cdf0e10cSrcweir 				GetDoc()->GetDocShell()->IsReadOnlyUI() )
1635cdf0e10cSrcweir 			{
1636cdf0e10cSrcweir 				GetDoc()->GetDocShell()->SetReadOnlyUI( sal_False );
1637cdf0e10cSrcweir 				CallChgLnk();		// UI bescheid sagen!
1638cdf0e10cSrcweir 			}
1639cdf0e10cSrcweir 		}
1640cdf0e10cSrcweir 	}
1641cdf0e10cSrcweir 
1642cdf0e10cSrcweir 	UpdateCrsrPos();
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir     // #100722# The cursor must always point into content; there's some code
1645cdf0e10cSrcweir     // that relies on this. (E.g. in SwEditShell::GetScriptType, which always
1646cdf0e10cSrcweir     // loops _behind_ the last node in the selection, which always works if you
1647cdf0e10cSrcweir     // are in content.) To achieve this, we'll force cursor(s) to point into
1648cdf0e10cSrcweir     // content, if UpdateCrsrPos() hasn't already done so.
1649cdf0e10cSrcweir     SwPaM* pCmp = pCurCrsr;
1650cdf0e10cSrcweir     do
1651cdf0e10cSrcweir     {
1652cdf0e10cSrcweir         // start will move forwards, end will move backwards
1653cdf0e10cSrcweir         bool bPointIsStart = ( pCmp->Start() == pCmp->GetPoint() );
1654cdf0e10cSrcweir 
1655cdf0e10cSrcweir         // move point; forward if it's the start, backwards if it's the end
1656cdf0e10cSrcweir         if( ! pCmp->GetPoint()->nNode.GetNode().IsCntntNode() )
1657cdf0e10cSrcweir             pCmp->Move( bPointIsStart ? fnMoveForward : fnMoveBackward,
1658cdf0e10cSrcweir                         fnGoCntnt );
1659cdf0e10cSrcweir 
1660cdf0e10cSrcweir         // move mark (if exists); forward if it's the start, else backwards
1661cdf0e10cSrcweir         if( pCmp->HasMark() )
1662cdf0e10cSrcweir         {
1663cdf0e10cSrcweir             if( ! pCmp->GetMark()->nNode.GetNode().IsCntntNode() )
1664cdf0e10cSrcweir             {
1665cdf0e10cSrcweir                 pCmp->Exchange();
1666cdf0e10cSrcweir                 pCmp->Move( !bPointIsStart ? fnMoveForward : fnMoveBackward,
1667cdf0e10cSrcweir                             fnGoCntnt );
1668cdf0e10cSrcweir                 pCmp->Exchange();
1669cdf0e10cSrcweir             }
1670cdf0e10cSrcweir         }
1671cdf0e10cSrcweir 
1672cdf0e10cSrcweir         // iterate to next PaM in ring
1673cdf0e10cSrcweir         pCmp = static_cast<SwPaM*>( pCmp->GetNext() );
1674cdf0e10cSrcweir     }
1675cdf0e10cSrcweir     while( pCmp != pCurCrsr );
1676cdf0e10cSrcweir 
1677cdf0e10cSrcweir 
1678cdf0e10cSrcweir 	SwRect aOld( aCharRect );
1679cdf0e10cSrcweir 	sal_Bool bFirst = sal_True;
1680cdf0e10cSrcweir 	SwCntntFrm *pFrm;
1681cdf0e10cSrcweir 	int nLoopCnt = 100;
1682cdf0e10cSrcweir     SwShellCrsr* pShellCrsr = getShellCrsr( true );
1683cdf0e10cSrcweir 
1684cdf0e10cSrcweir 	do {
1685cdf0e10cSrcweir 		sal_Bool bAgainst;
1686cdf0e10cSrcweir 		do {
1687cdf0e10cSrcweir 			bAgainst = sal_False;
1688cdf0e10cSrcweir 			pFrm = pShellCrsr->GetCntntNode()->getLayoutFrm( GetLayout(),
1689cdf0e10cSrcweir 						&pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), sal_False );
1690cdf0e10cSrcweir 			// ist der Frm nicht mehr vorhanden, dann muss das gesamte Layout
1691cdf0e10cSrcweir 			// erzeugt werden, weil ja mal hier einer vorhanden war !!
1692cdf0e10cSrcweir 			if ( !pFrm )
1693cdf0e10cSrcweir 			{
1694cdf0e10cSrcweir 				do
1695cdf0e10cSrcweir 				{
1696cdf0e10cSrcweir 					CalcLayout();
1697cdf0e10cSrcweir 					pFrm = pShellCrsr->GetCntntNode()->getLayoutFrm( GetLayout(),
1698cdf0e10cSrcweir 								&pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), sal_False );
1699cdf0e10cSrcweir 				}  while( !pFrm );
1700cdf0e10cSrcweir 			}
1701cdf0e10cSrcweir 			else if ( Imp()->IsIdleAction() )
1702cdf0e10cSrcweir 				//Wir stellen sicher, dass anstaendig Formatiert wurde #42224#
1703cdf0e10cSrcweir 				pFrm->PrepareCrsr();
1704cdf0e10cSrcweir 
1705cdf0e10cSrcweir 			// im geschuetzten Fly? aber bei Rahmenselektion ignorieren
1706cdf0e10cSrcweir 			if( !IsReadOnlyAvailable() && pFrm->IsProtected() &&
1707cdf0e10cSrcweir 				( !Imp()->GetDrawView() ||
1708cdf0e10cSrcweir 				  !Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) &&
1709cdf0e10cSrcweir 				(!pDoc->GetDocShell() ||
1710cdf0e10cSrcweir 				 !pDoc->GetDocShell()->IsReadOnly() || bAllProtect ) )
1711cdf0e10cSrcweir 			{
1712cdf0e10cSrcweir 				// dann suche eine gueltige Position
1713cdf0e10cSrcweir 				sal_Bool bChgState = sal_True;
1714cdf0e10cSrcweir 				if( !FindValidCntntNode(!HasDrawView() ||
1715cdf0e10cSrcweir 					0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1716cdf0e10cSrcweir 				{
1717cdf0e10cSrcweir 					// alles ist geschuetzt / versteckt -> besonderer Mode
1718cdf0e10cSrcweir 					if( bAllProtect )
1719cdf0e10cSrcweir 						bChgState = sal_False;
1720cdf0e10cSrcweir 					else
1721cdf0e10cSrcweir 					{
1722cdf0e10cSrcweir 						eMvState = MV_NONE;     // Status fuers Crsr-Travelling
1723cdf0e10cSrcweir 						bAllProtect = sal_True;
1724cdf0e10cSrcweir 						if( GetDoc()->GetDocShell() )
1725cdf0e10cSrcweir 						{
1726cdf0e10cSrcweir 							GetDoc()->GetDocShell()->SetReadOnlyUI( sal_True );
1727cdf0e10cSrcweir 							CallChgLnk();		// UI bescheid sagen!
1728cdf0e10cSrcweir 						}
1729cdf0e10cSrcweir 						return;
1730cdf0e10cSrcweir 					}
1731cdf0e10cSrcweir 				}
1732cdf0e10cSrcweir 
1733cdf0e10cSrcweir 				if( bChgState )
1734cdf0e10cSrcweir 				{
1735cdf0e10cSrcweir 					sal_Bool bWasAllProtect = bAllProtect;
1736cdf0e10cSrcweir 					bAllProtect = sal_False;
1737cdf0e10cSrcweir 					if( bWasAllProtect && GetDoc()->GetDocShell() &&
1738cdf0e10cSrcweir 						GetDoc()->GetDocShell()->IsReadOnlyUI() )
1739cdf0e10cSrcweir 					{
1740cdf0e10cSrcweir 						GetDoc()->GetDocShell()->SetReadOnlyUI( sal_False );
1741cdf0e10cSrcweir 						CallChgLnk();		// UI bescheid sagen!
1742cdf0e10cSrcweir 					}
1743cdf0e10cSrcweir 					bAllProtect = sal_False;
1744cdf0e10cSrcweir 					bAgainst = sal_True;        // nochmal den richigen Frm suchen
1745cdf0e10cSrcweir 				}
1746cdf0e10cSrcweir 			}
1747cdf0e10cSrcweir 		} while( bAgainst );
1748cdf0e10cSrcweir 
1749cdf0e10cSrcweir 		if( !( eFlags & SwCrsrShell::NOCALRECT ))
1750cdf0e10cSrcweir 		{
1751cdf0e10cSrcweir 			SwCrsrMoveState aTmpState( eMvState );
1752cdf0e10cSrcweir 			aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1753cdf0e10cSrcweir             aTmpState.bRealHeight = sal_True;
1754cdf0e10cSrcweir 			aTmpState.bRealWidth = IsOverwriteCrsr();
1755cdf0e10cSrcweir             aTmpState.nCursorBidiLevel = pShellCrsr->GetCrsrBidiLevel();
1756cdf0e10cSrcweir 
1757cdf0e10cSrcweir             // #i27615#,#i30453#
1758cdf0e10cSrcweir             SwSpecialPos aSpecialPos;
1759cdf0e10cSrcweir             aSpecialPos.nExtendRange = SP_EXTEND_RANGE_BEFORE;
1760cdf0e10cSrcweir             if (pShellCrsr->IsInFrontOfLabel())
1761cdf0e10cSrcweir             {
1762cdf0e10cSrcweir                 aTmpState.pSpecialPos = &aSpecialPos;
1763cdf0e10cSrcweir             }
1764cdf0e10cSrcweir 
1765cdf0e10cSrcweir 			if( !pFrm->GetCharRect( aCharRect, *pShellCrsr->GetPoint(), &aTmpState ) )
1766cdf0e10cSrcweir 			{
1767cdf0e10cSrcweir 				Point& rPt = pShellCrsr->GetPtPos();
1768cdf0e10cSrcweir 				rPt = aCharRect.Center();
1769cdf0e10cSrcweir 				pFrm->GetCrsrOfst( pShellCrsr->GetPoint(), rPt, &aTmpState );
1770cdf0e10cSrcweir             }
1771cdf0e10cSrcweir //			ALIGNRECT( aCharRect );
1772cdf0e10cSrcweir 
1773cdf0e10cSrcweir             if( !pShellCrsr->HasMark() )
1774cdf0e10cSrcweir 				aCrsrHeight = aTmpState.aRealHeight;
1775cdf0e10cSrcweir 			else
1776cdf0e10cSrcweir 			{
1777cdf0e10cSrcweir 				aCrsrHeight.X() = 0;
1778cdf0e10cSrcweir                 aCrsrHeight.Y() = aTmpState.aRealHeight.Y() < 0 ?
1779cdf0e10cSrcweir                                   -aCharRect.Width() : aCharRect.Height();
1780cdf0e10cSrcweir 			}
1781cdf0e10cSrcweir 		}
1782cdf0e10cSrcweir 		else
1783cdf0e10cSrcweir 		{
1784cdf0e10cSrcweir 			aCrsrHeight.X() = 0;
1785cdf0e10cSrcweir 			aCrsrHeight.Y() = aCharRect.Height();
1786cdf0e10cSrcweir 		}
1787cdf0e10cSrcweir 
1788cdf0e10cSrcweir 		if( !bFirst && aOld == aCharRect )
1789cdf0e10cSrcweir 			break;
1790cdf0e10cSrcweir 
1791cdf0e10cSrcweir 		// falls das Layout meint, nach dem 100 durchlauf ist man immer noch
1792cdf0e10cSrcweir 		// im Fluss, sollte man die akt. Pos. als gegeben hinnehmen!
1793cdf0e10cSrcweir 		// siehe Bug: 29658
1794cdf0e10cSrcweir 		if( !--nLoopCnt )
1795cdf0e10cSrcweir 		{
1796cdf0e10cSrcweir 			ASSERT( !this, "Endlosschleife? CharRect != OldCharRect ");
1797cdf0e10cSrcweir 			break;
1798cdf0e10cSrcweir 		}
1799cdf0e10cSrcweir 		aOld = aCharRect;
1800cdf0e10cSrcweir 		bFirst = sal_False;
1801cdf0e10cSrcweir 
1802cdf0e10cSrcweir 		// Cursor-Points auf die neuen Positionen setzen
1803cdf0e10cSrcweir 		pShellCrsr->GetPtPos().X() = aCharRect.Left();
1804cdf0e10cSrcweir 		pShellCrsr->GetPtPos().Y() = aCharRect.Top();
1805cdf0e10cSrcweir 
1806cdf0e10cSrcweir 		if( !(eFlags & SwCrsrShell::UPDOWN ))	// alte Pos. von Up/Down loeschen
1807cdf0e10cSrcweir 		{
1808cdf0e10cSrcweir 			pFrm->Calc();
1809cdf0e10cSrcweir             nUpDownX = pFrm->IsVertical() ?
1810cdf0e10cSrcweir                        aCharRect.Top() - pFrm->Frm().Top() :
1811cdf0e10cSrcweir                        aCharRect.Left() - pFrm->Frm().Left();
1812cdf0e10cSrcweir         }
1813cdf0e10cSrcweir 
1814cdf0e10cSrcweir 		// Curosr in den sichtbaren Bereich scrollen
1815cdf0e10cSrcweir         if( bHasFocus && eFlags & SwCrsrShell::SCROLLWIN &&
1816cdf0e10cSrcweir 			(HasSelection() || eFlags & SwCrsrShell::READONLY ||
1817cdf0e10cSrcweir              !IsCrsrReadonly() || GetViewOptions()->IsSelectionInReadonly()) )
1818cdf0e10cSrcweir 		{
1819cdf0e10cSrcweir 			//JP 30.04.99:  damit das EndAction, beim evtuellen Scrollen, den
1820cdf0e10cSrcweir 			//		SV-Crsr nicht wieder sichtbar macht, wird hier das Flag
1821cdf0e10cSrcweir 			//		gesichert und zurueckgesetzt.
1822cdf0e10cSrcweir 			sal_Bool bSav = bSVCrsrVis; bSVCrsrVis = sal_False;
1823cdf0e10cSrcweir 			MakeSelVisible();
1824cdf0e10cSrcweir 			bSVCrsrVis = bSav;
1825cdf0e10cSrcweir 		}
1826cdf0e10cSrcweir 
1827cdf0e10cSrcweir 	} while( eFlags & SwCrsrShell::SCROLLWIN );
1828cdf0e10cSrcweir 
1829cdf0e10cSrcweir     if( pBlockCrsr )
1830cdf0e10cSrcweir         RefreshBlockCursor();
1831cdf0e10cSrcweir 
183269a74367SOliver-Rainer Wittmann     if( !bIdleEnd && bHasFocus && !bBasicHideCrsr )
1833cdf0e10cSrcweir     {
1834cdf0e10cSrcweir         if( pTblCrsr )
1835cdf0e10cSrcweir             pTblCrsr->SwSelPaintRects::Show();
1836cdf0e10cSrcweir         else
1837cdf0e10cSrcweir         {
1838cdf0e10cSrcweir             pCurCrsr->SwSelPaintRects::Show();
1839cdf0e10cSrcweir             if( pBlockCrsr )
1840cdf0e10cSrcweir             {
1841cdf0e10cSrcweir                 SwShellCrsr* pNxt = dynamic_cast<SwShellCrsr*>(pCurCrsr->GetNext());
1842cdf0e10cSrcweir                 while( pNxt && pNxt != pCurCrsr )
1843cdf0e10cSrcweir                 {
1844cdf0e10cSrcweir                     pNxt->SwSelPaintRects::Show();
1845cdf0e10cSrcweir                     pNxt = dynamic_cast<SwShellCrsr*>(pNxt->GetNext());
1846cdf0e10cSrcweir                 }
1847cdf0e10cSrcweir             }
1848cdf0e10cSrcweir         }
1849cdf0e10cSrcweir     }
1850cdf0e10cSrcweir 
1851cdf0e10cSrcweir 	eMvState = MV_NONE;		// Status fuers Crsr-Travelling - GetCrsrOfst
1852cdf0e10cSrcweir 
1853cdf0e10cSrcweir 	if( pFrm && Imp()->IsAccessible() )
1854cdf0e10cSrcweir 		Imp()->InvalidateAccessibleCursorPosition( pFrm );
1855cdf0e10cSrcweir 
1856cdf0e10cSrcweir     // switch from blinking cursor to read-only-text-selection cursor
1857cdf0e10cSrcweir     static const long nNoBlinkTime = STYLE_CURSOR_NOBLINKTIME;
1858cdf0e10cSrcweir     const long nBlinkTime = GetOut()->GetSettings().GetStyleSettings().
1859cdf0e10cSrcweir                             GetCursorBlinkTime();
1860cdf0e10cSrcweir 
1861cdf0e10cSrcweir     if ( (IsCrsrReadonly() && GetViewOptions()->IsSelectionInReadonly()) ==
1862cdf0e10cSrcweir         ( nBlinkTime != nNoBlinkTime ) )
1863cdf0e10cSrcweir     {
1864cdf0e10cSrcweir         // non blinking cursor in read only - text selection mode
1865cdf0e10cSrcweir         AllSettings aSettings = GetOut()->GetSettings();
1866cdf0e10cSrcweir         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1867cdf0e10cSrcweir         const long nNewBlinkTime = nBlinkTime == nNoBlinkTime ?
1868cdf0e10cSrcweir                                    Application::GetSettings().GetStyleSettings().GetCursorBlinkTime() :
1869cdf0e10cSrcweir                                    nNoBlinkTime;
1870cdf0e10cSrcweir         aStyleSettings.SetCursorBlinkTime( nNewBlinkTime );
1871cdf0e10cSrcweir         aSettings.SetStyleSettings( aStyleSettings );
1872cdf0e10cSrcweir         GetOut()->SetSettings( aSettings );
1873cdf0e10cSrcweir     }
1874cdf0e10cSrcweir 
1875cdf0e10cSrcweir     if( bSVCrsrVis )
1876cdf0e10cSrcweir 		pVisCrsr->Show();           // wieder anzeigen
1877cdf0e10cSrcweir }
1878cdf0e10cSrcweir 
RefreshBlockCursor()1879cdf0e10cSrcweir void SwCrsrShell::RefreshBlockCursor()
1880cdf0e10cSrcweir {
1881cdf0e10cSrcweir     ASSERT( pBlockCrsr, "Don't call me without a block cursor" );
1882cdf0e10cSrcweir     SwShellCrsr &rBlock = pBlockCrsr->getShellCrsr();
1883cdf0e10cSrcweir     Point aPt = rBlock.GetPtPos();
1884cdf0e10cSrcweir     SwCntntFrm* pFrm = rBlock.GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, rBlock.GetPoint(), sal_False );
1885cdf0e10cSrcweir     Point aMk;
1886cdf0e10cSrcweir     if( pBlockCrsr->getEndPoint() && pBlockCrsr->getStartPoint() )
1887cdf0e10cSrcweir     {
1888cdf0e10cSrcweir         aPt = *pBlockCrsr->getStartPoint();
1889cdf0e10cSrcweir         aMk = *pBlockCrsr->getEndPoint();
1890cdf0e10cSrcweir     }
1891cdf0e10cSrcweir     else
1892cdf0e10cSrcweir     {
1893cdf0e10cSrcweir         aPt = rBlock.GetPtPos();
1894cdf0e10cSrcweir         if( pFrm )
1895cdf0e10cSrcweir         {
1896cdf0e10cSrcweir             if( pFrm->IsVertical() )
1897cdf0e10cSrcweir                 aPt.Y() = pFrm->Frm().Top() + GetUpDownX();
1898cdf0e10cSrcweir             else
1899cdf0e10cSrcweir                 aPt.X() = pFrm->Frm().Left() + GetUpDownX();
1900cdf0e10cSrcweir         }
1901cdf0e10cSrcweir         aMk = rBlock.GetMkPos();
1902cdf0e10cSrcweir     }
1903cdf0e10cSrcweir     SwRect aRect( aMk, aPt );
1904cdf0e10cSrcweir     aRect.Justify();
1905cdf0e10cSrcweir     SwSelectionList aSelList( pFrm );
1906cdf0e10cSrcweir 
1907cdf0e10cSrcweir     if( GetLayout()->FillSelection( aSelList, aRect ) )
1908cdf0e10cSrcweir     {
1909cdf0e10cSrcweir         SwCursor* pNxt = (SwCursor*)pCurCrsr->GetNext();
1910cdf0e10cSrcweir         while( pNxt != pCurCrsr )
1911cdf0e10cSrcweir         {
1912cdf0e10cSrcweir             delete pNxt;
1913cdf0e10cSrcweir             pNxt = (SwCursor*)pCurCrsr->GetNext();
1914cdf0e10cSrcweir         }
1915cdf0e10cSrcweir 
1916cdf0e10cSrcweir         std::list<SwPaM*>::iterator pStart = aSelList.getStart();
1917cdf0e10cSrcweir         std::list<SwPaM*>::iterator pPam = aSelList.getEnd();
1918cdf0e10cSrcweir         ASSERT( pPam != pStart, "FillSelection should deliver at least one PaM" )
1919cdf0e10cSrcweir         pCurCrsr->SetMark();
1920cdf0e10cSrcweir         --pPam;
1921cdf0e10cSrcweir         // If there is only one text portion inside the rectangle, a simple
1922cdf0e10cSrcweir         // selection is created
1923cdf0e10cSrcweir         if( pPam == pStart )
1924cdf0e10cSrcweir         {
1925cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *(*pPam)->GetPoint();
1926cdf0e10cSrcweir             if( (*pPam)->HasMark() )
1927cdf0e10cSrcweir                 *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1928cdf0e10cSrcweir             else
1929cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1930cdf0e10cSrcweir             delete *pPam;
1931cdf0e10cSrcweir             pCurCrsr->SetColumnSelection( false );
1932cdf0e10cSrcweir         }
1933cdf0e10cSrcweir         else
1934cdf0e10cSrcweir         {
1935cdf0e10cSrcweir             // The order of the SwSelectionList has to be preserved but
1936cdf0e10cSrcweir             // the order inside the ring created by CreateCrsr() is not like
1937cdf0e10cSrcweir             // exspected => First create the selections before the last one
1938cdf0e10cSrcweir             // downto the first selection.
1939cdf0e10cSrcweir             // At least create the cursor for the last selection
1940cdf0e10cSrcweir             --pPam;
1941cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n-1 (if n == number of selections)
1942cdf0e10cSrcweir             if( (*pPam)->HasMark() )
1943cdf0e10cSrcweir                 *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1944cdf0e10cSrcweir             else
1945cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1946cdf0e10cSrcweir             delete *pPam;
1947cdf0e10cSrcweir             pCurCrsr->SetColumnSelection( true );
1948cdf0e10cSrcweir             while( pPam != pStart )
1949cdf0e10cSrcweir             {
1950cdf0e10cSrcweir                 --pPam;
1951cdf0e10cSrcweir 
1952cdf0e10cSrcweir                 SwShellCrsr* pNew = new SwShellCrsr( *pCurCrsr );
1953cdf0e10cSrcweir                 pNew->Insert( pCurCrsr, 0 );
1954cdf0e10cSrcweir                 pCurCrsr->Remove( 0, pCurCrsr->Count() );
1955cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1956cdf0e10cSrcweir 
1957cdf0e10cSrcweir                 *pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n-2, n-3, .., 2, 1
1958cdf0e10cSrcweir                 if( (*pPam)->HasMark() )
1959cdf0e10cSrcweir                 {
1960cdf0e10cSrcweir                     pCurCrsr->SetMark();
1961cdf0e10cSrcweir                     *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1962cdf0e10cSrcweir                 }
1963cdf0e10cSrcweir                 else
1964cdf0e10cSrcweir                     pCurCrsr->DeleteMark();
1965cdf0e10cSrcweir                 pCurCrsr->SetColumnSelection( true );
1966cdf0e10cSrcweir                 delete *pPam;
1967cdf0e10cSrcweir             }
1968cdf0e10cSrcweir             {
1969cdf0e10cSrcweir                 SwShellCrsr* pNew = new SwShellCrsr( *pCurCrsr );
1970cdf0e10cSrcweir                 pNew->Insert( pCurCrsr, 0 );
1971cdf0e10cSrcweir                 pCurCrsr->Remove( 0, pCurCrsr->Count() );
1972cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1973cdf0e10cSrcweir             }
1974cdf0e10cSrcweir             pPam = aSelList.getEnd();
1975cdf0e10cSrcweir             --pPam;
1976cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n, the last selection
1977cdf0e10cSrcweir             if( (*pPam)->HasMark() )
1978cdf0e10cSrcweir             {
1979cdf0e10cSrcweir                 pCurCrsr->SetMark();
1980cdf0e10cSrcweir                 *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1981cdf0e10cSrcweir             }
1982cdf0e10cSrcweir             else
1983cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1984cdf0e10cSrcweir             pCurCrsr->SetColumnSelection( true );
1985cdf0e10cSrcweir             delete *pPam;
1986cdf0e10cSrcweir         }
1987cdf0e10cSrcweir 	}
1988cdf0e10cSrcweir }
1989cdf0e10cSrcweir 
1990cdf0e10cSrcweir // erzeuge eine Kopie vom Cursor und speicher diese im Stack
1991cdf0e10cSrcweir 
1992cdf0e10cSrcweir 
Push()1993cdf0e10cSrcweir void SwCrsrShell::Push()
1994cdf0e10cSrcweir {
1995cdf0e10cSrcweir 	pCrsrStk = new SwShellCrsr( *this, *pCurCrsr->GetPoint(),
1996cdf0e10cSrcweir 									pCurCrsr->GetPtPos(), pCrsrStk );
1997cdf0e10cSrcweir 
1998cdf0e10cSrcweir 	if( pCurCrsr->HasMark() )
1999cdf0e10cSrcweir 	{
2000cdf0e10cSrcweir 		pCrsrStk->SetMark();
2001cdf0e10cSrcweir 		*pCrsrStk->GetMark() = *pCurCrsr->GetMark();
2002cdf0e10cSrcweir 	}
2003cdf0e10cSrcweir }
2004cdf0e10cSrcweir 
2005cdf0e10cSrcweir /*
2006cdf0e10cSrcweir  *  Loescht einen Cursor (gesteuert durch bOldCrsr)
2007cdf0e10cSrcweir  *      - vom Stack oder    ( bOldCrsr = sal_True )
2008cdf0e10cSrcweir  *      - den aktuellen und der auf dem Stack stehende wird zum aktuellen
2009cdf0e10cSrcweir  *
2010cdf0e10cSrcweir  *  Return:  es war auf dem Stack noch einer vorhanden
2011cdf0e10cSrcweir  */
2012cdf0e10cSrcweir 
2013cdf0e10cSrcweir 
Pop(sal_Bool bOldCrsr)2014cdf0e10cSrcweir sal_Bool SwCrsrShell::Pop( sal_Bool bOldCrsr )
2015cdf0e10cSrcweir {
2016cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
2017cdf0e10cSrcweir 
2018cdf0e10cSrcweir 	// noch weitere vorhanden ?
2019cdf0e10cSrcweir 	if( 0 == pCrsrStk )
2020cdf0e10cSrcweir 		return sal_False;
2021cdf0e10cSrcweir 
2022cdf0e10cSrcweir 	SwShellCrsr *pTmp = 0, *pOldStk = pCrsrStk;
2023cdf0e10cSrcweir 
2024cdf0e10cSrcweir 	// der Nachfolger wird der Aktuelle
2025cdf0e10cSrcweir 	if( pCrsrStk->GetNext() != pCrsrStk )
2026cdf0e10cSrcweir     {
2027cdf0e10cSrcweir         pTmp = dynamic_cast<SwShellCrsr*>(pCrsrStk->GetNext());
2028cdf0e10cSrcweir     }
2029cdf0e10cSrcweir 
2030cdf0e10cSrcweir 	if( bOldCrsr )              // loesche vom Stack
2031cdf0e10cSrcweir 		delete pCrsrStk;        //
2032cdf0e10cSrcweir 
2033cdf0e10cSrcweir 	pCrsrStk = pTmp;            // neu zuweisen
2034cdf0e10cSrcweir 
2035cdf0e10cSrcweir 	if( !bOldCrsr )
2036cdf0e10cSrcweir 	{
2037cdf0e10cSrcweir 		SwCrsrSaveState aSaveState( *pCurCrsr );
2038cdf0e10cSrcweir 
2039cdf0e10cSrcweir 		// wurde die sichtbare SSelection nicht veraendert
2040cdf0e10cSrcweir 		if( pOldStk->GetPtPos() == pCurCrsr->GetPtPos() ||
2041cdf0e10cSrcweir 			pOldStk->GetPtPos() == pCurCrsr->GetMkPos() )
2042cdf0e10cSrcweir 		{
2043cdf0e10cSrcweir 			// "Selektions-Rechtecke" verschieben
2044cdf0e10cSrcweir 			pCurCrsr->Insert( pOldStk, 0 );
2045cdf0e10cSrcweir 			pOldStk->Remove( 0, pOldStk->Count() );
2046cdf0e10cSrcweir 		}
2047cdf0e10cSrcweir 
2048cdf0e10cSrcweir 		if( pOldStk->HasMark() )
2049cdf0e10cSrcweir 		{
2050cdf0e10cSrcweir 			pCurCrsr->SetMark();
2051cdf0e10cSrcweir 			*pCurCrsr->GetMark() = *pOldStk->GetMark();
2052cdf0e10cSrcweir 			pCurCrsr->GetMkPos() = pOldStk->GetMkPos();
2053cdf0e10cSrcweir 		}
2054cdf0e10cSrcweir 		else
2055cdf0e10cSrcweir 			// keine Selection also alte aufheben und auf die alte Pos setzen
2056cdf0e10cSrcweir 			pCurCrsr->DeleteMark();
2057cdf0e10cSrcweir 		*pCurCrsr->GetPoint() = *pOldStk->GetPoint();
2058cdf0e10cSrcweir 		pCurCrsr->GetPtPos() = pOldStk->GetPtPos();
2059cdf0e10cSrcweir 		delete pOldStk;
2060cdf0e10cSrcweir 
2061cdf0e10cSrcweir 		if( !pCurCrsr->IsInProtectTable( sal_True ) &&
2062cdf0e10cSrcweir             !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
2063cdf0e10cSrcweir                                  nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
2064cdf0e10cSrcweir 			UpdateCrsr();             // akt. Cursor Updaten
2065cdf0e10cSrcweir 	}
2066cdf0e10cSrcweir 	return sal_True;
2067cdf0e10cSrcweir }
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir /*
2070cdf0e10cSrcweir  * Verbinde zwei Cursor miteinander.
2071cdf0e10cSrcweir  * Loesche vom Stack den obersten und setzen dessen GetMark im Aktuellen.
2072cdf0e10cSrcweir  */
2073cdf0e10cSrcweir 
2074cdf0e10cSrcweir 
Combine()2075cdf0e10cSrcweir void SwCrsrShell::Combine()
2076cdf0e10cSrcweir {
2077cdf0e10cSrcweir 	// noch weitere vorhanden ?
2078cdf0e10cSrcweir 	if( 0 == pCrsrStk )
2079cdf0e10cSrcweir 		return;
2080cdf0e10cSrcweir 
2081cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
2082cdf0e10cSrcweir 	SwCrsrSaveState aSaveState( *pCurCrsr );
2083cdf0e10cSrcweir 	if( pCrsrStk->HasMark() )           // nur wenn GetMark gesetzt wurde
2084cdf0e10cSrcweir 	{
2085cdf0e10cSrcweir #ifndef DBG_UTIL
2086cdf0e10cSrcweir 		CheckNodesRange( pCrsrStk->GetMark()->nNode, pCurCrsr->GetPoint()->nNode, sal_True );
2087cdf0e10cSrcweir #else
2088cdf0e10cSrcweir 		if( !CheckNodesRange( pCrsrStk->GetMark()->nNode, pCurCrsr->GetPoint()->nNode, sal_True ))
2089cdf0e10cSrcweir 			ASSERT( !this, "StackCrsr & akt. Crsr nicht in gleicher Section." );
2090cdf0e10cSrcweir #endif
2091cdf0e10cSrcweir 		// kopiere das GetMark
2092cdf0e10cSrcweir 		if( !pCurCrsr->HasMark() )
2093cdf0e10cSrcweir 			pCurCrsr->SetMark();
2094cdf0e10cSrcweir 		*pCurCrsr->GetMark() = *pCrsrStk->GetMark();
2095cdf0e10cSrcweir 		pCurCrsr->GetMkPos() = pCrsrStk->GetMkPos();
2096cdf0e10cSrcweir 	}
2097cdf0e10cSrcweir 
2098cdf0e10cSrcweir 	SwShellCrsr * pTmp = 0;
2099cdf0e10cSrcweir 	if( pCrsrStk->GetNext() != pCrsrStk )
2100cdf0e10cSrcweir     {
2101cdf0e10cSrcweir         pTmp = dynamic_cast<SwShellCrsr*>(pCrsrStk->GetNext());
2102cdf0e10cSrcweir     }
2103cdf0e10cSrcweir 	delete pCrsrStk;
2104cdf0e10cSrcweir 	pCrsrStk = pTmp;
2105cdf0e10cSrcweir 	if( !pCurCrsr->IsInProtectTable( sal_True ) &&
2106cdf0e10cSrcweir         !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
2107cdf0e10cSrcweir                              nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
2108cdf0e10cSrcweir 		UpdateCrsr();             // akt. Cursor Updaten
2109cdf0e10cSrcweir }
2110cdf0e10cSrcweir 
2111cdf0e10cSrcweir 
HideCrsrs()2112cdf0e10cSrcweir void SwCrsrShell::HideCrsrs()
2113cdf0e10cSrcweir {
2114cdf0e10cSrcweir 	if( !bHasFocus || bBasicHideCrsr )
2115cdf0e10cSrcweir 		return;
2116cdf0e10cSrcweir 
2117cdf0e10cSrcweir 	// ist Cursor sichtbar, dann verstecke den SV-Cursor
2118cdf0e10cSrcweir 	if( pVisCrsr->IsVisible() )
2119cdf0e10cSrcweir 	{
2120cdf0e10cSrcweir 		SET_CURR_SHELL( this );
2121cdf0e10cSrcweir 		pVisCrsr->Hide();
2122cdf0e10cSrcweir 	}
2123cdf0e10cSrcweir 	// hebe die Invertierung der SSelection auf
2124cdf0e10cSrcweir 	SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
2125cdf0e10cSrcweir 	pAktCrsr->Hide();
2126cdf0e10cSrcweir }
2127cdf0e10cSrcweir 
2128cdf0e10cSrcweir 
2129cdf0e10cSrcweir 
ShowCrsrs(sal_Bool bCrsrVis)2130cdf0e10cSrcweir void SwCrsrShell::ShowCrsrs( sal_Bool bCrsrVis )
2131cdf0e10cSrcweir {
2132cdf0e10cSrcweir 	if( !bHasFocus || bAllProtect || bBasicHideCrsr )
2133cdf0e10cSrcweir 		return;
2134cdf0e10cSrcweir 
2135cdf0e10cSrcweir 	SET_CURR_SHELL( this );
2136cdf0e10cSrcweir 	SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
2137cdf0e10cSrcweir 	pAktCrsr->Show();
2138cdf0e10cSrcweir 
2139cdf0e10cSrcweir 	if( bSVCrsrVis && bCrsrVis )    // auch SV-Cursor wieder anzeigen
2140cdf0e10cSrcweir 		pVisCrsr->Show();
2141cdf0e10cSrcweir }
2142cdf0e10cSrcweir 
2143cdf0e10cSrcweir // Methoden zum Anzeigen bzw. Verstecken des sichtbaren Text-Cursors
2144cdf0e10cSrcweir 
2145cdf0e10cSrcweir 
ShowCrsr()2146cdf0e10cSrcweir void SwCrsrShell::ShowCrsr()
2147cdf0e10cSrcweir {
214869a74367SOliver-Rainer Wittmann     if( !bBasicHideCrsr )
214969a74367SOliver-Rainer Wittmann     {
215069a74367SOliver-Rainer Wittmann         bSVCrsrVis = sal_True;
215169a74367SOliver-Rainer Wittmann         pCurCrsr->SetShowTxtInputFldOverlay( true );
215269a74367SOliver-Rainer Wittmann         UpdateCrsr();
215369a74367SOliver-Rainer Wittmann     }
2154cdf0e10cSrcweir }
2155cdf0e10cSrcweir 
2156cdf0e10cSrcweir 
HideCrsr()2157cdf0e10cSrcweir void SwCrsrShell::HideCrsr()
2158cdf0e10cSrcweir {
215969a74367SOliver-Rainer Wittmann     if( !bBasicHideCrsr )
216069a74367SOliver-Rainer Wittmann     {
216169a74367SOliver-Rainer Wittmann         bSVCrsrVis = sal_False;
216269a74367SOliver-Rainer Wittmann         // evt. die sel. Bereiche aufheben !!
216369a74367SOliver-Rainer Wittmann         SET_CURR_SHELL( this );
216469a74367SOliver-Rainer Wittmann         pCurCrsr->SetShowTxtInputFldOverlay( false );
216569a74367SOliver-Rainer Wittmann         pVisCrsr->Hide();
216669a74367SOliver-Rainer Wittmann     }
2167cdf0e10cSrcweir }
2168cdf0e10cSrcweir 
2169cdf0e10cSrcweir 
ShLooseFcs()2170cdf0e10cSrcweir void SwCrsrShell::ShLooseFcs()
2171cdf0e10cSrcweir {
2172cdf0e10cSrcweir 	if( !bBasicHideCrsr )
2173cdf0e10cSrcweir 		HideCrsrs();
2174cdf0e10cSrcweir 	bHasFocus = sal_False;
2175cdf0e10cSrcweir }
2176cdf0e10cSrcweir 
2177cdf0e10cSrcweir 
ShGetFcs(sal_Bool bUpdate)2178cdf0e10cSrcweir void SwCrsrShell::ShGetFcs( sal_Bool bUpdate )
2179cdf0e10cSrcweir {
2180cdf0e10cSrcweir 	bHasFocus = sal_True;
2181cdf0e10cSrcweir 	if( !bBasicHideCrsr && VisArea().Width() )
2182cdf0e10cSrcweir 	{
2183cdf0e10cSrcweir 		UpdateCrsr( static_cast<sal_uInt16>( bUpdate ?
2184cdf0e10cSrcweir                     SwCrsrShell::CHKRANGE|SwCrsrShell::SCROLLWIN
2185cdf0e10cSrcweir 					: SwCrsrShell::CHKRANGE ) );
2186cdf0e10cSrcweir 		ShowCrsrs( bSVCrsrVis ? sal_True : sal_False );
2187cdf0e10cSrcweir 	}
2188cdf0e10cSrcweir }
2189cdf0e10cSrcweir 
2190cdf0e10cSrcweir // gebe den aktuellen Frame, in dem der Cursor steht, zurueck
2191cdf0e10cSrcweir 
GetCurrFrm(const sal_Bool bCalcFrm) const2192cdf0e10cSrcweir SwCntntFrm *SwCrsrShell::GetCurrFrm( const sal_Bool bCalcFrm ) const
2193cdf0e10cSrcweir {
2194cdf0e10cSrcweir 	SET_CURR_SHELL( (ViewShell*)this );
2195cdf0e10cSrcweir 	SwCntntFrm *pRet = 0;
2196cdf0e10cSrcweir 	SwCntntNode *pNd = pCurCrsr->GetCntntNode();
2197cdf0e10cSrcweir 	if ( pNd )
2198cdf0e10cSrcweir 	{
2199cdf0e10cSrcweir 		if ( bCalcFrm )
2200cdf0e10cSrcweir 		{
2201cdf0e10cSrcweir 			const sal_uInt16* pST = &nStartAction;
2202cdf0e10cSrcweir 			++(*((sal_uInt16*)pST));
2203cdf0e10cSrcweir 			const Size aOldSz( GetDocSize() );
2204cdf0e10cSrcweir 			pRet = pNd->getLayoutFrm( GetLayout(), &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() );
2205cdf0e10cSrcweir 			--(*((sal_uInt16*)pST));
2206cdf0e10cSrcweir 			if( aOldSz != GetDocSize() )
2207cdf0e10cSrcweir                 ((SwCrsrShell*)this)->SizeChgNotify();
2208cdf0e10cSrcweir 		}
2209cdf0e10cSrcweir 		else
2210cdf0e10cSrcweir 			pRet = pNd->getLayoutFrm( GetLayout(), &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint(), sal_False);
2211cdf0e10cSrcweir 	}
2212cdf0e10cSrcweir 	return pRet;
2213cdf0e10cSrcweir }
2214cdf0e10cSrcweir 
2215cdf0e10cSrcweir 
2216cdf0e10cSrcweir // alle Attribut/Format-Aenderungen am akt. Node werden an den
2217cdf0e10cSrcweir // Link weitergeleitet.
2218cdf0e10cSrcweir 
2219cdf0e10cSrcweir 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)2220cdf0e10cSrcweir void SwCrsrShell::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
2221cdf0e10cSrcweir {
2222cdf0e10cSrcweir     const sal_uInt16 nWhich = pOld ?
2223cdf0e10cSrcweir                           pOld->Which() :
2224cdf0e10cSrcweir                           pNew ?
2225cdf0e10cSrcweir                           pNew->Which() :
2226cdf0e10cSrcweir                           sal::static_int_cast<sal_uInt16>(RES_MSG_BEGIN);
2227cdf0e10cSrcweir 
2228cdf0e10cSrcweir 	if( bCallChgLnk &&
2229cdf0e10cSrcweir 		( nWhich < RES_MSG_BEGIN || nWhich >= RES_MSG_END ||
2230cdf0e10cSrcweir 			nWhich == RES_FMT_CHG || nWhich == RES_UPDATE_ATTR ||
2231cdf0e10cSrcweir 			nWhich == RES_ATTRSET_CHG ))
2232cdf0e10cSrcweir 		// die Messages werden nicht weitergemeldet
2233cdf0e10cSrcweir 		//MA 07. Apr. 94 fix(6681): RES_UPDATE_ATTR wird implizit vom
2234cdf0e10cSrcweir 		//SwTxtNode::Insert(SwTxtHint*, sal_uInt16) abgesetzt; hier wird reagiert und
2235cdf0e10cSrcweir 		//vom Insert brauch nicht mehr die Keule RES_FMT_CHG versandt werden.
2236cdf0e10cSrcweir 		CallChgLnk();
2237cdf0e10cSrcweir 
2238cdf0e10cSrcweir 	if( aGrfArrivedLnk.IsSet() &&
2239cdf0e10cSrcweir 		( RES_GRAPHIC_ARRIVED == nWhich || RES_GRAPHIC_SWAPIN == nWhich ))
2240cdf0e10cSrcweir 		aGrfArrivedLnk.Call( this );
2241cdf0e10cSrcweir }
2242cdf0e10cSrcweir 
2243cdf0e10cSrcweir 
2244cdf0e10cSrcweir // Abfrage, ob der aktuelle Cursor eine Selektion aufspannt,
2245cdf0e10cSrcweir // also, ob GetMark gesetzt und SPoint und GetMark unterschiedlich sind.
2246cdf0e10cSrcweir 
2247cdf0e10cSrcweir 
HasSelection() const2248cdf0e10cSrcweir sal_Bool SwCrsrShell::HasSelection() const
2249cdf0e10cSrcweir {
2250cdf0e10cSrcweir 	const SwPaM* pCrsr = getShellCrsr( true );
2251cdf0e10cSrcweir 	return( IsTableMode() || ( pCrsr->HasMark() &&
2252cdf0e10cSrcweir 			*pCrsr->GetPoint() != *pCrsr->GetMark())
2253cdf0e10cSrcweir 		? sal_True : sal_False );
2254cdf0e10cSrcweir }
2255cdf0e10cSrcweir 
2256cdf0e10cSrcweir 
CallChgLnk()2257cdf0e10cSrcweir void SwCrsrShell::CallChgLnk()
2258cdf0e10cSrcweir {
2259cdf0e10cSrcweir 	// innerhalb von Start-/End-Action kein Call, sondern nur merken,
2260cdf0e10cSrcweir 	// das sich etwas geaendert hat. Wird bei EndAction beachtet.
2261cdf0e10cSrcweir 	if( BasicActionPend() )
2262cdf0e10cSrcweir 		bChgCallFlag = sal_True;		// das Change merken
2263cdf0e10cSrcweir 	else if( aChgLnk.IsSet() )
2264cdf0e10cSrcweir 	{
2265cdf0e10cSrcweir 		if( bCallChgLnk )
2266cdf0e10cSrcweir 			aChgLnk.Call( this );
2267cdf0e10cSrcweir 		bChgCallFlag = sal_False;		// Flag zuruecksetzen
2268cdf0e10cSrcweir 	}
2269cdf0e10cSrcweir }
2270cdf0e10cSrcweir 
2271cdf0e10cSrcweir // returne den am akt.Cursor selektierten Text eines Nodes.
2272cdf0e10cSrcweir 
2273cdf0e10cSrcweir 
GetSelTxt() const2274cdf0e10cSrcweir String SwCrsrShell::GetSelTxt() const
2275cdf0e10cSrcweir {
2276cdf0e10cSrcweir 	String aTxt;
2277cdf0e10cSrcweir 	if( pCurCrsr->GetPoint()->nNode.GetIndex() ==
2278cdf0e10cSrcweir 		pCurCrsr->GetMark()->nNode.GetIndex() )
2279cdf0e10cSrcweir 	{
2280cdf0e10cSrcweir 		SwTxtNode* pTxtNd = pCurCrsr->GetNode()->GetTxtNode();
2281cdf0e10cSrcweir 		if( pTxtNd )
2282cdf0e10cSrcweir 		{
2283cdf0e10cSrcweir 			xub_StrLen nStt = pCurCrsr->Start()->nContent.GetIndex();
2284cdf0e10cSrcweir 			aTxt = pTxtNd->GetExpandTxt( nStt,
2285cdf0e10cSrcweir 					pCurCrsr->End()->nContent.GetIndex() - nStt );
2286cdf0e10cSrcweir 		}
2287cdf0e10cSrcweir 	}
2288cdf0e10cSrcweir 	return aTxt;
2289cdf0e10cSrcweir }
2290cdf0e10cSrcweir 
2291cdf0e10cSrcweir // gebe nur den Text ab der akt. Cursor Position zurueck (bis zum NodeEnde)
2292cdf0e10cSrcweir 
2293cdf0e10cSrcweir 
GetText() const2294cdf0e10cSrcweir String SwCrsrShell::GetText() const
2295cdf0e10cSrcweir {
2296cdf0e10cSrcweir 	String aTxt;
2297cdf0e10cSrcweir 	if( pCurCrsr->GetPoint()->nNode.GetIndex() ==
2298cdf0e10cSrcweir 		pCurCrsr->GetMark()->nNode.GetIndex() )
2299cdf0e10cSrcweir 	{
2300cdf0e10cSrcweir 		SwTxtNode* pTxtNd = pCurCrsr->GetNode()->GetTxtNode();
2301cdf0e10cSrcweir 		if( pTxtNd )
2302cdf0e10cSrcweir 			aTxt = pTxtNd->GetTxt().Copy(
2303cdf0e10cSrcweir 					pCurCrsr->GetPoint()->nContent.GetIndex() );
2304cdf0e10cSrcweir 	}
2305cdf0e10cSrcweir 	return aTxt;
2306cdf0e10cSrcweir }
2307cdf0e10cSrcweir 
2308cdf0e10cSrcweir // hole vom Start/Ende der akt. SSelection das nte Zeichen
GetChar(sal_Bool bEnd,long nOffset)2309cdf0e10cSrcweir sal_Unicode SwCrsrShell::GetChar( sal_Bool bEnd, long nOffset )
2310cdf0e10cSrcweir {
2311cdf0e10cSrcweir 	if( IsTableMode() )			// im TabelleMode nicht moeglich
2312cdf0e10cSrcweir 		return 0;
2313cdf0e10cSrcweir 
2314cdf0e10cSrcweir 	const SwPosition* pPos = !pCurCrsr->HasMark() ? pCurCrsr->GetPoint()
2315cdf0e10cSrcweir 								: bEnd ? pCurCrsr->End() : pCurCrsr->Start();
2316cdf0e10cSrcweir 	SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
2317cdf0e10cSrcweir     if( !pTxtNd )
2318cdf0e10cSrcweir         return 0;
2319cdf0e10cSrcweir 
2320cdf0e10cSrcweir 	xub_StrLen nPos = pPos->nContent.GetIndex();
2321cdf0e10cSrcweir 	const String& rStr = pTxtNd->GetTxt();
2322cdf0e10cSrcweir 	sal_Unicode cCh = 0;
2323cdf0e10cSrcweir 
2324cdf0e10cSrcweir 	if( ((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.Len() )
2325cdf0e10cSrcweir 		cCh = rStr.GetChar( static_cast<xub_StrLen>(nPos+nOffset) );
2326cdf0e10cSrcweir 
2327cdf0e10cSrcweir 	return cCh;
2328cdf0e10cSrcweir }
2329cdf0e10cSrcweir 
2330cdf0e10cSrcweir // erweiter die akt. SSelection am Anfang/Ende um n Zeichen
2331cdf0e10cSrcweir 
2332cdf0e10cSrcweir 
ExtendSelection(sal_Bool bEnd,xub_StrLen nCount)2333cdf0e10cSrcweir sal_Bool SwCrsrShell::ExtendSelection( sal_Bool bEnd, xub_StrLen nCount )
2334cdf0e10cSrcweir {
2335cdf0e10cSrcweir 	if( !pCurCrsr->HasMark() || IsTableMode() )
2336cdf0e10cSrcweir 		return sal_False;			// keine Selektion
2337cdf0e10cSrcweir 
2338cdf0e10cSrcweir 	SwPosition* pPos = bEnd ? pCurCrsr->End() : pCurCrsr->Start();
2339cdf0e10cSrcweir 	SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
2340cdf0e10cSrcweir 	ASSERT( pTxtNd, "kein TextNode, wie soll erweitert werden?" );
2341cdf0e10cSrcweir 
2342cdf0e10cSrcweir 	xub_StrLen nPos = pPos->nContent.GetIndex();
2343cdf0e10cSrcweir 	if( bEnd )
2344cdf0e10cSrcweir 	{
2345cdf0e10cSrcweir 		if( ( nPos + nCount ) <= pTxtNd->GetTxt().Len() )
2346cdf0e10cSrcweir 			nPos = nPos + nCount;
2347cdf0e10cSrcweir 		else
2348cdf0e10cSrcweir 			return sal_False;		// nicht mehr moeglich
2349cdf0e10cSrcweir 	}
2350cdf0e10cSrcweir 	else if( nPos >= nCount )
2351cdf0e10cSrcweir 		nPos = nPos - nCount;
2352cdf0e10cSrcweir 	else
2353cdf0e10cSrcweir 		return sal_False;			// nicht mehr moeglich
2354cdf0e10cSrcweir 
2355cdf0e10cSrcweir 	SwCallLink aLk( *this );	// Crsr-Moves ueberwachen,
2356cdf0e10cSrcweir 
2357cdf0e10cSrcweir 	pPos->nContent = nPos;
2358cdf0e10cSrcweir 	UpdateCrsr();
2359cdf0e10cSrcweir 
2360cdf0e10cSrcweir 	return sal_True;
2361cdf0e10cSrcweir }
2362cdf0e10cSrcweir 
2363cdf0e10cSrcweir // setze nur den sichtbaren Cursor an die angegebene Dokument-Pos.
2364cdf0e10cSrcweir // returnt sal_False: wenn der SPoint vom Layout korrigiert wurde.
2365cdf0e10cSrcweir 
SetVisCrsr(const Point & rPt)2366cdf0e10cSrcweir sal_Bool SwCrsrShell::SetVisCrsr( const Point &rPt )
2367cdf0e10cSrcweir {
2368cdf0e10cSrcweir 	SET_CURR_SHELL( this );
2369cdf0e10cSrcweir 	Point aPt( rPt );
2370cdf0e10cSrcweir 	SwPosition aPos( *pCurCrsr->GetPoint() );
2371cdf0e10cSrcweir 	SwCrsrMoveState aTmpState( MV_SETONLYTEXT );
2372cdf0e10cSrcweir 	aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
2373cdf0e10cSrcweir 	aTmpState.bRealHeight = sal_True;
2374cdf0e10cSrcweir 
2375cdf0e10cSrcweir 	sal_Bool bRet = GetLayout()->GetCrsrOfst( &aPos, aPt /*, &aTmpState*/ );
2376cdf0e10cSrcweir 
2377cdf0e10cSrcweir     SetInFrontOfLabel( sal_False ); // #i27615#
2378cdf0e10cSrcweir 
2379cdf0e10cSrcweir 	// nur in TextNodes anzeigen !!
2380cdf0e10cSrcweir 	SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode();
2381cdf0e10cSrcweir 	if( !pTxtNd )
2382cdf0e10cSrcweir 		return sal_False;
2383cdf0e10cSrcweir 
2384cdf0e10cSrcweir 	const SwSectionNode* pSectNd = pTxtNd->FindSectionNode();
2385cdf0e10cSrcweir 	if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() ||
2386cdf0e10cSrcweir 					( !IsReadOnlyAvailable() &&
2387cdf0e10cSrcweir 					  pSectNd->GetSection().IsProtectFlag())) )
2388cdf0e10cSrcweir 		return sal_False;
2389cdf0e10cSrcweir 
2390cdf0e10cSrcweir 	SwCntntFrm *pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt, &aPos );
2391cdf0e10cSrcweir 	if ( Imp()->IsIdleAction() )
2392cdf0e10cSrcweir 		pFrm->PrepareCrsr();
2393cdf0e10cSrcweir 	SwRect aTmp( aCharRect );
2394cdf0e10cSrcweir 
2395cdf0e10cSrcweir 	pFrm->GetCharRect( aCharRect, aPos, &aTmpState );
2396cdf0e10cSrcweir //	ALIGNRECT( aCharRect );
2397cdf0e10cSrcweir 
2398cdf0e10cSrcweir 	if( aTmp == aCharRect && 		// BUG 10137: bleibt der Cursor auf der
2399cdf0e10cSrcweir 		pVisCrsr->IsVisible() )     // Position nicht hidden & showen
2400cdf0e10cSrcweir 		return sal_True;
2401cdf0e10cSrcweir 
2402cdf0e10cSrcweir 	pVisCrsr->Hide();       // sichtbaren Cursor immer verstecken
2403cdf0e10cSrcweir 	if( IsScrollMDI( this, aCharRect ))
2404cdf0e10cSrcweir 	{
2405cdf0e10cSrcweir 		MakeVisible( aCharRect );
2406cdf0e10cSrcweir 		pCurCrsr->Show();
2407cdf0e10cSrcweir 	}
2408cdf0e10cSrcweir 
2409cdf0e10cSrcweir 	// Bug 29584: bei Rahmenselektion ist der Cursor versteckt, aber den
2410cdf0e10cSrcweir 	//			D&D-Cursor will man trotzdem haben
2411cdf0e10cSrcweir //	if( bSVCrsrVis )
2412cdf0e10cSrcweir 	{
2413cdf0e10cSrcweir 		if( aTmpState.bRealHeight )
2414cdf0e10cSrcweir 			aCrsrHeight = aTmpState.aRealHeight;
2415cdf0e10cSrcweir 		else
2416cdf0e10cSrcweir 		{
2417cdf0e10cSrcweir 			aCrsrHeight.X() = 0;
2418cdf0e10cSrcweir 			aCrsrHeight.Y() = aCharRect.Height();
2419cdf0e10cSrcweir 		}
2420cdf0e10cSrcweir 
2421cdf0e10cSrcweir 		pVisCrsr->SetDragCrsr( sal_True );
2422cdf0e10cSrcweir 		pVisCrsr->Show();           // wieder anzeigen
2423cdf0e10cSrcweir 	}
2424cdf0e10cSrcweir 	return bRet;
2425cdf0e10cSrcweir }
2426cdf0e10cSrcweir 
IsOverReadOnlyPos(const Point & rPt) const2427cdf0e10cSrcweir sal_Bool SwCrsrShell::IsOverReadOnlyPos( const Point& rPt ) const
2428cdf0e10cSrcweir {
2429cdf0e10cSrcweir 	Point aPt( rPt );
2430cdf0e10cSrcweir 	SwPaM aPam( *pCurCrsr->GetPoint() );
2431cdf0e10cSrcweir     GetLayout()->GetCrsrOfst( aPam.GetPoint(), aPt );
2432cdf0e10cSrcweir     return aPam.HasReadonlySel( GetViewOptions()->IsFormView() );
2433cdf0e10cSrcweir }
2434cdf0e10cSrcweir 
2435cdf0e10cSrcweir 
2436cdf0e10cSrcweir 	// returne die Anzahl der Cursor im Ring (Flag besagt ob man nur
2437cdf0e10cSrcweir 	// aufgepspannte haben will - sprich etwas selektiert ist (Basic))
GetCrsrCnt(sal_Bool bAll) const2438cdf0e10cSrcweir sal_uInt16 SwCrsrShell::GetCrsrCnt( sal_Bool bAll ) const
2439cdf0e10cSrcweir {
2440cdf0e10cSrcweir 	Ring* pTmp = GetCrsr()->GetNext();
2441cdf0e10cSrcweir 	sal_uInt16 n = (bAll || ( pCurCrsr->HasMark() &&
2442cdf0e10cSrcweir 					*pCurCrsr->GetPoint() != *pCurCrsr->GetMark())) ? 1 : 0;
2443cdf0e10cSrcweir 	while( pTmp != pCurCrsr )
2444cdf0e10cSrcweir 	{
2445cdf0e10cSrcweir 		if( bAll || ( ((SwPaM*)pTmp)->HasMark() &&
2446cdf0e10cSrcweir 				*((SwPaM*)pTmp)->GetPoint() != *((SwPaM*)pTmp)->GetMark()))
2447cdf0e10cSrcweir 			++n;
2448cdf0e10cSrcweir 		pTmp = pTmp->GetNext();
2449cdf0e10cSrcweir 	}
2450cdf0e10cSrcweir 	return n;
2451cdf0e10cSrcweir }
2452cdf0e10cSrcweir 
2453cdf0e10cSrcweir 
IsStartOfDoc() const2454cdf0e10cSrcweir sal_Bool SwCrsrShell::IsStartOfDoc() const
2455cdf0e10cSrcweir {
2456cdf0e10cSrcweir 	if( pCurCrsr->GetPoint()->nContent.GetIndex() )
2457cdf0e10cSrcweir 		return sal_False;
2458cdf0e10cSrcweir 
2459cdf0e10cSrcweir 	// Hinter EndOfIcons kommt die Content-Section (EndNd+StNd+CntntNd)
2460cdf0e10cSrcweir 	SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfExtras(), 2 );
2461cdf0e10cSrcweir 	if( !aIdx.GetNode().IsCntntNode() )
2462cdf0e10cSrcweir 		GetDoc()->GetNodes().GoNext( &aIdx );
2463cdf0e10cSrcweir 	return aIdx == pCurCrsr->GetPoint()->nNode;
2464cdf0e10cSrcweir }
2465cdf0e10cSrcweir 
2466cdf0e10cSrcweir 
IsEndOfDoc() const2467cdf0e10cSrcweir sal_Bool SwCrsrShell::IsEndOfDoc() const
2468cdf0e10cSrcweir {
2469cdf0e10cSrcweir 	SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfContent(), -1 );
2470cdf0e10cSrcweir 	SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
2471cdf0e10cSrcweir 	if( !pCNd )
2472cdf0e10cSrcweir 		pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx );
2473cdf0e10cSrcweir 
2474cdf0e10cSrcweir 	return aIdx == pCurCrsr->GetPoint()->nNode &&
2475cdf0e10cSrcweir 			pCNd->Len() == pCurCrsr->GetPoint()->nContent.GetIndex();
2476cdf0e10cSrcweir }
2477cdf0e10cSrcweir 
2478cdf0e10cSrcweir 
2479cdf0e10cSrcweir // loesche alle erzeugten Crsr, setze den Tabellen-Crsr und den letzten
2480cdf0e10cSrcweir // Cursor auf seinen TextNode (oder StartNode?).
2481cdf0e10cSrcweir // Beim naechsten ::GetCrsr werden sie wieder alle erzeugt
2482cdf0e10cSrcweir // Wird fuers Drag&Drop / ClipBorad-Paste in Tabellen benoetigt.
ParkTblCrsr()2483cdf0e10cSrcweir sal_Bool SwCrsrShell::ParkTblCrsr()
2484cdf0e10cSrcweir {
2485cdf0e10cSrcweir 	if( !pTblCrsr )
2486cdf0e10cSrcweir 		return sal_False;
2487cdf0e10cSrcweir 
2488cdf0e10cSrcweir 	pTblCrsr->ParkCrsr();
2489cdf0e10cSrcweir 
2490cdf0e10cSrcweir 	while( pCurCrsr->GetNext() != pCurCrsr )
2491cdf0e10cSrcweir 		delete pCurCrsr->GetNext();
2492cdf0e10cSrcweir 
2493cdf0e10cSrcweir 	// vom Cursor !immer! SPoint und Mark umsetzen
2494cdf0e10cSrcweir 	pCurCrsr->SetMark();
2495cdf0e10cSrcweir 	*pCurCrsr->GetMark() = *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint();
2496cdf0e10cSrcweir 	pCurCrsr->DeleteMark();
2497cdf0e10cSrcweir 
2498cdf0e10cSrcweir 	return sal_True;
2499cdf0e10cSrcweir }
2500cdf0e10cSrcweir 
2501cdf0e10cSrcweir /***********************************************************************
2502cdf0e10cSrcweir #*	Class		:  SwCrsrShell
2503cdf0e10cSrcweir #*	Methode 	:  ParkCrsr
2504cdf0e10cSrcweir #*	Beschreibung:  Vernichtet Selektionen und zus. Crsr aller Shell der
2505cdf0e10cSrcweir #*				   verbleibende Crsr der Shell wird geparkt.
2506cdf0e10cSrcweir #*	Datum		:  MA 05. Nov. 92
2507cdf0e10cSrcweir #*	Update		:  JP 19.09.97
2508cdf0e10cSrcweir #***********************************************************************/
2509cdf0e10cSrcweir 
_ParkPams(SwPaM * pDelRg,SwShellCrsr ** ppDelRing)2510cdf0e10cSrcweir void SwCrsrShell::_ParkPams( SwPaM* pDelRg, SwShellCrsr** ppDelRing )
2511cdf0e10cSrcweir {
2512cdf0e10cSrcweir 	const SwPosition *pStt = pDelRg->Start(),
2513cdf0e10cSrcweir 		*pEnd = pDelRg->GetPoint() == pStt ? pDelRg->GetMark() : pDelRg->GetPoint();
2514cdf0e10cSrcweir 
2515cdf0e10cSrcweir 	SwPaM *pTmpDel = 0, *pTmp = *ppDelRing;
2516cdf0e10cSrcweir 
2517cdf0e10cSrcweir 	// durchsuche den gesamten Ring
2518cdf0e10cSrcweir 	sal_Bool bGoNext;
2519cdf0e10cSrcweir 	do {
2520cdf0e10cSrcweir 		const SwPosition *pTmpStt = pTmp->Start(),
2521cdf0e10cSrcweir 						*pTmpEnd = pTmp->GetPoint() == pTmpStt ?
2522cdf0e10cSrcweir 										pTmp->GetMark() : pTmp->GetPoint();
2523cdf0e10cSrcweir 		/*
2524cdf0e10cSrcweir 		 * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich
2525cdf0e10cSrcweir 		 * muss der alte Bereich aufgehoben werden.
2526cdf0e10cSrcweir 		 * Beim Vergleich ist darauf zu achten, das End() nicht mehr zum
2527cdf0e10cSrcweir 		 * Bereich gehoert !
2528cdf0e10cSrcweir 		 */
2529cdf0e10cSrcweir 		if( *pStt <= *pTmpStt )
2530cdf0e10cSrcweir 		{
2531cdf0e10cSrcweir 			if( *pEnd > *pTmpStt ||
2532cdf0e10cSrcweir 				( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
2533cdf0e10cSrcweir 				pTmpDel = pTmp;
2534cdf0e10cSrcweir 		}
2535cdf0e10cSrcweir 		else
2536cdf0e10cSrcweir 			if( *pStt < *pTmpEnd )
2537cdf0e10cSrcweir 				pTmpDel = pTmp;
2538cdf0e10cSrcweir 
2539cdf0e10cSrcweir 		bGoNext = sal_True;
2540cdf0e10cSrcweir 		if( pTmpDel )			// ist der Pam im Bereich ?? loesche ihn
2541cdf0e10cSrcweir 		{
2542cdf0e10cSrcweir 			sal_Bool bDelete = sal_True;
2543cdf0e10cSrcweir 			if( *ppDelRing == pTmpDel )
2544cdf0e10cSrcweir 			{
2545cdf0e10cSrcweir 				if( *ppDelRing == pCurCrsr )
2546cdf0e10cSrcweir 				{
2547cdf0e10cSrcweir 					if( sal_True == ( bDelete = GoNextCrsr() ))
2548cdf0e10cSrcweir 					{
2549cdf0e10cSrcweir 						bGoNext = sal_False;
2550cdf0e10cSrcweir 						pTmp = (SwPaM*)pTmp->GetNext();
2551cdf0e10cSrcweir 					}
2552cdf0e10cSrcweir 				}
2553cdf0e10cSrcweir 				else
2554cdf0e10cSrcweir 					bDelete = sal_False;		// StackCrsr nie loeschen !!
2555cdf0e10cSrcweir 			}
2556cdf0e10cSrcweir 
2557cdf0e10cSrcweir 			if( bDelete )
2558cdf0e10cSrcweir 				delete pTmpDel; 		// hebe alten Bereich auf
2559cdf0e10cSrcweir 			else
2560cdf0e10cSrcweir 			{
2561cdf0e10cSrcweir 				pTmpDel->GetPoint()->nContent.Assign( 0, 0 );
2562cdf0e10cSrcweir 				pTmpDel->GetPoint()->nNode = 0;
2563cdf0e10cSrcweir 				pTmpDel->SetMark();
2564cdf0e10cSrcweir 				pTmpDel->DeleteMark();
2565cdf0e10cSrcweir 			}
2566cdf0e10cSrcweir 			pTmpDel = 0;
2567cdf0e10cSrcweir 		}
2568cdf0e10cSrcweir 		else if( !pTmp->HasMark() ) 	// sorge auf jedenfall dafuer, das
2569cdf0e10cSrcweir 		{						// nicht benutzte Indizies beachtet werden!
2570cdf0e10cSrcweir 			pTmp->SetMark();			// SPoint liegt nicht im Bereich,
2571cdf0e10cSrcweir 			pTmp->DeleteMark(); 		// aber vielleicht GetMark, also setzen
2572cdf0e10cSrcweir 		}
2573cdf0e10cSrcweir 		if( bGoNext )
2574cdf0e10cSrcweir 			pTmp = (SwPaM*)pTmp->GetNext();
2575cdf0e10cSrcweir 	} while( !bGoNext || *ppDelRing != pTmp );
2576cdf0e10cSrcweir }
2577cdf0e10cSrcweir 
ParkCrsr(const SwNodeIndex & rIdx)2578cdf0e10cSrcweir void SwCrsrShell::ParkCrsr( const SwNodeIndex &rIdx )
2579cdf0e10cSrcweir {
2580cdf0e10cSrcweir 	SwNode *pNode = &rIdx.GetNode();
2581cdf0e10cSrcweir 
2582cdf0e10cSrcweir 	// erzeuge einen neuen Pam
2583cdf0e10cSrcweir 	SwPaM * pNew = new SwPaM( *GetCrsr()->GetPoint() );
2584cdf0e10cSrcweir 	if( pNode->GetStartNode() )
2585cdf0e10cSrcweir 	{
2586cdf0e10cSrcweir 		if( ( pNode = pNode->StartOfSectionNode())->IsTableNode() )
2587cdf0e10cSrcweir 		{
2588cdf0e10cSrcweir 			// der angegebene Node steht in einer Tabelle, also Parke
2589cdf0e10cSrcweir 			// den Crsr auf dem Tabellen-Node (ausserhalb der Tabelle)
2590cdf0e10cSrcweir 			pNew->GetPoint()->nNode = *pNode->StartOfSectionNode();
2591cdf0e10cSrcweir 		}
2592cdf0e10cSrcweir 		else	// also auf dem StartNode selbst.
2593cdf0e10cSrcweir 				// Dann immer ueber seinen EndNode den StartNode erfragen !!!
2594cdf0e10cSrcweir 				// (StartOfSection vom StartNode ist der Parent !)
2595cdf0e10cSrcweir 			pNew->GetPoint()->nNode = *pNode->EndOfSectionNode()->StartOfSectionNode();
2596cdf0e10cSrcweir 	}
2597cdf0e10cSrcweir 	else
2598cdf0e10cSrcweir 		pNew->GetPoint()->nNode = *pNode->StartOfSectionNode();
2599cdf0e10cSrcweir 	pNew->SetMark();
2600cdf0e10cSrcweir 	pNew->GetPoint()->nNode = *pNode->EndOfSectionNode();
2601cdf0e10cSrcweir 
2602cdf0e10cSrcweir 	//Alle Shells wollen etwas davon haben.
2603cdf0e10cSrcweir 	ViewShell *pTmp = this;
2604cdf0e10cSrcweir 	do {
2605cdf0e10cSrcweir 		if( pTmp->IsA( TYPE( SwCrsrShell )))
2606cdf0e10cSrcweir 		{
2607cdf0e10cSrcweir 			SwCrsrShell* pSh = (SwCrsrShell*)pTmp;
2608cdf0e10cSrcweir 			if( pSh->pCrsrStk )
2609cdf0e10cSrcweir 				pSh->_ParkPams( pNew, &pSh->pCrsrStk );
2610cdf0e10cSrcweir 
2611cdf0e10cSrcweir 			pSh->_ParkPams( pNew, &pSh->pCurCrsr );
2612cdf0e10cSrcweir 			if( pSh->pTblCrsr )
2613cdf0e10cSrcweir 			{
2614cdf0e10cSrcweir 				// setze den Tabellen Cursor immer auf 0, den aktuellen
2615cdf0e10cSrcweir 				// immer auf den Anfang der Tabelle
2616cdf0e10cSrcweir 				SwPaM* pTCrsr = pSh->GetTblCrs();
2617cdf0e10cSrcweir 				SwNode* pTblNd = pTCrsr->GetPoint()->nNode.GetNode().FindTableNode();
2618cdf0e10cSrcweir 				if ( pTblNd )
2619cdf0e10cSrcweir 				{
2620cdf0e10cSrcweir 					pTCrsr->GetPoint()->nContent.Assign( 0, 0 );
2621cdf0e10cSrcweir 					pTCrsr->GetPoint()->nNode = 0;
2622cdf0e10cSrcweir 					pTCrsr->SetMark();
2623cdf0e10cSrcweir 					pTCrsr->DeleteMark();
2624cdf0e10cSrcweir 					pSh->pCurCrsr->GetPoint()->nNode = *pTblNd;
2625cdf0e10cSrcweir 				}
2626cdf0e10cSrcweir 			}
2627cdf0e10cSrcweir 		}
2628cdf0e10cSrcweir 	} while ( this != (pTmp = (ViewShell*)pTmp->GetNext() ));
2629cdf0e10cSrcweir 	delete pNew;
2630cdf0e10cSrcweir }
2631cdf0e10cSrcweir 
2632cdf0e10cSrcweir //=========================================================================
2633cdf0e10cSrcweir 
2634cdf0e10cSrcweir /*
2635cdf0e10cSrcweir  * der Copy-Constructor
2636cdf0e10cSrcweir  * Cursor-Position kopieren, in den Ring eingetragen.
2637cdf0e10cSrcweir  * Alle Ansichten eines Dokumentes stehen im Ring der Shells.
2638cdf0e10cSrcweir  */
2639cdf0e10cSrcweir 
SwCrsrShell(SwCrsrShell & rShell,Window * pInitWin)2640cdf0e10cSrcweir SwCrsrShell::SwCrsrShell( SwCrsrShell& rShell, Window *pInitWin )
2641cdf0e10cSrcweir 	: ViewShell( rShell, pInitWin ),
2642cdf0e10cSrcweir 	SwModify( 0 ), pCrsrStk( 0 ), pBlockCrsr( 0 ), pTblCrsr( 0 ),
2643cdf0e10cSrcweir 	pBoxIdx( 0 ), pBoxPtr( 0 ), nCrsrMove( 0 ), nBasicActionCnt( 0 ),
2644cdf0e10cSrcweir     eMvState( MV_NONE ),
2645cdf0e10cSrcweir     // --> OD 2008-04-02 #refactorlists#
2646cdf0e10cSrcweir     sMarkedListId(),
2647cdf0e10cSrcweir     nMarkedListLevel( 0 )
2648cdf0e10cSrcweir     // <--
2649cdf0e10cSrcweir {
2650cdf0e10cSrcweir 	SET_CURR_SHELL( this );
2651cdf0e10cSrcweir 	// Nur die Position vom aktuellen Cursor aus der Copy-Shell uebernehmen
2652cdf0e10cSrcweir 	pCurCrsr = new SwShellCrsr( *this, *(rShell.pCurCrsr->GetPoint()) );
2653cdf0e10cSrcweir 	pCurCrsr->GetCntntNode()->Add( this );
2654cdf0e10cSrcweir 
2655cdf0e10cSrcweir 	bAllProtect = bVisPortChgd = bChgCallFlag = bInCMvVisportChgd =
2656cdf0e10cSrcweir 	bGCAttr = bIgnoreReadonly = bSelTblCells = bBasicHideCrsr =
2657cdf0e10cSrcweir 	bOverwriteCrsr = sal_False;
2658cdf0e10cSrcweir 	bCallChgLnk = bHasFocus = bSVCrsrVis = bAutoUpdateCells = sal_True;
2659cdf0e10cSrcweir 	bSetCrsrInReadOnly = sal_True;
2660cdf0e10cSrcweir 	pVisCrsr = new SwVisCrsr( this );
2661cdf0e10cSrcweir //	UpdateCrsr( 0 );
2662cdf0e10cSrcweir     // OD 11.02.2003 #100556#
2663cdf0e10cSrcweir     mbMacroExecAllowed = rShell.IsMacroExecAllowed();
2664ca62e2c2SSteve Yin 	oldColFrm = NULL;
2665cdf0e10cSrcweir }
2666cdf0e10cSrcweir 
2667cdf0e10cSrcweir 
2668cdf0e10cSrcweir /*
2669cdf0e10cSrcweir  * der normale Constructor
2670cdf0e10cSrcweir  */
2671cdf0e10cSrcweir 
SwCrsrShell(SwDoc & rDoc,Window * pInitWin,const SwViewOption * pInitOpt)2672cdf0e10cSrcweir SwCrsrShell::SwCrsrShell( SwDoc& rDoc, Window *pInitWin,
2673cdf0e10cSrcweir 							const SwViewOption *pInitOpt )
2674cdf0e10cSrcweir 	: ViewShell( rDoc, pInitWin, pInitOpt ),
2675cdf0e10cSrcweir 	SwModify( 0 ), pCrsrStk( 0 ), pBlockCrsr( 0 ), pTblCrsr( 0 ),
2676cdf0e10cSrcweir 	pBoxIdx( 0 ), pBoxPtr( 0 ), nCrsrMove( 0 ), nBasicActionCnt( 0 ),
2677cdf0e10cSrcweir     eMvState( MV_NONE ), // state for crsr-travelling - GetCrsrOfst
2678cdf0e10cSrcweir     // --> OD 2008-04-02 #refactorlists#
2679cdf0e10cSrcweir     sMarkedListId(),
2680cdf0e10cSrcweir     nMarkedListLevel( 0 )
2681cdf0e10cSrcweir     // <--
2682cdf0e10cSrcweir {
2683cdf0e10cSrcweir 	SET_CURR_SHELL( this );
2684cdf0e10cSrcweir 	/*
2685cdf0e10cSrcweir 	 * Erzeugen des initialen Cursors, wird auf die erste
2686cdf0e10cSrcweir 	 * Inhaltsposition gesetzt
2687cdf0e10cSrcweir 	 */
2688cdf0e10cSrcweir 	SwNodes& rNds = rDoc.GetNodes();
2689cdf0e10cSrcweir 
2690cdf0e10cSrcweir 	SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
2691cdf0e10cSrcweir 	SwCntntNode* pCNd = rNds.GoNext( &aNodeIdx ); // gehe zum 1. ContentNode
2692cdf0e10cSrcweir 
2693cdf0e10cSrcweir 	pCurCrsr = new SwShellCrsr( *this, SwPosition( aNodeIdx, SwIndex( pCNd, 0 )));
2694cdf0e10cSrcweir 
2695cdf0e10cSrcweir 	// melde die Shell beim akt. Node als abhaengig an, dadurch koennen alle
2696cdf0e10cSrcweir 	// Attribut-Aenderungen ueber den Link weiter gemeldet werden.
2697cdf0e10cSrcweir 	pCNd->Add( this );
2698cdf0e10cSrcweir 
2699cdf0e10cSrcweir 	bAllProtect = bVisPortChgd = bChgCallFlag = bInCMvVisportChgd =
2700cdf0e10cSrcweir 	bGCAttr = bIgnoreReadonly = bSelTblCells = bBasicHideCrsr =
2701cdf0e10cSrcweir 	bOverwriteCrsr = sal_False;
2702cdf0e10cSrcweir 	bCallChgLnk = bHasFocus = bSVCrsrVis = bAutoUpdateCells = sal_True;
2703cdf0e10cSrcweir 	bSetCrsrInReadOnly = sal_True;
2704cdf0e10cSrcweir 
2705cdf0e10cSrcweir 	pVisCrsr = new SwVisCrsr( this );
2706cdf0e10cSrcweir //	UpdateCrsr( 0 );
2707cdf0e10cSrcweir     // OD 11.02.2003 #100556#
2708cdf0e10cSrcweir     mbMacroExecAllowed = true;
2709cdf0e10cSrcweir }
2710cdf0e10cSrcweir 
2711cdf0e10cSrcweir 
2712cdf0e10cSrcweir 
~SwCrsrShell()2713cdf0e10cSrcweir SwCrsrShell::~SwCrsrShell()
2714cdf0e10cSrcweir {
2715cdf0e10cSrcweir 	// wenn es nicht die letzte View so sollte zu mindest das
2716cdf0e10cSrcweir 	// Feld noch geupdatet werden.
2717cdf0e10cSrcweir 	if( GetNext() != this )
2718cdf0e10cSrcweir 		CheckTblBoxCntnt( pCurCrsr->GetPoint() );
2719cdf0e10cSrcweir 	else
2720cdf0e10cSrcweir 		ClearTblBoxCntnt();
2721cdf0e10cSrcweir 
2722cdf0e10cSrcweir 	delete pVisCrsr;
2723cdf0e10cSrcweir     delete pBlockCrsr;
2724cdf0e10cSrcweir 	delete pTblCrsr;
2725cdf0e10cSrcweir 
2726cdf0e10cSrcweir 	/*
2727cdf0e10cSrcweir 	 * Freigabe der Cursor
2728cdf0e10cSrcweir 	 */
2729cdf0e10cSrcweir 	while(pCurCrsr->GetNext() != pCurCrsr)
2730cdf0e10cSrcweir 		delete pCurCrsr->GetNext();
2731cdf0e10cSrcweir 	delete pCurCrsr;
2732cdf0e10cSrcweir 
2733cdf0e10cSrcweir 	// Stack freigeben
2734cdf0e10cSrcweir 	if( pCrsrStk )
2735cdf0e10cSrcweir 	{
2736cdf0e10cSrcweir 		while( pCrsrStk->GetNext() != pCrsrStk )
2737cdf0e10cSrcweir 			delete pCrsrStk->GetNext();
2738cdf0e10cSrcweir 		delete pCrsrStk;
2739cdf0e10cSrcweir 	}
2740cdf0e10cSrcweir 
2741cdf0e10cSrcweir 	// JP 27.07.98: Bug 54025 - ggfs. den HTML-Parser, der als Client in
2742cdf0e10cSrcweir 	// 				der CursorShell haengt keine Chance geben, sich an den
2743cdf0e10cSrcweir 	//				TextNode zu haengen.
2744cdf0e10cSrcweir 	if( GetRegisteredIn() )
2745cdf0e10cSrcweir 		GetRegisteredInNonConst()->Remove( this );
2746cdf0e10cSrcweir }
2747cdf0e10cSrcweir 
getShellCrsr(bool bBlock)2748cdf0e10cSrcweir SwShellCrsr* SwCrsrShell::getShellCrsr( bool bBlock )
2749cdf0e10cSrcweir {
2750cdf0e10cSrcweir     if( pTblCrsr )
2751cdf0e10cSrcweir         return pTblCrsr;
2752cdf0e10cSrcweir     if( pBlockCrsr && bBlock )
2753cdf0e10cSrcweir         return &pBlockCrsr->getShellCrsr();
2754cdf0e10cSrcweir     return pCurCrsr;
2755cdf0e10cSrcweir }
2756cdf0e10cSrcweir 
2757cdf0e10cSrcweir //Sollte fuer das Clipboard der WaitPtr geschaltet werden?
2758cdf0e10cSrcweir //Warten bei TableMode, Mehrfachselektion und mehr als x Selektieren Absaetzen.
2759cdf0e10cSrcweir 
ShouldWait() const2760cdf0e10cSrcweir sal_Bool SwCrsrShell::ShouldWait() const
2761cdf0e10cSrcweir {
2762cdf0e10cSrcweir 	if ( IsTableMode() || GetCrsrCnt() > 1 )
2763cdf0e10cSrcweir 		return sal_True;
2764cdf0e10cSrcweir 
2765cdf0e10cSrcweir 	if( HasDrawView() && GetDrawView()->GetMarkedObjectList().GetMarkCount() )
2766cdf0e10cSrcweir 		return sal_True;
2767cdf0e10cSrcweir 
2768cdf0e10cSrcweir 	SwPaM* pPam = GetCrsr();
2769cdf0e10cSrcweir 	return pPam->Start()->nNode.GetIndex() + 10 <
2770cdf0e10cSrcweir 			pPam->End()->nNode.GetIndex();
2771cdf0e10cSrcweir }
2772cdf0e10cSrcweir 
2773cdf0e10cSrcweir 
UpdateTblSelBoxes()2774cdf0e10cSrcweir sal_uInt16 SwCrsrShell::UpdateTblSelBoxes()
2775cdf0e10cSrcweir {
2776cdf0e10cSrcweir 	if( pTblCrsr && ( pTblCrsr->IsChgd() || !pTblCrsr->GetBoxesCount() ))
2777cdf0e10cSrcweir 		 GetLayout()->MakeTblCrsrs( *pTblCrsr );
2778cdf0e10cSrcweir 	return pTblCrsr ? pTblCrsr->GetBoxesCount() : 0;
2779cdf0e10cSrcweir }
2780cdf0e10cSrcweir 
2781cdf0e10cSrcweir // zeige das akt. selektierte "Object" an
MakeSelVisible()2782cdf0e10cSrcweir void SwCrsrShell::MakeSelVisible()
2783cdf0e10cSrcweir {
2784cdf0e10cSrcweir 	ASSERT( bHasFocus, "kein Focus aber Cursor sichtbar machen?" );
2785cdf0e10cSrcweir 	if( aCrsrHeight.Y() < aCharRect.Height() && aCharRect.Height() > VisArea().Height() )
2786cdf0e10cSrcweir 	{
2787cdf0e10cSrcweir 		SwRect aTmp( aCharRect );
2788cdf0e10cSrcweir 		long nDiff = aCharRect.Height() - VisArea().Height();
2789cdf0e10cSrcweir 		if( nDiff < aCrsrHeight.X() )
2790cdf0e10cSrcweir 			aTmp.Top( nDiff + aCharRect.Top() );
2791cdf0e10cSrcweir 		else
2792cdf0e10cSrcweir 		{
2793cdf0e10cSrcweir 			aTmp.Top( aCrsrHeight.X() + aCharRect.Top() );
2794cdf0e10cSrcweir 			aTmp.Height( aCrsrHeight.Y() );
2795cdf0e10cSrcweir 		}
2796cdf0e10cSrcweir         if( !aTmp.HasArea() )
2797cdf0e10cSrcweir         {
2798cdf0e10cSrcweir             aTmp.SSize().Height() += 1;
2799cdf0e10cSrcweir             aTmp.SSize().Width() += 1;
2800cdf0e10cSrcweir         }
2801cdf0e10cSrcweir 		MakeVisible( aTmp );
2802cdf0e10cSrcweir 	}
2803cdf0e10cSrcweir 	else
2804cdf0e10cSrcweir 	{
2805cdf0e10cSrcweir 		if( aCharRect.HasArea() )
2806cdf0e10cSrcweir 			MakeVisible( aCharRect );
2807cdf0e10cSrcweir 		else
2808cdf0e10cSrcweir 		{
2809cdf0e10cSrcweir 			SwRect aTmp( aCharRect );
2810cdf0e10cSrcweir 			aTmp.SSize().Height() += 1; aTmp.SSize().Width() += 1;
2811cdf0e10cSrcweir 			MakeVisible( aTmp );
2812cdf0e10cSrcweir 		}
2813cdf0e10cSrcweir 	}
2814cdf0e10cSrcweir }
2815cdf0e10cSrcweir 
2816cdf0e10cSrcweir 
2817cdf0e10cSrcweir // suche eine gueltige ContentPosition (nicht geschuetzt/nicht versteckt)
FindValidCntntNode(sal_Bool bOnlyText)2818cdf0e10cSrcweir sal_Bool SwCrsrShell::FindValidCntntNode( sal_Bool bOnlyText )
2819cdf0e10cSrcweir {
2820cdf0e10cSrcweir 	if( pTblCrsr )		// was soll ich jetzt machen ??
2821cdf0e10cSrcweir 	{
2822cdf0e10cSrcweir 		ASSERT( !this, "TabellenSelection nicht aufgehoben!" );
2823cdf0e10cSrcweir 		return sal_False;
2824cdf0e10cSrcweir 	}
2825cdf0e10cSrcweir 
2826cdf0e10cSrcweir 	//JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt
2827cdf0e10cSrcweir 	if( !bAllProtect && GetDoc()->GetDocShell() &&
2828cdf0e10cSrcweir 		GetDoc()->GetDocShell()->IsReadOnlyUI() )
2829cdf0e10cSrcweir 		return sal_True;
2830cdf0e10cSrcweir 
2831cdf0e10cSrcweir 	// dann raus da!
2832cdf0e10cSrcweir 	if( pCurCrsr->HasMark()	)
2833cdf0e10cSrcweir 		ClearMark();
2834cdf0e10cSrcweir 
2835cdf0e10cSrcweir 	// als erstes mal auf Rahmen abpruefen
2836cdf0e10cSrcweir 	SwNodeIndex& rNdIdx = pCurCrsr->GetPoint()->nNode;
2837cdf0e10cSrcweir 	sal_uLong nNdIdx = rNdIdx.GetIndex();		// sichern
2838cdf0e10cSrcweir 	SwNodes& rNds = pDoc->GetNodes();
2839cdf0e10cSrcweir 	SwCntntNode* pCNd = rNdIdx.GetNode().GetCntntNode();
2840cdf0e10cSrcweir 	const SwCntntFrm * pFrm;
2841cdf0e10cSrcweir 
2842cdf0e10cSrcweir 	if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( GetLayout(),0,pCurCrsr->GetPoint(),sal_False)) &&
2843cdf0e10cSrcweir 		!IsReadOnlyAvailable() && pFrm->IsProtected() &&
2844cdf0e10cSrcweir 		nNdIdx < rNds.GetEndOfExtras().GetIndex() )
2845cdf0e10cSrcweir 	{
2846cdf0e10cSrcweir 		// geschuetzter Rahmen ueberspringen
2847cdf0e10cSrcweir 		SwPaM aPam( *pCurCrsr->GetPoint() );
2848cdf0e10cSrcweir 		aPam.SetMark();
2849cdf0e10cSrcweir 		aPam.GetMark()->nNode = rNds.GetEndOfContent();
2850cdf0e10cSrcweir 		aPam.GetPoint()->nNode = *pCNd->EndOfSectionNode();
2851cdf0e10cSrcweir 
2852cdf0e10cSrcweir 		sal_Bool bFirst = sal_False;
2853cdf0e10cSrcweir 		if( 0 == (pCNd = ::GetNode( aPam, bFirst, fnMoveForward, sal_False )))
2854cdf0e10cSrcweir 		{
2855cdf0e10cSrcweir 			aPam.GetMark()->nNode = *rNds.GetEndOfPostIts().StartOfSectionNode();
2856cdf0e10cSrcweir 			pCNd = ::GetNode( aPam, bFirst, fnMoveBackward, sal_False );
2857cdf0e10cSrcweir 		}
2858cdf0e10cSrcweir 
2859cdf0e10cSrcweir 		if( !pCNd )		// sollte nie passieren !!!
2860cdf0e10cSrcweir 		{
2861cdf0e10cSrcweir 			rNdIdx = nNdIdx;		// alten Node zurueck
2862cdf0e10cSrcweir 			return sal_False;
2863cdf0e10cSrcweir 		}
2864cdf0e10cSrcweir 		*pCurCrsr->GetPoint() = *aPam.GetPoint();
2865cdf0e10cSrcweir 	}
2866cdf0e10cSrcweir 	else if( bOnlyText && pCNd && pCNd->IsNoTxtNode() )
2867cdf0e10cSrcweir 	{
2868cdf0e10cSrcweir 		// dann auf den Anfang vom Doc stellen
2869cdf0e10cSrcweir 		rNdIdx = pDoc->GetNodes().GetEndOfExtras();
2870cdf0e10cSrcweir 		pCurCrsr->GetPoint()->nContent.Assign( pDoc->GetNodes().GoNext(
2871cdf0e10cSrcweir 															&rNdIdx ), 0 );
2872cdf0e10cSrcweir 		nNdIdx = rNdIdx.GetIndex();
2873cdf0e10cSrcweir 	}
2874cdf0e10cSrcweir 
2875cdf0e10cSrcweir 	sal_Bool bOk = sal_True;
2876cdf0e10cSrcweir 
2877cdf0e10cSrcweir     // #i9059# cursor may not stand in protected cells
2878cdf0e10cSrcweir     //         (unless cursor in protected areas is OK.)
2879cdf0e10cSrcweir     const SwTableNode* pTableNode = rNdIdx.GetNode().FindTableNode();
2880cdf0e10cSrcweir     if( !IsReadOnlyAvailable()  &&
2881cdf0e10cSrcweir         pTableNode != NULL  &&  rNdIdx.GetNode().IsProtect() )
2882cdf0e10cSrcweir     {
2883cdf0e10cSrcweir         // we're in a table, and we're in a protected area, so we're
2884cdf0e10cSrcweir         // probably in a protected cell.
2885cdf0e10cSrcweir 
2886cdf0e10cSrcweir         // move forward into non-protected area.
2887cdf0e10cSrcweir         SwPaM aPam( rNdIdx.GetNode(), 0 );
2888cdf0e10cSrcweir         while( aPam.GetNode()->IsProtect() &&
2889cdf0e10cSrcweir                aPam.Move( fnMoveForward, fnGoCntnt ) )
2890cdf0e10cSrcweir             ; // nothing to do in the loop; the aPam.Move does the moving!
2891cdf0e10cSrcweir 
2892cdf0e10cSrcweir         // didn't work? then go backwards!
2893cdf0e10cSrcweir         if( aPam.GetNode()->IsProtect() )
2894cdf0e10cSrcweir         {
2895cdf0e10cSrcweir             SwPaM aTmpPaM( rNdIdx.GetNode(), 0 );
2896cdf0e10cSrcweir 			aPam = aTmpPaM;
2897cdf0e10cSrcweir             while( aPam.GetNode()->IsProtect() &&
2898cdf0e10cSrcweir                    aPam.Move( fnMoveBackward, fnGoCntnt ) )
2899cdf0e10cSrcweir                 ; // nothing to do in the loop; the aPam.Move does the moving!
2900cdf0e10cSrcweir         }
2901cdf0e10cSrcweir 
2902cdf0e10cSrcweir         // if we're successful, set the new position
2903cdf0e10cSrcweir         if( ! aPam.GetNode()->IsProtect() )
2904cdf0e10cSrcweir         {
2905cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *aPam.GetPoint();
2906cdf0e10cSrcweir         }
2907cdf0e10cSrcweir     }
2908cdf0e10cSrcweir 
2909cdf0e10cSrcweir 	// in einem geschuetzten Bereich
2910cdf0e10cSrcweir 	const SwSectionNode* pSectNd = rNdIdx.GetNode().FindSectionNode();
2911cdf0e10cSrcweir 	if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
2912cdf0e10cSrcweir 		( !IsReadOnlyAvailable() &&
2913cdf0e10cSrcweir 		   pSectNd->GetSection().IsProtectFlag() )) )
2914cdf0e10cSrcweir 	{
2915cdf0e10cSrcweir 		typedef SwCntntNode* (SwNodes:: *FNGoSection)( SwNodeIndex *, int, int ) const;
2916cdf0e10cSrcweir         FNGoSection funcGoSection = &SwNodes::GoNextSection;
2917cdf0e10cSrcweir 
2918cdf0e10cSrcweir 		bOk = sal_False;
2919cdf0e10cSrcweir 
2920cdf0e10cSrcweir 		for( int nLoopCnt = 0; !bOk && nLoopCnt < 2; ++nLoopCnt )
2921cdf0e10cSrcweir 		{
2922cdf0e10cSrcweir 			sal_Bool bWeiter;
2923cdf0e10cSrcweir 			do {
2924cdf0e10cSrcweir 				bWeiter = sal_False;
2925cdf0e10cSrcweir                 while( 0 != ( pCNd = (rNds.*funcGoSection)( &rNdIdx,
2926cdf0e10cSrcweir 											sal_True, !IsReadOnlyAvailable() )) )
2927cdf0e10cSrcweir 				{
2928cdf0e10cSrcweir 					// in eine Tabelle verschoben -> pruefe ob die
2929cdf0e10cSrcweir 					// vielleicht geschuetzt ist
2930cdf0e10cSrcweir 					if( pCNd->FindTableNode() )
2931cdf0e10cSrcweir 					{
2932cdf0e10cSrcweir 						SwCallLink aTmp( *this );
2933cdf0e10cSrcweir 						SwCrsrSaveState aSaveState( *pCurCrsr );
2934cdf0e10cSrcweir 						aTmp.nNdTyp = 0;		// im DTOR nichts machen!
2935cdf0e10cSrcweir 						if( !pCurCrsr->IsInProtectTable( sal_True, sal_True ) )
2936cdf0e10cSrcweir 						{
2937cdf0e10cSrcweir 							const SwSectionNode* pSNd = pCNd->FindSectionNode();
2938cdf0e10cSrcweir 							if( !pSNd || !pSNd->GetSection().IsHiddenFlag()
2939cdf0e10cSrcweir 								|| (!IsReadOnlyAvailable()  &&
2940cdf0e10cSrcweir 									pSNd->GetSection().IsProtectFlag() ))
2941cdf0e10cSrcweir 							{
2942cdf0e10cSrcweir 								bOk = sal_True;
2943cdf0e10cSrcweir 								break;		// eine nicht geschuetzte Zelle gef.
2944cdf0e10cSrcweir 							}
2945cdf0e10cSrcweir 							continue;		// dann weiter suchen
2946cdf0e10cSrcweir 						}
2947cdf0e10cSrcweir 					}
2948cdf0e10cSrcweir 					else
2949cdf0e10cSrcweir 					{
2950cdf0e10cSrcweir 						bOk = sal_True;
2951cdf0e10cSrcweir 						break;		// eine nicht geschuetzte Zelle gef.
2952cdf0e10cSrcweir 					}
2953cdf0e10cSrcweir 				}
2954cdf0e10cSrcweir 
2955cdf0e10cSrcweir 				if( bOk && rNdIdx.GetIndex() < rNds.GetEndOfExtras().GetIndex() )
2956cdf0e10cSrcweir 				{
2957cdf0e10cSrcweir 					// Teste mal auf Fly - kann auch noch geschuetzt sein!!
2958cdf0e10cSrcweir 					if( 0 == (pFrm = pCNd->getLayoutFrm( GetLayout(),0,0,sal_False)) ||
2959cdf0e10cSrcweir 						( !IsReadOnlyAvailable() && pFrm->IsProtected() ) ||
2960cdf0e10cSrcweir 						( bOnlyText && pCNd->IsNoTxtNode() ) )
2961cdf0e10cSrcweir 					{
2962cdf0e10cSrcweir 						// dann weiter suchen!
2963cdf0e10cSrcweir 						bOk = sal_False;
2964cdf0e10cSrcweir 						bWeiter = sal_True;
2965cdf0e10cSrcweir 					}
2966cdf0e10cSrcweir 				}
2967cdf0e10cSrcweir 			} while( bWeiter );
2968cdf0e10cSrcweir 
2969cdf0e10cSrcweir 			if( !bOk )
2970cdf0e10cSrcweir 			{
2971cdf0e10cSrcweir 				if( !nLoopCnt )
2972cdf0e10cSrcweir                     funcGoSection = &SwNodes::GoPrevSection;
2973cdf0e10cSrcweir 				rNdIdx = nNdIdx;
2974cdf0e10cSrcweir 			}
2975cdf0e10cSrcweir 		}
2976cdf0e10cSrcweir 	}
2977cdf0e10cSrcweir 	if( bOk )
2978cdf0e10cSrcweir 	{
2979cdf0e10cSrcweir 		pCNd = rNdIdx.GetNode().GetCntntNode();
2980cdf0e10cSrcweir //		sal_uInt16 nCntnt = Min( pCNd->Len(), pCurCrsr->GetPoint()->nContent.GetIndex() );
2981cdf0e10cSrcweir 		xub_StrLen nCntnt = rNdIdx.GetIndex() < nNdIdx ? pCNd->Len() : 0;
2982cdf0e10cSrcweir 		pCurCrsr->GetPoint()->nContent.Assign( pCNd, nCntnt );
2983cdf0e10cSrcweir 	}
2984cdf0e10cSrcweir 	else
2985cdf0e10cSrcweir 	{
2986cdf0e10cSrcweir 		pCNd = rNdIdx.GetNode().GetCntntNode();
2987cdf0e10cSrcweir 
2988cdf0e10cSrcweir 		// falls Cursor im versteckten Bereich ist, auf jedenfall schon mal
2989cdf0e10cSrcweir 		// verschieben!!
2990cdf0e10cSrcweir 		if( !pCNd || !pCNd->getLayoutFrm( GetLayout(),0,0,sal_False) )
2991cdf0e10cSrcweir 		{
2992cdf0e10cSrcweir 			SwCrsrMoveState aTmpState( MV_NONE );
2993cdf0e10cSrcweir 			aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
2994cdf0e10cSrcweir 			GetLayout()->GetCrsrOfst( pCurCrsr->GetPoint(), pCurCrsr->GetPtPos(),
2995cdf0e10cSrcweir 										&aTmpState );
2996cdf0e10cSrcweir 		}
2997cdf0e10cSrcweir 	}
2998cdf0e10cSrcweir 	return bOk;
2999cdf0e10cSrcweir }
3000cdf0e10cSrcweir 
3001cdf0e10cSrcweir 
IsCrsrReadonly() const3002cdf0e10cSrcweir sal_Bool SwCrsrShell::IsCrsrReadonly() const
3003cdf0e10cSrcweir {
3004cdf0e10cSrcweir     if ( GetViewOptions()->IsReadonly() ||
300569a74367SOliver-Rainer Wittmann          GetViewOptions()->IsFormView() ) // Formular view
300669a74367SOliver-Rainer Wittmann     {
300769a74367SOliver-Rainer Wittmann         SwFrm *pFrm = GetCurrFrm( sal_False );
3008cdf0e10cSrcweir         const SwFlyFrm* pFly;
3009cdf0e10cSrcweir         const SwSection* pSection;
3010cdf0e10cSrcweir 
3011cdf0e10cSrcweir         if( pFrm && pFrm->IsInFly() &&
301269a74367SOliver-Rainer Wittmann             (pFly = pFrm->FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
301369a74367SOliver-Rainer Wittmann             pFly->Lower() &&
301469a74367SOliver-Rainer Wittmann             !pFly->Lower()->IsNoTxtFrm() &&
301569a74367SOliver-Rainer Wittmann             !GetDrawView()->GetMarkedObjectList().GetMarkCount() )
301669a74367SOliver-Rainer Wittmann         {
301769a74367SOliver-Rainer Wittmann             return sal_False;
301869a74367SOliver-Rainer Wittmann         }
301969a74367SOliver-Rainer Wittmann         // edit in readonly sections
3020cdf0e10cSrcweir         else if ( pFrm && pFrm->IsInSct() &&
302169a74367SOliver-Rainer Wittmann             0 != ( pSection = pFrm->FindSctFrm()->GetSection() ) &&
302269a74367SOliver-Rainer Wittmann             pSection->IsEditInReadonlyFlag() )
302369a74367SOliver-Rainer Wittmann         {
302469a74367SOliver-Rainer Wittmann             return sal_False;
302569a74367SOliver-Rainer Wittmann         }
302669a74367SOliver-Rainer Wittmann         else if ( !IsMultiSelection() && CrsrInsideInputFld() )
3027cdf0e10cSrcweir         {
3028cdf0e10cSrcweir             return sal_False;
3029cdf0e10cSrcweir         }
3030cdf0e10cSrcweir 
303169a74367SOliver-Rainer Wittmann         return sal_True;
303269a74367SOliver-Rainer Wittmann     }
303369a74367SOliver-Rainer Wittmann     return sal_False;
3034cdf0e10cSrcweir }
3035cdf0e10cSrcweir 
3036cdf0e10cSrcweir 
3037cdf0e10cSrcweir // darf der Cursor in ReadOnlyBereiche?
SetReadOnlyAvailable(sal_Bool bFlag)3038cdf0e10cSrcweir void SwCrsrShell::SetReadOnlyAvailable( sal_Bool bFlag )
3039cdf0e10cSrcweir {
3040cdf0e10cSrcweir 	// im GlobalDoc darf NIE umgeschaltet werden
3041cdf0e10cSrcweir 	if( (!GetDoc()->GetDocShell() ||
3042cdf0e10cSrcweir 		 !GetDoc()->GetDocShell()->IsA( SwGlobalDocShell::StaticType() )) &&
3043cdf0e10cSrcweir 		bFlag != bSetCrsrInReadOnly )
3044cdf0e10cSrcweir 	{
3045cdf0e10cSrcweir 		// wenn das Flag ausgeschaltet wird, dann muessen erstmal alle
3046cdf0e10cSrcweir 		// Selektionen aufgehoben werden. Denn sonst wird sich darauf
3047cdf0e10cSrcweir 		// verlassen, das nichts geschuetztes selektiert ist!
3048cdf0e10cSrcweir 		if( !bFlag )
3049cdf0e10cSrcweir 		{
3050cdf0e10cSrcweir 			ClearMark();
3051cdf0e10cSrcweir 		}
3052cdf0e10cSrcweir 		bSetCrsrInReadOnly = bFlag;
3053cdf0e10cSrcweir 		UpdateCrsr();
3054cdf0e10cSrcweir 	}
3055cdf0e10cSrcweir }
3056cdf0e10cSrcweir 
HasReadonlySel() const3057cdf0e10cSrcweir sal_Bool SwCrsrShell::HasReadonlySel() const
3058cdf0e10cSrcweir {
3059*23d8f725SOliver-Rainer Wittmann     sal_Bool bRet = sal_False;
3060*23d8f725SOliver-Rainer Wittmann     if ( IsReadOnlyAvailable() || GetViewOptions()->IsFormView() )
3061*23d8f725SOliver-Rainer Wittmann     {
3062*23d8f725SOliver-Rainer Wittmann         if ( pTblCrsr != NULL )
3063*23d8f725SOliver-Rainer Wittmann         {
3064*23d8f725SOliver-Rainer Wittmann             bRet = pTblCrsr->HasReadOnlyBoxSel()
3065*23d8f725SOliver-Rainer Wittmann                    || pTblCrsr->HasReadonlySel( GetViewOptions()->IsFormView() );
3066*23d8f725SOliver-Rainer Wittmann         }
3067cdf0e10cSrcweir         else
3068*23d8f725SOliver-Rainer Wittmann         {
3069*23d8f725SOliver-Rainer Wittmann             const SwPaM* pCrsr = pCurCrsr;
3070cdf0e10cSrcweir 
3071*23d8f725SOliver-Rainer Wittmann             do
3072*23d8f725SOliver-Rainer Wittmann             {
3073*23d8f725SOliver-Rainer Wittmann                 if ( pCrsr->HasReadonlySel( GetViewOptions()->IsFormView() ) )
3074*23d8f725SOliver-Rainer Wittmann                 {
3075*23d8f725SOliver-Rainer Wittmann                     bRet = sal_True;
3076*23d8f725SOliver-Rainer Wittmann                 }
3077*23d8f725SOliver-Rainer Wittmann 
3078*23d8f725SOliver-Rainer Wittmann                 pCrsr = (SwPaM*)pCrsr->GetNext();
3079*23d8f725SOliver-Rainer Wittmann             } while ( !bRet && pCrsr != pCurCrsr );
3080*23d8f725SOliver-Rainer Wittmann         }
3081*23d8f725SOliver-Rainer Wittmann     }
3082*23d8f725SOliver-Rainer Wittmann     return bRet;
3083cdf0e10cSrcweir }
3084cdf0e10cSrcweir 
IsSelFullPara() const3085cdf0e10cSrcweir sal_Bool SwCrsrShell::IsSelFullPara() const
3086cdf0e10cSrcweir {
3087cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
3088cdf0e10cSrcweir 
3089cdf0e10cSrcweir 	if( pCurCrsr->GetPoint()->nNode.GetIndex() ==
3090cdf0e10cSrcweir 		pCurCrsr->GetMark()->nNode.GetIndex() && pCurCrsr == pCurCrsr->GetNext() )
3091cdf0e10cSrcweir 	{
3092cdf0e10cSrcweir 		xub_StrLen nStt = pCurCrsr->GetPoint()->nContent.GetIndex(),
3093cdf0e10cSrcweir 				   nEnd = pCurCrsr->GetMark()->nContent.GetIndex();
3094cdf0e10cSrcweir 		if( nStt > nEnd )
3095cdf0e10cSrcweir 		{
3096cdf0e10cSrcweir 			xub_StrLen nTmp = nStt;
3097cdf0e10cSrcweir 			nStt = nEnd;
3098cdf0e10cSrcweir 			nEnd = nTmp;
3099cdf0e10cSrcweir 		}
3100cdf0e10cSrcweir 		const SwCntntNode* pCNd = pCurCrsr->GetCntntNode();
3101cdf0e10cSrcweir 		bRet = pCNd && !nStt && nEnd == pCNd->Len();
3102cdf0e10cSrcweir 	}
3103cdf0e10cSrcweir 	return bRet;
3104cdf0e10cSrcweir }
3105cdf0e10cSrcweir 
GetTextDirection(const Point * pPt) const3106cdf0e10cSrcweir short SwCrsrShell::GetTextDirection( const Point* pPt ) const
3107cdf0e10cSrcweir {
3108cdf0e10cSrcweir 	SwPosition aPos( *pCurCrsr->GetPoint() );
3109cdf0e10cSrcweir 	Point aPt( pPt ? *pPt : pCurCrsr->GetPtPos() );
3110cdf0e10cSrcweir 	if( pPt )
3111cdf0e10cSrcweir 	{
3112cdf0e10cSrcweir 		SwCrsrMoveState aTmpState( MV_NONE );
3113cdf0e10cSrcweir 		aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
3114cdf0e10cSrcweir 
3115cdf0e10cSrcweir 		GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState );
3116cdf0e10cSrcweir 	}
3117cdf0e10cSrcweir 
3118cdf0e10cSrcweir     return pDoc->GetTextDirection( aPos, &aPt );
3119cdf0e10cSrcweir }
3120cdf0e10cSrcweir 
IsInVerticalText(const Point * pPt) const3121cdf0e10cSrcweir sal_Bool SwCrsrShell::IsInVerticalText( const Point* pPt ) const
3122cdf0e10cSrcweir {
3123cdf0e10cSrcweir     const short nDir = GetTextDirection( pPt );
3124cdf0e10cSrcweir     return FRMDIR_VERT_TOP_RIGHT == nDir || FRMDIR_VERT_TOP_LEFT == nDir;
3125cdf0e10cSrcweir }
3126cdf0e10cSrcweir 
IsInRightToLeftText(const Point * pPt) const3127cdf0e10cSrcweir sal_Bool SwCrsrShell::IsInRightToLeftText( const Point* pPt ) const
3128cdf0e10cSrcweir {
3129cdf0e10cSrcweir     const short nDir = GetTextDirection( pPt );
3130cdf0e10cSrcweir     // GetTextDirection uses FRMDIR_VERT_TOP_LEFT to indicate RTL in
3131cdf0e10cSrcweir     // vertical environment
3132cdf0e10cSrcweir     return FRMDIR_VERT_TOP_LEFT == nDir || FRMDIR_HORI_RIGHT_TOP == nDir;
3133cdf0e10cSrcweir }
3134cdf0e10cSrcweir 
3135cdf0e10cSrcweir //
3136cdf0e10cSrcweir // If the current cursor position is inside a hidden range, the hidden range
3137cdf0e10cSrcweir // is selected:
3138cdf0e10cSrcweir //
SelectHiddenRange()3139cdf0e10cSrcweir bool SwCrsrShell::SelectHiddenRange()
3140cdf0e10cSrcweir {
3141cdf0e10cSrcweir     bool bRet = false;
3142cdf0e10cSrcweir     if ( !GetViewOptions()->IsShowHiddenChar() && !pCurCrsr->HasMark() )
3143cdf0e10cSrcweir     {
3144cdf0e10cSrcweir         SwPosition& rPt = *(SwPosition*)pCurCrsr->GetPoint();
3145cdf0e10cSrcweir         const SwTxtNode* pNode = rPt.nNode.GetNode().GetTxtNode();
3146cdf0e10cSrcweir         if ( pNode )
3147cdf0e10cSrcweir         {
3148cdf0e10cSrcweir             const xub_StrLen nPos = rPt.nContent.GetIndex();
3149cdf0e10cSrcweir 
3150cdf0e10cSrcweir             // check if nPos is in hidden range
3151cdf0e10cSrcweir             xub_StrLen nHiddenStart;
3152cdf0e10cSrcweir             xub_StrLen nHiddenEnd;
3153cdf0e10cSrcweir             SwScriptInfo::GetBoundsOfHiddenRange( *pNode, nPos, nHiddenStart, nHiddenEnd );
3154cdf0e10cSrcweir             if ( STRING_LEN != nHiddenStart )
3155cdf0e10cSrcweir             {
3156cdf0e10cSrcweir                 // make selection:
3157cdf0e10cSrcweir                 pCurCrsr->SetMark();
3158cdf0e10cSrcweir                 pCurCrsr->GetMark()->nContent = nHiddenEnd;
3159cdf0e10cSrcweir                 bRet = true;
3160cdf0e10cSrcweir             }
3161cdf0e10cSrcweir         }
3162cdf0e10cSrcweir     }
3163cdf0e10cSrcweir 
3164cdf0e10cSrcweir     return bRet;
3165cdf0e10cSrcweir }
3166cdf0e10cSrcweir 
3167cdf0e10cSrcweir /*  */
3168cdf0e10cSrcweir 
3169cdf0e10cSrcweir 	// die Suchfunktionen
Find(const SearchOptions & rSearchOpt,sal_Bool bSearchInNotes,SwDocPositions eStart,SwDocPositions eEnde,sal_Bool & bCancel,FindRanges eRng,int bReplace)3170cdf0e10cSrcweir sal_uLong SwCrsrShell::Find( const SearchOptions& rSearchOpt, sal_Bool bSearchInNotes,
3171cdf0e10cSrcweir 							SwDocPositions eStart, SwDocPositions eEnde,
3172cdf0e10cSrcweir                             sal_Bool& bCancel,
3173cdf0e10cSrcweir 							FindRanges eRng, int bReplace )
3174cdf0e10cSrcweir {
3175cdf0e10cSrcweir 	if( pTblCrsr )
3176cdf0e10cSrcweir 		GetCrsr();
3177cdf0e10cSrcweir 	delete pTblCrsr, pTblCrsr = 0;
3178cdf0e10cSrcweir     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
3179cdf0e10cSrcweir     sal_uLong nRet = pCurCrsr->Find( rSearchOpt, bSearchInNotes, eStart, eEnde, bCancel, eRng, bReplace );
3180cdf0e10cSrcweir     if( nRet || bCancel )
3181cdf0e10cSrcweir         UpdateCrsr();
3182cdf0e10cSrcweir     return nRet;
3183cdf0e10cSrcweir }
3184cdf0e10cSrcweir 
Find(const SwTxtFmtColl & rFmtColl,SwDocPositions eStart,SwDocPositions eEnde,sal_Bool & bCancel,FindRanges eRng,const SwTxtFmtColl * pReplFmt)3185cdf0e10cSrcweir sal_uLong SwCrsrShell::Find( const SwTxtFmtColl& rFmtColl,
3186cdf0e10cSrcweir 							SwDocPositions eStart, SwDocPositions eEnde,
3187cdf0e10cSrcweir 			                sal_Bool& bCancel,
3188cdf0e10cSrcweir 							FindRanges eRng, const SwTxtFmtColl* pReplFmt )
3189cdf0e10cSrcweir {
3190cdf0e10cSrcweir 	if( pTblCrsr )
3191cdf0e10cSrcweir 		GetCrsr();
3192cdf0e10cSrcweir 	delete pTblCrsr, pTblCrsr = 0;
3193cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
3194cdf0e10cSrcweir 	sal_uLong nRet = pCurCrsr->Find( rFmtColl, eStart, eEnde, bCancel, eRng, pReplFmt );
3195cdf0e10cSrcweir 	if( nRet )
3196cdf0e10cSrcweir 		UpdateCrsr();
3197cdf0e10cSrcweir 	return nRet;
3198cdf0e10cSrcweir }
3199cdf0e10cSrcweir 
Find(const SfxItemSet & rSet,sal_Bool bNoCollections,SwDocPositions eStart,SwDocPositions eEnde,sal_Bool & bCancel,FindRanges eRng,const SearchOptions * pSearchOpt,const SfxItemSet * rReplSet)3200cdf0e10cSrcweir sal_uLong SwCrsrShell::Find( const SfxItemSet& rSet, sal_Bool bNoCollections,
3201cdf0e10cSrcweir 							SwDocPositions eStart, SwDocPositions eEnde,
3202cdf0e10cSrcweir 							sal_Bool& bCancel,
3203cdf0e10cSrcweir 							FindRanges eRng, const SearchOptions* pSearchOpt,
3204cdf0e10cSrcweir 							const SfxItemSet* rReplSet )
3205cdf0e10cSrcweir {
3206cdf0e10cSrcweir 	if( pTblCrsr )
3207cdf0e10cSrcweir 		GetCrsr();
3208cdf0e10cSrcweir 	delete pTblCrsr, pTblCrsr = 0;
3209cdf0e10cSrcweir 	SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
3210cdf0e10cSrcweir 	sal_uLong nRet = pCurCrsr->Find( rSet, bNoCollections, eStart, eEnde, bCancel,
3211cdf0e10cSrcweir 								eRng, pSearchOpt, rReplSet );
3212cdf0e10cSrcweir 	if( nRet )
3213cdf0e10cSrcweir 		UpdateCrsr();
3214cdf0e10cSrcweir 	return nRet;
3215cdf0e10cSrcweir }
3216cdf0e10cSrcweir 
SetSelection(const SwPaM & rCrsr)3217cdf0e10cSrcweir void SwCrsrShell::SetSelection( const SwPaM& rCrsr )
3218cdf0e10cSrcweir {
3219cdf0e10cSrcweir 	StartAction();
3220cdf0e10cSrcweir 	SwPaM* pCrsr = GetCrsr();
3221cdf0e10cSrcweir 	*pCrsr->GetPoint() = *rCrsr.GetPoint();
3222cdf0e10cSrcweir 	if(rCrsr.HasMark())
3223cdf0e10cSrcweir 	{
3224cdf0e10cSrcweir 		pCrsr->SetMark();
3225cdf0e10cSrcweir 		*pCrsr->GetMark() = *rCrsr.GetMark();
3226cdf0e10cSrcweir 	}
3227cdf0e10cSrcweir 	if((SwPaM*)rCrsr.GetNext() != &rCrsr)
3228cdf0e10cSrcweir 	{
3229cdf0e10cSrcweir 		const SwPaM *_pStartCrsr = (SwPaM*)rCrsr.GetNext();
3230cdf0e10cSrcweir 		do
3231cdf0e10cSrcweir 		{
3232cdf0e10cSrcweir             SwPaM* pCurrentCrsr = CreateCrsr();
3233cdf0e10cSrcweir             *pCurrentCrsr->GetPoint() = *_pStartCrsr->GetPoint();
3234cdf0e10cSrcweir 			if(_pStartCrsr->HasMark())
3235cdf0e10cSrcweir 			{
3236cdf0e10cSrcweir                 pCurrentCrsr->SetMark();
3237cdf0e10cSrcweir                 *pCurrentCrsr->GetMark() = *_pStartCrsr->GetMark();
3238cdf0e10cSrcweir 			}
3239cdf0e10cSrcweir 		} while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != &rCrsr );
3240cdf0e10cSrcweir 	}
3241cdf0e10cSrcweir 	EndAction();
3242cdf0e10cSrcweir }
3243cdf0e10cSrcweir 
lcl_RemoveMark(SwPaM * pPam)3244cdf0e10cSrcweir void lcl_RemoveMark( SwPaM* pPam )
3245cdf0e10cSrcweir {
3246cdf0e10cSrcweir     ASSERT( pPam->HasMark(), "Don't remove pPoint!" )
3247cdf0e10cSrcweir     pPam->GetMark()->nContent.Assign( 0, 0 );
3248cdf0e10cSrcweir     pPam->GetMark()->nNode = 0;
3249cdf0e10cSrcweir     pPam->DeleteMark();
3250cdf0e10cSrcweir }
3251cdf0e10cSrcweir 
lcl_NodeContext(const SwNode & rNode)3252cdf0e10cSrcweir const SwStartNode* lcl_NodeContext( const SwNode& rNode )
3253cdf0e10cSrcweir {
3254cdf0e10cSrcweir     const SwStartNode *pRet = rNode.StartOfSectionNode();
3255cdf0e10cSrcweir     while( pRet->IsSectionNode() || pRet->IsTableNode() ||
3256cdf0e10cSrcweir         pRet->GetStartNodeType() == SwTableBoxStartNode )
3257cdf0e10cSrcweir     {
3258cdf0e10cSrcweir         pRet = pRet->StartOfSectionNode();
3259cdf0e10cSrcweir     }
3260cdf0e10cSrcweir     return pRet;
3261cdf0e10cSrcweir }
3262cdf0e10cSrcweir 
3263cdf0e10cSrcweir /**
3264cdf0e10cSrcweir    Checks if a position is valid. To be valid the position's node must
3265cdf0e10cSrcweir    be a content node and the content must not be unregistered.
3266cdf0e10cSrcweir 
3267cdf0e10cSrcweir    @param aPos the position to check.
3268cdf0e10cSrcweir */
lcl_PosOk(const SwPosition & aPos)3269cdf0e10cSrcweir bool lcl_PosOk(const SwPosition & aPos)
3270cdf0e10cSrcweir {
3271cdf0e10cSrcweir     return NULL != aPos.nNode.GetNode().GetCntntNode() &&
3272cdf0e10cSrcweir            SwIndexReg::pEmptyIndexArray != aPos.nContent.GetIdxReg();
3273cdf0e10cSrcweir }
3274cdf0e10cSrcweir 
3275cdf0e10cSrcweir /**
3276cdf0e10cSrcweir    Checks if a PaM is valid. For a PaM to be valid its point must be
3277cdf0e10cSrcweir    valid. Additionaly if the PaM has a mark this has to be valid, too.
3278cdf0e10cSrcweir 
3279cdf0e10cSrcweir    @param aPam the PaM to check
3280cdf0e10cSrcweir */
lcl_CrsrOk(SwPaM & aPam)3281cdf0e10cSrcweir static bool lcl_CrsrOk(SwPaM & aPam)
3282cdf0e10cSrcweir {
3283cdf0e10cSrcweir     return lcl_PosOk(*aPam.GetPoint()) && (! aPam.HasMark()
3284cdf0e10cSrcweir         || lcl_PosOk(*aPam.GetMark()));
3285cdf0e10cSrcweir }
3286cdf0e10cSrcweir 
ClearUpCrsrs()3287cdf0e10cSrcweir void SwCrsrShell::ClearUpCrsrs()
3288cdf0e10cSrcweir {
3289cdf0e10cSrcweir     // start of the ring
3290cdf0e10cSrcweir     SwPaM * pStartCrsr = GetCrsr();
3291cdf0e10cSrcweir     // start loop with second entry of the ring
3292cdf0e10cSrcweir     SwPaM * pCrsr = (SwPaM *) pStartCrsr->GetNext();
3293cdf0e10cSrcweir     SwPaM * pTmpCrsr;
3294cdf0e10cSrcweir     bool bChanged = false;
3295cdf0e10cSrcweir 
3296cdf0e10cSrcweir     /*
3297cdf0e10cSrcweir        For all entries in the ring except the start entry delete the
3298cdf0e10cSrcweir        entry if it is invalid.
3299cdf0e10cSrcweir     */
3300cdf0e10cSrcweir     while (pCrsr != pStartCrsr)
3301cdf0e10cSrcweir     {
3302cdf0e10cSrcweir         pTmpCrsr = (SwPaM *) pCrsr->GetNext();
3303cdf0e10cSrcweir 
3304cdf0e10cSrcweir         if ( ! lcl_CrsrOk(*pCrsr))
3305cdf0e10cSrcweir         {
3306cdf0e10cSrcweir             delete pCrsr;
3307cdf0e10cSrcweir 
3308cdf0e10cSrcweir             bChanged = true;
3309cdf0e10cSrcweir         }
3310cdf0e10cSrcweir 
3311cdf0e10cSrcweir         pCrsr = pTmpCrsr;
3312cdf0e10cSrcweir     }
3313cdf0e10cSrcweir 
3314cdf0e10cSrcweir     if( pStartCrsr->HasMark() && !lcl_PosOk( *pStartCrsr->GetMark() ) )
3315cdf0e10cSrcweir     {
3316cdf0e10cSrcweir         lcl_RemoveMark( pStartCrsr );
3317cdf0e10cSrcweir         bChanged = true;
3318cdf0e10cSrcweir     }
3319cdf0e10cSrcweir     if( !lcl_PosOk( *pStartCrsr->GetPoint() ) )
3320cdf0e10cSrcweir     {
3321cdf0e10cSrcweir         SwNodes & aNodes = GetDoc()->GetNodes();
3322cdf0e10cSrcweir         const SwNode* pStart = lcl_NodeContext( pStartCrsr->GetPoint()->nNode.GetNode() );
3323cdf0e10cSrcweir         SwNodeIndex aIdx( pStartCrsr->GetPoint()->nNode );
3324cdf0e10cSrcweir         SwNode * pNode = aNodes.GoPrevious(&aIdx);
3325cdf0e10cSrcweir         if( pNode == NULL || lcl_NodeContext( *pNode ) != pStart )
3326cdf0e10cSrcweir             aNodes.GoNext( &aIdx );
3327cdf0e10cSrcweir         if( pNode == NULL || lcl_NodeContext( *pNode ) != pStart )
3328cdf0e10cSrcweir         {
3329cdf0e10cSrcweir             /*
3330cdf0e10cSrcweir               If the start entry of the ring is invalid replace it with a
3331cdf0e10cSrcweir               cursor pointing to the beginning of the first content node in
3332cdf0e10cSrcweir               the document.
3333cdf0e10cSrcweir             */
3334cdf0e10cSrcweir             aIdx = (*(aNodes.GetEndOfContent().StartOfSectionNode()));
3335cdf0e10cSrcweir             pNode = aNodes.GoNext( &aIdx );
3336cdf0e10cSrcweir         }
3337cdf0e10cSrcweir         bool bFound = (pNode != NULL);
3338cdf0e10cSrcweir 
3339cdf0e10cSrcweir         ASSERT(bFound, "no content node found");
3340cdf0e10cSrcweir 
3341cdf0e10cSrcweir         if (bFound)
3342cdf0e10cSrcweir         {
3343cdf0e10cSrcweir             SwPaM aTmpPam(*pNode);
3344cdf0e10cSrcweir             *pStartCrsr = aTmpPam;
3345cdf0e10cSrcweir         }
3346cdf0e10cSrcweir 
3347cdf0e10cSrcweir         bChanged = true;
3348cdf0e10cSrcweir     }
3349cdf0e10cSrcweir 
3350cdf0e10cSrcweir     /*
3351cdf0e10cSrcweir       If at least one of the cursors in the ring have been deleted or
3352cdf0e10cSrcweir       replaced, remove the table cursor.
3353cdf0e10cSrcweir     */
3354cdf0e10cSrcweir     if (pTblCrsr != NULL && bChanged)
3355cdf0e10cSrcweir         TblCrsrToCursor();
3356cdf0e10cSrcweir }
3357cdf0e10cSrcweir 
3358cdf0e10cSrcweir // #111827#
GetCrsrDescr() const3359cdf0e10cSrcweir String SwCrsrShell::GetCrsrDescr() const
3360cdf0e10cSrcweir {
3361cdf0e10cSrcweir     String aResult;
3362cdf0e10cSrcweir 
3363cdf0e10cSrcweir     if (IsMultiSelection())
3364cdf0e10cSrcweir         aResult += String(SW_RES(STR_MULTISEL));
3365cdf0e10cSrcweir     else
3366cdf0e10cSrcweir         aResult = GetDoc()->GetPaMDescr(*GetCrsr());
3367cdf0e10cSrcweir 
3368cdf0e10cSrcweir     return aResult;
3369cdf0e10cSrcweir }
3370cdf0e10cSrcweir 
3371cdf0e10cSrcweir // SMARTTAGS
3372cdf0e10cSrcweir 
lcl_FillRecognizerData(uno::Sequence<rtl::OUString> & rSmartTagTypes,uno::Sequence<uno::Reference<container::XStringKeyMap>> & rStringKeyMaps,const SwWrongList & rSmartTagList,xub_StrLen nCurrent)3373cdf0e10cSrcweir void lcl_FillRecognizerData( uno::Sequence< rtl::OUString >& rSmartTagTypes,
3374cdf0e10cSrcweir                              uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3375cdf0e10cSrcweir                              const SwWrongList& rSmartTagList, xub_StrLen nCurrent )
3376cdf0e10cSrcweir {
3377cdf0e10cSrcweir     // Insert smart tag information
3378cdf0e10cSrcweir     std::vector< rtl::OUString > aSmartTagTypes;
3379cdf0e10cSrcweir     std::vector< uno::Reference< container::XStringKeyMap > > aStringKeyMaps;
3380cdf0e10cSrcweir 
3381cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rSmartTagList.Count(); ++i )
3382cdf0e10cSrcweir     {
3383cdf0e10cSrcweir         const xub_StrLen nSTPos = rSmartTagList.Pos( i );
3384cdf0e10cSrcweir         const xub_StrLen nSTLen = rSmartTagList.Len( i );
3385cdf0e10cSrcweir 
3386cdf0e10cSrcweir         if ( nSTPos <= nCurrent && nCurrent < nSTPos + nSTLen )
3387cdf0e10cSrcweir         {
3388cdf0e10cSrcweir             const SwWrongArea* pArea = rSmartTagList.GetElement( i );
3389cdf0e10cSrcweir             if ( pArea )
3390cdf0e10cSrcweir             {
3391cdf0e10cSrcweir                 aSmartTagTypes.push_back( pArea->maType );
3392cdf0e10cSrcweir                 aStringKeyMaps.push_back( pArea->mxPropertyBag );
3393cdf0e10cSrcweir             }
3394cdf0e10cSrcweir         }
3395cdf0e10cSrcweir     }
3396cdf0e10cSrcweir 
3397cdf0e10cSrcweir     if ( aSmartTagTypes.size() )
3398cdf0e10cSrcweir     {
3399cdf0e10cSrcweir         rSmartTagTypes.realloc( aSmartTagTypes.size() );
3400cdf0e10cSrcweir         rStringKeyMaps.realloc( aSmartTagTypes.size() );
3401cdf0e10cSrcweir 
3402cdf0e10cSrcweir         std::vector< rtl::OUString >::const_iterator aTypesIter = aSmartTagTypes.begin();
3403cdf0e10cSrcweir         sal_uInt16 i = 0;
3404cdf0e10cSrcweir         for ( aTypesIter = aSmartTagTypes.begin(); aTypesIter != aSmartTagTypes.end(); ++aTypesIter )
3405cdf0e10cSrcweir             rSmartTagTypes[i++] = *aTypesIter;
3406cdf0e10cSrcweir 
3407cdf0e10cSrcweir         std::vector< uno::Reference< container::XStringKeyMap > >::const_iterator aMapsIter = aStringKeyMaps.begin();
3408cdf0e10cSrcweir         i = 0;
3409cdf0e10cSrcweir         for ( aMapsIter = aStringKeyMaps.begin(); aMapsIter != aStringKeyMaps.end(); ++aMapsIter )
3410cdf0e10cSrcweir             rStringKeyMaps[i++] = *aMapsIter;
3411cdf0e10cSrcweir     }
3412cdf0e10cSrcweir }
3413cdf0e10cSrcweir 
lcl_FillTextRange(uno::Reference<text::XTextRange> & rRange,SwTxtNode & rNode,xub_StrLen nBegin,xub_StrLen nLen)3414cdf0e10cSrcweir void lcl_FillTextRange( uno::Reference<text::XTextRange>& rRange,
3415cdf0e10cSrcweir                    SwTxtNode& rNode, xub_StrLen nBegin, xub_StrLen nLen )
3416cdf0e10cSrcweir {
3417cdf0e10cSrcweir     // create SwPosition for nStartIndex
3418cdf0e10cSrcweir     SwIndex aIndex( &rNode, nBegin );
3419cdf0e10cSrcweir     SwPosition aStartPos( rNode, aIndex );
3420cdf0e10cSrcweir 
3421cdf0e10cSrcweir     // create SwPosition for nEndIndex
3422cdf0e10cSrcweir     SwPosition aEndPos( aStartPos );
3423cdf0e10cSrcweir     aEndPos.nContent = nBegin + nLen;
3424cdf0e10cSrcweir 
3425cdf0e10cSrcweir     const uno::Reference<text::XTextRange> xRange =
3426cdf0e10cSrcweir         SwXTextRange::CreateXTextRange(*rNode.GetDoc(), aStartPos, &aEndPos);
3427cdf0e10cSrcweir 
3428cdf0e10cSrcweir     rRange = xRange;
3429cdf0e10cSrcweir }
3430cdf0e10cSrcweir 
GetSmartTagTerm(uno::Sequence<rtl::OUString> & rSmartTagTypes,uno::Sequence<uno::Reference<container::XStringKeyMap>> & rStringKeyMaps,uno::Reference<text::XTextRange> & rRange) const3431cdf0e10cSrcweir void SwCrsrShell::GetSmartTagTerm( uno::Sequence< rtl::OUString >& rSmartTagTypes,
3432cdf0e10cSrcweir                                    uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3433cdf0e10cSrcweir                                    uno::Reference< text::XTextRange>& rRange ) const
3434cdf0e10cSrcweir {
3435cdf0e10cSrcweir     if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
3436cdf0e10cSrcweir         return;
3437cdf0e10cSrcweir 
3438cdf0e10cSrcweir     SwPaM* pCrsr = GetCrsr();
3439cdf0e10cSrcweir     SwPosition aPos( *pCrsr->GetPoint() );
3440cdf0e10cSrcweir     SwTxtNode *pNode = aPos.nNode.GetNode().GetTxtNode();
3441cdf0e10cSrcweir     if ( pNode && !pNode->IsInProtectSect() )
3442cdf0e10cSrcweir     {
3443cdf0e10cSrcweir         const SwWrongList *pSmartTagList = pNode->GetSmartTags();
3444cdf0e10cSrcweir         if ( pSmartTagList )
3445cdf0e10cSrcweir         {
3446cdf0e10cSrcweir             xub_StrLen nCurrent = aPos.nContent.GetIndex();
3447cdf0e10cSrcweir             xub_StrLen nBegin = nCurrent;
3448cdf0e10cSrcweir             xub_StrLen nLen = 1;
3449cdf0e10cSrcweir 
3450cdf0e10cSrcweir             if( pSmartTagList->InWrongWord( nBegin, nLen ) && !pNode->IsSymbol(nBegin) )
3451cdf0e10cSrcweir             {
3452cdf0e10cSrcweir                 const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
3453cdf0e10cSrcweir                 const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
3454cdf0e10cSrcweir                 if ( pSubList )
3455cdf0e10cSrcweir                 {
3456cdf0e10cSrcweir                     pSmartTagList = pSubList;
3457cdf0e10cSrcweir                     nCurrent = 0;
3458cdf0e10cSrcweir                 }
3459cdf0e10cSrcweir 
3460cdf0e10cSrcweir                 lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
3461cdf0e10cSrcweir                 lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
3462cdf0e10cSrcweir             }
3463cdf0e10cSrcweir         }
3464cdf0e10cSrcweir     }
3465cdf0e10cSrcweir }
3466cdf0e10cSrcweir 
3467cdf0e10cSrcweir // see also SwEditShell::GetCorrection( const Point* pPt, SwRect& rSelectRect )
GetSmartTagTerm(const Point & rPt,SwRect & rSelectRect,uno::Sequence<rtl::OUString> & rSmartTagTypes,uno::Sequence<uno::Reference<container::XStringKeyMap>> & rStringKeyMaps,uno::Reference<text::XTextRange> & rRange)3468cdf0e10cSrcweir void SwCrsrShell::GetSmartTagTerm( const Point& rPt, SwRect& rSelectRect,
3469cdf0e10cSrcweir                                    uno::Sequence< rtl::OUString >& rSmartTagTypes,
3470cdf0e10cSrcweir                                    uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3471cdf0e10cSrcweir                                    uno::Reference<text::XTextRange>& rRange )
3472cdf0e10cSrcweir {
3473cdf0e10cSrcweir     if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
3474cdf0e10cSrcweir         return;
3475cdf0e10cSrcweir 
3476cdf0e10cSrcweir     SwPaM* pCrsr = GetCrsr();
3477cdf0e10cSrcweir     SwPosition aPos( *pCrsr->GetPoint() );
3478cdf0e10cSrcweir     Point aPt( rPt );
3479cdf0e10cSrcweir     SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
3480cdf0e10cSrcweir     SwSpecialPos aSpecialPos;
3481cdf0e10cSrcweir     eTmpState.pSpecialPos = &aSpecialPos;
3482cdf0e10cSrcweir     SwTxtNode *pNode;
3483cdf0e10cSrcweir     const SwWrongList *pSmartTagList;
3484cdf0e10cSrcweir 
3485cdf0e10cSrcweir     if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
3486cdf0e10cSrcweir         0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
3487cdf0e10cSrcweir         0 != (pSmartTagList = pNode->GetSmartTags()) &&
3488cdf0e10cSrcweir         !pNode->IsInProtectSect() )
3489cdf0e10cSrcweir     {
3490cdf0e10cSrcweir         xub_StrLen nCurrent = aPos.nContent.GetIndex();
3491cdf0e10cSrcweir         xub_StrLen nBegin = nCurrent;
3492cdf0e10cSrcweir         xub_StrLen nLen = 1;
3493cdf0e10cSrcweir 
3494cdf0e10cSrcweir         if( pSmartTagList->InWrongWord( nBegin, nLen ) && !pNode->IsSymbol(nBegin) )
3495cdf0e10cSrcweir         {
3496cdf0e10cSrcweir             const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
3497cdf0e10cSrcweir             const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
3498cdf0e10cSrcweir             if ( pSubList )
3499cdf0e10cSrcweir             {
3500cdf0e10cSrcweir                 pSmartTagList = pSubList;
3501cdf0e10cSrcweir                 nCurrent = eTmpState.pSpecialPos->nCharOfst;
3502cdf0e10cSrcweir             }
3503cdf0e10cSrcweir 
3504cdf0e10cSrcweir             lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
3505cdf0e10cSrcweir             lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
3506cdf0e10cSrcweir 
3507cdf0e10cSrcweir             // get smarttag word
3508cdf0e10cSrcweir             String aText( pNode->GetTxt().Copy( nBegin, nLen ) );
3509cdf0e10cSrcweir 
3510cdf0e10cSrcweir             //save the start and end positons of the line and the starting point
3511cdf0e10cSrcweir             Push();
3512cdf0e10cSrcweir             LeftMargin();
3513cdf0e10cSrcweir             xub_StrLen nLineStart = GetCrsr()->GetPoint()->nContent.GetIndex();
3514cdf0e10cSrcweir             RightMargin();
3515cdf0e10cSrcweir             xub_StrLen nLineEnd = GetCrsr()->GetPoint()->nContent.GetIndex();
3516cdf0e10cSrcweir             Pop(sal_False);
3517cdf0e10cSrcweir 
3518cdf0e10cSrcweir             // make sure the selection build later from the
3519cdf0e10cSrcweir             // data below does not include footnotes and other
3520cdf0e10cSrcweir             // "in word" character to the left and right in order
3521cdf0e10cSrcweir             // to preserve those. Therefore count those "in words"
3522cdf0e10cSrcweir             // in order to modify the selection accordingly.
3523cdf0e10cSrcweir             const sal_Unicode* pChar = aText.GetBuffer();
3524cdf0e10cSrcweir             xub_StrLen nLeft = 0;
3525cdf0e10cSrcweir             while (pChar && *pChar++ == CH_TXTATR_INWORD)
3526cdf0e10cSrcweir                 ++nLeft;
3527cdf0e10cSrcweir             pChar = aText.Len() ? aText.GetBuffer() + aText.Len() - 1 : 0;
3528cdf0e10cSrcweir             xub_StrLen nRight = 0;
3529cdf0e10cSrcweir             while (pChar && *pChar-- == CH_TXTATR_INWORD)
3530cdf0e10cSrcweir                 ++nRight;
3531cdf0e10cSrcweir 
3532cdf0e10cSrcweir             aPos.nContent = nBegin + nLeft;
3533cdf0e10cSrcweir             pCrsr = GetCrsr();
3534cdf0e10cSrcweir             *pCrsr->GetPoint() = aPos;
3535cdf0e10cSrcweir             pCrsr->SetMark();
3536cdf0e10cSrcweir             ExtendSelection( sal_True, nLen - nLeft - nRight );
3537cdf0e10cSrcweir             //no determine the rectangle in the current line
3538cdf0e10cSrcweir             xub_StrLen nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
3539cdf0e10cSrcweir             //take one less than the line end - otherwise the next line would be calculated
3540cdf0e10cSrcweir             xub_StrLen nWordEnd = (nBegin + nLen - nLeft - nRight) > nLineEnd ? nLineEnd - 1: (nBegin + nLen - nLeft - nRight);
3541cdf0e10cSrcweir             Push();
3542cdf0e10cSrcweir             pCrsr->DeleteMark();
3543cdf0e10cSrcweir             SwIndex& rContent = GetCrsr()->GetPoint()->nContent;
3544cdf0e10cSrcweir             rContent = nWordStart;
3545cdf0e10cSrcweir             SwRect aStartRect;
3546cdf0e10cSrcweir             SwCrsrMoveState aState;
3547cdf0e10cSrcweir             aState.bRealWidth = sal_True;
3548cdf0e10cSrcweir             SwCntntNode* pCntntNode = pCrsr->GetCntntNode();
3549cdf0e10cSrcweir             SwCntntFrm *pCntntFrame = pCntntNode->getLayoutFrm( GetLayout(), &rPt, pCrsr->GetPoint(), sal_False);
3550cdf0e10cSrcweir 
3551cdf0e10cSrcweir             pCntntFrame->GetCharRect( aStartRect, *pCrsr->GetPoint(), &aState );
3552cdf0e10cSrcweir             rContent = nWordEnd;
3553cdf0e10cSrcweir             SwRect aEndRect;
3554cdf0e10cSrcweir             pCntntFrame->GetCharRect( aEndRect, *pCrsr->GetPoint(),&aState );
3555cdf0e10cSrcweir             rSelectRect = aStartRect.Union( aEndRect );
3556cdf0e10cSrcweir             Pop(sal_False);
3557cdf0e10cSrcweir         }
3558cdf0e10cSrcweir     }
3559cdf0e10cSrcweir }
3560cdf0e10cSrcweir 
3561