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

Generated by: LCOV version 1.10