LibreOffice Module sc (master) 1
table6.cxx
Go to the documentation of this file.
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
21#include <com/sun/star/util/SearchResult.hpp>
22#include <svl/srchitem.hxx>
23#include <editeng/editobj.hxx>
24#include <osl/diagnose.h>
25#include <sal/log.hxx>
26
27#include <table.hxx>
28#include <formulacell.hxx>
29#include <document.hxx>
30#include <stlpool.hxx>
31#include <stlsheet.hxx>
32#include <markdata.hxx>
33#include <editutil.hxx>
34#include <postit.hxx>
35
36namespace {
37
38void lcl_GetTextWithBreaks( const EditTextObject& rData, ScDocument* pDoc, OUString& rVal )
39{
40 EditEngine& rEngine = pDoc->GetEditEngine();
41 rEngine.SetText(rData);
42 rVal = rEngine.GetText();
43}
44
45}
46
47bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
48 const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
49{
50 if ( !IsColRowValid( nCol, nRow ) )
51 return false;
52
53 bool bFound = false;
54 bool bDoSearch = true;
55 bool bDoBack = rSearchItem.GetBackward();
56 bool bSearchFormatted = rSearchItem.IsSearchFormatted();
57
58 OUString aString;
59 ScRefCellValue aCell;
60 if (rSearchItem.GetSelection())
61 bDoSearch = rMark.IsCellMarked(nCol, nRow);
62
63 if (!bDoSearch)
64 return false;
65
66 ScPostIt* pNote;
67 if (rSearchItem.GetCellType() == SvxSearchCellType::NOTE)
68 {
69 pNote = aCol[nCol].GetCellNote(rBlockPos, nRow);
70 if (!pNote)
71 return false;
72 }
73 else
74 {
75 aCell = aCol[nCol].GetCellValue(rBlockPos, nRow);
76 if (aCell.isEmpty())
77 return false;
78 pNote = nullptr;
79 }
80
81 CellType eCellType = aCell.getType();
82 switch (rSearchItem.GetCellType())
83 {
84 case SvxSearchCellType::FORMULA:
85 {
86 if ( eCellType == CELLTYPE_FORMULA )
87 aString = aCell.getFormula()->GetFormula(rDocument.GetGrammar());
88 else if ( eCellType == CELLTYPE_EDIT )
89 lcl_GetTextWithBreaks(*aCell.getEditText(), &rDocument, aString);
90 else
91 {
92 if( !bSearchFormatted )
93 aString = aCol[nCol].GetInputString( rBlockPos, nRow );
94 else
95 aString = aCol[nCol].GetString( rBlockPos, nRow );
96 }
97 break;
98 }
99 case SvxSearchCellType::VALUE:
100 if ( eCellType == CELLTYPE_EDIT )
101 lcl_GetTextWithBreaks(*aCell.getEditText(), &rDocument, aString);
102 else
103 {
104 if( !bSearchFormatted )
105 aString = aCol[nCol].GetInputString( rBlockPos, nRow );
106 else
107 aString = aCol[nCol].GetString( rBlockPos, nRow );
108 }
109 break;
110 case SvxSearchCellType::NOTE:
111 {
112 if (pNote)
113 aString = pNote->GetText();
114 break;
115 }
116 default:
117 break;
118 }
119 sal_Int32 nStart = 0;
120 sal_Int32 nEnd = aString.getLength();
121 css::util::SearchResult aSearchResult;
122 if (pSearchText)
123 {
124 if ( bDoBack )
125 {
126 sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
127 bFound = pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
128 // change results to definition before 614:
129 --nEnd;
130 }
131 else
132 {
133 bFound = pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
134 // change results to definition before 614:
135 --nEnd;
136 }
137
138 if (bFound && rSearchItem.GetWordOnly())
139 bFound = (nStart == 0 && nEnd == aString.getLength() - 1);
140 }
141 else
142 {
143 OSL_FAIL("pSearchText == NULL");
144 return bFound;
145 }
146
147 if (!bFound)
148 return false;
149 if ( rSearchItem.GetCommand() != SvxSearchCmd::REPLACE
150 && rSearchItem.GetCommand() != SvxSearchCmd::REPLACE_ALL )
151 return bFound;
152
153 if (!IsBlockEditable(nCol, nRow, nCol, nRow))
154 return bFound;
155
156 ScMatrixMode cMatrixFlag = ScMatrixMode::NONE;
157
158 // Don't split the matrix, only replace Matrix formulas
159 if (eCellType == CELLTYPE_FORMULA)
160 {
161 cMatrixFlag = aCell.getFormula()->GetMatrixFlag();
162 if(cMatrixFlag == ScMatrixMode::Reference)
163 return bFound;
164 }
165 // No UndoDoc => Matrix not restorable => don't replace
166 if (cMatrixFlag != ScMatrixMode::NONE && !pUndoDoc)
167 return bFound;
168
169 if ( cMatrixFlag == ScMatrixMode::NONE && rSearchItem.GetCommand() == SvxSearchCmd::REPLACE )
170 rUndoStr = aString;
171 else if (pUndoDoc)
172 {
173 ScAddress aAdr( nCol, nRow, nTab );
174 aCell.commit(*pUndoDoc, aAdr);
175 }
176
177 bool bRepeat = !rSearchItem.GetWordOnly();
178 do
179 {
180 // don't continue search if the found text is empty,
181 // otherwise it would never stop (#35410#)
182 if ( nEnd < nStart )
183 bRepeat = false;
184
185 OUString sReplStr = rSearchItem.GetReplaceString();
186 if (rSearchItem.GetRegExp())
187 {
188 pSearchText->ReplaceBackReferences( sReplStr, aString, aSearchResult );
189 OUStringBuffer aStrBuffer(aString);
190 aStrBuffer.remove(nStart, nEnd-nStart+1);
191 aStrBuffer.insert(nStart, sReplStr);
192 aString = aStrBuffer.makeStringAndClear();
193 }
194 else
195 {
196 OUStringBuffer aStrBuffer(aString);
197 aStrBuffer.remove(nStart, nEnd-nStart+1);
198 aStrBuffer.insert(nStart, rSearchItem.GetReplaceString());
199 aString = aStrBuffer.makeStringAndClear();
200 }
201
202 // Adjust index
203 if (bDoBack)
204 {
205 nEnd = nStart;
206 nStart = 0;
207 }
208 else
209 {
210 nStart = nStart + sReplStr.getLength();
211 nEnd = aString.getLength();
212 }
213
214 // continue search ?
215 if (bRepeat)
216 {
217 if ( rSearchItem.GetCommand() != SvxSearchCmd::REPLACE_ALL || nStart >= nEnd )
218 bRepeat = false;
219 else if (bDoBack)
220 {
221 sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
222 bRepeat = pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
223 // change results to definition before 614:
224 --nEnd;
225 }
226 else
227 {
228 bRepeat = pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
229 // change results to definition before 614:
230 --nEnd;
231 }
232 }
233 }
234 while (bRepeat);
235 if (rSearchItem.GetCellType() == SvxSearchCellType::NOTE)
236 {
237 // NB: rich text format is lost.
238 // This is also true of Cells.
239 if (pNote)
240 pNote->SetText( ScAddress( nCol, nRow, nTab ), aString );
241 }
242 else if ( cMatrixFlag != ScMatrixMode::NONE )
243 { // don't split Matrix
244 if ( aString.getLength() > 2 )
245 { // remove {} here so that "{=" can be replaced by "{=..."
246 if ( aString[ aString.getLength()-1 ] == '}' )
247 aString = aString.copy( 0, aString.getLength()-1 );
248 if ( aString[0] == '{' )
249 aString = aString.copy( 1 );
250 }
251 ScAddress aAdr( nCol, nRow, nTab );
252 ScFormulaCell* pFCell = new ScFormulaCell( rDocument, aAdr,
253 aString, rDocument.GetGrammar(), cMatrixFlag );
254 SCCOL nMatCols;
255 SCROW nMatRows;
256 aCell.getFormula()->GetMatColsRows(nMatCols, nMatRows);
257 pFCell->SetMatColsRows( nMatCols, nMatRows );
258 aCol[nCol].SetFormulaCell(nRow, pFCell);
259 }
260 else if (eCellType != CELLTYPE_FORMULA && aString.indexOf('\n') != -1)
261 {
263 rEngine.SetTextCurrentDefaults(aString);
264 SetEditText(nCol, nRow, rEngine.CreateTextObject());
265 }
266 else
267 aCol[nCol].SetString(nRow, nTab, aString, rDocument.GetAddressConvention());
268 // pCell is invalid now (deleted)
269 aCol[nCol].InitBlockPosition( rBlockPos ); // invalidate also the cached position
270
271 return bFound;
272}
273
274void ScTable::SkipFilteredRows(SCROW& rRow, SCROW& rLastNonFilteredRow, bool bForward)
275{
276 if (bForward)
277 {
278 // forward search
279
280 if (rRow <= rLastNonFilteredRow)
281 return;
282
283 SCROW nLastRow = rRow;
284 if (RowFiltered(rRow, nullptr, &nLastRow))
285 // move to the first non-filtered row.
286 rRow = nLastRow + 1;
287 else
288 // record the last non-filtered row to avoid checking
289 // the filtered state for each and every row.
290 rLastNonFilteredRow = nLastRow;
291 }
292 else
293 {
294 // backward search
295
296 if (rRow >= rLastNonFilteredRow)
297 return;
298
299 SCROW nFirstRow = rRow;
300 if (RowFiltered(rRow, &nFirstRow))
301 // move to the first non-filtered row.
302 rRow = nFirstRow - 1;
303 else
304 // record the last non-filtered row to avoid checking
305 // the filtered state for each and every row.
306 rLastNonFilteredRow = nFirstRow;
307 }
308}
309
310bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
311 const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
312{
313 SCCOL nLastCol;
314 SCROW nLastRow;
315 if (rSearchItem.GetCellType() == SvxSearchCellType::NOTE)
316 GetCellArea( nLastCol, nLastRow);
317 else
318 GetLastDataPos(nLastCol, nLastRow);
319 std::vector< sc::ColumnBlockConstPosition > blockPos;
320 return Search(rSearchItem, rCol, rRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
321}
322
323bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
324 SCCOL nLastCol, SCROW nLastRow,
325 const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc,
326 std::vector< sc::ColumnBlockConstPosition >& blockPos)
327{
328 bool bFound = false;
329 bool bAll = (rSearchItem.GetCommand() == SvxSearchCmd::FIND_ALL)
330 ||(rSearchItem.GetCommand() == SvxSearchCmd::REPLACE_ALL);
331 SCCOL nCol = rCol;
332 SCROW nRow = rRow;
333
334 bool bSkipFiltered = !rSearchItem.IsSearchFiltered();
335 bool bSearchNotes = (rSearchItem.GetCellType() == SvxSearchCellType::NOTE);
336 // We need to cache sc::ColumnBlockConstPosition per each column.
337 if (static_cast<SCCOL>(blockPos.size()) != nLastCol + 1)
338 {
339 blockPos.resize( nLastCol + 1 );
340 for( SCCOL i = 0; i <= nLastCol; ++i )
341 aCol[ i ].InitBlockPosition( blockPos[ i ] );
342 }
343 if (!bAll && rSearchItem.GetBackward())
344 {
345 SCROW nLastNonFilteredRow = rDocument.MaxRow() + 1;
346 if (rSearchItem.GetRowDirection())
347 {
348 nCol--;
349 nCol = std::min(nCol, nLastCol);
350 nRow = std::min(nRow, nLastRow);
351 while (!bFound && (nRow >= 0))
352 {
353 if (bSkipFiltered)
354 SkipFilteredRows(nRow, nLastNonFilteredRow, false);
355
356 while (!bFound && (nCol >= 0))
357 {
358 bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ], nRow,
359 rMark, rUndoStr, pUndoDoc);
360 if (!bFound)
361 {
362 bool bIsEmpty;
363 do
364 {
365 nCol--;
366 if (nCol >= 0)
367 {
368 if (bSearchNotes)
369 bIsEmpty = !aCol[nCol].HasCellNotes();
370 else
371 bIsEmpty = aCol[nCol].IsEmptyData();
372 }
373 else
374 bIsEmpty = true;
375 }
376 while ((nCol >= 0) && bIsEmpty);
377 }
378 }
379 if (!bFound)
380 {
381 nCol = nLastCol;
382 nRow--;
383 }
384 }
385 }
386 else
387 {
388 nRow--;
389 nCol = std::min(nCol, nLastCol);
390 nRow = std::min(nRow, nLastRow);
391 while (!bFound && (nCol >= 0))
392 {
393 while (!bFound && (nRow >= 0))
394 {
395 if (bSkipFiltered)
396 SkipFilteredRows(nRow, nLastNonFilteredRow, false);
397
398 bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ],
399 nRow, rMark, rUndoStr, pUndoDoc);
400 if (!bFound)
401 {
402 if (bSearchNotes)
403 {
404 /* TODO: can we look for the previous cell note instead? */
405 --nRow;
406 }
407 else
408 {
409 if (!aCol[nCol].GetPrevDataPos(nRow))
410 nRow = -1;
411 }
412 }
413 }
414 if (!bFound)
415 {
416 // Not found in this column. Move to the next column.
417 bool bIsEmpty;
418 nRow = nLastRow;
419 nLastNonFilteredRow = rDocument.MaxRow() + 1;
420 do
421 {
422 nCol--;
423 if (nCol >= 0)
424 {
425 if (bSearchNotes)
426 bIsEmpty = !aCol[nCol].HasCellNotes();
427 else
428 bIsEmpty = aCol[nCol].IsEmptyData();
429 }
430 else
431 bIsEmpty = true;
432 }
433 while ((nCol >= 0) && bIsEmpty);
434 }
435 }
436 }
437 }
438 else
439 {
440 SCROW nLastNonFilteredRow = -1;
441 if (rSearchItem.GetRowDirection())
442 {
443 nCol++;
444 while (!bFound && (nRow <= nLastRow))
445 {
446 if (bSkipFiltered)
447 SkipFilteredRows(nRow, nLastNonFilteredRow, true);
448
449 while (!bFound && (nCol <= nLastCol))
450 {
451 bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ],
452 nRow, rMark, rUndoStr, pUndoDoc);
453 if (!bFound)
454 {
455 nCol++;
456 while ((nCol <= nLastCol) &&
457 (bSearchNotes ? !aCol[nCol].HasCellNotes() : aCol[nCol].IsEmptyData()))
458 nCol++;
459 }
460 }
461 if (!bFound)
462 {
463 nCol = 0;
464 nRow++;
465 }
466 }
467 }
468 else
469 {
470 nRow++;
471 while (!bFound && (nCol <= nLastCol))
472 {
473 while (!bFound && (nRow <= nLastRow))
474 {
475 if (bSkipFiltered)
476 SkipFilteredRows(nRow, nLastNonFilteredRow, true);
477
478 // GetSearchAndReplaceStart sets a nCol of -1 for
479 // ColDirection() only if rSearchItem.GetPattern() is true,
480 // so a negative column shouldn't be possible here.
481 assert(nCol >= 0 && "negative nCol for ColDirection");
482
483 bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ],
484 nRow, rMark, rUndoStr, pUndoDoc);
485 if (!bFound)
486 {
487 if (bSearchNotes)
488 {
489 /* TODO: can we look for the next cell note instead? */
490 ++nRow;
491 }
492 else
493 {
494 if (!aCol[nCol].GetNextDataPos(nRow))
495 nRow = rDocument.MaxRow() + 1;
496 }
497 }
498 }
499 if (!bFound)
500 {
501 // Not found in this column. Move to the next column.
502 nRow = 0;
503 nLastNonFilteredRow = -1;
504 nCol++;
505 while ((nCol <= nLastCol) &&
506 (bSearchNotes ? !aCol[nCol].HasCellNotes() : aCol[nCol].IsEmptyData()))
507 nCol++;
508 }
509 }
510 }
511 }
512 if (bFound)
513 {
514 rCol = nCol;
515 rRow = nRow;
516 }
517 return bFound;
518}
519
520bool ScTable::SearchAll(const SvxSearchItem& rSearchItem, const ScMarkData& rMark,
521 ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
522{
523 bool bFound = true;
524 SCCOL nCol = 0;
525 SCROW nRow = -1;
526 bool bEverFound = false;
527
528 SCCOL nLastCol;
529 SCROW nLastRow;
530 if (rSearchItem.GetCellType() == SvxSearchCellType::NOTE)
531 GetCellArea( nLastCol, nLastRow);
532 else
533 GetLastDataPos(nLastCol, nLastRow);
534
535 std::vector< sc::ColumnBlockConstPosition > blockPos;
536 do
537 {
538 bFound = Search(rSearchItem, nCol, nRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
539 if (bFound)
540 {
541 bEverFound = true;
542 rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
543 }
544 }
545 while (bFound);
546
547 return bEverFound;
548}
549
551{
552 if (rSearchItem.GetBackward())
553 {
554 if (rSearchItem.GetRowDirection())
555 rCol += 1;
556 else
557 rRow += 1;
558 }
559 else
560 {
561 if (rSearchItem.GetRowDirection())
562 rCol -= 1;
563 else
564 rRow -= 1;
565 }
566}
567
568bool ScTable::Replace(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
569 const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
570{
571 SCCOL nCol = rCol;
572 SCROW nRow = rRow;
573
574 UpdateSearchItemAddressForReplace( rSearchItem, nCol, nRow );
575 bool bFound = Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
576 if (bFound)
577 {
578 rCol = nCol;
579 rRow = nRow;
580 }
581 return bFound;
582}
583
585 const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges,
586 OUString& rUndoStr, ScDocument* pUndoDoc, bool& bMatchedRangesWereClamped)
587{
588 SCCOL nCol = 0;
589 SCROW nRow = -1;
590
591 SCCOL nLastCol;
592 SCROW nLastRow;
593 if (rSearchItem.GetCellType() == SvxSearchCellType::NOTE)
594 GetCellArea( nLastCol, nLastRow);
595 else
596 GetLastDataPos(nLastCol, nLastRow);
597
598 // tdf#92160 - columnar replace is faster, and more memory efficient.
599 SvxSearchItem aCopyItem(rSearchItem);
600 aCopyItem.SetRowDirection(false);
601
602 std::vector< sc::ColumnBlockConstPosition > blockPos;
603 bool bEverFound = false;
604 while (true)
605 {
606 bool bFound = Search(aCopyItem, nCol, nRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
607
608 if (bFound)
609 {
610 bEverFound = true;
611 // The combination of this loop and the Join() algorithm is O(n^2),
612 // so just give up if the list gets too big.
613 if (rMatchedRanges.size() < 1000)
614 rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
615 else
616 bMatchedRangesWereClamped = true;
617 }
618 else
619 break;
620 }
621 return bEverFound;
622}
623
624bool ScTable::SearchStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
625 const ScMarkData& rMark)
626{
627 const ScStyleSheet* pSearchStyle = static_cast<const ScStyleSheet*>(
629 rSearchItem.GetSearchString(), SfxStyleFamily::Para ));
630
631 SCCOL nCol = rCol;
632 SCROW nRow = rRow;
633 bool bFound = false;
634
635 bool bSelect = rSearchItem.GetSelection();
636 bool bRows = rSearchItem.GetRowDirection();
637 bool bBack = rSearchItem.GetBackward();
638 short nAdd = bBack ? -1 : 1;
639
640 if (bRows) // by row
641 {
642 if ( !IsColValid( nCol ) )
643 {
644 SAL_WARN( "sc.core", "SearchStyle: bad column " << nCol);
645 return false;
646 }
647 nRow += nAdd;
648 do
649 {
650 SCROW nNextRow = aCol[nCol].SearchStyle( nRow, pSearchStyle, bBack, bSelect, rMark );
651 if (!ValidRow(nNextRow))
652 {
653 nRow = bBack ? rDocument.MaxRow() : 0;
654 nCol = sal::static_int_cast<SCCOL>( nCol + nAdd );
655 }
656 else
657 {
658 nRow = nNextRow;
659 bFound = true;
660 }
661 }
662 while ( !bFound && IsColValid( nCol ) );
663 }
664 else // by column
665 {
666 SCCOL aColSize = aCol.size();
667 std::vector< SCROW > nNextRows ( aColSize );
668 SCCOL i;
669 for (i=0; i < aColSize; ++i)
670 {
671 SCROW nSRow = nRow;
672 if (bBack)
673 {
674 if (i>=nCol) --nSRow;
675 }
676 else
677 {
678 if (i<=nCol) ++nSRow;
679 }
680 nNextRows[i] = aCol[i].SearchStyle( nSRow, pSearchStyle, bBack, bSelect, rMark );
681 }
682 if (bBack) // backwards
683 {
684 nRow = -1;
685 for (i = aColSize - 1; i>=0; --i)
686 if (nNextRows[i]>nRow)
687 {
688 nCol = i;
689 nRow = nNextRows[i];
690 bFound = true;
691 }
692 }
693 else // forwards
694 {
695 nRow = rDocument.MaxRow()+1;
696 for (i=0; i < aColSize; ++i)
697 if (nNextRows[i]<nRow)
698 {
699 nCol = i;
700 nRow = nNextRows[i];
701 bFound = true;
702 }
703 }
704 }
705
706 if (bFound)
707 {
708 rCol = nCol;
709 rRow = nRow;
710 }
711 return bFound;
712}
713
714//TODO: return single Pattern for Undo
715
716bool ScTable::ReplaceStyle(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
717 const ScMarkData& rMark, bool bIsUndo)
718{
719 bool bRet;
720 if (bIsUndo)
721 bRet = true;
722 else
723 bRet = SearchStyle(rSearchItem, rCol, rRow, rMark);
724 if (bRet)
725 {
726 const ScStyleSheet* pReplaceStyle = static_cast<const ScStyleSheet*>(
728 rSearchItem.GetReplaceString(), SfxStyleFamily::Para ));
729
730 if (pReplaceStyle)
731 ApplyStyle( rCol, rRow, pReplaceStyle );
732 else
733 {
734 OSL_FAIL("pReplaceStyle==0");
735 }
736 }
737
738 return bRet;
739}
740
742 const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges)
743{
744 const ScStyleSheet* pSearchStyle = static_cast<const ScStyleSheet*>(
746 rSearchItem.GetSearchString(), SfxStyleFamily::Para ));
747 bool bSelect = rSearchItem.GetSelection();
748 bool bBack = rSearchItem.GetBackward();
749 bool bEverFound = false;
750
751 for (SCCOL i=0; i < aCol.size(); ++i)
752 {
753 bool bFound = true;
754 SCROW nRow = 0;
755 SCROW nEndRow;
756 while (bFound && nRow <= rDocument.MaxRow())
757 {
758 bFound = aCol[i].SearchStyleRange( nRow, nEndRow, pSearchStyle, bBack, bSelect, rMark );
759 if (bFound)
760 {
761 if (nEndRow<nRow)
762 std::swap( nRow, nEndRow );
763 rMatchedRanges.Join(ScRange(i, nRow, nTab, i, nEndRow, nTab));
764 nRow = nEndRow + 1;
765 bEverFound = true;
766 }
767 }
768 }
769
770 return bEverFound;
771}
772
774 const SvxSearchItem& rSearchItem, const ScMarkData& rMark, ScRangeList& rMatchedRanges,
775 ScDocument* pUndoDoc)
776{
777 bool bRet = SearchAllStyle(rSearchItem, rMark, rMatchedRanges);
778 if (bRet)
779 {
780 const ScStyleSheet* pReplaceStyle = static_cast<const ScStyleSheet*>(
782 rSearchItem.GetReplaceString(), SfxStyleFamily::Para ));
783
784 if (pReplaceStyle)
785 {
786 if (pUndoDoc)
788 InsertDeleteFlags::ATTRIB, true, *pUndoDoc, &rMark);
789 ApplySelectionStyle( *pReplaceStyle, rMark );
790 }
791 else
792 {
793 OSL_FAIL("pReplaceStyle==0");
794 }
795 }
796
797 return bRet;
798}
799
801 const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark,
802 ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc, bool& bMatchedRangesWereClamped)
803{
804 SvxSearchCmd nCommand = rSearchItem.GetCommand();
805 bool bFound = false;
806 if ( ValidColRow(rCol, rRow) ||
807 ((nCommand == SvxSearchCmd::FIND || nCommand == SvxSearchCmd::REPLACE) &&
808 (((rCol == GetDoc().GetMaxColCount() || rCol == -1) && ValidRow(rRow)) ||
809 ((rRow == GetDoc().GetMaxRowCount() || rRow == -1) && ValidCol(rCol))
810 )
811 )
812 )
813 {
814 bool bStyles = rSearchItem.GetPattern();
815 if (bStyles)
816 {
817 if (nCommand == SvxSearchCmd::FIND)
818 bFound = SearchStyle(rSearchItem, rCol, rRow, rMark);
819 else if (nCommand == SvxSearchCmd::REPLACE)
820 bFound = ReplaceStyle(rSearchItem, rCol, rRow, rMark, false);
821 else if (nCommand == SvxSearchCmd::FIND_ALL)
822 bFound = SearchAllStyle(rSearchItem, rMark, rMatchedRanges);
823 else if (nCommand == SvxSearchCmd::REPLACE_ALL)
824 bFound = ReplaceAllStyle(rSearchItem, rMark, rMatchedRanges, pUndoDoc);
825 }
826 else if (ScDocument::IsEmptyCellSearch( rSearchItem))
827 {
828 // Search for empty cells.
829 bFound = SearchAndReplaceEmptyCells(rSearchItem, rCol, rRow, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
830 }
831 else
832 {
833 // SearchParam no longer needed - SearchOptions contains all settings
834 i18nutil::SearchOptions2 aSearchOptions = rSearchItem.GetSearchOptions();
835 aSearchOptions.Locale = ScGlobal::GetLocale();
836
837 // reflect UseAsianOptions flag in SearchOptions
838 // (use only ignore case and width if asian options are disabled).
839 // This is also done in SvxSearchDialog CommandHdl, but not in API object.
840 if ( !rSearchItem.IsUseAsianOptions() )
841 aSearchOptions.transliterateFlags &=
842 TransliterationFlags::IGNORE_CASE |
843 TransliterationFlags::IGNORE_WIDTH;
844
845 pSearchText.reset( new utl::TextSearch( aSearchOptions ) );
846
847 if (nCommand == SvxSearchCmd::FIND)
848 bFound = Search(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
849 else if (nCommand == SvxSearchCmd::FIND_ALL)
850 bFound = SearchAll(rSearchItem, rMark, rMatchedRanges, rUndoStr, pUndoDoc);
851 else if (nCommand == SvxSearchCmd::REPLACE)
852 bFound = Replace(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
853 else if (nCommand == SvxSearchCmd::REPLACE_ALL)
854 bFound = ReplaceAll(rSearchItem, rMark, rMatchedRanges, rUndoStr, pUndoDoc, bMatchedRangesWereClamped);
855
856 pSearchText.reset();
857 }
858 }
859 return bFound;
860}
861
863 const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark,
864 ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
865{
866 SCCOL nColStart, nColEnd;
867 SCROW nRowStart, nRowEnd;
868 GetFirstDataPos(nColStart, nRowStart);
869 GetLastDataPos(nColEnd, nRowEnd);
870
871 ScRangeList aRanges(ScRange(nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab));
872
873 if (rSearchItem.GetSelection())
874 {
875 // current selection only.
876 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
877 // There is no selection. Bail out.
878 return false;
879
880 ScRangeList aMarkedRanges, aNewRanges;
881 rMark.FillRangeListWithMarks(&aMarkedRanges, true);
882 for ( size_t i = 0, n = aMarkedRanges.size(); i < n; ++i )
883 {
884 ScRange & rRange = aMarkedRanges[ i ];
885 if (rRange.aStart.Col() > nColEnd || rRange.aStart.Row() > nRowEnd || rRange.aEnd.Col() < nColStart || rRange.aEnd.Row() < nRowStart)
886 // This range is outside the data area. Skip it.
887 continue;
888
889 // Shrink the range into data area only.
890 if (rRange.aStart.Col() < nColStart)
891 rRange.aStart.SetCol(nColStart);
892 if (rRange.aStart.Row() < nRowStart)
893 rRange.aStart.SetRow(nRowStart);
894
895 if (rRange.aEnd.Col() > nColEnd)
896 rRange.aEnd.SetCol(nColEnd);
897 if (rRange.aEnd.Row() > nRowEnd)
898 rRange.aEnd.SetRow(nRowEnd);
899
900 aNewRanges.push_back(rRange);
901 }
902 aRanges = aNewRanges;
903 }
904
905 SvxSearchCmd nCommand = rSearchItem.GetCommand();
906 if (nCommand == SvxSearchCmd::FIND || nCommand == SvxSearchCmd::REPLACE)
907 {
908 if (rSearchItem.GetBackward())
909 {
910 for ( size_t i = aRanges.size(); i > 0; --i )
911 {
912 const ScRange & rRange = aRanges[ i - 1 ];
913 if (SearchRangeForEmptyCell(rRange, rSearchItem, rCol, rRow, rUndoStr))
914 return true;
915 }
916 }
917 else
918 {
919 for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
920 {
921 const ScRange & rRange = aRanges[ i ];
922 if (SearchRangeForEmptyCell(rRange, rSearchItem, rCol, rRow, rUndoStr))
923 return true;
924 }
925 }
926 }
927 else if (nCommand == SvxSearchCmd::FIND_ALL || nCommand == SvxSearchCmd::REPLACE_ALL)
928 {
929 bool bFound = false;
930 for ( size_t i = 0, nListSize = aRanges.size(); i < nListSize; ++i )
931 {
932 ScRange const & rRange = aRanges[ i ];
933 bFound |= SearchRangeForAllEmptyCells(rRange, rSearchItem, rMatchedRanges, rUndoStr, pUndoDoc);
934 }
935 return bFound;
936 }
937 return false;
938}
939
940namespace {
941
942bool lcl_maybeReplaceCellString(
943 ScColumn& rColObj, SCCOL& rCol, SCROW& rRow, OUString& rUndoStr, SCCOL nCol, SCROW nRow, const SvxSearchItem& rSearchItem)
944{
945 ScRefCellValue aCell = rColObj.GetCellValue(nRow);
946 if (aCell.isEmpty())
947 {
948 // empty cell found.
949 rCol = nCol;
950 rRow = nRow;
951 if (rSearchItem.GetCommand() == SvxSearchCmd::REPLACE &&
952 !rSearchItem.GetReplaceString().isEmpty())
953 {
954 rColObj.SetRawString(nRow, rSearchItem.GetReplaceString());
955 rUndoStr.clear();
956 }
957 return true;
958 }
959 return false;
960}
961
962}
963
965 const ScRange& rRange, const SvxSearchItem& rSearchItem,
966 SCCOL& rCol, SCROW& rRow, OUString& rUndoStr)
967{
968 SvxSearchCmd nCmd = rSearchItem.GetCommand();
969 bool bSkipFiltered = rSearchItem.IsSearchFiltered();
970 if (rSearchItem.GetBackward())
971 {
972 // backward search
973 if (rSearchItem.GetRowDirection())
974 {
975 // row direction.
976 SCROW nLastNonFilteredRow = rDocument.MaxRow() + 1;
977 SCROW nBeginRow = std::min(rRange.aEnd.Row(), rRow);
978 for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
979 {
980 if (bSkipFiltered)
981 SkipFilteredRows(nRow, nLastNonFilteredRow, false);
982 if (nRow < rRange.aStart.Row())
983 break;
984
985 SCCOL nBeginCol = rRange.aEnd.Col();
986 if (nRow == rRow && nBeginCol >= rCol)
987 // always start from one cell before the cursor.
988 nBeginCol = rCol - (nCmd == SvxSearchCmd::FIND ? 1 : 0);
989
990 for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
991 {
992 if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
993 return true;
994 }
995 }
996 }
997 else
998 {
999 // column direction.
1000 SCCOL nBeginCol = std::min(rRange.aEnd.Col(), rCol);
1001 for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
1002 {
1003 SCROW nLastNonFilteredRow = rDocument.MaxRow() + 1;
1004 SCROW nBeginRow = rRange.aEnd.Row();
1005 if (nCol == rCol && nBeginRow >= rRow)
1006 // always start from one cell before the cursor.
1007 nBeginRow = rRow - (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1008 for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
1009 {
1010 if (bSkipFiltered)
1011 SkipFilteredRows(nRow, nLastNonFilteredRow, false);
1012 if (nRow < rRange.aStart.Row())
1013 break;
1014
1015 if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1016 return true;
1017 }
1018 }
1019 }
1020 }
1021 else
1022 {
1023 // forward search
1024 if (rSearchItem.GetRowDirection())
1025 {
1026 // row direction.
1027 SCROW nLastNonFilteredRow = -1;
1028 SCROW nBeginRow = rRange.aStart.Row() < rRow ? rRow : rRange.aStart.Row();
1029 for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
1030 {
1031 if (bSkipFiltered)
1032 SkipFilteredRows(nRow, nLastNonFilteredRow, true);
1033 if (nRow > rRange.aEnd.Row())
1034 break;
1035
1036 SCCOL nBeginCol = rRange.aStart.Col();
1037 if (nRow == rRow && nBeginCol <= rCol)
1038 // always start from one cell past the cursor.
1039 nBeginCol = rCol + (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1040 for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
1041 {
1042 if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1043 return true;
1044 }
1045 }
1046 }
1047 else
1048 {
1049 // column direction.
1050 SCCOL nBeginCol = rRange.aStart.Col() < rCol ? rCol : rRange.aStart.Col();
1051 for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
1052 {
1053 SCROW nLastNonFilteredRow = -1;
1054 SCROW nBeginRow = rRange.aStart.Row();
1055 if (nCol == rCol && nBeginRow <= rRow)
1056 // always start from one cell past the cursor.
1057 nBeginRow = rRow + (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1058 for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
1059 {
1060 if (bSkipFiltered)
1061 SkipFilteredRows(nRow, nLastNonFilteredRow, true);
1062 if (nRow > rRange.aEnd.Row())
1063 break;
1064
1065 if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1066 return true;
1067 }
1068 }
1069 }
1070 }
1071 return false;
1072}
1073
1075 const ScRange& rRange, const SvxSearchItem& rSearchItem,
1076 ScRangeList& rMatchedRanges, OUString& rUndoStr, ScDocument* pUndoDoc)
1077{
1078 bool bFound = false;
1079 bool bReplace = (rSearchItem.GetCommand() == SvxSearchCmd::REPLACE_ALL) &&
1080 !rSearchItem.GetReplaceString().isEmpty();
1081 bool bSkipFiltered = rSearchItem.IsSearchFiltered();
1082
1083 for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
1084 {
1085 SCROW nLastNonFilteredRow = -1;
1086 if (aCol[nCol].IsEmptyData())
1087 {
1088 // The entire column is empty.
1089 const SCROW nEndRow = rRange.aEnd.Row();
1090 for (SCROW nRow = rRange.aStart.Row(); nRow <= nEndRow; ++nRow)
1091 {
1092 SCROW nLastRow;
1093 const bool bFiltered = RowFiltered(nRow, nullptr, &nLastRow);
1094 if (nLastRow > nEndRow)
1095 nLastRow = nEndRow;
1096 if (!bFiltered)
1097 {
1098 rMatchedRanges.Join(ScRange(nCol, nRow, nTab, nCol, nLastRow, nTab));
1099 if (bReplace)
1100 {
1101 const OUString& rNewStr = rSearchItem.GetReplaceString();
1102 for (SCROW i = nRow; i <= nLastRow; ++i)
1103 {
1104 aCol[nCol].SetRawString(i, rNewStr);
1105 if (pUndoDoc)
1106 {
1107 // TODO: I'm using a string cell with empty content to
1108 // trigger deletion of cell instance on undo. Maybe I
1109 // should create a new cell type for this?
1110 pUndoDoc->SetString(ScAddress(nCol, i, nTab), OUString());
1111 }
1112 }
1113 rUndoStr.clear();
1114 }
1115 }
1116
1117 nRow = nLastRow; // move to the last filtered row.
1118 }
1119 bFound = true;
1120 continue;
1121 }
1122
1123 for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
1124 {
1125 if (bSkipFiltered)
1126 SkipFilteredRows(nRow, nLastNonFilteredRow, true);
1127 if (nRow > rRange.aEnd.Row())
1128 break;
1129
1130 ScRefCellValue aCell = aCol[nCol].GetCellValue(nRow);
1131 if (aCell.isEmpty())
1132 {
1133 // empty cell found
1134 rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
1135 bFound = true;
1136
1137 if (bReplace)
1138 {
1139 aCol[nCol].SetRawString(nRow, rSearchItem.GetReplaceString());
1140 if (pUndoDoc)
1141 {
1142 // TODO: I'm using a string cell with empty content to
1143 // trigger deletion of cell instance on undo. Maybe I
1144 // should create a new cell type for this?
1145 pUndoDoc->SetString(ScAddress(nCol, nRow, nTab), OUString());
1146 }
1147 }
1148 }
1149 }
1150 }
1151 return bFound;
1152}
1153
1154/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString GetText(LineEnd eEnd=LINEEND_LF) const
std::unique_ptr< EditTextObject > CreateTextObject()
void SetText(const OUString &rStr)
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
SCCOL size() const
ScRefCellValue GetCellValue(SCROW nRow) const
Definition: column.cxx:638
void SetRawString(SCROW nRow, const OUString &rStr)
Definition: column3.cxx:2977
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:492
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:483
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3391
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
Definition: document.hxx:1010
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2041
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
Definition: document.cxx:6055
static bool IsEmptyCellSearch(const SvxSearchItem &rSearchItem)
Definition: documen3.cxx:1300
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:619
void GetMatColsRows(SCCOL &nCols, SCROW &nRows) const
ScMatrixMode GetMatrixFlag() const
void SetMatColsRows(SCCOL nCols, SCROW nRows)
OUString GetFormula(const formula::FormulaGrammar::Grammar=formula::FormulaGrammar::GRAM_DEFAULT, const ScInterpreterContext *pContext=nullptr) const
static css::lang::Locale & GetLocale()
Definition: global.cxx:1121
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
bool IsMultiMarked() const
Definition: markdata.hxx:81
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:372
bool IsCellMarked(SCCOL nCol, SCROW nRow, bool bNoSimple=false) const
Definition: markdata.cxx:270
bool IsMarked() const
Definition: markdata.hxx:80
Additional class containing cell annotation data.
Definition: postit.hxx:58
void SetText(const ScAddress &rPos, const OUString &rText)
Changes the caption text of this note.
Definition: postit.cxx:548
OUString GetText() const
Returns the caption text of this note.
Definition: postit.cxx:527
void Join(const ScRange &, bool bIsInList=false)
Definition: rangelst.cxx:152
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
size_t size() const
Definition: rangelst.hxx:89
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
bool ValidCol(SCCOL nCol) const
Definition: table.hxx:356
bool IsBlockEditable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool *pOnlyNotBecauseOfMatrix=nullptr, bool bNoMatrixAtAll=false) const
Definition: table2.cxx:2641
bool SearchRangeForAllEmptyCells(const ScRange &rRange, const SvxSearchItem &rSearchItem, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc)
Definition: table6.cxx:1074
bool ReplaceStyle(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, bool bIsUndo)
Definition: table6.cxx:716
bool GetCellArea(SCCOL &rEndCol, SCROW &rEndRow)
Definition: table1.cxx:521
bool SearchAllStyle(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges)
Definition: table6.cxx:741
bool SearchAll(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc)
Definition: table6.cxx:520
bool SearchAndReplaceEmptyCells(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc)
Definition: table6.cxx:862
ScColContainer aCol
Definition: table.hxx:162
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: table.hxx:358
bool SetEditText(SCCOL nCol, SCROW nRow, std::unique_ptr< EditTextObject > pEditText)
Definition: table2.cxx:1664
bool IsColValid(const SCCOL nScCol) const
Definition: table.hxx:344
bool SearchStyle(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark)
Definition: table6.cxx:624
void ApplyStyle(SCCOL nCol, SCROW nRow, const ScStyleSheet *rStyle)
Definition: table2.cxx:3006
bool SearchAndReplace(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc, bool &bMatchedRangesWereClamped)
Definition: table6.cxx:800
SCTAB nTab
Definition: table.hxx:218
bool IsColRowValid(const SCCOL nScCol, const SCROW nScRow) const
Definition: table.hxx:348
void GetLastDataPos(SCCOL &rCol, SCROW &rRow) const
Definition: table2.cxx:2053
void SkipFilteredRows(SCROW &rRow, SCROW &rLastNonFilteredRow, bool bForward)
Definition: table6.cxx:274
bool ReplaceAll(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc, bool &bMatchedRangesWereClamped)
Definition: table6.cxx:584
bool IsEmptyData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow) const
Definition: table1.cxx:1197
static void UpdateSearchItemAddressForReplace(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow)
Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
Definition: table6.cxx:550
bool RowFiltered(SCROW nRow, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: table5.cxx:848
bool Replace(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, OUString &rUndoStr, ScDocument *pUndoDoc)
Definition: table6.cxx:568
ScDocument & rDocument
Definition: table.hxx:219
ScDocument & GetDoc()
Definition: table.hxx:297
bool ReplaceAllStyle(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges, ScDocument *pUndoDoc)
Definition: table6.cxx:773
void ApplySelectionStyle(const ScStyleSheet &rStyle, const ScMarkData &rMark)
Definition: table2.cxx:3044
void GetFirstDataPos(SCCOL &rCol, SCROW &rRow) const
Definition: table2.cxx:2038
bool Search(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, OUString &rUndoStr, ScDocument *pUndoDoc)
Definition: table6.cxx:310
std::unique_ptr< utl::TextSearch > pSearchText
Definition: table.hxx:220
bool ValidRow(SCROW nRow) const
Definition: table.hxx:357
bool SearchRangeForEmptyCell(const ScRange &rRange, const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, OUString &rUndoStr)
Definition: table6.cxx:964
bool SearchCell(const SvxSearchItem &rSearchItem, SCCOL nCol, sc::ColumnBlockConstPosition &rBlockPos, SCROW nRow, const ScMarkData &rMark, OUString &rUndoStr, ScDocument *pUndoDoc)
Definition: table6.cxx:47
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
const OUString & GetSearchString() const
SvxSearchCmd GetCommand() const
const OUString & GetReplaceString() const
bool IsSearchFiltered() const
const i18nutil::SearchOptions2 & GetSearchOptions() const
bool GetSelection() const
bool GetWordOnly() const
void SetRowDirection(bool bNewRowDirection)
bool IsSearchFormatted() const
bool GetRowDirection() const
SvxSearchCellType GetCellType() const
bool GetBackward() const
bool IsUseAsianOptions() const
bool GetRegExp() const
bool GetPattern() const
ScMatrixMode
CellType
Definition: global.hxx:272
@ CELLTYPE_EDIT
Definition: global.hxx:277
@ CELLTYPE_FORMULA
Definition: global.hxx:276
@ ATTRIB
Internal use only (d&d undo): do not delete caption objects of cell notes.
sal_Int64 n
#define SAL_WARN(area, stream)
int i
SvxSearchCmd
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:137
const EditTextObject * getEditText() const
Definition: cellvalue.hxx:136
bool isEmpty() const
Definition: cellvalue.cxx:667
void commit(ScDocument &rDoc, const ScAddress &rPos) const
Set cell value at specified position in specified document.
Definition: cellvalue.cxx:589
CellType getType() const
Definition: cellvalue.hxx:133
TransliterationFlags transliterateFlags
css::lang::Locale Locale
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17