LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - table6.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 159 513 31.0 %
Date: 2013-07-09 Functions: 9 20 45.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             : #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             : //--------------------------------------------------------------------------
      37             : 
      38             : 
      39             : using ::com::sun::star::util::SearchOptions;
      40             : 
      41             : namespace {
      42             : 
      43           4 : bool lcl_GetTextWithBreaks( const EditTextObject& rData, ScDocument* pDoc, OUString& rVal )
      44             : {
      45             :     //  true = more than 1 paragraph
      46             : 
      47           4 :     EditEngine& rEngine = pDoc->GetEditEngine();
      48           4 :     rEngine.SetText(rData);
      49           4 :     rVal = rEngine.GetText( LINEEND_LF );
      50           4 :     return ( rEngine.GetParagraphCount() > 1 );
      51             : }
      52             : 
      53             : }
      54             : 
      55        4594 : bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRow,
      56             :                          const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
      57             : {
      58        4594 :     bool    bFound = false;
      59        4594 :     bool    bDoSearch = true;
      60        4594 :     bool    bDoBack = rSearchItem.GetBackward();
      61             : 
      62        4594 :     OUString  aString;
      63        9188 :     ScRefCellValue aCell;
      64        4594 :     if (rSearchItem.GetSelection())
      65        4477 :         bDoSearch = rMark.IsCellMarked(nCol, nRow);
      66             : 
      67        4594 :     if (!bDoSearch)
      68        3512 :         return false;
      69             : 
      70        1082 :     aCell = aCol[nCol].GetCellValue(nRow);
      71        1082 :     if (aCell.isEmpty())
      72          63 :         return false;
      73             : 
      74        1019 :     bool bMultiLine = false;
      75        1019 :     CellType eCellType = aCell.meType;
      76        1019 :     switch (rSearchItem.GetCellType())
      77             :     {
      78             :         case SVX_SEARCHIN_FORMULA:
      79             :         {
      80        1019 :             if ( eCellType == CELLTYPE_FORMULA )
      81          18 :                 aCell.mpFormula->GetFormula(aString, pDocument->GetGrammar());
      82        1001 :             else if ( eCellType == CELLTYPE_EDIT )
      83           4 :                 bMultiLine = lcl_GetTextWithBreaks(*aCell.mpEditText, pDocument, aString);
      84             :             else
      85             :             {
      86         997 :                 aCol[nCol].GetInputString( nRow, aString );
      87             :             }
      88             :         }
      89        1019 :         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        1019 :     sal_Int32 nStart = 0;
     104        1019 :     sal_Int32 nEnd = aString.getLength();
     105        1019 :     ::com::sun::star::util::SearchResult aSearchResult;
     106        1019 :     if (pSearchText)
     107             :     {
     108        1019 :         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        1019 :             bFound = pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
     118             :             // change results to definition before 614:
     119        1019 :             --nEnd;
     120             :         }
     121             : 
     122        1019 :         if (bFound && rSearchItem.GetWordOnly())
     123         106 :             bFound = (nStart == 0 && nEnd == aString.getLength() - 1);
     124             :     }
     125             :     else
     126             :     {
     127             :         OSL_FAIL("pSearchText == NULL");
     128           0 :         return bFound;
     129             :     }
     130             : 
     131        1019 :     sal_uInt8 cMatrixFlag = MM_NONE;
     132        1599 :     if ( bFound &&
     133         580 :         ( (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE)
     134         580 :         ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) ) &&
     135             :             // Matrix nicht zerreissen, nur Matrixformel ersetzen
     136           3 :             !( (eCellType == CELLTYPE_FORMULA &&
     137           3 :             ((cMatrixFlag = aCell.mpFormula->GetMatrixFlag()) == MM_REFERENCE))
     138             :             // kein UndoDoc => Matrix nicht wiederherstellbar => nicht ersetzen
     139        1589 :             || (cMatrixFlag != MM_NONE && !pUndoDoc) ) &&
     140         285 :          IsBlockEditable(nCol, nRow, nCol, nRow)
     141             :         )
     142             :     {
     143         285 :         if ( cMatrixFlag == MM_NONE && rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE )
     144           0 :             rUndoStr = aString;
     145         285 :         else if (pUndoDoc)
     146             :         {
     147         285 :             ScAddress aAdr( nCol, nRow, nTab );
     148         285 :             aCell.commit(*pUndoDoc, aAdr);
     149             :         }
     150         285 :         bool bRepeat = !rSearchItem.GetWordOnly();
     151         285 :         do
     152             :         {
     153             :             //  wenn der gefundene Text leer ist, nicht weitersuchen,
     154             :             //  sonst wuerde man nie mehr aufhoeren (#35410#)
     155         285 :             if ( nEnd < nStart )
     156           0 :                 bRepeat = false;
     157             : 
     158         285 :             OUString sReplStr = rSearchItem.GetReplaceString();
     159         285 :             if (rSearchItem.GetRegExp())
     160             :             {
     161         269 :                 pSearchText->ReplaceBackReferences( sReplStr, aString, aSearchResult );
     162         269 :                 OUStringBuffer aStrBuffer(aString);
     163         269 :                 aStrBuffer.remove(nStart, nEnd-nStart+1);
     164         269 :                 aStrBuffer.insert(nStart, sReplStr);
     165         269 :                 aString = aStrBuffer.makeStringAndClear();
     166             :             }
     167             :             else
     168             :             {
     169          16 :                 OUStringBuffer aStrBuffer(aString);
     170          16 :                 aStrBuffer.remove(nStart, nEnd-nStart+1);
     171          16 :                 aStrBuffer.insert(nStart, rSearchItem.GetReplaceString());
     172          16 :                 aString = aStrBuffer.makeStringAndClear();
     173             :             }
     174             : 
     175             :                     //  Indizes anpassen
     176         285 :             if (bDoBack)
     177             :             {
     178           0 :                 nEnd = nStart;
     179           0 :                 nStart = 0;
     180             :             }
     181             :             else
     182             :             {
     183         285 :                 nStart = nStart + sReplStr.getLength();
     184         285 :                 nEnd = aString.getLength();
     185             :             }
     186             : 
     187             :                     //  weitersuchen ?
     188         285 :             if (bRepeat)
     189             :             {
     190         285 :                 if ( rSearchItem.GetCommand() != SVX_SEARCHCMD_REPLACE_ALL || nStart >= nEnd )
     191         281 :                     bRepeat = false;
     192           4 :                 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           4 :                     bRepeat = pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
     202             :                     // change results to definition before 614:
     203           4 :                     --nEnd;
     204             :                 }
     205         285 :             }
     206             :         }
     207             :         while (bRepeat);
     208             : 
     209         285 :         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         285 :         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         285 :             aCol[nCol].SetString(nRow, nTab, aString, pDocument->GetAddressConvention());
     235             :         // pCell is invalid now (deleted)
     236             :     }
     237        5613 :     return bFound;
     238             : }
     239             : 
     240        4594 : void ScTable::SkipFilteredRows(SCROW& rRow, SCROW& rLastNonFilteredRow, bool bForward)
     241             : {
     242        4594 :     if (bForward)
     243             :     {
     244             :         // forward search
     245             : 
     246        4594 :         if (rRow <= rLastNonFilteredRow)
     247        3436 :             return;
     248             : 
     249        1158 :         SCROW nLastRow = rRow;
     250        1158 :         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        1158 :             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         637 : bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
     277             :                      const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
     278             : {
     279         637 :     bool bFound = false;
     280         637 :     bool bAll =  (rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL)
     281         637 :                ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL);
     282         637 :     SCCOL nCol = rCol;
     283         637 :     SCROW nRow = rRow;
     284             :     SCCOL nLastCol;
     285             :     SCROW nLastRow;
     286         637 :     GetLastDataPos(nLastCol, nLastRow);
     287         637 :     bool bSkipFiltered = !rSearchItem.IsSearchFiltered();
     288         637 :     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         637 :         SCROW nLastNonFilteredRow = -1;
     364         637 :         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         637 :             nRow++;
     391        2441 :             while (!bFound && (nCol <= nLastCol))
     392             :             {
     393        6928 :                 while (!bFound && (nRow <= nLastRow))
     394             :                 {
     395        4594 :                     if (bSkipFiltered)
     396        4594 :                         SkipFilteredRows(nRow, nLastNonFilteredRow, true);
     397             : 
     398        4594 :                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     399        4594 :                     if (!bFound)
     400             :                     {
     401        4014 :                          if (!aCol[nCol].GetNextDataPos(nRow))
     402         578 :                             nRow = MAXROW + 1;
     403             :                     }
     404             :                 }
     405        1167 :                 if (!bFound)
     406             :                 {
     407             :                     // Not found in this column.  Move to the next column.
     408         587 :                     nRow = 0;
     409         587 :                     nLastNonFilteredRow = -1;
     410         587 :                     nCol++;
     411         587 :                     while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
     412             :                 }
     413             :             }
     414             :         }
     415             :     }
     416         637 :     if (bFound)
     417             :     {
     418         580 :         rCol = nCol;
     419         580 :         rRow = nRow;
     420             :     }
     421         637 :     return bFound;
     422             : }
     423             : 
     424          23 : bool ScTable::SearchAll(const SvxSearchItem& rSearchItem, const ScMarkData& rMark,
     425             :                         ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     426             : {
     427          23 :     bool bFound = true;
     428          23 :     SCCOL nCol = 0;
     429          23 :     SCROW nRow = -1;
     430          23 :     bool bEverFound = false;
     431             : 
     432         303 :     do
     433             :     {
     434         303 :         bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     435         303 :         if (bFound)
     436             :         {
     437         280 :             bEverFound = true;
     438         280 :             rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
     439             :         }
     440             :     }
     441             :     while (bFound);
     442             : 
     443          23 :     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 :     bool bFound = false;
     468           0 :     SCCOL nCol = rCol;
     469           0 :     SCROW nRow = rRow;
     470             : 
     471           0 :     UpdateSearchItemAddressForReplace( rSearchItem, nCol, nRow );
     472           0 :     bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     473           0 :     if (bFound)
     474             :     {
     475           0 :         rCol = nCol;
     476           0 :         rRow = nRow;
     477             :     }
     478           0 :     return bFound;
     479             : }
     480             : 
     481          26 : bool ScTable::ReplaceAll(
     482             :     const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges,
     483             :     OUString& rUndoStr, ScDocument* pUndoDoc)
     484             : {
     485          26 :     SCCOL nCol = 0;
     486          26 :     SCROW nRow = -1;
     487             : 
     488          26 :     bool bEverFound = false;
     489             :     while (true)
     490             :     {
     491         311 :         bool bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
     492             : 
     493         311 :         if (bFound)
     494             :         {
     495         285 :             bEverFound = true;
     496         285 :             rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
     497             :         }
     498             :         else
     499          26 :             break;
     500             :     }
     501         285 :     return bEverFound;
     502             : }
     503             : 
     504           0 : bool ScTable::SearchStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
     505             :                           const ScMarkData& rMark)
     506             : {
     507             :     const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
     508           0 :                                         pDocument->GetStyleSheetPool()->Find(
     509           0 :                                         rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
     510             : 
     511           0 :     SCsCOL nCol = rCol;
     512           0 :     SCsROW nRow = rRow;
     513           0 :     bool bFound = false;
     514             : 
     515           0 :     bool bSelect = rSearchItem.GetSelection();
     516           0 :     bool bRows = rSearchItem.GetRowDirection();
     517           0 :     bool bBack = rSearchItem.GetBackward();
     518           0 :     short nAdd = bBack ? -1 : 1;
     519             : 
     520           0 :     if (bRows)                                      // zeilenweise
     521             :     {
     522           0 :         nRow += nAdd;
     523           0 :         do
     524             :         {
     525           0 :             SCsROW nNextRow = aCol[nCol].SearchStyle( nRow, pSearchStyle, bBack, bSelect, rMark );
     526           0 :             if (!ValidRow(nNextRow))
     527             :             {
     528           0 :                 nRow = bBack ? MAXROW : 0;
     529           0 :                 nCol = sal::static_int_cast<SCsCOL>( nCol + nAdd );
     530             :             }
     531             :             else
     532             :             {
     533           0 :                 nRow = nNextRow;
     534           0 :                 bFound = true;
     535             :             }
     536             :         }
     537           0 :         while (!bFound && ValidCol(nCol));
     538             :     }
     539             :     else                                            // spaltenweise
     540             :     {
     541             :         SCsROW nNextRows[MAXCOLCOUNT];
     542             :         SCsCOL i;
     543           0 :         for (i=0; i<=MAXCOL; i++)
     544             :         {
     545           0 :             SCsROW nSRow = nRow;
     546           0 :             if (bBack)  { if (i>=nCol) --nSRow; }
     547           0 :             else        { if (i<=nCol) ++nSRow; }
     548           0 :             nNextRows[i] = aCol[i].SearchStyle( nSRow, pSearchStyle, bBack, bSelect, rMark );
     549             :         }
     550           0 :         if (bBack)                          // rueckwaerts
     551             :         {
     552           0 :             nRow = -1;
     553           0 :             for (i=MAXCOL; i>=0; i--)
     554           0 :                 if (nNextRows[i]>nRow)
     555             :                 {
     556           0 :                     nCol = i;
     557           0 :                     nRow = nNextRows[i];
     558           0 :                     bFound = true;
     559             :                 }
     560             :         }
     561             :         else                                // vorwaerts
     562             :         {
     563           0 :             nRow = MAXROW+1;
     564           0 :             for (i=0; i<=MAXCOL; i++)
     565           0 :                 if (nNextRows[i]<nRow)
     566             :                 {
     567           0 :                     nCol = i;
     568           0 :                     nRow = nNextRows[i];
     569           0 :                     bFound = true;
     570             :                 }
     571             :         }
     572             :     }
     573             : 
     574           0 :     if (bFound)
     575             :     {
     576           0 :         rCol = (SCCOL) nCol;
     577           0 :         rRow = (SCROW) nRow;
     578             :     }
     579           0 :     return bFound;
     580             : }
     581             : 
     582             : //!     einzelnes Pattern fuer Undo zurueckgeben
     583             : 
     584           0 : bool ScTable::ReplaceStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
     585             :                            const ScMarkData& rMark, bool bIsUndo)
     586             : {
     587             :     bool bRet;
     588           0 :     if (bIsUndo)
     589           0 :         bRet = true;
     590             :     else
     591           0 :         bRet = SearchStyle(rSearchItem, rCol, rRow, rMark);
     592           0 :     if (bRet)
     593             :     {
     594             :         const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
     595           0 :                                         pDocument->GetStyleSheetPool()->Find(
     596           0 :                                         rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
     597             : 
     598           0 :         if (pReplaceStyle)
     599           0 :             ApplyStyle( rCol, rRow, *pReplaceStyle );
     600             :         else
     601             :         {
     602             :             OSL_FAIL("pReplaceStyle==0");
     603             :         }
     604             :     }
     605             : 
     606           0 :     return bRet;
     607             : }
     608             : 
     609           0 : bool ScTable::SearchAllStyle(
     610             :     const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges)
     611             : {
     612             :     const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
     613           0 :                                         pDocument->GetStyleSheetPool()->Find(
     614           0 :                                         rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
     615           0 :     bool bSelect = rSearchItem.GetSelection();
     616           0 :     bool bBack = rSearchItem.GetBackward();
     617           0 :     bool bEverFound = false;
     618             : 
     619           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
     620             :     {
     621           0 :         bool bFound = true;
     622           0 :         SCsROW nRow = 0;
     623             :         SCsROW nEndRow;
     624           0 :         while (bFound && nRow <= MAXROW)
     625             :         {
     626           0 :             bFound = aCol[i].SearchStyleRange( nRow, nEndRow, pSearchStyle, bBack, bSelect, rMark );
     627           0 :             if (bFound)
     628             :             {
     629           0 :                 if (nEndRow<nRow)
     630             :                 {
     631           0 :                     SCsROW nTemp = nRow;
     632           0 :                     nRow = nEndRow;
     633           0 :                     nEndRow = nTemp;
     634             :                 }
     635           0 :                 rMatchedRanges.Join(ScRange(i, nRow, nTab, i, nEndRow, nTab));
     636           0 :                 nRow = nEndRow + 1;
     637           0 :                 bEverFound = true;
     638             :             }
     639             :         }
     640             :     }
     641             : 
     642           0 :     return bEverFound;
     643             : }
     644             : 
     645           0 : bool ScTable::ReplaceAllStyle(
     646             :     const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges,
     647             :     ScDocument* pUndoDoc)
     648             : {
     649           0 :     bool bRet = SearchAllStyle(rSearchItem, rMark, rMatchedRanges);
     650           0 :     if (bRet)
     651             :     {
     652             :         const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
     653           0 :                                         pDocument->GetStyleSheetPool()->Find(
     654           0 :                                         rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
     655             : 
     656           0 :         if (pReplaceStyle)
     657             :         {
     658           0 :             if (pUndoDoc)
     659             :                 pDocument->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab,
     660           0 :                                             IDF_ATTRIB, true, pUndoDoc, &rMark );
     661           0 :             ApplySelectionStyle( *pReplaceStyle, rMark );
     662             :         }
     663             :         else
     664             :         {
     665             :             OSL_FAIL("pReplaceStyle==0");
     666             :         }
     667             :     }
     668             : 
     669           0 :     return bRet;
     670             : }
     671             : 
     672          72 : bool ScTable::SearchAndReplace(
     673             :     const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark,
     674             :     ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     675             : {
     676          72 :     sal_uInt16 nCommand = rSearchItem.GetCommand();
     677          72 :     bool bFound = false;
     678         144 :     if ( ValidColRow(rCol, rRow) ||
     679          21 :          ((nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE) &&
     680          63 :            (((rCol == MAXCOLCOUNT || rCol == -1) && ValidRow(rRow)) ||
     681          42 :             ((rRow == MAXROWCOUNT || rRow == -1) && ValidCol(rCol))
     682             :            )
     683             :          )
     684             :        )
     685             :     {
     686          72 :         bool bStyles = rSearchItem.GetPattern();
     687          72 :         if (bStyles)
     688             :         {
     689           0 :             if (nCommand == SVX_SEARCHCMD_FIND)
     690           0 :                 bFound = SearchStyle(rSearchItem, rCol, rRow, rMark);
     691           0 :             else if (nCommand == SVX_SEARCHCMD_REPLACE)
     692           0 :                 bFound = ReplaceStyle(rSearchItem, rCol, rRow, rMark, false);
     693           0 :             else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
     694           0 :                 bFound = SearchAllStyle(rSearchItem, rMark, rMatchedRanges);
     695           0 :             else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
     696           0 :                 bFound = ReplaceAllStyle(rSearchItem, rMark, rMatchedRanges, pUndoDoc);
     697             :         }
     698             :         else
     699             :         {
     700             :             //  SearchParam no longer needed - SearchOptions contains all settings
     701          72 :             com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
     702          72 :             aSearchOptions.Locale = *ScGlobal::GetLocale();
     703             : 
     704          72 :             if (aSearchOptions.searchString.isEmpty())
     705             :             {
     706             :                 // Search for empty cells.
     707           0 :                 return SearchAndReplaceEmptyCells(rSearchItem, rCol, rRow, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
     708             :             }
     709             : 
     710             :             //  reflect UseAsianOptions flag in SearchOptions
     711             :             //  (use only ignore case and width if asian options are disabled).
     712             :             //  This is also done in SvxSearchDialog CommandHdl, but not in API object.
     713          72 :             if ( !rSearchItem.IsUseAsianOptions() )
     714             :                 aSearchOptions.transliterateFlags &=
     715             :                     ( com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
     716          72 :                       com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
     717             : 
     718          72 :             pSearchText = new utl::TextSearch( aSearchOptions );
     719             : 
     720          72 :             if (nCommand == SVX_SEARCHCMD_FIND)
     721          23 :                 bFound = Search(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
     722          49 :             else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
     723          23 :                 bFound = SearchAll(rSearchItem, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
     724          26 :             else if (nCommand == SVX_SEARCHCMD_REPLACE)
     725           0 :                 bFound = Replace(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
     726          26 :             else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
     727          26 :                 bFound = ReplaceAll(rSearchItem, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
     728             : 
     729          72 :             delete pSearchText;
     730          72 :             pSearchText = NULL;
     731             :         }
     732             :     }
     733          72 :     return bFound;
     734             : }
     735             : 
     736           0 : bool ScTable::SearchAndReplaceEmptyCells(
     737             :     const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark,
     738             :     ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     739             : {
     740             :     SCCOL nColStart, nColEnd;
     741             :     SCROW nRowStart, nRowEnd;
     742           0 :     GetFirstDataPos(nColStart, nRowStart);
     743           0 :     GetLastDataPos(nColEnd, nRowEnd);
     744             : 
     745           0 :     ScRangeList aRanges;
     746           0 :     aRanges.Append(ScRange(nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab));
     747             : 
     748           0 :     if (rSearchItem.GetSelection())
     749             :     {
     750             :         // current selection only.
     751           0 :         if (!rMark.IsMarked() && !rMark.IsMultiMarked())
     752             :             // There is no selection.  Bail out.
     753           0 :             return false;
     754             : 
     755           0 :         ScRangeList aMarkedRanges, aNewRanges;
     756           0 :         rMark.FillRangeListWithMarks(&aMarkedRanges, true);
     757           0 :         for ( size_t i = 0, n = aMarkedRanges.size(); i < n; ++i )
     758             :         {
     759           0 :             ScRange* p = aMarkedRanges[ i ];
     760           0 :             if (p->aStart.Col() > nColEnd || p->aStart.Row() > nRowEnd)
     761             :                 // This range is outside the data area.  Skip it.
     762           0 :                 continue;
     763             : 
     764             :             // Shrink the range into data area only.
     765           0 :             if (p->aStart.Col() < nColStart)
     766           0 :                 p->aStart.SetCol(rCol);
     767           0 :             if (p->aStart.Row() < nRowStart)
     768           0 :                 p->aStart.SetRow(rRow);
     769             : 
     770           0 :             if (p->aEnd.Col() > nColEnd)
     771           0 :                 p->aEnd.SetCol(nColEnd);
     772           0 :             if (p->aEnd.Row() > nRowEnd)
     773           0 :                 p->aEnd.SetRow(nRowEnd);
     774             : 
     775           0 :             aNewRanges.Append(*p);
     776             :         }
     777           0 :         aRanges = aNewRanges;
     778             :     }
     779             : 
     780           0 :     sal_uInt16 nCommand = rSearchItem.GetCommand();
     781           0 :     if (nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE)
     782             :     {
     783           0 :         if (rSearchItem.GetBackward())
     784             :         {
     785           0 :             for ( size_t i = aRanges.size(); i > 0; --i )
     786             :             {
     787           0 :                 ScRange* p = aRanges[ i - 1 ];
     788           0 :                 if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr))
     789           0 :                     return true;
     790             :             }
     791             :         }
     792             :         else
     793             :         {
     794           0 :             for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
     795             :             {
     796           0 :                 ScRange* p = aRanges[ i ];
     797           0 :                 if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr))
     798           0 :                     return true;
     799             :             }
     800           0 :         }
     801             :     }
     802           0 :     else if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
     803             :     {
     804           0 :         bool bFound = false;
     805           0 :         for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
     806             :         {
     807           0 :             ScRange* p = aRanges[ i ];
     808           0 :             bFound |= SearchRangeForAllEmptyCells(*p, rSearchItem, rMatchedRanges, rUndoStr, pUndoDoc);
     809             :         }
     810           0 :         return bFound;
     811             :     }
     812           0 :     return false;
     813             : }
     814             : 
     815             : namespace {
     816             : 
     817           0 : bool lcl_maybeReplaceCellString(
     818             :     ScColumn& rColObj, SCCOL& rCol, SCROW& rRow, OUString& rUndoStr, SCCOL nCol, SCROW nRow, const SvxSearchItem& rSearchItem)
     819             : {
     820           0 :     ScRefCellValue aCell = rColObj.GetCellValue(nRow);
     821           0 :     if (aCell.isEmpty())
     822             :     {
     823             :         // empty cell found.
     824           0 :         rCol = nCol;
     825           0 :         rRow = nRow;
     826           0 :         if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
     827           0 :             !rSearchItem.GetReplaceString().isEmpty())
     828             :         {
     829           0 :             rColObj.SetRawString(nRow, rSearchItem.GetReplaceString());
     830           0 :             rUndoStr = OUString();
     831             :         }
     832           0 :         return true;
     833             :     }
     834           0 :     return false;
     835             : }
     836             : 
     837             : }
     838             : 
     839           0 : bool ScTable::SearchRangeForEmptyCell(
     840             :     const ScRange& rRange, const SvxSearchItem& rSearchItem,
     841             :     SCCOL& rCol, SCROW& rRow, OUString& rUndoStr)
     842             : {
     843           0 :     sal_uInt16 nCmd = rSearchItem.GetCommand();
     844           0 :     bool bSkipFiltered = rSearchItem.IsSearchFiltered();
     845           0 :     if (rSearchItem.GetBackward())
     846             :     {
     847             :         // backward search
     848           0 :         if (rSearchItem.GetRowDirection())
     849             :         {
     850             :             // row direction.
     851           0 :             SCROW nLastNonFilteredRow = MAXROW + 1;
     852           0 :             SCROW nBeginRow = rRange.aEnd.Row() > rRow ? rRow : rRange.aEnd.Row();
     853           0 :             for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
     854             :             {
     855           0 :                 if (bSkipFiltered)
     856           0 :                     SkipFilteredRows(nRow, nLastNonFilteredRow, false);
     857           0 :                 if (nRow < rRange.aStart.Row())
     858           0 :                     break;
     859             : 
     860           0 :                 SCCOL nBeginCol = rRange.aEnd.Col();
     861           0 :                 if (nRow == rRow && nBeginCol >= rCol)
     862             :                     // always start from one cell before the cursor.
     863           0 :                     nBeginCol = rCol - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     864             : 
     865           0 :                 for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
     866             :                 {
     867           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     868           0 :                         return true;
     869             :                 }
     870             :             }
     871             :         }
     872             :         else
     873             :         {
     874             :             // column direction.
     875           0 :             SCCOL nBeginCol = rRange.aEnd.Col() > rCol ? rCol : rRange.aEnd.Col();
     876           0 :             for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
     877             :             {
     878           0 :                 SCROW nLastNonFilteredRow = MAXROW + 1;
     879           0 :                 SCROW nBeginRow = rRange.aEnd.Row();
     880           0 :                 if (nCol == rCol && nBeginRow >= rRow)
     881             :                     // always start from one cell before the cursor.
     882           0 :                     nBeginRow = rRow - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     883           0 :                 for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
     884             :                 {
     885           0 :                     if (bSkipFiltered)
     886           0 :                         SkipFilteredRows(nRow, nLastNonFilteredRow, false);
     887           0 :                     if (nRow < rRange.aStart.Row())
     888           0 :                         break;
     889             : 
     890           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     891           0 :                         return true;
     892             :                 }
     893             :             }
     894             :         }
     895             :     }
     896             :     else
     897             :     {
     898             :         // forward search
     899           0 :         if (rSearchItem.GetRowDirection())
     900             :         {
     901             :             // row direction.
     902           0 :             SCROW nLastNonFilteredRow = -1;
     903           0 :             SCROW nBeginRow = rRange.aStart.Row() < rRow ? rRow : rRange.aStart.Row();
     904           0 :             for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
     905             :             {
     906           0 :                 if (bSkipFiltered)
     907           0 :                     SkipFilteredRows(nRow, nLastNonFilteredRow, true);
     908           0 :                 if (nRow > rRange.aEnd.Row())
     909           0 :                     break;
     910             : 
     911           0 :                 SCCOL nBeginCol = rRange.aStart.Col();
     912           0 :                 if (nRow == rRow && nBeginCol <= rCol)
     913             :                     // always start from one cell past the cursor.
     914           0 :                     nBeginCol = rCol + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     915           0 :                 for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
     916             :                 {
     917           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     918           0 :                         return true;
     919             :                 }
     920             :             }
     921             :         }
     922             :         else
     923             :         {
     924             :             // column direction.
     925           0 :             SCCOL nBeginCol = rRange.aStart.Col() < rCol ? rCol : rRange.aStart.Col();
     926           0 :             for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
     927             :             {
     928           0 :                 SCROW nLastNonFilteredRow = -1;
     929           0 :                 SCROW nBeginRow = rRange.aStart.Row();
     930           0 :                 if (nCol == rCol && nBeginRow <= rRow)
     931             :                     // always start from one cell past the cursor.
     932           0 :                     nBeginRow = rRow + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
     933           0 :                 for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
     934             :                 {
     935           0 :                     if (bSkipFiltered)
     936           0 :                         SkipFilteredRows(nRow, nLastNonFilteredRow, true);
     937           0 :                     if (nRow > rRange.aEnd.Row())
     938           0 :                         break;
     939             : 
     940           0 :                     if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
     941           0 :                         return true;
     942             :                 }
     943             :             }
     944             :         }
     945             :     }
     946           0 :     return false;
     947             : }
     948             : 
     949           0 : bool ScTable::SearchRangeForAllEmptyCells(
     950             :     const ScRange& rRange, const SvxSearchItem& rSearchItem,
     951             :     ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
     952             : {
     953           0 :     bool bFound = false;
     954           0 :     bool bReplace = (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) &&
     955           0 :                     !rSearchItem.GetReplaceString().isEmpty();
     956           0 :     bool bSkipFiltered = rSearchItem.IsSearchFiltered();
     957             : 
     958           0 :     for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
     959             :     {
     960           0 :         SCROW nLastNonFilteredRow = -1;
     961           0 :         if (aCol[nCol].IsEmptyData())
     962             :         {
     963             :             // The entire column is empty.
     964           0 :             for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
     965             :             {
     966             :                 SCROW nLastRow;
     967           0 :                 if (!RowFiltered(nRow, NULL, &nLastRow))
     968             :                 {
     969           0 :                     rMatchedRanges.Join(ScRange(nCol, nRow, nTab, nCol, nLastRow, nTab));
     970           0 :                     if (bReplace)
     971             :                     {
     972           0 :                         const String& rNewStr = rSearchItem.GetReplaceString();
     973           0 :                         for (SCROW i = nRow; i <= nLastRow; ++i)
     974             :                         {
     975           0 :                             aCol[nCol].SetRawString(i, rNewStr);
     976           0 :                             if (pUndoDoc)
     977             :                             {
     978             :                                 // TODO: I'm using a string cell with empty content to
     979             :                                 // trigger deletion of cell instance on undo.  Maybe I
     980             :                                 // should create a new cell type for this?
     981           0 :                                 ScSetStringParam aParam;
     982           0 :                                 aParam.setTextInput();
     983           0 :                                 pUndoDoc->SetString(ScAddress(nCol, i, nTab), EMPTY_OUSTRING);
     984             :                             }
     985             :                         }
     986           0 :                         rUndoStr = String();
     987             :                     }
     988             :                 }
     989             : 
     990           0 :                 nRow = nLastRow; // move to the last filtered row.
     991             :             }
     992           0 :             bFound = true;
     993           0 :             continue;
     994             :         }
     995             : 
     996           0 :         for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
     997             :         {
     998           0 :             if (bSkipFiltered)
     999           0 :                 SkipFilteredRows(nRow, nLastNonFilteredRow, true);
    1000           0 :             if (nRow > rRange.aEnd.Row())
    1001           0 :                 break;
    1002             : 
    1003           0 :             ScRefCellValue aCell = aCol[nCol].GetCellValue(nRow);
    1004           0 :             if (aCell.isEmpty())
    1005             :             {
    1006             :                 // empty cell found
    1007           0 :                 rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
    1008           0 :                 bFound = true;
    1009             : 
    1010           0 :                 if (bReplace)
    1011             :                 {
    1012           0 :                     aCol[nCol].SetRawString(nRow, rSearchItem.GetReplaceString());
    1013           0 :                     if (pUndoDoc)
    1014             :                     {
    1015             :                         // TODO: I'm using a string cell with empty content to
    1016             :                         // trigger deletion of cell instance on undo.  Maybe I
    1017             :                         // should create a new cell type for this?
    1018           0 :                         ScSetStringParam aParam;
    1019           0 :                         aParam.setTextInput();
    1020           0 :                         pUndoDoc->SetString(ScAddress(nCol, nRow, nTab), EMPTY_OUSTRING);
    1021             :                     }
    1022             :                 }
    1023             :             }
    1024           0 :         }
    1025             :     }
    1026           0 :     return bFound;
    1027             : }
    1028             : 
    1029           0 : void ScTable::RebuildFormulaGroups()
    1030             : {
    1031           0 :     for (SCCOL i=0; i<=MAXCOL; i++)
    1032           0 :         aCol[i].RebuildFormulaGroups();
    1033          93 : }
    1034             : 
    1035             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10