xref: /trunk/main/sw/source/core/crsr/crsrsh.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
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
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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 
GetCharRectAt(SwRect & rOrig,const SwPosition & rPos,SwCrsrMoveState * pCMS) const1236af7a586eSTsutomu Uchino sal_Bool SwCrsrShell::GetCharRectAt( SwRect& rOrig, const SwPosition& rPos,
1237af7a586eSTsutomu Uchino                                      SwCrsrMoveState* pCMS ) const
1238af7a586eSTsutomu Uchino {
1239af7a586eSTsutomu Uchino     SwCntntFrm * pFrm = GetCurrFrm();
1240af7a586eSTsutomu Uchino     return pFrm ? pFrm->GetCharRect( rOrig, rPos, pCMS ) : sal_False;
1241af7a586eSTsutomu Uchino }
1242af7a586eSTsutomu Uchino 
1243af7a586eSTsutomu Uchino 
Paint(const Rectangle & rRect)1244cdf0e10cSrcweir void SwCrsrShell::Paint( const Rectangle &rRect)
1245cdf0e10cSrcweir {
1246cdf0e10cSrcweir     SET_CURR_SHELL( this );
1247cdf0e10cSrcweir 
1248cdf0e10cSrcweir     // beim Painten immer alle Cursor ausschalten
1249cdf0e10cSrcweir     SwRect aRect( rRect );
1250cdf0e10cSrcweir 
1251cdf0e10cSrcweir     sal_Bool bVis = sal_False;
1252cdf0e10cSrcweir     // ist Cursor sichtbar, dann verstecke den SV-Cursor
1253cdf0e10cSrcweir     if( pVisCrsr->IsVisible() && !aRect.IsOver( aCharRect ) )   //JP 18.06.97: ???
1254cdf0e10cSrcweir     {
1255cdf0e10cSrcweir         bVis = sal_True;
1256cdf0e10cSrcweir         pVisCrsr->Hide();
1257cdf0e10cSrcweir     }
1258cdf0e10cSrcweir 
1259cdf0e10cSrcweir     // Bereich neu painten
1260cdf0e10cSrcweir     ViewShell::Paint( rRect );
1261cdf0e10cSrcweir 
1262cdf0e10cSrcweir     if( bHasFocus && !bBasicHideCrsr )
1263cdf0e10cSrcweir     {
1264cdf0e10cSrcweir         SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
1265cdf0e10cSrcweir //      pAktCrsr->Invalidate( aRect );
1266cdf0e10cSrcweir         if( !ActionPend() )
1267cdf0e10cSrcweir         {
1268cdf0e10cSrcweir             // damit nicht rechts/unten die Raender abgeschnitten werden
1269cdf0e10cSrcweir             pAktCrsr->Invalidate( VisArea() );
1270cdf0e10cSrcweir             pAktCrsr->Show();
1271cdf0e10cSrcweir         }
1272cdf0e10cSrcweir         else
1273cdf0e10cSrcweir             pAktCrsr->Invalidate( aRect );
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir     }
1276cdf0e10cSrcweir     if( bSVCrsrVis && bVis )        // auch SV-Cursor wieder anzeigen
1277cdf0e10cSrcweir         pVisCrsr->Show();
1278cdf0e10cSrcweir }
1279cdf0e10cSrcweir 
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir 
VisPortChgd(const SwRect & rRect)1282cdf0e10cSrcweir void SwCrsrShell::VisPortChgd( const SwRect & rRect )
1283cdf0e10cSrcweir {
1284cdf0e10cSrcweir     SET_CURR_SHELL( this );
1285cdf0e10cSrcweir     sal_Bool bVis;      // beim Scrollen immer alle Cursor ausschalten
1286cdf0e10cSrcweir 
1287cdf0e10cSrcweir     // ist Cursor sichtbar, dann verstecke den SV-Cursor
1288cdf0e10cSrcweir     if( sal_True == ( bVis = pVisCrsr->IsVisible() ))
1289cdf0e10cSrcweir         pVisCrsr->Hide();
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir     bVisPortChgd = sal_True;
1292cdf0e10cSrcweir     aOldRBPos.X() = VisArea().Right();
1293cdf0e10cSrcweir     aOldRBPos.Y() = VisArea().Bottom();
1294cdf0e10cSrcweir 
1295cdf0e10cSrcweir     //Damit es es keine Probleme mit dem SV-Cursor gibt, wird in
1296cdf0e10cSrcweir     //ViewShell::VisPo.. ein Update() auf das Window gerufen.
1297cdf0e10cSrcweir     //Waehrend des Paintens duerfen aber nun wieder keine Selectionen
1298cdf0e10cSrcweir     //angezeigt werden, deshalb wird der Aufruf hier geklammert.
1299cdf0e10cSrcweir     ViewShell::VisPortChgd( rRect );        // Bereich verschieben
1300cdf0e10cSrcweir 
1301cdf0e10cSrcweir /*
1302cdf0e10cSrcweir     SwRect aRect( rRect );
1303cdf0e10cSrcweir     if( VisArea().IsOver( aRect ) )
1304cdf0e10cSrcweir         pCurCrsr->Invalidate( aRect );
1305cdf0e10cSrcweir */
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir     if( bSVCrsrVis && bVis )    // auch SV-Cursor wieder anzeigen
1308cdf0e10cSrcweir         pVisCrsr->Show();
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir     if( nCrsrMove )
1311cdf0e10cSrcweir         bInCMvVisportChgd = sal_True;
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir     bVisPortChgd = sal_False;
1314cdf0e10cSrcweir }
1315cdf0e10cSrcweir 
1316cdf0e10cSrcweir // aktualisiere den Crsrs, d.H. setze ihn wieder in den Content.
1317cdf0e10cSrcweir // Das sollte nur aufgerufen werden, wenn der Cursor z.B. beim
1318cdf0e10cSrcweir // Loeschen von Rahmen irgendwohin gesetzt wurde. Die Position
1319cdf0e10cSrcweir // ergibt sich aus seiner aktuellen Position im Layout !!
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir 
UpdateCrsrPos()1322cdf0e10cSrcweir void SwCrsrShell::UpdateCrsrPos()
1323cdf0e10cSrcweir {
1324cdf0e10cSrcweir     SET_CURR_SHELL( this );
1325cdf0e10cSrcweir     ++nStartAction;
1326cdf0e10cSrcweir     SwShellCrsr* pShellCrsr = getShellCrsr( true );
1327cdf0e10cSrcweir     Size aOldSz( GetDocSize() );
1328cdf0e10cSrcweir     SwCntntNode *pCNode = pShellCrsr->GetCntntNode();
1329cdf0e10cSrcweir     SwCntntFrm  *pFrm = pCNode ?
1330cdf0e10cSrcweir         pCNode->getLayoutFrm( GetLayout(), &pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), sal_False ) :0;
1331cdf0e10cSrcweir     if( !pFrm || (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow()) )
1332cdf0e10cSrcweir     {
1333cdf0e10cSrcweir         SwCrsrMoveState aTmpState( MV_NONE );
1334cdf0e10cSrcweir         aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1335cdf0e10cSrcweir         GetLayout()->GetCrsrOfst( pShellCrsr->GetPoint(), pShellCrsr->GetPtPos(),
1336cdf0e10cSrcweir                                      &aTmpState );
1337cdf0e10cSrcweir         if( pShellCrsr->HasMark())
1338cdf0e10cSrcweir             pShellCrsr->DeleteMark();
1339cdf0e10cSrcweir     }
1340cdf0e10cSrcweir     IGrammarContact *pGrammarContact = GetDoc() ? GetDoc()->getGrammarContact() : 0;
1341cdf0e10cSrcweir     if( pGrammarContact )
1342cdf0e10cSrcweir         pGrammarContact->updateCursorPosition( *pCurCrsr->GetPoint() );
1343cdf0e10cSrcweir     --nStartAction;
1344cdf0e10cSrcweir     if( aOldSz != GetDocSize() )
1345cdf0e10cSrcweir         SizeChgNotify();
1346cdf0e10cSrcweir }
1347cdf0e10cSrcweir 
1348cdf0e10cSrcweir // JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen
1349cdf0e10cSrcweir //              stehen, so mussen diese daraus verschoben werden
lcl_CheckHiddenSection(SwNodeIndex & rIdx)1350cdf0e10cSrcweir static void lcl_CheckHiddenSection( SwNodeIndex& rIdx )
1351cdf0e10cSrcweir {
1352cdf0e10cSrcweir     const SwSectionNode* pSectNd = rIdx.GetNode().FindSectionNode();
1353cdf0e10cSrcweir     if( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
1354cdf0e10cSrcweir     {
1355cdf0e10cSrcweir         SwNodeIndex aTmp( *pSectNd );
1356cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1357cdf0e10cSrcweir         const SwNode* pFrmNd =
1358cdf0e10cSrcweir #endif
1359cdf0e10cSrcweir         rIdx.GetNodes().FindPrvNxtFrmNode( aTmp, pSectNd->EndOfSectionNode() );
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1362cdf0e10cSrcweir         (void) pFrmNd;
1363cdf0e10cSrcweir         ASSERT( pFrmNd, "keinen Node mit Frames gefunden" );
1364cdf0e10cSrcweir #endif
1365cdf0e10cSrcweir         rIdx = aTmp;
1366cdf0e10cSrcweir     }
1367cdf0e10cSrcweir }
1368cdf0e10cSrcweir 
1369cdf0e10cSrcweir // Try to set the cursor to the next visible content node.
lcl_CheckHiddenPara(SwPosition & rPos)1370cdf0e10cSrcweir static void lcl_CheckHiddenPara( SwPosition& rPos )
1371cdf0e10cSrcweir {
1372cdf0e10cSrcweir     SwNodeIndex aTmp( rPos.nNode );
1373cdf0e10cSrcweir     SwTxtNode* pTxtNd = aTmp.GetNode().GetTxtNode();
1374cdf0e10cSrcweir     while( pTxtNd && pTxtNd->HasHiddenCharAttribute( true ) )
1375cdf0e10cSrcweir     {
1376cdf0e10cSrcweir         SwCntntNode* pCntnt = aTmp.GetNodes().GoNext( &aTmp );
1377cdf0e10cSrcweir         if ( pCntnt && pCntnt->IsTxtNode() )
1378cdf0e10cSrcweir             pTxtNd = (SwTxtNode*)pCntnt;
1379cdf0e10cSrcweir         else
1380cdf0e10cSrcweir             pTxtNd = 0;
1381cdf0e10cSrcweir     }
1382cdf0e10cSrcweir 
1383cdf0e10cSrcweir     if ( pTxtNd )
1384cdf0e10cSrcweir         rPos = SwPosition( aTmp, SwIndex( pTxtNd, 0 ) );
1385cdf0e10cSrcweir }
1386cdf0e10cSrcweir 
1387cdf0e10cSrcweir // --> OD 2005-12-14 #i27301# - helper class, which notifies the accessibility
1388cdf0e10cSrcweir // about invalid text selections in its destructor
1389cdf0e10cSrcweir class SwNotifyAccAboutInvalidTextSelections
1390cdf0e10cSrcweir {
1391cdf0e10cSrcweir     private:
1392cdf0e10cSrcweir         SwCrsrShell& mrCrsrSh;
1393cdf0e10cSrcweir 
1394cdf0e10cSrcweir     public:
SwNotifyAccAboutInvalidTextSelections(SwCrsrShell & _rCrsrSh)1395cdf0e10cSrcweir         SwNotifyAccAboutInvalidTextSelections( SwCrsrShell& _rCrsrSh )
1396cdf0e10cSrcweir             : mrCrsrSh( _rCrsrSh )
1397cdf0e10cSrcweir         {}
1398cdf0e10cSrcweir 
~SwNotifyAccAboutInvalidTextSelections()1399cdf0e10cSrcweir         ~SwNotifyAccAboutInvalidTextSelections()
1400cdf0e10cSrcweir         {
1401cdf0e10cSrcweir             mrCrsrSh.InvalidateAccessibleParaTextSelection();
1402cdf0e10cSrcweir         }
1403cdf0e10cSrcweir };
1404cdf0e10cSrcweir // <--
UpdateCrsr(sal_uInt16 eFlags,sal_Bool bIdleEnd)1405cdf0e10cSrcweir void SwCrsrShell::UpdateCrsr( sal_uInt16 eFlags, sal_Bool bIdleEnd )
1406cdf0e10cSrcweir {
1407cdf0e10cSrcweir     SET_CURR_SHELL( this );
1408cdf0e10cSrcweir 
1409cdf0e10cSrcweir     ClearUpCrsrs();
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir     // erfrage den Count fuer die Start-/End-Actions und ob die Shell
1412cdf0e10cSrcweir     // ueberhaupt den Focus hat
1413cdf0e10cSrcweir //  if( ActionPend() /*|| !bHasFocus*/ )
1414cdf0e10cSrcweir     //JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction der
1415cdf0e10cSrcweir     //              Cursor geupdatet werden; um z.B. den TabellenCursor zu
1416cdf0e10cSrcweir     //              erzeugen. Im EndAction wird jetzt das UpdateCrsr gerufen!
1417cdf0e10cSrcweir     if( ActionPend() && BasicActionPend() )
1418cdf0e10cSrcweir     {
1419cdf0e10cSrcweir         if ( eFlags & SwCrsrShell::READONLY )
1420cdf0e10cSrcweir             bIgnoreReadonly = sal_True;
1421cdf0e10cSrcweir         return;             // wenn nicht, dann kein Update !!
1422cdf0e10cSrcweir     }
1423cdf0e10cSrcweir 
1424cdf0e10cSrcweir     SwNotifyAccAboutInvalidTextSelections aInvalidateTextSelections( *this );
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir     if ( bIgnoreReadonly )
1427cdf0e10cSrcweir     {
1428cdf0e10cSrcweir         bIgnoreReadonly = sal_False;
1429cdf0e10cSrcweir         eFlags |= SwCrsrShell::READONLY;
1430cdf0e10cSrcweir     }
1431cdf0e10cSrcweir 
1432cdf0e10cSrcweir     if( eFlags & SwCrsrShell::CHKRANGE )    // alle Cursor-Bewegungen auf
1433cdf0e10cSrcweir         CheckRange( pCurCrsr );         // ueberlappende Bereiche testen
1434cdf0e10cSrcweir 
1435cdf0e10cSrcweir     if( !bIdleEnd )
1436cdf0e10cSrcweir         CheckTblBoxCntnt();
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir     // steht der akt. Crsr in einer Tabelle und in unterschiedlichen Boxen
1439cdf0e10cSrcweir     // (oder ist noch TabellenMode), dann gilt der Tabellen Mode
1440cdf0e10cSrcweir     SwPaM* pTstCrsr = getShellCrsr( true );
1441cdf0e10cSrcweir     if( pTstCrsr->HasMark() && !pBlockCrsr &&
1442cdf0e10cSrcweir         pDoc->IsIdxInTbl( pTstCrsr->GetPoint()->nNode ) &&
1443cdf0e10cSrcweir           ( pTblCrsr ||
1444cdf0e10cSrcweir             pTstCrsr->GetNode( sal_True )->StartOfSectionNode() !=
1445cdf0e10cSrcweir             pTstCrsr->GetNode( sal_False )->StartOfSectionNode() ) )
1446cdf0e10cSrcweir     {
1447cdf0e10cSrcweir         SwShellCrsr* pITmpCrsr = getShellCrsr( true );
1448cdf0e10cSrcweir         Point aTmpPt( pITmpCrsr->GetPtPos() );
1449cdf0e10cSrcweir         Point aTmpMk( pITmpCrsr->GetMkPos() );
1450cdf0e10cSrcweir         SwPosition* pPos = pITmpCrsr->GetPoint();
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir         // JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen
1453cdf0e10cSrcweir         //              stehen, so mussen diese daraus verschoben werden
1454cdf0e10cSrcweir         lcl_CheckHiddenSection( pPos->nNode );
1455cdf0e10cSrcweir         lcl_CheckHiddenSection( pITmpCrsr->GetMark()->nNode );
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir         // Move cursor out of hidden paragraphs
1458cdf0e10cSrcweir         if ( !GetViewOptions()->IsShowHiddenChar() )
1459cdf0e10cSrcweir         {
1460cdf0e10cSrcweir             lcl_CheckHiddenPara( *pPos );
1461cdf0e10cSrcweir             lcl_CheckHiddenPara( *pITmpCrsr->GetMark() );
1462cdf0e10cSrcweir         }
1463cdf0e10cSrcweir 
1464cdf0e10cSrcweir         SwCntntFrm *pTblFrm = pPos->nNode.GetNode().GetCntntNode()->
1465cdf0e10cSrcweir                               getLayoutFrm( GetLayout(), &aTmpPt, pPos, sal_False );
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir         ASSERT( pTblFrm, "Tabelle Crsr nicht im Content ??" );
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir         // --> FME 2005-12-02 #126107# Make code robust. The table
1470cdf0e10cSrcweir         // cursor may point to a table in a currently inactive header.
1471cdf0e10cSrcweir         SwTabFrm *pTab = pTblFrm ? pTblFrm->FindTabFrm() : 0;
1472cdf0e10cSrcweir         // <--
1473cdf0e10cSrcweir 
1474cdf0e10cSrcweir         if ( pTab && pTab->GetTable()->GetRowsToRepeat() > 0 )
1475cdf0e10cSrcweir         {
1476cdf0e10cSrcweir             // First check if point is in repeated headline:
1477cdf0e10cSrcweir             bool bInRepeatedHeadline = pTab->IsFollow() && pTab->IsInHeadline( *pTblFrm );
1478cdf0e10cSrcweir 
1479cdf0e10cSrcweir             // Second check if mark is in repeated headline:
1480cdf0e10cSrcweir             if ( !bInRepeatedHeadline )
1481cdf0e10cSrcweir             {
1482cdf0e10cSrcweir                 SwCntntFrm* pMarkTblFrm = pITmpCrsr->GetCntntNode( sal_False )->
1483cdf0e10cSrcweir                     getLayoutFrm( GetLayout(), &aTmpMk, pITmpCrsr->GetMark(), sal_False );
1484cdf0e10cSrcweir                 ASSERT( pMarkTblFrm, "Tabelle Crsr nicht im Content ??" );
1485cdf0e10cSrcweir 
1486cdf0e10cSrcweir                 if ( pMarkTblFrm )
1487cdf0e10cSrcweir                 {
1488cdf0e10cSrcweir                     SwTabFrm* pMarkTab = pMarkTblFrm->FindTabFrm();
1489cdf0e10cSrcweir                     ASSERT( pMarkTab, "Tabelle Crsr nicht im Content ??" );
1490cdf0e10cSrcweir 
1491cdf0e10cSrcweir                     // --> FME 2005-11-28 #120360# Make code robust:
1492cdf0e10cSrcweir                     if ( pMarkTab )
1493cdf0e10cSrcweir                     {
1494cdf0e10cSrcweir                         bInRepeatedHeadline = pMarkTab->IsFollow() && pMarkTab->IsInHeadline( *pMarkTblFrm );
1495cdf0e10cSrcweir                     }
1496cdf0e10cSrcweir                     // <--
1497cdf0e10cSrcweir                 }
1498cdf0e10cSrcweir             }
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir             // No table cursor in repeaded headlines:
1501cdf0e10cSrcweir             if ( bInRepeatedHeadline )
1502cdf0e10cSrcweir             {
1503cdf0e10cSrcweir                 pTblFrm = 0;
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir                 SwPosSection fnPosSect = *pPos <  *pITmpCrsr->GetMark()
1506cdf0e10cSrcweir                                             ? fnSectionStart
1507cdf0e10cSrcweir                                             : fnSectionEnd;
1508cdf0e10cSrcweir 
1509cdf0e10cSrcweir                 // dann nur innerhalb der Box selektieren
1510cdf0e10cSrcweir                 if( pTblCrsr )
1511cdf0e10cSrcweir                 {
1512cdf0e10cSrcweir                     pCurCrsr->SetMark();
1513cdf0e10cSrcweir                     *pCurCrsr->GetMark() = *pTblCrsr->GetMark();
1514cdf0e10cSrcweir                     pCurCrsr->GetMkPos() = pTblCrsr->GetMkPos();
1515cdf0e10cSrcweir                     pTblCrsr->DeleteMark();
1516cdf0e10cSrcweir                     pTblCrsr->SwSelPaintRects::Hide();
1517cdf0e10cSrcweir                 }
1518cdf0e10cSrcweir 
1519cdf0e10cSrcweir                 *pCurCrsr->GetPoint() = *pCurCrsr->GetMark();
1520cdf0e10cSrcweir                 (*fnSectionCurr)( *pCurCrsr, fnPosSect );
1521cdf0e10cSrcweir             }
1522cdf0e10cSrcweir         }
1523cdf0e10cSrcweir 
1524cdf0e10cSrcweir         // wir wollen wirklich eine Tabellen-Selektion
1525cdf0e10cSrcweir         if( pTab && pTblFrm )
1526cdf0e10cSrcweir         {
1527cdf0e10cSrcweir             if( !pTblCrsr )
1528cdf0e10cSrcweir             {
1529cdf0e10cSrcweir                 pTblCrsr = new SwShellTableCrsr( *this,
1530cdf0e10cSrcweir                                 *pCurCrsr->GetMark(), pCurCrsr->GetMkPos(),
1531cdf0e10cSrcweir                                 *pPos, aTmpPt );
1532cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1533cdf0e10cSrcweir                 pCurCrsr->SwSelPaintRects::Hide();
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir                 CheckTblBoxCntnt();
1536cdf0e10cSrcweir             }
1537cdf0e10cSrcweir 
1538cdf0e10cSrcweir             SwCrsrMoveState aTmpState( MV_NONE );
1539cdf0e10cSrcweir             aTmpState.bRealHeight = sal_True;
1540cdf0e10cSrcweir             if( !pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint(), &aTmpState ) )
1541cdf0e10cSrcweir             {
1542cdf0e10cSrcweir                 Point aCentrPt( aCharRect.Center() );
1543cdf0e10cSrcweir                 aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1544cdf0e10cSrcweir                 pTblFrm->GetCrsrOfst( pTblCrsr->GetPoint(), aCentrPt, &aTmpState );
1545cdf0e10cSrcweir #ifndef DBG_UTIL
1546cdf0e10cSrcweir                 pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint() );
1547cdf0e10cSrcweir #else
1548cdf0e10cSrcweir                 if ( !pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint() ) )
1549870262e3SDon Lewis                     ASSERT( sal_False, "GetCharRect failed." );
1550cdf0e10cSrcweir #endif
1551cdf0e10cSrcweir             }
1552cdf0e10cSrcweir //          ALIGNRECT( aCharRect );
1553cdf0e10cSrcweir 
1554cdf0e10cSrcweir             pVisCrsr->Hide();       // sichtbaren Cursor immer verstecken
1555cdf0e10cSrcweir             // Curosr in den sichtbaren Bereich scrollen
1556cdf0e10cSrcweir             if( (eFlags & SwCrsrShell::SCROLLWIN) &&
1557cdf0e10cSrcweir                 (HasSelection() || eFlags & SwCrsrShell::READONLY ||
1558cdf0e10cSrcweir                  !IsCrsrReadonly()) )
1559cdf0e10cSrcweir             {
1560cdf0e10cSrcweir                 SwFrm* pBoxFrm = pTblFrm;
1561cdf0e10cSrcweir                 while( pBoxFrm && !pBoxFrm->IsCellFrm() )
1562cdf0e10cSrcweir                     pBoxFrm = pBoxFrm->GetUpper();
1563cdf0e10cSrcweir                 if( pBoxFrm && pBoxFrm->Frm().HasArea() )
1564cdf0e10cSrcweir                     MakeVisible( pBoxFrm->Frm() );
1565cdf0e10cSrcweir                 else
1566cdf0e10cSrcweir                     MakeVisible( aCharRect );
1567cdf0e10cSrcweir             }
1568cdf0e10cSrcweir 
1569cdf0e10cSrcweir             // lasse vom Layout die Crsr in den Boxen erzeugen
1570cdf0e10cSrcweir             if( pTblCrsr->IsCrsrMovedUpdt() )
1571cdf0e10cSrcweir                 GetLayout()->MakeTblCrsrs( *pTblCrsr );
1572cdf0e10cSrcweir             if( bHasFocus && !bBasicHideCrsr )
1573cdf0e10cSrcweir                 pTblCrsr->Show();
1574cdf0e10cSrcweir 
1575cdf0e10cSrcweir             // Cursor-Points auf die neuen Positionen setzen
1576cdf0e10cSrcweir             pTblCrsr->GetPtPos().X() = aCharRect.Left();
1577cdf0e10cSrcweir             pTblCrsr->GetPtPos().Y() = aCharRect.Top();
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir             if( bSVCrsrVis )
1580cdf0e10cSrcweir             {
1581cdf0e10cSrcweir                 aCrsrHeight.X() = 0;
1582cdf0e10cSrcweir                 aCrsrHeight.Y() = aTmpState.aRealHeight.Y() < 0 ?
1583cdf0e10cSrcweir                                   -aCharRect.Width() : aCharRect.Height();
1584cdf0e10cSrcweir                 pVisCrsr->Show();           // wieder anzeigen
1585cdf0e10cSrcweir             }
1586cdf0e10cSrcweir             eMvState = MV_NONE;     // Status fuers Crsr-Travelling - GetCrsrOfst
1587cdf0e10cSrcweir             if( pTblFrm && Imp()->IsAccessible() )
1588cdf0e10cSrcweir                 Imp()->InvalidateAccessibleCursorPosition( pTblFrm );
1589cdf0e10cSrcweir             return;
1590cdf0e10cSrcweir         }
1591cdf0e10cSrcweir     }
1592cdf0e10cSrcweir 
1593cdf0e10cSrcweir     if( pTblCrsr )
1594cdf0e10cSrcweir     {
1595cdf0e10cSrcweir         // Cursor Ring loeschen
1596cdf0e10cSrcweir         while( pCurCrsr->GetNext() != pCurCrsr )
1597cdf0e10cSrcweir             delete pCurCrsr->GetNext();
1598cdf0e10cSrcweir         pCurCrsr->DeleteMark();
1599cdf0e10cSrcweir         *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint();
1600cdf0e10cSrcweir         pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos();
1601cdf0e10cSrcweir         delete pTblCrsr, pTblCrsr = 0;
1602cdf0e10cSrcweir     }
1603cdf0e10cSrcweir 
1604cdf0e10cSrcweir     pVisCrsr->Hide();       // sichtbaren Cursor immer verstecken
1605cdf0e10cSrcweir 
1606cdf0e10cSrcweir     // sind wir vielleicht in einer geschuetzten/versteckten Section ?
1607cdf0e10cSrcweir     {
1608cdf0e10cSrcweir         SwShellCrsr* pShellCrsr = getShellCrsr( true );
1609cdf0e10cSrcweir         sal_Bool bChgState = sal_True;
1610cdf0e10cSrcweir         const SwSectionNode* pSectNd = pShellCrsr->GetNode()->FindSectionNode();
1611cdf0e10cSrcweir         if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
1612cdf0e10cSrcweir             ( !IsReadOnlyAvailable() &&
1613cdf0e10cSrcweir               pSectNd->GetSection().IsProtectFlag() &&
1614cdf0e10cSrcweir              ( !pDoc->GetDocShell() ||
1615cdf0e10cSrcweir                !pDoc->GetDocShell()->IsReadOnly() || bAllProtect )) ) )
1616cdf0e10cSrcweir         {
1617cdf0e10cSrcweir             if( !FindValidCntntNode( !HasDrawView() ||
1618cdf0e10cSrcweir                     0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1619cdf0e10cSrcweir             {
1620cdf0e10cSrcweir                 // alles ist geschuetzt / versteckt -> besonderer Mode
1621cdf0e10cSrcweir                 if( bAllProtect && !IsReadOnlyAvailable() &&
1622cdf0e10cSrcweir                     pSectNd->GetSection().IsProtectFlag() )
1623cdf0e10cSrcweir                     bChgState = sal_False;
1624cdf0e10cSrcweir                 else
1625cdf0e10cSrcweir                 {
1626cdf0e10cSrcweir                     eMvState = MV_NONE;     // Status fuers Crsr-Travelling
1627cdf0e10cSrcweir                     bAllProtect = sal_True;
1628cdf0e10cSrcweir                     if( GetDoc()->GetDocShell() )
1629cdf0e10cSrcweir                     {
1630cdf0e10cSrcweir                         GetDoc()->GetDocShell()->SetReadOnlyUI( sal_True );
1631cdf0e10cSrcweir                         CallChgLnk();       // UI bescheid sagen!
1632cdf0e10cSrcweir                     }
1633cdf0e10cSrcweir                     return;
1634cdf0e10cSrcweir                 }
1635cdf0e10cSrcweir             }
1636cdf0e10cSrcweir         }
1637cdf0e10cSrcweir         if( bChgState )
1638cdf0e10cSrcweir         {
1639cdf0e10cSrcweir             sal_Bool bWasAllProtect = bAllProtect;
1640cdf0e10cSrcweir             bAllProtect = sal_False;
1641cdf0e10cSrcweir             if( bWasAllProtect && GetDoc()->GetDocShell() &&
1642cdf0e10cSrcweir                 GetDoc()->GetDocShell()->IsReadOnlyUI() )
1643cdf0e10cSrcweir             {
1644cdf0e10cSrcweir                 GetDoc()->GetDocShell()->SetReadOnlyUI( sal_False );
1645cdf0e10cSrcweir                 CallChgLnk();       // UI bescheid sagen!
1646cdf0e10cSrcweir             }
1647cdf0e10cSrcweir         }
1648cdf0e10cSrcweir     }
1649cdf0e10cSrcweir 
1650cdf0e10cSrcweir     UpdateCrsrPos();
1651cdf0e10cSrcweir 
1652cdf0e10cSrcweir     // #100722# The cursor must always point into content; there's some code
1653cdf0e10cSrcweir     // that relies on this. (E.g. in SwEditShell::GetScriptType, which always
1654cdf0e10cSrcweir     // loops _behind_ the last node in the selection, which always works if you
1655cdf0e10cSrcweir     // are in content.) To achieve this, we'll force cursor(s) to point into
1656cdf0e10cSrcweir     // content, if UpdateCrsrPos() hasn't already done so.
1657cdf0e10cSrcweir     SwPaM* pCmp = pCurCrsr;
1658cdf0e10cSrcweir     do
1659cdf0e10cSrcweir     {
1660cdf0e10cSrcweir         // start will move forwards, end will move backwards
1661cdf0e10cSrcweir         bool bPointIsStart = ( pCmp->Start() == pCmp->GetPoint() );
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir         // move point; forward if it's the start, backwards if it's the end
1664cdf0e10cSrcweir         if( ! pCmp->GetPoint()->nNode.GetNode().IsCntntNode() )
1665cdf0e10cSrcweir             pCmp->Move( bPointIsStart ? fnMoveForward : fnMoveBackward,
1666cdf0e10cSrcweir                         fnGoCntnt );
1667cdf0e10cSrcweir 
1668cdf0e10cSrcweir         // move mark (if exists); forward if it's the start, else backwards
1669cdf0e10cSrcweir         if( pCmp->HasMark() )
1670cdf0e10cSrcweir         {
1671cdf0e10cSrcweir             if( ! pCmp->GetMark()->nNode.GetNode().IsCntntNode() )
1672cdf0e10cSrcweir             {
1673cdf0e10cSrcweir                 pCmp->Exchange();
1674cdf0e10cSrcweir                 pCmp->Move( !bPointIsStart ? fnMoveForward : fnMoveBackward,
1675cdf0e10cSrcweir                             fnGoCntnt );
1676cdf0e10cSrcweir                 pCmp->Exchange();
1677cdf0e10cSrcweir             }
1678cdf0e10cSrcweir         }
1679cdf0e10cSrcweir 
1680cdf0e10cSrcweir         // iterate to next PaM in ring
1681cdf0e10cSrcweir         pCmp = static_cast<SwPaM*>( pCmp->GetNext() );
1682cdf0e10cSrcweir     }
1683cdf0e10cSrcweir     while( pCmp != pCurCrsr );
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir 
1686cdf0e10cSrcweir     SwRect aOld( aCharRect );
1687cdf0e10cSrcweir     sal_Bool bFirst = sal_True;
1688cdf0e10cSrcweir     SwCntntFrm *pFrm;
1689cdf0e10cSrcweir     int nLoopCnt = 100;
1690cdf0e10cSrcweir     SwShellCrsr* pShellCrsr = getShellCrsr( true );
1691cdf0e10cSrcweir 
1692cdf0e10cSrcweir     do {
1693cdf0e10cSrcweir         sal_Bool bAgainst;
1694cdf0e10cSrcweir         do {
1695cdf0e10cSrcweir             bAgainst = sal_False;
1696cdf0e10cSrcweir             pFrm = pShellCrsr->GetCntntNode()->getLayoutFrm( GetLayout(),
1697cdf0e10cSrcweir                         &pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), sal_False );
1698cdf0e10cSrcweir             // ist der Frm nicht mehr vorhanden, dann muss das gesamte Layout
1699cdf0e10cSrcweir             // erzeugt werden, weil ja mal hier einer vorhanden war !!
1700cdf0e10cSrcweir             if ( !pFrm )
1701cdf0e10cSrcweir             {
1702cdf0e10cSrcweir                 do
1703cdf0e10cSrcweir                 {
1704cdf0e10cSrcweir                     CalcLayout();
1705cdf0e10cSrcweir                     pFrm = pShellCrsr->GetCntntNode()->getLayoutFrm( GetLayout(),
1706cdf0e10cSrcweir                                 &pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), sal_False );
1707cdf0e10cSrcweir                 }  while( !pFrm );
1708cdf0e10cSrcweir             }
1709cdf0e10cSrcweir             else if ( Imp()->IsIdleAction() )
1710cdf0e10cSrcweir                 //Wir stellen sicher, dass anstaendig Formatiert wurde #42224#
1711cdf0e10cSrcweir                 pFrm->PrepareCrsr();
1712cdf0e10cSrcweir 
1713cdf0e10cSrcweir             // im geschuetzten Fly? aber bei Rahmenselektion ignorieren
1714cdf0e10cSrcweir             if( !IsReadOnlyAvailable() && pFrm->IsProtected() &&
1715cdf0e10cSrcweir                 ( !Imp()->GetDrawView() ||
1716cdf0e10cSrcweir                   !Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) &&
1717cdf0e10cSrcweir                 (!pDoc->GetDocShell() ||
1718cdf0e10cSrcweir                  !pDoc->GetDocShell()->IsReadOnly() || bAllProtect ) )
1719cdf0e10cSrcweir             {
1720cdf0e10cSrcweir                 // dann suche eine gueltige Position
1721cdf0e10cSrcweir                 sal_Bool bChgState = sal_True;
1722cdf0e10cSrcweir                 if( !FindValidCntntNode(!HasDrawView() ||
1723cdf0e10cSrcweir                     0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1724cdf0e10cSrcweir                 {
1725cdf0e10cSrcweir                     // alles ist geschuetzt / versteckt -> besonderer Mode
1726cdf0e10cSrcweir                     if( bAllProtect )
1727cdf0e10cSrcweir                         bChgState = sal_False;
1728cdf0e10cSrcweir                     else
1729cdf0e10cSrcweir                     {
1730cdf0e10cSrcweir                         eMvState = MV_NONE;     // Status fuers Crsr-Travelling
1731cdf0e10cSrcweir                         bAllProtect = sal_True;
1732cdf0e10cSrcweir                         if( GetDoc()->GetDocShell() )
1733cdf0e10cSrcweir                         {
1734cdf0e10cSrcweir                             GetDoc()->GetDocShell()->SetReadOnlyUI( sal_True );
1735cdf0e10cSrcweir                             CallChgLnk();       // UI bescheid sagen!
1736cdf0e10cSrcweir                         }
1737cdf0e10cSrcweir                         return;
1738cdf0e10cSrcweir                     }
1739cdf0e10cSrcweir                 }
1740cdf0e10cSrcweir 
1741cdf0e10cSrcweir                 if( bChgState )
1742cdf0e10cSrcweir                 {
1743cdf0e10cSrcweir                     sal_Bool bWasAllProtect = bAllProtect;
1744cdf0e10cSrcweir                     bAllProtect = sal_False;
1745cdf0e10cSrcweir                     if( bWasAllProtect && GetDoc()->GetDocShell() &&
1746cdf0e10cSrcweir                         GetDoc()->GetDocShell()->IsReadOnlyUI() )
1747cdf0e10cSrcweir                     {
1748cdf0e10cSrcweir                         GetDoc()->GetDocShell()->SetReadOnlyUI( sal_False );
1749cdf0e10cSrcweir                         CallChgLnk();       // UI bescheid sagen!
1750cdf0e10cSrcweir                     }
1751cdf0e10cSrcweir                     bAllProtect = sal_False;
1752cdf0e10cSrcweir                     bAgainst = sal_True;        // nochmal den richigen Frm suchen
1753cdf0e10cSrcweir                 }
1754cdf0e10cSrcweir             }
1755cdf0e10cSrcweir         } while( bAgainst );
1756cdf0e10cSrcweir 
1757cdf0e10cSrcweir         if( !( eFlags & SwCrsrShell::NOCALRECT ))
1758cdf0e10cSrcweir         {
1759cdf0e10cSrcweir             SwCrsrMoveState aTmpState( eMvState );
1760cdf0e10cSrcweir             aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
1761cdf0e10cSrcweir             aTmpState.bRealHeight = sal_True;
1762cdf0e10cSrcweir             aTmpState.bRealWidth = IsOverwriteCrsr();
1763cdf0e10cSrcweir             aTmpState.nCursorBidiLevel = pShellCrsr->GetCrsrBidiLevel();
1764cdf0e10cSrcweir 
1765cdf0e10cSrcweir             // #i27615#,#i30453#
1766cdf0e10cSrcweir             SwSpecialPos aSpecialPos;
1767cdf0e10cSrcweir             aSpecialPos.nExtendRange = SP_EXTEND_RANGE_BEFORE;
1768cdf0e10cSrcweir             if (pShellCrsr->IsInFrontOfLabel())
1769cdf0e10cSrcweir             {
1770cdf0e10cSrcweir                 aTmpState.pSpecialPos = &aSpecialPos;
1771cdf0e10cSrcweir             }
1772cdf0e10cSrcweir 
1773cdf0e10cSrcweir             if( !pFrm->GetCharRect( aCharRect, *pShellCrsr->GetPoint(), &aTmpState ) )
1774cdf0e10cSrcweir             {
1775cdf0e10cSrcweir                 Point& rPt = pShellCrsr->GetPtPos();
1776cdf0e10cSrcweir                 rPt = aCharRect.Center();
1777cdf0e10cSrcweir                 pFrm->GetCrsrOfst( pShellCrsr->GetPoint(), rPt, &aTmpState );
1778cdf0e10cSrcweir             }
1779cdf0e10cSrcweir //          ALIGNRECT( aCharRect );
1780cdf0e10cSrcweir 
1781cdf0e10cSrcweir             if( !pShellCrsr->HasMark() )
1782cdf0e10cSrcweir                 aCrsrHeight = aTmpState.aRealHeight;
1783cdf0e10cSrcweir             else
1784cdf0e10cSrcweir             {
1785cdf0e10cSrcweir                 aCrsrHeight.X() = 0;
1786cdf0e10cSrcweir                 aCrsrHeight.Y() = aTmpState.aRealHeight.Y() < 0 ?
1787cdf0e10cSrcweir                                   -aCharRect.Width() : aCharRect.Height();
1788cdf0e10cSrcweir             }
1789cdf0e10cSrcweir         }
1790cdf0e10cSrcweir         else
1791cdf0e10cSrcweir         {
1792cdf0e10cSrcweir             aCrsrHeight.X() = 0;
1793cdf0e10cSrcweir             aCrsrHeight.Y() = aCharRect.Height();
1794cdf0e10cSrcweir         }
1795cdf0e10cSrcweir 
1796cdf0e10cSrcweir         if( !bFirst && aOld == aCharRect )
1797cdf0e10cSrcweir             break;
1798cdf0e10cSrcweir 
1799cdf0e10cSrcweir         // falls das Layout meint, nach dem 100 durchlauf ist man immer noch
1800cdf0e10cSrcweir         // im Fluss, sollte man die akt. Pos. als gegeben hinnehmen!
1801cdf0e10cSrcweir         // siehe Bug: 29658
1802cdf0e10cSrcweir         if( !--nLoopCnt )
1803cdf0e10cSrcweir         {
1804870262e3SDon Lewis             ASSERT( sal_False, "Endless loop? CharRect != OldCharRect ");
1805cdf0e10cSrcweir             break;
1806cdf0e10cSrcweir         }
1807cdf0e10cSrcweir         aOld = aCharRect;
1808cdf0e10cSrcweir         bFirst = sal_False;
1809cdf0e10cSrcweir 
1810cdf0e10cSrcweir         // Cursor-Points auf die neuen Positionen setzen
1811cdf0e10cSrcweir         pShellCrsr->GetPtPos().X() = aCharRect.Left();
1812cdf0e10cSrcweir         pShellCrsr->GetPtPos().Y() = aCharRect.Top();
1813cdf0e10cSrcweir 
1814cdf0e10cSrcweir         if( !(eFlags & SwCrsrShell::UPDOWN ))   // alte Pos. von Up/Down loeschen
1815cdf0e10cSrcweir         {
1816cdf0e10cSrcweir             pFrm->Calc();
1817cdf0e10cSrcweir             nUpDownX = pFrm->IsVertical() ?
1818cdf0e10cSrcweir                        aCharRect.Top() - pFrm->Frm().Top() :
1819cdf0e10cSrcweir                        aCharRect.Left() - pFrm->Frm().Left();
1820cdf0e10cSrcweir         }
1821cdf0e10cSrcweir 
1822cdf0e10cSrcweir         // Curosr in den sichtbaren Bereich scrollen
1823cdf0e10cSrcweir         if( bHasFocus && eFlags & SwCrsrShell::SCROLLWIN &&
1824cdf0e10cSrcweir             (HasSelection() || eFlags & SwCrsrShell::READONLY ||
1825cdf0e10cSrcweir              !IsCrsrReadonly() || GetViewOptions()->IsSelectionInReadonly()) )
1826cdf0e10cSrcweir         {
1827cdf0e10cSrcweir             //JP 30.04.99:  damit das EndAction, beim evtuellen Scrollen, den
1828cdf0e10cSrcweir             //      SV-Crsr nicht wieder sichtbar macht, wird hier das Flag
1829cdf0e10cSrcweir             //      gesichert und zurueckgesetzt.
1830cdf0e10cSrcweir             sal_Bool bSav = bSVCrsrVis; bSVCrsrVis = sal_False;
1831cdf0e10cSrcweir             MakeSelVisible();
1832cdf0e10cSrcweir             bSVCrsrVis = bSav;
1833cdf0e10cSrcweir         }
1834cdf0e10cSrcweir 
1835cdf0e10cSrcweir     } while( eFlags & SwCrsrShell::SCROLLWIN );
1836cdf0e10cSrcweir 
1837cdf0e10cSrcweir     if( pBlockCrsr )
1838cdf0e10cSrcweir         RefreshBlockCursor();
1839cdf0e10cSrcweir 
1840cdf0e10cSrcweir     if( !bIdleEnd && bHasFocus && !bBasicHideCrsr )
1841cdf0e10cSrcweir     {
1842cdf0e10cSrcweir         if( pTblCrsr )
1843cdf0e10cSrcweir             pTblCrsr->SwSelPaintRects::Show();
1844cdf0e10cSrcweir         else
1845cdf0e10cSrcweir         {
1846cdf0e10cSrcweir             pCurCrsr->SwSelPaintRects::Show();
1847cdf0e10cSrcweir             if( pBlockCrsr )
1848cdf0e10cSrcweir             {
1849cdf0e10cSrcweir                 SwShellCrsr* pNxt = dynamic_cast<SwShellCrsr*>(pCurCrsr->GetNext());
1850cdf0e10cSrcweir                 while( pNxt && pNxt != pCurCrsr )
1851cdf0e10cSrcweir                 {
1852cdf0e10cSrcweir                     pNxt->SwSelPaintRects::Show();
1853cdf0e10cSrcweir                     pNxt = dynamic_cast<SwShellCrsr*>(pNxt->GetNext());
1854cdf0e10cSrcweir                 }
1855cdf0e10cSrcweir             }
1856cdf0e10cSrcweir         }
1857cdf0e10cSrcweir     }
1858cdf0e10cSrcweir 
1859cdf0e10cSrcweir     eMvState = MV_NONE;     // Status fuers Crsr-Travelling - GetCrsrOfst
1860cdf0e10cSrcweir 
1861cdf0e10cSrcweir     if( pFrm && Imp()->IsAccessible() )
1862cdf0e10cSrcweir         Imp()->InvalidateAccessibleCursorPosition( pFrm );
1863cdf0e10cSrcweir 
1864cdf0e10cSrcweir     // switch from blinking cursor to read-only-text-selection cursor
1865cdf0e10cSrcweir     static const long nNoBlinkTime = STYLE_CURSOR_NOBLINKTIME;
1866cdf0e10cSrcweir     const long nBlinkTime = GetOut()->GetSettings().GetStyleSettings().
1867cdf0e10cSrcweir                             GetCursorBlinkTime();
1868cdf0e10cSrcweir 
1869cdf0e10cSrcweir     if ( (IsCrsrReadonly() && GetViewOptions()->IsSelectionInReadonly()) ==
1870cdf0e10cSrcweir         ( nBlinkTime != nNoBlinkTime ) )
1871cdf0e10cSrcweir     {
1872cdf0e10cSrcweir         // non blinking cursor in read only - text selection mode
1873cdf0e10cSrcweir         AllSettings aSettings = GetOut()->GetSettings();
1874cdf0e10cSrcweir         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1875cdf0e10cSrcweir         const long nNewBlinkTime = nBlinkTime == nNoBlinkTime ?
1876cdf0e10cSrcweir                                    Application::GetSettings().GetStyleSettings().GetCursorBlinkTime() :
1877cdf0e10cSrcweir                                    nNoBlinkTime;
1878cdf0e10cSrcweir         aStyleSettings.SetCursorBlinkTime( nNewBlinkTime );
1879cdf0e10cSrcweir         aSettings.SetStyleSettings( aStyleSettings );
1880cdf0e10cSrcweir         GetOut()->SetSettings( aSettings );
1881cdf0e10cSrcweir     }
1882cdf0e10cSrcweir 
1883cdf0e10cSrcweir     if( bSVCrsrVis )
1884cdf0e10cSrcweir         pVisCrsr->Show();           // wieder anzeigen
1885cdf0e10cSrcweir }
1886cdf0e10cSrcweir 
RefreshBlockCursor()1887cdf0e10cSrcweir void SwCrsrShell::RefreshBlockCursor()
1888cdf0e10cSrcweir {
1889cdf0e10cSrcweir     ASSERT( pBlockCrsr, "Don't call me without a block cursor" );
1890cdf0e10cSrcweir     SwShellCrsr &rBlock = pBlockCrsr->getShellCrsr();
1891cdf0e10cSrcweir     Point aPt = rBlock.GetPtPos();
1892cdf0e10cSrcweir     SwCntntFrm* pFrm = rBlock.GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, rBlock.GetPoint(), sal_False );
1893cdf0e10cSrcweir     Point aMk;
1894cdf0e10cSrcweir     if( pBlockCrsr->getEndPoint() && pBlockCrsr->getStartPoint() )
1895cdf0e10cSrcweir     {
1896cdf0e10cSrcweir         aPt = *pBlockCrsr->getStartPoint();
1897cdf0e10cSrcweir         aMk = *pBlockCrsr->getEndPoint();
1898cdf0e10cSrcweir     }
1899cdf0e10cSrcweir     else
1900cdf0e10cSrcweir     {
1901cdf0e10cSrcweir         aPt = rBlock.GetPtPos();
1902cdf0e10cSrcweir         if( pFrm )
1903cdf0e10cSrcweir         {
1904cdf0e10cSrcweir             if( pFrm->IsVertical() )
1905cdf0e10cSrcweir                 aPt.Y() = pFrm->Frm().Top() + GetUpDownX();
1906cdf0e10cSrcweir             else
1907cdf0e10cSrcweir                 aPt.X() = pFrm->Frm().Left() + GetUpDownX();
1908cdf0e10cSrcweir         }
1909cdf0e10cSrcweir         aMk = rBlock.GetMkPos();
1910cdf0e10cSrcweir     }
1911cdf0e10cSrcweir     SwRect aRect( aMk, aPt );
1912cdf0e10cSrcweir     aRect.Justify();
1913cdf0e10cSrcweir     SwSelectionList aSelList( pFrm );
1914cdf0e10cSrcweir 
1915cdf0e10cSrcweir     if( GetLayout()->FillSelection( aSelList, aRect ) )
1916cdf0e10cSrcweir     {
1917cdf0e10cSrcweir         SwCursor* pNxt = (SwCursor*)pCurCrsr->GetNext();
1918cdf0e10cSrcweir         while( pNxt != pCurCrsr )
1919cdf0e10cSrcweir         {
1920cdf0e10cSrcweir             delete pNxt;
1921cdf0e10cSrcweir             pNxt = (SwCursor*)pCurCrsr->GetNext();
1922cdf0e10cSrcweir         }
1923cdf0e10cSrcweir 
1924cdf0e10cSrcweir         std::list<SwPaM*>::iterator pStart = aSelList.getStart();
1925cdf0e10cSrcweir         std::list<SwPaM*>::iterator pPam = aSelList.getEnd();
1926cdf0e10cSrcweir         ASSERT( pPam != pStart, "FillSelection should deliver at least one PaM" )
1927cdf0e10cSrcweir         pCurCrsr->SetMark();
1928cdf0e10cSrcweir         --pPam;
1929cdf0e10cSrcweir         // If there is only one text portion inside the rectangle, a simple
1930cdf0e10cSrcweir         // selection is created
1931cdf0e10cSrcweir         if( pPam == pStart )
1932cdf0e10cSrcweir         {
1933cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *(*pPam)->GetPoint();
1934cdf0e10cSrcweir             if( (*pPam)->HasMark() )
1935cdf0e10cSrcweir                 *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1936cdf0e10cSrcweir             else
1937cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1938cdf0e10cSrcweir             delete *pPam;
1939cdf0e10cSrcweir             pCurCrsr->SetColumnSelection( false );
1940cdf0e10cSrcweir         }
1941cdf0e10cSrcweir         else
1942cdf0e10cSrcweir         {
1943cdf0e10cSrcweir             // The order of the SwSelectionList has to be preserved but
1944cdf0e10cSrcweir             // the order inside the ring created by CreateCrsr() is not like
1945*7de601c3SJohn Bampton             // expected => First create the selections before the last one
1946cdf0e10cSrcweir             // downto the first selection.
1947cdf0e10cSrcweir             // At least create the cursor for the last selection
1948cdf0e10cSrcweir             --pPam;
1949cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n-1 (if n == number of selections)
1950cdf0e10cSrcweir             if( (*pPam)->HasMark() )
1951cdf0e10cSrcweir                 *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1952cdf0e10cSrcweir             else
1953cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1954cdf0e10cSrcweir             delete *pPam;
1955cdf0e10cSrcweir             pCurCrsr->SetColumnSelection( true );
1956cdf0e10cSrcweir             while( pPam != pStart )
1957cdf0e10cSrcweir             {
1958cdf0e10cSrcweir                 --pPam;
1959cdf0e10cSrcweir 
1960cdf0e10cSrcweir                 SwShellCrsr* pNew = new SwShellCrsr( *pCurCrsr );
1961cdf0e10cSrcweir                 pNew->Insert( pCurCrsr, 0 );
1962cdf0e10cSrcweir                 pCurCrsr->Remove( 0, pCurCrsr->Count() );
1963cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1964cdf0e10cSrcweir 
1965cdf0e10cSrcweir                 *pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n-2, n-3, .., 2, 1
1966cdf0e10cSrcweir                 if( (*pPam)->HasMark() )
1967cdf0e10cSrcweir                 {
1968cdf0e10cSrcweir                     pCurCrsr->SetMark();
1969cdf0e10cSrcweir                     *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1970cdf0e10cSrcweir                 }
1971cdf0e10cSrcweir                 else
1972cdf0e10cSrcweir                     pCurCrsr->DeleteMark();
1973cdf0e10cSrcweir                 pCurCrsr->SetColumnSelection( true );
1974cdf0e10cSrcweir                 delete *pPam;
1975cdf0e10cSrcweir             }
1976cdf0e10cSrcweir             {
1977cdf0e10cSrcweir                 SwShellCrsr* pNew = new SwShellCrsr( *pCurCrsr );
1978cdf0e10cSrcweir                 pNew->Insert( pCurCrsr, 0 );
1979cdf0e10cSrcweir                 pCurCrsr->Remove( 0, pCurCrsr->Count() );
1980cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1981cdf0e10cSrcweir             }
1982cdf0e10cSrcweir             pPam = aSelList.getEnd();
1983cdf0e10cSrcweir             --pPam;
1984cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n, the last selection
1985cdf0e10cSrcweir             if( (*pPam)->HasMark() )
1986cdf0e10cSrcweir             {
1987cdf0e10cSrcweir                 pCurCrsr->SetMark();
1988cdf0e10cSrcweir                 *pCurCrsr->GetMark() = *(*pPam)->GetMark();
1989cdf0e10cSrcweir             }
1990cdf0e10cSrcweir             else
1991cdf0e10cSrcweir                 pCurCrsr->DeleteMark();
1992cdf0e10cSrcweir             pCurCrsr->SetColumnSelection( true );
1993cdf0e10cSrcweir             delete *pPam;
1994cdf0e10cSrcweir         }
1995cdf0e10cSrcweir     }
1996cdf0e10cSrcweir }
1997cdf0e10cSrcweir 
1998cdf0e10cSrcweir // erzeuge eine Kopie vom Cursor und speicher diese im Stack
1999cdf0e10cSrcweir 
2000cdf0e10cSrcweir 
Push()2001cdf0e10cSrcweir void SwCrsrShell::Push()
2002cdf0e10cSrcweir {
2003cdf0e10cSrcweir     pCrsrStk = new SwShellCrsr( *this, *pCurCrsr->GetPoint(),
2004cdf0e10cSrcweir                                     pCurCrsr->GetPtPos(), pCrsrStk );
2005cdf0e10cSrcweir 
2006cdf0e10cSrcweir     if( pCurCrsr->HasMark() )
2007cdf0e10cSrcweir     {
2008cdf0e10cSrcweir         pCrsrStk->SetMark();
2009cdf0e10cSrcweir         *pCrsrStk->GetMark() = *pCurCrsr->GetMark();
2010cdf0e10cSrcweir     }
2011cdf0e10cSrcweir }
2012cdf0e10cSrcweir 
2013cdf0e10cSrcweir /*
2014cdf0e10cSrcweir  *  Loescht einen Cursor (gesteuert durch bOldCrsr)
2015cdf0e10cSrcweir  *      - vom Stack oder    ( bOldCrsr = sal_True )
2016cdf0e10cSrcweir  *      - den aktuellen und der auf dem Stack stehende wird zum aktuellen
2017cdf0e10cSrcweir  *
2018cdf0e10cSrcweir  *  Return:  es war auf dem Stack noch einer vorhanden
2019cdf0e10cSrcweir  */
2020cdf0e10cSrcweir 
2021cdf0e10cSrcweir 
Pop(sal_Bool bOldCrsr)2022cdf0e10cSrcweir sal_Bool SwCrsrShell::Pop( sal_Bool bOldCrsr )
2023cdf0e10cSrcweir {
2024cdf0e10cSrcweir     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
2025cdf0e10cSrcweir 
2026cdf0e10cSrcweir     // noch weitere vorhanden ?
2027cdf0e10cSrcweir     if( 0 == pCrsrStk )
2028cdf0e10cSrcweir         return sal_False;
2029cdf0e10cSrcweir 
2030cdf0e10cSrcweir     SwShellCrsr *pTmp = 0, *pOldStk = pCrsrStk;
2031cdf0e10cSrcweir 
2032cdf0e10cSrcweir     // der Nachfolger wird der Aktuelle
2033cdf0e10cSrcweir     if( pCrsrStk->GetNext() != pCrsrStk )
2034cdf0e10cSrcweir     {
2035cdf0e10cSrcweir         pTmp = dynamic_cast<SwShellCrsr*>(pCrsrStk->GetNext());
2036cdf0e10cSrcweir     }
2037cdf0e10cSrcweir 
2038cdf0e10cSrcweir     if( bOldCrsr )              // loesche vom Stack
2039cdf0e10cSrcweir         delete pCrsrStk;        //
2040cdf0e10cSrcweir 
2041cdf0e10cSrcweir     pCrsrStk = pTmp;            // neu zuweisen
2042cdf0e10cSrcweir 
2043cdf0e10cSrcweir     if( !bOldCrsr )
2044cdf0e10cSrcweir     {
2045cdf0e10cSrcweir         SwCrsrSaveState aSaveState( *pCurCrsr );
2046cdf0e10cSrcweir 
2047cdf0e10cSrcweir         // wurde die sichtbare SSelection nicht veraendert
2048cdf0e10cSrcweir         if( pOldStk->GetPtPos() == pCurCrsr->GetPtPos() ||
2049cdf0e10cSrcweir             pOldStk->GetPtPos() == pCurCrsr->GetMkPos() )
2050cdf0e10cSrcweir         {
2051cdf0e10cSrcweir             // "Selektions-Rechtecke" verschieben
2052cdf0e10cSrcweir             pCurCrsr->Insert( pOldStk, 0 );
2053cdf0e10cSrcweir             pOldStk->Remove( 0, pOldStk->Count() );
2054cdf0e10cSrcweir         }
2055cdf0e10cSrcweir 
2056cdf0e10cSrcweir         if( pOldStk->HasMark() )
2057cdf0e10cSrcweir         {
2058cdf0e10cSrcweir             pCurCrsr->SetMark();
2059cdf0e10cSrcweir             *pCurCrsr->GetMark() = *pOldStk->GetMark();
2060cdf0e10cSrcweir             pCurCrsr->GetMkPos() = pOldStk->GetMkPos();
2061cdf0e10cSrcweir         }
2062cdf0e10cSrcweir         else
2063cdf0e10cSrcweir             // keine Selection also alte aufheben und auf die alte Pos setzen
2064cdf0e10cSrcweir             pCurCrsr->DeleteMark();
2065cdf0e10cSrcweir         *pCurCrsr->GetPoint() = *pOldStk->GetPoint();
2066cdf0e10cSrcweir         pCurCrsr->GetPtPos() = pOldStk->GetPtPos();
2067cdf0e10cSrcweir         delete pOldStk;
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir         if( !pCurCrsr->IsInProtectTable( sal_True ) &&
2070cdf0e10cSrcweir             !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
2071cdf0e10cSrcweir                                  nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
2072cdf0e10cSrcweir             UpdateCrsr();             // akt. Cursor Updaten
2073cdf0e10cSrcweir     }
2074cdf0e10cSrcweir     return sal_True;
2075cdf0e10cSrcweir }
2076cdf0e10cSrcweir 
2077cdf0e10cSrcweir /*
2078cdf0e10cSrcweir  * Verbinde zwei Cursor miteinander.
2079cdf0e10cSrcweir  * Loesche vom Stack den obersten und setzen dessen GetMark im Aktuellen.
2080cdf0e10cSrcweir  */
2081cdf0e10cSrcweir 
2082cdf0e10cSrcweir 
Combine()2083cdf0e10cSrcweir void SwCrsrShell::Combine()
2084cdf0e10cSrcweir {
2085cdf0e10cSrcweir     // noch weitere vorhanden ?
2086cdf0e10cSrcweir     if( 0 == pCrsrStk )
2087cdf0e10cSrcweir         return;
2088cdf0e10cSrcweir 
2089cdf0e10cSrcweir     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
2090cdf0e10cSrcweir     SwCrsrSaveState aSaveState( *pCurCrsr );
2091cdf0e10cSrcweir     if( pCrsrStk->HasMark() )           // nur wenn GetMark gesetzt wurde
2092cdf0e10cSrcweir     {
2093cdf0e10cSrcweir #ifndef DBG_UTIL
2094cdf0e10cSrcweir         CheckNodesRange( pCrsrStk->GetMark()->nNode, pCurCrsr->GetPoint()->nNode, sal_True );
2095cdf0e10cSrcweir #else
2096cdf0e10cSrcweir         if( !CheckNodesRange( pCrsrStk->GetMark()->nNode, pCurCrsr->GetPoint()->nNode, sal_True ))
2097870262e3SDon Lewis             ASSERT( sal_False, "StackCrsr & act. Crsr not in the same section." );
2098cdf0e10cSrcweir #endif
2099cdf0e10cSrcweir         // kopiere das GetMark
2100cdf0e10cSrcweir         if( !pCurCrsr->HasMark() )
2101cdf0e10cSrcweir             pCurCrsr->SetMark();
2102cdf0e10cSrcweir         *pCurCrsr->GetMark() = *pCrsrStk->GetMark();
2103cdf0e10cSrcweir         pCurCrsr->GetMkPos() = pCrsrStk->GetMkPos();
2104cdf0e10cSrcweir     }
2105cdf0e10cSrcweir 
2106cdf0e10cSrcweir     SwShellCrsr * pTmp = 0;
2107cdf0e10cSrcweir     if( pCrsrStk->GetNext() != pCrsrStk )
2108cdf0e10cSrcweir     {
2109cdf0e10cSrcweir         pTmp = dynamic_cast<SwShellCrsr*>(pCrsrStk->GetNext());
2110cdf0e10cSrcweir     }
2111cdf0e10cSrcweir     delete pCrsrStk;
2112cdf0e10cSrcweir     pCrsrStk = pTmp;
2113cdf0e10cSrcweir     if( !pCurCrsr->IsInProtectTable( sal_True ) &&
2114cdf0e10cSrcweir         !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
2115cdf0e10cSrcweir                              nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
2116cdf0e10cSrcweir         UpdateCrsr();             // akt. Cursor Updaten
2117cdf0e10cSrcweir }
2118cdf0e10cSrcweir 
2119cdf0e10cSrcweir 
HideCrsrs()2120cdf0e10cSrcweir void SwCrsrShell::HideCrsrs()
2121cdf0e10cSrcweir {
2122cdf0e10cSrcweir     if( !bHasFocus || bBasicHideCrsr )
2123cdf0e10cSrcweir         return;
2124cdf0e10cSrcweir 
2125cdf0e10cSrcweir     // ist Cursor sichtbar, dann verstecke den SV-Cursor
2126cdf0e10cSrcweir     if( pVisCrsr->IsVisible() )
2127cdf0e10cSrcweir     {
2128cdf0e10cSrcweir         SET_CURR_SHELL( this );
2129cdf0e10cSrcweir         pVisCrsr->Hide();
2130cdf0e10cSrcweir     }
2131cdf0e10cSrcweir     // hebe die Invertierung der SSelection auf
2132cdf0e10cSrcweir     SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
2133cdf0e10cSrcweir     pAktCrsr->Hide();
2134cdf0e10cSrcweir }
2135cdf0e10cSrcweir 
2136cdf0e10cSrcweir 
2137cdf0e10cSrcweir 
ShowCrsrs(sal_Bool bCrsrVis)2138cdf0e10cSrcweir void SwCrsrShell::ShowCrsrs( sal_Bool bCrsrVis )
2139cdf0e10cSrcweir {
2140cdf0e10cSrcweir     if( !bHasFocus || bAllProtect || bBasicHideCrsr )
2141cdf0e10cSrcweir         return;
2142cdf0e10cSrcweir 
2143cdf0e10cSrcweir     SET_CURR_SHELL( this );
2144cdf0e10cSrcweir     SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
2145cdf0e10cSrcweir     pAktCrsr->Show();
2146cdf0e10cSrcweir 
2147cdf0e10cSrcweir     if( bSVCrsrVis && bCrsrVis )    // auch SV-Cursor wieder anzeigen
2148cdf0e10cSrcweir         pVisCrsr->Show();
2149cdf0e10cSrcweir }
2150cdf0e10cSrcweir 
2151cdf0e10cSrcweir // Methoden zum Anzeigen bzw. Verstecken des sichtbaren Text-Cursors
2152cdf0e10cSrcweir 
2153cdf0e10cSrcweir 
ShowCrsr()2154cdf0e10cSrcweir void SwCrsrShell::ShowCrsr()
2155cdf0e10cSrcweir {
2156cdf0e10cSrcweir     if( !bBasicHideCrsr )
2157cdf0e10cSrcweir     {
2158cdf0e10cSrcweir         bSVCrsrVis = sal_True;
215969a74367SOliver-Rainer Wittmann         pCurCrsr->SetShowTxtInputFldOverlay( true );
2160cdf0e10cSrcweir         UpdateCrsr();
2161cdf0e10cSrcweir     }
2162cdf0e10cSrcweir }
2163cdf0e10cSrcweir 
2164cdf0e10cSrcweir 
HideCrsr()2165cdf0e10cSrcweir void SwCrsrShell::HideCrsr()
2166cdf0e10cSrcweir {
2167cdf0e10cSrcweir     if( !bBasicHideCrsr )
2168cdf0e10cSrcweir     {
2169cdf0e10cSrcweir         bSVCrsrVis = sal_False;
2170cdf0e10cSrcweir         // evt. die sel. Bereiche aufheben !!
2171cdf0e10cSrcweir         SET_CURR_SHELL( this );
217269a74367SOliver-Rainer Wittmann         pCurCrsr->SetShowTxtInputFldOverlay( false );
2173cdf0e10cSrcweir         pVisCrsr->Hide();
2174cdf0e10cSrcweir     }
2175cdf0e10cSrcweir }
2176cdf0e10cSrcweir 
2177cdf0e10cSrcweir 
ShLooseFcs()2178cdf0e10cSrcweir void SwCrsrShell::ShLooseFcs()
2179cdf0e10cSrcweir {
2180cdf0e10cSrcweir     if( !bBasicHideCrsr )
2181cdf0e10cSrcweir         HideCrsrs();
2182cdf0e10cSrcweir     bHasFocus = sal_False;
2183cdf0e10cSrcweir }
2184cdf0e10cSrcweir 
2185cdf0e10cSrcweir 
ShGetFcs(sal_Bool bUpdate)2186cdf0e10cSrcweir void SwCrsrShell::ShGetFcs( sal_Bool bUpdate )
2187cdf0e10cSrcweir {
2188cdf0e10cSrcweir     bHasFocus = sal_True;
2189cdf0e10cSrcweir     if( !bBasicHideCrsr && VisArea().Width() )
2190cdf0e10cSrcweir     {
2191cdf0e10cSrcweir         UpdateCrsr( static_cast<sal_uInt16>( bUpdate ?
2192cdf0e10cSrcweir                     SwCrsrShell::CHKRANGE|SwCrsrShell::SCROLLWIN
2193cdf0e10cSrcweir                     : SwCrsrShell::CHKRANGE ) );
2194cdf0e10cSrcweir         ShowCrsrs( bSVCrsrVis ? sal_True : sal_False );
2195cdf0e10cSrcweir     }
2196cdf0e10cSrcweir }
2197cdf0e10cSrcweir 
2198cdf0e10cSrcweir // gebe den aktuellen Frame, in dem der Cursor steht, zurueck
2199cdf0e10cSrcweir 
GetCurrFrm(const sal_Bool bCalcFrm) const2200cdf0e10cSrcweir SwCntntFrm *SwCrsrShell::GetCurrFrm( const sal_Bool bCalcFrm ) const
2201cdf0e10cSrcweir {
2202cdf0e10cSrcweir     SET_CURR_SHELL( (ViewShell*)this );
2203cdf0e10cSrcweir     SwCntntFrm *pRet = 0;
2204cdf0e10cSrcweir     SwCntntNode *pNd = pCurCrsr->GetCntntNode();
2205cdf0e10cSrcweir     if ( pNd )
2206cdf0e10cSrcweir     {
2207cdf0e10cSrcweir         if ( bCalcFrm )
2208cdf0e10cSrcweir         {
2209cdf0e10cSrcweir             const sal_uInt16* pST = &nStartAction;
2210cdf0e10cSrcweir             ++(*((sal_uInt16*)pST));
2211cdf0e10cSrcweir             const Size aOldSz( GetDocSize() );
2212cdf0e10cSrcweir             pRet = pNd->getLayoutFrm( GetLayout(), &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() );
2213cdf0e10cSrcweir             --(*((sal_uInt16*)pST));
2214cdf0e10cSrcweir             if( aOldSz != GetDocSize() )
2215cdf0e10cSrcweir                 ((SwCrsrShell*)this)->SizeChgNotify();
2216cdf0e10cSrcweir         }
2217cdf0e10cSrcweir         else
2218cdf0e10cSrcweir             pRet = pNd->getLayoutFrm( GetLayout(), &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint(), sal_False);
2219cdf0e10cSrcweir     }
2220cdf0e10cSrcweir     return pRet;
2221cdf0e10cSrcweir }
2222cdf0e10cSrcweir 
2223cdf0e10cSrcweir 
2224cdf0e10cSrcweir // alle Attribut/Format-Aenderungen am akt. Node werden an den
2225cdf0e10cSrcweir // Link weitergeleitet.
2226cdf0e10cSrcweir 
2227cdf0e10cSrcweir 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)2228cdf0e10cSrcweir void SwCrsrShell::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
2229cdf0e10cSrcweir {
2230cdf0e10cSrcweir     const sal_uInt16 nWhich = pOld ?
2231cdf0e10cSrcweir                           pOld->Which() :
2232cdf0e10cSrcweir                           pNew ?
2233cdf0e10cSrcweir                           pNew->Which() :
2234cdf0e10cSrcweir                           sal::static_int_cast<sal_uInt16>(RES_MSG_BEGIN);
2235cdf0e10cSrcweir 
2236cdf0e10cSrcweir     if( bCallChgLnk &&
2237cdf0e10cSrcweir         ( nWhich < RES_MSG_BEGIN || nWhich >= RES_MSG_END ||
2238cdf0e10cSrcweir             nWhich == RES_FMT_CHG || nWhich == RES_UPDATE_ATTR ||
2239cdf0e10cSrcweir             nWhich == RES_ATTRSET_CHG ))
2240cdf0e10cSrcweir         // die Messages werden nicht weitergemeldet
2241cdf0e10cSrcweir         //MA 07. Apr. 94 fix(6681): RES_UPDATE_ATTR wird implizit vom
2242cdf0e10cSrcweir         //SwTxtNode::Insert(SwTxtHint*, sal_uInt16) abgesetzt; hier wird reagiert und
2243cdf0e10cSrcweir         //vom Insert brauch nicht mehr die Keule RES_FMT_CHG versandt werden.
2244cdf0e10cSrcweir         CallChgLnk();
2245cdf0e10cSrcweir 
2246cdf0e10cSrcweir     if( aGrfArrivedLnk.IsSet() &&
2247cdf0e10cSrcweir         ( RES_GRAPHIC_ARRIVED == nWhich || RES_GRAPHIC_SWAPIN == nWhich ))
2248cdf0e10cSrcweir         aGrfArrivedLnk.Call( this );
2249cdf0e10cSrcweir }
2250cdf0e10cSrcweir 
2251cdf0e10cSrcweir 
2252cdf0e10cSrcweir // Abfrage, ob der aktuelle Cursor eine Selektion aufspannt,
2253cdf0e10cSrcweir // also, ob GetMark gesetzt und SPoint und GetMark unterschiedlich sind.
2254cdf0e10cSrcweir 
2255cdf0e10cSrcweir 
HasSelection() const2256cdf0e10cSrcweir sal_Bool SwCrsrShell::HasSelection() const
2257cdf0e10cSrcweir {
2258cdf0e10cSrcweir     const SwPaM* pCrsr = getShellCrsr( true );
2259cdf0e10cSrcweir     return( IsTableMode() || ( pCrsr->HasMark() &&
2260cdf0e10cSrcweir             *pCrsr->GetPoint() != *pCrsr->GetMark())
2261cdf0e10cSrcweir         ? sal_True : sal_False );
2262cdf0e10cSrcweir }
2263cdf0e10cSrcweir 
2264cdf0e10cSrcweir 
CallChgLnk()2265cdf0e10cSrcweir void SwCrsrShell::CallChgLnk()
2266cdf0e10cSrcweir {
2267cdf0e10cSrcweir     // innerhalb von Start-/End-Action kein Call, sondern nur merken,
2268cdf0e10cSrcweir     // das sich etwas geaendert hat. Wird bei EndAction beachtet.
2269cdf0e10cSrcweir     if( BasicActionPend() )
2270cdf0e10cSrcweir         bChgCallFlag = sal_True;        // das Change merken
2271cdf0e10cSrcweir     else if( aChgLnk.IsSet() )
2272cdf0e10cSrcweir     {
2273cdf0e10cSrcweir         if( bCallChgLnk )
2274cdf0e10cSrcweir             aChgLnk.Call( this );
2275cdf0e10cSrcweir         bChgCallFlag = sal_False;       // Flag zuruecksetzen
2276cdf0e10cSrcweir     }
2277cdf0e10cSrcweir }
2278cdf0e10cSrcweir 
2279cdf0e10cSrcweir // returne den am akt.Cursor selektierten Text eines Nodes.
2280cdf0e10cSrcweir 
2281cdf0e10cSrcweir 
GetSelTxt() const2282cdf0e10cSrcweir String SwCrsrShell::GetSelTxt() const
2283cdf0e10cSrcweir {
2284cdf0e10cSrcweir     String aTxt;
2285cdf0e10cSrcweir     if( pCurCrsr->GetPoint()->nNode.GetIndex() ==
2286cdf0e10cSrcweir         pCurCrsr->GetMark()->nNode.GetIndex() )
2287cdf0e10cSrcweir     {
2288cdf0e10cSrcweir         SwTxtNode* pTxtNd = pCurCrsr->GetNode()->GetTxtNode();
2289cdf0e10cSrcweir         if( pTxtNd )
2290cdf0e10cSrcweir         {
2291cdf0e10cSrcweir             xub_StrLen nStt = pCurCrsr->Start()->nContent.GetIndex();
2292cdf0e10cSrcweir             aTxt = pTxtNd->GetExpandTxt( nStt,
2293cdf0e10cSrcweir                     pCurCrsr->End()->nContent.GetIndex() - nStt );
2294cdf0e10cSrcweir         }
2295cdf0e10cSrcweir     }
2296cdf0e10cSrcweir     return aTxt;
2297cdf0e10cSrcweir }
2298cdf0e10cSrcweir 
2299cdf0e10cSrcweir // gebe nur den Text ab der akt. Cursor Position zurueck (bis zum NodeEnde)
2300cdf0e10cSrcweir 
2301cdf0e10cSrcweir 
GetText() const2302cdf0e10cSrcweir String SwCrsrShell::GetText() const
2303cdf0e10cSrcweir {
2304cdf0e10cSrcweir     String aTxt;
2305cdf0e10cSrcweir     if( pCurCrsr->GetPoint()->nNode.GetIndex() ==
2306cdf0e10cSrcweir         pCurCrsr->GetMark()->nNode.GetIndex() )
2307cdf0e10cSrcweir     {
2308cdf0e10cSrcweir         SwTxtNode* pTxtNd = pCurCrsr->GetNode()->GetTxtNode();
2309cdf0e10cSrcweir         if( pTxtNd )
2310cdf0e10cSrcweir             aTxt = pTxtNd->GetTxt().Copy(
2311cdf0e10cSrcweir                     pCurCrsr->GetPoint()->nContent.GetIndex() );
2312cdf0e10cSrcweir     }
2313cdf0e10cSrcweir     return aTxt;
2314cdf0e10cSrcweir }
2315cdf0e10cSrcweir 
2316cdf0e10cSrcweir // hole vom Start/Ende der akt. SSelection das nte Zeichen
GetChar(sal_Bool bEnd,long nOffset)2317cdf0e10cSrcweir sal_Unicode SwCrsrShell::GetChar( sal_Bool bEnd, long nOffset )
2318cdf0e10cSrcweir {
2319cdf0e10cSrcweir     if( IsTableMode() )         // im TabelleMode nicht moeglich
2320cdf0e10cSrcweir         return 0;
2321cdf0e10cSrcweir 
2322cdf0e10cSrcweir     const SwPosition* pPos = !pCurCrsr->HasMark() ? pCurCrsr->GetPoint()
2323cdf0e10cSrcweir                                 : bEnd ? pCurCrsr->End() : pCurCrsr->Start();
2324cdf0e10cSrcweir     SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
2325cdf0e10cSrcweir     if( !pTxtNd )
2326cdf0e10cSrcweir         return 0;
2327cdf0e10cSrcweir 
2328cdf0e10cSrcweir     xub_StrLen nPos = pPos->nContent.GetIndex();
2329cdf0e10cSrcweir     const String& rStr = pTxtNd->GetTxt();
2330cdf0e10cSrcweir     sal_Unicode cCh = 0;
2331cdf0e10cSrcweir 
2332cdf0e10cSrcweir     if( ((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.Len() )
2333cdf0e10cSrcweir         cCh = rStr.GetChar( static_cast<xub_StrLen>(nPos+nOffset) );
2334cdf0e10cSrcweir 
2335cdf0e10cSrcweir     return cCh;
2336cdf0e10cSrcweir }
2337cdf0e10cSrcweir 
2338cdf0e10cSrcweir // erweiter die akt. SSelection am Anfang/Ende um n Zeichen
2339cdf0e10cSrcweir 
2340cdf0e10cSrcweir 
ExtendSelection(sal_Bool bEnd,xub_StrLen nCount)2341cdf0e10cSrcweir sal_Bool SwCrsrShell::ExtendSelection( sal_Bool bEnd, xub_StrLen nCount )
2342cdf0e10cSrcweir {
2343cdf0e10cSrcweir     if( !pCurCrsr->HasMark() || IsTableMode() )
2344cdf0e10cSrcweir         return sal_False;           // keine Selektion
2345cdf0e10cSrcweir 
2346cdf0e10cSrcweir     SwPosition* pPos = bEnd ? pCurCrsr->End() : pCurCrsr->Start();
2347cdf0e10cSrcweir     SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
2348cdf0e10cSrcweir     ASSERT( pTxtNd, "kein TextNode, wie soll erweitert werden?" );
2349cdf0e10cSrcweir 
2350cdf0e10cSrcweir     xub_StrLen nPos = pPos->nContent.GetIndex();
2351cdf0e10cSrcweir     if( bEnd )
2352cdf0e10cSrcweir     {
2353cdf0e10cSrcweir         if( ( nPos + nCount ) <= pTxtNd->GetTxt().Len() )
2354cdf0e10cSrcweir             nPos = nPos + nCount;
2355cdf0e10cSrcweir         else
2356cdf0e10cSrcweir             return sal_False;       // nicht mehr moeglich
2357cdf0e10cSrcweir     }
2358cdf0e10cSrcweir     else if( nPos >= nCount )
2359cdf0e10cSrcweir         nPos = nPos - nCount;
2360cdf0e10cSrcweir     else
2361cdf0e10cSrcweir         return sal_False;           // nicht mehr moeglich
2362cdf0e10cSrcweir 
2363cdf0e10cSrcweir     SwCallLink aLk( *this );    // Crsr-Moves ueberwachen,
2364cdf0e10cSrcweir 
2365cdf0e10cSrcweir     pPos->nContent = nPos;
2366cdf0e10cSrcweir     UpdateCrsr();
2367cdf0e10cSrcweir 
2368cdf0e10cSrcweir     return sal_True;
2369cdf0e10cSrcweir }
2370cdf0e10cSrcweir 
2371cdf0e10cSrcweir // setze nur den sichtbaren Cursor an die angegebene Dokument-Pos.
2372cdf0e10cSrcweir // returnt sal_False: wenn der SPoint vom Layout korrigiert wurde.
2373cdf0e10cSrcweir 
SetVisCrsr(const Point & rPt)2374cdf0e10cSrcweir sal_Bool SwCrsrShell::SetVisCrsr( const Point &rPt )
2375cdf0e10cSrcweir {
2376cdf0e10cSrcweir     SET_CURR_SHELL( this );
2377cdf0e10cSrcweir     Point aPt( rPt );
2378cdf0e10cSrcweir     SwPosition aPos( *pCurCrsr->GetPoint() );
2379cdf0e10cSrcweir     SwCrsrMoveState aTmpState( MV_SETONLYTEXT );
2380cdf0e10cSrcweir     aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
2381cdf0e10cSrcweir     aTmpState.bRealHeight = sal_True;
2382cdf0e10cSrcweir 
2383cdf0e10cSrcweir     sal_Bool bRet = GetLayout()->GetCrsrOfst( &aPos, aPt /*, &aTmpState*/ );
2384cdf0e10cSrcweir 
2385cdf0e10cSrcweir     SetInFrontOfLabel( sal_False ); // #i27615#
2386cdf0e10cSrcweir 
2387cdf0e10cSrcweir     // nur in TextNodes anzeigen !!
2388cdf0e10cSrcweir     SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode();
2389cdf0e10cSrcweir     if( !pTxtNd )
2390cdf0e10cSrcweir         return sal_False;
2391cdf0e10cSrcweir 
2392cdf0e10cSrcweir     const SwSectionNode* pSectNd = pTxtNd->FindSectionNode();
2393cdf0e10cSrcweir     if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() ||
2394cdf0e10cSrcweir                     ( !IsReadOnlyAvailable() &&
2395cdf0e10cSrcweir                       pSectNd->GetSection().IsProtectFlag())) )
2396cdf0e10cSrcweir         return sal_False;
2397cdf0e10cSrcweir 
2398cdf0e10cSrcweir     SwCntntFrm *pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt, &aPos );
2399cdf0e10cSrcweir     if ( Imp()->IsIdleAction() )
2400cdf0e10cSrcweir         pFrm->PrepareCrsr();
2401cdf0e10cSrcweir     SwRect aTmp( aCharRect );
2402cdf0e10cSrcweir 
2403cdf0e10cSrcweir     pFrm->GetCharRect( aCharRect, aPos, &aTmpState );
2404cdf0e10cSrcweir //  ALIGNRECT( aCharRect );
2405cdf0e10cSrcweir 
2406cdf0e10cSrcweir     if( aTmp == aCharRect &&        // BUG 10137: bleibt der Cursor auf der
2407cdf0e10cSrcweir         pVisCrsr->IsVisible() )     // Position nicht hidden & showen
2408cdf0e10cSrcweir         return sal_True;
2409cdf0e10cSrcweir 
2410cdf0e10cSrcweir     pVisCrsr->Hide();       // sichtbaren Cursor immer verstecken
2411cdf0e10cSrcweir     if( IsScrollMDI( this, aCharRect ))
2412cdf0e10cSrcweir     {
2413cdf0e10cSrcweir         MakeVisible( aCharRect );
2414cdf0e10cSrcweir         pCurCrsr->Show();
2415cdf0e10cSrcweir     }
2416cdf0e10cSrcweir 
2417cdf0e10cSrcweir     // Bug 29584: bei Rahmenselektion ist der Cursor versteckt, aber den
2418cdf0e10cSrcweir     //          D&D-Cursor will man trotzdem haben
2419cdf0e10cSrcweir //  if( bSVCrsrVis )
2420cdf0e10cSrcweir     {
2421cdf0e10cSrcweir         if( aTmpState.bRealHeight )
2422cdf0e10cSrcweir             aCrsrHeight = aTmpState.aRealHeight;
2423cdf0e10cSrcweir         else
2424cdf0e10cSrcweir         {
2425cdf0e10cSrcweir             aCrsrHeight.X() = 0;
2426cdf0e10cSrcweir             aCrsrHeight.Y() = aCharRect.Height();
2427cdf0e10cSrcweir         }
2428cdf0e10cSrcweir 
2429cdf0e10cSrcweir         pVisCrsr->SetDragCrsr( sal_True );
2430cdf0e10cSrcweir         pVisCrsr->Show();           // wieder anzeigen
2431cdf0e10cSrcweir     }
2432cdf0e10cSrcweir     return bRet;
2433cdf0e10cSrcweir }
2434cdf0e10cSrcweir 
IsOverReadOnlyPos(const Point & rPt) const2435cdf0e10cSrcweir sal_Bool SwCrsrShell::IsOverReadOnlyPos( const Point& rPt ) const
2436cdf0e10cSrcweir {
2437cdf0e10cSrcweir     Point aPt( rPt );
2438cdf0e10cSrcweir     SwPaM aPam( *pCurCrsr->GetPoint() );
2439cdf0e10cSrcweir     GetLayout()->GetCrsrOfst( aPam.GetPoint(), aPt );
2440cdf0e10cSrcweir     return aPam.HasReadonlySel( GetViewOptions()->IsFormView() );
2441cdf0e10cSrcweir }
2442cdf0e10cSrcweir 
2443cdf0e10cSrcweir 
2444cdf0e10cSrcweir     // returne die Anzahl der Cursor im Ring (Flag besagt ob man nur
2445cdf0e10cSrcweir     // aufgepspannte haben will - sprich etwas selektiert ist (Basic))
GetCrsrCnt(sal_Bool bAll) const2446cdf0e10cSrcweir sal_uInt16 SwCrsrShell::GetCrsrCnt( sal_Bool bAll ) const
2447cdf0e10cSrcweir {
2448cdf0e10cSrcweir     Ring* pTmp = GetCrsr()->GetNext();
2449cdf0e10cSrcweir     sal_uInt16 n = (bAll || ( pCurCrsr->HasMark() &&
2450cdf0e10cSrcweir                     *pCurCrsr->GetPoint() != *pCurCrsr->GetMark())) ? 1 : 0;
2451cdf0e10cSrcweir     while( pTmp != pCurCrsr )
2452cdf0e10cSrcweir     {
2453cdf0e10cSrcweir         if( bAll || ( ((SwPaM*)pTmp)->HasMark() &&
2454cdf0e10cSrcweir                 *((SwPaM*)pTmp)->GetPoint() != *((SwPaM*)pTmp)->GetMark()))
2455cdf0e10cSrcweir             ++n;
2456cdf0e10cSrcweir         pTmp = pTmp->GetNext();
2457cdf0e10cSrcweir     }
2458cdf0e10cSrcweir     return n;
2459cdf0e10cSrcweir }
2460cdf0e10cSrcweir 
2461cdf0e10cSrcweir 
IsStartOfDoc() const2462cdf0e10cSrcweir sal_Bool SwCrsrShell::IsStartOfDoc() const
2463cdf0e10cSrcweir {
2464cdf0e10cSrcweir     if( pCurCrsr->GetPoint()->nContent.GetIndex() )
2465cdf0e10cSrcweir         return sal_False;
2466cdf0e10cSrcweir 
2467cdf0e10cSrcweir     // Hinter EndOfIcons kommt die Content-Section (EndNd+StNd+CntntNd)
2468cdf0e10cSrcweir     SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfExtras(), 2 );
2469cdf0e10cSrcweir     if( !aIdx.GetNode().IsCntntNode() )
2470cdf0e10cSrcweir         GetDoc()->GetNodes().GoNext( &aIdx );
2471cdf0e10cSrcweir     return aIdx == pCurCrsr->GetPoint()->nNode;
2472cdf0e10cSrcweir }
2473cdf0e10cSrcweir 
2474cdf0e10cSrcweir 
IsEndOfDoc() const2475cdf0e10cSrcweir sal_Bool SwCrsrShell::IsEndOfDoc() const
2476cdf0e10cSrcweir {
2477cdf0e10cSrcweir     SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfContent(), -1 );
2478cdf0e10cSrcweir     SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
2479cdf0e10cSrcweir     if( !pCNd )
2480cdf0e10cSrcweir         pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx );
2481cdf0e10cSrcweir 
2482cdf0e10cSrcweir     return aIdx == pCurCrsr->GetPoint()->nNode &&
2483cdf0e10cSrcweir             pCNd->Len() == pCurCrsr->GetPoint()->nContent.GetIndex();
2484cdf0e10cSrcweir }
2485cdf0e10cSrcweir 
2486cdf0e10cSrcweir 
2487cdf0e10cSrcweir // loesche alle erzeugten Crsr, setze den Tabellen-Crsr und den letzten
2488cdf0e10cSrcweir // Cursor auf seinen TextNode (oder StartNode?).
2489cdf0e10cSrcweir // Beim naechsten ::GetCrsr werden sie wieder alle erzeugt
2490cdf0e10cSrcweir // Wird fuers Drag&Drop / ClipBorad-Paste in Tabellen benoetigt.
ParkTblCrsr()2491cdf0e10cSrcweir sal_Bool SwCrsrShell::ParkTblCrsr()
2492cdf0e10cSrcweir {
2493cdf0e10cSrcweir     if( !pTblCrsr )
2494cdf0e10cSrcweir         return sal_False;
2495cdf0e10cSrcweir 
2496cdf0e10cSrcweir     pTblCrsr->ParkCrsr();
2497cdf0e10cSrcweir 
2498cdf0e10cSrcweir     while( pCurCrsr->GetNext() != pCurCrsr )
2499cdf0e10cSrcweir         delete pCurCrsr->GetNext();
2500cdf0e10cSrcweir 
2501cdf0e10cSrcweir     // vom Cursor !immer! SPoint und Mark umsetzen
2502cdf0e10cSrcweir     pCurCrsr->SetMark();
2503cdf0e10cSrcweir     *pCurCrsr->GetMark() = *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint();
2504cdf0e10cSrcweir     pCurCrsr->DeleteMark();
2505cdf0e10cSrcweir 
2506cdf0e10cSrcweir     return sal_True;
2507cdf0e10cSrcweir }
2508cdf0e10cSrcweir 
2509cdf0e10cSrcweir /***********************************************************************
2510cdf0e10cSrcweir #*  Class       :  SwCrsrShell
2511cdf0e10cSrcweir #*  Methode     :  ParkCrsr
2512cdf0e10cSrcweir #*  Beschreibung:  Vernichtet Selektionen und zus. Crsr aller Shell der
2513cdf0e10cSrcweir #*                 verbleibende Crsr der Shell wird geparkt.
2514cdf0e10cSrcweir #*  Datum       :  MA 05. Nov. 92
2515cdf0e10cSrcweir #*  Update      :  JP 19.09.97
2516cdf0e10cSrcweir #***********************************************************************/
2517cdf0e10cSrcweir 
_ParkPams(SwPaM * pDelRg,SwShellCrsr ** ppDelRing)2518cdf0e10cSrcweir void SwCrsrShell::_ParkPams( SwPaM* pDelRg, SwShellCrsr** ppDelRing )
2519cdf0e10cSrcweir {
2520cdf0e10cSrcweir     const SwPosition *pStt = pDelRg->Start(),
2521cdf0e10cSrcweir         *pEnd = pDelRg->GetPoint() == pStt ? pDelRg->GetMark() : pDelRg->GetPoint();
2522cdf0e10cSrcweir 
2523cdf0e10cSrcweir     SwPaM *pTmpDel = 0, *pTmp = *ppDelRing;
2524cdf0e10cSrcweir 
2525cdf0e10cSrcweir     // durchsuche den gesamten Ring
2526cdf0e10cSrcweir     sal_Bool bGoNext;
2527cdf0e10cSrcweir     do {
2528cdf0e10cSrcweir         const SwPosition *pTmpStt = pTmp->Start(),
2529cdf0e10cSrcweir                         *pTmpEnd = pTmp->GetPoint() == pTmpStt ?
2530cdf0e10cSrcweir                                         pTmp->GetMark() : pTmp->GetPoint();
2531cdf0e10cSrcweir         /*
2532cdf0e10cSrcweir          * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich
2533cdf0e10cSrcweir          * muss der alte Bereich aufgehoben werden.
2534cdf0e10cSrcweir          * Beim Vergleich ist darauf zu achten, das End() nicht mehr zum
2535cdf0e10cSrcweir          * Bereich gehoert !
2536cdf0e10cSrcweir          */
2537cdf0e10cSrcweir         if( *pStt <= *pTmpStt )
2538cdf0e10cSrcweir         {
2539cdf0e10cSrcweir             if( *pEnd > *pTmpStt ||
2540cdf0e10cSrcweir                 ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
2541cdf0e10cSrcweir                 pTmpDel = pTmp;
2542cdf0e10cSrcweir         }
2543cdf0e10cSrcweir         else
2544cdf0e10cSrcweir             if( *pStt < *pTmpEnd )
2545cdf0e10cSrcweir                 pTmpDel = pTmp;
2546cdf0e10cSrcweir 
2547cdf0e10cSrcweir         bGoNext = sal_True;
2548cdf0e10cSrcweir         if( pTmpDel )           // ist der Pam im Bereich ?? loesche ihn
2549cdf0e10cSrcweir         {
2550cdf0e10cSrcweir             sal_Bool bDelete = sal_True;
2551cdf0e10cSrcweir             if( *ppDelRing == pTmpDel )
2552cdf0e10cSrcweir             {
2553cdf0e10cSrcweir                 if( *ppDelRing == pCurCrsr )
2554cdf0e10cSrcweir                 {
2555cdf0e10cSrcweir                     if( sal_True == ( bDelete = GoNextCrsr() ))
2556cdf0e10cSrcweir                     {
2557cdf0e10cSrcweir                         bGoNext = sal_False;
2558cdf0e10cSrcweir                         pTmp = (SwPaM*)pTmp->GetNext();
2559cdf0e10cSrcweir                     }
2560cdf0e10cSrcweir                 }
2561cdf0e10cSrcweir                 else
2562cdf0e10cSrcweir                     bDelete = sal_False;        // StackCrsr nie loeschen !!
2563cdf0e10cSrcweir             }
2564cdf0e10cSrcweir 
2565cdf0e10cSrcweir             if( bDelete )
2566cdf0e10cSrcweir                 delete pTmpDel;         // hebe alten Bereich auf
2567cdf0e10cSrcweir             else
2568cdf0e10cSrcweir             {
2569cdf0e10cSrcweir                 pTmpDel->GetPoint()->nContent.Assign( 0, 0 );
2570cdf0e10cSrcweir                 pTmpDel->GetPoint()->nNode = 0;
2571cdf0e10cSrcweir                 pTmpDel->SetMark();
2572cdf0e10cSrcweir                 pTmpDel->DeleteMark();
2573cdf0e10cSrcweir             }
2574cdf0e10cSrcweir             pTmpDel = 0;
2575cdf0e10cSrcweir         }
2576cdf0e10cSrcweir         else if( !pTmp->HasMark() )     // sorge auf jedenfall dafuer, das
2577cdf0e10cSrcweir         {                       // nicht benutzte Indizies beachtet werden!
2578cdf0e10cSrcweir             pTmp->SetMark();            // SPoint liegt nicht im Bereich,
2579cdf0e10cSrcweir             pTmp->DeleteMark();         // aber vielleicht GetMark, also setzen
2580cdf0e10cSrcweir         }
2581cdf0e10cSrcweir         if( bGoNext )
2582cdf0e10cSrcweir             pTmp = (SwPaM*)pTmp->GetNext();
2583cdf0e10cSrcweir     } while( !bGoNext || *ppDelRing != pTmp );
2584cdf0e10cSrcweir }
2585cdf0e10cSrcweir 
ParkCrsr(const SwNodeIndex & rIdx)2586cdf0e10cSrcweir void SwCrsrShell::ParkCrsr( const SwNodeIndex &rIdx )
2587cdf0e10cSrcweir {
2588cdf0e10cSrcweir     SwNode *pNode = &rIdx.GetNode();
2589cdf0e10cSrcweir 
2590cdf0e10cSrcweir     // erzeuge einen neuen Pam
2591cdf0e10cSrcweir     SwPaM * pNew = new SwPaM( *GetCrsr()->GetPoint() );
2592cdf0e10cSrcweir     if( pNode->GetStartNode() )
2593cdf0e10cSrcweir     {
2594cdf0e10cSrcweir         if( ( pNode = pNode->StartOfSectionNode())->IsTableNode() )
2595cdf0e10cSrcweir         {
2596cdf0e10cSrcweir             // der angegebene Node steht in einer Tabelle, also Parke
2597cdf0e10cSrcweir             // den Crsr auf dem Tabellen-Node (ausserhalb der Tabelle)
2598cdf0e10cSrcweir             pNew->GetPoint()->nNode = *pNode->StartOfSectionNode();
2599cdf0e10cSrcweir         }
2600cdf0e10cSrcweir         else    // also auf dem StartNode selbst.
2601cdf0e10cSrcweir                 // Dann immer ueber seinen EndNode den StartNode erfragen !!!
2602cdf0e10cSrcweir                 // (StartOfSection vom StartNode ist der Parent !)
2603cdf0e10cSrcweir             pNew->GetPoint()->nNode = *pNode->EndOfSectionNode()->StartOfSectionNode();
2604cdf0e10cSrcweir     }
2605cdf0e10cSrcweir     else
2606cdf0e10cSrcweir         pNew->GetPoint()->nNode = *pNode->StartOfSectionNode();
2607cdf0e10cSrcweir     pNew->SetMark();
2608cdf0e10cSrcweir     pNew->GetPoint()->nNode = *pNode->EndOfSectionNode();
2609cdf0e10cSrcweir 
2610cdf0e10cSrcweir     //Alle Shells wollen etwas davon haben.
2611cdf0e10cSrcweir     ViewShell *pTmp = this;
2612cdf0e10cSrcweir     do {
2613cdf0e10cSrcweir         if( pTmp->IsA( TYPE( SwCrsrShell )))
2614cdf0e10cSrcweir         {
2615cdf0e10cSrcweir             SwCrsrShell* pSh = (SwCrsrShell*)pTmp;
2616cdf0e10cSrcweir             if( pSh->pCrsrStk )
2617cdf0e10cSrcweir                 pSh->_ParkPams( pNew, &pSh->pCrsrStk );
2618cdf0e10cSrcweir 
2619cdf0e10cSrcweir             pSh->_ParkPams( pNew, &pSh->pCurCrsr );
2620cdf0e10cSrcweir             if( pSh->pTblCrsr )
2621cdf0e10cSrcweir             {
2622cdf0e10cSrcweir                 // setze den Tabellen Cursor immer auf 0, den aktuellen
2623cdf0e10cSrcweir                 // immer auf den Anfang der Tabelle
2624cdf0e10cSrcweir                 SwPaM* pTCrsr = pSh->GetTblCrs();
2625cdf0e10cSrcweir                 SwNode* pTblNd = pTCrsr->GetPoint()->nNode.GetNode().FindTableNode();
2626cdf0e10cSrcweir                 if ( pTblNd )
2627cdf0e10cSrcweir                 {
2628cdf0e10cSrcweir                     pTCrsr->GetPoint()->nContent.Assign( 0, 0 );
2629cdf0e10cSrcweir                     pTCrsr->GetPoint()->nNode = 0;
2630cdf0e10cSrcweir                     pTCrsr->SetMark();
2631cdf0e10cSrcweir                     pTCrsr->DeleteMark();
2632cdf0e10cSrcweir                     pSh->pCurCrsr->GetPoint()->nNode = *pTblNd;
2633cdf0e10cSrcweir                 }
2634cdf0e10cSrcweir             }
2635cdf0e10cSrcweir         }
2636cdf0e10cSrcweir     } while ( this != (pTmp = (ViewShell*)pTmp->GetNext() ));
2637cdf0e10cSrcweir     delete pNew;
2638cdf0e10cSrcweir }
2639cdf0e10cSrcweir 
2640cdf0e10cSrcweir //=========================================================================
2641cdf0e10cSrcweir 
2642cdf0e10cSrcweir /*
2643cdf0e10cSrcweir  * der Copy-Constructor
2644cdf0e10cSrcweir  * Cursor-Position kopieren, in den Ring eingetragen.
2645cdf0e10cSrcweir  * Alle Ansichten eines Dokumentes stehen im Ring der Shells.
2646cdf0e10cSrcweir  */
2647cdf0e10cSrcweir 
SwCrsrShell(SwCrsrShell & rShell,Window * pInitWin)2648cdf0e10cSrcweir SwCrsrShell::SwCrsrShell( SwCrsrShell& rShell, Window *pInitWin )
2649cdf0e10cSrcweir     : ViewShell( rShell, pInitWin ),
2650cdf0e10cSrcweir     SwModify( 0 ), pCrsrStk( 0 ), pBlockCrsr( 0 ), pTblCrsr( 0 ),
2651cdf0e10cSrcweir     pBoxIdx( 0 ), pBoxPtr( 0 ), nCrsrMove( 0 ), nBasicActionCnt( 0 ),
2652cdf0e10cSrcweir     eMvState( MV_NONE ),
2653cdf0e10cSrcweir     // --> OD 2008-04-02 #refactorlists#
2654cdf0e10cSrcweir     sMarkedListId(),
2655cdf0e10cSrcweir     nMarkedListLevel( 0 )
2656cdf0e10cSrcweir     // <--
2657cdf0e10cSrcweir {
2658cdf0e10cSrcweir     SET_CURR_SHELL( this );
2659cdf0e10cSrcweir     // Nur die Position vom aktuellen Cursor aus der Copy-Shell uebernehmen
2660cdf0e10cSrcweir     pCurCrsr = new SwShellCrsr( *this, *(rShell.pCurCrsr->GetPoint()) );
2661cdf0e10cSrcweir     pCurCrsr->GetCntntNode()->Add( this );
2662cdf0e10cSrcweir 
2663cdf0e10cSrcweir     bAllProtect = bVisPortChgd = bChgCallFlag = bInCMvVisportChgd =
2664cdf0e10cSrcweir     bGCAttr = bIgnoreReadonly = bSelTblCells = bBasicHideCrsr =
2665cdf0e10cSrcweir     bOverwriteCrsr = sal_False;
2666cdf0e10cSrcweir     bCallChgLnk = bHasFocus = bSVCrsrVis = bAutoUpdateCells = sal_True;
2667cdf0e10cSrcweir     bSetCrsrInReadOnly = sal_True;
2668cdf0e10cSrcweir     pVisCrsr = new SwVisCrsr( this );
2669cdf0e10cSrcweir //  UpdateCrsr( 0 );
2670cdf0e10cSrcweir     // OD 11.02.2003 #100556#
2671cdf0e10cSrcweir     mbMacroExecAllowed = rShell.IsMacroExecAllowed();
2672ca62e2c2SSteve Yin     oldColFrm = NULL;
2673cdf0e10cSrcweir }
2674cdf0e10cSrcweir 
2675cdf0e10cSrcweir 
2676cdf0e10cSrcweir /*
2677cdf0e10cSrcweir  * der normale Constructor
2678cdf0e10cSrcweir  */
2679cdf0e10cSrcweir 
SwCrsrShell(SwDoc & rDoc,Window * pInitWin,const SwViewOption * pInitOpt)2680cdf0e10cSrcweir SwCrsrShell::SwCrsrShell( SwDoc& rDoc, Window *pInitWin,
2681cdf0e10cSrcweir                             const SwViewOption *pInitOpt )
2682cdf0e10cSrcweir     : ViewShell( rDoc, pInitWin, pInitOpt ),
2683cdf0e10cSrcweir     SwModify( 0 ), pCrsrStk( 0 ), pBlockCrsr( 0 ), pTblCrsr( 0 ),
2684cdf0e10cSrcweir     pBoxIdx( 0 ), pBoxPtr( 0 ), nCrsrMove( 0 ), nBasicActionCnt( 0 ),
2685cdf0e10cSrcweir     eMvState( MV_NONE ), // state for crsr-travelling - GetCrsrOfst
2686cdf0e10cSrcweir     // --> OD 2008-04-02 #refactorlists#
2687cdf0e10cSrcweir     sMarkedListId(),
2688cdf0e10cSrcweir     nMarkedListLevel( 0 )
2689cdf0e10cSrcweir     // <--
2690cdf0e10cSrcweir {
2691cdf0e10cSrcweir     SET_CURR_SHELL( this );
2692cdf0e10cSrcweir     /*
2693cdf0e10cSrcweir      * Erzeugen des initialen Cursors, wird auf die erste
2694cdf0e10cSrcweir      * Inhaltsposition gesetzt
2695cdf0e10cSrcweir      */
2696cdf0e10cSrcweir     SwNodes& rNds = rDoc.GetNodes();
2697cdf0e10cSrcweir 
2698cdf0e10cSrcweir     SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
2699cdf0e10cSrcweir     SwCntntNode* pCNd = rNds.GoNext( &aNodeIdx ); // gehe zum 1. ContentNode
2700cdf0e10cSrcweir 
2701cdf0e10cSrcweir     pCurCrsr = new SwShellCrsr( *this, SwPosition( aNodeIdx, SwIndex( pCNd, 0 )));
2702cdf0e10cSrcweir 
2703cdf0e10cSrcweir     // melde die Shell beim akt. Node als abhaengig an, dadurch koennen alle
2704cdf0e10cSrcweir     // Attribut-Aenderungen ueber den Link weiter gemeldet werden.
2705cdf0e10cSrcweir     pCNd->Add( this );
2706cdf0e10cSrcweir 
2707cdf0e10cSrcweir     bAllProtect = bVisPortChgd = bChgCallFlag = bInCMvVisportChgd =
2708cdf0e10cSrcweir     bGCAttr = bIgnoreReadonly = bSelTblCells = bBasicHideCrsr =
2709cdf0e10cSrcweir     bOverwriteCrsr = sal_False;
2710cdf0e10cSrcweir     bCallChgLnk = bHasFocus = bSVCrsrVis = bAutoUpdateCells = sal_True;
2711cdf0e10cSrcweir     bSetCrsrInReadOnly = sal_True;
2712cdf0e10cSrcweir 
2713cdf0e10cSrcweir     pVisCrsr = new SwVisCrsr( this );
2714cdf0e10cSrcweir //  UpdateCrsr( 0 );
2715cdf0e10cSrcweir     // OD 11.02.2003 #100556#
2716cdf0e10cSrcweir     mbMacroExecAllowed = true;
2717cdf0e10cSrcweir }
2718cdf0e10cSrcweir 
2719cdf0e10cSrcweir 
2720cdf0e10cSrcweir 
~SwCrsrShell()2721cdf0e10cSrcweir SwCrsrShell::~SwCrsrShell()
2722cdf0e10cSrcweir {
2723cdf0e10cSrcweir     // wenn es nicht die letzte View so sollte zu mindest das
2724cdf0e10cSrcweir     // Feld noch geupdatet werden.
2725cdf0e10cSrcweir     if( GetNext() != this )
2726cdf0e10cSrcweir         CheckTblBoxCntnt( pCurCrsr->GetPoint() );
2727cdf0e10cSrcweir     else
2728cdf0e10cSrcweir         ClearTblBoxCntnt();
2729cdf0e10cSrcweir 
2730cdf0e10cSrcweir     delete pVisCrsr;
2731cdf0e10cSrcweir     delete pBlockCrsr;
2732cdf0e10cSrcweir     delete pTblCrsr;
2733cdf0e10cSrcweir 
2734cdf0e10cSrcweir     /*
2735cdf0e10cSrcweir      * Freigabe der Cursor
2736cdf0e10cSrcweir      */
2737cdf0e10cSrcweir     while(pCurCrsr->GetNext() != pCurCrsr)
2738cdf0e10cSrcweir         delete pCurCrsr->GetNext();
2739cdf0e10cSrcweir     delete pCurCrsr;
2740cdf0e10cSrcweir 
2741cdf0e10cSrcweir     // Stack freigeben
2742cdf0e10cSrcweir     if( pCrsrStk )
2743cdf0e10cSrcweir     {
2744cdf0e10cSrcweir         while( pCrsrStk->GetNext() != pCrsrStk )
2745cdf0e10cSrcweir             delete pCrsrStk->GetNext();
2746cdf0e10cSrcweir         delete pCrsrStk;
2747cdf0e10cSrcweir     }
2748cdf0e10cSrcweir 
2749cdf0e10cSrcweir     // JP 27.07.98: Bug 54025 - ggfs. den HTML-Parser, der als Client in
2750cdf0e10cSrcweir     //              der CursorShell haengt keine Chance geben, sich an den
2751cdf0e10cSrcweir     //              TextNode zu haengen.
2752cdf0e10cSrcweir     if( GetRegisteredIn() )
2753cdf0e10cSrcweir         GetRegisteredInNonConst()->Remove( this );
2754cdf0e10cSrcweir }
2755cdf0e10cSrcweir 
getShellCrsr(bool bBlock)2756cdf0e10cSrcweir SwShellCrsr* SwCrsrShell::getShellCrsr( bool bBlock )
2757cdf0e10cSrcweir {
2758cdf0e10cSrcweir     if( pTblCrsr )
2759cdf0e10cSrcweir         return pTblCrsr;
2760cdf0e10cSrcweir     if( pBlockCrsr && bBlock )
2761cdf0e10cSrcweir         return &pBlockCrsr->getShellCrsr();
2762cdf0e10cSrcweir     return pCurCrsr;
2763cdf0e10cSrcweir }
2764cdf0e10cSrcweir 
2765cdf0e10cSrcweir //Sollte fuer das Clipboard der WaitPtr geschaltet werden?
2766cdf0e10cSrcweir //Warten bei TableMode, Mehrfachselektion und mehr als x Selektieren Absaetzen.
2767cdf0e10cSrcweir 
ShouldWait() const2768cdf0e10cSrcweir sal_Bool SwCrsrShell::ShouldWait() const
2769cdf0e10cSrcweir {
2770cdf0e10cSrcweir     if ( IsTableMode() || GetCrsrCnt() > 1 )
2771cdf0e10cSrcweir         return sal_True;
2772cdf0e10cSrcweir 
2773cdf0e10cSrcweir     if( HasDrawView() && GetDrawView()->GetMarkedObjectList().GetMarkCount() )
2774cdf0e10cSrcweir         return sal_True;
2775cdf0e10cSrcweir 
2776cdf0e10cSrcweir     SwPaM* pPam = GetCrsr();
2777cdf0e10cSrcweir     return pPam->Start()->nNode.GetIndex() + 10 <
2778cdf0e10cSrcweir             pPam->End()->nNode.GetIndex();
2779cdf0e10cSrcweir }
2780cdf0e10cSrcweir 
2781cdf0e10cSrcweir 
UpdateTblSelBoxes()2782cdf0e10cSrcweir sal_uInt16 SwCrsrShell::UpdateTblSelBoxes()
2783cdf0e10cSrcweir {
2784cdf0e10cSrcweir     if( pTblCrsr && ( pTblCrsr->IsChgd() || !pTblCrsr->GetBoxesCount() ))
2785cdf0e10cSrcweir          GetLayout()->MakeTblCrsrs( *pTblCrsr );
2786cdf0e10cSrcweir     return pTblCrsr ? pTblCrsr->GetBoxesCount() : 0;
2787cdf0e10cSrcweir }
2788cdf0e10cSrcweir 
2789cdf0e10cSrcweir // zeige das akt. selektierte "Object" an
MakeSelVisible()2790cdf0e10cSrcweir void SwCrsrShell::MakeSelVisible()
2791cdf0e10cSrcweir {
2792cdf0e10cSrcweir     ASSERT( bHasFocus, "kein Focus aber Cursor sichtbar machen?" );
2793cdf0e10cSrcweir     if( aCrsrHeight.Y() < aCharRect.Height() && aCharRect.Height() > VisArea().Height() )
2794cdf0e10cSrcweir     {
2795cdf0e10cSrcweir         SwRect aTmp( aCharRect );
2796cdf0e10cSrcweir         long nDiff = aCharRect.Height() - VisArea().Height();
2797cdf0e10cSrcweir         if( nDiff < aCrsrHeight.X() )
2798cdf0e10cSrcweir             aTmp.Top( nDiff + aCharRect.Top() );
2799cdf0e10cSrcweir         else
2800cdf0e10cSrcweir         {
2801cdf0e10cSrcweir             aTmp.Top( aCrsrHeight.X() + aCharRect.Top() );
2802cdf0e10cSrcweir             aTmp.Height( aCrsrHeight.Y() );
2803cdf0e10cSrcweir         }
2804cdf0e10cSrcweir         if( !aTmp.HasArea() )
2805cdf0e10cSrcweir         {
2806cdf0e10cSrcweir             aTmp.SSize().Height() += 1;
2807cdf0e10cSrcweir             aTmp.SSize().Width() += 1;
2808cdf0e10cSrcweir         }
2809cdf0e10cSrcweir         MakeVisible( aTmp );
2810cdf0e10cSrcweir     }
2811cdf0e10cSrcweir     else
2812cdf0e10cSrcweir     {
2813cdf0e10cSrcweir         if( aCharRect.HasArea() )
2814cdf0e10cSrcweir             MakeVisible( aCharRect );
2815cdf0e10cSrcweir         else
2816cdf0e10cSrcweir         {
2817cdf0e10cSrcweir             SwRect aTmp( aCharRect );
2818cdf0e10cSrcweir             aTmp.SSize().Height() += 1; aTmp.SSize().Width() += 1;
2819cdf0e10cSrcweir             MakeVisible( aTmp );
2820cdf0e10cSrcweir         }
2821cdf0e10cSrcweir     }
2822cdf0e10cSrcweir }
2823cdf0e10cSrcweir 
2824cdf0e10cSrcweir 
2825cdf0e10cSrcweir // suche eine gueltige ContentPosition (nicht geschuetzt/nicht versteckt)
FindValidCntntNode(sal_Bool bOnlyText)2826cdf0e10cSrcweir sal_Bool SwCrsrShell::FindValidCntntNode( sal_Bool bOnlyText )
2827cdf0e10cSrcweir {
2828cdf0e10cSrcweir     if( pTblCrsr )      // was soll ich jetzt machen ??
2829cdf0e10cSrcweir     {
2830870262e3SDon Lewis         ASSERT( sal_False, "Table Selection not canceled!" );
2831cdf0e10cSrcweir         return sal_False;
2832cdf0e10cSrcweir     }
2833cdf0e10cSrcweir 
2834cdf0e10cSrcweir     //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt
2835cdf0e10cSrcweir     if( !bAllProtect && GetDoc()->GetDocShell() &&
2836cdf0e10cSrcweir         GetDoc()->GetDocShell()->IsReadOnlyUI() )
2837cdf0e10cSrcweir         return sal_True;
2838cdf0e10cSrcweir 
2839cdf0e10cSrcweir     // dann raus da!
2840cdf0e10cSrcweir     if( pCurCrsr->HasMark() )
2841cdf0e10cSrcweir         ClearMark();
2842cdf0e10cSrcweir 
2843cdf0e10cSrcweir     // als erstes mal auf Rahmen abpruefen
2844cdf0e10cSrcweir     SwNodeIndex& rNdIdx = pCurCrsr->GetPoint()->nNode;
2845cdf0e10cSrcweir     sal_uLong nNdIdx = rNdIdx.GetIndex();       // sichern
2846cdf0e10cSrcweir     SwNodes& rNds = pDoc->GetNodes();
2847cdf0e10cSrcweir     SwCntntNode* pCNd = rNdIdx.GetNode().GetCntntNode();
2848cdf0e10cSrcweir     const SwCntntFrm * pFrm;
2849cdf0e10cSrcweir 
2850cdf0e10cSrcweir     if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( GetLayout(),0,pCurCrsr->GetPoint(),sal_False)) &&
2851cdf0e10cSrcweir         !IsReadOnlyAvailable() && pFrm->IsProtected() &&
2852cdf0e10cSrcweir         nNdIdx < rNds.GetEndOfExtras().GetIndex() )
2853cdf0e10cSrcweir     {
2854cdf0e10cSrcweir         // geschuetzter Rahmen ueberspringen
2855cdf0e10cSrcweir         SwPaM aPam( *pCurCrsr->GetPoint() );
2856cdf0e10cSrcweir         aPam.SetMark();
2857cdf0e10cSrcweir         aPam.GetMark()->nNode = rNds.GetEndOfContent();
2858cdf0e10cSrcweir         aPam.GetPoint()->nNode = *pCNd->EndOfSectionNode();
2859cdf0e10cSrcweir 
2860cdf0e10cSrcweir         sal_Bool bFirst = sal_False;
2861cdf0e10cSrcweir         if( 0 == (pCNd = ::GetNode( aPam, bFirst, fnMoveForward, sal_False )))
2862cdf0e10cSrcweir         {
2863cdf0e10cSrcweir             aPam.GetMark()->nNode = *rNds.GetEndOfPostIts().StartOfSectionNode();
2864cdf0e10cSrcweir             pCNd = ::GetNode( aPam, bFirst, fnMoveBackward, sal_False );
2865cdf0e10cSrcweir         }
2866cdf0e10cSrcweir 
2867cdf0e10cSrcweir         if( !pCNd )     // sollte nie passieren !!!
2868cdf0e10cSrcweir         {
2869cdf0e10cSrcweir             rNdIdx = nNdIdx;        // alten Node zurueck
2870cdf0e10cSrcweir             return sal_False;
2871cdf0e10cSrcweir         }
2872cdf0e10cSrcweir         *pCurCrsr->GetPoint() = *aPam.GetPoint();
2873cdf0e10cSrcweir     }
2874cdf0e10cSrcweir     else if( bOnlyText && pCNd && pCNd->IsNoTxtNode() )
2875cdf0e10cSrcweir     {
2876cdf0e10cSrcweir         // dann auf den Anfang vom Doc stellen
2877cdf0e10cSrcweir         rNdIdx = pDoc->GetNodes().GetEndOfExtras();
2878cdf0e10cSrcweir         pCurCrsr->GetPoint()->nContent.Assign( pDoc->GetNodes().GoNext(
2879cdf0e10cSrcweir                                                             &rNdIdx ), 0 );
2880cdf0e10cSrcweir         nNdIdx = rNdIdx.GetIndex();
2881cdf0e10cSrcweir     }
2882cdf0e10cSrcweir 
2883cdf0e10cSrcweir     sal_Bool bOk = sal_True;
2884cdf0e10cSrcweir 
2885cdf0e10cSrcweir     // #i9059# cursor may not stand in protected cells
2886cdf0e10cSrcweir     //         (unless cursor in protected areas is OK.)
2887cdf0e10cSrcweir     const SwTableNode* pTableNode = rNdIdx.GetNode().FindTableNode();
2888cdf0e10cSrcweir     if( !IsReadOnlyAvailable()  &&
2889cdf0e10cSrcweir         pTableNode != NULL  &&  rNdIdx.GetNode().IsProtect() )
2890cdf0e10cSrcweir     {
2891cdf0e10cSrcweir         // we're in a table, and we're in a protected area, so we're
2892cdf0e10cSrcweir         // probably in a protected cell.
2893cdf0e10cSrcweir 
2894cdf0e10cSrcweir         // move forward into non-protected area.
2895cdf0e10cSrcweir         SwPaM aPam( rNdIdx.GetNode(), 0 );
2896cdf0e10cSrcweir         while( aPam.GetNode()->IsProtect() &&
2897cdf0e10cSrcweir                aPam.Move( fnMoveForward, fnGoCntnt ) )
2898cdf0e10cSrcweir             ; // nothing to do in the loop; the aPam.Move does the moving!
2899cdf0e10cSrcweir 
2900cdf0e10cSrcweir         // didn't work? then go backwards!
2901cdf0e10cSrcweir         if( aPam.GetNode()->IsProtect() )
2902cdf0e10cSrcweir         {
2903cdf0e10cSrcweir             SwPaM aTmpPaM( rNdIdx.GetNode(), 0 );
2904cdf0e10cSrcweir             aPam = aTmpPaM;
2905cdf0e10cSrcweir             while( aPam.GetNode()->IsProtect() &&
2906cdf0e10cSrcweir                    aPam.Move( fnMoveBackward, fnGoCntnt ) )
2907cdf0e10cSrcweir                 ; // nothing to do in the loop; the aPam.Move does the moving!
2908cdf0e10cSrcweir         }
2909cdf0e10cSrcweir 
2910cdf0e10cSrcweir         // if we're successful, set the new position
2911cdf0e10cSrcweir         if( ! aPam.GetNode()->IsProtect() )
2912cdf0e10cSrcweir         {
2913cdf0e10cSrcweir             *pCurCrsr->GetPoint() = *aPam.GetPoint();
2914cdf0e10cSrcweir         }
2915cdf0e10cSrcweir     }
2916cdf0e10cSrcweir 
2917cdf0e10cSrcweir     // in einem geschuetzten Bereich
2918cdf0e10cSrcweir     const SwSectionNode* pSectNd = rNdIdx.GetNode().FindSectionNode();
2919cdf0e10cSrcweir     if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
2920cdf0e10cSrcweir         ( !IsReadOnlyAvailable() &&
2921cdf0e10cSrcweir            pSectNd->GetSection().IsProtectFlag() )) )
2922cdf0e10cSrcweir     {
2923cdf0e10cSrcweir         typedef SwCntntNode* (SwNodes:: *FNGoSection)( SwNodeIndex *, int, int ) const;
2924cdf0e10cSrcweir         FNGoSection funcGoSection = &SwNodes::GoNextSection;
2925cdf0e10cSrcweir 
2926cdf0e10cSrcweir         bOk = sal_False;
2927cdf0e10cSrcweir 
2928cdf0e10cSrcweir         for( int nLoopCnt = 0; !bOk && nLoopCnt < 2; ++nLoopCnt )
2929cdf0e10cSrcweir         {
2930cdf0e10cSrcweir             sal_Bool bWeiter;
2931cdf0e10cSrcweir             do {
2932cdf0e10cSrcweir                 bWeiter = sal_False;
2933cdf0e10cSrcweir                 while( 0 != ( pCNd = (rNds.*funcGoSection)( &rNdIdx,
2934cdf0e10cSrcweir                                             sal_True, !IsReadOnlyAvailable() )) )
2935cdf0e10cSrcweir                 {
2936cdf0e10cSrcweir                     // in eine Tabelle verschoben -> pruefe ob die
2937cdf0e10cSrcweir                     // vielleicht geschuetzt ist
2938cdf0e10cSrcweir                     if( pCNd->FindTableNode() )
2939cdf0e10cSrcweir                     {
2940cdf0e10cSrcweir                         SwCallLink aTmp( *this );
2941cdf0e10cSrcweir                         SwCrsrSaveState aSaveState( *pCurCrsr );
2942cdf0e10cSrcweir                         aTmp.nNdTyp = 0;        // im DTOR nichts machen!
2943cdf0e10cSrcweir                         if( !pCurCrsr->IsInProtectTable( sal_True, sal_True ) )
2944cdf0e10cSrcweir                         {
2945cdf0e10cSrcweir                             const SwSectionNode* pSNd = pCNd->FindSectionNode();
2946cdf0e10cSrcweir                             if( !pSNd || !pSNd->GetSection().IsHiddenFlag()
2947cdf0e10cSrcweir                                 || (!IsReadOnlyAvailable()  &&
2948cdf0e10cSrcweir                                     pSNd->GetSection().IsProtectFlag() ))
2949cdf0e10cSrcweir                             {
2950cdf0e10cSrcweir                                 bOk = sal_True;
2951cdf0e10cSrcweir                                 break;      // eine nicht geschuetzte Zelle gef.
2952cdf0e10cSrcweir                             }
2953cdf0e10cSrcweir                             continue;       // dann weiter suchen
2954cdf0e10cSrcweir                         }
2955cdf0e10cSrcweir                     }
2956cdf0e10cSrcweir                     else
2957cdf0e10cSrcweir                     {
2958cdf0e10cSrcweir                         bOk = sal_True;
2959cdf0e10cSrcweir                         break;      // eine nicht geschuetzte Zelle gef.
2960cdf0e10cSrcweir                     }
2961cdf0e10cSrcweir                 }
2962cdf0e10cSrcweir 
2963cdf0e10cSrcweir                 if( bOk && rNdIdx.GetIndex() < rNds.GetEndOfExtras().GetIndex() )
2964cdf0e10cSrcweir                 {
2965cdf0e10cSrcweir                     // Teste mal auf Fly - kann auch noch geschuetzt sein!!
2966cdf0e10cSrcweir                     if( 0 == (pFrm = pCNd->getLayoutFrm( GetLayout(),0,0,sal_False)) ||
2967cdf0e10cSrcweir                         ( !IsReadOnlyAvailable() && pFrm->IsProtected() ) ||
2968cdf0e10cSrcweir                         ( bOnlyText && pCNd->IsNoTxtNode() ) )
2969cdf0e10cSrcweir                     {
2970cdf0e10cSrcweir                         // dann weiter suchen!
2971cdf0e10cSrcweir                         bOk = sal_False;
2972cdf0e10cSrcweir                         bWeiter = sal_True;
2973cdf0e10cSrcweir                     }
2974cdf0e10cSrcweir                 }
2975cdf0e10cSrcweir             } while( bWeiter );
2976cdf0e10cSrcweir 
2977cdf0e10cSrcweir             if( !bOk )
2978cdf0e10cSrcweir             {
2979cdf0e10cSrcweir                 if( !nLoopCnt )
2980cdf0e10cSrcweir                     funcGoSection = &SwNodes::GoPrevSection;
2981cdf0e10cSrcweir                 rNdIdx = nNdIdx;
2982cdf0e10cSrcweir             }
2983cdf0e10cSrcweir         }
2984cdf0e10cSrcweir     }
2985cdf0e10cSrcweir     if( bOk )
2986cdf0e10cSrcweir     {
2987cdf0e10cSrcweir         pCNd = rNdIdx.GetNode().GetCntntNode();
2988cdf0e10cSrcweir //      sal_uInt16 nCntnt = Min( pCNd->Len(), pCurCrsr->GetPoint()->nContent.GetIndex() );
2989cdf0e10cSrcweir         xub_StrLen nCntnt = rNdIdx.GetIndex() < nNdIdx ? pCNd->Len() : 0;
2990cdf0e10cSrcweir         pCurCrsr->GetPoint()->nContent.Assign( pCNd, nCntnt );
2991cdf0e10cSrcweir     }
2992cdf0e10cSrcweir     else
2993cdf0e10cSrcweir     {
2994cdf0e10cSrcweir         pCNd = rNdIdx.GetNode().GetCntntNode();
2995cdf0e10cSrcweir 
2996cdf0e10cSrcweir         // falls Cursor im versteckten Bereich ist, auf jedenfall schon mal
2997cdf0e10cSrcweir         // verschieben!!
2998cdf0e10cSrcweir         if( !pCNd || !pCNd->getLayoutFrm( GetLayout(),0,0,sal_False) )
2999cdf0e10cSrcweir         {
3000cdf0e10cSrcweir             SwCrsrMoveState aTmpState( MV_NONE );
3001cdf0e10cSrcweir             aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
3002cdf0e10cSrcweir             GetLayout()->GetCrsrOfst( pCurCrsr->GetPoint(), pCurCrsr->GetPtPos(),
3003cdf0e10cSrcweir                                         &aTmpState );
3004cdf0e10cSrcweir         }
3005cdf0e10cSrcweir     }
3006cdf0e10cSrcweir     return bOk;
3007cdf0e10cSrcweir }
3008cdf0e10cSrcweir 
3009cdf0e10cSrcweir 
IsCrsrReadonly() const3010cdf0e10cSrcweir sal_Bool SwCrsrShell::IsCrsrReadonly() const
3011cdf0e10cSrcweir {
3012cdf0e10cSrcweir     if ( GetViewOptions()->IsReadonly() ||
301369a74367SOliver-Rainer Wittmann          GetViewOptions()->IsFormView() ) // Formular view
3014cdf0e10cSrcweir     {
3015cdf0e10cSrcweir         SwFrm *pFrm = GetCurrFrm( sal_False );
3016cdf0e10cSrcweir         const SwFlyFrm* pFly;
3017cdf0e10cSrcweir         const SwSection* pSection;
3018cdf0e10cSrcweir 
3019cdf0e10cSrcweir         if( pFrm && pFrm->IsInFly() &&
3020cdf0e10cSrcweir             (pFly = pFrm->FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
3021cdf0e10cSrcweir             pFly->Lower() &&
3022cdf0e10cSrcweir             !pFly->Lower()->IsNoTxtFrm() &&
3023cdf0e10cSrcweir             !GetDrawView()->GetMarkedObjectList().GetMarkCount() )
3024cdf0e10cSrcweir         {
3025cdf0e10cSrcweir             return sal_False;
3026cdf0e10cSrcweir         }
302769a74367SOliver-Rainer Wittmann         // edit in readonly sections
3028cdf0e10cSrcweir         else if ( pFrm && pFrm->IsInSct() &&
3029cdf0e10cSrcweir             0 != ( pSection = pFrm->FindSctFrm()->GetSection() ) &&
3030cdf0e10cSrcweir             pSection->IsEditInReadonlyFlag() )
3031cdf0e10cSrcweir         {
3032cdf0e10cSrcweir             return sal_False;
3033cdf0e10cSrcweir         }
303469a74367SOliver-Rainer Wittmann         else if ( !IsMultiSelection() && CrsrInsideInputFld() )
303569a74367SOliver-Rainer Wittmann         {
303669a74367SOliver-Rainer Wittmann             return sal_False;
303769a74367SOliver-Rainer Wittmann         }
3038cdf0e10cSrcweir 
3039cdf0e10cSrcweir         return sal_True;
3040cdf0e10cSrcweir     }
3041cdf0e10cSrcweir     return sal_False;
3042cdf0e10cSrcweir }
3043cdf0e10cSrcweir 
3044cdf0e10cSrcweir 
3045cdf0e10cSrcweir // darf der Cursor in ReadOnlyBereiche?
SetReadOnlyAvailable(sal_Bool bFlag)3046cdf0e10cSrcweir void SwCrsrShell::SetReadOnlyAvailable( sal_Bool bFlag )
3047cdf0e10cSrcweir {
3048cdf0e10cSrcweir     // im GlobalDoc darf NIE umgeschaltet werden
3049cdf0e10cSrcweir     if( (!GetDoc()->GetDocShell() ||
3050cdf0e10cSrcweir          !GetDoc()->GetDocShell()->IsA( SwGlobalDocShell::StaticType() )) &&
3051cdf0e10cSrcweir         bFlag != bSetCrsrInReadOnly )
3052cdf0e10cSrcweir     {
3053cdf0e10cSrcweir         // wenn das Flag ausgeschaltet wird, dann muessen erstmal alle
3054cdf0e10cSrcweir         // Selektionen aufgehoben werden. Denn sonst wird sich darauf
3055cdf0e10cSrcweir         // verlassen, das nichts geschuetztes selektiert ist!
3056cdf0e10cSrcweir         if( !bFlag )
3057cdf0e10cSrcweir         {
3058cdf0e10cSrcweir             ClearMark();
3059cdf0e10cSrcweir         }
3060cdf0e10cSrcweir         bSetCrsrInReadOnly = bFlag;
3061cdf0e10cSrcweir         UpdateCrsr();
3062cdf0e10cSrcweir     }
3063cdf0e10cSrcweir }
3064cdf0e10cSrcweir 
HasReadonlySel() const3065cdf0e10cSrcweir sal_Bool SwCrsrShell::HasReadonlySel() const
3066cdf0e10cSrcweir {
3067cdf0e10cSrcweir     sal_Bool bRet = sal_False;
306823d8f725SOliver-Rainer Wittmann     if ( IsReadOnlyAvailable() || GetViewOptions()->IsFormView() )
3069cdf0e10cSrcweir     {
307023d8f725SOliver-Rainer Wittmann         if ( pTblCrsr != NULL )
307123d8f725SOliver-Rainer Wittmann         {
307223d8f725SOliver-Rainer Wittmann             bRet = pTblCrsr->HasReadOnlyBoxSel()
307323d8f725SOliver-Rainer Wittmann                    || pTblCrsr->HasReadonlySel( GetViewOptions()->IsFormView() );
307423d8f725SOliver-Rainer Wittmann         }
3075cdf0e10cSrcweir         else
3076cdf0e10cSrcweir         {
3077cdf0e10cSrcweir             const SwPaM* pCrsr = pCurCrsr;
3078cdf0e10cSrcweir 
307923d8f725SOliver-Rainer Wittmann             do
308023d8f725SOliver-Rainer Wittmann             {
308123d8f725SOliver-Rainer Wittmann                 if ( pCrsr->HasReadonlySel( GetViewOptions()->IsFormView() ) )
308223d8f725SOliver-Rainer Wittmann                 {
3083cdf0e10cSrcweir                     bRet = sal_True;
308423d8f725SOliver-Rainer Wittmann                 }
308523d8f725SOliver-Rainer Wittmann 
308623d8f725SOliver-Rainer Wittmann                 pCrsr = (SwPaM*)pCrsr->GetNext();
308723d8f725SOliver-Rainer Wittmann             } while ( !bRet && pCrsr != pCurCrsr );
3088cdf0e10cSrcweir         }
3089cdf0e10cSrcweir     }
3090cdf0e10cSrcweir     return bRet;
3091cdf0e10cSrcweir }
3092cdf0e10cSrcweir 
IsSelFullPara() const3093cdf0e10cSrcweir sal_Bool SwCrsrShell::IsSelFullPara() const
3094cdf0e10cSrcweir {
3095cdf0e10cSrcweir     sal_Bool bRet = sal_False;
3096cdf0e10cSrcweir 
3097cdf0e10cSrcweir     if( pCurCrsr->GetPoint()->nNode.GetIndex() ==
3098cdf0e10cSrcweir         pCurCrsr->GetMark()->nNode.GetIndex() && pCurCrsr == pCurCrsr->GetNext() )
3099cdf0e10cSrcweir     {
3100cdf0e10cSrcweir         xub_StrLen nStt = pCurCrsr->GetPoint()->nContent.GetIndex(),
3101cdf0e10cSrcweir                    nEnd = pCurCrsr->GetMark()->nContent.GetIndex();
3102cdf0e10cSrcweir         if( nStt > nEnd )
3103cdf0e10cSrcweir         {
3104cdf0e10cSrcweir             xub_StrLen nTmp = nStt;
3105cdf0e10cSrcweir             nStt = nEnd;
3106cdf0e10cSrcweir             nEnd = nTmp;
3107cdf0e10cSrcweir         }
3108cdf0e10cSrcweir         const SwCntntNode* pCNd = pCurCrsr->GetCntntNode();
3109cdf0e10cSrcweir         bRet = pCNd && !nStt && nEnd == pCNd->Len();
3110cdf0e10cSrcweir     }
3111cdf0e10cSrcweir     return bRet;
3112cdf0e10cSrcweir }
3113cdf0e10cSrcweir 
GetTextDirection(const Point * pPt) const3114cdf0e10cSrcweir short SwCrsrShell::GetTextDirection( const Point* pPt ) const
3115cdf0e10cSrcweir {
3116cdf0e10cSrcweir     SwPosition aPos( *pCurCrsr->GetPoint() );
3117cdf0e10cSrcweir     Point aPt( pPt ? *pPt : pCurCrsr->GetPtPos() );
3118cdf0e10cSrcweir     if( pPt )
3119cdf0e10cSrcweir     {
3120cdf0e10cSrcweir         SwCrsrMoveState aTmpState( MV_NONE );
3121cdf0e10cSrcweir         aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
3122cdf0e10cSrcweir 
3123cdf0e10cSrcweir         GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState );
3124cdf0e10cSrcweir     }
3125cdf0e10cSrcweir 
3126cdf0e10cSrcweir     return pDoc->GetTextDirection( aPos, &aPt );
3127cdf0e10cSrcweir }
3128cdf0e10cSrcweir 
IsInVerticalText(const Point * pPt) const3129cdf0e10cSrcweir sal_Bool SwCrsrShell::IsInVerticalText( const Point* pPt ) const
3130cdf0e10cSrcweir {
3131cdf0e10cSrcweir     const short nDir = GetTextDirection( pPt );
3132cdf0e10cSrcweir     return FRMDIR_VERT_TOP_RIGHT == nDir || FRMDIR_VERT_TOP_LEFT == nDir;
3133cdf0e10cSrcweir }
3134cdf0e10cSrcweir 
IsInRightToLeftText(const Point * pPt) const3135cdf0e10cSrcweir sal_Bool SwCrsrShell::IsInRightToLeftText( const Point* pPt ) const
3136cdf0e10cSrcweir {
3137cdf0e10cSrcweir     const short nDir = GetTextDirection( pPt );
3138cdf0e10cSrcweir     // GetTextDirection uses FRMDIR_VERT_TOP_LEFT to indicate RTL in
3139cdf0e10cSrcweir     // vertical environment
3140cdf0e10cSrcweir     return FRMDIR_VERT_TOP_LEFT == nDir || FRMDIR_HORI_RIGHT_TOP == nDir;
3141cdf0e10cSrcweir }
3142cdf0e10cSrcweir 
3143cdf0e10cSrcweir //
3144cdf0e10cSrcweir // If the current cursor position is inside a hidden range, the hidden range
3145cdf0e10cSrcweir // is selected:
3146cdf0e10cSrcweir //
SelectHiddenRange()3147cdf0e10cSrcweir bool SwCrsrShell::SelectHiddenRange()
3148cdf0e10cSrcweir {
3149cdf0e10cSrcweir     bool bRet = false;
3150cdf0e10cSrcweir     if ( !GetViewOptions()->IsShowHiddenChar() && !pCurCrsr->HasMark() )
3151cdf0e10cSrcweir     {
3152cdf0e10cSrcweir         SwPosition& rPt = *(SwPosition*)pCurCrsr->GetPoint();
3153cdf0e10cSrcweir         const SwTxtNode* pNode = rPt.nNode.GetNode().GetTxtNode();
3154cdf0e10cSrcweir         if ( pNode )
3155cdf0e10cSrcweir         {
3156cdf0e10cSrcweir             const xub_StrLen nPos = rPt.nContent.GetIndex();
3157cdf0e10cSrcweir 
3158cdf0e10cSrcweir             // check if nPos is in hidden range
3159cdf0e10cSrcweir             xub_StrLen nHiddenStart;
3160cdf0e10cSrcweir             xub_StrLen nHiddenEnd;
3161cdf0e10cSrcweir             SwScriptInfo::GetBoundsOfHiddenRange( *pNode, nPos, nHiddenStart, nHiddenEnd );
3162cdf0e10cSrcweir             if ( STRING_LEN != nHiddenStart )
3163cdf0e10cSrcweir             {
3164cdf0e10cSrcweir                 // make selection:
3165cdf0e10cSrcweir                 pCurCrsr->SetMark();
3166cdf0e10cSrcweir                 pCurCrsr->GetMark()->nContent = nHiddenEnd;
3167cdf0e10cSrcweir                 bRet = true;
3168cdf0e10cSrcweir             }
3169cdf0e10cSrcweir         }
3170cdf0e10cSrcweir     }
3171cdf0e10cSrcweir 
3172cdf0e10cSrcweir     return bRet;
3173cdf0e10cSrcweir }
3174cdf0e10cSrcweir 
31751dda6fa0Smseidel /* */
3176cdf0e10cSrcweir 
3177cdf0e10cSrcweir     // die Suchfunktionen
Find(const SearchOptions & rSearchOpt,sal_Bool bSearchInNotes,SwDocPositions eStart,SwDocPositions eEnde,sal_Bool & bCancel,FindRanges eRng,int bReplace)3178cdf0e10cSrcweir sal_uLong SwCrsrShell::Find( const SearchOptions& rSearchOpt, sal_Bool bSearchInNotes,
3179cdf0e10cSrcweir                             SwDocPositions eStart, SwDocPositions eEnde,
3180cdf0e10cSrcweir                             sal_Bool& bCancel,
3181cdf0e10cSrcweir                             FindRanges eRng, int bReplace )
3182cdf0e10cSrcweir {
3183cdf0e10cSrcweir     if( pTblCrsr )
3184cdf0e10cSrcweir         GetCrsr();
3185cdf0e10cSrcweir     delete pTblCrsr, pTblCrsr = 0;
3186cdf0e10cSrcweir     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
3187cdf0e10cSrcweir     sal_uLong nRet = pCurCrsr->Find( rSearchOpt, bSearchInNotes, eStart, eEnde, bCancel, eRng, bReplace );
3188cdf0e10cSrcweir     if( nRet || bCancel )
3189cdf0e10cSrcweir         UpdateCrsr();
3190cdf0e10cSrcweir     return nRet;
3191cdf0e10cSrcweir }
3192cdf0e10cSrcweir 
Find(const SwTxtFmtColl & rFmtColl,SwDocPositions eStart,SwDocPositions eEnde,sal_Bool & bCancel,FindRanges eRng,const SwTxtFmtColl * pReplFmt)3193cdf0e10cSrcweir sal_uLong SwCrsrShell::Find( const SwTxtFmtColl& rFmtColl,
3194cdf0e10cSrcweir                             SwDocPositions eStart, SwDocPositions eEnde,
3195cdf0e10cSrcweir                             sal_Bool& bCancel,
3196cdf0e10cSrcweir                             FindRanges eRng, const SwTxtFmtColl* pReplFmt )
3197cdf0e10cSrcweir {
3198cdf0e10cSrcweir     if( pTblCrsr )
3199cdf0e10cSrcweir         GetCrsr();
3200cdf0e10cSrcweir     delete pTblCrsr, pTblCrsr = 0;
3201cdf0e10cSrcweir     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
3202cdf0e10cSrcweir     sal_uLong nRet = pCurCrsr->Find( rFmtColl, eStart, eEnde, bCancel, eRng, pReplFmt );
3203cdf0e10cSrcweir     if( nRet )
3204cdf0e10cSrcweir         UpdateCrsr();
3205cdf0e10cSrcweir     return nRet;
3206cdf0e10cSrcweir }
3207cdf0e10cSrcweir 
Find(const SfxItemSet & rSet,sal_Bool bNoCollections,SwDocPositions eStart,SwDocPositions eEnde,sal_Bool & bCancel,FindRanges eRng,const SearchOptions * pSearchOpt,const SfxItemSet * rReplSet)3208cdf0e10cSrcweir sal_uLong SwCrsrShell::Find( const SfxItemSet& rSet, sal_Bool bNoCollections,
3209cdf0e10cSrcweir                             SwDocPositions eStart, SwDocPositions eEnde,
3210cdf0e10cSrcweir                             sal_Bool& bCancel,
3211cdf0e10cSrcweir                             FindRanges eRng, const SearchOptions* pSearchOpt,
3212cdf0e10cSrcweir                             const SfxItemSet* rReplSet )
3213cdf0e10cSrcweir {
3214cdf0e10cSrcweir     if( pTblCrsr )
3215cdf0e10cSrcweir         GetCrsr();
3216cdf0e10cSrcweir     delete pTblCrsr, pTblCrsr = 0;
3217cdf0e10cSrcweir     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
3218cdf0e10cSrcweir     sal_uLong nRet = pCurCrsr->Find( rSet, bNoCollections, eStart, eEnde, bCancel,
3219cdf0e10cSrcweir                                 eRng, pSearchOpt, rReplSet );
3220cdf0e10cSrcweir     if( nRet )
3221cdf0e10cSrcweir         UpdateCrsr();
3222cdf0e10cSrcweir     return nRet;
3223cdf0e10cSrcweir }
3224cdf0e10cSrcweir 
SetSelection(const SwPaM & rCrsr)3225cdf0e10cSrcweir void SwCrsrShell::SetSelection( const SwPaM& rCrsr )
3226cdf0e10cSrcweir {
3227cdf0e10cSrcweir     StartAction();
3228cdf0e10cSrcweir     SwPaM* pCrsr = GetCrsr();
3229cdf0e10cSrcweir     *pCrsr->GetPoint() = *rCrsr.GetPoint();
3230cdf0e10cSrcweir     if(rCrsr.HasMark())
3231cdf0e10cSrcweir     {
3232cdf0e10cSrcweir         pCrsr->SetMark();
3233cdf0e10cSrcweir         *pCrsr->GetMark() = *rCrsr.GetMark();
3234cdf0e10cSrcweir     }
3235cdf0e10cSrcweir     if((SwPaM*)rCrsr.GetNext() != &rCrsr)
3236cdf0e10cSrcweir     {
3237cdf0e10cSrcweir         const SwPaM *_pStartCrsr = (SwPaM*)rCrsr.GetNext();
3238cdf0e10cSrcweir         do
3239cdf0e10cSrcweir         {
3240cdf0e10cSrcweir             SwPaM* pCurrentCrsr = CreateCrsr();
3241cdf0e10cSrcweir             *pCurrentCrsr->GetPoint() = *_pStartCrsr->GetPoint();
3242cdf0e10cSrcweir             if(_pStartCrsr->HasMark())
3243cdf0e10cSrcweir             {
3244cdf0e10cSrcweir                 pCurrentCrsr->SetMark();
3245cdf0e10cSrcweir                 *pCurrentCrsr->GetMark() = *_pStartCrsr->GetMark();
3246cdf0e10cSrcweir             }
3247cdf0e10cSrcweir         } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != &rCrsr );
3248cdf0e10cSrcweir     }
3249cdf0e10cSrcweir     EndAction();
3250cdf0e10cSrcweir }
3251cdf0e10cSrcweir 
lcl_RemoveMark(SwPaM * pPam)3252cdf0e10cSrcweir void lcl_RemoveMark( SwPaM* pPam )
3253cdf0e10cSrcweir {
3254cdf0e10cSrcweir     ASSERT( pPam->HasMark(), "Don't remove pPoint!" )
3255cdf0e10cSrcweir     pPam->GetMark()->nContent.Assign( 0, 0 );
3256cdf0e10cSrcweir     pPam->GetMark()->nNode = 0;
3257cdf0e10cSrcweir     pPam->DeleteMark();
3258cdf0e10cSrcweir }
3259cdf0e10cSrcweir 
lcl_NodeContext(const SwNode & rNode)3260cdf0e10cSrcweir const SwStartNode* lcl_NodeContext( const SwNode& rNode )
3261cdf0e10cSrcweir {
3262cdf0e10cSrcweir     const SwStartNode *pRet = rNode.StartOfSectionNode();
3263cdf0e10cSrcweir     while( pRet->IsSectionNode() || pRet->IsTableNode() ||
3264cdf0e10cSrcweir         pRet->GetStartNodeType() == SwTableBoxStartNode )
3265cdf0e10cSrcweir     {
3266cdf0e10cSrcweir         pRet = pRet->StartOfSectionNode();
3267cdf0e10cSrcweir     }
3268cdf0e10cSrcweir     return pRet;
3269cdf0e10cSrcweir }
3270cdf0e10cSrcweir 
3271cdf0e10cSrcweir /**
3272cdf0e10cSrcweir    Checks if a position is valid. To be valid the position's node must
3273cdf0e10cSrcweir    be a content node and the content must not be unregistered.
3274cdf0e10cSrcweir 
3275cdf0e10cSrcweir    @param aPos the position to check.
3276cdf0e10cSrcweir */
lcl_PosOk(const SwPosition & aPos)3277cdf0e10cSrcweir bool lcl_PosOk(const SwPosition & aPos)
3278cdf0e10cSrcweir {
3279cdf0e10cSrcweir     return NULL != aPos.nNode.GetNode().GetCntntNode() &&
3280cdf0e10cSrcweir            SwIndexReg::pEmptyIndexArray != aPos.nContent.GetIdxReg();
3281cdf0e10cSrcweir }
3282cdf0e10cSrcweir 
3283cdf0e10cSrcweir /**
3284cdf0e10cSrcweir    Checks if a PaM is valid. For a PaM to be valid its point must be
328586e1cf34SPedro Giffuni    valid. Additionally if the PaM has a mark this has to be valid, too.
3286cdf0e10cSrcweir 
3287cdf0e10cSrcweir    @param aPam the PaM to check
3288cdf0e10cSrcweir */
lcl_CrsrOk(SwPaM & aPam)3289cdf0e10cSrcweir static bool lcl_CrsrOk(SwPaM & aPam)
3290cdf0e10cSrcweir {
3291cdf0e10cSrcweir     return lcl_PosOk(*aPam.GetPoint()) && (! aPam.HasMark()
3292cdf0e10cSrcweir         || lcl_PosOk(*aPam.GetMark()));
3293cdf0e10cSrcweir }
3294cdf0e10cSrcweir 
ClearUpCrsrs()3295cdf0e10cSrcweir void SwCrsrShell::ClearUpCrsrs()
3296cdf0e10cSrcweir {
3297cdf0e10cSrcweir     // start of the ring
3298cdf0e10cSrcweir     SwPaM * pStartCrsr = GetCrsr();
3299cdf0e10cSrcweir     // start loop with second entry of the ring
3300cdf0e10cSrcweir     SwPaM * pCrsr = (SwPaM *) pStartCrsr->GetNext();
3301cdf0e10cSrcweir     SwPaM * pTmpCrsr;
3302cdf0e10cSrcweir     bool bChanged = false;
3303cdf0e10cSrcweir 
3304cdf0e10cSrcweir     /*
3305cdf0e10cSrcweir        For all entries in the ring except the start entry delete the
3306cdf0e10cSrcweir        entry if it is invalid.
3307cdf0e10cSrcweir     */
3308cdf0e10cSrcweir     while (pCrsr != pStartCrsr)
3309cdf0e10cSrcweir     {
3310cdf0e10cSrcweir         pTmpCrsr = (SwPaM *) pCrsr->GetNext();
3311cdf0e10cSrcweir 
3312cdf0e10cSrcweir         if ( ! lcl_CrsrOk(*pCrsr))
3313cdf0e10cSrcweir         {
3314cdf0e10cSrcweir             delete pCrsr;
3315cdf0e10cSrcweir 
3316cdf0e10cSrcweir             bChanged = true;
3317cdf0e10cSrcweir         }
3318cdf0e10cSrcweir 
3319cdf0e10cSrcweir         pCrsr = pTmpCrsr;
3320cdf0e10cSrcweir     }
3321cdf0e10cSrcweir 
3322cdf0e10cSrcweir     if( pStartCrsr->HasMark() && !lcl_PosOk( *pStartCrsr->GetMark() ) )
3323cdf0e10cSrcweir     {
3324cdf0e10cSrcweir         lcl_RemoveMark( pStartCrsr );
3325cdf0e10cSrcweir         bChanged = true;
3326cdf0e10cSrcweir     }
3327cdf0e10cSrcweir     if( !lcl_PosOk( *pStartCrsr->GetPoint() ) )
3328cdf0e10cSrcweir     {
3329cdf0e10cSrcweir         SwNodes & aNodes = GetDoc()->GetNodes();
3330cdf0e10cSrcweir         const SwNode* pStart = lcl_NodeContext( pStartCrsr->GetPoint()->nNode.GetNode() );
3331cdf0e10cSrcweir         SwNodeIndex aIdx( pStartCrsr->GetPoint()->nNode );
3332cdf0e10cSrcweir         SwNode * pNode = aNodes.GoPrevious(&aIdx);
3333cdf0e10cSrcweir         if( pNode == NULL || lcl_NodeContext( *pNode ) != pStart )
3334cdf0e10cSrcweir             aNodes.GoNext( &aIdx );
3335cdf0e10cSrcweir         if( pNode == NULL || lcl_NodeContext( *pNode ) != pStart )
3336cdf0e10cSrcweir         {
3337cdf0e10cSrcweir             /*
3338cdf0e10cSrcweir               If the start entry of the ring is invalid replace it with a
3339cdf0e10cSrcweir               cursor pointing to the beginning of the first content node in
3340cdf0e10cSrcweir               the document.
3341cdf0e10cSrcweir             */
3342cdf0e10cSrcweir             aIdx = (*(aNodes.GetEndOfContent().StartOfSectionNode()));
3343cdf0e10cSrcweir             pNode = aNodes.GoNext( &aIdx );
3344cdf0e10cSrcweir         }
3345cdf0e10cSrcweir         bool bFound = (pNode != NULL);
3346cdf0e10cSrcweir 
3347cdf0e10cSrcweir         ASSERT(bFound, "no content node found");
3348cdf0e10cSrcweir 
3349cdf0e10cSrcweir         if (bFound)
3350cdf0e10cSrcweir         {
3351cdf0e10cSrcweir             SwPaM aTmpPam(*pNode);
3352cdf0e10cSrcweir             *pStartCrsr = aTmpPam;
3353cdf0e10cSrcweir         }
3354cdf0e10cSrcweir 
3355cdf0e10cSrcweir         bChanged = true;
3356cdf0e10cSrcweir     }
3357cdf0e10cSrcweir 
3358cdf0e10cSrcweir     /*
3359cdf0e10cSrcweir       If at least one of the cursors in the ring have been deleted or
3360cdf0e10cSrcweir       replaced, remove the table cursor.
3361cdf0e10cSrcweir     */
3362cdf0e10cSrcweir     if (pTblCrsr != NULL && bChanged)
3363cdf0e10cSrcweir         TblCrsrToCursor();
3364cdf0e10cSrcweir }
3365cdf0e10cSrcweir 
3366cdf0e10cSrcweir // #111827#
GetCrsrDescr() const3367cdf0e10cSrcweir String SwCrsrShell::GetCrsrDescr() const
3368cdf0e10cSrcweir {
3369cdf0e10cSrcweir     String aResult;
3370cdf0e10cSrcweir 
3371cdf0e10cSrcweir     if (IsMultiSelection())
3372cdf0e10cSrcweir         aResult += String(SW_RES(STR_MULTISEL));
3373cdf0e10cSrcweir     else
3374cdf0e10cSrcweir         aResult = GetDoc()->GetPaMDescr(*GetCrsr());
3375cdf0e10cSrcweir 
3376cdf0e10cSrcweir     return aResult;
3377cdf0e10cSrcweir }
3378cdf0e10cSrcweir 
3379cdf0e10cSrcweir // SMARTTAGS
3380cdf0e10cSrcweir 
lcl_FillRecognizerData(uno::Sequence<rtl::OUString> & rSmartTagTypes,uno::Sequence<uno::Reference<container::XStringKeyMap>> & rStringKeyMaps,const SwWrongList & rSmartTagList,xub_StrLen nCurrent)3381cdf0e10cSrcweir void lcl_FillRecognizerData( uno::Sequence< rtl::OUString >& rSmartTagTypes,
3382cdf0e10cSrcweir                              uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3383cdf0e10cSrcweir                              const SwWrongList& rSmartTagList, xub_StrLen nCurrent )
3384cdf0e10cSrcweir {
3385cdf0e10cSrcweir     // Insert smart tag information
3386cdf0e10cSrcweir     std::vector< rtl::OUString > aSmartTagTypes;
3387cdf0e10cSrcweir     std::vector< uno::Reference< container::XStringKeyMap > > aStringKeyMaps;
3388cdf0e10cSrcweir 
3389cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rSmartTagList.Count(); ++i )
3390cdf0e10cSrcweir     {
3391cdf0e10cSrcweir         const xub_StrLen nSTPos = rSmartTagList.Pos( i );
3392cdf0e10cSrcweir         const xub_StrLen nSTLen = rSmartTagList.Len( i );
3393cdf0e10cSrcweir 
3394cdf0e10cSrcweir         if ( nSTPos <= nCurrent && nCurrent < nSTPos + nSTLen )
3395cdf0e10cSrcweir         {
3396cdf0e10cSrcweir             const SwWrongArea* pArea = rSmartTagList.GetElement( i );
3397cdf0e10cSrcweir             if ( pArea )
3398cdf0e10cSrcweir             {
3399cdf0e10cSrcweir                 aSmartTagTypes.push_back( pArea->maType );
3400cdf0e10cSrcweir                 aStringKeyMaps.push_back( pArea->mxPropertyBag );
3401cdf0e10cSrcweir             }
3402cdf0e10cSrcweir         }
3403cdf0e10cSrcweir     }
3404cdf0e10cSrcweir 
3405cdf0e10cSrcweir     if ( aSmartTagTypes.size() )
3406cdf0e10cSrcweir     {
3407cdf0e10cSrcweir         rSmartTagTypes.realloc( aSmartTagTypes.size() );
3408cdf0e10cSrcweir         rStringKeyMaps.realloc( aSmartTagTypes.size() );
3409cdf0e10cSrcweir 
3410cdf0e10cSrcweir         std::vector< rtl::OUString >::const_iterator aTypesIter = aSmartTagTypes.begin();
3411cdf0e10cSrcweir         sal_uInt16 i = 0;
3412cdf0e10cSrcweir         for ( aTypesIter = aSmartTagTypes.begin(); aTypesIter != aSmartTagTypes.end(); ++aTypesIter )
3413cdf0e10cSrcweir             rSmartTagTypes[i++] = *aTypesIter;
3414cdf0e10cSrcweir 
3415cdf0e10cSrcweir         std::vector< uno::Reference< container::XStringKeyMap > >::const_iterator aMapsIter = aStringKeyMaps.begin();
3416cdf0e10cSrcweir         i = 0;
3417cdf0e10cSrcweir         for ( aMapsIter = aStringKeyMaps.begin(); aMapsIter != aStringKeyMaps.end(); ++aMapsIter )
3418cdf0e10cSrcweir             rStringKeyMaps[i++] = *aMapsIter;
3419cdf0e10cSrcweir     }
3420cdf0e10cSrcweir }
3421cdf0e10cSrcweir 
lcl_FillTextRange(uno::Reference<text::XTextRange> & rRange,SwTxtNode & rNode,xub_StrLen nBegin,xub_StrLen nLen)3422cdf0e10cSrcweir void lcl_FillTextRange( uno::Reference<text::XTextRange>& rRange,
3423cdf0e10cSrcweir                    SwTxtNode& rNode, xub_StrLen nBegin, xub_StrLen nLen )
3424cdf0e10cSrcweir {
3425cdf0e10cSrcweir     // create SwPosition for nStartIndex
3426cdf0e10cSrcweir     SwIndex aIndex( &rNode, nBegin );
3427cdf0e10cSrcweir     SwPosition aStartPos( rNode, aIndex );
3428cdf0e10cSrcweir 
3429cdf0e10cSrcweir     // create SwPosition for nEndIndex
3430cdf0e10cSrcweir     SwPosition aEndPos( aStartPos );
3431cdf0e10cSrcweir     aEndPos.nContent = nBegin + nLen;
3432cdf0e10cSrcweir 
3433cdf0e10cSrcweir     const uno::Reference<text::XTextRange> xRange =
3434cdf0e10cSrcweir         SwXTextRange::CreateXTextRange(*rNode.GetDoc(), aStartPos, &aEndPos);
3435cdf0e10cSrcweir 
3436cdf0e10cSrcweir     rRange = xRange;
3437cdf0e10cSrcweir }
3438cdf0e10cSrcweir 
GetSmartTagTerm(uno::Sequence<rtl::OUString> & rSmartTagTypes,uno::Sequence<uno::Reference<container::XStringKeyMap>> & rStringKeyMaps,uno::Reference<text::XTextRange> & rRange) const3439cdf0e10cSrcweir void SwCrsrShell::GetSmartTagTerm( uno::Sequence< rtl::OUString >& rSmartTagTypes,
3440cdf0e10cSrcweir                                    uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3441cdf0e10cSrcweir                                    uno::Reference< text::XTextRange>& rRange ) const
3442cdf0e10cSrcweir {
3443cdf0e10cSrcweir     if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
3444cdf0e10cSrcweir         return;
3445cdf0e10cSrcweir 
3446cdf0e10cSrcweir     SwPaM* pCrsr = GetCrsr();
3447cdf0e10cSrcweir     SwPosition aPos( *pCrsr->GetPoint() );
3448cdf0e10cSrcweir     SwTxtNode *pNode = aPos.nNode.GetNode().GetTxtNode();
3449cdf0e10cSrcweir     if ( pNode && !pNode->IsInProtectSect() )
3450cdf0e10cSrcweir     {
3451cdf0e10cSrcweir         const SwWrongList *pSmartTagList = pNode->GetSmartTags();
3452cdf0e10cSrcweir         if ( pSmartTagList )
3453cdf0e10cSrcweir         {
3454cdf0e10cSrcweir             xub_StrLen nCurrent = aPos.nContent.GetIndex();
3455cdf0e10cSrcweir             xub_StrLen nBegin = nCurrent;
3456cdf0e10cSrcweir             xub_StrLen nLen = 1;
3457cdf0e10cSrcweir 
3458cdf0e10cSrcweir             if( pSmartTagList->InWrongWord( nBegin, nLen ) && !pNode->IsSymbol(nBegin) )
3459cdf0e10cSrcweir             {
3460cdf0e10cSrcweir                 const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
3461cdf0e10cSrcweir                 const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
3462cdf0e10cSrcweir                 if ( pSubList )
3463cdf0e10cSrcweir                 {
3464cdf0e10cSrcweir                     pSmartTagList = pSubList;
3465cdf0e10cSrcweir                     nCurrent = 0;
3466cdf0e10cSrcweir                 }
3467cdf0e10cSrcweir 
3468cdf0e10cSrcweir                 lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
3469cdf0e10cSrcweir                 lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
3470cdf0e10cSrcweir             }
3471cdf0e10cSrcweir         }
3472cdf0e10cSrcweir     }
3473cdf0e10cSrcweir }
3474cdf0e10cSrcweir 
3475cdf0e10cSrcweir // 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)3476cdf0e10cSrcweir void SwCrsrShell::GetSmartTagTerm( const Point& rPt, SwRect& rSelectRect,
3477cdf0e10cSrcweir                                    uno::Sequence< rtl::OUString >& rSmartTagTypes,
3478cdf0e10cSrcweir                                    uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3479cdf0e10cSrcweir                                    uno::Reference<text::XTextRange>& rRange )
3480cdf0e10cSrcweir {
3481cdf0e10cSrcweir     if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
3482cdf0e10cSrcweir         return;
3483cdf0e10cSrcweir 
3484cdf0e10cSrcweir     SwPaM* pCrsr = GetCrsr();
3485cdf0e10cSrcweir     SwPosition aPos( *pCrsr->GetPoint() );
3486cdf0e10cSrcweir     Point aPt( rPt );
3487cdf0e10cSrcweir     SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
3488cdf0e10cSrcweir     SwSpecialPos aSpecialPos;
3489cdf0e10cSrcweir     eTmpState.pSpecialPos = &aSpecialPos;
3490cdf0e10cSrcweir     SwTxtNode *pNode;
3491cdf0e10cSrcweir     const SwWrongList *pSmartTagList;
3492cdf0e10cSrcweir 
3493cdf0e10cSrcweir     if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
3494cdf0e10cSrcweir         0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
3495cdf0e10cSrcweir         0 != (pSmartTagList = pNode->GetSmartTags()) &&
3496cdf0e10cSrcweir         !pNode->IsInProtectSect() )
3497cdf0e10cSrcweir     {
3498cdf0e10cSrcweir         xub_StrLen nCurrent = aPos.nContent.GetIndex();
3499cdf0e10cSrcweir         xub_StrLen nBegin = nCurrent;
3500cdf0e10cSrcweir         xub_StrLen nLen = 1;
3501cdf0e10cSrcweir 
3502cdf0e10cSrcweir         if( pSmartTagList->InWrongWord( nBegin, nLen ) && !pNode->IsSymbol(nBegin) )
3503cdf0e10cSrcweir         {
3504cdf0e10cSrcweir             const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
3505cdf0e10cSrcweir             const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
3506cdf0e10cSrcweir             if ( pSubList )
3507cdf0e10cSrcweir             {
3508cdf0e10cSrcweir                 pSmartTagList = pSubList;
3509cdf0e10cSrcweir                 nCurrent = eTmpState.pSpecialPos->nCharOfst;
3510cdf0e10cSrcweir             }
3511cdf0e10cSrcweir 
3512cdf0e10cSrcweir             lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
3513cdf0e10cSrcweir             lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
3514cdf0e10cSrcweir 
3515cdf0e10cSrcweir             // get smarttag word
3516cdf0e10cSrcweir             String aText( pNode->GetTxt().Copy( nBegin, nLen ) );
3517cdf0e10cSrcweir 
351851754c86SJohn Bampton             //save the start and end positions of the line and the starting point
3519cdf0e10cSrcweir             Push();
3520cdf0e10cSrcweir             LeftMargin();
3521cdf0e10cSrcweir             xub_StrLen nLineStart = GetCrsr()->GetPoint()->nContent.GetIndex();
3522cdf0e10cSrcweir             RightMargin();
3523cdf0e10cSrcweir             xub_StrLen nLineEnd = GetCrsr()->GetPoint()->nContent.GetIndex();
3524cdf0e10cSrcweir             Pop(sal_False);
3525cdf0e10cSrcweir 
3526cdf0e10cSrcweir             // make sure the selection build later from the
3527cdf0e10cSrcweir             // data below does not include footnotes and other
3528cdf0e10cSrcweir             // "in word" character to the left and right in order
3529cdf0e10cSrcweir             // to preserve those. Therefore count those "in words"
3530cdf0e10cSrcweir             // in order to modify the selection accordingly.
3531cdf0e10cSrcweir             const sal_Unicode* pChar = aText.GetBuffer();
3532cdf0e10cSrcweir             xub_StrLen nLeft = 0;
3533cdf0e10cSrcweir             while (pChar && *pChar++ == CH_TXTATR_INWORD)
3534cdf0e10cSrcweir                 ++nLeft;
3535cdf0e10cSrcweir             pChar = aText.Len() ? aText.GetBuffer() + aText.Len() - 1 : 0;
3536cdf0e10cSrcweir             xub_StrLen nRight = 0;
3537cdf0e10cSrcweir             while (pChar && *pChar-- == CH_TXTATR_INWORD)
3538cdf0e10cSrcweir                 ++nRight;
3539cdf0e10cSrcweir 
3540cdf0e10cSrcweir             aPos.nContent = nBegin + nLeft;
3541cdf0e10cSrcweir             pCrsr = GetCrsr();
3542cdf0e10cSrcweir             *pCrsr->GetPoint() = aPos;
3543cdf0e10cSrcweir             pCrsr->SetMark();
3544cdf0e10cSrcweir             ExtendSelection( sal_True, nLen - nLeft - nRight );
3545cdf0e10cSrcweir             //no determine the rectangle in the current line
3546cdf0e10cSrcweir             xub_StrLen nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
3547cdf0e10cSrcweir             //take one less than the line end - otherwise the next line would be calculated
3548cdf0e10cSrcweir             xub_StrLen nWordEnd = (nBegin + nLen - nLeft - nRight) > nLineEnd ? nLineEnd - 1: (nBegin + nLen - nLeft - nRight);
3549cdf0e10cSrcweir             Push();
3550cdf0e10cSrcweir             pCrsr->DeleteMark();
3551cdf0e10cSrcweir             SwIndex& rContent = GetCrsr()->GetPoint()->nContent;
3552cdf0e10cSrcweir             rContent = nWordStart;
3553cdf0e10cSrcweir             SwRect aStartRect;
3554cdf0e10cSrcweir             SwCrsrMoveState aState;
3555cdf0e10cSrcweir             aState.bRealWidth = sal_True;
3556cdf0e10cSrcweir             SwCntntNode* pCntntNode = pCrsr->GetCntntNode();
3557cdf0e10cSrcweir             SwCntntFrm *pCntntFrame = pCntntNode->getLayoutFrm( GetLayout(), &rPt, pCrsr->GetPoint(), sal_False);
3558cdf0e10cSrcweir 
3559cdf0e10cSrcweir             pCntntFrame->GetCharRect( aStartRect, *pCrsr->GetPoint(), &aState );
3560cdf0e10cSrcweir             rContent = nWordEnd;
3561cdf0e10cSrcweir             SwRect aEndRect;
3562cdf0e10cSrcweir             pCntntFrame->GetCharRect( aEndRect, *pCrsr->GetPoint(),&aState );
3563cdf0e10cSrcweir             rSelectRect = aStartRect.Union( aEndRect );
3564cdf0e10cSrcweir             Pop(sal_False);
3565cdf0e10cSrcweir         }
3566cdf0e10cSrcweir     }
3567cdf0e10cSrcweir }
3568