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