LCOV - code coverage report
Current view: top level - sw/source/core/crsr - findtxt.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 162 326 49.7 %
Date: 2012-08-25 Functions: 7 11 63.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 161 630 25.6 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <com/sun/star/util/SearchOptions.hpp>
      31                 :            : #include <com/sun/star/util/SearchFlags.hpp>
      32                 :            : 
      33                 :            : #include <comphelper/string.hxx>
      34                 :            : 
      35                 :            : #include <vcl/svapp.hxx>
      36                 :            : #include <vcl/window.hxx>
      37                 :            : 
      38                 :            : #include <txatritr.hxx>
      39                 :            : #include <fldbas.hxx>
      40                 :            : #include <fmtfld.hxx>
      41                 :            : #include <txtatr.hxx>
      42                 :            : #include <txtfld.hxx>
      43                 :            : #include <swcrsr.hxx>
      44                 :            : #include <doc.hxx>
      45                 :            : #include <IDocumentUndoRedo.hxx>
      46                 :            : #include <pamtyp.hxx>
      47                 :            : #include <ndtxt.hxx>
      48                 :            : #include <swundo.hxx>
      49                 :            : #include <UndoInsert.hxx>
      50                 :            : #include <breakit.hxx>
      51                 :            : 
      52                 :            : #include <docsh.hxx>
      53                 :            : #include <PostItMgr.hxx>
      54                 :            : #include <viewsh.hxx>
      55                 :            : 
      56                 :            : using namespace ::com::sun::star;
      57                 :            : using namespace util;
      58                 :            : 
      59                 :            : String *ReplaceBackReferences( const SearchOptions& rSearchOpt, SwPaM* pPam );
      60                 :            : 
      61                 :        584 : String& lcl_CleanStr( const SwTxtNode& rNd, xub_StrLen nStart, xub_StrLen& rEnd,
      62                 :            :                       std::vector<sal_uLong> &rArr, String& rRet,
      63                 :            :                       bool bRemoveSoftHyphen )
      64                 :            : {
      65         [ +  - ]:        584 :     rRet = rNd.GetTxt();
      66                 :        584 :     rArr.clear();
      67                 :            : 
      68                 :        584 :     const SwpHints *pHts = rNd.GetpSwpHints();
      69                 :            : 
      70                 :        584 :     sal_uInt16 n = 0;
      71                 :        584 :     xub_StrLen nSoftHyphen = nStart;
      72                 :        584 :     xub_StrLen nHintStart = STRING_LEN;
      73                 :        584 :     bool bNewHint       = true;
      74                 :        584 :     bool bNewSoftHyphen = true;
      75                 :        584 :     const xub_StrLen nEnd = rEnd;
      76         [ +  - ]:        584 :     std::vector<sal_uInt16> aReplaced;
      77                 :            : 
      78                 :         16 :     do
      79                 :            :     {
      80         [ +  - ]:        600 :         if ( bNewHint )
      81                 :         24 :             nHintStart = pHts && n < pHts->Count() ?
      82         [ +  - ]:         16 :                          *(*pHts)[n]->GetStart() :
      83   [ +  +  +  + ]:        640 :                          STRING_LEN;
      84                 :            : 
      85         [ +  + ]:        600 :         if ( bNewSoftHyphen )
      86                 :            :             nSoftHyphen = bRemoveSoftHyphen ?
      87                 :        584 :                           rNd.GetTxt().Search( CHAR_SOFTHYPHEN, nSoftHyphen ) :
      88   [ +  -  +  - ]:       1168 :                           STRING_LEN;
      89                 :            : 
      90                 :        600 :         bNewHint       = false;
      91                 :        600 :         bNewSoftHyphen = false;
      92                 :            : 
      93                 :        600 :         xub_StrLen nStt = 0;
      94                 :            : 
      95                 :            :         // Check if next stop is a hint.
      96 [ +  + ][ +  - ]:        600 :         if ( STRING_LEN != nHintStart && nHintStart < nSoftHyphen && nHintStart < nEnd )
                 [ +  - ]
      97                 :            :         {
      98                 :         16 :             nStt = nHintStart;
      99                 :         16 :             bNewHint = true;
     100                 :            :         }
     101                 :            :         // Check if next stop is a soft hyphen.
     102 [ -  + ][ #  # ]:        584 :         else if ( STRING_LEN != nSoftHyphen && nSoftHyphen < nHintStart && nSoftHyphen < nEnd )
                 [ #  # ]
     103                 :            :         {
     104                 :          0 :             nStt = nSoftHyphen;
     105                 :          0 :             bNewSoftHyphen = true;
     106                 :            :         }
     107                 :            :         // If nSoftHyphen == nHintStart, the current hint *must* be a hint with an end.
     108 [ -  + ][ #  # ]:        584 :         else if ( STRING_LEN != nSoftHyphen && nSoftHyphen == nHintStart )
     109                 :            :         {
     110                 :          0 :             nStt = nSoftHyphen;
     111                 :          0 :             bNewHint = true;
     112                 :          0 :             bNewSoftHyphen = true;
     113                 :            :         }
     114                 :            :         else
     115                 :            :             break;
     116                 :            : 
     117                 :         16 :         const xub_StrLen nAkt = nStt - rArr.size();
     118                 :            : 
     119         [ +  - ]:         16 :         if ( bNewHint )
     120                 :            :         {
     121         [ +  - ]:         16 :             const SwTxtAttr* pHt = (*pHts)[n];
     122 [ +  - ][ +  - ]:         16 :             if ( pHt->HasDummyChar() && (nStt >= nStart) )
                 [ +  - ]
     123                 :            :             {
     124 [ +  - ][ +  - ]:         16 :                    switch( pHt->Which() )
     125                 :            :                 {
     126                 :            :                 case RES_TXTATR_FLYCNT:
     127                 :            :                 case RES_TXTATR_FTN:
     128                 :            :                    case RES_TXTATR_FIELD:
     129                 :            :                 case RES_TXTATR_REFMARK:
     130                 :            :                    case RES_TXTATR_TOXMARK:
     131                 :            :                 case RES_TXTATR_META:
     132                 :            :                 case RES_TXTATR_METAFIELD:
     133                 :            :                     {
     134                 :            :                         // (1998) they are desired as separators and
     135                 :            :                         // belong not any longer to a word.
     136                 :            :                         // they should also be ignored at a
     137                 :            :                         // beginning/end of a sentence if blank. Those are
     138                 :            :                         // simply removed if first. If at the end, we keep the
     139                 :            :                         // replacement and remove afterwards all at a string's
     140                 :            :                         // end (might be normal 0x7f).
     141         [ +  - ]:         16 :                         sal_Bool bEmpty = RES_TXTATR_FIELD != pHt->Which() ||
     142                 :            :                             !(static_cast<SwTxtFld const*>(pHt)
     143 [ -  + ][ #  # ]:         16 :                                 ->GetFld().GetFld()->ExpandField(true).Len());
         [ #  # ][ -  + ]
         [ #  # ][ #  # ]
     144 [ +  - ][ +  - ]:         16 :                         if ( bEmpty && nStart == nAkt )
     145                 :            :                            {
     146         [ +  - ]:         16 :                             rArr.push_back( nAkt );
     147                 :         16 :                             --rEnd;
     148         [ +  - ]:         16 :                             rRet.Erase( nAkt, 1 );
     149                 :            :                            }
     150                 :            :                         else
     151                 :            :                            {
     152         [ #  # ]:          0 :                             if ( bEmpty )
     153         [ #  # ]:          0 :                                 aReplaced.push_back( nAkt );
     154         [ #  # ]:          0 :                             rRet.SetChar( nAkt, '\x7f' );
     155                 :            :                            }
     156                 :            :                        }
     157                 :         16 :                        break;
     158                 :            :                    default:
     159                 :            :                     OSL_FAIL( "unknown case in lcl_CleanStr" );
     160                 :         16 :                     break;
     161                 :            :                 }
     162                 :            :             }
     163                 :         16 :             ++n;
     164                 :            :         }
     165                 :            : 
     166         [ -  + ]:         16 :         if ( bNewSoftHyphen )
     167                 :            :         {
     168         [ #  # ]:          0 :             rArr.push_back( nAkt );
     169                 :          0 :             --rEnd;
     170         [ #  # ]:          0 :             rRet.Erase( nAkt, 1 );
     171                 :          0 :             ++nSoftHyphen;
     172                 :            :         }
     173                 :            :     }
     174                 :            :     while ( true );
     175                 :            : 
     176         [ -  + ]:        584 :     for( sal_uInt16 i = aReplaced.size(); i; )
     177                 :            :     {
     178         [ #  # ]:          0 :         const xub_StrLen nTmp = aReplaced[ --i ];
     179         [ #  # ]:          0 :         if( nTmp == rRet.Len() - 1 )
     180                 :            :         {
     181         [ #  # ]:          0 :             rRet.Erase( nTmp );
     182         [ #  # ]:          0 :             rArr.push_back( nTmp );
     183                 :          0 :             --rEnd;
     184                 :            :         }
     185                 :            :     }
     186                 :            : 
     187                 :        584 :     return rRet;
     188                 :            : }
     189                 :            : 
     190                 :            : // skip all non SwPostIts inside the array
     191                 :          0 : xub_StrLen GetPostIt(xub_StrLen aCount,const SwpHints *pHts)
     192                 :            : {
     193                 :          0 :     xub_StrLen aIndex = 0;
     194         [ #  # ]:          0 :     while (aCount)
     195                 :            :     {
     196         [ #  # ]:          0 :         for (xub_StrLen i = 0; i <pHts->Count();i++)
     197                 :            :         {
     198                 :          0 :             aIndex++;
     199                 :          0 :             const SwTxtAttr* pTxtAttr = (*pHts)[i];
     200         [ #  # ]:          0 :             if ( (pTxtAttr->Which()==RES_TXTATR_FIELD) &&
           [ #  #  #  # ]
     201                 :          0 :                     (pTxtAttr->GetFld().GetFld()->Which()==RES_POSTITFLD))
     202                 :            :             {
     203                 :          0 :                 aCount--;
     204         [ #  # ]:          0 :                 if (!aCount)
     205                 :          0 :                     break;
     206                 :            :             }
     207                 :            :         }
     208                 :            :     }
     209                 :            :     // throw away all following non postits
     210         [ #  # ]:          0 :     for (xub_StrLen i = aIndex; i <pHts->Count();i++)
     211                 :            :     {
     212                 :          0 :         const SwTxtAttr* pTxtAttr = (*pHts)[i];
     213         [ #  # ]:          0 :         if ( (pTxtAttr->Which()==RES_TXTATR_FIELD) &&
           [ #  #  #  # ]
     214                 :          0 :                 (pTxtAttr->GetFld().GetFld()->Which()==RES_POSTITFLD))
     215                 :          0 :             break;
     216                 :            :         else
     217                 :          0 :             aIndex++;
     218                 :            :     }
     219                 :          0 :     return aIndex;
     220                 :            : }
     221                 :            : 
     222                 :        180 : sal_uInt8 SwPaM::Find( const SearchOptions& rSearchOpt, sal_Bool bSearchInNotes , utl::TextSearch& rSTxt,
     223                 :            :                     SwMoveFn fnMove, const SwPaM * pRegion,
     224                 :            :                     sal_Bool bInReadOnly )
     225                 :            : {
     226         [ -  + ]:        180 :     if( rSearchOpt.searchString.isEmpty() )
     227                 :          0 :         return sal_False;
     228                 :            : 
     229         [ +  - ]:        180 :     SwPaM* pPam = MakeRegion( fnMove, pRegion );
     230                 :        180 :     sal_Bool bSrchForward = fnMove == fnMoveForward;
     231                 :        180 :     SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode;
     232                 :        180 :     SwIndex& rCntntIdx = pPam->GetPoint()->nContent;
     233                 :            : 
     234                 :            :     // If a beginning/end, from out of node; stop if empty node
     235   [ +  +  +  + ]:        384 :     if( bSrchForward
         [ #  # ][ #  # ]
         [ +  + ][ +  - ]
     236         [ +  - ]:        180 :         ? ( rCntntIdx.GetIndex() == pPam->GetCntntNode()->Len() &&
     237                 :         24 :             rCntntIdx.GetIndex() )
     238         [ #  # ]:          0 :         : !rCntntIdx.GetIndex() && pPam->GetCntntNode()->Len() )
     239                 :            :     {
     240 [ +  - ][ -  + ]:         10 :         if( !(*fnMove->fnNds)( &rNdIdx, sal_False ))
     241                 :            :         {
     242 [ #  # ][ #  # ]:          0 :             delete pPam;
     243                 :          0 :             return sal_False;
     244                 :            :         }
     245                 :         10 :         SwCntntNode *pNd = rNdIdx.GetNode().GetCntntNode();
     246 [ #  # ][ -  + ]:         10 :         xub_StrLen nTmpPos = bSrchForward ? 0 : pNd->Len();
     247 [ +  - ][ +  - ]:         10 :         rCntntIdx.Assign( pNd, nTmpPos );
     248                 :            :     }
     249                 :            : 
     250                 :            :     // If bFound is true then the string was found and is between nStart and nEnd
     251                 :        180 :     sal_Bool bFound = sal_False;
     252                 :            :     // start position in text or initial position
     253                 :        180 :     sal_Bool bFirst = sal_True;
     254                 :            :     SwCntntNode * pNode;
     255                 :            : 
     256                 :            :     xub_StrLen nStart, nEnd, nTxtLen;
     257                 :            : 
     258                 :        180 :     sal_Bool bRegSearch = SearchAlgorithms_REGEXP == rSearchOpt.algorithmType;
     259                 :          0 :     sal_Bool bChkEmptyPara = bRegSearch && 2 == rSearchOpt.searchString.getLength() &&
     260                 :          0 :                         ( !rSearchOpt.searchString.compareToAscii( "^$" ) ||
     261   [ -  +  #  #  :        180 :                           !rSearchOpt.searchString.compareToAscii( "$^" ) );
           #  # ][ #  # ]
     262                 :          0 :     sal_Bool bChkParaEnd = bRegSearch && 1 == rSearchOpt.searchString.getLength() &&
     263   [ -  +  #  # ]:        180 :                       !rSearchOpt.searchString.compareToAscii( "$" );
                 [ #  # ]
     264                 :            : 
     265                 :            :     // LanguageType eLastLang = 0;
     266 [ +  - ][ +  + ]:        604 :     while( 0 != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ) ))
     267                 :            :     {
     268         [ +  + ]:        592 :         if( pNode->IsTxtNode() )
     269                 :            :         {
     270                 :        584 :             nTxtLen = ((SwTxtNode*)pNode)->GetTxt().Len();
     271         [ +  + ]:        584 :             if( rNdIdx == pPam->GetMark()->nNode )
     272                 :          2 :                 nEnd = pPam->GetMark()->nContent.GetIndex();
     273                 :            :             else
     274         [ +  - ]:        582 :                 nEnd = bSrchForward ? nTxtLen : 0;
     275                 :        584 :             nStart = rCntntIdx.GetIndex();
     276                 :            : 
     277                 :            :             /* #i80135# */
     278                 :            :             // if there are SwPostItFields inside our current node text, we
     279                 :            :             // split the text into seperate pieces and search for text inside
     280                 :            :             // the pieces as well as inside the fields
     281                 :        584 :             const SwpHints *pHts = ((SwTxtNode*)pNode)->GetpSwpHints();
     282                 :            : 
     283                 :            :             // count PostItFields by looping over all fields
     284                 :        584 :             xub_StrLen aNumberPostits = 0;
     285                 :        584 :             xub_StrLen aIgnore = 0;
     286 [ -  + ][ +  + ]:        584 :             if (pHts && bSearchInNotes)
     287                 :            :             {
     288         [ #  # ]:          0 :                 if (!bSrchForward)
     289                 :            :                 {
     290                 :          0 :                     xub_StrLen swap = nEnd;
     291                 :          0 :                     nEnd = nStart;
     292                 :          0 :                     nStart = swap;
     293                 :            :                 }
     294                 :            : 
     295         [ #  # ]:          0 :                 for (xub_StrLen i = 0; i <pHts->Count();i++)
     296                 :            :                 {
     297         [ #  # ]:          0 :                     xub_StrLen aPos = *(*pHts)[i]->GetStart();
     298         [ #  # ]:          0 :                     const SwTxtAttr* pTxtAttr = (*pHts)[i];
     299         [ #  # ]:          0 :                     if ( (pTxtAttr->Which()==RES_TXTATR_FIELD) &&
           [ #  #  #  # ]
                 [ #  # ]
     300                 :          0 :                                 (pTxtAttr->GetFld().GetFld()->Which()==RES_POSTITFLD))
     301                 :            :                     {
     302 [ #  # ][ #  # ]:          0 :                         if ( (aPos >= nStart) && (aPos <= nEnd) )
     303                 :          0 :                             aNumberPostits++;
     304                 :            :                         else
     305                 :            :                         {
     306         [ #  # ]:          0 :                             if (bSrchForward)
     307                 :          0 :                                 aIgnore++;
     308                 :            :                         }
     309                 :            :                     }
     310                 :            :                 }
     311                 :            : 
     312         [ #  # ]:          0 :                 if (!bSrchForward)
     313                 :            :                 {
     314                 :          0 :                     xub_StrLen swap = nEnd;
     315                 :          0 :                     nEnd = nStart;
     316                 :          0 :                     nStart = swap;
     317                 :            :                 }
     318                 :            : 
     319                 :            :             }
     320                 :            : 
     321                 :        584 :             SwDocShell *const pDocShell = pNode->GetDoc()->GetDocShell();
     322         [ +  - ]:        584 :             ViewShell *const pWrtShell = (pDocShell) ? (ViewShell*)(pDocShell->GetWrtShell()) : 0;
     323 [ +  - ][ +  - ]:        584 :             SwPostItMgr *const pPostItMgr = (pWrtShell) ? pWrtShell->GetPostItMgr() : 0;
     324                 :            : 
     325                 :        584 :             xub_StrLen aStart = 0;
     326                 :            :             // do we need to finish a note?
     327 [ +  - ][ +  - ]:        584 :             if (pPostItMgr && pPostItMgr->HasActiveSidebarWin())
         [ -  + ][ -  + ]
     328                 :            :             {
     329         [ #  # ]:          0 :                 if (bSearchInNotes)
     330                 :            :                 {
     331         [ #  # ]:          0 :                     if (bSrchForward)
     332                 :          0 :                         aStart++;
     333                 :            :                     else
     334                 :            :                     {
     335         [ #  # ]:          0 :                         if (aNumberPostits)
     336                 :          0 :                             --aNumberPostits;
     337                 :            :                     }
     338                 :            :                     //search inside and finsih and put focus back into the doc
     339 [ #  # ][ #  # ]:          0 :                     if (pPostItMgr->FinishSearchReplace(rSearchOpt,bSrchForward))
     340                 :            :                     {
     341                 :          0 :                         bFound = true ;
     342                 :          0 :                         break;
     343                 :            :                     }
     344                 :            :                 }
     345                 :            :                 else
     346                 :            :                 {
     347         [ #  # ]:          0 :                     pPostItMgr->SetActiveSidebarWin(0);
     348                 :            :                 }
     349                 :            :             }
     350                 :            : 
     351         [ -  + ]:        584 :             if (aNumberPostits)
     352                 :            :             {
     353                 :            :                 // now we have to split
     354                 :          0 :                 xub_StrLen nStartInside = 0;
     355                 :          0 :                 xub_StrLen nEndInside = 0;
     356         [ #  # ]:          0 :                 sal_Int16 aLoop= bSrchForward ? aStart : aNumberPostits;
     357                 :            : 
     358 [ #  # ][ #  # ]:          0 :                 while ( (aLoop>=0) && (aLoop<=aNumberPostits))
                 [ #  # ]
     359                 :            :                 {
     360         [ #  # ]:          0 :                     if (bSrchForward)
     361                 :            :                     {
     362 [ #  # ][ #  # ]:          0 :                         nStartInside = aLoop==0 ? nStart : *(*pHts)[GetPostIt(aLoop+aIgnore-1,pHts)]->GetStart()+1;
                 [ #  # ]
     363 [ #  # ][ #  # ]:          0 :                         nEndInside = aLoop==aNumberPostits ? nEnd : *(*pHts)[GetPostIt(aLoop+aIgnore,pHts)]->GetStart();
                 [ #  # ]
     364                 :          0 :                         nTxtLen = nEndInside - nStartInside;
     365                 :            :                     }
     366                 :            :                     else
     367                 :            :                     {
     368 [ #  # ][ #  # ]:          0 :                         nStartInside =  aLoop==aNumberPostits ? nStart : *(*pHts)[GetPostIt(aLoop+aIgnore,pHts)]->GetStart();
                 [ #  # ]
     369 [ #  # ][ #  # ]:          0 :                         nEndInside = aLoop==0 ? nEnd : *(*pHts)[GetPostIt(aLoop+aIgnore-1,pHts)]->GetStart()+1;
                 [ #  # ]
     370                 :          0 :                         nTxtLen = nStartInside - nEndInside;
     371                 :            :                     }
     372                 :            :                     // search inside the text between a note
     373                 :            :                     bFound = DoSearch( rSearchOpt, rSTxt, fnMove, bSrchForward,
     374                 :            :                                        bRegSearch, bChkEmptyPara, bChkParaEnd,
     375                 :            :                                        nStartInside, nEndInside, nTxtLen, pNode,
     376 [ #  # ][ #  # ]:          0 :                                        pPam );
     377         [ #  # ]:          0 :                     if ( bFound )
     378                 :          0 :                         break;
     379                 :            :                     else
     380                 :            :                     {
     381                 :            :                         // we should now be right in front of a note, search inside
     382 [ #  # ][ #  # ]:          0 :                         if ( (bSrchForward && (GetPostIt(aLoop + aIgnore,pHts) < pHts->Count()) ) || ( !bSrchForward && (aLoop!=0) ))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     383                 :            :                         {
     384 [ #  # ][ #  # ]:          0 :                             const SwTxtAttr* pTxtAttr = bSrchForward ?  (*pHts)[GetPostIt(aLoop+aIgnore,pHts)] : (*pHts)[GetPostIt(aLoop+aIgnore-1,pHts)];
         [ #  # ][ #  # ]
                 [ #  # ]
     385 [ #  # ][ #  # ]:          0 :                             if ( pPostItMgr && pPostItMgr->SearchReplace(((SwTxtFld*)pTxtAttr)->GetFld(),rSearchOpt,bSrchForward) )
         [ #  # ][ #  # ]
     386                 :            :                             {
     387                 :          0 :                                 bFound = true ;
     388                 :          0 :                                 break;
     389                 :            :                             }
     390                 :            :                         }
     391                 :            :                     }
     392         [ #  # ]:          0 :                     aLoop = bSrchForward ? aLoop+1 : aLoop-1;
     393                 :            :                 }
     394                 :            :             }
     395                 :            :             else
     396                 :            :             {
     397                 :            :                 // if there is no SwPostItField inside or searching inside notes
     398                 :            :                 // is disabled, we search the whole length just like before
     399                 :            :                 bFound = DoSearch( rSearchOpt, rSTxt, fnMove, bSrchForward,
     400                 :            :                                    bRegSearch, bChkEmptyPara, bChkParaEnd,
     401 [ +  - ][ +  - ]:        584 :                                    nStart, nEnd, nTxtLen, pNode, pPam );
     402                 :            :             }
     403         [ +  + ]:        584 :             if (bFound)
     404                 :        168 :                 break;
     405                 :            :         }
     406                 :            :     }
     407 [ +  - ][ +  - ]:        180 :     delete pPam;
     408                 :        180 :     return bFound;
     409                 :            : }
     410                 :            : 
     411                 :        584 : bool SwPaM::DoSearch( const SearchOptions& rSearchOpt, utl::TextSearch& rSTxt,
     412                 :            :                       SwMoveFn fnMove, sal_Bool bSrchForward, sal_Bool bRegSearch,
     413                 :            :                       sal_Bool bChkEmptyPara, sal_Bool bChkParaEnd,
     414                 :            :                       xub_StrLen &nStart, xub_StrLen &nEnd, xub_StrLen nTxtLen,
     415                 :            :                       SwNode* pNode, SwPaM* pPam)
     416                 :            : {
     417                 :        584 :     bool bFound = false;
     418                 :        584 :     SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode;
     419                 :        584 :     const SwNode* pSttNd = &rNdIdx.GetNode();
     420         [ +  - ]:        584 :     String sCleanStr;
     421         [ +  - ]:        584 :     std::vector<sal_uLong> aFltArr;
     422                 :        584 :     LanguageType eLastLang = 0;
     423                 :            :     // if the search string contains a soft hypen,
     424                 :            :     // we don't strip them from the text:
     425                 :        584 :     bool bRemoveSoftHyphens = true;
     426         [ -  + ]:        584 :     if ( bRegSearch )
     427                 :            :     {
     428         [ #  # ]:          0 :         const rtl::OUString a00AD(RTL_CONSTASCII_USTRINGPARAM("\\x00AD"));
     429         [ #  # ]:          0 :         if ( -1 != rSearchOpt.searchString.indexOf( a00AD ) )
     430                 :          0 :              bRemoveSoftHyphens = false;
     431                 :            :     }
     432                 :            :     else
     433                 :            :     {
     434   [ -  +  #  # ]:        584 :         if ( 1 == rSearchOpt.searchString.getLength() &&
                 [ -  + ]
     435                 :          0 :              CHAR_SOFTHYPHEN == rSearchOpt.searchString.toChar() )
     436                 :          0 :              bRemoveSoftHyphens = false;
     437                 :            :     }
     438                 :            : 
     439         [ +  - ]:        584 :     if( bSrchForward )
     440                 :            :         lcl_CleanStr( *(SwTxtNode*)pNode, nStart, nEnd,
     441 [ +  - ][ +  - ]:        584 :                         aFltArr, sCleanStr, bRemoveSoftHyphens );
     442                 :            :     else
     443                 :            :         lcl_CleanStr( *(SwTxtNode*)pNode, nEnd, nStart,
     444 [ #  # ][ #  # ]:          0 :                         aFltArr, sCleanStr, bRemoveSoftHyphens );
     445                 :            : 
     446                 :        584 :     SwScriptIterator* pScriptIter = 0;
     447                 :        584 :     sal_uInt16 nSearchScript = 0;
     448                 :        584 :     sal_uInt16 nCurrScript = 0;
     449                 :            : 
     450   [ -  +  #  # ]:       1168 :     if ( SearchAlgorithms_APPROXIMATE == rSearchOpt.algorithmType &&
                 [ -  + ]
     451 [ #  # ][ -  + ]:        584 :          pBreakIt->GetBreakIter().is() )
                 [ #  # ]
     452                 :            :     {
     453 [ #  # ][ #  # ]:          0 :         pScriptIter = new SwScriptIterator( sCleanStr, nStart, bSrchForward );
     454         [ #  # ]:          0 :         nSearchScript = pBreakIt->GetRealScriptOfText( rSearchOpt.searchString, 0 );
     455                 :            :     }
     456                 :            : 
     457                 :        584 :     xub_StrLen nStringEnd = nEnd;
     458 [ +  - ][ +  + ]:        688 :     while ( (bSrchForward && nStart < nStringEnd) ||
         [ -  + ][ #  # ]
                 [ +  + ]
     459                 :            :             (! bSrchForward && nStart > nStringEnd) )
     460                 :            :     {
     461                 :            :         // SearchAlgorithms_APPROXIMATE works on a per word base so we have to
     462                 :            :         // provide the text searcher with the correct locale, because it uses
     463                 :            :         // the break-iterator
     464         [ -  + ]:        272 :         if ( pScriptIter )
     465                 :            :         {
     466                 :          0 :             nEnd = pScriptIter->GetScriptChgPos();
     467                 :          0 :             nCurrScript = pScriptIter->GetCurrScript();
     468         [ #  # ]:          0 :             if ( nSearchScript == nCurrScript )
     469                 :            :             {
     470                 :            :                 const LanguageType eCurrLang =
     471                 :            :                         ((SwTxtNode*)pNode)->GetLang( bSrchForward ?
     472                 :            :                                                       nStart :
     473 [ #  # ][ #  # ]:          0 :                                                       nEnd );
                 [ #  # ]
     474                 :            : 
     475         [ #  # ]:          0 :                 if ( eCurrLang != eLastLang )
     476                 :            :                 {
     477                 :            :                     const lang::Locale aLocale(
     478         [ #  # ]:          0 :                             pBreakIt->GetLocale( eCurrLang ) );
     479         [ #  # ]:          0 :                     rSTxt.SetLocale( rSearchOpt, aLocale );
     480                 :          0 :                     eLastLang = eCurrLang;
     481                 :            :                 }
     482                 :            :             }
     483         [ #  # ]:          0 :             pScriptIter->Next();
     484                 :            :         }
     485                 :            : 
     486 [ +  - ][ +  + ]:        544 :         if( nSearchScript == nCurrScript &&
                 [ +  + ]
     487 [ +  - ][ +  - ]:        272 :             (rSTxt.*fnMove->fnSearch)( sCleanStr, &nStart, &nEnd, 0 ))
     488                 :            :         {
     489                 :            :             // set section correctly
     490         [ +  - ]:        168 :             *GetPoint() = *pPam->GetPoint();
     491         [ +  - ]:        168 :             SetMark();
     492                 :            : 
     493                 :            :             // adjust start and end
     494         [ -  + ]:        168 :             if( !aFltArr.empty() )
     495                 :            :             {
     496                 :            :                 xub_StrLen n, nNew;
     497                 :            :                 // if backward search, switch positions temporarily
     498         [ #  # ]:          0 :                 if( !bSrchForward ) { n = nStart; nStart = nEnd; nEnd = n; }
     499                 :            : 
     500 [ #  # ][ #  # ]:          0 :                 for( n = 0, nNew = nStart;
                 [ #  # ]
     501         [ #  # ]:          0 :                     n < aFltArr.size() && aFltArr[ n ] <= nStart;
     502                 :            :                     ++n, ++nNew )
     503                 :            :                     ;
     504                 :          0 :                 nStart = nNew;
     505 [ #  # ][ #  # ]:          0 :                 for( n = 0, nNew = nEnd;
                 [ #  # ]
     506         [ #  # ]:          0 :                     n < aFltArr.size() && aFltArr[ n ] < nEnd;
     507                 :            :                     ++n, ++nNew )
     508                 :            :                     ;
     509                 :            : 
     510                 :          0 :                 nEnd = nNew;
     511                 :            :                 // if backward search, switch positions temporarily
     512         [ #  # ]:          0 :                 if( !bSrchForward ) { n = nStart; nStart = nEnd; nEnd = n; }
     513                 :            :             }
     514         [ +  - ]:        168 :             GetMark()->nContent = nStart;
     515         [ +  - ]:        168 :             GetPoint()->nContent = nEnd;
     516                 :            : 
     517                 :            :             // if backward search, switch point and mark
     518         [ -  + ]:        168 :             if( !bSrchForward )
     519                 :          0 :                 Exchange();
     520                 :        168 :             bFound = sal_True;
     521                 :        168 :             break;
     522                 :            :         }
     523                 :        104 :         nStart = nEnd;
     524                 :            :     }
     525                 :            : 
     526                 :        584 :     delete pScriptIter;
     527                 :            : 
     528         [ +  + ]:        584 :     if ( bFound )
     529                 :        168 :         return true;
     530 [ -  + ][ #  # ]:        416 :     else if( ( bChkEmptyPara && !nStart && !nTxtLen ) || bChkParaEnd )
         [ #  # ][ -  + ]
     531                 :            :     {
     532         [ #  # ]:          0 :         *GetPoint() = *pPam->GetPoint();
     533 [ #  # ][ #  # ]:          0 :         GetPoint()->nContent = bChkParaEnd ? nTxtLen : 0;
     534         [ #  # ]:          0 :         SetMark();
     535 [ #  # ][ #  # ]:          0 :         if( (bSrchForward || pSttNd != &rNdIdx.GetNode()) &&
         [ #  # ][ #  #  
             #  #  #  # ]
                 [ #  # ]
     536         [ #  # ]:          0 :             Move( fnMoveForward, fnGoCntnt ) &&
     537                 :          0 :             (!bSrchForward || pSttNd != &GetPoint()->nNode.GetNode()) &&
     538                 :          0 :             1 == Abs( (int)( GetPoint()->nNode.GetIndex() -
     539                 :          0 :                              GetMark()->nNode.GetIndex()) ) )
     540                 :            :         {
     541                 :            :             // if backward search, switch point and mark
     542         [ #  # ]:          0 :             if( !bSrchForward )
     543                 :          0 :                 Exchange();
     544                 :          0 :             return true;
     545                 :            :         }
     546                 :            :     }
     547         [ +  - ]:        584 :     return bFound;
     548                 :            : }
     549                 :            : 
     550                 :            : /// parameters for search and replace in text
     551                 :            : struct SwFindParaText : public SwFindParas
     552                 :            : {
     553                 :            :     const SearchOptions& rSearchOpt;
     554                 :            :     SwCursor& rCursor;
     555                 :            :     utl::TextSearch aSTxt;
     556                 :            :     sal_Bool bReplace;
     557                 :            :     sal_Bool bSearchInNotes;
     558                 :            : 
     559                 :         18 :     SwFindParaText( const SearchOptions& rOpt, sal_Bool bSearchNotes, int bRepl, SwCursor& rCrsr )
     560         [ +  - ]:         18 :         : rSearchOpt( rOpt ), rCursor( rCrsr ), aSTxt( rOpt ), bReplace( 0 != bRepl ), bSearchInNotes( bSearchNotes )
     561                 :         18 :     {}
     562                 :            :     virtual int Find( SwPaM* , SwMoveFn , const SwPaM*, sal_Bool bInReadOnly );
     563                 :            :     virtual int IsReplaceMode() const;
     564                 :            :     virtual ~SwFindParaText();
     565                 :            : };
     566                 :            : 
     567         [ +  - ]:         18 : SwFindParaText::~SwFindParaText()
     568                 :            : {
     569         [ -  + ]:         18 : }
     570                 :            : 
     571                 :        180 : int SwFindParaText::Find( SwPaM* pCrsr, SwMoveFn fnMove,
     572                 :            :                             const SwPaM* pRegion, sal_Bool bInReadOnly )
     573                 :            : {
     574 [ +  - ][ +  + ]:        180 :     if( bInReadOnly && bReplace )
     575                 :         92 :         bInReadOnly = sal_False;
     576                 :            : 
     577                 :        180 :     sal_Bool bFnd = (sal_Bool)pCrsr->Find( rSearchOpt, bSearchInNotes, aSTxt, fnMove, pRegion, bInReadOnly );
     578                 :            : 
     579                 :            : 
     580 [ +  + ][ +  + ]:        180 :     if( bFnd && bReplace ) // replace string
     581                 :            :     {
     582                 :            :         // use replace method in SwDoc
     583                 :         88 :         const bool bRegExp(SearchAlgorithms_REGEXP == rSearchOpt.algorithmType);
     584         [ +  - ]:         88 :         SwIndex& rSttCntIdx = pCrsr->Start()->nContent;
     585                 :         88 :         xub_StrLen nSttCnt = rSttCntIdx.GetIndex();
     586                 :            :         // add to shell-cursor-ring so that the regions will be moved enventually
     587                 :         88 :         Ring *pPrev(0);
     588         [ -  + ]:         88 :         if( bRegExp )
     589                 :            :         {
     590                 :          0 :             pPrev = pRegion->GetPrev();
     591         [ #  # ]:          0 :             ((Ring*)pRegion)->MoveRingTo( &rCursor );
     592                 :            :         }
     593                 :            : 
     594                 :            :         ::std::auto_ptr<String> pRepl( (bRegExp)
     595 [ -  + ][ #  # ]:         88 :                 ? ReplaceBackReferences( rSearchOpt, pCrsr ) : 0 );
     596                 :         88 :         rCursor.GetDoc()->ReplaceRange( *pCrsr,
     597                 :         88 :             (pRepl.get()) ? *pRepl : String(rSearchOpt.replaceString),
     598 [ +  - ][ +  - ]:         88 :             bRegExp );
                 [ +  - ]
           [ -  +  #  # ]
     599         [ +  - ]:         88 :         rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() );
     600                 :            : 
     601         [ -  + ]:         88 :         if( bRegExp )
     602                 :            :         {
     603                 :            :             // and remove region again
     604                 :          0 :             Ring *p, *pNext = (Ring*)pRegion;
     605         [ #  # ]:          0 :             do {
     606                 :          0 :                 p = pNext;
     607                 :          0 :                 pNext = p->GetNext();
     608         [ #  # ]:          0 :                 p->MoveTo( (Ring*)pRegion );
     609                 :            :             } while( p != pPrev );
     610                 :            :         }
     611 [ +  - ][ +  - ]:         88 :         pCrsr->Start()->nContent = nSttCnt;
     612         [ +  - ]:         88 :         return FIND_NO_RING;
     613                 :            :     }
     614         [ +  + ]:        180 :     return bFnd ? FIND_FOUND : FIND_NOT_FOUND;
     615                 :            : }
     616                 :            : 
     617                 :            : 
     618                 :          0 : int SwFindParaText::IsReplaceMode() const
     619                 :            : {
     620                 :          0 :     return bReplace;
     621                 :            : }
     622                 :            : 
     623                 :            : 
     624                 :         18 : sal_uLong SwCursor::Find( const SearchOptions& rSearchOpt, sal_Bool bSearchInNotes,
     625                 :            :                           SwDocPositions nStart, SwDocPositions nEnd,
     626                 :            :                           sal_Bool& bCancel, FindRanges eFndRngs, int bReplace )
     627                 :            : {
     628                 :            :     // switch off OLE-notifications
     629                 :         18 :     SwDoc* pDoc = GetDoc();
     630                 :         18 :     Link aLnk( pDoc->GetOle2Link() );
     631         [ +  - ]:         18 :     pDoc->SetOle2Link( Link() );
     632                 :            : 
     633 [ +  - ][ +  - ]:         18 :     bool const bStartUndo = pDoc->GetIDocumentUndoRedo().DoesUndo() && bReplace;
         [ +  + ][ +  - ]
     634         [ +  + ]:         18 :     if (bStartUndo)
     635                 :            :     {
     636 [ +  - ][ +  - ]:          4 :         pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_REPLACE, NULL );
     637                 :            :     }
     638                 :            : 
     639                 :         18 :     sal_Bool bSearchSel = 0 != (rSearchOpt.searchFlag & SearchFlags::REG_NOT_BEGINOFLINE);
     640         [ -  + ]:         18 :     if( bSearchSel )
     641                 :          0 :         eFndRngs = (FindRanges)(eFndRngs | FND_IN_SEL);
     642         [ +  - ]:         18 :     SwFindParaText aSwFindParaText( rSearchOpt, bSearchInNotes, bReplace, *this );
     643         [ +  - ]:         18 :     sal_uLong nRet = FindAll( aSwFindParaText, nStart, nEnd, eFndRngs, bCancel );
     644                 :         18 :     pDoc->SetOle2Link( aLnk );
     645 [ +  + ][ +  + ]:         18 :     if( nRet && bReplace )
     646         [ +  - ]:          4 :         pDoc->SetModified();
     647                 :            : 
     648         [ +  + ]:         18 :     if (bStartUndo)
     649                 :            :     {
     650                 :            :         SwRewriter rewriter(MakeUndoReplaceRewriter(
     651         [ +  - ]:          4 :                 nRet, rSearchOpt.searchString, rSearchOpt.replaceString));
     652 [ +  - ][ +  - ]:          4 :         pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_REPLACE, & rewriter );
                 [ +  - ]
     653                 :            :     }
     654         [ +  - ]:         18 :     return nRet;
     655                 :            : }
     656                 :            : 
     657                 :          0 : String *ReplaceBackReferences( const SearchOptions& rSearchOpt, SwPaM* pPam )
     658                 :            : {
     659                 :          0 :     String *pRet = 0;
     660 [ #  # ][ #  # ]:          0 :     if( pPam && pPam->HasMark() &&
         [ #  # ][ #  # ]
     661                 :            :         SearchAlgorithms_REGEXP == rSearchOpt.algorithmType )
     662                 :            :     {
     663                 :          0 :         const SwCntntNode* pTxtNode = pPam->GetCntntNode( sal_True );
     664 [ #  # ][ #  # ]:          0 :         if( pTxtNode && pTxtNode->IsTxtNode() && pTxtNode == pPam->GetCntntNode( sal_False ) )
         [ #  # ][ #  # ]
     665                 :            :         {
     666         [ #  # ]:          0 :             utl::TextSearch aSTxt( rSearchOpt );
     667         [ #  # ]:          0 :             String aStr( pPam->GetTxt() );
     668         [ #  # ]:          0 :             String aSearchStr( rSearchOpt.searchString );
     669         [ #  # ]:          0 :             String aReplaceStr( rSearchOpt.replaceString );
     670 [ #  # ][ #  # ]:          0 :             aStr = comphelper::string::remove(aStr, CH_TXTATR_BREAKWORD);
     671 [ #  # ][ #  # ]:          0 :             aStr = comphelper::string::remove(aStr, CH_TXTATR_INWORD);
     672                 :          0 :             xub_StrLen nStart = 0;
     673                 :          0 :             rtl::OUString sX( 'x' );
     674 [ #  # ][ #  # ]:          0 :             if( pPam->Start()->nContent > 0 )
     675                 :            :             {
     676 [ #  # ][ #  # ]:          0 :                 aStr.Insert( sX, 0 );
                 [ #  # ]
     677                 :          0 :                 ++nStart;
     678                 :            :             }
     679                 :          0 :             xub_StrLen nEnd = aStr.Len();
     680                 :          0 :             bool bDeleteLastX = false;
     681 [ #  # ][ #  # ]:          0 :             if( pPam->End()->nContent < (static_cast<const SwTxtNode*>(pTxtNode))->GetTxt().Len() )
     682                 :            :             {
     683 [ #  # ][ #  # ]:          0 :                 aStr.Insert( sX );
                 [ #  # ]
     684                 :          0 :                 bDeleteLastX = true;
     685                 :            :             }
     686         [ #  # ]:          0 :             SearchResult aResult;
     687 [ #  # ][ #  # ]:          0 :             if( aSTxt.SearchFrwrd( aStr, &nStart, &nEnd, &aResult ) )
     688                 :            :             {
     689         [ #  # ]:          0 :                 if( bDeleteLastX )
     690         [ #  # ]:          0 :                     aStr.Erase( aStr.Len() - 1 );
     691         [ #  # ]:          0 :                 aSTxt.ReplaceBackReferences( aReplaceStr, aStr, aResult );
     692 [ #  # ][ #  # ]:          0 :                 pRet = new String( aReplaceStr );
     693 [ #  # ][ #  # ]:          0 :             }
         [ #  # ][ #  # ]
                 [ #  # ]
     694                 :            :         }
     695                 :            :     }
     696                 :          0 :     return pRet;
     697                 :            : }
     698                 :            : 
     699                 :            : 
     700                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10