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

Generated by: LCOV version 1.10