LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/edit - edlingu.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 884 0.0 %
Date: 2012-12-17 Functions: 0 60 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
      22             : #include <com/sun/star/linguistic2/XProofreader.hpp>
      23             : #include <com/sun/star/linguistic2/XProofreadingIterator.hpp>
      24             : #include <com/sun/star/text/XFlatParagraph.hpp>
      25             : #include <comphelper/string.hxx>
      26             : 
      27             : #include <unoflatpara.hxx>
      28             : 
      29             : #include <comcore.hrc>
      30             : #include <hintids.hxx>
      31             : #include <linguistic/lngprops.hxx>
      32             : #include <vcl/msgbox.hxx>
      33             : #include <editeng/unolingu.hxx>
      34             : #include <editeng/svxacorr.hxx>
      35             : #include <editeng/langitem.hxx>
      36             : #include <editeng/SpellPortions.hxx>
      37             : #include <editeng/scripttypeitem.hxx>
      38             : #include <charatr.hxx>
      39             : #include <editsh.hxx>
      40             : #include <doc.hxx>
      41             : #include <IDocumentUndoRedo.hxx>
      42             : #include <rootfrm.hxx>      // SwRootFrm
      43             : #include <pam.hxx>
      44             : #include <swundo.hxx>       // fuer die UndoIds
      45             : #include <ndtxt.hxx>        // AdjHyphPos
      46             : #include <viewopt.hxx>      // HyphStart/End
      47             : #include <viscrs.hxx>       // SwShellCrsr
      48             : #include <SwGrammarMarkUp.hxx>      // SwWrongList
      49             : #include <mdiexp.hxx>       // Statusanzeige
      50             : #include <statstr.hrc>      // StatLine-String
      51             : #include <cntfrm.hxx>
      52             : #include <crsskip.hxx>
      53             : #include <splargs.hxx>
      54             : #include <redline.hxx>      // SwRedline
      55             : #include <docary.hxx>       // SwRedlineTbl
      56             : #include <docsh.hxx>
      57             : #include <txatbase.hxx>
      58             : #include <txtfrm.hxx>
      59             : 
      60             : using namespace ::svx;
      61             : using namespace ::com::sun::star;
      62             : using namespace ::com::sun::star::uno;
      63             : using namespace ::com::sun::star::beans;
      64             : using namespace ::com::sun::star::linguistic2;
      65             : 
      66             : /*************************************************************************
      67             :  *                     class SwLinguIter
      68             :  *************************************************************************/
      69             : 
      70             : class SwLinguIter
      71             : {
      72             :     SwEditShell *pSh;
      73             :     SwPosition  *pStart;
      74             :     SwPosition  *pEnd;
      75             :     SwPosition  *pCurr;
      76             :     SwPosition  *pCurrX;
      77             :     sal_uInt16 nCrsrCnt;
      78             : public:
      79             :     SwLinguIter();
      80             : 
      81           0 :     inline SwEditShell *GetSh()             { return pSh; }
      82             :     inline const SwEditShell *GetSh() const { return pSh; }
      83             : 
      84           0 :     inline const SwPosition *GetEnd() const { return pEnd; }
      85           0 :     inline void SetEnd( SwPosition* pNew ){ delete pEnd; pEnd = pNew; }
      86             : 
      87           0 :     inline const SwPosition *GetStart() const { return pStart; }
      88           0 :     inline void SetStart( SwPosition* pNew ){ delete pStart; pStart = pNew; }
      89             : 
      90           0 :     inline const SwPosition *GetCurr() const { return pCurr; }
      91           0 :     inline void SetCurr( SwPosition* pNew ){ delete pCurr; pCurr = pNew; }
      92             : 
      93           0 :     inline const SwPosition *GetCurrX() const { return pCurrX; }
      94           0 :     inline void SetCurrX( SwPosition* pNew ){ delete pCurrX; pCurrX = pNew; }
      95             : 
      96           0 :     inline sal_uInt16& GetCrsrCnt(){ return nCrsrCnt; }
      97             : 
      98             :     // Der UI-Bauchladen:
      99             :     void _Start( SwEditShell *pSh, SwDocPositions eStart,
     100             :                 SwDocPositions eEnd );
     101             :     void _End(bool bRestoreSelection = true);
     102             : };
     103             : 
     104             : /*************************************************************************
     105             :  *                     class SwSpellIter
     106             :  *************************************************************************/
     107             : 
     108             : // #i18881# to be able to identify the postions of the changed words
     109             : // the content positions of each portion need to be saved
     110             : struct SpellContentPosition
     111             : {
     112             :     sal_uInt16 nLeft;
     113             :     sal_uInt16 nRight;
     114             : };
     115             : typedef std::vector<SpellContentPosition>  SpellContentPositions;
     116           0 : class SwSpellIter : public SwLinguIter
     117             : {
     118             :     uno::Reference< XSpellChecker1 >    xSpeller;
     119             :     ::svx::SpellPortions                aLastPortions;
     120             : 
     121             :     SpellContentPositions               aLastPositions;
     122             :     bool                                bBackToStartOfSentence;
     123             :     bool                                bMoveToEndOfSentence;
     124             : 
     125             : 
     126             :     void    CreatePortion(uno::Reference< XSpellAlternatives > xAlt,
     127             :                 linguistic2::ProofreadingResult* pGrammarResult,
     128             :                 bool bIsField, bool bIsHidden);
     129             : 
     130             :     void    AddPortion(uno::Reference< XSpellAlternatives > xAlt,
     131             :                        linguistic2::ProofreadingResult* pGrammarResult,
     132             :                        const SpellContentPositions& rDeletedRedlines);
     133             : public:
     134           0 :     SwSpellIter() :
     135           0 :         bBackToStartOfSentence(false), bMoveToEndOfSentence(false) {}
     136             : 
     137             :     void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
     138             : 
     139             :     uno::Any    Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
     140             : 
     141             :     bool                                SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammarCheck);
     142             :     void                                ToSentenceStart();
     143           0 :     const ::svx::SpellPortions          GetLastPortions() const { return aLastPortions;}
     144           0 :     SpellContentPositions               GetLastPositions() const {return aLastPositions;}
     145           0 :     void                                ContinueAfterThisSentence() { bMoveToEndOfSentence = true; }
     146             : };
     147             : 
     148             : /*************************************************************************
     149             :  *                     class SwConvIter
     150             :  * used for text conversion
     151             :  *************************************************************************/
     152             : 
     153             : class SwConvIter : public SwLinguIter
     154             : {
     155             :     SwConversionArgs &rArgs;
     156             : public:
     157           0 :     SwConvIter( SwConversionArgs &rConvArgs ) :
     158           0 :         rArgs( rConvArgs )
     159           0 :     {}
     160             : 
     161             :     void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
     162             : 
     163             :     uno::Any    Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
     164             : };
     165             : 
     166             : /*************************************************************************
     167             :  *                     class SwHyphIter
     168             :  *************************************************************************/
     169             : 
     170             : class SwHyphIter : public SwLinguIter
     171             : {
     172             :     sal_Bool bOldIdle;
     173             :     void DelSoftHyph( SwPaM &rPam );
     174             : 
     175             : public:
     176           0 :     SwHyphIter() : bOldIdle(sal_False) {}
     177             : 
     178             :     void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
     179             :     void End();
     180             : 
     181             :     void Ignore();
     182             : 
     183             :     uno::Any    Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
     184             : 
     185             :     sal_Bool IsAuto();
     186             :     void InsertSoftHyph( const xub_StrLen nHyphPos );
     187             :     void ShowSelection();
     188             : };
     189             : 
     190             : static SwSpellIter* pSpellIter = 0;
     191             : static SwConvIter*  pConvIter = 0;
     192             : static SwHyphIter*  pHyphIter = 0;
     193             : 
     194             : // Wir ersparen uns in Hyphenate ein GetFrm()
     195             : // Achtung: in txtedt.cxx stehen extern-Deklarationen auf diese Pointer!
     196             : const SwTxtNode *pLinguNode;
     197             :       SwTxtFrm  *pLinguFrm;
     198             : 
     199             : /*************************************************************************
     200             :  *                      SwLinguIter::SwLinguIter
     201             :  *************************************************************************/
     202             : 
     203           0 : SwLinguIter::SwLinguIter()
     204           0 :     : pSh( 0 ), pStart( 0 ), pEnd( 0 ), pCurr( 0 ), pCurrX( 0 )
     205             : {
     206             :     // @@@ es fehlt: Sicherstellen der Reentrance, OSL_ENSURE( etc.
     207           0 : }
     208             : 
     209             : /*************************************************************************
     210             :  *                      SwLinguIter::Start
     211             :  *************************************************************************/
     212             : 
     213             : 
     214             : 
     215           0 : void SwLinguIter::_Start( SwEditShell *pShell, SwDocPositions eStart,
     216             :                             SwDocPositions eEnd )
     217             : {
     218             :     // es fehlt: Sicherstellen der Reentrance, Locking
     219           0 :     if( pSh )
     220           0 :         return;
     221             : 
     222             :     bool bSetCurr;
     223             : 
     224           0 :     pSh = pShell;
     225             : 
     226           0 :     SET_CURR_SHELL( pSh );
     227             : 
     228             :     OSL_ENSURE( !pEnd, "LinguStart ohne End?");
     229             : 
     230           0 :     SwPaM *pCrsr = pSh->GetCrsr();
     231             : 
     232           0 :     if( pShell->HasSelection() || pCrsr != pCrsr->GetNext() )
     233             :     {
     234           0 :         bSetCurr = 0 != GetCurr();
     235           0 :         nCrsrCnt = pSh->GetCrsrCnt();
     236           0 :         if( pSh->IsTableMode() )
     237           0 :             pSh->TblCrsrToCursor();
     238             : 
     239           0 :         pSh->Push();
     240             :         sal_uInt16 n;
     241           0 :         for( n = 0; n < nCrsrCnt; ++n )
     242             :         {
     243           0 :             pSh->Push();
     244           0 :             pSh->DestroyCrsr();
     245             :         }
     246           0 :         pSh->Pop( sal_False );
     247             :     }
     248             :     else
     249             :     {
     250           0 :         bSetCurr = false;
     251           0 :         nCrsrCnt = 1;
     252           0 :         pSh->Push();
     253           0 :         pSh->SetLinguRange( eStart, eEnd );
     254             :     }
     255             : 
     256           0 :     pCrsr = pSh->GetCrsr();
     257           0 :     if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
     258           0 :         pCrsr->Exchange();
     259             : 
     260           0 :     pStart = new SwPosition( *pCrsr->GetPoint() );
     261           0 :     pEnd = new SwPosition( *pCrsr->GetMark() );
     262           0 :     if( bSetCurr )
     263             :     {
     264           0 :         SwPosition* pNew = new SwPosition( *GetStart() );
     265           0 :         SetCurr( pNew );
     266           0 :         pNew = new SwPosition( *pNew );
     267           0 :         SetCurrX( pNew );
     268             :     }
     269             : 
     270           0 :     pCrsr->SetMark();
     271             : 
     272           0 :     pLinguFrm = 0;
     273           0 :     pLinguNode = 0;
     274             : }
     275             : 
     276             : /*************************************************************************
     277             :  *                      SwLinguIter::End
     278             :  *************************************************************************/
     279             : 
     280             : 
     281             : 
     282           0 : void SwLinguIter::_End(bool bRestoreSelection)
     283             : {
     284           0 :     if( !pSh )
     285           0 :         return;
     286             : 
     287             :     OSL_ENSURE( pEnd, "SwEditShell::SpellEnd() ohne Start?");
     288           0 :     if(bRestoreSelection)
     289             :     {
     290           0 :         while( nCrsrCnt-- )
     291           0 :             pSh->Pop( sal_False );
     292             : 
     293           0 :         pSh->KillPams();
     294           0 :         pSh->ClearMark();
     295             :     }
     296           0 :     DELETEZ(pStart);
     297           0 :     DELETEZ(pEnd);
     298           0 :     DELETEZ(pCurr);
     299           0 :     DELETEZ(pCurrX);
     300             : 
     301           0 :     pSh = 0;
     302             : }
     303             : 
     304             : /*************************************************************************
     305             :  *               virtual SwSpellIter::Start()
     306             :  *************************************************************************/
     307             : 
     308             : 
     309             : 
     310           0 : void SwSpellIter::Start( SwEditShell *pShell, SwDocPositions eStart,
     311             :                         SwDocPositions eEnd )
     312             : {
     313           0 :     if( GetSh() )
     314           0 :         return;
     315             : 
     316           0 :      uno::Reference< beans::XPropertySet >  xProp( ::GetLinguPropertySet() );
     317           0 :     xSpeller = ::GetSpellChecker();
     318           0 :     if ( xSpeller.is() )
     319           0 :         _Start( pShell, eStart, eEnd );
     320           0 :     aLastPortions.clear();
     321           0 :     aLastPositions.clear();
     322             : }
     323             : 
     324             : /*************************************************************************
     325             :  *                   SwSpellIter::Continue
     326             :  *************************************************************************/
     327             : 
     328             : // SwSpellIter::Continue ist das alte Original von
     329             : // SwEditShell::SpellContinue()
     330             : 
     331           0 : uno::Any SwSpellIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
     332             : {
     333             :     //!!
     334             :     //!! Please check SwConvIter also when modifying this
     335             :     //!!
     336             : 
     337           0 :     uno::Any    aSpellRet;
     338           0 :     SwEditShell *pMySh = GetSh();
     339           0 :     if( !pMySh )
     340             :         return aSpellRet;
     341             : 
     342             :     OSL_ENSURE( GetEnd(), "SwEditShell::SpellContinue() ohne Start?");
     343             : 
     344           0 :     uno::Reference< uno::XInterface >  xSpellRet;
     345           0 :     bool bGoOn = true;
     346           0 :     do {
     347           0 :         SwPaM *pCrsr = pMySh->GetCrsr();
     348           0 :         if ( !pCrsr->HasMark() )
     349           0 :             pCrsr->SetMark();
     350             : 
     351           0 :         uno::Reference< beans::XPropertySet >  xProp( GetLinguPropertySet() );
     352           0 :         *pMySh->GetCrsr()->GetPoint() = *GetCurr();
     353           0 :         *pMySh->GetCrsr()->GetMark() = *GetEnd();
     354           0 :         pMySh->GetDoc()->Spell(*pMySh->GetCrsr(),
     355           0 :                     xSpeller, pPageCnt, pPageSt, false ) >>= xSpellRet;
     356           0 :         bGoOn = GetCrsrCnt() > 1;
     357           0 :         if( xSpellRet.is() )
     358             :         {
     359           0 :             bGoOn = false;
     360           0 :             SwPosition* pNewPoint = new SwPosition( *pCrsr->GetPoint() );
     361           0 :             SwPosition* pNewMark = new SwPosition( *pCrsr->GetMark() );
     362           0 :             SetCurr( pNewPoint );
     363           0 :             SetCurrX( pNewMark );
     364             :         }
     365           0 :         if( bGoOn )
     366             :         {
     367           0 :             pMySh->Pop( sal_False );
     368           0 :             pCrsr = pMySh->GetCrsr();
     369           0 :             if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
     370           0 :                 pCrsr->Exchange();
     371           0 :             SwPosition* pNew = new SwPosition( *pCrsr->GetPoint() );
     372           0 :             SetStart( pNew );
     373           0 :             pNew = new SwPosition( *pCrsr->GetMark() );
     374           0 :             SetEnd( pNew );
     375           0 :             pNew = new SwPosition( *GetStart() );
     376           0 :             SetCurr( pNew );
     377           0 :             pNew = new SwPosition( *pNew );
     378           0 :             SetCurrX( pNew );
     379           0 :             pCrsr->SetMark();
     380           0 :             --GetCrsrCnt();
     381           0 :         }
     382             :     }while ( bGoOn );
     383           0 :     aSpellRet <<= xSpellRet;
     384           0 :     return aSpellRet;
     385             : }
     386             : 
     387             : /*************************************************************************
     388             :  *               virtual SwConvIter::Start()
     389             :  *************************************************************************/
     390             : 
     391             : 
     392             : 
     393           0 : void SwConvIter::Start( SwEditShell *pShell, SwDocPositions eStart,
     394             :                         SwDocPositions eEnd )
     395             : {
     396           0 :     if( GetSh() )
     397           0 :         return;
     398           0 :     _Start( pShell, eStart, eEnd );
     399             : }
     400             : 
     401             : /*************************************************************************
     402             :  *                   SwConvIter::Continue
     403             :  *************************************************************************/
     404             : 
     405           0 : uno::Any SwConvIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
     406             : {
     407             :     //!!
     408             :     //!! Please check SwSpellIter also when modifying this
     409             :     //!!
     410             : 
     411           0 :     uno::Any    aConvRet( makeAny( rtl::OUString() ) );
     412           0 :     SwEditShell *pMySh = GetSh();
     413           0 :     if( !pMySh )
     414           0 :         return aConvRet;
     415             : 
     416             :     OSL_ENSURE( GetEnd(), "SwConvIter::Continue() ohne Start?");
     417             : 
     418           0 :     rtl::OUString aConvText;
     419           0 :     bool bGoOn = true;
     420           0 :     do {
     421           0 :         SwPaM *pCrsr = pMySh->GetCrsr();
     422           0 :         if ( !pCrsr->HasMark() )
     423           0 :             pCrsr->SetMark();
     424             : 
     425           0 :         *pMySh->GetCrsr()->GetPoint() = *GetCurr();
     426           0 :         *pMySh->GetCrsr()->GetMark() = *GetEnd();
     427             : 
     428             :         // call function to find next text portion to be converted
     429           0 :         uno::Reference< linguistic2::XSpellChecker1 > xEmpty;
     430           0 :         pMySh->GetDoc()->Spell( *pMySh->GetCrsr(),
     431           0 :                     xEmpty, pPageCnt, pPageSt, false, &rArgs ) >>= aConvText;
     432             : 
     433           0 :         bGoOn = GetCrsrCnt() > 1;
     434           0 :         if( !aConvText.isEmpty() )
     435             :         {
     436           0 :             bGoOn = false;
     437           0 :             SwPosition* pNewPoint = new SwPosition( *pCrsr->GetPoint() );
     438           0 :             SwPosition* pNewMark = new SwPosition( *pCrsr->GetMark() );
     439             : 
     440           0 :             SetCurr( pNewPoint );
     441           0 :             SetCurrX( pNewMark );
     442             :         }
     443           0 :         if( bGoOn )
     444             :         {
     445           0 :             pMySh->Pop( sal_False );
     446           0 :             pCrsr = pMySh->GetCrsr();
     447           0 :             if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
     448           0 :                 pCrsr->Exchange();
     449           0 :             SwPosition* pNew = new SwPosition( *pCrsr->GetPoint() );
     450           0 :             SetStart( pNew );
     451           0 :             pNew = new SwPosition( *pCrsr->GetMark() );
     452           0 :             SetEnd( pNew );
     453           0 :             pNew = new SwPosition( *GetStart() );
     454           0 :             SetCurr( pNew );
     455           0 :             pNew = new SwPosition( *pNew );
     456           0 :             SetCurrX( pNew );
     457           0 :             pCrsr->SetMark();
     458           0 :             --GetCrsrCnt();
     459           0 :         }
     460             :     }while ( bGoOn );
     461           0 :     return makeAny( aConvText );
     462             : }
     463             : 
     464             : 
     465             : /*************************************************************************
     466             :  *                   SwHyphIter
     467             :  *************************************************************************/
     468             : 
     469             : 
     470           0 : sal_Bool SwHyphIter::IsAuto()
     471             : {
     472           0 :     uno::Reference< beans::XPropertySet >  xProp( ::GetLinguPropertySet() );
     473           0 :     return xProp.is() ? *(sal_Bool*)xProp->getPropertyValue(
     474           0 :                                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UPN_IS_HYPH_AUTO)) ).getValue()
     475           0 :                       : sal_False;
     476             : }
     477             : 
     478             : 
     479           0 : void SwHyphIter::ShowSelection()
     480             : {
     481           0 :     SwEditShell *pMySh = GetSh();
     482           0 :     if( pMySh )
     483             :     {
     484           0 :         pMySh->StartAction();
     485             :         // Ganz fatal: durch das EndAction() werden Formatierungen
     486             :         // angeregt, die dazu fuehren koennen, dass im Hyphenator
     487             :         // neue Worte eingestellt werden. Deswegen sichern!
     488           0 :         pMySh->EndAction();
     489             :     }
     490           0 : }
     491             : 
     492             : /*************************************************************************
     493             :  *               virtual SwHyphIter::Start()
     494             :  *************************************************************************/
     495             : 
     496             : 
     497             : 
     498           0 : void SwHyphIter::Start( SwEditShell *pShell, SwDocPositions eStart, SwDocPositions eEnd )
     499             : {
     500             :     // robust
     501           0 :     if( GetSh() || GetEnd() )
     502             :     {
     503             :         OSL_ENSURE( !GetSh(), "+SwEditShell::HyphStart: missing HyphEnd()" );
     504           0 :         return;
     505             :     }
     506             : 
     507             : // nothing to be done (at least not in the way as in the "else" part)
     508           0 :     bOldIdle = pShell->GetViewOptions()->IsIdle();
     509           0 :     ((SwViewOption*)pShell->GetViewOptions())->SetIdle( sal_False );
     510           0 :     _Start( pShell, eStart, eEnd );
     511             : }
     512             : 
     513             : /*************************************************************************
     514             :  *                 virtual SwHyphIter::End
     515             :  *************************************************************************/
     516             : 
     517             : // Selektionen wiederherstellen
     518             : 
     519             : 
     520             : 
     521           0 : void SwHyphIter::End()
     522             : {
     523           0 :     if( !GetSh() )
     524           0 :         return;
     525           0 :     ((SwViewOption*)GetSh()->GetViewOptions())->SetIdle( bOldIdle );
     526           0 :     _End();
     527             : }
     528             : 
     529             : /*************************************************************************
     530             :  *                   SwHyphIter::Continue
     531             :  *************************************************************************/
     532             : 
     533           0 : uno::Any SwHyphIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
     534             : {
     535           0 :     uno::Any    aHyphRet;
     536           0 :     SwEditShell *pMySh = GetSh();
     537           0 :     if( !pMySh )
     538             :         return aHyphRet;
     539             : 
     540           0 :     const bool bAuto = IsAuto();
     541           0 :      uno::Reference< XHyphenatedWord >  xHyphWord;
     542           0 :     bool bGoOn = false;
     543           0 :     do {
     544             :         SwPaM *pCrsr;
     545           0 :         do {
     546             :             OSL_ENSURE( GetEnd(), "SwEditShell::SpellContinue() ohne Start?" );
     547           0 :             pCrsr = pMySh->GetCrsr();
     548           0 :             if ( !pCrsr->HasMark() )
     549           0 :                 pCrsr->SetMark();
     550           0 :             if ( *pCrsr->GetPoint() < *pCrsr->GetMark() )
     551             :             {
     552           0 :                 pCrsr->Exchange();
     553           0 :                 pCrsr->SetMark();
     554             :             }
     555             : 
     556           0 :             if ( *pCrsr->End() <= *GetEnd() )
     557             :             {
     558           0 :                 *pCrsr->GetMark() = *GetEnd();
     559             : 
     560             :                 // Muss an der aktuellen Cursorpos das Wort getrennt werden ?
     561           0 :                 const Point aCrsrPos( pMySh->GetCharRect().Pos() );
     562             :                 xHyphWord = pMySh->GetDoc()->Hyphenate( pCrsr, aCrsrPos,
     563           0 :                                                        pPageCnt, pPageSt );
     564             :             }
     565             : 
     566           0 :             if( bAuto && xHyphWord.is() )
     567             :             {
     568           0 :                 pMySh->InsertSoftHyph( xHyphWord->getHyphenationPos() + 1);
     569             :             }
     570           0 :         } while( bAuto && xHyphWord.is() ); //end of do-while
     571           0 :         bGoOn = !xHyphWord.is() && GetCrsrCnt() > 1;
     572             : 
     573           0 :         if( bGoOn )
     574             :         {
     575           0 :             pMySh->Pop( sal_False );
     576           0 :             pCrsr = pMySh->GetCrsr();
     577           0 :             if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
     578           0 :                 pCrsr->Exchange();
     579           0 :             SwPosition* pNew = new SwPosition(*pCrsr->End());
     580           0 :             SetEnd( pNew );
     581           0 :             pCrsr->SetMark();
     582           0 :             --GetCrsrCnt();
     583             :         }
     584             :     } while ( bGoOn );
     585           0 :     aHyphRet <<= xHyphWord;
     586           0 :     return aHyphRet;
     587             : }
     588             : 
     589             : /*************************************************************************
     590             :  *                  SwHyphIter::HyphIgnore
     591             :  *************************************************************************/
     592             : 
     593             : // Beschreibung: Trennstelle ignorieren
     594             : 
     595           0 : void SwHyphIter::Ignore()
     596             : {
     597           0 :     SwEditShell *pMySh = GetSh();
     598           0 :     SwPaM *pCrsr = pMySh->GetCrsr();
     599             : 
     600             :     // Alten SoftHyphen loeschen
     601           0 :     DelSoftHyph( *pCrsr );
     602             : 
     603             :     // und weiter
     604           0 :     pCrsr->Start()->nContent = pCrsr->End()->nContent;
     605           0 :     pCrsr->SetMark();
     606           0 : }
     607             : 
     608             : /*************************************************************************
     609             :  *                        SwHyphIter::DelSoftHyph
     610             :  *************************************************************************/
     611             : 
     612           0 : void SwHyphIter::DelSoftHyph( SwPaM &rPam )
     613             : {
     614           0 :     const SwPosition* pStt = rPam.Start();
     615           0 :     const xub_StrLen nStart = pStt->nContent.GetIndex();
     616           0 :     const xub_StrLen nEnd   = rPam.End()->nContent.GetIndex();
     617           0 :     SwTxtNode *pNode = pStt->nNode.GetNode().GetTxtNode();
     618           0 :     pNode->DelSoftHyph( nStart, nEnd );
     619           0 : }
     620             : 
     621             : /*************************************************************************
     622             :  *                  SwHyphIter::InsertSoftHyph
     623             :  *************************************************************************/
     624             : 
     625             : 
     626           0 : void SwHyphIter::InsertSoftHyph( const xub_StrLen nHyphPos )
     627             : {
     628           0 :     SwEditShell *pMySh = GetSh();
     629             :     OSL_ENSURE( pMySh,  "+SwEditShell::InsertSoftHyph: missing HyphStart()");
     630           0 :     if( !pMySh )
     631           0 :         return;
     632             : 
     633           0 :     SwPaM *pCrsr = pMySh->GetCrsr();
     634           0 :     SwPosition* pSttPos = pCrsr->Start();
     635           0 :     SwPosition* pEndPos = pCrsr->End();
     636             : 
     637           0 :     xub_StrLen nLastHyphLen = GetEnd()->nContent.GetIndex() -
     638           0 :                           pSttPos->nContent.GetIndex();
     639             : 
     640           0 :     if( pSttPos->nNode != pEndPos->nNode || !nLastHyphLen )
     641             :     {
     642             :         OSL_ENSURE( pSttPos->nNode == pEndPos->nNode,
     643             :                 "+SwEditShell::InsertSoftHyph: node warp during hyphenation" );
     644             :         OSL_ENSURE(nLastHyphLen, "+SwEditShell::InsertSoftHyph: missing HyphContinue()");
     645           0 :         *pSttPos = *pEndPos;
     646           0 :         return;
     647             :     }
     648             : 
     649           0 :     pMySh->StartAction();
     650             :     {
     651           0 :         SwDoc *pDoc = pMySh->GetDoc();
     652           0 :         DelSoftHyph( *pCrsr );
     653           0 :         pSttPos->nContent += nHyphPos;
     654           0 :         SwPaM aRg( *pSttPos );
     655           0 :         pDoc->InsertString( aRg, rtl::OUString(CHAR_SOFTHYPHEN) );
     656             :         // Durch das Einfuegen des SoftHyphs ist ein Zeichen hinzugekommen
     657             : //JP 18.07.95: warum, ist doch ein SwIndex, dieser wird doch mitverschoben !!
     658             : //        pSttPos->nContent++;
     659             :     }
     660             :     // Die Selektion wird wieder aufgehoben
     661           0 :     pCrsr->DeleteMark();
     662           0 :     pMySh->EndAction();
     663           0 :     pCrsr->SetMark();
     664             : }
     665             : 
     666             : // --------------------- Methoden der SwEditShell ------------------------
     667             : 
     668           0 : bool SwEditShell::HasLastSentenceGotGrammarChecked() const
     669             : {
     670           0 :     bool bTextWasGrammarChecked = false;
     671           0 :     if (pSpellIter)
     672             :     {
     673           0 :         ::svx::SpellPortions aLastPortions( pSpellIter->GetLastPortions() );
     674           0 :         for (size_t i = 0;  i < aLastPortions.size() && !bTextWasGrammarChecked;  ++i)
     675             :         {
     676             :             // bIsGrammarError is also true if the text was only checked but no
     677             :             // grammar error was found. (That is if a ProofreadingResult was obtained in
     678             :             // SwDoc::Spell and in turn bIsGrammarError was set in SwSpellIter::CreatePortion)
     679           0 :             if (aLastPortions[i].bIsGrammarError)
     680           0 :                 bTextWasGrammarChecked = true;
     681           0 :         }
     682             :     }
     683           0 :     return bTextWasGrammarChecked;
     684             : }
     685             : 
     686             : /*************************************************************************
     687             :  *                      SwEditShell::HasConvIter
     688             :  *************************************************************************/
     689             : 
     690           0 : sal_Bool SwEditShell::HasConvIter() const
     691             : {
     692           0 :     return 0 != pConvIter;
     693             : }
     694             : 
     695             : /*************************************************************************
     696             :  *                      SwEditShell::HasHyphIter
     697             :  *************************************************************************/
     698             : 
     699           0 : sal_Bool SwEditShell::HasHyphIter() const
     700             : {
     701           0 :     return 0 != pHyphIter;
     702             : }
     703             : 
     704             : /*************************************************************************
     705             :  *                      SwEditShell::SetFindRange
     706             :  *************************************************************************/
     707             : 
     708           0 : void SwEditShell::SetLinguRange( SwDocPositions eStart, SwDocPositions eEnd )
     709             : {
     710           0 :     SwPaM *pCrsr = GetCrsr();
     711           0 :     MakeFindRange( static_cast<sal_uInt16>(eStart), static_cast<sal_uInt16>(eEnd), pCrsr );
     712           0 :     if( *pCrsr->GetPoint() > *pCrsr->GetMark() )
     713           0 :         pCrsr->Exchange();
     714           0 : }
     715             : 
     716             : /*************************************************************************
     717             :  *                  SwEditShell::SpellStart
     718             :  *************************************************************************/
     719             : 
     720           0 : void SwEditShell::SpellStart(
     721             :         SwDocPositions eStart, SwDocPositions eEnd, SwDocPositions eCurr,
     722             :         SwConversionArgs *pConvArgs )
     723             : {
     724           0 :     SwLinguIter *pLinguIter = 0;
     725             : 
     726             :     // do not spell if interactive spelling is active elsewhere
     727           0 :     if (!pConvArgs && !pSpellIter)
     728             :     {
     729             :         OSL_ENSURE( !pSpellIter, "wer ist da schon am spellen?" );
     730           0 :         pSpellIter = new SwSpellIter;
     731           0 :         pLinguIter = pSpellIter;
     732             :     }
     733             :     // do not do text conversion if it is active elsewhere
     734           0 :     if (pConvArgs && !pConvIter)
     735             :     {
     736             :         OSL_ENSURE( !pConvIter, "text conversion already active!" );
     737           0 :         pConvIter = new SwConvIter( *pConvArgs );
     738           0 :         pLinguIter = pConvIter;
     739             :     }
     740             : 
     741           0 :     if (pLinguIter)
     742             :     {
     743           0 :         SwCursor* pSwCrsr = GetSwCrsr();
     744             : 
     745           0 :         SwPosition *pTmp = new SwPosition( *pSwCrsr->GetPoint() );
     746           0 :         pSwCrsr->FillFindPos( eCurr, *pTmp );
     747           0 :         pLinguIter->SetCurr( pTmp );
     748             : 
     749           0 :         pTmp = new SwPosition( *pTmp );
     750           0 :         pLinguIter->SetCurrX( pTmp );
     751             :     }
     752             : 
     753           0 :     if (!pConvArgs && pSpellIter)
     754           0 :         pSpellIter->Start( this, eStart, eEnd );
     755           0 :     if (pConvArgs && pConvIter)
     756           0 :         pConvIter->Start( this, eStart, eEnd );
     757           0 : }
     758             : 
     759             : /*************************************************************************
     760             :  *                  SwEditShell::SpellEnd
     761             :  *************************************************************************/
     762             : 
     763           0 : void SwEditShell::SpellEnd( SwConversionArgs *pConvArgs, bool bRestoreSelection )
     764             : {
     765           0 :     if (!pConvArgs && pSpellIter && pSpellIter->GetSh() == this)
     766             :     {
     767             :         OSL_ENSURE( pSpellIter, "wo ist mein Iterator?" );
     768           0 :         pSpellIter->_End(bRestoreSelection);
     769           0 :         delete pSpellIter, pSpellIter = 0;
     770             :     }
     771           0 :     if (pConvArgs && pConvIter && pConvIter->GetSh() == this)
     772             :     {
     773             :         OSL_ENSURE( pConvIter, "wo ist mein Iterator?" );
     774           0 :         pConvIter->_End();
     775           0 :         delete pConvIter, pConvIter = 0;
     776             :     }
     777           0 : }
     778             : 
     779             : /*************************************************************************
     780             :  *                  SwEditShell::SpellContinue
     781             :  *************************************************************************/
     782             : 
     783             : // liefert Rueckgabewerte entsprechend SPL_ in splchk.hxx
     784             : 
     785           0 : uno::Any SwEditShell::SpellContinue(
     786             :         sal_uInt16* pPageCnt, sal_uInt16* pPageSt,
     787             :         SwConversionArgs *pConvArgs )
     788             : {
     789           0 :     uno::Any aRes;
     790             : 
     791           0 :     if ((!pConvArgs && pSpellIter->GetSh() != this) ||
     792           0 :         ( pConvArgs && pConvIter->GetSh() != this))
     793             :         return aRes;
     794             : 
     795           0 :     if( pPageCnt && !*pPageCnt )
     796             :     {
     797           0 :         sal_uInt16 nEndPage = GetLayout()->GetPageNum();
     798           0 :         nEndPage += nEndPage * 10 / 100;
     799           0 :         *pPageCnt = nEndPage;
     800           0 :         if( nEndPage )
     801           0 :             ::StartProgress( STR_STATSTR_SPELL, 0, nEndPage, GetDoc()->GetDocShell() );
     802             :     }
     803             : 
     804             :     OSL_ENSURE(  pConvArgs || pSpellIter, "SpellIter missing" );
     805             :     OSL_ENSURE( !pConvArgs || pConvIter,  "ConvIter missing" );
     806             :     //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
     807             :     //              KEIN StartAction, da damit auch die Paints abgeschaltet
     808             :     //              werden !!!!!
     809           0 :     ++nStartAction;
     810           0 :     rtl::OUString aRet;
     811           0 :     uno::Reference< uno::XInterface >  xRet;
     812           0 :     if (pConvArgs)
     813             :     {
     814           0 :         pConvIter->Continue( pPageCnt, pPageSt ) >>= aRet;
     815           0 :         aRes <<= aRet;
     816             :     }
     817             :     else
     818             :     {
     819           0 :         pSpellIter->Continue( pPageCnt, pPageSt ) >>= xRet;
     820           0 :         aRes <<= xRet;
     821             :     }
     822           0 :     --nStartAction;
     823             : 
     824           0 :     if( !aRet.isEmpty() || xRet.is() )
     825             :     {
     826             :         // dann die awt::Selection sichtbar machen
     827           0 :         StartAction();
     828           0 :         EndAction();
     829             :     }
     830           0 :     return aRes;
     831             : }
     832             : /*************************************************************************
     833             :  *                  SwEditShell::HyphStart
     834             :  *************************************************************************/
     835             : 
     836             : /* Interaktive Trennung, BP 10.03.93
     837             :  *
     838             :  * 1) HyphStart
     839             :  *    - Aufheben aller Selektionen
     840             :  *    - Sichern des aktuellen Cursors
     841             :  *    - falls keine Selektion vorhanden:
     842             :  *      - neue Selektion bis zum Dokumentende
     843             :  * 2) HyphContinue
     844             :  *    - nLastHyphLen wird auf den Selektionsstart addiert
     845             :  *    - iteriert ueber alle selektierten Bereiche
     846             :  *      - pDoc->Hyphenate() iteriert ueber alle Nodes der Selektion
     847             :  *          - pTxtNode->Hyphenate() ruft das SwTxtFrm::Hyphenate zur EditShell
     848             :  *              - SwTxtFrm:Hyphenate() iteriert ueber die Zeilen des Pams
     849             :  *                  - LineIter::Hyphenate() stellt den Hyphenator
     850             :  *                    und den Pam auf das zu trennende Wort ein.
     851             :  *    - Es gibt nur zwei Returnwerte sal_True, wenn eine Trennstelle anliegt
     852             :  *      und sal_False, wenn der Pam abgearbeitet wurde.
     853             :  *    - Bei sal_True wird das selektierte Wort zur Anzeige gebracht und
     854             :  *      nLastHyphLen gesetzt.
     855             :  *    - Bei sal_False wird die aktuelle Selektion geloescht und die naechste
     856             :  *      zur aktuellen gewaehlt. Return HYPH_OK, wenn keine mehr vorhanden.
     857             :  * 3) InsertSoftHyph (wird ggf. von der UI gerufen)
     858             :  *    - Der aktuelle Cursor wird plaziert und das Attribut eingefuegt.
     859             :  * 4) HyphEnd
     860             :  *    - Wiederherstellen des alten Cursors, EndAction
     861             :  */
     862             : 
     863             : 
     864             : 
     865           0 : void SwEditShell::HyphStart( SwDocPositions eStart, SwDocPositions eEnd )
     866             : {
     867             :     // do not hyphenate if interactive hyphenationg is active elsewhere
     868           0 :     if (!pHyphIter)
     869             :     {
     870             :         OSL_ENSURE( !pHyphIter, "wer ist da schon am hyphinieren?" );
     871           0 :         pHyphIter = new SwHyphIter;
     872           0 :         pHyphIter->Start( this, eStart, eEnd );
     873             :     }
     874           0 : }
     875             : 
     876             : /*************************************************************************
     877             :  *                  SwEditShell::HyphEnd
     878             :  *************************************************************************/
     879             : 
     880             : // Selektionen wiederherstellen
     881             : 
     882             : 
     883             : 
     884           0 : void SwEditShell::HyphEnd()
     885             : {
     886           0 :     if (pHyphIter->GetSh() == this)
     887             :     {
     888             :         OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
     889           0 :         pHyphIter->End();
     890           0 :         delete pHyphIter, pHyphIter = 0;
     891             :     }
     892           0 : }
     893             : 
     894             : /*************************************************************************
     895             :  *                  SwEditShell::HyphContinue
     896             :  *************************************************************************/
     897             : 
     898             : // Returnwerte: (BP: ich wuerde es genau umdrehen, aber die UI wuenscht es so)
     899             : // HYPH_CONTINUE, wenn eine Trennstelle anliegt
     900             : // HYPH_OK, wenn der selektierte Bereich abgearbeitet wurde.
     901             : 
     902             : 
     903             : uno::Reference< uno::XInterface >
     904           0 :     SwEditShell::HyphContinue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
     905             : {
     906           0 :     if (pHyphIter->GetSh() != this)
     907           0 :         return 0;
     908             : 
     909           0 :     if( pPageCnt && !*pPageCnt && !*pPageSt )
     910             :     {
     911           0 :         sal_uInt16 nEndPage = GetLayout()->GetPageNum();
     912           0 :         nEndPage += nEndPage * 10 / 100;
     913           0 :         if( nEndPage > 14 )
     914             :         {
     915           0 :             *pPageCnt = nEndPage;
     916           0 :             ::StartProgress( STR_STATSTR_HYPHEN, 0, nEndPage, GetDoc()->GetDocShell());
     917             :         }
     918             :         else                // Hiermit unterdruecken wir ein fuer allemal
     919           0 :             *pPageSt = 1;   // das StatLineStartPercent
     920             :     }
     921             : 
     922             :     OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
     923             :     //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
     924             :     //              KEIN StartAction, da damit auch die Paints abgeschaltet
     925             :     //              werden !!!!!
     926           0 :     ++nStartAction;
     927           0 :     uno::Reference< uno::XInterface >  xRet;
     928           0 :     pHyphIter->Continue( pPageCnt, pPageSt ) >>= xRet;
     929           0 :     --nStartAction;
     930             : 
     931           0 :     if( xRet.is() )
     932           0 :         pHyphIter->ShowSelection();
     933             : 
     934           0 :     return xRet;
     935             : }
     936             : 
     937             : 
     938             : /*************************************************************************
     939             :  *                  SwEditShell::InsertSoftHyph
     940             :  *************************************************************************/
     941             : 
     942             : // Zum Einfuegen des SoftHyphens, Position ist der Offset
     943             : // innerhalb des getrennten Wortes.
     944             : 
     945             : 
     946           0 : void SwEditShell::InsertSoftHyph( const xub_StrLen nHyphPos )
     947             : {
     948             :     OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
     949           0 :     pHyphIter->InsertSoftHyph( nHyphPos );
     950           0 : }
     951             : 
     952             : 
     953             : /*************************************************************************
     954             :  *                  SwEditShell::HyphIgnore
     955             :  *************************************************************************/
     956             : 
     957             : // Beschreibung: Trennstelle ignorieren
     958             : 
     959           0 : void SwEditShell::HyphIgnore()
     960             : {
     961             :     OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
     962             :     //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
     963             :     //              KEIN StartAction, da damit auch die Paints abgeschaltet
     964             :     //              werden !!!!!
     965           0 :     ++nStartAction;
     966           0 :     pHyphIter->Ignore();
     967           0 :     --nStartAction;
     968             : 
     969           0 :     pHyphIter->ShowSelection();
     970           0 : }
     971             : 
     972             : /*************************************************************************
     973             :  *                  SwEditShell::GetCorrection()
     974             :  * liefert eine Liste von Vorschlaegen fuer falsch geschriebene Worte,
     975             :  * ein NULL-Pointer signalisiert, dass das Wort richtig geschrieben ist,
     976             :  * eine leere Liste, dass das Wort zwar unbekannt ist, aber keine Alternativen
     977             :  * geliefert werden koennen.
     978             :  *************************************************************************/
     979             : 
     980             : 
     981             : uno::Reference< XSpellAlternatives >
     982           0 :     SwEditShell::GetCorrection( const Point* pPt, SwRect& rSelectRect )
     983             : {
     984           0 :      uno::Reference< XSpellAlternatives >  xSpellAlt;
     985             : 
     986           0 :     if( IsTableMode() )
     987           0 :         return NULL;
     988           0 :     SwPaM* pCrsr = GetCrsr();
     989           0 :     SwPosition aPos( *pCrsr->GetPoint() );
     990           0 :      Point aPt( *pPt );
     991           0 :     SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
     992             :     SwTxtNode *pNode;
     993             :     SwWrongList *pWrong;
     994           0 :     if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
     995           0 :         0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
     996             :         0 != (pWrong = pNode->GetWrong()) &&
     997           0 :         !pNode->IsInProtectSect() )
     998             :     {
     999           0 :         xub_StrLen nBegin = aPos.nContent.GetIndex();
    1000           0 :         xub_StrLen nLen = 1;
    1001           0 :         if( pWrong->InWrongWord(nBegin,nLen) && !pNode->IsSymbol(nBegin) )
    1002             :         {
    1003           0 :             String aText( pNode->GetTxt().Copy( nBegin, nLen ) );
    1004           0 :             String aWord( aText );
    1005           0 :             aWord = comphelper::string::remove(aWord, CH_TXTATR_BREAKWORD);
    1006           0 :             aWord = comphelper::string::remove(aWord, CH_TXTATR_INWORD);
    1007             : 
    1008           0 :             uno::Reference< XSpellChecker1 >  xSpell( ::GetSpellChecker() );
    1009           0 :             if( xSpell.is() )
    1010             :             {
    1011           0 :                 LanguageType eActLang = (LanguageType)pNode->GetLang( nBegin, nLen );
    1012           0 :                 if( xSpell->hasLanguage( eActLang ))
    1013             :                 {
    1014             :                     // restrict the maximal number of suggestions displayed
    1015             :                     // in the context menu.
    1016             :                     // Note: That could of course be done by clipping the
    1017             :                     // resulting sequence but the current third party
    1018             :                     // implementations result differs greatly if the number of
    1019             :                     // suggestions to be retuned gets changed. Statistically
    1020             :                     // it gets much better if told to return e.g. only 7 strings
    1021             :                     // than returning e.g. 16 suggestions and using only the
    1022             :                     // first 7. Thus we hand down the value to use to that
    1023             :                     // implementation here by providing an additional parameter.
    1024           0 :                     Sequence< PropertyValue > aPropVals(1);
    1025           0 :                     PropertyValue &rVal = aPropVals.getArray()[0];
    1026           0 :                     rVal.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( UPN_MAX_NUMBER_OF_SUGGESTIONS ));
    1027           0 :                     rVal.Value <<= (sal_Int16) 7;
    1028             : 
    1029           0 :                     xSpellAlt = xSpell->spell( aWord, eActLang, aPropVals );
    1030             :                 }
    1031             :             }
    1032             : 
    1033           0 :             if ( xSpellAlt.is() )   // error found?
    1034             :             {
    1035             :                 //save the start and end positons of the line and the starting point
    1036           0 :                 Push();
    1037           0 :                 LeftMargin();
    1038           0 :                 xub_StrLen nLineStart = GetCrsr()->GetPoint()->nContent.GetIndex();
    1039           0 :                 RightMargin();
    1040           0 :                 xub_StrLen nLineEnd = GetCrsr()->GetPoint()->nContent.GetIndex();
    1041           0 :                 Pop(sal_False);
    1042             : 
    1043             :                 // make sure the selection build later from the data below does
    1044             :                 // not "in word" character to the left and right in order to
    1045             :                 // preserve those. Therefore count those "in words" in order to
    1046             :                 // modify the selection accordingly.
    1047           0 :                 const sal_Unicode* pChar = aText.GetBuffer();
    1048           0 :                 xub_StrLen nLeft = 0;
    1049           0 :                 while (pChar && *pChar++ == CH_TXTATR_INWORD)
    1050           0 :                     ++nLeft;
    1051           0 :                 pChar = aText.Len() ? aText.GetBuffer() + aText.Len() - 1 : 0;
    1052           0 :                 xub_StrLen nRight = 0;
    1053           0 :                 while (pChar && *pChar-- == CH_TXTATR_INWORD)
    1054           0 :                     ++nRight;
    1055             : 
    1056           0 :                 aPos.nContent = nBegin + nLeft;
    1057           0 :                 pCrsr = GetCrsr();
    1058           0 :                 *pCrsr->GetPoint() = aPos;
    1059           0 :                 pCrsr->SetMark();
    1060           0 :                 ExtendSelection( sal_True, nLen - nLeft - nRight );
    1061             :                 //no determine the rectangle in the current line
    1062           0 :                 xub_StrLen nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
    1063             :                 //take one less than the line end - otherwise the next line would be calculated
    1064           0 :                 xub_StrLen nWordEnd = (nBegin + nLen - nLeft - nRight) > nLineEnd ? nLineEnd: (nBegin + nLen - nLeft - nRight);
    1065           0 :                 Push();
    1066           0 :                 pCrsr->DeleteMark();
    1067           0 :                 SwIndex& rContent = GetCrsr()->GetPoint()->nContent;
    1068           0 :                 rContent = nWordStart;
    1069           0 :                 SwRect aStartRect;
    1070           0 :                 SwCrsrMoveState aState;
    1071           0 :                 aState.bRealWidth = sal_True;
    1072           0 :                 SwCntntNode* pCntntNode = pCrsr->GetCntntNode();
    1073           0 :                 SwCntntFrm *pCntntFrame = pCntntNode->getLayoutFrm( GetLayout(), pPt, pCrsr->GetPoint(), sal_False);
    1074             : 
    1075           0 :                 pCntntFrame->GetCharRect( aStartRect, *pCrsr->GetPoint(), &aState );
    1076           0 :                 rContent = nWordEnd - 1;
    1077           0 :                 SwRect aEndRect;
    1078           0 :                 pCntntFrame->GetCharRect( aEndRect, *pCrsr->GetPoint(),&aState );
    1079           0 :                 rSelectRect = aStartRect.Union( aEndRect );
    1080           0 :                 Pop(sal_False);
    1081           0 :             }
    1082             :         }
    1083             :     }
    1084           0 :     return xSpellAlt;
    1085             : }
    1086             : 
    1087             : 
    1088             : 
    1089           0 : bool SwEditShell::GetGrammarCorrection(
    1090             :     linguistic2::ProofreadingResult /*out*/ &rResult,    // the complete result
    1091             :     sal_Int32 /*out*/ &rErrorPosInText,                     // offset of error position in string that was grammar checked...
    1092             :     sal_Int32 /*out*/ &rErrorIndexInResult,                 // index of error in rResult.aGrammarErrors
    1093             :     uno::Sequence< rtl::OUString > /*out*/ &rSuggestions,   // suggestions to be used for the error found
    1094             :     const Point *pPt, SwRect &rSelectRect )
    1095             : {
    1096           0 :     bool bRes = false;
    1097             : 
    1098           0 :     if( IsTableMode() )
    1099           0 :         return bRes;
    1100             : 
    1101           0 :     SwPaM* pCrsr = GetCrsr();
    1102           0 :     SwPosition aPos( *pCrsr->GetPoint() );
    1103           0 :     Point aPt( *pPt );
    1104           0 :     SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
    1105             :     SwTxtNode *pNode;
    1106             :     SwGrammarMarkUp *pWrong;
    1107           0 :     if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
    1108           0 :         0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
    1109             :         0 != (pWrong = pNode->GetGrammarCheck()) &&
    1110           0 :         !pNode->IsInProtectSect() )
    1111             :     {
    1112           0 :         xub_StrLen nBegin = aPos.nContent.GetIndex();
    1113           0 :         xub_StrLen nLen = 1;
    1114           0 :         if (pWrong->InWrongWord(nBegin, nLen))
    1115             :         {
    1116           0 :             String aText( pNode->GetTxt().Copy( nBegin, nLen ) );
    1117             : 
    1118           0 :             uno::Reference< linguistic2::XProofreadingIterator >  xGCIterator( pDoc->GetGCIterator() );
    1119           0 :             if (xGCIterator.is())
    1120             :             {
    1121             : //                LanguageType eActLang = (LanguageType)pNode->GetLang( nBegin, nLen );
    1122           0 :                 uno::Reference< lang::XComponent > xDoc( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY );
    1123             : 
    1124             :                 // Expand the string:
    1125           0 :                 const ModelToViewHelper aConversionMap(*pNode);
    1126           0 :                 rtl::OUString aExpandText = aConversionMap.getViewText();
    1127             :                 // get XFlatParagraph to use...
    1128           0 :                 uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *pNode, aExpandText, aConversionMap );
    1129             : 
    1130             :                 // get error position of cursor in XFlatParagraph
    1131           0 :                 rErrorPosInText = aConversionMap.ConvertToViewPosition( nBegin );
    1132             : 
    1133           0 :                 sal_Int32 nStartOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceStart( nBegin ) );
    1134           0 :                 sal_Int32 nEndOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceEnd( nBegin ) );
    1135           0 :                 if( nEndOfSentence == STRING_LEN )
    1136             :                 {
    1137           0 :                         nEndOfSentence = aExpandText.getLength();
    1138             :                 }
    1139             : 
    1140           0 :                 rResult = xGCIterator->checkSentenceAtPosition(
    1141           0 :                         xDoc, xFlatPara, aExpandText, lang::Locale(), nStartOfSentence, nEndOfSentence, rErrorPosInText );
    1142           0 :                 bRes = true;
    1143             : 
    1144             :                 // get suggestions to use for the specific error position
    1145           0 :                 sal_Int32 nErrors = rResult.aErrors.getLength();
    1146           0 :                 rSuggestions.realloc( 0 );
    1147           0 :                 for (sal_Int32 i = 0;  i < nErrors; ++i )
    1148             :                 {
    1149             :                     // return suggestions for first error that includes the given error position
    1150           0 :                     const linguistic2::SingleProofreadingError &rError = rResult.aErrors[i];
    1151           0 :                     if (rError.nErrorStart <= rErrorPosInText &&
    1152             :                         rErrorPosInText + nLen <= rError.nErrorStart + rError.nErrorLength)
    1153             :                     {
    1154           0 :                         rSuggestions = rError.aSuggestions;
    1155           0 :                         rErrorIndexInResult = i;
    1156           0 :                         break;
    1157             :                     }
    1158           0 :                 }
    1159             :             }
    1160             : 
    1161           0 :             if (rResult.aErrors.getLength() > 0)    // error found?
    1162             :             {
    1163             :                 //save the start and end positons of the line and the starting point
    1164           0 :                 Push();
    1165           0 :                 LeftMargin();
    1166           0 :                 xub_StrLen nLineStart = GetCrsr()->GetPoint()->nContent.GetIndex();
    1167           0 :                 RightMargin();
    1168           0 :                 xub_StrLen nLineEnd = GetCrsr()->GetPoint()->nContent.GetIndex();
    1169           0 :                 Pop(sal_False);
    1170             : 
    1171             :                 // make sure the selection build later from the data below does
    1172             :                 // not include "in word" character to the left and right in
    1173             :                 // order to preserve those. Therefore count those "in words" in
    1174             :                 // order to modify the selection accordingly.
    1175           0 :                 const sal_Unicode* pChar = aText.GetBuffer();
    1176           0 :                 xub_StrLen nLeft = 0;
    1177           0 :                 while (pChar && *pChar++ == CH_TXTATR_INWORD)
    1178           0 :                     ++nLeft;
    1179           0 :                 pChar = aText.Len() ? aText.GetBuffer() + aText.Len() - 1 : 0;
    1180           0 :                 xub_StrLen nRight = 0;
    1181           0 :                 while (pChar && *pChar-- == CH_TXTATR_INWORD)
    1182           0 :                     ++nRight;
    1183             : 
    1184           0 :                 aPos.nContent = nBegin + nLeft;
    1185           0 :                 pCrsr = GetCrsr();
    1186           0 :                 *pCrsr->GetPoint() = aPos;
    1187           0 :                 pCrsr->SetMark();
    1188           0 :                 ExtendSelection( sal_True, nLen - nLeft - nRight );
    1189             :                 //no determine the rectangle in the current line
    1190           0 :                 xub_StrLen nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
    1191             :                 //take one less than the line end - otherwise the next line would be calculated
    1192           0 :                 xub_StrLen nWordEnd = (nBegin + nLen - nLeft - nRight) > nLineEnd ? nLineEnd: (nBegin + nLen - nLeft - nRight);
    1193           0 :                 Push();
    1194           0 :                 pCrsr->DeleteMark();
    1195           0 :                 SwIndex& rContent = GetCrsr()->GetPoint()->nContent;
    1196           0 :                 rContent = nWordStart;
    1197           0 :                 SwRect aStartRect;
    1198           0 :                 SwCrsrMoveState aState;
    1199           0 :                 aState.bRealWidth = sal_True;
    1200           0 :                 SwCntntNode* pCntntNode = pCrsr->GetCntntNode();
    1201           0 :                 SwCntntFrm *pCntntFrame = pCntntNode->getLayoutFrm( GetLayout(), pPt, pCrsr->GetPoint(), sal_False);
    1202             : 
    1203           0 :                 pCntntFrame->GetCharRect( aStartRect, *pCrsr->GetPoint(), &aState );
    1204           0 :                 rContent = nWordEnd - 1;
    1205           0 :                 SwRect aEndRect;
    1206           0 :                 pCntntFrame->GetCharRect( aEndRect, *pCrsr->GetPoint(),&aState );
    1207           0 :                 rSelectRect = aStartRect.Union( aEndRect );
    1208           0 :                 Pop(sal_False);
    1209           0 :             }
    1210             :         }
    1211             :     }
    1212             : 
    1213           0 :     return bRes;
    1214             : }
    1215             : 
    1216           0 : bool SwEditShell::SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammarCheck)
    1217             : {
    1218             :     OSL_ENSURE(  pSpellIter, "SpellIter missing" );
    1219           0 :     if(!pSpellIter)
    1220           0 :         return false;
    1221           0 :     bool bRet = pSpellIter->SpellSentence(rPortions, bIsGrammarCheck);
    1222             : 
    1223             :     // make Selection visible - this should simply move the
    1224             :     // cursor to the end of the sentence
    1225           0 :     StartAction();
    1226           0 :     EndAction();
    1227           0 :     return bRet;
    1228             : }
    1229             : /*-------------------------------------------------------------------------
    1230             :     make SpellIter start with the current sentence when called next time
    1231             :   -----------------------------------------------------------------------*/
    1232           0 : void SwEditShell::PutSpellingToSentenceStart()
    1233             : {
    1234             :     OSL_ENSURE(  pSpellIter, "SpellIter missing" );
    1235           0 :     if(!pSpellIter)
    1236           0 :         return;
    1237           0 :     pSpellIter->ToSentenceStart();
    1238             : }
    1239             : 
    1240           0 : static sal_uInt32 lcl_CountRedlines(
    1241             :                             const ::svx::SpellPortions& rLastPortions)
    1242             : {
    1243           0 :     sal_uInt32 nRet = 0;
    1244           0 :     SpellPortions::const_iterator aIter = rLastPortions.begin();
    1245           0 :     for( ; aIter != rLastPortions.end(); ++aIter)
    1246             :     {
    1247           0 :         if( aIter->bIsHidden )
    1248           0 :             ++nRet;
    1249             :     }
    1250           0 :     return nRet;
    1251             : }
    1252             : 
    1253           0 : void SwEditShell::MoveContinuationPosToEndOfCheckedSentence()
    1254             : {
    1255             :     // give hint that continuation position for spell/grammar checking is
    1256             :     // at the end of this sentence
    1257           0 :     if (pSpellIter)
    1258             :     {
    1259           0 :         pSpellIter->SetCurr( new SwPosition( *pSpellIter->GetCurrX() ) );
    1260           0 :         pSpellIter->ContinueAfterThisSentence();
    1261             :     }
    1262           0 : }
    1263             : 
    1264             : 
    1265           0 : void SwEditShell::ApplyChangedSentence(const ::svx::SpellPortions& rNewPortions, bool bRecheck)
    1266             : {
    1267             :     // Note: rNewPortions.size() == 0 is valid and happens when the whole
    1268             :     // sentence got removed in the dialog
    1269             : 
    1270             :     OSL_ENSURE(  pSpellIter, "SpellIter missing" );
    1271           0 :     if(pSpellIter &&
    1272           0 :        pSpellIter->GetLastPortions().size() > 0)    // no portions -> no text to be changed
    1273             :     {
    1274           0 :         const SpellPortions& rLastPortions = pSpellIter->GetLastPortions();
    1275           0 :         const SpellContentPositions  rLastPositions = pSpellIter->GetLastPositions();
    1276             :         OSL_ENSURE(rLastPortions.size() > 0 &&
    1277             :                 rLastPortions.size() == rLastPositions.size(),
    1278             :                 "last vectors of spelling results are not set or not equal");
    1279             : 
    1280             :         // iterate over the new portions, beginning at the end to take advantage of the previously
    1281             :         // saved content positions
    1282             : 
    1283           0 :         pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_UI_TEXT_CORRECTION, NULL );
    1284           0 :         StartAction();
    1285             : 
    1286           0 :         SwPaM *pCrsr = GetCrsr();
    1287             :         // save cursor position (which should be at the end of the current sentence)
    1288             :         // for later restoration
    1289           0 :         Push();
    1290             : 
    1291           0 :         sal_uInt32 nRedlinePortions = lcl_CountRedlines(rLastPortions);
    1292           0 :         if((rLastPortions.size() - nRedlinePortions) == rNewPortions.size())
    1293             :         {
    1294             :             OSL_ENSURE( !rNewPortions.empty(), "rNewPortions should not be empty here" );
    1295             :             OSL_ENSURE( !rLastPortions.empty(), "rLastPortions should not be empty here" );
    1296             :             OSL_ENSURE( !rLastPositions.empty(), "rLastPositions should not be empty here" );
    1297             : 
    1298             :             //the simple case: the same number of elements on both sides
    1299             :             //each changed element has to be applied to the corresponding source element
    1300           0 :             svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.end();
    1301           0 :             SpellPortions::const_iterator aCurrentOldPortion = rLastPortions.end();
    1302           0 :             SpellContentPositions::const_iterator aCurrentOldPosition = rLastPositions.end();
    1303           0 :             do
    1304             :             {
    1305           0 :                 --aCurrentNewPortion;
    1306           0 :                 --aCurrentOldPortion;
    1307           0 :                 --aCurrentOldPosition;
    1308             :                 //jump over redline portions
    1309           0 :                 while(aCurrentOldPortion->bIsHidden)
    1310             :                 {
    1311           0 :                     if (aCurrentOldPortion  != rLastPortions.begin() &&
    1312           0 :                         aCurrentOldPosition != rLastPositions.begin())
    1313             :                     {
    1314           0 :                         --aCurrentOldPortion;
    1315           0 :                         --aCurrentOldPosition;
    1316             :                     }
    1317             :                     else
    1318             :                     {
    1319             :                         OSL_FAIL("ApplyChangedSentence: iterator positions broken" );
    1320           0 :                         break;
    1321             :                     }
    1322             :                 }
    1323           0 :                 if ( !pCrsr->HasMark() )
    1324           0 :                     pCrsr->SetMark();
    1325           0 :                 pCrsr->GetPoint()->nContent = aCurrentOldPosition->nLeft;
    1326           0 :                 pCrsr->GetMark()->nContent = aCurrentOldPosition->nRight;
    1327           0 :                 sal_uInt16 nScriptType = GetI18NScriptTypeOfLanguage( aCurrentNewPortion->eLanguage );
    1328           0 :                 sal_uInt16 nLangWhichId = RES_CHRATR_LANGUAGE;
    1329           0 :                 switch(nScriptType)
    1330             :                 {
    1331           0 :                     case SCRIPTTYPE_ASIAN : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
    1332           0 :                     case SCRIPTTYPE_COMPLEX : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
    1333             :                 }
    1334           0 :                 if(aCurrentNewPortion->sText != aCurrentOldPortion->sText)
    1335             :                 {
    1336             :                     //change text ...
    1337           0 :                     pDoc->DeleteAndJoin(*pCrsr);
    1338             :                     // ... and apply language if necessary
    1339           0 :                     if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
    1340           0 :                         SetAttr( SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId), nLangWhichId );
    1341           0 :                     pDoc->InsertString(*pCrsr, aCurrentNewPortion->sText);
    1342             :                 }
    1343           0 :                 else if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
    1344             :                 {
    1345             :                     //apply language
    1346           0 :                     SetAttr( SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId), nLangWhichId );
    1347             :                 }
    1348           0 :                 else if( aCurrentNewPortion->bIgnoreThisError )
    1349             :                 {
    1350             :                     //add the 'ignore' markup to the TextNode's grammar ignore markup list
    1351           0 :                     IgnoreGrammarErrorAt( *pCrsr );
    1352             :                     OSL_FAIL("TODO: add ignore mark to text node");
    1353             :                 }
    1354           0 :                 if(aCurrentNewPortion == rNewPortions.begin())
    1355           0 :                     break;
    1356             :             }
    1357           0 :             while(aCurrentNewPortion != rNewPortions.begin());
    1358             :         }
    1359             :         else
    1360             :         {
    1361             :             OSL_ENSURE( !rLastPositions.empty(), "rLastPositions should not be empty here" );
    1362             : 
    1363             :             //select the complete sentence
    1364           0 :             SpellContentPositions::const_iterator aCurrentEndPosition = rLastPositions.end();
    1365           0 :             --aCurrentEndPosition;
    1366           0 :             SpellContentPositions::const_iterator aCurrentStartPosition = rLastPositions.begin();
    1367           0 :             pCrsr->GetPoint()->nContent = aCurrentStartPosition->nLeft;
    1368           0 :             pCrsr->GetMark()->nContent = aCurrentEndPosition->nRight;
    1369             : 
    1370             :             //delete the sentence completely
    1371           0 :             pDoc->DeleteAndJoin(*pCrsr);
    1372           0 :             svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.begin();
    1373           0 :             while(aCurrentNewPortion != rNewPortions.end())
    1374             :             {
    1375             :                 //set the language attribute
    1376           0 :                 sal_uInt16 nScriptType = GetScriptType();
    1377           0 :                 sal_uInt16 nLangWhichId = RES_CHRATR_LANGUAGE;
    1378           0 :                 switch(nScriptType)
    1379             :                 {
    1380           0 :                     case SCRIPTTYPE_ASIAN : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
    1381           0 :                     case SCRIPTTYPE_COMPLEX : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
    1382             :                 }
    1383           0 :                 SfxItemSet aSet(GetAttrPool(), nLangWhichId, nLangWhichId, 0);
    1384           0 :                 GetCurAttr( aSet );
    1385           0 :                 const SvxLanguageItem& rLang = static_cast<const SvxLanguageItem& >(aSet.Get(nLangWhichId));
    1386           0 :                 if(rLang.GetLanguage() != aCurrentNewPortion->eLanguage)
    1387           0 :                     SetAttr( SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId) );
    1388             :                 //insert the new string
    1389           0 :                 pDoc->InsertString(*pCrsr, aCurrentNewPortion->sText);
    1390             : 
    1391             :                 //set the cursor to the end of the inserted string
    1392           0 :                 *pCrsr->Start() = *pCrsr->End();
    1393           0 :                 ++aCurrentNewPortion;
    1394           0 :             }
    1395             :         }
    1396             : 
    1397             :         // restore cursor to the end of the sentence
    1398             :         // (will work also if the sentence length has changed,
    1399             :         // since cursors get updated automatically!)
    1400           0 :         Pop( sal_False );
    1401             : 
    1402             :         // collapse cursor to the end of the modified sentence
    1403           0 :         *pCrsr->Start() = *pCrsr->End();
    1404           0 :         if (bRecheck)
    1405             :         {
    1406             :             //in grammar check the current sentence has to be checked again
    1407           0 :             GoStartSentence();
    1408             :         }
    1409             :         // set continuation position for spell/grammar checking to the end of this sentence
    1410           0 :         pSpellIter->SetCurr( new SwPosition( *pCrsr->Start() ) );
    1411             : 
    1412           0 :         pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_UI_TEXT_CORRECTION, NULL );
    1413           0 :         EndAction();
    1414             :     }
    1415           0 : }
    1416             : /*-------------------------------------------------------------------------
    1417             :     collect all deleted redlines of the current text node beginning at the
    1418             :     start of the cursor position
    1419             :   -----------------------------------------------------------------------*/
    1420           0 : static SpellContentPositions lcl_CollectDeletedRedlines(SwEditShell* pSh)
    1421             : {
    1422           0 :     SpellContentPositions aRedlines;
    1423           0 :     SwDoc* pDoc = pSh->GetDoc();
    1424           0 :     const bool bShowChg = IDocumentRedlineAccess::IsShowChanges( pDoc->GetRedlineMode() );
    1425           0 :     if ( bShowChg )
    1426             :     {
    1427           0 :         SwPaM *pCrsr = pSh->GetCrsr();
    1428           0 :         const SwPosition* pStartPos = pCrsr->Start();
    1429           0 :         const SwTxtNode* pTxtNode = pCrsr->GetNode()->GetTxtNode();
    1430             : 
    1431           0 :         sal_uInt16 nAct = pDoc->GetRedlinePos( *pTxtNode, USHRT_MAX );
    1432           0 :         const xub_StrLen nStartIndex = pStartPos->nContent.GetIndex();
    1433           0 :         for ( ; nAct < pDoc->GetRedlineTbl().size(); nAct++ )
    1434             :         {
    1435           0 :             const SwRedline* pRed = pDoc->GetRedlineTbl()[ nAct ];
    1436             : 
    1437           0 :             if ( pRed->Start()->nNode > pTxtNode->GetIndex() )
    1438           0 :                 break;
    1439             : 
    1440           0 :             if( nsRedlineType_t::REDLINE_DELETE == pRed->GetType() )
    1441             :             {
    1442             :                 xub_StrLen nStart, nEnd;
    1443           0 :                 pRed->CalcStartEnd( pTxtNode->GetIndex(), nStart, nEnd );
    1444           0 :                 if(nStart >= nStartIndex || nEnd >= nStartIndex)
    1445             :                 {
    1446             :                     SpellContentPosition aAdd;
    1447           0 :                     aAdd.nLeft = nStart;
    1448           0 :                     aAdd.nRight = nEnd;
    1449           0 :                     aRedlines.push_back(aAdd);
    1450             :                 }
    1451             :             }
    1452             :         }
    1453             :     }
    1454           0 :     return aRedlines;
    1455             : }
    1456             : /*-------------------------------------------------------------------------
    1457             :     remove the redline positions after the current selection
    1458             :   -----------------------------------------------------------------------*/
    1459           0 : static void lcl_CutRedlines( SpellContentPositions& aDeletedRedlines, SwEditShell* pSh )
    1460             : {
    1461           0 :     if(!aDeletedRedlines.empty())
    1462             :     {
    1463           0 :         SwPaM *pCrsr = pSh->GetCrsr();
    1464           0 :         const SwPosition* pEndPos = pCrsr->End();
    1465           0 :         xub_StrLen nEnd = pEndPos->nContent.GetIndex();
    1466           0 :         while(!aDeletedRedlines.empty() &&
    1467           0 :                 aDeletedRedlines.back().nLeft > nEnd)
    1468             :         {
    1469           0 :             aDeletedRedlines.pop_back();
    1470             :         }
    1471             :     }
    1472           0 : }
    1473             : 
    1474           0 : static SpellContentPosition  lcl_FindNextDeletedRedline(
    1475             :         const SpellContentPositions& rDeletedRedlines,
    1476             :         xub_StrLen nSearchFrom )
    1477             : {
    1478             :     SpellContentPosition aRet;
    1479           0 :     aRet.nLeft = aRet.nRight = STRING_MAXLEN;
    1480           0 :     if(!rDeletedRedlines.empty())
    1481             :     {
    1482           0 :         SpellContentPositions::const_iterator aIter = rDeletedRedlines.begin();
    1483           0 :         for( ; aIter != rDeletedRedlines.end(); ++aIter)
    1484             :         {
    1485           0 :             if(aIter->nLeft < nSearchFrom)
    1486           0 :                 continue;
    1487           0 :             aRet = *aIter;
    1488           0 :             break;
    1489             :         }
    1490             :     }
    1491           0 :     return aRet;
    1492             : }
    1493             : 
    1494           0 : bool SwSpellIter::SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammarCheck)
    1495             : {
    1496           0 :     bool bRet = false;
    1497           0 :     aLastPortions.clear();
    1498           0 :     aLastPositions.clear();
    1499             : 
    1500           0 :     SwEditShell *pMySh = GetSh();
    1501           0 :     if( !pMySh )
    1502           0 :         return false;
    1503             : 
    1504             :     OSL_ENSURE( GetEnd(), "SwEditShell::SpellSentence() ohne Start?");
    1505             : 
    1506           0 :     uno::Reference< XSpellAlternatives >  xSpellRet;
    1507           0 :     linguistic2::ProofreadingResult aGrammarResult;
    1508           0 :     bool bGoOn = true;
    1509           0 :     bool bGrammarErrorFound = false;
    1510           0 :     do {
    1511           0 :         SwPaM *pCrsr = pMySh->GetCrsr();
    1512           0 :         if ( !pCrsr->HasMark() )
    1513           0 :             pCrsr->SetMark();
    1514             : 
    1515           0 :         *pCrsr->GetPoint() = *GetCurr();
    1516           0 :         *pCrsr->GetMark() = *GetEnd();
    1517             : 
    1518           0 :         if( bBackToStartOfSentence )
    1519             :         {
    1520           0 :             pMySh->GoStartSentence();
    1521           0 :             bBackToStartOfSentence = false;
    1522             :         }
    1523             :         uno::Any aSpellRet =
    1524             :         pMySh->GetDoc()->Spell(*pCrsr,
    1525           0 :                     xSpeller, 0, 0, bIsGrammarCheck );
    1526           0 :         aSpellRet >>= xSpellRet;
    1527           0 :         aSpellRet >>= aGrammarResult;
    1528           0 :         bGoOn = GetCrsrCnt() > 1;
    1529           0 :         bGrammarErrorFound = aGrammarResult.aErrors.getLength() > 0;
    1530           0 :         if( xSpellRet.is() || bGrammarErrorFound )
    1531             :         {
    1532           0 :             bGoOn = false;
    1533           0 :             SwPosition* pNewPoint = new SwPosition( *pCrsr->GetPoint() );
    1534           0 :             SwPosition* pNewMark = new SwPosition( *pCrsr->GetMark() );
    1535             : 
    1536           0 :             SetCurr( pNewPoint );
    1537           0 :             SetCurrX( pNewMark );
    1538             :         }
    1539           0 :         if( bGoOn )
    1540             :         {
    1541           0 :             pMySh->Pop( sal_False );
    1542           0 :             pCrsr = pMySh->GetCrsr();
    1543           0 :             if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
    1544           0 :                 pCrsr->Exchange();
    1545           0 :             SwPosition* pNew = new SwPosition( *pCrsr->GetPoint() );
    1546           0 :             SetStart( pNew );
    1547           0 :             pNew = new SwPosition( *pCrsr->GetMark() );
    1548           0 :             SetEnd( pNew );
    1549           0 :             pNew = new SwPosition( *GetStart() );
    1550           0 :             SetCurr( pNew );
    1551           0 :             pNew = new SwPosition( *pNew );
    1552           0 :             SetCurrX( pNew );
    1553           0 :             pCrsr->SetMark();
    1554           0 :             --GetCrsrCnt();
    1555           0 :         }
    1556             :     }
    1557             :     while ( bGoOn );
    1558           0 :     if(xSpellRet.is() || bGrammarErrorFound)
    1559             :     {
    1560             :         //an error has been found
    1561             :         //To fill the spell portions the beginning of the sentence has to be found
    1562           0 :         SwPaM *pCrsr = pMySh->GetCrsr();
    1563             :         //set the mark to the right if necessary
    1564           0 :         if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
    1565           0 :             pCrsr->Exchange();
    1566             :         //the cursor has to be collapsed on the left to go to the start of the sentence - if sentence ends inside of the error
    1567           0 :         pCrsr->DeleteMark();
    1568           0 :         pCrsr->SetMark();
    1569           0 :         bool bStartSent = 0 != pMySh->GoStartSentence();
    1570           0 :         SpellContentPositions aDeletedRedlines = lcl_CollectDeletedRedlines(pMySh);
    1571           0 :         if(bStartSent)
    1572             :         {
    1573             :             //create a portion from the start part
    1574           0 :             AddPortion(0, 0, aDeletedRedlines);
    1575             :         }
    1576             :         //Set the cursor to the error already found
    1577           0 :         *pCrsr->GetPoint() = *GetCurrX();
    1578           0 :         *pCrsr->GetMark() = *GetCurr();
    1579           0 :         AddPortion(xSpellRet, &aGrammarResult, aDeletedRedlines);
    1580             : 
    1581             : 
    1582             :         //save the end position of the error to continue from here
    1583           0 :         SwPosition aSaveStartPos = *pCrsr->End();
    1584             :         //determine the end of the current sentence
    1585           0 :         if ( *pCrsr->GetPoint() < *pCrsr->GetMark() )
    1586           0 :             pCrsr->Exchange();
    1587             :         //again collapse to start marking after the end of the error
    1588           0 :         pCrsr->DeleteMark();
    1589           0 :         pCrsr->SetMark();
    1590             : 
    1591           0 :         pMySh->GoEndSentence();
    1592           0 :         if( bGrammarErrorFound )
    1593             :         {
    1594           0 :             const ModelToViewHelper aConversionMap(*(SwTxtNode*)pCrsr->GetNode());
    1595           0 :             rtl::OUString aExpandText = aConversionMap.getViewText();
    1596           0 :             xub_StrLen nSentenceEnd = (xub_StrLen)aConversionMap.ConvertToViewPosition( aGrammarResult.nBehindEndOfSentencePosition );
    1597             :             // remove trailing space
    1598           0 :             if( aExpandText[nSentenceEnd - 1] == ' ' )
    1599           0 :                 --nSentenceEnd;
    1600           0 :             if( pCrsr->End()->nContent.GetIndex() < nSentenceEnd )
    1601             :             {
    1602           0 :                 pCrsr->End()->nContent.Assign(
    1603           0 :                     pCrsr->End()->nNode.GetNode().GetCntntNode(), nSentenceEnd);
    1604           0 :             }
    1605             :         }
    1606             : 
    1607           0 :         lcl_CutRedlines( aDeletedRedlines, pMySh );
    1608             :         //save the 'global' end of the spellchecking
    1609           0 :         const SwPosition aSaveEndPos = *GetEnd();
    1610             :         //set the sentence end as 'local' end
    1611           0 :         SetEnd( new SwPosition( *pCrsr->End() ));
    1612             : 
    1613           0 :         *pCrsr->GetPoint() = aSaveStartPos;
    1614           0 :         *pCrsr->GetMark() = *GetEnd();
    1615             :         //now the rest of the sentence has to be searched for errors
    1616             :         // for each error the non-error text between the current and the last error has
    1617             :         // to be added to the portions - if necessary broken into same-language-portions
    1618           0 :         if( !bGrammarErrorFound ) //in grammar check there's only one error returned
    1619             :         {
    1620           0 :             do
    1621             :             {
    1622           0 :                 xSpellRet = 0;
    1623             :                 // don't search for grammar errors here anymore!
    1624             :                 pMySh->GetDoc()->Spell(*pCrsr,
    1625           0 :                             xSpeller, 0, 0, false ) >>= xSpellRet;
    1626           0 :                 if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
    1627           0 :                     pCrsr->Exchange();
    1628           0 :                 SetCurr( new SwPosition( *pCrsr->GetPoint() ));
    1629           0 :                 SetCurrX( new SwPosition( *pCrsr->GetMark() ));
    1630             : 
    1631             :                 //if an error has been found go back to the text
    1632             :                 //preceeding the error
    1633           0 :                 if(xSpellRet.is())
    1634             :                 {
    1635           0 :                     *pCrsr->GetPoint() = aSaveStartPos;
    1636           0 :                     *pCrsr->GetMark() = *GetCurr();
    1637             :                 }
    1638             :                 //add the portion
    1639           0 :                 AddPortion(0, 0, aDeletedRedlines);
    1640             : 
    1641           0 :                 if(xSpellRet.is())
    1642             :                 {
    1643           0 :                     *pCrsr->GetPoint() = *GetCurr();
    1644           0 :                     *pCrsr->GetMark() = *GetCurrX();
    1645           0 :                     AddPortion(xSpellRet, 0, aDeletedRedlines);
    1646             :                     //move the cursor to the end of the error string
    1647           0 :                     *pCrsr->GetPoint() = *GetCurrX();
    1648             :                     //and save the end of the error as new start position
    1649           0 :                     aSaveStartPos = *GetCurrX();
    1650             :                     //and the end of the sentence
    1651           0 :                     *pCrsr->GetMark() = *GetEnd();
    1652             :                 }
    1653             :                 // if the end of the sentence has already been reached then break here
    1654           0 :                 if(*GetCurrX() >= *GetEnd())
    1655           0 :                     break;
    1656             :             }
    1657           0 :             while(xSpellRet.is());
    1658             :         }
    1659             :         else
    1660             :         {
    1661             :             //go to the end of sentence as the grammar check returned it
    1662             :             // at this time the Point is behind the grammar error
    1663             :             // and the mark points to the sentence end as
    1664           0 :             if ( *pCrsr->GetPoint() < *pCrsr->GetMark() )
    1665           0 :                 pCrsr->Exchange();
    1666             :         }
    1667             : 
    1668             :         // the part between the last error and the end of the sentence has to be added
    1669           0 :         *pMySh->GetCrsr()->GetPoint() = *GetEnd();
    1670           0 :         if(*GetCurrX() < *GetEnd())
    1671             :         {
    1672           0 :             AddPortion(0, 0, aDeletedRedlines);
    1673             :         }
    1674             :         //set the shell cursor to the end of the sentence to prevent a visible selection
    1675           0 :         *pCrsr->GetMark() = *GetEnd();
    1676           0 :         if( !bIsGrammarCheck )
    1677             :         {
    1678             :             //set the current position to the end of the sentence
    1679           0 :             SetCurr( new SwPosition(*GetEnd()) );
    1680             :         }
    1681             :         //restore the 'global' end
    1682           0 :         SetEnd( new SwPosition(aSaveEndPos) );
    1683           0 :         rPortions = aLastPortions;
    1684           0 :         bRet = true;
    1685             :     }
    1686             :     else
    1687             :     {
    1688             :         //if no error could be found the selection has to be corrected - at least if it's not in the body
    1689           0 :         *pMySh->GetCrsr()->GetPoint() = *GetEnd();
    1690           0 :         pMySh->GetCrsr()->DeleteMark();
    1691             :     }
    1692             : 
    1693           0 :     return bRet;
    1694             : }
    1695             : 
    1696           0 : void SwSpellIter::ToSentenceStart()
    1697             : {
    1698           0 :     bBackToStartOfSentence = true;
    1699           0 : }
    1700             : 
    1701           0 : static LanguageType lcl_GetLanguage(SwEditShell& rSh)
    1702             : {
    1703           0 :     sal_uInt16 nScriptType = rSh.GetScriptType();
    1704           0 :     sal_uInt16 nLangWhichId = RES_CHRATR_LANGUAGE;
    1705             : 
    1706           0 :     switch(nScriptType)
    1707             :     {
    1708           0 :         case SCRIPTTYPE_ASIAN : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
    1709           0 :         case SCRIPTTYPE_COMPLEX : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
    1710             :     }
    1711           0 :     SfxItemSet aSet(rSh.GetAttrPool(), nLangWhichId, nLangWhichId, 0);
    1712           0 :     rSh.GetCurAttr( aSet );
    1713           0 :     const SvxLanguageItem& rLang = static_cast<const SvxLanguageItem& >(aSet.Get(nLangWhichId));
    1714           0 :     return rLang.GetLanguage();
    1715             : }
    1716             : /*-------------------------------------------------------------------------
    1717             :     create a text portion at the given position
    1718             :   -----------------------------------------------------------------------*/
    1719           0 : void SwSpellIter::CreatePortion(uno::Reference< XSpellAlternatives > xAlt,
    1720             :                         linguistic2::ProofreadingResult* pGrammarResult,
    1721             :         bool bIsField, bool bIsHidden)
    1722             : {
    1723           0 :     svx::SpellPortion aPortion;
    1724           0 :     String sText;
    1725           0 :     GetSh()->GetSelectedText( sText );
    1726           0 :     if(sText.Len())
    1727             :     {
    1728             :         //in case of redlined deletions the selection of an error is not
    1729             :         //the same as the _real_ word
    1730           0 :         if(xAlt.is())
    1731           0 :             aPortion.sText = xAlt->getWord();
    1732           0 :         else if(pGrammarResult)
    1733             :         {
    1734           0 :             aPortion.bIsGrammarError = true;
    1735           0 :             if(pGrammarResult->aErrors.getLength())
    1736             :             {
    1737           0 :                 aPortion.aGrammarError = pGrammarResult->aErrors[0];
    1738           0 :                 aPortion.sText = pGrammarResult->aText.copy( aPortion.aGrammarError.nErrorStart, aPortion.aGrammarError.nErrorLength );
    1739           0 :                 aPortion.xGrammarChecker = pGrammarResult->xProofreader;
    1740           0 :                 const beans::PropertyValue* pProperties = pGrammarResult->aProperties.getConstArray();
    1741           0 :                 for( sal_Int32 nProp = 0; nProp < pGrammarResult->aProperties.getLength(); ++nProp )
    1742             :                 {
    1743           0 :                     if ( pProperties->Name == "DialogTitle" )
    1744             :                     {
    1745           0 :                         pProperties->Value >>= aPortion.sDialogTitle;
    1746           0 :                         break;
    1747             :                     }
    1748             :                 }
    1749             :             }
    1750             :         }
    1751             :         else
    1752           0 :             aPortion.sText = sText;
    1753           0 :         aPortion.eLanguage = lcl_GetLanguage(*GetSh());
    1754           0 :         aPortion.bIsField = bIsField;
    1755           0 :         aPortion.bIsHidden = bIsHidden;
    1756           0 :         aPortion.xAlternatives = xAlt;
    1757             :         SpellContentPosition aPosition;
    1758           0 :         SwPaM *pCrsr = GetSh()->GetCrsr();
    1759           0 :         aPosition.nLeft = pCrsr->Start()->nContent.GetIndex();
    1760           0 :         aPosition.nRight = pCrsr->End()->nContent.GetIndex();
    1761           0 :         aLastPortions.push_back(aPortion);
    1762           0 :         aLastPositions.push_back(aPosition);
    1763           0 :     }
    1764           0 : }
    1765             : 
    1766           0 : void    SwSpellIter::AddPortion(uno::Reference< XSpellAlternatives > xAlt,
    1767             :                                 linguistic2::ProofreadingResult* pGrammarResult,
    1768             :                                 const SpellContentPositions& rDeletedRedlines)
    1769             : {
    1770           0 :     SwEditShell *pMySh = GetSh();
    1771           0 :     String sText;
    1772           0 :     pMySh->GetSelectedText( sText );
    1773           0 :     if(sText.Len())
    1774             :     {
    1775           0 :         if(xAlt.is() || pGrammarResult != 0)
    1776             :         {
    1777           0 :             CreatePortion(xAlt, pGrammarResult, false, false);
    1778             :         }
    1779             :         else
    1780             :         {
    1781           0 :             SwPaM *pCrsr = GetSh()->GetCrsr();
    1782           0 :             if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
    1783           0 :                 pCrsr->Exchange();
    1784             :             //save the start and end positions
    1785           0 :             SwPosition aStart(*pCrsr->GetPoint());
    1786           0 :             SwPosition aEnd(*pCrsr->GetMark());
    1787             :             //iterate over the text to find changes in language
    1788             :             //set the mark equal to the point
    1789           0 :             *pCrsr->GetMark() = aStart;
    1790           0 :             SwTxtNode* pTxtNode = pCrsr->GetNode()->GetTxtNode();
    1791           0 :             LanguageType eStartLanguage = lcl_GetLanguage(*GetSh());
    1792             :             SpellContentPosition  aNextRedline = lcl_FindNextDeletedRedline(
    1793           0 :                         rDeletedRedlines, aStart.nContent.GetIndex() );
    1794           0 :             if( aNextRedline.nLeft == aStart.nContent.GetIndex() )
    1795             :             {
    1796             :                 //select until the end of the current redline
    1797           0 :                 xub_StrLen nEnd = aEnd.nContent.GetIndex() < aNextRedline.nRight ?
    1798           0 :                             aEnd.nContent.GetIndex() : aNextRedline.nRight;
    1799           0 :                 pCrsr->GetPoint()->nContent.Assign( pTxtNode, nEnd );
    1800           0 :                 CreatePortion(xAlt, pGrammarResult, false, true);
    1801           0 :                 aStart = *pCrsr->End();
    1802             :                 //search for next redline
    1803             :                 aNextRedline = lcl_FindNextDeletedRedline(
    1804           0 :                             rDeletedRedlines, aStart.nContent.GetIndex() );
    1805             :             }
    1806           0 :             while(*pCrsr->GetPoint() < aEnd)
    1807             :             {
    1808             :                 //#125786 in table cell with fixed row height the cursor might not move forward
    1809           0 :                 if(!GetSh()->Right(1, CRSR_SKIP_CELLS))
    1810           0 :                     break;
    1811             : 
    1812           0 :                 bool bField = false;
    1813             :                 //read the character at the current position to check if it's a field
    1814           0 :                 sal_Unicode cChar = pTxtNode->GetTxt().GetChar( pCrsr->GetMark()->nContent.GetIndex() );
    1815           0 :                 if( CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar)
    1816             :                 {
    1817             :                     const SwTxtAttr* pTxtAttr = pTxtNode->GetTxtAttrForCharAt(
    1818           0 :                         pCrsr->GetMark()->nContent.GetIndex() );
    1819             :                     const sal_uInt16 nWhich = pTxtAttr
    1820             :                         ? pTxtAttr->Which()
    1821           0 :                         : static_cast<sal_uInt16>(RES_TXTATR_END);
    1822           0 :                     switch (nWhich)
    1823             :                     {
    1824             :                         case RES_TXTATR_FIELD:
    1825             :                         case RES_TXTATR_FTN:
    1826             :                         case RES_TXTATR_FLYCNT:
    1827           0 :                             bField = true;
    1828           0 :                             break;
    1829             :                     }
    1830             :                 }
    1831             : 
    1832           0 :                 LanguageType eCurLanguage = lcl_GetLanguage(*GetSh());
    1833           0 :                 bool bRedline = aNextRedline.nLeft == pCrsr->GetPoint()->nContent.GetIndex();
    1834             :                 // create a portion if the next character
    1835             :                 //  - is a field,
    1836             :                 //  - is at the beginning of a deleted redline
    1837             :                 //  - has a different language
    1838           0 :                 if(bField || bRedline || eCurLanguage != eStartLanguage)
    1839             :                 {
    1840           0 :                     eStartLanguage = eCurLanguage;
    1841             :                     //go one step back - the cursor currently selects the first character
    1842             :                     //with a different language
    1843             :                     //in the case of redlining it's different
    1844           0 :                     if(eCurLanguage != eStartLanguage || bField)
    1845           0 :                         *pCrsr->GetPoint() = *pCrsr->GetMark();
    1846             :                     //set to the last start
    1847           0 :                     *pCrsr->GetMark() = aStart;
    1848             :                     //create portion should only be called if a selection exists
    1849             :                     //there's no selection if there's a field at the beginning
    1850           0 :                     if(*pCrsr->Start() != *pCrsr->End())
    1851           0 :                         CreatePortion(xAlt, pGrammarResult, false, false);
    1852           0 :                     aStart = *pCrsr->End();
    1853             :                     //now export the field - if there is any
    1854           0 :                     if(bField)
    1855             :                     {
    1856           0 :                         *pCrsr->GetMark() = *pCrsr->GetPoint();
    1857           0 :                         GetSh()->Right(1, CRSR_SKIP_CELLS);
    1858           0 :                         CreatePortion(xAlt, pGrammarResult, true, false);
    1859           0 :                         aStart = *pCrsr->End();
    1860             :                     }
    1861             :                 }
    1862             :                 // if a redline start then create a portion for it
    1863           0 :                 if(bRedline)
    1864             :                 {
    1865           0 :                     *pCrsr->GetMark() = *pCrsr->GetPoint();
    1866             :                     //select until the end of the current redline
    1867           0 :                     xub_StrLen nEnd = aEnd.nContent.GetIndex() < aNextRedline.nRight ?
    1868           0 :                                 aEnd.nContent.GetIndex() : aNextRedline.nRight;
    1869           0 :                     pCrsr->GetPoint()->nContent.Assign( pTxtNode, nEnd );
    1870           0 :                     CreatePortion(xAlt, pGrammarResult, false, true);
    1871           0 :                     aStart = *pCrsr->End();
    1872             :                     //search for next redline
    1873             :                     aNextRedline = lcl_FindNextDeletedRedline(
    1874           0 :                                 rDeletedRedlines, aStart.nContent.GetIndex() );
    1875             :                 }
    1876           0 :                 *pCrsr->GetMark() = *pCrsr->GetPoint();
    1877             :             }
    1878           0 :             pCrsr->SetMark();
    1879           0 :             *pCrsr->GetMark() = aStart;
    1880           0 :             CreatePortion(xAlt, pGrammarResult, false, false);
    1881             :         }
    1882           0 :     }
    1883           0 : }
    1884             : 
    1885           0 : void SwEditShell::IgnoreGrammarErrorAt( SwPaM& rErrorPosition )
    1886             : {
    1887             :     SwTxtNode *pNode;
    1888             :     SwWrongList *pWrong;
    1889           0 :     SwNodeIndex aIdx = rErrorPosition.Start()->nNode;
    1890           0 :     SwNodeIndex aEndIdx = rErrorPosition.Start()->nNode;
    1891           0 :     xub_StrLen nStart = rErrorPosition.Start()->nContent.GetIndex();
    1892           0 :     xub_StrLen nEnd = STRING_LEN;
    1893           0 :     while( aIdx <= aEndIdx )
    1894             :     {
    1895           0 :         pNode = aIdx.GetNode().GetTxtNode();
    1896           0 :         if( pNode ) {
    1897           0 :             if( aIdx == aEndIdx )
    1898           0 :                 nEnd = rErrorPosition.End()->nContent.GetIndex();
    1899           0 :             pWrong = pNode->GetGrammarCheck();
    1900           0 :             if( pWrong )
    1901           0 :                 pWrong->RemoveEntry( nStart, nEnd );
    1902           0 :             pWrong = pNode->GetWrong();
    1903           0 :             if( pWrong )
    1904           0 :                 pWrong->RemoveEntry( nStart, nEnd );
    1905           0 :             SwTxtFrm::repaintTextFrames( *pNode );
    1906             :         }
    1907           0 :         ++aIdx;
    1908           0 :         nStart = 0;
    1909           0 :     }
    1910           0 : }
    1911             : 
    1912             : 
    1913             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10