LCOV - code coverage report
Current view: top level - sc/source/core/data - table6.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 154 513 30.0 %
Date: 2014-11-03 Functions: 8 19 42.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/i18n/TransliterationModules.hpp>
      21             : 
      22             : #include <unotools/textsearch.hxx>
      23             : #include <svl/srchitem.hxx>
      24             : #include <editeng/editobj.hxx>
      25             : 
      26             : #include "table.hxx"
      27             : #include "formulacell.hxx"
      28             : #include "document.hxx"
      29             : #include "stlpool.hxx"
      30             : #include "markdata.hxx"
      31             : #include "editutil.hxx"
      32             : #include "detfunc.hxx"
      33             : #include "postit.hxx"
      34             : #include "stringutil.hxx"
      35             : 
      36             : using ::com::sun::star::util::SearchOptions;
      37             : 
      38             : namespace {
      39             : 
      40           0 : bool lcl_GetTextWithBreaks( const EditTextObject& rData, ScDocument* pDoc, OUString& rVal )
      41             : {
      42             :     //  true = more than 1 paragraph
      43             : 
      44           0 :     EditEngine& rEngine = pDoc->GetEditEngine();
      45           0 :     rEngine.SetText(rData);
      46           0 :     rVal = rEngine.GetText( LINEEND_LF );
      47           0 :     return ( rEngine.GetParagraphCount() > 1 );
      48             : }
      49             : 
      50             : }
      51             : 
      52        9188 : bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRow,
      53             :                          const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
      54             : {
      55        9188 :     if (!ValidColRow( nCol, nRow))
      56           0 :         return false;
      57             : 
      58        9188 :     bool    bFound = false;
      59        9188 :     bool    bDoSearch = true;
      60        9188 :     bool    bDoBack = rSearchItem.GetBackward();
      61             : 
      62        9188 :     OUString  aString;
      63       18376 :     ScRefCellValue aCell;
      64        9188 :     if (rSearchItem.GetSelection())
      65        8954 :         bDoSearch = rMark.IsCellMarked(nCol, nRow);
      66             : 
      67        9188 :     if (!bDoSearch)
      68        7024 :         return false;
      69             : 
      70        2164 :     aCell = aCol[nCol].GetCellValue(nRow);
      71        2164 :     if (aCell.isEmpty())
      72         126 :         return false;
      73             : 
      74        2038 :     bool bMultiLine = false;
      75        2038 :     CellType eCellType = aCell.meType;
      76        2038 :     switch (rSearchItem.GetCellType())
      77             :     {
      78             :         case SVX_SEARCHIN_FORMULA:
      79             :         {
      80        2038 :             if ( eCellType == CELLTYPE_FORMULA )
      81          36 :                 aCell.mpFormula->GetFormula(aString, pDocument->GetGrammar());
      82        2002 :             else if ( eCellType == CELLTYPE_EDIT )
      83           0 :                 bMultiLine = lcl_GetTextWithBreaks(*aCell.mpEditText, pDocument, aString);
      84             :             else
      85             :             {
      86        2002 :                 aCol[nCol].GetInputString( nRow, aString );
      87             :             }
      88             :         }
      89        2038 :         break;
      90             :         case SVX_SEARCHIN_VALUE:
      91           0 :             if ( eCellType == CELLTYPE_EDIT )
      92           0 :                 bMultiLine = lcl_GetTextWithBreaks(*aCell.mpEditText, pDocument, aString);
      93             :             else
      94             :             {
      95           0 :                 aCol[nCol].GetInputString( nRow, aString );
      96             :             }
      97           0 :             break;
      98             :         case SVX_SEARCHIN_NOTE:
      99           0 :             break; // don't search this case here
     100             :         default:
     101           0 :             break;
     102             :     }
     103        2038 :     sal_Int32 nStart = 0;
     104        2038 :     sal_Int32 nEnd = aString.getLength();
     105        2038 :     ::com::sun::star::util::SearchResult aSearchResult;
     106        2038 :     if (pSearchText)
     107             :     {
     108        2038 :         if ( bDoBack )
     109             :         {
     110           0 :            sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
     111           0 :             bFound = pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
     112             :             // change results to definition before 614:
     113           0 :             --nEnd;
     114             :         }
     115             :         else
     116             :         {
     117        2038 :             bFound = pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
     118             :             // change results to definition before 614:
     119        2038 :             --nEnd;
     120             :         }
     121             : 
     122        2038 :         if (bFound && rSearchItem.GetWordOnly())
     123         212 :             bFound = (nStart == 0 && nEnd == aString.getLength() - 1);
     124             :     }
     125             :     else
     126             :     {
     127             :         OSL_FAIL("pSearchText == NULL");
     128           0 :         return bFound;
     129             :     }
     130             : 
     131        2038 :     sal_uInt8 cMatrixFlag = MM_NONE;
     132        3198 :     if ( bFound &&
     133        1160 :         ( (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE)
     134        1160 :         ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) ) &&
     135             :             // Matrix nicht zerreissen, nur Matrixformel ersetzen
     136           6 :             !( (eCellType == CELLTYPE_FORMULA &&
     137           6 :             ((cMatrixFlag = aCell.mpFormula->GetMatrixFlag()) == MM_REFERENCE))
     138             :             // kein UndoDoc => Matrix nicht wiederherstellbar => nicht ersetzen
     139        3178 :             || (cMatrixFlag != MM_NONE && !pUndoDoc) ) &&
     140         570 :          IsBlockEditable(nCol, nRow, nCol, nRow)
     141             :         )
     142             :     {
     143         570 :         if ( cMatrixFlag == MM_NONE && rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE )
     144           0 :             rUndoStr = aString;
     145         570 :         else if (pUndoDoc)
     146             :         {
     147         570 :             ScAddress aAdr( nCol, nRow, nTab );
     148         570 :             aCell.commit(*pUndoDoc, aAdr);
     149             :         }
     150         570 :         bool bRepeat = !rSearchItem.GetWordOnly();
     151         570 :         do
     152             :         {
     153             :             //  wenn der gefundene Text leer ist, nicht weitersuchen,
     154             :             //  sonst wuerde man nie mehr aufhoeren (#35410#)
     155         570 :             if ( nEnd < nStart )
     156           0 :                 bRepeat = false;
     157             : 
     158         570 :             OUString sReplStr = rSearchItem.GetReplaceString();
     159         570 :             if (rSearchItem.GetRegExp())
     160             :             {
     161         538 :                 pSearchText->ReplaceBackReferences( sReplStr, aString, aSearchResult );
     162         538 :                 OUStringBuffer aStrBuffer(aString);
     163         538 :                 aStrBuffer.remove(nStart, nEnd-nStart+1);
     164         538 :                 aStrBuffer.insert(nStart, sReplStr);
     165         538 :                 aString = aStrBuffer.makeStringAndClear();
     166             :             }
     167             :             else
     168             :             {
     169          32 :                 OUStringBuffer aStrBuffer(aString);
     170          32 :                 aStrBuffer.remove(nStart, nEnd-nStart+1);
     171          32 :                 aStrBuffer.insert(nStart, rSearchItem.GetReplaceString());
     172          32 :                 aString = aStrBuffer.makeStringAndClear();
     173             :             }
     174             : 
     175             :                     //  Indizes anpassen
     176         570 :             if (bDoBack)
     177             :             {
     178           0 :                 nEnd = nStart;
     179           0 :                 nStart = 0;
     180             :             }
     181             :             else
     182             :             {
     183         570 :                 nStart = nStart + sReplStr.getLength();
     184         570 :                 nEnd = aString.getLength();
     185             :             }
     186             : 
     187             :                     //  weitersuchen ?
     188         570 :             if (bRepeat)
     189             :             {
     190         570 :                 if ( rSearchItem.GetCommand() != SVX_SEARCHCMD_REPLACE_ALL || nStart >= nEnd )
     191         562 :                     bRepeat = false;
     192           8 :                 else if (bDoBack)
     193             :                 {
     194           0 :                     sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
     195           0 :                     bRepeat = pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
     196             :                     // change results to definition before 614:
     197           0 :                     --nEnd;
     198             :                 }
     199             :                 else
     200             :                 {
     201           8 :                     bRepeat = pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
     202             :                     // change results to definition before 614:
     203           8 :                     --nEnd;
     204             :                 }
     205         570 :             }
     206             :         }
     207             :         while (bRepeat);
     208             : 
     209         570 :         if ( cMatrixFlag != MM_NONE )
     210             :         {   // Matrix nicht zerreissen
     211           0 :             if ( aString.getLength() > 2 )
     212             :             {   // {} raus, erst hier damit auch "{=" durch "{=..." ersetzt werden kann
     213           0 :                 if ( aString[ aString.getLength()-1 ] == '}' )
     214           0 :                     aString = aString.copy( 0, aString.getLength()-1 );
     215           0 :                 if ( aString[0] == '{' )
     216           0 :                     aString = aString.copy( 1 );
     217             :             }
     218           0 :             ScAddress aAdr( nCol, nRow, nTab );
     219             :             ScFormulaCell* pFCell = new ScFormulaCell( pDocument, aAdr,
     220           0 :                 aString, pDocument->GetGrammar(), cMatrixFlag );
     221             :             SCCOL nMatCols;
     222             :             SCROW nMatRows;
     223           0 :             aCell.mpFormula->GetMatColsRows(nMatCols, nMatRows);
     224           0 :             pFCell->SetMatColsRows( nMatCols, nMatRows );
     225           0 :             aCol[nCol].SetFormulaCell(nRow, pFCell);
     226             :         }
     227         570 :         else if ( bMultiLine && aString.indexOf('\n') != -1 )
     228             :         {
     229           0 :             ScFieldEditEngine& rEngine = pDocument->GetEditEngine();
     230           0 :             rEngine.SetText(aString);
     231           0 :             SetEditText(nCol, nRow, rEngine.CreateTextObject());
     232             :         }
     233             :         else
     234         570 :             aCol[nCol].SetString(nRow, nTab, aString, pDocument->GetAddressConvention());
     235             :         // pCell is invalid now (deleted)
     236             :     }
     237       11226 :     return bFound;
     238             : }
     239             : 
     240        9188 : void ScTable::SkipFilteredRows(SCROW& rRow, SCROW& rLastNonFilteredRow, bool bForward)
     241             : {
     242        9188 :     if (bForward)
     243             :     {
     244             :         // forward search
     245             : 
     246        9188 :         if (rRow <= rLastNonFilteredRow)
     247        6872 :             return;
     248             : 
     249        2316 :         SCROW nLastRow = rRow;
     250        2316 :         if (RowFiltered(rRow, NULL, &nLastRow))
     251             :             // move to the first non-filtered row.
     252           0 :             rRow = nLastRow + 1;
     253             :         else
     254             :             // record the last non-filtered row to avoid checking
     255             :             // the filtered state for each and every row.
     256        2316 :             rLastNonFilteredRow = nLastRow;
     257             :     }
     258             :     else
     259             :     {
     260             :         // backward search
     261             : 
     262           0 :         if (rRow >= rLastNonFilteredRow)
     263           0 :             return;
     264             : 
     265           0 :         SCROW nFirstRow = rRow;
     266           0 :         if (RowFiltered(rRow, &nFirstRow, NULL))
     267             :             // move to the first non-filtered row.
     268           0 :             rRow = nFirstRow - 1;
     269             :         else
     270             :             // record the last non-filtered row to avoid checking
     271             :             // the filtered state for each and every row.
     272           0 :             rLastNonFilteredRow = nFirstRow;
     273             :     }
     274             : }
     275             : 
     276        1274 : bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
     277             :                      const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
     278             : {
     279        1274 :     bool bFound = false;
     280        1274 :     bool bAll =  (rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL)
     281        1274 :                ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL);
     282        1274 :     SCCOL nCol = rCol;
     283        1274 :     SCROW nRow = rRow;
     284             :     SCCOL nLastCol;
     285             :     SCROW nLastRow;
     286        1274 :     GetLastDataPos(nLastCol, nLastRow);
     287        1274 :     bool bSkipFiltered = !rSearchItem.IsSearchFiltered();
     288        1274 :     if (!bAll && rSearchItem.GetBackward())
     289             :     {
     290           0 :         SCROW nLastNonFilteredRow = MAXROW + 1;
     291           0 :         nCol = std::min(nCol, (SCCOL)(nLastCol + 1));
     292           0 :         nRow = std::min(nRow, (SCROW)(nLastRow + 1));
     293           0 :         if (rSearchItem.GetRowDirection())
     294             :         {
     295           0 :             nCol--;
     296           0 :             while (!bFound && ((SCsROW)nRow >= 0))
     297             :             {
     298           0 :                 if (bSkipFiltered)
     299           0 :                     SkipFilteredRows(nRow, nLastNonFilteredRow, false);
     300             : 
     301           0 :                 while (!bFound && ((SCsCOL)nCol >= 0))
     302             :                 {
     303           0 :                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     304           0 :                     if (!bFound)
     305             :                     {
     306             :                         bool bIsEmpty;
     307           0 :                         do
     308             :                         {
     309           0 :                             nCol--;
     310           0 :                             if ((SCsCOL)nCol >= 0)
     311           0 :                                 bIsEmpty = aCol[nCol].IsEmptyData();
     312             :                             else
     313           0 :                                 bIsEmpty = true;
     314             :                         }
     315           0 :                         while (((SCsCOL)nCol >= 0) && bIsEmpty);
     316             :                     }
     317             :                 }
     318           0 :                 if (!bFound)
     319             :                 {
     320           0 :                     nCol = nLastCol;
     321           0 :                     nRow--;
     322             :                 }
     323             :             }
     324             :         }
     325             :         else
     326             :         {
     327           0 :             nRow--;
     328           0 :             while (!bFound && ((SCsCOL)nCol >= 0))
     329             :             {
     330           0 :                 while (!bFound && ((SCsROW)nRow >= 0))
     331             :                 {
     332           0 :                     if (bSkipFiltered)
     333           0 :                         SkipFilteredRows(nRow, nLastNonFilteredRow, false);
     334             : 
     335           0 :                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     336           0 :                     if (!bFound)
     337             :                     {
     338           0 :                          if (!aCol[nCol].GetPrevDataPos(nRow))
     339           0 :                             nRow = -1;
     340             :                     }
     341             :                 }
     342           0 :                 if (!bFound)
     343             :                 {
     344             :                     // Not found in this column.  Move to the next column.
     345             :                     bool bIsEmpty;
     346           0 :                     nRow = nLastRow;
     347           0 :                     nLastNonFilteredRow = MAXROW + 1;
     348           0 :                     do
     349             :                     {
     350           0 :                         nCol--;
     351           0 :                         if ((SCsCOL)nCol >= 0)
     352           0 :                             bIsEmpty = aCol[nCol].IsEmptyData();
     353             :                         else
     354           0 :                             bIsEmpty = true;
     355             :                     }
     356           0 :                     while (((SCsCOL)nCol >= 0) && bIsEmpty);
     357             :                 }
     358             :             }
     359             :         }
     360             :     }
     361             :     else
     362             :     {
     363        1274 :         SCROW nLastNonFilteredRow = -1;
     364        1274 :         if (!bAll && rSearchItem.GetRowDirection())
     365             :         {
     366           0 :             nCol++;
     367           0 :             while (!bFound && (nRow <= nLastRow))
     368             :             {
     369           0 :                 if (bSkipFiltered)
     370           0 :                     SkipFilteredRows(nRow, nLastNonFilteredRow, true);
     371             : 
     372           0 :                 while (!bFound && (nCol <= nLastCol))
     373             :                 {
     374           0 :                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     375           0 :                     if (!bFound)
     376             :                     {
     377           0 :                         nCol++;
     378           0 :                         while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
     379             :                     }
     380             :                 }
     381           0 :                 if (!bFound)
     382             :                 {
     383           0 :                     nCol = 0;
     384           0 :                     nRow++;
     385             :                 }
     386             :             }
     387             :         }
     388             :         else
     389             :         {
     390        1274 :             nRow++;
     391        4882 :             while (!bFound && (nCol <= nLastCol))
     392             :             {
     393       13856 :                 while (!bFound && (nRow <= nLastRow))
     394             :                 {
     395        9188 :                     if (bSkipFiltered)
     396        9188 :                         SkipFilteredRows(nRow, nLastNonFilteredRow, true);
     397             : 
     398        9188 :                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     399        9188 :                     if (!bFound)
     400             :                     {
     401        8028 :                          if (!aCol[nCol].GetNextDataPos(nRow))
     402        1156 :                             nRow = MAXROW + 1;
     403             :                     }
     404             :                 }
     405        2334 :                 if (!bFound)
     406             :                 {
     407             :                     // Not found in this column.  Move to the next column.
     408        1174 :                     nRow = 0;
     409        1174 :                     nLastNonFilteredRow = -1;
     410        1174 :                     nCol++;
     411        1174 :                     while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
     412             :                 }
     413             :             }
     414             :         }
     415             :     }
     416        1274 :     if (bFound)
     417             :     {
     418        1160 :         rCol = nCol;
     419        1160 :         rRow = nRow;
     420             :     }
     421        1274 :     return bFound;
     422             : }
     423             : 
     424          46 : bool ScTable::SearchAll(const SvxSearchItem& rSearchItem, const ScMarkData& rMark,
     425             :                         ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     426             : {
     427          46 :     bool bFound = true;
     428          46 :     SCCOL nCol = 0;
     429          46 :     SCROW nRow = -1;
     430          46 :     bool bEverFound = false;
     431             : 
     432         606 :     do
     433             :     {
     434         606 :         bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     435         606 :         if (bFound)
     436             :         {
     437         560 :             bEverFound = true;
     438         560 :             rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
     439             :         }
     440             :     }
     441             :     while (bFound);
     442             : 
     443          46 :     return bEverFound;
     444             : }
     445             : 
     446           0 : void ScTable::UpdateSearchItemAddressForReplace( const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow )
     447             : {
     448           0 :     if (rSearchItem.GetBackward())
     449             :     {
     450           0 :         if (rSearchItem.GetRowDirection())
     451           0 :             rCol += 1;
     452             :         else
     453           0 :             rRow += 1;
     454             :     }
     455             :     else
     456             :     {
     457           0 :         if (rSearchItem.GetRowDirection())
     458           0 :             rCol -= 1;
     459             :         else
     460           0 :             rRow -= 1;
     461             :     }
     462           0 : }
     463             : 
     464           0 : bool ScTable::Replace(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
     465             :                       const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
     466             : {
     467           0 :     SCCOL nCol = rCol;
     468           0 :     SCROW nRow = rRow;
     469             : 
     470           0 :     UpdateSearchItemAddressForReplace( rSearchItem, nCol, nRow );
     471           0 :     bool bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     472           0 :     if (bFound)
     473             :     {
     474           0 :         rCol = nCol;
     475           0 :         rRow = nRow;
     476             :     }
     477           0 :     return bFound;
     478             : }
     479             : 
     480          52 : bool ScTable::ReplaceAll(
     481             :     const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges,
     482             :     OUString& rUndoStr, ScDocument* pUndoDoc)
     483             : {
     484          52 :     SCCOL nCol = 0;
     485          52 :     SCROW nRow = -1;
     486             : 
     487          52 :     bool bEverFound = false;
     488             :     while (true)
     489             :     {
     490         622 :         bool bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     491             : 
     492         622 :         if (bFound)
     493             :         {
     494         570 :             bEverFound = true;
     495         570 :             rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
     496             :         }
     497             :         else
     498          52 :             break;
     499             :     }
     500         570 :     return bEverFound;
     501             : }
     502             : 
     503           0 : bool ScTable::SearchStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
     504             :                           const ScMarkData& rMark)
     505             : {
     506             :     const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
     507           0 :                                         pDocument->GetStyleSheetPool()->Find(
     508           0 :                                         rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
     509             : 
     510           0 :     SCsCOL nCol = rCol;
     511           0 :     SCsROW nRow = rRow;
     512           0 :     bool bFound = false;
     513             : 
     514           0 :     bool bSelect = rSearchItem.GetSelection();
     515           0 :     bool bRows = rSearchItem.GetRowDirection();
     516           0 :     bool bBack = rSearchItem.GetBackward();
     517           0 :     short nAdd = bBack ? -1 : 1;
     518             : 
     519           0 :     if (bRows)                                      // zeilenweise
     520             :     {
     521           0 :         if (!ValidCol(nCol))
     522             :         {
     523             :             SAL_WARN( "sc.core", "SearchStyle: bad column " << nCol);
     524           0 :             return false;
     525             :         }
     526           0 :         nRow += nAdd;
     527           0 :         do
     528             :         {
     529           0 :             SCsROW nNextRow = aCol[nCol].SearchStyle( nRow, pSearchStyle, bBack, bSelect, rMark );
     530           0 :             if (!ValidRow(nNextRow))
     531             :             {
     532           0 :                 nRow = bBack ? MAXROW : 0;
     533           0 :                 nCol = sal::static_int_cast<SCsCOL>( nCol + nAdd );
     534             :             }
     535             :             else
     536             :             {
     537           0 :                 nRow = nNextRow;
     538           0 :                 bFound = true;
     539             :             }
     540             :         }
     541           0 :         while (!bFound && ValidCol(nCol));
     542             :     }
     543             :     else                                            // spaltenweise
     544             :     {
     545             :         SCsROW nNextRows[MAXCOLCOUNT];
     546             :         SCsCOL i;
     547           0 :         for (i=0; i<=MAXCOL; i++)
     548             :         {
     549           0 :             SCsROW nSRow = nRow;
     550           0 :             if (bBack)  { if (i>=nCol) --nSRow; }
     551           0 :             else        { if (i<=nCol) ++nSRow; }
     552           0 :             nNextRows[i] = aCol[i].SearchStyle( nSRow, pSearchStyle, bBack, bSelect, rMark );
     553             :         }
     554           0 :         if (bBack)                          // rueckwaerts
     555             :         {
     556           0 :             nRow = -1;
     557           0 :             for (i=MAXCOL; i>=0; i--)
     558           0 :                 if (nNextRows[i]>nRow)
     559             :                 {
     560           0 :                     nCol = i;
     561           0 :                     nRow = nNextRows[i];
     562           0 :                     bFound = true;
     563             :                 }
     564             :         }
     565             :         else                                // vorwaerts
     566             :         {
     567           0 :             nRow = MAXROW+1;
     568           0 :             for (i=0; i<=MAXCOL; i++)
     569           0 :                 if (nNextRows[i]<nRow)
     570             :                 {
     571           0 :                     nCol = i;
     572           0 :                     nRow = nNextRows[i];
     573           0 :                     bFound = true;
     574             :                 }
     575             :         }
     576             :     }
     577             : 
     578           0 :     if (bFound)
     579             :     {
     580           0 :         rCol = (SCCOL) nCol;
     581           0 :         rRow = (SCROW) nRow;
     582             :     }
     583           0 :     return bFound;
     584             : }
     585             : 
     586             : //!     einzelnes Pattern fuer Undo zurueckgeben
     587             : 
     588           0 : bool ScTable::ReplaceStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
     589             :                            const ScMarkData& rMark, bool bIsUndo)
     590             : {
     591             :     bool bRet;
     592           0 :     if (bIsUndo)
     593           0 :         bRet = true;
     594             :     else
     595           0 :         bRet = SearchStyle(rSearchItem, rCol, rRow, rMark);
     596           0 :     if (bRet)
     597             :     {
     598             :         const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
     599           0 :                                         pDocument->GetStyleSheetPool()->Find(
     600           0 :                                         rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
     601             : 
     602           0 :         if (pReplaceStyle)
     603           0 :             ApplyStyle( rCol, rRow, *pReplaceStyle );
     604             :         else
     605             :         {
     606             :             OSL_FAIL("pReplaceStyle==0");
     607             :         }
     608             :     }
     609             : 
     610           0 :     return bRet;
     611             : }
     612             : 
     613           0 : bool ScTable::SearchAllStyle(
     614             :     const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges)
     615             : {
     616             :     const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
     617           0 :                                         pDocument->GetStyleSheetPool()->Find(
     618           0 :                                         rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
     619           0 :     bool bSelect = rSearchItem.GetSelection();
     620           0 :     bool bBack = rSearchItem.GetBackward();
     621           0 :     bool bEverFound = false;
     622             : 
     623           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
     624             :     {
     625           0 :         bool bFound = true;
     626           0 :         SCsROW nRow = 0;
     627             :         SCsROW nEndRow;
     628           0 :         while (bFound && nRow <= MAXROW)
     629             :         {
     630           0 :             bFound = aCol[i].SearchStyleRange( nRow, nEndRow, pSearchStyle, bBack, bSelect, rMark );
     631           0 :             if (bFound)
     632             :             {
     633           0 :                 if (nEndRow<nRow)
     634             :                 {
     635           0 :                     SCsROW nTemp = nRow;
     636           0 :                     nRow = nEndRow;
     637           0 :                     nEndRow = nTemp;
     638             :                 }
     639           0 :                 rMatchedRanges.Join(ScRange(i, nRow, nTab, i, nEndRow, nTab));
     640           0 :                 nRow = nEndRow + 1;
     641           0 :                 bEverFound = true;
     642             :             }
     643             :         }
     644             :     }
     645             : 
     646           0 :     return bEverFound;
     647             : }
     648             : 
     649           0 : bool ScTable::ReplaceAllStyle(
     650             :     const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges,
     651             :     ScDocument* pUndoDoc)
     652             : {
     653           0 :     bool bRet = SearchAllStyle(rSearchItem, rMark, rMatchedRanges);
     654           0 :     if (bRet)
     655             :     {
     656             :         const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
     657           0 :                                         pDocument->GetStyleSheetPool()->Find(
     658           0 :                                         rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
     659             : 
     660           0 :         if (pReplaceStyle)
     661             :         {
     662           0 :             if (pUndoDoc)
     663             :                 pDocument->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab,
     664           0 :                                             IDF_ATTRIB, true, pUndoDoc, &rMark );
     665           0 :             ApplySelectionStyle( *pReplaceStyle, rMark );
     666             :         }
     667             :         else
     668             :         {
     669             :             OSL_FAIL("pReplaceStyle==0");
     670             :         }
     671             :     }
     672             : 
     673           0 :     return bRet;
     674             : }
     675             : 
     676         144 : bool ScTable::SearchAndReplace(
     677             :     const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark,
     678             :     ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     679             : {
     680         144 :     sal_uInt16 nCommand = rSearchItem.GetCommand();
     681         144 :     bool bFound = false;
     682         288 :     if ( ValidColRow(rCol, rRow) ||
     683          42 :          ((nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE) &&
     684         126 :            (((rCol == MAXCOLCOUNT || rCol == -1) && ValidRow(rRow)) ||
     685          84 :             ((rRow == MAXROWCOUNT || rRow == -1) && ValidCol(rCol))
     686             :            )
     687             :          )
     688             :        )
     689             :     {
     690         144 :         bool bStyles = rSearchItem.GetPattern();
     691         144 :         if (bStyles)
     692             :         {
     693           0 :             if (nCommand == SVX_SEARCHCMD_FIND)
     694           0 :                 bFound = SearchStyle(rSearchItem, rCol, rRow, rMark);
     695           0 :             else if (nCommand == SVX_SEARCHCMD_REPLACE)
     696           0 :                 bFound = ReplaceStyle(rSearchItem, rCol, rRow, rMark, false);
     697           0 :             else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
     698           0 :                 bFound = SearchAllStyle(rSearchItem, rMark, rMatchedRanges);
     699           0 :             else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
     700           0 :                 bFound = ReplaceAllStyle(rSearchItem, rMark, rMatchedRanges, pUndoDoc);
     701             :         }
     702             :         else
     703             :         {
     704             :             //  SearchParam no longer needed - SearchOptions contains all settings
     705         144 :             com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
     706         144 :             aSearchOptions.Locale = *ScGlobal::GetLocale();
     707             : 
     708         144 :             if (aSearchOptions.searchString.isEmpty())
     709             :             {
     710             :                 // Search for empty cells.
     711           0 :                 return SearchAndReplaceEmptyCells(rSearchItem, rCol, rRow, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
     712             :             }
     713             : 
     714             :             //  reflect UseAsianOptions flag in SearchOptions
     715             :             //  (use only ignore case and width if asian options are disabled).
     716             :             //  This is also done in SvxSearchDialog CommandHdl, but not in API object.
     717         144 :             if ( !rSearchItem.IsUseAsianOptions() )
     718             :                 aSearchOptions.transliterateFlags &=
     719             :                     ( com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
     720         144 :                       com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
     721             : 
     722         144 :             pSearchText = new utl::TextSearch( aSearchOptions );
     723             : 
     724         144 :             if (nCommand == SVX_SEARCHCMD_FIND)
     725          46 :                 bFound = Search(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
     726          98 :             else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
     727          46 :                 bFound = SearchAll(rSearchItem, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
     728          52 :             else if (nCommand == SVX_SEARCHCMD_REPLACE)
     729           0 :                 bFound = Replace(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
     730          52 :             else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
     731          52 :                 bFound = ReplaceAll(rSearchItem, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
     732             : 
     733         144 :             delete pSearchText;
     734         144 :             pSearchText = NULL;
     735             :         }
     736             :     }
     737         144 :     return bFound;
     738             : }
     739             : 
     740           0 : bool ScTable::SearchAndReplaceEmptyCells(
     741             :     const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark,
     742             :     ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     743             : {
     744             :     SCCOL nColStart, nColEnd;
     745             :     SCROW nRowStart, nRowEnd;
     746           0 :     GetFirstDataPos(nColStart, nRowStart);
     747           0 :     GetLastDataPos(nColEnd, nRowEnd);
     748             : 
     749           0 :     ScRangeList aRanges;
     750           0 :     aRanges.Append(ScRange(nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab));
     751             : 
     752           0 :     if (rSearchItem.GetSelection())
     753             :     {
     754             :         // current selection only.
     755           0 :         if (!rMark.IsMarked() && !rMark.IsMultiMarked())
     756             :             // There is no selection.  Bail out.
     757           0 :             return false;
     758             : 
     759           0 :         ScRangeList aMarkedRanges, aNewRanges;
     760           0 :         rMark.FillRangeListWithMarks(&aMarkedRanges, true);
     761           0 :         for ( size_t i = 0, n = aMarkedRanges.size(); i < n; ++i )
     762             :         {
     763           0 :             ScRange* p = aMarkedRanges[ i ];
     764           0 :             if (p->aStart.Col() > nColEnd || p->aStart.Row() > nRowEnd)
     765             :                 // This range is outside the data area.  Skip it.
     766           0 :                 continue;
     767             : 
     768             :             // Shrink the range into data area only.
     769           0 :             if (p->aStart.Col() < nColStart)
     770           0 :                 p->aStart.SetCol(rCol);
     771           0 :             if (p->aStart.Row() < nRowStart)
     772           0 :                 p->aStart.SetRow(rRow);
     773             : 
     774           0 :             if (p->aEnd.Col() > nColEnd)
     775           0 :                 p->aEnd.SetCol(nColEnd);
     776           0 :             if (p->aEnd.Row() > nRowEnd)
     777           0 :                 p->aEnd.SetRow(nRowEnd);
     778             : 
     779           0 :             aNewRanges.Append(*p);
     780             :         }
     781           0 :         aRanges = aNewRanges;
     782             :     }
     783             : 
     784           0 :     sal_uInt16 nCommand = rSearchItem.GetCommand();
     785           0 :     if (nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE)
     786             :     {
     787           0 :         if (rSearchItem.GetBackward())
     788             :         {
     789           0 :             for ( size_t i = aRanges.size(); i > 0; --i )
     790             :             {
     791           0 :                 ScRange* p = aRanges[ i - 1 ];
     792           0 :                 if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr))
     793           0 :                     return true;
     794             :             }
     795             :         }
     796             :         else
     797             :         {
     798           0 :             for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
     799             :             {
     800           0 :                 ScRange* p = aRanges[ i ];
     801           0 :                 if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr))
     802           0 :                     return true;
     803             :             }
     804           0 :         }
     805             :     }
     806           0 :     else if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
     807             :     {
     808           0 :         bool bFound = false;
     809           0 :         for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
     810             :         {
     811           0 :             ScRange* p = aRanges[ i ];
     812           0 :             bFound |= SearchRangeForAllEmptyCells(*p, rSearchItem, rMatchedRanges, rUndoStr, pUndoDoc);
     813             :         }
     814           0 :         return bFound;
     815             :     }
     816           0 :     return false;
     817             : }
     818             : 
     819             : namespace {
     820             : 
     821           0 : bool lcl_maybeReplaceCellString(
     822             :     ScColumn& rColObj, SCCOL& rCol, SCROW& rRow, OUString& rUndoStr, SCCOL nCol, SCROW nRow, const SvxSearchItem& rSearchItem)
     823             : {
     824           0 :     ScRefCellValue aCell = rColObj.GetCellValue(nRow);
     825           0 :     if (aCell.isEmpty())
     826             :     {
     827             :         // empty cell found.
     828           0 :         rCol = nCol;
     829           0 :         rRow = nRow;
     830           0 :         if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
     831           0 :             !rSearchItem.GetReplaceString().isEmpty())
     832             :         {
     833           0 :             rColObj.SetRawString(nRow, rSearchItem.GetReplaceString());
     834           0 :             rUndoStr = OUString();
     835             :         }
     836           0 :         return true;
     837             :     }
     838           0 :     return false;
     839             : }
     840             : 
     841             : }
     842             : 
     843           0 : bool ScTable::SearchRangeForEmptyCell(
     844             :     const ScRange& rRange, const SvxSearchItem& rSearchItem,
     845             :     SCCOL& rCol, SCROW& rRow, OUString& rUndoStr)
     846             : {
     847           0 :     sal_uInt16 nCmd = rSearchItem.GetCommand();
     848           0 :     bool bSkipFiltered = rSearchItem.IsSearchFiltered();
     849           0 :     if (rSearchItem.GetBackward())
     850             :     {
     851             :         // backward search
     852           0 :         if (rSearchItem.GetRowDirection())
     853             :         {
     854             :             // row direction.
     855           0 :             SCROW nLastNonFilteredRow = MAXROW + 1;
     856           0 :             SCROW nBeginRow = rRange.aEnd.Row() > rRow ? rRow : rRange.aEnd.Row();
     857           0 :             for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
     858             :             {
     859           0 :                 if (bSkipFiltered)
     860           0 :                     SkipFilteredRows(nRow, nLastNonFilteredRow, false);
     861           0 :                 if (nRow < rRange.aStart.Row())
     862           0 :                     break;
     863             : 
     864           0 :                 SCCOL nBeginCol = rRange.aEnd.Col();
     865           0 :                 if (nRow == rRow && nBeginCol >= rCol)
     866             :                     // always start from one cell before the cursor.
     867           0 :                     nBeginCol = rCol - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     868             : 
     869           0 :                 for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
     870             :                 {
     871           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     872           0 :                         return true;
     873             :                 }
     874             :             }
     875             :         }
     876             :         else
     877             :         {
     878             :             // column direction.
     879           0 :             SCCOL nBeginCol = rRange.aEnd.Col() > rCol ? rCol : rRange.aEnd.Col();
     880           0 :             for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
     881             :             {
     882           0 :                 SCROW nLastNonFilteredRow = MAXROW + 1;
     883           0 :                 SCROW nBeginRow = rRange.aEnd.Row();
     884           0 :                 if (nCol == rCol && nBeginRow >= rRow)
     885             :                     // always start from one cell before the cursor.
     886           0 :                     nBeginRow = rRow - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     887           0 :                 for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
     888             :                 {
     889           0 :                     if (bSkipFiltered)
     890           0 :                         SkipFilteredRows(nRow, nLastNonFilteredRow, false);
     891           0 :                     if (nRow < rRange.aStart.Row())
     892           0 :                         break;
     893             : 
     894           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     895           0 :                         return true;
     896             :                 }
     897             :             }
     898             :         }
     899             :     }
     900             :     else
     901             :     {
     902             :         // forward search
     903           0 :         if (rSearchItem.GetRowDirection())
     904             :         {
     905             :             // row direction.
     906           0 :             SCROW nLastNonFilteredRow = -1;
     907           0 :             SCROW nBeginRow = rRange.aStart.Row() < rRow ? rRow : rRange.aStart.Row();
     908           0 :             for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
     909             :             {
     910           0 :                 if (bSkipFiltered)
     911           0 :                     SkipFilteredRows(nRow, nLastNonFilteredRow, true);
     912           0 :                 if (nRow > rRange.aEnd.Row())
     913           0 :                     break;
     914             : 
     915           0 :                 SCCOL nBeginCol = rRange.aStart.Col();
     916           0 :                 if (nRow == rRow && nBeginCol <= rCol)
     917             :                     // always start from one cell past the cursor.
     918           0 :                     nBeginCol = rCol + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     919           0 :                 for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
     920             :                 {
     921           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     922           0 :                         return true;
     923             :                 }
     924             :             }
     925             :         }
     926             :         else
     927             :         {
     928             :             // column direction.
     929           0 :             SCCOL nBeginCol = rRange.aStart.Col() < rCol ? rCol : rRange.aStart.Col();
     930           0 :             for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
     931             :             {
     932           0 :                 SCROW nLastNonFilteredRow = -1;
     933           0 :                 SCROW nBeginRow = rRange.aStart.Row();
     934           0 :                 if (nCol == rCol && nBeginRow <= rRow)
     935             :                     // always start from one cell past the cursor.
     936           0 :                     nBeginRow = rRow + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     937           0 :                 for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
     938             :                 {
     939           0 :                     if (bSkipFiltered)
     940           0 :                         SkipFilteredRows(nRow, nLastNonFilteredRow, true);
     941           0 :                     if (nRow > rRange.aEnd.Row())
     942           0 :                         break;
     943             : 
     944           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     945           0 :                         return true;
     946             :                 }
     947             :             }
     948             :         }
     949             :     }
     950           0 :     return false;
     951             : }
     952             : 
     953           0 : bool ScTable::SearchRangeForAllEmptyCells(
     954             :     const ScRange& rRange, const SvxSearchItem& rSearchItem,
     955             :     ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     956             : {
     957           0 :     bool bFound = false;
     958           0 :     bool bReplace = (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) &&
     959           0 :                     !rSearchItem.GetReplaceString().isEmpty();
     960           0 :     bool bSkipFiltered = rSearchItem.IsSearchFiltered();
     961             : 
     962           0 :     for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
     963             :     {
     964           0 :         SCROW nLastNonFilteredRow = -1;
     965           0 :         if (aCol[nCol].IsEmptyData())
     966             :         {
     967             :             // The entire column is empty.
     968           0 :             for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
     969             :             {
     970             :                 SCROW nLastRow;
     971           0 :                 if (!RowFiltered(nRow, NULL, &nLastRow))
     972             :                 {
     973           0 :                     rMatchedRanges.Join(ScRange(nCol, nRow, nTab, nCol, nLastRow, nTab));
     974           0 :                     if (bReplace)
     975             :                     {
     976           0 :                         const OUString& rNewStr = rSearchItem.GetReplaceString();
     977           0 :                         for (SCROW i = nRow; i <= nLastRow; ++i)
     978             :                         {
     979           0 :                             aCol[nCol].SetRawString(i, rNewStr);
     980           0 :                             if (pUndoDoc)
     981             :                             {
     982             :                                 // TODO: I'm using a string cell with empty content to
     983             :                                 // trigger deletion of cell instance on undo.  Maybe I
     984             :                                 // should create a new cell type for this?
     985           0 :                                 ScSetStringParam aParam;
     986           0 :                                 aParam.setTextInput();
     987           0 :                                 pUndoDoc->SetString(ScAddress(nCol, i, nTab), EMPTY_OUSTRING);
     988             :                             }
     989             :                         }
     990           0 :                         rUndoStr = OUString();
     991             :                     }
     992             :                 }
     993             : 
     994           0 :                 nRow = nLastRow; // move to the last filtered row.
     995             :             }
     996           0 :             bFound = true;
     997           0 :             continue;
     998             :         }
     999             : 
    1000           0 :         for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
    1001             :         {
    1002           0 :             if (bSkipFiltered)
    1003           0 :                 SkipFilteredRows(nRow, nLastNonFilteredRow, true);
    1004           0 :             if (nRow > rRange.aEnd.Row())
    1005           0 :                 break;
    1006             : 
    1007           0 :             ScRefCellValue aCell = aCol[nCol].GetCellValue(nRow);
    1008           0 :             if (aCell.isEmpty())
    1009             :             {
    1010             :                 // empty cell found
    1011           0 :                 rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
    1012           0 :                 bFound = true;
    1013             : 
    1014           0 :                 if (bReplace)
    1015             :                 {
    1016           0 :                     aCol[nCol].SetRawString(nRow, rSearchItem.GetReplaceString());
    1017           0 :                     if (pUndoDoc)
    1018             :                     {
    1019             :                         // TODO: I'm using a string cell with empty content to
    1020             :                         // trigger deletion of cell instance on undo.  Maybe I
    1021             :                         // should create a new cell type for this?
    1022           0 :                         ScSetStringParam aParam;
    1023           0 :                         aParam.setTextInput();
    1024           0 :                         pUndoDoc->SetString(ScAddress(nCol, nRow, nTab), EMPTY_OUSTRING);
    1025             :                     }
    1026             :                 }
    1027             :             }
    1028           0 :         }
    1029             :     }
    1030           0 :     return bFound;
    1031         228 : }
    1032             : 
    1033             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10