LCOV - code coverage report
Current view: top level - editeng/source/editeng - edtspell.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 95 359 26.5 %
Date: 2012-08-25 Functions: 23 51 45.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 48 484 9.9 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <vcl/wrkwin.hxx>
      31                 :            : #include <vcl/dialog.hxx>
      32                 :            : #include <vcl/msgbox.hxx>
      33                 :            : #include <vcl/svapp.hxx>
      34                 :            : 
      35                 :            : #include <impedit.hxx>
      36                 :            : #include <editeng/editview.hxx>
      37                 :            : #include <editeng/editeng.hxx>
      38                 :            : #include <edtspell.hxx>
      39                 :            : #include <editeng/flditem.hxx>
      40                 :            : #include <editeng/fontitem.hxx>
      41                 :            : #include <svl/intitem.hxx>
      42                 :            : #include <svl/eitem.hxx>
      43                 :            : #include <editeng/unolingu.hxx>
      44                 :            : #include <linguistic/lngprops.hxx>
      45                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      46                 :            : 
      47                 :            : using ::rtl::OUString;
      48                 :            : using namespace com::sun::star::uno;
      49                 :            : using namespace com::sun::star::beans;
      50                 :            : using namespace com::sun::star::linguistic2;
      51                 :            : 
      52                 :            : 
      53                 :         18 : EditSpellWrapper::EditSpellWrapper( Window* _pWin,
      54                 :            :         Reference< XSpellChecker1 >  &xChecker,
      55                 :            :         sal_Bool bIsStart, sal_Bool bIsAllRight, EditView* pView ) :
      56                 :         18 :     SvxSpellWrapper( _pWin, xChecker, bIsStart, bIsAllRight )
      57                 :            : {
      58                 :            :     SAL_WARN_IF( !pView, "editeng", "One view has to be abandoned!" );
      59                 :            :     // Keep IgnoreList, delete ReplaceList...
      60 [ -  + ][ +  - ]:         18 :     if (SvxGetChangeAllList().is())
      61 [ #  # ][ #  # ]:          0 :         SvxGetChangeAllList()->clear();
                 [ #  # ]
      62                 :         18 :     pEditView = pView;
      63                 :         18 : }
      64                 :            : 
      65                 :         18 : void EditSpellWrapper::SpellStart( SvxSpellArea eArea )
      66                 :            : {
      67                 :         18 :     EditEngine* pEE = pEditView->GetEditEngine();
      68                 :         18 :     ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
      69                 :         18 :     SpellInfo* pSpellInfo = pImpEE->GetSpellInfo();
      70                 :            : 
      71         [ -  + ]:         18 :     if ( eArea == SVX_SPELL_BODY_START )
      72                 :            :     {
      73                 :            :         // Is called when
      74                 :            :         // a) Spell-Forward has arrived at the end and should restart at the top
      75                 :            :         // IsEndDone() returns also sal_True, when backward-spelling is started at the end!
      76         [ #  # ]:          0 :         if ( IsEndDone() )
      77                 :            :         {
      78                 :          0 :             pSpellInfo->bSpellToEnd = sal_False;
      79                 :          0 :             pSpellInfo->aSpellTo = pSpellInfo->aSpellStart;
      80                 :            :             pEditView->GetImpEditView()->SetEditSelection(
      81 [ #  # ][ #  # ]:          0 :                     pEE->GetEditDoc().GetStartPaM() );
      82                 :            :         }
      83                 :            :         else
      84                 :            :         {
      85                 :          0 :             pSpellInfo->bSpellToEnd = sal_True;
      86                 :            :             pSpellInfo->aSpellTo = pImpEE->CreateEPaM(
      87         [ #  # ]:          0 :                     pEE->GetEditDoc().GetStartPaM() );
      88                 :            :         }
      89                 :            :     }
      90         [ +  - ]:         18 :     else if ( eArea == SVX_SPELL_BODY_END )
      91                 :            :     {
      92                 :            :         // Is called when
      93                 :            :         // a) Spell-Forward is launched
      94                 :            :         // IsStartDone() return also sal_True, when forward-spelling is started at the beginning!
      95         [ -  + ]:         18 :         if ( !IsStartDone() )
      96                 :            :         {
      97                 :          0 :             pSpellInfo->bSpellToEnd = sal_True;
      98                 :            :             pSpellInfo->aSpellTo = pImpEE->CreateEPaM(
      99         [ #  # ]:          0 :                     pEE->GetEditDoc().GetEndPaM() );
     100                 :            :         }
     101                 :            :         else
     102                 :            :         {
     103                 :         18 :             pSpellInfo->bSpellToEnd = sal_False;
     104                 :         18 :             pSpellInfo->aSpellTo = pSpellInfo->aSpellStart;
     105                 :            :             pEditView->GetImpEditView()->SetEditSelection(
     106 [ +  - ][ +  - ]:         18 :                     pEE->GetEditDoc().GetEndPaM() );
     107                 :            :         }
     108                 :            :     }
     109                 :            :     else if ( eArea == SVX_SPELL_BODY )
     110                 :            :     {
     111                 :            :         ;   // Is handled by the App through SpellNextDocument
     112                 :            :     }
     113                 :            :     else
     114                 :            :     {
     115                 :            :         OSL_FAIL( "SpellStart: Unknown Area!" );
     116                 :            :     }
     117                 :         18 : }
     118                 :            : 
     119                 :         18 : sal_Bool EditSpellWrapper::SpellContinue()
     120                 :            : {
     121         [ +  - ]:         18 :     SetLast( pEditView->GetImpEditEngine()->ImpSpell( pEditView ) );
     122                 :         18 :     return GetLast().is();
     123                 :            : }
     124                 :            : 
     125                 :         18 : void EditSpellWrapper::SpellEnd()
     126                 :            : {
     127                 :            :     // Base class will show language errors...
     128                 :         18 :     SvxSpellWrapper::SpellEnd();
     129                 :         18 : }
     130                 :            : 
     131                 :          0 : sal_Bool EditSpellWrapper::HasOtherCnt()
     132                 :            : {
     133                 :          0 :     return sal_False;
     134                 :            : }
     135                 :            : 
     136                 :         18 : sal_Bool EditSpellWrapper::SpellMore()
     137                 :            : {
     138                 :         18 :     EditEngine* pEE = pEditView->GetEditEngine();
     139                 :         18 :     ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
     140                 :         18 :     SpellInfo* pSpellInfo = pImpEE->GetSpellInfo();
     141                 :         18 :     sal_Bool bMore = sal_False;
     142         [ -  + ]:         18 :     if ( pSpellInfo->bMultipleDoc )
     143                 :            :     {
     144                 :          0 :         bMore = pEE->SpellNextDocument();
     145         [ #  # ]:          0 :         if ( bMore )
     146                 :            :         {
     147                 :            :             // The text has been entered into the engine, when backwords then
     148                 :            :             // it must be behind the selection.
     149         [ #  # ]:          0 :             Reference< XPropertySet >  xProp( SvxGetLinguPropertySet() );
     150                 :            :             pEditView->GetImpEditView()->SetEditSelection(
     151 [ #  # ][ #  # ]:          0 :                         pEE->GetEditDoc().GetStartPaM() );
         [ #  # ][ #  # ]
     152                 :            :         }
     153                 :            :     }
     154                 :         18 :     return bMore;
     155                 :            : }
     156                 :            : 
     157                 :          0 : void EditSpellWrapper::ScrollArea()
     158                 :            : {
     159                 :            :     // No further action needed ...
     160                 :            :     // Except for, that the area is to be scrolled in the center, and not stand
     161                 :            :     // still anywhere.
     162                 :          0 : }
     163                 :            : 
     164                 :          0 : void EditSpellWrapper::ReplaceAll( const String &rNewText,
     165                 :            :             sal_Int16 )
     166                 :            : {
     167                 :            :     // Is called when the word is in ReplaceList of the spell checker
     168                 :          0 :     pEditView->InsertText( rNewText );
     169                 :          0 :     CheckSpellTo();
     170                 :          0 : }
     171                 :            : 
     172                 :          0 : void EditSpellWrapper::ChangeWord( const String& rNewWord,
     173                 :            :             const sal_uInt16 )
     174                 :            : {
     175                 :            :     // Will be called when Word Button Change
     176                 :            :     // or internally by me ChangeAll
     177                 :            : 
     178                 :            :     // If there is a dot Punkt after the word, this dot will be stripped away.
     179                 :            :     // If '"' => PreStripped.
     180         [ #  # ]:          0 :     String aNewWord( rNewWord );
     181         [ #  # ]:          0 :     pEditView->InsertText( aNewWord );
     182 [ #  # ][ #  # ]:          0 :     CheckSpellTo();
     183                 :          0 : }
     184                 :            : 
     185                 :          0 : void EditSpellWrapper::ChangeThesWord( const String& rNewWord )
     186                 :            : {
     187                 :          0 :     pEditView->InsertText( rNewWord );
     188                 :          0 :     CheckSpellTo();
     189                 :          0 : }
     190                 :            : 
     191                 :          0 : void EditSpellWrapper::AutoCorrect( const String&, const String& )
     192                 :            : {
     193                 :          0 : }
     194                 :            : 
     195                 :          0 : void EditSpellWrapper::CheckSpellTo()
     196                 :            : {
     197         [ #  # ]:          0 :     ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
     198                 :          0 :     SpellInfo* pSpellInfo = pImpEE->GetSpellInfo();
     199         [ #  # ]:          0 :     EditPaM aPaM( pEditView->GetImpEditView()->GetEditSelection().Max() );
     200         [ #  # ]:          0 :     EPaM aEPaM = pImpEE->CreateEPaM( aPaM );
     201         [ #  # ]:          0 :     if ( aEPaM.nPara == pSpellInfo->aSpellTo.nPara )
     202                 :            :     {
     203                 :            :         // Check if SpellToEnd still has a valid Index, if replace has been
     204                 :            :         // performed in the paragraph.
     205 [ #  # ][ #  # ]:          0 :         if ( pSpellInfo->aSpellTo.nIndex > aPaM.GetNode()->Len() )
                 [ #  # ]
     206 [ #  # ][ #  # ]:          0 :             pSpellInfo->aSpellTo.nIndex = aPaM.GetNode()->Len();
     207                 :            :     }
     208                 :          0 : }
     209                 :            : 
     210                 :            : //////////////////////////////////////////////////////////////////////
     211                 :            : 
     212                 :            : #define NOT_INVALID 0xFFFF
     213                 :            : 
     214                 :      37883 : WrongList::WrongList() : nInvalidStart(0), nInvalidEnd(0xFFFF) {}
     215                 :            : 
     216                 :      21645 : WrongList::WrongList(const WrongList& r) :
     217                 :            :     maRanges(r.maRanges),
     218                 :            :     nInvalidStart(r.nInvalidStart),
     219                 :      21645 :     nInvalidEnd(r.nInvalidEnd) {}
     220                 :            : 
     221                 :      59465 : WrongList::~WrongList() {}
     222                 :            : 
     223                 :      23256 : bool WrongList::IsInvalid() const
     224                 :            : {
     225                 :      23256 :     return nInvalidStart != NOT_INVALID;
     226                 :            : }
     227                 :            : 
     228                 :       2952 : void WrongList::SetValid()
     229                 :            : {
     230                 :       2952 :     nInvalidStart = NOT_INVALID;
     231                 :       2952 :     nInvalidEnd = 0;
     232                 :       2952 : }
     233                 :            : 
     234                 :       1005 : void WrongList::MarkInvalid( sal_uInt16 nS, sal_uInt16 nE )
     235                 :            : {
     236 [ +  + ][ -  + ]:       1005 :     if ( ( nInvalidStart == NOT_INVALID ) || ( nInvalidStart > nS ) )
     237                 :        408 :         nInvalidStart = nS;
     238         [ +  + ]:       1005 :     if ( nInvalidEnd < nE )
     239                 :        486 :         nInvalidEnd = nE;
     240                 :       1005 : }
     241                 :            : 
     242                 :      20147 : void WrongList::TextInserted( sal_uInt16 nPos, sal_uInt16 nNew, sal_Bool bPosIsSep )
     243                 :            : {
     244         [ -  + ]:      20147 :     if ( !IsInvalid() )
     245                 :            :     {
     246                 :          0 :         nInvalidStart = nPos;
     247                 :          0 :         nInvalidEnd = nPos+nNew;
     248                 :            :     }
     249                 :            :     else
     250                 :            :     {
     251         [ -  + ]:      20147 :         if ( nInvalidStart > nPos )
     252                 :          0 :             nInvalidStart = nPos;
     253         [ +  - ]:      20147 :         if ( nInvalidEnd >= nPos )
     254                 :      20147 :             nInvalidEnd = nInvalidEnd + nNew;
     255                 :            :         else
     256                 :          0 :             nInvalidEnd = nPos+nNew;
     257                 :            :     }
     258                 :            : 
     259         [ -  + ]:      20147 :     for (size_t i = 0, n = maRanges.size(); i < n; ++i)
     260                 :            :     {
     261                 :          0 :         WrongRange& rWrong = maRanges[i];
     262                 :          0 :         bool bRefIsValid = true;
     263         [ #  # ]:          0 :         if (rWrong.nEnd >= nPos)
     264                 :            :         {
     265                 :            :             // Move all Wrongs after the insert position...
     266         [ #  # ]:          0 :             if (rWrong.nStart > nPos)
     267                 :            :             {
     268                 :          0 :                 rWrong.nStart += nNew;
     269                 :          0 :                 rWrong.nEnd += nNew;
     270                 :            :             }
     271                 :            :             // 1: Starts before and goes until nPos...
     272         [ #  # ]:          0 :             else if (rWrong.nEnd == nPos)
     273                 :            :             {
     274                 :            :                 // Should be halted at a blank!
     275         [ #  # ]:          0 :                 if ( !bPosIsSep )
     276                 :          0 :                     rWrong.nEnd += nNew;
     277                 :            :             }
     278                 :            :             // 2: Starts before and goes until after nPos...
     279 [ #  # ][ #  # ]:          0 :             else if ((rWrong.nStart < nPos) && (rWrong.nEnd > nPos))
     280                 :            :             {
     281                 :          0 :                 rWrong.nEnd += nNew;
     282                 :            :                 // When a separator remove and re-examine the Wrong
     283         [ #  # ]:          0 :                 if ( bPosIsSep )
     284                 :            :                 {
     285                 :            :                     // Split Wrong...
     286                 :          0 :                     WrongRange aNewWrong(rWrong.nStart, nPos);
     287                 :          0 :                     rWrong.nStart = nPos + 1;
     288 [ #  # ][ #  # ]:          0 :                     maRanges.insert(maRanges.begin() + i, aNewWrong);
     289                 :            :                     // Reference no longer valid after Insert, the other
     290                 :            :                     // was inserted in front of this position
     291                 :          0 :                     bRefIsValid = false;
     292                 :          0 :                     ++i; // Not this again...
     293                 :          0 :                 }
     294                 :            :             }
     295                 :            :             // 3: Attribute starts at position ..
     296         [ #  # ]:          0 :             else if (rWrong.nStart == nPos)
     297                 :            :             {
     298                 :          0 :                 rWrong.nEnd += nNew;
     299         [ #  # ]:          0 :                 if ( bPosIsSep )
     300                 :          0 :                     ++(rWrong.nStart);
     301                 :            :             }
     302                 :            :         }
     303                 :            :         SAL_WARN_IF(bRefIsValid && rWrong.nStart >= rWrong.nEnd, "editeng",
     304                 :            :                 "TextInserted, WrongRange: Start >= End?!");
     305                 :            :         (void)bRefIsValid;
     306                 :            :     }
     307                 :            : 
     308                 :            :     SAL_WARN_IF(DbgIsBuggy(), "editeng", "InsertWrong: WrongList broken!");
     309                 :      20147 : }
     310                 :            : 
     311                 :         81 : void WrongList::TextDeleted( sal_uInt16 nPos, sal_uInt16 nDeleted )
     312                 :            : {
     313                 :         81 :     sal_uInt16 nEndChanges = nPos+nDeleted;
     314         [ -  + ]:         81 :     if ( !IsInvalid() )
     315                 :            :     {
     316         [ #  # ]:          0 :         sal_uInt16 nNewInvalidStart = nPos ? nPos - 1 : 0;
     317                 :          0 :         nInvalidStart = nNewInvalidStart;
     318                 :          0 :         nInvalidEnd = nNewInvalidStart + 1;
     319                 :            :     }
     320                 :            :     else
     321                 :            :     {
     322         [ -  + ]:         81 :         if ( nInvalidStart > nPos )
     323                 :          0 :             nInvalidStart = nPos;
     324         [ -  + ]:         81 :         if ( nInvalidEnd > nPos )
     325                 :            :         {
     326         [ #  # ]:          0 :             if ( nInvalidEnd > nEndChanges )
     327                 :          0 :                 nInvalidEnd = nInvalidEnd - nDeleted;
     328                 :            :             else
     329                 :          0 :                 nInvalidEnd = nPos+1;
     330                 :            :         }
     331                 :            :     }
     332                 :            : 
     333 [ +  - ][ -  + ]:         81 :     for (WrongList::iterator i = begin(); i != end(); )
     334                 :            :     {
     335                 :          0 :         sal_Bool bDelWrong = sal_False;
     336         [ #  # ]:          0 :         if (i->nEnd >= nPos)
     337                 :            :         {
     338                 :            :             // Move all Wrongs after the insert position...
     339         [ #  # ]:          0 :             if (i->nStart >= nEndChanges)
     340                 :            :             {
     341                 :          0 :                 i->nStart -= nDeleted;
     342                 :          0 :                 i->nEnd -= nDeleted;
     343                 :            :             }
     344                 :            :             // 1. Delete Internal Wrongs ...
     345 [ #  # ][ #  # ]:          0 :             else if (i->nStart >= nPos && i->nEnd <= nEndChanges)
                 [ #  # ]
     346                 :            :             {
     347                 :          0 :                 bDelWrong = sal_True;
     348                 :            :             }
     349                 :            :             // 2. Wrong begins before, ends inside or behind it ...
     350 [ #  # ][ #  # ]:          0 :             else if (i->nStart <= nPos && i->nEnd > nPos)
                 [ #  # ]
     351                 :            :             {
     352         [ #  # ]:          0 :                 if (i->nEnd <= nEndChanges)   // ends inside
     353                 :          0 :                     i->nEnd = nPos;
     354                 :            :                 else
     355                 :          0 :                     i->nEnd -= nDeleted; // ends after
     356                 :            :             }
     357                 :            :             // 3. Wrong begins inside, ending after ...
     358 [ #  # ][ #  # ]:          0 :             else if (i->nStart >= nPos && i->nEnd > nEndChanges)
                 [ #  # ]
     359                 :            :             {
     360                 :          0 :                 i->nStart = nEndChanges - nDeleted;
     361                 :          0 :                 i->nEnd -= nDeleted;
     362                 :            :             }
     363                 :            :         }
     364                 :            :         SAL_WARN_IF(i->nStart >= i->nEnd, "editeng",
     365                 :            :                 "TextDeleted, WrongRange: Start >= End?!");
     366         [ #  # ]:          0 :         if ( bDelWrong )
     367                 :            :         {
     368         [ #  # ]:          0 :             i = maRanges.erase(i);
     369                 :            :         }
     370                 :            :         else
     371                 :            :         {
     372                 :          0 :             ++i;
     373                 :            :         }
     374                 :            :     }
     375                 :            : 
     376                 :            :     SAL_WARN_IF(DbgIsBuggy(), "editeng", "TextDeleted: WrongList broken!");
     377                 :         81 : }
     378                 :            : 
     379                 :        518 : sal_Bool WrongList::NextWrong( sal_uInt16& rnStart, sal_uInt16& rnEnd ) const
     380                 :            : {
     381                 :            :     /*
     382                 :            :         rnStart get the start position, is possibly adjusted wrt. Wrong start
     383                 :            :         rnEnd does not have to be initialized.
     384                 :            :     */
     385 [ +  - ][ +  + ]:        519 :     for (WrongList::const_iterator i = begin(); i != end(); ++i)
     386                 :            :     {
     387         [ +  + ]:        518 :         if ( i->nEnd > rnStart )
     388                 :            :         {
     389                 :        517 :             rnStart = i->nStart;
     390                 :        517 :             rnEnd = i->nEnd;
     391                 :        517 :             return sal_True;
     392                 :            :         }
     393                 :            :     }
     394                 :        518 :     return sal_False;
     395                 :            : }
     396                 :            : 
     397                 :        197 : sal_Bool WrongList::HasWrong( sal_uInt16 nStart, sal_uInt16 nEnd ) const
     398                 :            : {
     399 [ +  - ][ +  + ]:        198 :     for (WrongList::const_iterator i = begin(); i != end(); ++i)
     400                 :            :     {
     401 [ -  + ][ #  # ]:          1 :         if (i->nStart == nStart && i->nEnd == nEnd)
                 [ -  + ]
     402                 :          0 :             return sal_True;
     403         [ -  + ]:          1 :         else if ( i->nStart >= nStart )
     404                 :          0 :             break;
     405                 :            :     }
     406                 :        197 :     return sal_False;
     407                 :            : }
     408                 :            : 
     409                 :       2941 : sal_Bool WrongList::HasAnyWrong( sal_uInt16 nStart, sal_uInt16 nEnd ) const
     410                 :            : {
     411 [ +  - ][ +  + ]:       2943 :     for (WrongList::const_iterator i = begin(); i != end(); ++i)
     412                 :            :     {
     413 [ -  + ][ #  # ]:          2 :         if (i->nEnd >= nStart && i->nStart < nEnd)
                 [ -  + ]
     414                 :          0 :             return sal_True;
     415         [ -  + ]:          2 :         else if (i->nStart >= nEnd)
     416                 :          0 :             break;
     417                 :            :     }
     418                 :       2941 :     return sal_False;
     419                 :            : }
     420                 :            : 
     421                 :          0 : void WrongList::ClearWrongs( sal_uInt16 nStart, sal_uInt16 nEnd,
     422                 :            :             const ContentNode* pNode )
     423                 :            : {
     424 [ #  # ][ #  # ]:          0 :     for (WrongList::iterator i = begin(); i != end(); )
     425                 :            :     {
     426 [ #  # ][ #  # ]:          0 :         if (i->nEnd > nStart && i->nStart < nEnd)
                 [ #  # ]
     427                 :            :         {
     428         [ #  # ]:          0 :             if (i->nEnd > nEnd) // Runs out
     429                 :            :             {
     430                 :          0 :                 i->nStart = nEnd;
     431                 :            :                 // Blanks?
     432 [ #  # ][ #  # ]:          0 :                 while (i->nStart < pNode->Len() &&
         [ #  # ][ #  # ]
                 [ #  # ]
     433         [ #  # ]:          0 :                        (pNode->GetChar(i->nStart) == ' ' ||
     434         [ #  # ]:          0 :                         pNode->IsFeature(i->nStart)))
     435                 :            :                 {
     436                 :          0 :                     ++(i->nStart);
     437                 :            :                 }
     438                 :          0 :                 ++i;
     439                 :            :             }
     440                 :            :             else
     441                 :            :             {
     442         [ #  # ]:          0 :                 i = maRanges.erase(i);
     443                 :            :                 // no increment here
     444                 :            :             }
     445                 :            :         }
     446                 :            :         else
     447                 :            :         {
     448                 :          0 :             ++i;
     449                 :            :         }
     450                 :            :     }
     451                 :            : 
     452                 :            :     SAL_WARN_IF(DbgIsBuggy(), "editeng", "ClearWrongs: WrongList broken!");
     453                 :          0 : }
     454                 :            : 
     455                 :        197 : void WrongList::InsertWrong( sal_uInt16 nStart, sal_uInt16 nEnd,
     456                 :            :             sal_Bool bClearRange )
     457                 :            : {
     458                 :        197 :     WrongList::iterator nPos = end();
     459 [ +  - ][ +  + ]:        198 :     for (WrongList::iterator i = begin(); i != end(); ++i)
     460                 :            :     {
     461         [ -  + ]:          1 :         if (i->nStart >= nStart )
     462                 :            :         {
     463                 :          0 :             nPos = i;
     464         [ #  # ]:          0 :             if ( bClearRange )
     465                 :            :             {
     466                 :            :                 // It can really only happen that the Wrong starts exactly here
     467                 :            :                 // and runs along, but not that there are several ranges ...
     468                 :            :                 // Exactly in the range is no one allowed to be, otherwise this
     469                 :            :                 // Method can not be called!
     470                 :            :                 SAL_WARN_IF((i->nStart != nStart || i->nEnd <= nEnd) && i->nStart <= nEnd, "editeng", "InsertWrong: RangeMismatch!");
     471 [ #  # ][ #  # ]:          0 :                 if (i->nStart == nStart && i->nEnd > nEnd)
                 [ #  # ]
     472                 :          0 :                     i->nStart = nEnd + 1;
     473                 :            :             }
     474                 :          0 :             break;
     475                 :            :         }
     476                 :            :     }
     477                 :            : 
     478 [ +  - ][ -  + ]:        197 :     if (nPos != maRanges.end())
     479         [ #  # ]:          0 :         maRanges.insert(nPos, WrongRange(nStart, nEnd));
     480                 :            :     else
     481         [ +  - ]:        197 :         maRanges.push_back(WrongRange(nStart, nEnd));
     482                 :            : 
     483                 :            :     SAL_WARN_IF(DbgIsBuggy(), "editeng", "InsertWrong: WrongList broken!");
     484                 :        197 : }
     485                 :            : 
     486                 :          0 : void WrongList::MarkWrongsInvalid()
     487                 :            : {
     488         [ #  # ]:          0 :     if (!maRanges.empty())
     489                 :          0 :         MarkInvalid(maRanges.front().nStart, maRanges.back().nEnd );
     490                 :          0 : }
     491                 :            : 
     492                 :      21645 : WrongList* WrongList::Clone() const
     493                 :            : {
     494         [ +  - ]:      21645 :     return new WrongList(*this);
     495                 :            : }
     496                 :            : 
     497                 :            : // #i102062#
     498                 :          0 : bool WrongList::operator==(const WrongList& rCompare) const
     499                 :            : {
     500                 :            :     // cleck direct members
     501   [ #  #  #  #  :          0 :     if(GetInvalidStart() != rCompare.GetInvalidStart()
           #  # ][ #  # ]
     502                 :          0 :         || GetInvalidEnd() != rCompare.GetInvalidEnd()
     503                 :          0 :         || maRanges.size() != rCompare.maRanges.size())
     504                 :          0 :         return false;
     505                 :            : 
     506                 :          0 :     WrongList::const_iterator rCA = maRanges.begin();
     507                 :          0 :     WrongList::const_iterator rCB = rCompare.maRanges.begin();
     508                 :            : 
     509 [ #  # ][ #  # ]:          0 :     for (; rCA != maRanges.end(); ++rCA, ++rCB)
     510                 :            :     {
     511 [ #  # ][ #  # ]:          0 :         if(rCA->nStart != rCB->nStart || rCA->nEnd != rCB->nEnd)
                 [ #  # ]
     512                 :          0 :             return false;
     513                 :            :     }
     514                 :            : 
     515                 :          0 :     return true;
     516                 :            : }
     517                 :            : 
     518                 :      11720 : bool WrongList::empty() const
     519                 :            : {
     520                 :      11720 :     return maRanges.empty();
     521                 :            : }
     522                 :            : 
     523                 :          0 : void WrongList::push_back(const WrongRange& rRange)
     524                 :            : {
     525                 :          0 :     maRanges.push_back(rRange);
     526                 :          0 : }
     527                 :            : 
     528                 :          0 : WrongRange& WrongList::back()
     529                 :            : {
     530                 :          0 :     return maRanges.back();
     531                 :            : }
     532                 :            : 
     533                 :          0 : const WrongRange& WrongList::back() const
     534                 :            : {
     535                 :          0 :     return maRanges.back();
     536                 :            : }
     537                 :            : 
     538                 :        686 : WrongList::iterator WrongList::begin()
     539                 :            : {
     540                 :        686 :     return maRanges.begin();
     541                 :            : }
     542                 :            : 
     543                 :        884 : WrongList::iterator WrongList::end()
     544                 :            : {
     545                 :        884 :     return maRanges.end();
     546                 :            : }
     547                 :            : 
     548                 :       3656 : WrongList::const_iterator WrongList::begin() const
     549                 :            : {
     550                 :       3656 :     return maRanges.begin();
     551                 :            : }
     552                 :            : 
     553                 :       3660 : WrongList::const_iterator WrongList::end() const
     554                 :            : {
     555                 :       3660 :     return maRanges.end();
     556                 :            : }
     557                 :            : 
     558                 :          0 : sal_Bool WrongList::DbgIsBuggy() const
     559                 :            : {
     560                 :            :     // Check if the ranges overlap.
     561                 :          0 :     sal_Bool bError = sal_False;
     562 [ #  # ][ #  # ]:          0 :     for (WrongList::const_iterator i = begin(); !bError && (i != end()); ++i)
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     563                 :            :     {
     564 [ #  # ][ #  # ]:          0 :         for (WrongList::const_iterator j = i + 1; !bError && (j != end()); ++j)
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     565                 :            :         {
     566                 :            :             // 1) Start before, End after the second Start
     567 [ #  # ][ #  # ]:          0 :             if (i->nStart <= j->nStart && i->nEnd >= j->nStart)
                 [ #  # ]
     568                 :          0 :                 bError = sal_True;
     569                 :            :             // 2) Start after the second Start, but still before the second End
     570 [ #  # ][ #  # ]:          0 :             else if (i->nStart >= j->nStart && i->nStart <= j->nEnd)
                 [ #  # ]
     571                 :          0 :                 bError = sal_True;
     572                 :            :         }
     573                 :            :     }
     574                 :          0 :     return bError;
     575                 :            : }
     576                 :            : 
     577                 :            : //////////////////////////////////////////////////////////////////////
     578                 :            : 
     579                 :          0 : EdtAutoCorrDoc::EdtAutoCorrDoc(
     580                 :            :     EditEngine* pE, ContentNode* pN, sal_uInt16 nCrsr, sal_Unicode cIns) :
     581                 :            :     mpEditEngine(pE),
     582                 :            :     pCurNode(pN),
     583                 :            :     nCursor(nCrsr),
     584                 :            :     bAllowUndoAction(cIns != 0),
     585                 :          0 :     bUndoAction(false) {}
     586                 :            : 
     587                 :          0 : EdtAutoCorrDoc::~EdtAutoCorrDoc()
     588                 :            : {
     589         [ #  # ]:          0 :     if ( bUndoAction )
     590         [ #  # ]:          0 :         mpEditEngine->UndoActionEnd( EDITUNDO_INSERT );
     591         [ #  # ]:          0 : }
     592                 :            : 
     593                 :          0 : sal_Bool EdtAutoCorrDoc::Delete( sal_uInt16 nStt, sal_uInt16 nEnd )
     594                 :            : {
     595 [ #  # ][ #  # ]:          0 :     EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) );
                 [ #  # ]
     596         [ #  # ]:          0 :     mpEditEngine->DeleteSelection(aSel);
     597                 :            :     SAL_WARN_IF(nCursor < nEnd, "editeng",
     598                 :            :             "Cursor in the heart of the action?!");
     599                 :          0 :     nCursor -= ( nEnd-nStt );
     600                 :          0 :     bAllowUndoAction = sal_False;
     601                 :          0 :     return sal_True;
     602                 :            : }
     603                 :            : 
     604                 :          0 : sal_Bool EdtAutoCorrDoc::Insert( sal_uInt16 nPos, const String& rTxt )
     605                 :            : {
     606 [ #  # ][ #  # ]:          0 :     EditSelection aSel = EditPaM( pCurNode, nPos );
     607         [ #  # ]:          0 :     mpEditEngine->InsertText(aSel, rTxt);
     608                 :            :     SAL_WARN_IF(nCursor < nPos, "editeng",
     609                 :            :             "Cursor in the heart of the action?!");
     610                 :          0 :     nCursor = nCursor + rTxt.Len();
     611                 :            : 
     612 [ #  # ][ #  # ]:          0 :     if ( bAllowUndoAction && ( rTxt.Len() == 1 ) )
                 [ #  # ]
     613         [ #  # ]:          0 :         ImplStartUndoAction();
     614                 :          0 :     bAllowUndoAction = sal_False;
     615                 :            : 
     616                 :          0 :     return sal_True;
     617                 :            : }
     618                 :            : 
     619                 :          0 : sal_Bool EdtAutoCorrDoc::Replace( sal_uInt16 nPos, const String& rTxt )
     620                 :            : {
     621                 :          0 :     return ReplaceRange( nPos, rTxt.Len(), rTxt );
     622                 :            : }
     623                 :            : 
     624                 :          0 : sal_Bool EdtAutoCorrDoc::ReplaceRange( xub_StrLen nPos, xub_StrLen nSourceLength, const String& rTxt )
     625                 :            : {
     626                 :            :     // Actually a Replace introduce => corresponds to UNDO
     627                 :          0 :     sal_uInt16 nEnd = nPos+nSourceLength;
     628         [ #  # ]:          0 :     if ( nEnd > pCurNode->Len() )
     629                 :          0 :         nEnd = pCurNode->Len();
     630                 :            : 
     631                 :            :     // #i5925# First insert new text behind to be deleted text, for keeping attributes.
     632 [ #  # ][ #  # ]:          0 :     mpEditEngine->InsertText(EditSelection(EditPaM(pCurNode, nEnd)), rTxt);
     633                 :            :     mpEditEngine->DeleteSelection(
     634 [ #  # ][ #  # ]:          0 :         EditSelection(EditPaM(pCurNode, nPos), EditPaM(pCurNode, nEnd)));
                 [ #  # ]
     635                 :            : 
     636         [ #  # ]:          0 :     if ( nPos == nCursor )
     637                 :          0 :         nCursor = nCursor + rTxt.Len();
     638                 :            : 
     639 [ #  # ][ #  # ]:          0 :     if ( bAllowUndoAction && ( rTxt.Len() == 1 ) )
                 [ #  # ]
     640                 :          0 :         ImplStartUndoAction();
     641                 :            : 
     642                 :          0 :     bAllowUndoAction = sal_False;
     643                 :            : 
     644                 :          0 :     return sal_True;
     645                 :            : }
     646                 :            : 
     647                 :          0 : sal_Bool EdtAutoCorrDoc::SetAttr( sal_uInt16 nStt, sal_uInt16 nEnd,
     648                 :            :             sal_uInt16 nSlotId, SfxPoolItem& rItem )
     649                 :            : {
     650                 :          0 :     SfxItemPool* pPool = &mpEditEngine->GetEditDoc().GetItemPool();
     651   [ #  #  #  # ]:          0 :     while ( pPool->GetSecondaryPool() &&
                 [ #  # ]
     652                 :          0 :             !pPool->GetName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EditEngineItemPool")) )
     653                 :            :     {
     654                 :          0 :         pPool = pPool->GetSecondaryPool();
     655                 :            : 
     656                 :            :     }
     657                 :          0 :     sal_uInt16 nWhich = pPool->GetWhich( nSlotId );
     658         [ #  # ]:          0 :     if ( nWhich )
     659                 :            :     {
     660                 :          0 :         rItem.SetWhich( nWhich );
     661                 :            : 
     662 [ #  # ][ #  # ]:          0 :         SfxItemSet aSet = mpEditEngine->GetEmptyItemSet();
     663         [ #  # ]:          0 :         aSet.Put( rItem );
     664                 :            : 
     665 [ #  # ][ #  # ]:          0 :         EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) );
                 [ #  # ]
     666                 :          0 :         aSel.Max().SetIndex( nEnd );    // ???
     667         [ #  # ]:          0 :         mpEditEngine->SetAttribs( aSel, aSet, ATTRSPECIAL_EDGE );
     668         [ #  # ]:          0 :         bAllowUndoAction = false;
     669                 :            :     }
     670                 :          0 :     return sal_True;
     671                 :            : }
     672                 :            : 
     673                 :          0 : sal_Bool EdtAutoCorrDoc::SetINetAttr( sal_uInt16 nStt, sal_uInt16 nEnd,
     674                 :            :             const String& rURL )
     675                 :            : {
     676                 :            :     // Turn the Text into a command field ...
     677 [ #  # ][ #  # ]:          0 :     EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) );
                 [ #  # ]
     678         [ #  # ]:          0 :     String aText = mpEditEngine->GetSelected(aSel);
     679 [ #  # ][ #  # ]:          0 :     aSel = mpEditEngine->DeleteSelection(aSel);
     680                 :            :     SAL_WARN_IF(nCursor < nEnd, "editeng",
     681                 :            :             "Cursor in the heart of the action?!");
     682                 :          0 :     nCursor -= ( nEnd-nStt );
     683                 :            :     SvxFieldItem aField( SvxURLField( rURL, aText, SVXURLFORMAT_REPR ),
     684 [ #  # ][ #  # ]:          0 :                                       EE_FEATURE_FIELD  );
         [ #  # ][ #  # ]
                 [ #  # ]
     685         [ #  # ]:          0 :     mpEditEngine->InsertField(aSel, aField);
     686                 :          0 :     nCursor++;
     687         [ #  # ]:          0 :     mpEditEngine->UpdateFieldsOnly();
     688                 :          0 :     bAllowUndoAction = false;
     689 [ #  # ][ #  # ]:          0 :     return sal_True;
     690                 :            : }
     691                 :            : 
     692                 :          0 : sal_Bool EdtAutoCorrDoc::HasSymbolChars( sal_uInt16 nStt, sal_uInt16 nEnd )
     693                 :            : {
     694 [ #  # ][ #  # ]:          0 :     sal_uInt16 nScriptType = mpEditEngine->GetScriptType( EditPaM( pCurNode, nStt ) );
                 [ #  # ]
     695         [ #  # ]:          0 :     sal_uInt16 nScriptFontInfoItemId = GetScriptItemId( EE_CHAR_FONTINFO, nScriptType );
     696                 :            : 
     697         [ #  # ]:          0 :     const CharAttribList::AttribsType& rAttribs = pCurNode->GetCharAttribs().GetAttribs();
     698 [ #  # ][ #  # ]:          0 :     CharAttribList::AttribsType::const_iterator it = rAttribs.begin(), itEnd = rAttribs.end();
     699 [ #  # ][ #  # ]:          0 :     for (; it != itEnd; ++it)
                 [ #  # ]
     700                 :            :     {
     701         [ #  # ]:          0 :         const EditCharAttrib& rAttr = *it;
     702         [ #  # ]:          0 :         if (rAttr.GetStart() >= nEnd)
     703                 :          0 :             return false;
     704                 :            : 
     705   [ #  #  #  # ]:          0 :         if (rAttr.Which() == nScriptFontInfoItemId &&
                 [ #  # ]
     706                 :          0 :             static_cast<const SvxFontItem*>(rAttr.GetItem())->GetCharSet() == RTL_TEXTENCODING_SYMBOL)
     707                 :            :         {
     708                 :            :             // check if the Attribtuteis within range...
     709         [ #  # ]:          0 :             if (rAttr.GetEnd() >= nStt)
     710                 :          0 :                 return true;
     711                 :            :         }
     712                 :            :     }
     713                 :          0 :     return false;
     714                 :            : }
     715                 :            : 
     716                 :          0 : const String* EdtAutoCorrDoc::GetPrevPara( sal_Bool )
     717                 :            : {
     718                 :            :     // Return previous paragraph, so that it can be determined,
     719                 :            :     // whether the current word is at the beginning of a sentence.
     720                 :            : 
     721                 :          0 :     bAllowUndoAction = sal_False;   // Not anymore ...
     722                 :            : 
     723                 :          0 :     EditDoc& rNodes = mpEditEngine->GetEditDoc();
     724                 :          0 :     sal_uInt16 nPos = rNodes.GetPos( pCurNode );
     725                 :            : 
     726                 :            :     // Special case: Bullet => Paragraph start => simply return NULL...
     727                 :            :     const SfxBoolItem& rBulletState = (const SfxBoolItem&)
     728                 :          0 :             mpEditEngine->GetParaAttrib( nPos, EE_PARA_BULLETSTATE );
     729         [ #  # ]:          0 :     sal_Bool bBullet = rBulletState.GetValue() ? sal_True : sal_False;
     730 [ #  # ][ #  # ]:          0 :     if ( !bBullet && (mpEditEngine->GetControlWord() & EE_CNTRL_OUTLINER) )
                 [ #  # ]
     731                 :            :     {
     732                 :            :         // The Outliner has still a Bullet at Level 0.
     733                 :            :         const SfxInt16Item& rLevel = (const SfxInt16Item&)
     734                 :          0 :                 mpEditEngine->GetParaAttrib( nPos, EE_PARA_OUTLLEVEL );
     735         [ #  # ]:          0 :         if ( rLevel.GetValue() == 0 )
     736                 :          0 :             bBullet = sal_True;
     737                 :            :     }
     738         [ #  # ]:          0 :     if ( bBullet )
     739                 :          0 :         return NULL;
     740                 :            : 
     741         [ #  # ]:          0 :     for ( sal_uInt16 n = nPos; n; )
     742                 :            :     {
     743                 :          0 :         n--;
     744                 :          0 :         ContentNode* pNode = rNodes[n];
     745         [ #  # ]:          0 :         if ( pNode->Len() )
     746                 :          0 :             return &pNode->GetString();
     747                 :            :     }
     748                 :          0 :     return NULL;
     749                 :            : 
     750                 :            : }
     751                 :            : 
     752                 :          0 : sal_Bool EdtAutoCorrDoc::ChgAutoCorrWord( sal_uInt16& rSttPos,
     753                 :            :             sal_uInt16 nEndPos, SvxAutoCorrect& rACorrect,
     754                 :            :             const String** ppPara )
     755                 :            : {
     756                 :            :     // Paragraph-start or a blank found, search for the word
     757                 :            :     // shortcut in Auto
     758                 :          0 :     bAllowUndoAction = sal_False;   // Not anymore ...
     759                 :            : 
     760         [ #  # ]:          0 :     String aShort( pCurNode->Copy( rSttPos, nEndPos - rSttPos ) );
     761                 :          0 :     sal_Bool bRet = sal_False;
     762                 :            : 
     763         [ #  # ]:          0 :     if( !aShort.Len() )
     764                 :          0 :         return bRet;
     765                 :            : 
     766 [ #  # ][ #  # ]:          0 :     LanguageType eLang = mpEditEngine->GetLanguage( EditPaM( pCurNode, rSttPos+1 ) );
     767 [ #  # ][ #  # ]:          0 :     const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(pCurNode->GetString(), rSttPos, nEndPos, *this, eLang);
     768 [ #  # ][ #  # ]:          0 :     if( pFnd && pFnd->IsTextOnly() )
                 [ #  # ]
     769                 :            :     {
     770                 :            :         // then replace
     771                 :            :         EditSelection aSel( EditPaM( pCurNode, rSttPos ),
     772 [ #  # ][ #  # ]:          0 :                             EditPaM( pCurNode, nEndPos ) );
                 [ #  # ]
     773 [ #  # ][ #  # ]:          0 :         aSel = mpEditEngine->DeleteSelection(aSel);
     774                 :            :         SAL_WARN_IF(nCursor < nEndPos, "editeng",
     775                 :            :                 "Cursor in the heart of the action?!");
     776                 :          0 :         nCursor -= ( nEndPos-rSttPos );
     777         [ #  # ]:          0 :         mpEditEngine->InsertText(aSel, pFnd->GetLong());
     778                 :          0 :         nCursor = nCursor + pFnd->GetLong().Len();
     779         [ #  # ]:          0 :         if( ppPara )
     780         [ #  # ]:          0 :             *ppPara = &pCurNode->GetString();
     781                 :          0 :         bRet = sal_True;
     782                 :            :     }
     783                 :            : 
     784         [ #  # ]:          0 :     return bRet;
     785                 :            : }
     786                 :            : 
     787                 :          0 : LanguageType EdtAutoCorrDoc::GetLanguage( sal_uInt16 nPos, sal_Bool ) const
     788                 :            : {
     789         [ #  # ]:          0 :     return mpEditEngine->GetLanguage( EditPaM( pCurNode, nPos+1 ) );
     790                 :            : }
     791                 :            : 
     792                 :          0 : void EdtAutoCorrDoc::ImplStartUndoAction()
     793                 :            : {
     794 [ #  # ][ #  # ]:          0 :     sal_uInt16 nPara = mpEditEngine->GetEditDoc().GetPos( pCurNode );
     795                 :          0 :     ESelection aSel( nPara, nCursor, nPara, nCursor );
     796         [ #  # ]:          0 :     mpEditEngine->UndoActionStart( EDITUNDO_INSERT, aSel );
     797                 :          0 :     bUndoAction = sal_True;
     798                 :          0 :     bAllowUndoAction = sal_False;
     799                 :          0 : }
     800                 :            : 
     801                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10