xref: /trunk/main/sc/source/core/data/table6.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <com/sun/star/i18n/TransliterationModules.hpp>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <unotools/textsearch.hxx>
32cdf0e10cSrcweir #include <svl/srchitem.hxx>
33cdf0e10cSrcweir #include <editeng/editobj.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include "table.hxx"
36cdf0e10cSrcweir #include "collect.hxx"
37cdf0e10cSrcweir #include "cell.hxx"
38cdf0e10cSrcweir #include "document.hxx"
39cdf0e10cSrcweir #include "stlpool.hxx"
40cdf0e10cSrcweir #include "markdata.hxx"
41cdf0e10cSrcweir #include "editutil.hxx"
42cdf0e10cSrcweir #include "detfunc.hxx"
43cdf0e10cSrcweir #include "postit.hxx"
44cdf0e10cSrcweir 
45cdf0e10cSrcweir //--------------------------------------------------------------------------
46cdf0e10cSrcweir 
47cdf0e10cSrcweir 
lcl_GetTextWithBreaks(const ScEditCell & rCell,ScDocument * pDoc,String & rVal)48cdf0e10cSrcweir sal_Bool lcl_GetTextWithBreaks( const ScEditCell& rCell, ScDocument* pDoc, String& rVal )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir     //  sal_True = more than 1 paragraph
51cdf0e10cSrcweir 
52cdf0e10cSrcweir     const EditTextObject* pData = NULL;
53cdf0e10cSrcweir     rCell.GetData( pData );
54cdf0e10cSrcweir     EditEngine& rEngine = pDoc->GetEditEngine();
55cdf0e10cSrcweir     rEngine.SetText( *pData );
56cdf0e10cSrcweir     rVal = rEngine.GetText( LINEEND_LF );
57cdf0e10cSrcweir     return ( rEngine.GetParagraphCount() > 1 );
58cdf0e10cSrcweir }
59cdf0e10cSrcweir 
SearchCell(const SvxSearchItem & rSearchItem,SCCOL nCol,SCROW nRow,const ScMarkData & rMark,String & rUndoStr,ScDocument * pUndoDoc)60cdf0e10cSrcweir sal_Bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRow,
61cdf0e10cSrcweir                             const ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc)
62cdf0e10cSrcweir {
63cdf0e10cSrcweir     sal_Bool    bFound = sal_False;
64cdf0e10cSrcweir     sal_Bool    bDoSearch = sal_True;
65cdf0e10cSrcweir     sal_Bool    bDoBack = rSearchItem.GetBackward();
66cdf0e10cSrcweir 
67cdf0e10cSrcweir     String  aString;
68cdf0e10cSrcweir     ScBaseCell* pCell;
69cdf0e10cSrcweir     if (rSearchItem.GetSelection())
70cdf0e10cSrcweir         bDoSearch = rMark.IsCellMarked(nCol, nRow);
71cdf0e10cSrcweir     if ( bDoSearch && ((pCell = aCol[nCol].GetCell( nRow )) != NULL) )
72cdf0e10cSrcweir     {
73cdf0e10cSrcweir         sal_Bool bMultiLine = sal_False;
74cdf0e10cSrcweir         CellType eCellType = pCell->GetCellType();
75cdf0e10cSrcweir         switch (rSearchItem.GetCellType())
76cdf0e10cSrcweir         {
77cdf0e10cSrcweir             case SVX_SEARCHIN_FORMULA:
78cdf0e10cSrcweir             {
79cdf0e10cSrcweir                 if ( eCellType == CELLTYPE_FORMULA )
80cdf0e10cSrcweir                     ((ScFormulaCell*)pCell)->GetFormula( aString,
81cdf0e10cSrcweir                        formula::FormulaGrammar::GRAM_NATIVE_UI);
82cdf0e10cSrcweir                 else if ( eCellType == CELLTYPE_EDIT )
83cdf0e10cSrcweir                     bMultiLine = lcl_GetTextWithBreaks(
84cdf0e10cSrcweir                         *(const ScEditCell*)pCell, pDocument, aString );
85cdf0e10cSrcweir                 else
86cdf0e10cSrcweir                     aCol[nCol].GetInputString( nRow, aString );
87cdf0e10cSrcweir             }
88cdf0e10cSrcweir             break;
89cdf0e10cSrcweir             case SVX_SEARCHIN_VALUE:
90cdf0e10cSrcweir                 if ( eCellType == CELLTYPE_EDIT )
91cdf0e10cSrcweir                     bMultiLine = lcl_GetTextWithBreaks(
92cdf0e10cSrcweir                         *(const ScEditCell*)pCell, pDocument, aString );
93cdf0e10cSrcweir                 else
94*2e4d2335SDamjan Jovanovic                     aCol[nCol].GetString( nRow, aString );
95cdf0e10cSrcweir                 break;
96cdf0e10cSrcweir             case SVX_SEARCHIN_NOTE:
97cdf0e10cSrcweir                 {
98cdf0e10cSrcweir                     if(const ScPostIt* pNote = pCell->GetNote())
99cdf0e10cSrcweir                     {
100cdf0e10cSrcweir                         aString = pNote->GetText();
101cdf0e10cSrcweir                         bMultiLine = pNote->HasMultiLineText();
102cdf0e10cSrcweir                     }
103cdf0e10cSrcweir                 }
104cdf0e10cSrcweir                 break;
105cdf0e10cSrcweir             default:
106cdf0e10cSrcweir                 break;
107cdf0e10cSrcweir         }
108cdf0e10cSrcweir         xub_StrLen nStart = 0;
109cdf0e10cSrcweir         xub_StrLen nEnd = aString.Len();
110cdf0e10cSrcweir         ::com::sun::star::util::SearchResult aSearchResult;
111cdf0e10cSrcweir         if (pSearchText)
112cdf0e10cSrcweir         {
113cdf0e10cSrcweir             if ( bDoBack )
114cdf0e10cSrcweir             {
115cdf0e10cSrcweir                 xub_StrLen nTemp=nStart; nStart=nEnd; nEnd=nTemp;
116cdf0e10cSrcweir                 bFound = (sal_Bool)(pSearchText->SearchBkwrd(aString, &nStart, &nEnd, &aSearchResult));
117cdf0e10cSrcweir                 // change results to definition before 614:
118cdf0e10cSrcweir                 --nEnd;
119cdf0e10cSrcweir             }
120cdf0e10cSrcweir             else
121cdf0e10cSrcweir             {
122cdf0e10cSrcweir                 bFound = (sal_Bool)(pSearchText->SearchFrwrd(aString, &nStart, &nEnd, &aSearchResult));
123cdf0e10cSrcweir                 // change results to definition before 614:
124cdf0e10cSrcweir                 --nEnd;
125cdf0e10cSrcweir             }
126cdf0e10cSrcweir 
127cdf0e10cSrcweir             if (bFound && rSearchItem.GetWordOnly())
128cdf0e10cSrcweir                 bFound = (nStart == 0 && nEnd == aString.Len() - 1);
129cdf0e10cSrcweir         }
130cdf0e10cSrcweir         else
131cdf0e10cSrcweir         {
132cdf0e10cSrcweir             DBG_ERROR("pSearchText == NULL");
133cdf0e10cSrcweir             return bFound;
134cdf0e10cSrcweir         }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir         sal_uInt8 cMatrixFlag = MM_NONE;
137cdf0e10cSrcweir         if ( bFound &&
138cdf0e10cSrcweir             ( (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE)
139cdf0e10cSrcweir             ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) ) &&
140cdf0e10cSrcweir                 // #60558# Matrix nicht zerreissen, nur Matrixformel ersetzen
141cdf0e10cSrcweir                 !( (eCellType == CELLTYPE_FORMULA &&
142cdf0e10cSrcweir                 ((cMatrixFlag = ((ScFormulaCell*)pCell)->GetMatrixFlag()) == MM_REFERENCE))
143cdf0e10cSrcweir                 // kein UndoDoc => Matrix nicht wiederherstellbar => nicht ersetzen
144cdf0e10cSrcweir                 || (cMatrixFlag != MM_NONE && !pUndoDoc) )
145cdf0e10cSrcweir             )
146cdf0e10cSrcweir         {
147cdf0e10cSrcweir             if ( cMatrixFlag == MM_NONE && rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE )
148cdf0e10cSrcweir                 rUndoStr = aString;
149cdf0e10cSrcweir             else if (pUndoDoc)
150cdf0e10cSrcweir             {
151cdf0e10cSrcweir                 ScAddress aAdr( nCol, nRow, nTab );
152cdf0e10cSrcweir                 ScBaseCell* pUndoCell = pCell->CloneWithoutNote( *pUndoDoc );
153cdf0e10cSrcweir                 pUndoDoc->PutCell( aAdr, pUndoCell);
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir             sal_Bool bRepeat = !rSearchItem.GetWordOnly();
156cdf0e10cSrcweir             do
157cdf0e10cSrcweir             {
158cdf0e10cSrcweir                 //  wenn der gefundene Text leer ist, nicht weitersuchen,
159cdf0e10cSrcweir                 //  sonst wuerde man nie mehr aufhoeren (#35410#)
160cdf0e10cSrcweir                 if ( nEnd < nStart || nEnd == STRING_MAXLEN )
161cdf0e10cSrcweir                     bRepeat = sal_False;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir                 String sReplStr = rSearchItem.GetReplaceString();
164cdf0e10cSrcweir                 if (rSearchItem.GetRegExp())
165cdf0e10cSrcweir                 {
166cdf0e10cSrcweir                     String sFndStr = aString.Copy(nStart, nEnd-nStart+1);
167cdf0e10cSrcweir                     pSearchText->ReplaceBackReferences( sReplStr, aString, aSearchResult );
168cdf0e10cSrcweir                     aString.Erase(nStart, nEnd-nStart+1);
169cdf0e10cSrcweir                     aString.Insert(sReplStr, nStart);
170cdf0e10cSrcweir                 }
171cdf0e10cSrcweir                 else
172cdf0e10cSrcweir                 {
173cdf0e10cSrcweir                     aString.Erase(nStart, nEnd - nStart + 1);
174cdf0e10cSrcweir                     aString.Insert(rSearchItem.GetReplaceString(), nStart);
175cdf0e10cSrcweir                 }
176cdf0e10cSrcweir 
177cdf0e10cSrcweir                         //  Indizes anpassen
178cdf0e10cSrcweir                 if (bDoBack)
179cdf0e10cSrcweir                 {
180cdf0e10cSrcweir                     nEnd = nStart;
181cdf0e10cSrcweir                     nStart = 0;
182cdf0e10cSrcweir                 }
183cdf0e10cSrcweir                 else
184cdf0e10cSrcweir                 {
185cdf0e10cSrcweir                     nStart = sal::static_int_cast<xub_StrLen>( nStart + sReplStr.Len() );
186cdf0e10cSrcweir                     nEnd = aString.Len();
187cdf0e10cSrcweir                 }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir                         //  weitersuchen ?
190cdf0e10cSrcweir                 if (bRepeat)
191cdf0e10cSrcweir                 {
192cdf0e10cSrcweir                     if ( rSearchItem.GetCommand() != SVX_SEARCHCMD_REPLACE_ALL || nStart >= nEnd )
193cdf0e10cSrcweir                         bRepeat = sal_False;
194cdf0e10cSrcweir                     else if (bDoBack)
195cdf0e10cSrcweir                     {
196cdf0e10cSrcweir                         xub_StrLen nTemp=nStart; nStart=nEnd; nEnd=nTemp;
197641e855fSTsutomu Uchino                         bRepeat = ((sal_Bool)(pSearchText->SearchBkwrd(aString, &nStart, &nEnd, &aSearchResult)));
198cdf0e10cSrcweir                         // change results to definition before 614:
199cdf0e10cSrcweir                         --nEnd;
200cdf0e10cSrcweir                     }
201cdf0e10cSrcweir                     else
202cdf0e10cSrcweir                     {
203641e855fSTsutomu Uchino                         bRepeat = ((sal_Bool)(pSearchText->SearchFrwrd(aString, &nStart, &nEnd, &aSearchResult)));
204cdf0e10cSrcweir                         // change results to definition before 614:
205cdf0e10cSrcweir                         --nEnd;
206cdf0e10cSrcweir                     }
207cdf0e10cSrcweir                 }
208cdf0e10cSrcweir             }
209cdf0e10cSrcweir             while (bRepeat);
210cdf0e10cSrcweir             if (rSearchItem.GetCellType() == SVX_SEARCHIN_NOTE)
211cdf0e10cSrcweir             {
212cdf0e10cSrcweir                 // NB: rich text format is lost.
213cdf0e10cSrcweir                 // This is also true of Cells.
214cdf0e10cSrcweir                 if( ScPostIt* pNote = pCell->GetNote() )
215cdf0e10cSrcweir                     pNote->SetText( ScAddress( nCol, nRow, nTab ), aString );
216cdf0e10cSrcweir             }
217cdf0e10cSrcweir             else if ( cMatrixFlag != MM_NONE )
218cdf0e10cSrcweir             {   // #60558# Matrix nicht zerreissen
219cdf0e10cSrcweir                 if ( aString.Len() > 2 )
220cdf0e10cSrcweir                 {   // {} raus, erst hier damit auch "{=" durch "{=..." ersetzt werden kann
221cdf0e10cSrcweir                     if ( aString.GetChar( aString.Len()-1 ) == '}' )
222cdf0e10cSrcweir                         aString.Erase( aString.Len()-1, 1 );
223cdf0e10cSrcweir                     if ( aString.GetChar(0) == '{' )
224cdf0e10cSrcweir                         aString.Erase( 0, 1 );
225cdf0e10cSrcweir                 }
226cdf0e10cSrcweir                 ScAddress aAdr( nCol, nRow, nTab );
227cdf0e10cSrcweir                 ScFormulaCell* pFCell = new ScFormulaCell( pDocument, aAdr,
228cdf0e10cSrcweir                     aString,formula::FormulaGrammar::GRAM_NATIVE_UI, cMatrixFlag );
229cdf0e10cSrcweir                 SCCOL nMatCols;
230cdf0e10cSrcweir                 SCROW nMatRows;
231cdf0e10cSrcweir                 ((ScFormulaCell*)pCell)->GetMatColsRows( nMatCols, nMatRows );
232cdf0e10cSrcweir                 pFCell->SetMatColsRows( nMatCols, nMatRows );
233cdf0e10cSrcweir                 aCol[nCol].Insert( nRow, pFCell );
234cdf0e10cSrcweir             }
235cdf0e10cSrcweir             else if ( bMultiLine && aString.Search('\n') != STRING_NOTFOUND )
236cdf0e10cSrcweir                 PutCell( nCol, nRow, new ScEditCell( aString, pDocument ) );
237cdf0e10cSrcweir             else
238cdf0e10cSrcweir                 aCol[nCol].SetString(nRow, nTab, aString);
239cdf0e10cSrcweir             // pCell is invalid now (deleted)
240cdf0e10cSrcweir         }
241cdf0e10cSrcweir     }
242cdf0e10cSrcweir     return bFound;
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
Search(const SvxSearchItem & rSearchItem,SCCOL & rCol,SCROW & rRow,const ScMarkData & rMark,String & rUndoStr,ScDocument * pUndoDoc)245cdf0e10cSrcweir sal_Bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
246cdf0e10cSrcweir                         const ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc)
247cdf0e10cSrcweir {
248cdf0e10cSrcweir     sal_Bool bFound = sal_False;
249cdf0e10cSrcweir     sal_Bool bAll =  (rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL)
250cdf0e10cSrcweir                ||(rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL);
251cdf0e10cSrcweir     SCCOL nCol = rCol;
252cdf0e10cSrcweir     SCROW nRow = rRow;
253cdf0e10cSrcweir     SCCOL nLastCol;
254cdf0e10cSrcweir     SCROW nLastRow;
255cdf0e10cSrcweir     GetLastDataPos(nLastCol, nLastRow);
256cdf0e10cSrcweir     if (!bAll && rSearchItem.GetBackward())
257cdf0e10cSrcweir     {
258cdf0e10cSrcweir         nCol = Min(nCol, (SCCOL)(nLastCol + 1));
259cdf0e10cSrcweir         nRow = Min(nRow, (SCROW)(nLastRow + 1));
260cdf0e10cSrcweir         if (rSearchItem.GetRowDirection())
261cdf0e10cSrcweir         {
262cdf0e10cSrcweir             nCol--;
263cdf0e10cSrcweir             while (!bFound && ((SCsROW)nRow >= 0))
264cdf0e10cSrcweir             {
265cdf0e10cSrcweir                 while (!bFound && ((SCsCOL)nCol >= 0))
266cdf0e10cSrcweir                 {
267cdf0e10cSrcweir                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
268cdf0e10cSrcweir                     if (!bFound)
269cdf0e10cSrcweir                     {
270cdf0e10cSrcweir                         sal_Bool bIsEmpty;
271cdf0e10cSrcweir                         do
272cdf0e10cSrcweir                         {
273cdf0e10cSrcweir                             nCol--;
274cdf0e10cSrcweir                             if ((SCsCOL)nCol >= 0)
275cdf0e10cSrcweir                                 bIsEmpty = aCol[nCol].IsEmptyData();
276cdf0e10cSrcweir                             else
277cdf0e10cSrcweir                                 bIsEmpty = sal_True;
278cdf0e10cSrcweir                         }
279cdf0e10cSrcweir                         while (((SCsCOL)nCol >= 0) && bIsEmpty);
280cdf0e10cSrcweir                     }
281cdf0e10cSrcweir                 }
282cdf0e10cSrcweir                 if (!bFound)
283cdf0e10cSrcweir                 {
284cdf0e10cSrcweir                     nCol = nLastCol;
285cdf0e10cSrcweir                     nRow--;
286cdf0e10cSrcweir                 }
287cdf0e10cSrcweir             }
288cdf0e10cSrcweir         }
289cdf0e10cSrcweir         else
290cdf0e10cSrcweir         {
291cdf0e10cSrcweir             nRow--;
292cdf0e10cSrcweir             while (!bFound && ((SCsCOL)nCol >= 0))
293cdf0e10cSrcweir             {
294cdf0e10cSrcweir                 while (!bFound && ((SCsROW)nRow >= 0))
295cdf0e10cSrcweir                 {
296cdf0e10cSrcweir                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
297cdf0e10cSrcweir                     if (!bFound)
298cdf0e10cSrcweir                     {
299cdf0e10cSrcweir                          if (!aCol[nCol].GetPrevDataPos(nRow))
300cdf0e10cSrcweir                             nRow = -1;
301cdf0e10cSrcweir                     }
302cdf0e10cSrcweir                 }
303cdf0e10cSrcweir                 if (!bFound)
304cdf0e10cSrcweir                 {
305cdf0e10cSrcweir                     sal_Bool bIsEmpty;
306cdf0e10cSrcweir                     nRow = nLastRow;
307cdf0e10cSrcweir                     do
308cdf0e10cSrcweir                     {
309cdf0e10cSrcweir                         nCol--;
310cdf0e10cSrcweir                         if ((SCsCOL)nCol >= 0)
311cdf0e10cSrcweir                             bIsEmpty = aCol[nCol].IsEmptyData();
312cdf0e10cSrcweir                         else
313cdf0e10cSrcweir                             bIsEmpty = sal_True;
314cdf0e10cSrcweir                     }
315cdf0e10cSrcweir                     while (((SCsCOL)nCol >= 0) && bIsEmpty);
316cdf0e10cSrcweir                 }
317cdf0e10cSrcweir             }
318cdf0e10cSrcweir         }
319cdf0e10cSrcweir     }
320cdf0e10cSrcweir     else
321cdf0e10cSrcweir     {
322cdf0e10cSrcweir         if (!bAll && rSearchItem.GetRowDirection())
323cdf0e10cSrcweir         {
324cdf0e10cSrcweir             nCol++;
325cdf0e10cSrcweir             while (!bFound && (nRow <= nLastRow))
326cdf0e10cSrcweir             {
327cdf0e10cSrcweir                 while (!bFound && (nCol <= nLastCol))
328cdf0e10cSrcweir                 {
329cdf0e10cSrcweir                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
330cdf0e10cSrcweir                     if (!bFound)
331cdf0e10cSrcweir                     {
332cdf0e10cSrcweir                         nCol++;
333cdf0e10cSrcweir                         while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
334cdf0e10cSrcweir                     }
335cdf0e10cSrcweir                 }
336cdf0e10cSrcweir                 if (!bFound)
337cdf0e10cSrcweir                 {
338cdf0e10cSrcweir                     nCol = 0;
339cdf0e10cSrcweir                     nRow++;
340cdf0e10cSrcweir                 }
341cdf0e10cSrcweir             }
342cdf0e10cSrcweir         }
343cdf0e10cSrcweir         else
344cdf0e10cSrcweir         {
345cdf0e10cSrcweir             nRow++;
346cdf0e10cSrcweir             while (!bFound && (nCol <= nLastCol))
347cdf0e10cSrcweir             {
348cdf0e10cSrcweir                 while (!bFound && (nRow <= nLastRow))
349cdf0e10cSrcweir                 {
350cdf0e10cSrcweir                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
351cdf0e10cSrcweir                     if (!bFound)
352cdf0e10cSrcweir                     {
353cdf0e10cSrcweir                          if (!aCol[nCol].GetNextDataPos(nRow))
354cdf0e10cSrcweir                             nRow = MAXROW + 1;
355cdf0e10cSrcweir                     }
356cdf0e10cSrcweir                 }
357cdf0e10cSrcweir                 if (!bFound)
358cdf0e10cSrcweir                 {
359cdf0e10cSrcweir                     nRow = 0;
360cdf0e10cSrcweir                     nCol++;
361cdf0e10cSrcweir                     while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
362cdf0e10cSrcweir                 }
363cdf0e10cSrcweir             }
364cdf0e10cSrcweir         }
365cdf0e10cSrcweir     }
366cdf0e10cSrcweir     if (bFound)
367cdf0e10cSrcweir     {
368cdf0e10cSrcweir         rCol = nCol;
369cdf0e10cSrcweir         rRow = nRow;
370cdf0e10cSrcweir     }
371cdf0e10cSrcweir     return bFound;
372cdf0e10cSrcweir }
373cdf0e10cSrcweir 
SearchAll(const SvxSearchItem & rSearchItem,ScMarkData & rMark,String & rUndoStr,ScDocument * pUndoDoc)374cdf0e10cSrcweir sal_Bool ScTable::SearchAll(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
375cdf0e10cSrcweir                         String& rUndoStr, ScDocument* pUndoDoc)
376cdf0e10cSrcweir {
377cdf0e10cSrcweir     sal_Bool bFound = sal_True;
378cdf0e10cSrcweir     SCCOL nCol = 0;
379cdf0e10cSrcweir     SCROW nRow = -1;
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     ScMarkData aNewMark( rMark );   // Tabellen-Markierungen kopieren
382cdf0e10cSrcweir     aNewMark.ResetMark();
383cdf0e10cSrcweir     do
384cdf0e10cSrcweir     {
385cdf0e10cSrcweir         bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
386cdf0e10cSrcweir         if (bFound)
387cdf0e10cSrcweir             aNewMark.SetMultiMarkArea( ScRange( nCol, nRow, nTab ) );
388cdf0e10cSrcweir     }
389cdf0e10cSrcweir     while (bFound);
390cdf0e10cSrcweir 
391cdf0e10cSrcweir     rMark = aNewMark;       //  Markierung kopieren
392cdf0e10cSrcweir                             //! pro Tabelle
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     return (aNewMark.IsMultiMarked());
395cdf0e10cSrcweir }
396cdf0e10cSrcweir 
Replace(const SvxSearchItem & rSearchItem,SCCOL & rCol,SCROW & rRow,const ScMarkData & rMark,String & rUndoStr,ScDocument * pUndoDoc)397cdf0e10cSrcweir sal_Bool ScTable::Replace(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
398cdf0e10cSrcweir                         const ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc)
399cdf0e10cSrcweir {
400cdf0e10cSrcweir     sal_Bool bFound = sal_False;
401cdf0e10cSrcweir     SCCOL nCol = rCol;
402cdf0e10cSrcweir     SCROW nRow = rRow;
403cdf0e10cSrcweir     if (rSearchItem.GetBackward())
404cdf0e10cSrcweir     {
405cdf0e10cSrcweir         if (rSearchItem.GetRowDirection())
406cdf0e10cSrcweir             nCol += 1;
407cdf0e10cSrcweir         else
408cdf0e10cSrcweir             nRow += 1;
409cdf0e10cSrcweir     }
410cdf0e10cSrcweir     else
411cdf0e10cSrcweir     {
412cdf0e10cSrcweir         if (rSearchItem.GetRowDirection())
413cdf0e10cSrcweir             nCol -= 1;
414cdf0e10cSrcweir         else
415cdf0e10cSrcweir             nRow -= 1;
416cdf0e10cSrcweir     }
417cdf0e10cSrcweir     bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
418cdf0e10cSrcweir     if (bFound)
419cdf0e10cSrcweir     {
420cdf0e10cSrcweir         rCol = nCol;
421cdf0e10cSrcweir         rRow = nRow;
422cdf0e10cSrcweir     }
423cdf0e10cSrcweir     return bFound;
424cdf0e10cSrcweir }
425cdf0e10cSrcweir 
ReplaceAll(const SvxSearchItem & rSearchItem,ScMarkData & rMark,String & rUndoStr,ScDocument * pUndoDoc)426cdf0e10cSrcweir sal_Bool ScTable::ReplaceAll(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
427cdf0e10cSrcweir                             String& rUndoStr, ScDocument* pUndoDoc)
428cdf0e10cSrcweir {
429cdf0e10cSrcweir     sal_Bool bOldDouble = ScColumn::bDoubleAlloc;       // sollte immer sal_False sein?
430cdf0e10cSrcweir     DBG_ASSERT(!bOldDouble,"bDoubleAlloc ???");
431cdf0e10cSrcweir     ScColumn::bDoubleAlloc = sal_True;                  // fuer Undo-Doc
432cdf0e10cSrcweir 
433cdf0e10cSrcweir     sal_Bool bFound = sal_True;
434cdf0e10cSrcweir     SCCOL nCol = 0;
435cdf0e10cSrcweir     SCROW nRow = -1;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir     ScMarkData aNewMark( rMark );   // Tabellen-Markierungen kopieren
438cdf0e10cSrcweir     aNewMark.ResetMark();
439cdf0e10cSrcweir     do
440cdf0e10cSrcweir     {
441cdf0e10cSrcweir         bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
442cdf0e10cSrcweir         if (bFound)
443cdf0e10cSrcweir             aNewMark.SetMultiMarkArea( ScRange( nCol, nRow, nTab ) );
444cdf0e10cSrcweir     }
445cdf0e10cSrcweir     while (bFound);
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     ScColumn::bDoubleAlloc = bOldDouble;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     rMark = aNewMark;       //  Markierung kopieren
450cdf0e10cSrcweir                             //! pro Tabelle
451cdf0e10cSrcweir 
452cdf0e10cSrcweir     return (aNewMark.IsMultiMarked());
453cdf0e10cSrcweir }
454cdf0e10cSrcweir 
SearchStyle(const SvxSearchItem & rSearchItem,SCCOL & rCol,SCROW & rRow,ScMarkData & rMark)455cdf0e10cSrcweir sal_Bool ScTable::SearchStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
456cdf0e10cSrcweir                             ScMarkData& rMark)
457cdf0e10cSrcweir {
458cdf0e10cSrcweir     const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
459cdf0e10cSrcweir                                         pDocument->GetStyleSheetPool()->Find(
460cdf0e10cSrcweir                                         rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
461cdf0e10cSrcweir 
462cdf0e10cSrcweir     SCsCOL nCol = rCol;
463cdf0e10cSrcweir     SCsROW nRow = rRow;
464cdf0e10cSrcweir     sal_Bool bFound = sal_False;
465cdf0e10cSrcweir 
466cdf0e10cSrcweir     sal_Bool bSelect = rSearchItem.GetSelection();
467cdf0e10cSrcweir     sal_Bool bRows = rSearchItem.GetRowDirection();
468cdf0e10cSrcweir     sal_Bool bBack = rSearchItem.GetBackward();
469cdf0e10cSrcweir     short nAdd = bBack ? -1 : 1;
470cdf0e10cSrcweir 
471cdf0e10cSrcweir     if (bRows)                                      // zeilenweise
472cdf0e10cSrcweir     {
473cdf0e10cSrcweir         nRow += nAdd;
474cdf0e10cSrcweir         do
475cdf0e10cSrcweir         {
476cdf0e10cSrcweir             SCsROW nNextRow = aCol[nCol].SearchStyle( nRow, pSearchStyle, bBack, bSelect, rMark );
477cdf0e10cSrcweir             if (!ValidRow(nNextRow))
478cdf0e10cSrcweir             {
479cdf0e10cSrcweir                 nRow = bBack ? MAXROW : 0;
480cdf0e10cSrcweir                 nCol = sal::static_int_cast<SCsCOL>( nCol + nAdd );
481cdf0e10cSrcweir             }
482cdf0e10cSrcweir             else
483cdf0e10cSrcweir             {
484cdf0e10cSrcweir                 nRow = nNextRow;
485cdf0e10cSrcweir                 bFound = sal_True;
486cdf0e10cSrcweir             }
487cdf0e10cSrcweir         }
488cdf0e10cSrcweir         while (!bFound && ValidCol(nCol));
489cdf0e10cSrcweir     }
490cdf0e10cSrcweir     else                                            // spaltenweise
491cdf0e10cSrcweir     {
492cdf0e10cSrcweir         SCsROW nNextRows[MAXCOLCOUNT];
493cdf0e10cSrcweir         SCsCOL i;
494cdf0e10cSrcweir         for (i=0; i<=MAXCOL; i++)
495cdf0e10cSrcweir         {
496cdf0e10cSrcweir             SCsROW nSRow = nRow;
497cdf0e10cSrcweir             if (bBack)  { if (i>=nCol) --nSRow; }
498cdf0e10cSrcweir             else        { if (i<=nCol) ++nSRow; }
499cdf0e10cSrcweir             nNextRows[i] = aCol[i].SearchStyle( nSRow, pSearchStyle, bBack, bSelect, rMark );
500cdf0e10cSrcweir         }
501cdf0e10cSrcweir         if (bBack)                          // rueckwaerts
502cdf0e10cSrcweir         {
503cdf0e10cSrcweir             nRow = -1;
504cdf0e10cSrcweir             for (i=MAXCOL; i>=0; i--)
505cdf0e10cSrcweir                 if (nNextRows[i]>nRow)
506cdf0e10cSrcweir                 {
507cdf0e10cSrcweir                     nCol = i;
508cdf0e10cSrcweir                     nRow = nNextRows[i];
509cdf0e10cSrcweir                     bFound = sal_True;
510cdf0e10cSrcweir                 }
511cdf0e10cSrcweir         }
512cdf0e10cSrcweir         else                                // vorwaerts
513cdf0e10cSrcweir         {
514cdf0e10cSrcweir             nRow = MAXROW+1;
515cdf0e10cSrcweir             for (i=0; i<=MAXCOL; i++)
516cdf0e10cSrcweir                 if (nNextRows[i]<nRow)
517cdf0e10cSrcweir                 {
518cdf0e10cSrcweir                     nCol = i;
519cdf0e10cSrcweir                     nRow = nNextRows[i];
520cdf0e10cSrcweir                     bFound = sal_True;
521cdf0e10cSrcweir                 }
522cdf0e10cSrcweir         }
523cdf0e10cSrcweir     }
524cdf0e10cSrcweir 
525cdf0e10cSrcweir     if (bFound)
526cdf0e10cSrcweir     {
527cdf0e10cSrcweir         rCol = (SCCOL) nCol;
528cdf0e10cSrcweir         rRow = (SCROW) nRow;
529cdf0e10cSrcweir     }
530cdf0e10cSrcweir     return bFound;
531cdf0e10cSrcweir }
532cdf0e10cSrcweir 
533cdf0e10cSrcweir //!     einzelnes Pattern fuer Undo zurueckgeben
534cdf0e10cSrcweir 
ReplaceStyle(const SvxSearchItem & rSearchItem,SCCOL & rCol,SCROW & rRow,ScMarkData & rMark,sal_Bool bIsUndo)535cdf0e10cSrcweir sal_Bool ScTable::ReplaceStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
536cdf0e10cSrcweir                            ScMarkData& rMark, sal_Bool bIsUndo)
537cdf0e10cSrcweir {
538cdf0e10cSrcweir     sal_Bool bRet;
539cdf0e10cSrcweir     if (bIsUndo)
540cdf0e10cSrcweir         bRet = sal_True;
541cdf0e10cSrcweir     else
542cdf0e10cSrcweir         bRet = SearchStyle(rSearchItem, rCol, rRow, rMark);
543cdf0e10cSrcweir     if (bRet)
544cdf0e10cSrcweir     {
545cdf0e10cSrcweir         const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
546cdf0e10cSrcweir                                         pDocument->GetStyleSheetPool()->Find(
547cdf0e10cSrcweir                                         rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
548cdf0e10cSrcweir 
549cdf0e10cSrcweir         if (pReplaceStyle)
550cdf0e10cSrcweir             ApplyStyle( rCol, rRow, *pReplaceStyle );
551cdf0e10cSrcweir         else
552cdf0e10cSrcweir         {
553cdf0e10cSrcweir             DBG_ERROR("pReplaceStyle==0");
554cdf0e10cSrcweir         }
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     return bRet;
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
SearchAllStyle(const SvxSearchItem & rSearchItem,ScMarkData & rMark)560cdf0e10cSrcweir sal_Bool ScTable::SearchAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark)
561cdf0e10cSrcweir {
562cdf0e10cSrcweir     const ScStyleSheet* pSearchStyle = (const ScStyleSheet*)
563cdf0e10cSrcweir                                         pDocument->GetStyleSheetPool()->Find(
564cdf0e10cSrcweir                                         rSearchItem.GetSearchString(), SFX_STYLE_FAMILY_PARA );
565cdf0e10cSrcweir     sal_Bool bSelect = rSearchItem.GetSelection();
566cdf0e10cSrcweir     sal_Bool bBack = rSearchItem.GetBackward();
567cdf0e10cSrcweir 
568cdf0e10cSrcweir     ScMarkData aNewMark( rMark );   // Tabellen-Markierungen kopieren
569cdf0e10cSrcweir     aNewMark.ResetMark();
570cdf0e10cSrcweir     for (SCCOL i=0; i<=MAXCOL; i++)
571cdf0e10cSrcweir     {
572cdf0e10cSrcweir         sal_Bool bFound = sal_True;
573cdf0e10cSrcweir         SCsROW nRow = 0;
574cdf0e10cSrcweir         SCsROW nEndRow;
575cdf0e10cSrcweir         while (bFound && nRow <= MAXROW)
576cdf0e10cSrcweir         {
577cdf0e10cSrcweir             bFound = aCol[i].SearchStyleRange( nRow, nEndRow, pSearchStyle, bBack, bSelect, rMark );
578cdf0e10cSrcweir             if (bFound)
579cdf0e10cSrcweir             {
580cdf0e10cSrcweir                 if (nEndRow<nRow)
581cdf0e10cSrcweir                 {
582cdf0e10cSrcweir                     SCsROW nTemp = nRow;
583cdf0e10cSrcweir                     nRow = nEndRow;
584cdf0e10cSrcweir                     nEndRow = nTemp;
585cdf0e10cSrcweir                 }
586cdf0e10cSrcweir                 aNewMark.SetMultiMarkArea( ScRange( i,nRow,nTab, i,nEndRow,nTab ) );
587cdf0e10cSrcweir                 nRow = nEndRow + 1;
588cdf0e10cSrcweir             }
589cdf0e10cSrcweir         }
590cdf0e10cSrcweir     }
591cdf0e10cSrcweir 
592cdf0e10cSrcweir     rMark = aNewMark;       //  Markierung kopieren
593cdf0e10cSrcweir                             //! pro Tabelle
594cdf0e10cSrcweir 
595cdf0e10cSrcweir     return (aNewMark.IsMultiMarked());
596cdf0e10cSrcweir }
597cdf0e10cSrcweir 
ReplaceAllStyle(const SvxSearchItem & rSearchItem,ScMarkData & rMark,ScDocument * pUndoDoc)598cdf0e10cSrcweir sal_Bool ScTable::ReplaceAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
599cdf0e10cSrcweir                                 ScDocument* pUndoDoc)
600cdf0e10cSrcweir {
601cdf0e10cSrcweir     sal_Bool bRet = SearchAllStyle(rSearchItem, rMark);
602cdf0e10cSrcweir     if (bRet)
603cdf0e10cSrcweir     {
604cdf0e10cSrcweir         const ScStyleSheet* pReplaceStyle = (const ScStyleSheet*)
605cdf0e10cSrcweir                                         pDocument->GetStyleSheetPool()->Find(
606cdf0e10cSrcweir                                         rSearchItem.GetReplaceString(), SFX_STYLE_FAMILY_PARA );
607cdf0e10cSrcweir 
608cdf0e10cSrcweir         if (pReplaceStyle)
609cdf0e10cSrcweir         {
610cdf0e10cSrcweir             if (pUndoDoc)
611cdf0e10cSrcweir                 pDocument->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab,
612cdf0e10cSrcweir                                             IDF_ATTRIB, sal_True, pUndoDoc, &rMark );
613cdf0e10cSrcweir             ApplySelectionStyle( *pReplaceStyle, rMark );
614cdf0e10cSrcweir         }
615cdf0e10cSrcweir         else
616cdf0e10cSrcweir         {
617cdf0e10cSrcweir             DBG_ERROR("pReplaceStyle==0");
618cdf0e10cSrcweir         }
619cdf0e10cSrcweir     }
620cdf0e10cSrcweir 
621cdf0e10cSrcweir     return bRet;
622cdf0e10cSrcweir }
623cdf0e10cSrcweir 
SearchAndReplace(const SvxSearchItem & rSearchItem,SCCOL & rCol,SCROW & rRow,ScMarkData & rMark,String & rUndoStr,ScDocument * pUndoDoc)624cdf0e10cSrcweir sal_Bool ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem,
625cdf0e10cSrcweir                                 SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
626cdf0e10cSrcweir                                 String& rUndoStr, ScDocument* pUndoDoc)
627cdf0e10cSrcweir {
628cdf0e10cSrcweir     sal_uInt16 nCommand = rSearchItem.GetCommand();
629cdf0e10cSrcweir     sal_Bool bFound = sal_False;
630cdf0e10cSrcweir     if ( ValidColRow(rCol, rRow) ||
631cdf0e10cSrcweir          ((nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE) &&
632cdf0e10cSrcweir            (((rCol == MAXCOLCOUNT || rCol == -1) && VALIDROW(rRow)) ||
633cdf0e10cSrcweir             ((rRow == MAXROWCOUNT || rRow == -1) && VALIDCOL(rCol))
634cdf0e10cSrcweir            )
635cdf0e10cSrcweir          )
636cdf0e10cSrcweir        )
637cdf0e10cSrcweir     {
638cdf0e10cSrcweir         sal_Bool bStyles = rSearchItem.GetPattern();
639cdf0e10cSrcweir         if (bStyles)
640cdf0e10cSrcweir         {
641cdf0e10cSrcweir             if (nCommand == SVX_SEARCHCMD_FIND)
642cdf0e10cSrcweir                 bFound = SearchStyle(rSearchItem, rCol, rRow, rMark);
643cdf0e10cSrcweir             else if (nCommand == SVX_SEARCHCMD_REPLACE)
644cdf0e10cSrcweir                 bFound = ReplaceStyle(rSearchItem, rCol, rRow, rMark, sal_False);
645cdf0e10cSrcweir             else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
646cdf0e10cSrcweir                 bFound = SearchAllStyle(rSearchItem, rMark);
647cdf0e10cSrcweir             else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
648cdf0e10cSrcweir                 bFound = ReplaceAllStyle(rSearchItem, rMark, pUndoDoc);
649cdf0e10cSrcweir         }
650cdf0e10cSrcweir         else
651cdf0e10cSrcweir         {
652cdf0e10cSrcweir             //  SearchParam no longer needed - SearchOptions contains all settings
653cdf0e10cSrcweir             com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
654cdf0e10cSrcweir             aSearchOptions.Locale = *ScGlobal::GetLocale();
655cdf0e10cSrcweir 
656cdf0e10cSrcweir             //  #107259# reflect UseAsianOptions flag in SearchOptions
657cdf0e10cSrcweir             //  (use only ignore case and width if asian options are disabled).
658cdf0e10cSrcweir             //  This is also done in SvxSearchDialog CommandHdl, but not in API object.
659cdf0e10cSrcweir             if ( !rSearchItem.IsUseAsianOptions() )
660cdf0e10cSrcweir                 aSearchOptions.transliterateFlags &=
661cdf0e10cSrcweir                     ( com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
662cdf0e10cSrcweir                       com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
663cdf0e10cSrcweir 
664cdf0e10cSrcweir             pSearchText = new utl::TextSearch( aSearchOptions );
665cdf0e10cSrcweir 
666cdf0e10cSrcweir             if (nCommand == SVX_SEARCHCMD_FIND)
667cdf0e10cSrcweir                 bFound = Search(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
668cdf0e10cSrcweir             else if (nCommand == SVX_SEARCHCMD_FIND_ALL)
669cdf0e10cSrcweir                 bFound = SearchAll(rSearchItem, rMark, rUndoStr, pUndoDoc);
670cdf0e10cSrcweir             else if (nCommand == SVX_SEARCHCMD_REPLACE)
671cdf0e10cSrcweir                 bFound = Replace(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
672cdf0e10cSrcweir             else if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
673cdf0e10cSrcweir                 bFound = ReplaceAll(rSearchItem, rMark, rUndoStr, pUndoDoc);
674cdf0e10cSrcweir 
675cdf0e10cSrcweir             delete pSearchText;
676cdf0e10cSrcweir             pSearchText = NULL;
677cdf0e10cSrcweir         }
678cdf0e10cSrcweir     }
679cdf0e10cSrcweir     return bFound;
680cdf0e10cSrcweir }
681