21#include <com/sun/star/util/SearchResult.hpp>
24#include <osl/diagnose.h>
29#include <document.hxx>
31#include <stlsheet.hxx>
57 bool bDoSearch =
true;
70 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
72 pNote =
aCol[nCol].GetCellNote(rBlockPos, nRow);
78 aCell =
aCol[nCol].GetCellValue(rBlockPos, nRow);
84 bool bMultiLine =
false;
88 case SvxSearchCellType::FORMULA:
96 if( !bSearchFormatted )
97 aString =
aCol[nCol].GetInputString( rBlockPos, nRow );
99 aString =
aCol[nCol].GetString( rBlockPos, nRow );
103 case SvxSearchCellType::VALUE:
108 if( !bSearchFormatted )
109 aString =
aCol[nCol].GetInputString( rBlockPos, nRow );
111 aString =
aCol[nCol].GetString( rBlockPos, nRow );
114 case SvxSearchCellType::NOTE:
126 sal_Int32 nStart = 0;
127 sal_Int32 nEnd = aString.getLength();
128 css::util::SearchResult aSearchResult;
133 sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
134 bFound =
pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
140 bFound =
pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
146 bFound = (nStart == 0 && nEnd == aString.getLength() - 1);
150 OSL_FAIL(
"pSearchText == NULL");
156 if ( rSearchItem.
GetCommand() != SvxSearchCmd::REPLACE
157 && rSearchItem.
GetCommand() != SvxSearchCmd::REPLACE_ALL )
181 aCell.
commit(*pUndoDoc, aAdr);
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();
203 OUStringBuffer aStrBuffer(aString);
204 aStrBuffer.remove(nStart, nEnd-nStart+1);
206 aString = aStrBuffer.makeStringAndClear();
217 nStart = nStart + sReplStr.getLength();
218 nEnd = aString.getLength();
224 if ( rSearchItem.
GetCommand() != SvxSearchCmd::REPLACE_ALL || nStart >= nEnd )
228 sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
229 bRepeat =
pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
235 bRepeat =
pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
242 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
251 if ( aString.getLength() > 2 )
253 if ( aString[ aString.getLength()-1 ] ==
'}' )
254 aString = aString.copy( 0, aString.getLength()-1 );
255 if ( aString[0] ==
'{' )
256 aString = aString.copy( 1 );
265 aCol[nCol].SetFormulaCell(nRow, pFCell);
267 else if ( bMultiLine && aString.indexOf(
'\n') != -1 )
276 aCol[nCol].InitBlockPosition( rBlockPos );
287 if (rRow <= rLastNonFilteredRow)
290 SCROW nLastRow = rRow;
297 rLastNonFilteredRow = nLastRow;
303 if (rRow >= rLastNonFilteredRow)
306 SCROW nFirstRow = rRow;
309 rRow = nFirstRow - 1;
313 rLastNonFilteredRow = nFirstRow;
322 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
326 std::vector< sc::ColumnBlockConstPosition > blockPos;
327 return Search(rSearchItem, rCol, rRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
333 std::vector< sc::ColumnBlockConstPosition >& blockPos)
336 bool bAll = (rSearchItem.
GetCommand() == SvxSearchCmd::FIND_ALL)
337 ||(rSearchItem.
GetCommand() == SvxSearchCmd::REPLACE_ALL);
342 bool bSearchNotes = (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE);
344 if (
static_cast<SCCOL>(blockPos.size()) != nLastCol + 1)
346 blockPos.resize( nLastCol + 1 );
347 for(
SCCOL i = 0;
i <= nLastCol; ++
i )
348 aCol[
i ].InitBlockPosition( blockPos[
i ] );
356 nCol = std::min(nCol, nLastCol);
357 nRow = std::min(nRow, nLastRow);
358 while (!bFound && (nRow >= 0))
363 while (!bFound && (nCol >= 0))
365 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ], nRow,
366 rMark, rUndoStr, pUndoDoc);
376 bIsEmpty = !
aCol[nCol].HasCellNotes();
378 bIsEmpty =
aCol[nCol].IsEmptyData();
383 while ((nCol >= 0) && bIsEmpty);
396 nCol = std::min(nCol, nLastCol);
397 nRow = std::min(nRow, nLastRow);
398 while (!bFound && (nCol >= 0))
400 while (!bFound && (nRow >= 0))
405 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ],
406 nRow, rMark, rUndoStr, pUndoDoc);
416 if (!
aCol[nCol].GetPrevDataPos(nRow))
433 bIsEmpty = !
aCol[nCol].HasCellNotes();
435 bIsEmpty =
aCol[nCol].IsEmptyData();
440 while ((nCol >= 0) && bIsEmpty);
447 SCROW nLastNonFilteredRow = -1;
451 while (!bFound && (nRow <= nLastRow))
456 while (!bFound && (nCol <= nLastCol))
458 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ],
459 nRow, rMark, rUndoStr, pUndoDoc);
463 while ((nCol <= nLastCol) &&
478 while (!bFound && (nCol <= nLastCol))
480 while (!bFound && (nRow <= nLastRow))
488 assert(nCol >= 0 &&
"negative nCol for ColDirection");
490 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ],
491 nRow, rMark, rUndoStr, pUndoDoc);
501 if (!
aCol[nCol].GetNextDataPos(nRow))
510 nLastNonFilteredRow = -1;
512 while ((nCol <= nLastCol) &&
533 bool bEverFound =
false;
537 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
542 std::vector< sc::ColumnBlockConstPosition > blockPos;
545 bFound =
Search(rSearchItem, nCol, nRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
582 bool bFound =
Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
593 OUString& rUndoStr,
ScDocument* pUndoDoc,
bool& bMatchedRangesWereClamped)
600 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
609 std::vector< sc::ColumnBlockConstPosition > blockPos;
610 bool bEverFound =
false;
613 bool bFound =
Search(aCopyItem, nCol, nRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
620 if (rMatchedRanges.
size() < 1000)
623 bMatchedRangesWereClamped =
true;
645 short nAdd = bBack ? -1 : 1;
651 SAL_WARN(
"sc.core",
"SearchStyle: bad column " << nCol);
657 SCROW nNextRow =
aCol[nCol].SearchStyle( nRow, pSearchStyle, bBack, bSelect, rMark );
661 nCol = sal::static_int_cast<SCCOL>( nCol + nAdd );
674 std::vector< SCROW > nNextRows ( aColSize );
676 for (
i=0;
i < aColSize; ++
i)
681 if (
i>=nCol) --nSRow;
685 if (
i<=nCol) ++nSRow;
687 nNextRows[
i] =
aCol[
i].SearchStyle( nSRow, pSearchStyle, bBack, bSelect, rMark );
692 for (
i = aColSize - 1;
i>=0; --
i)
693 if (nNextRows[
i]>nRow)
703 for (
i=0;
i < aColSize; ++
i)
704 if (nNextRows[
i]<nRow)
730 bRet =
SearchStyle(rSearchItem, rCol, rRow, rMark);
741 OSL_FAIL(
"pReplaceStyle==0");
756 bool bEverFound =
false;
765 bFound =
aCol[
i].SearchStyleRange( nRow, nEndRow, pSearchStyle, bBack, bSelect, rMark );
769 std::swap( nRow, nEndRow );
800 OSL_FAIL(
"pReplaceStyle==0");
809 ScRangeList& rMatchedRanges, OUString& rUndoStr,
ScDocument* pUndoDoc,
bool& bMatchedRangesWereClamped)
814 ((nCommand == SvxSearchCmd::FIND || nCommand == SvxSearchCmd::REPLACE) &&
815 (((rCol ==
GetDoc().GetMaxColCount() || rCol == -1) &&
ValidRow(rRow)) ||
816 ((rRow ==
GetDoc().GetMaxRowCount() || rRow == -1) &&
ValidCol(rCol))
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)
830 else if (nCommand == SvxSearchCmd::REPLACE_ALL)
831 bFound =
ReplaceAllStyle(rSearchItem, rMark, rMatchedRanges, pUndoDoc);
849 TransliterationFlags::IGNORE_CASE |
850 TransliterationFlags::IGNORE_WIDTH;
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);
873 SCCOL nColStart, nColEnd;
874 SCROW nRowStart, nRowEnd;
889 for (
size_t i = 0,
n = aMarkedRanges.
size();
i <
n; ++
i )
891 ScRange & rRange = aMarkedRanges[
i ];
902 if (rRange.
aEnd.
Col() > nColEnd)
904 if (rRange.
aEnd.
Row() > nRowEnd)
909 aRanges = aNewRanges;
913 if (nCommand == SvxSearchCmd::FIND || nCommand == SvxSearchCmd::REPLACE)
917 for (
size_t i = aRanges.
size();
i > 0; --
i )
919 const ScRange & rRange = aRanges[
i - 1 ];
926 for (
size_t i = 0, nListSize = aRanges.
size();
i < nListSize; ++
i )
928 const ScRange & rRange = aRanges[
i ];
934 else if (nCommand == SvxSearchCmd::FIND_ALL || nCommand == SvxSearchCmd::REPLACE_ALL)
937 for (
size_t i = 0, nListSize = aRanges.
size();
i < nListSize; ++
i )
939 ScRange const & rRange = aRanges[
i ];
949bool lcl_maybeReplaceCellString(
958 if (rSearchItem.
GetCommand() == SvxSearchCmd::REPLACE &&
993 if (nRow == rRow && nBeginCol >= rCol)
995 nBeginCol = rCol - (nCmd == SvxSearchCmd::FIND ? 1 : 0);
999 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1008 for (
SCCOL nCol = nBeginCol; nCol >= rRange.
aStart.
Col(); --nCol)
1012 if (nCol == rCol && nBeginRow >= rRow)
1014 nBeginRow = rRow - (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1015 for (
SCROW nRow = nBeginRow; nRow >= rRange.
aStart.
Row(); --nRow)
1022 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1034 SCROW nLastNonFilteredRow = -1;
1036 for (
SCROW nRow = nBeginRow; nRow <= rRange.
aEnd.
Row(); ++nRow)
1044 if (nRow == rRow && nBeginCol <= rCol)
1046 nBeginCol = rCol + (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1047 for (
SCCOL nCol = nBeginCol; nCol <= rRange.
aEnd.
Col(); ++nCol)
1049 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1058 for (
SCCOL nCol = nBeginCol; nCol <= rRange.
aEnd.
Col(); ++nCol)
1060 SCROW nLastNonFilteredRow = -1;
1062 if (nCol == rCol && nBeginRow <= rRow)
1064 nBeginRow = rRow + (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1065 for (
SCROW nRow = nBeginRow; nRow <= rRange.
aEnd.
Row(); ++nRow)
1072 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1085 bool bFound =
false;
1086 bool bReplace = (rSearchItem.
GetCommand() == SvxSearchCmd::REPLACE_ALL) &&
1092 SCROW nLastNonFilteredRow = -1;
1100 const bool bFiltered =
RowFiltered(nRow,
nullptr, &nLastRow);
1101 if (nLastRow > nEndRow)
1109 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
1111 aCol[nCol].SetRawString(
i, rNewStr);
OUString GetText(LineEnd eEnd=LINEEND_LF) const
std::unique_ptr< EditTextObject > CreateTextObject()
void SetText(const OUString &rStr)
sal_Int32 GetParagraphCount() const
ScRefCellValue GetCellValue(SCROW nRow) const
void SetRawString(SCROW nRow, const OUString &rStr)
SC_DLLPUBLIC SCCOL MaxCol() const
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
SC_DLLPUBLIC SCROW MaxRow() const
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
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)
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
static bool IsEmptyCellSearch(const SvxSearchItem &rSearchItem)
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
static css::lang::Locale & GetLocale()
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
bool IsMultiMarked() const
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
bool IsCellMarked(SCCOL nCol, SCROW nRow, bool bNoSimple=false) const
Additional class containing cell annotation data.
void SetText(const ScAddress &rPos, const OUString &rText)
Changes the caption text of this note.
OUString GetText() const
Returns the caption text of this note.
bool HasMultiLineText() const
Returns true, if the caption text of this note contains line breaks.
void Join(const ScRange &, bool bIsInList=false)
void push_back(const ScRange &rRange)
bool ValidCol(SCCOL nCol) const
bool IsBlockEditable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool *pOnlyNotBecauseOfMatrix=nullptr, bool bNoMatrixAtAll=false) const
bool SearchRangeForAllEmptyCells(const ScRange &rRange, const SvxSearchItem &rSearchItem, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc)
bool ReplaceStyle(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, bool bIsUndo)
bool GetCellArea(SCCOL &rEndCol, SCROW &rEndRow)
bool SearchAllStyle(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges)
bool SearchAll(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc)
bool SearchAndReplaceEmptyCells(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc)
bool ValidColRow(SCCOL nCol, SCROW nRow) const
bool SetEditText(SCCOL nCol, SCROW nRow, std::unique_ptr< EditTextObject > pEditText)
bool IsColValid(const SCCOL nScCol) const
bool SearchStyle(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark)
void ApplyStyle(SCCOL nCol, SCROW nRow, const ScStyleSheet *rStyle)
bool SearchAndReplace(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc, bool &bMatchedRangesWereClamped)
bool IsColRowValid(const SCCOL nScCol, const SCROW nScRow) const
void GetLastDataPos(SCCOL &rCol, SCROW &rRow) const
void SkipFilteredRows(SCROW &rRow, SCROW &rLastNonFilteredRow, bool bForward)
bool ReplaceAll(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges, OUString &rUndoStr, ScDocument *pUndoDoc, bool &bMatchedRangesWereClamped)
bool IsEmptyData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow) const
static void UpdateSearchItemAddressForReplace(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow)
Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
bool RowFiltered(SCROW nRow, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
bool Replace(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, OUString &rUndoStr, ScDocument *pUndoDoc)
bool ReplaceAllStyle(const SvxSearchItem &rSearchItem, const ScMarkData &rMark, ScRangeList &rMatchedRanges, ScDocument *pUndoDoc)
void ApplySelectionStyle(const ScStyleSheet &rStyle, const ScMarkData &rMark)
void GetFirstDataPos(SCCOL &rCol, SCROW &rRow) const
bool Search(const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark, OUString &rUndoStr, ScDocument *pUndoDoc)
std::unique_ptr< utl::TextSearch > pSearchText
bool ValidRow(SCROW nRow) const
bool SearchRangeForEmptyCell(const ScRange &rRange, const SvxSearchItem &rSearchItem, SCCOL &rCol, SCROW &rRow, OUString &rUndoStr)
bool SearchCell(const SvxSearchItem &rSearchItem, SCCOL nCol, sc::ColumnBlockConstPosition &rBlockPos, SCROW nRow, const ScMarkData &rMark, OUString &rUndoStr, ScDocument *pUndoDoc)
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
void SetRowDirection(bool bNewRowDirection)
bool IsSearchFormatted() const
bool GetRowDirection() const
SvxSearchCellType GetCellType() const
bool IsUseAsianOptions() const
@ ATTRIB
Internal use only (d&d undo): do not delete caption objects of cell notes.
#define SAL_WARN(area, stream)
This is very similar to ScCellValue, except that it references the original value instead of copying ...
ScFormulaCell * getFormula() const
const EditTextObject * getEditText() const
void commit(ScDocument &rDoc, const ScAddress &rPos) const
Set cell value at specified position in specified document.
TransliterationFlags transliterateFlags