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

Generated by: LCOV version 1.11