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

Generated by: LCOV version 1.10