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

Generated by: LCOV version 1.10