21#include <com/sun/star/util/SearchResult.hpp>
24#include <osl/diagnose.h>
29#include <document.hxx>
31#include <stlsheet.hxx>
54 bool bDoSearch =
true;
67 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
69 pNote =
aCol[nCol].GetCellNote(rBlockPos, nRow);
75 aCell =
aCol[nCol].GetCellValue(rBlockPos, nRow);
84 case SvxSearchCellType::FORMULA:
92 if( !bSearchFormatted )
93 aString =
aCol[nCol].GetInputString( rBlockPos, nRow );
95 aString =
aCol[nCol].GetString( rBlockPos, nRow );
99 case SvxSearchCellType::VALUE:
104 if( !bSearchFormatted )
105 aString =
aCol[nCol].GetInputString( rBlockPos, nRow );
107 aString =
aCol[nCol].GetString( rBlockPos, nRow );
110 case SvxSearchCellType::NOTE:
119 sal_Int32 nStart = 0;
120 sal_Int32 nEnd = aString.getLength();
121 css::util::SearchResult aSearchResult;
126 sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
127 bFound =
pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
133 bFound =
pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
139 bFound = (nStart == 0 && nEnd == aString.getLength() - 1);
143 OSL_FAIL(
"pSearchText == NULL");
149 if ( rSearchItem.
GetCommand() != SvxSearchCmd::REPLACE
150 && rSearchItem.
GetCommand() != SvxSearchCmd::REPLACE_ALL )
174 aCell.
commit(*pUndoDoc, aAdr);
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();
196 OUStringBuffer aStrBuffer(aString);
197 aStrBuffer.remove(nStart, nEnd-nStart+1);
199 aString = aStrBuffer.makeStringAndClear();
210 nStart = nStart + sReplStr.getLength();
211 nEnd = aString.getLength();
217 if ( rSearchItem.
GetCommand() != SvxSearchCmd::REPLACE_ALL || nStart >= nEnd )
221 sal_Int32 nTemp=nStart; nStart=nEnd; nEnd=nTemp;
222 bRepeat =
pSearchText->SearchBackward(aString, &nStart, &nEnd, &aSearchResult);
228 bRepeat =
pSearchText->SearchForward(aString, &nStart, &nEnd, &aSearchResult);
235 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
244 if ( aString.getLength() > 2 )
246 if ( aString[ aString.getLength()-1 ] ==
'}' )
247 aString = aString.copy( 0, aString.getLength()-1 );
248 if ( aString[0] ==
'{' )
249 aString = aString.copy( 1 );
258 aCol[nCol].SetFormulaCell(nRow, pFCell);
269 aCol[nCol].InitBlockPosition( rBlockPos );
280 if (rRow <= rLastNonFilteredRow)
283 SCROW nLastRow = rRow;
290 rLastNonFilteredRow = nLastRow;
296 if (rRow >= rLastNonFilteredRow)
299 SCROW nFirstRow = rRow;
302 rRow = nFirstRow - 1;
306 rLastNonFilteredRow = nFirstRow;
315 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
319 std::vector< sc::ColumnBlockConstPosition > blockPos;
320 return Search(rSearchItem, rCol, rRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
326 std::vector< sc::ColumnBlockConstPosition >& blockPos)
329 bool bAll = (rSearchItem.
GetCommand() == SvxSearchCmd::FIND_ALL)
330 ||(rSearchItem.
GetCommand() == SvxSearchCmd::REPLACE_ALL);
335 bool bSearchNotes = (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE);
337 if (
static_cast<SCCOL>(blockPos.size()) != nLastCol + 1)
339 blockPos.resize( nLastCol + 1 );
340 for(
SCCOL i = 0;
i <= nLastCol; ++
i )
341 aCol[
i ].InitBlockPosition( blockPos[
i ] );
349 nCol = std::min(nCol, nLastCol);
350 nRow = std::min(nRow, nLastRow);
351 while (!bFound && (nRow >= 0))
356 while (!bFound && (nCol >= 0))
358 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ], nRow,
359 rMark, rUndoStr, pUndoDoc);
369 bIsEmpty = !
aCol[nCol].HasCellNotes();
371 bIsEmpty =
aCol[nCol].IsEmptyData();
376 while ((nCol >= 0) && bIsEmpty);
389 nCol = std::min(nCol, nLastCol);
390 nRow = std::min(nRow, nLastRow);
391 while (!bFound && (nCol >= 0))
393 while (!bFound && (nRow >= 0))
398 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ],
399 nRow, rMark, rUndoStr, pUndoDoc);
409 if (!
aCol[nCol].GetPrevDataPos(nRow))
426 bIsEmpty = !
aCol[nCol].HasCellNotes();
428 bIsEmpty =
aCol[nCol].IsEmptyData();
433 while ((nCol >= 0) && bIsEmpty);
440 SCROW nLastNonFilteredRow = -1;
444 while (!bFound && (nRow <= nLastRow))
449 while (!bFound && (nCol <= nLastCol))
451 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ],
452 nRow, rMark, rUndoStr, pUndoDoc);
456 while ((nCol <= nLastCol) &&
471 while (!bFound && (nCol <= nLastCol))
473 while (!bFound && (nRow <= nLastRow))
481 assert(nCol >= 0 &&
"negative nCol for ColDirection");
483 bFound =
SearchCell(rSearchItem, nCol, blockPos[ nCol ],
484 nRow, rMark, rUndoStr, pUndoDoc);
494 if (!
aCol[nCol].GetNextDataPos(nRow))
503 nLastNonFilteredRow = -1;
505 while ((nCol <= nLastCol) &&
526 bool bEverFound =
false;
530 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
535 std::vector< sc::ColumnBlockConstPosition > blockPos;
538 bFound =
Search(rSearchItem, nCol, nRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
575 bool bFound =
Search(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
586 OUString& rUndoStr,
ScDocument* pUndoDoc,
bool& bMatchedRangesWereClamped)
593 if (rSearchItem.
GetCellType() == SvxSearchCellType::NOTE)
602 std::vector< sc::ColumnBlockConstPosition > blockPos;
603 bool bEverFound =
false;
606 bool bFound =
Search(aCopyItem, nCol, nRow, nLastCol, nLastRow, rMark, rUndoStr, pUndoDoc, blockPos);
613 if (rMatchedRanges.
size() < 1000)
616 bMatchedRangesWereClamped =
true;
638 short nAdd = bBack ? -1 : 1;
644 SAL_WARN(
"sc.core",
"SearchStyle: bad column " << nCol);
650 SCROW nNextRow =
aCol[nCol].SearchStyle( nRow, pSearchStyle, bBack, bSelect, rMark );
654 nCol = sal::static_int_cast<SCCOL>( nCol + nAdd );
667 std::vector< SCROW > nNextRows ( aColSize );
669 for (
i=0;
i < aColSize; ++
i)
674 if (
i>=nCol) --nSRow;
678 if (
i<=nCol) ++nSRow;
680 nNextRows[
i] =
aCol[
i].SearchStyle( nSRow, pSearchStyle, bBack, bSelect, rMark );
685 for (
i = aColSize - 1;
i>=0; --
i)
686 if (nNextRows[
i]>nRow)
696 for (
i=0;
i < aColSize; ++
i)
697 if (nNextRows[
i]<nRow)
723 bRet =
SearchStyle(rSearchItem, rCol, rRow, rMark);
734 OSL_FAIL(
"pReplaceStyle==0");
749 bool bEverFound =
false;
758 bFound =
aCol[
i].SearchStyleRange( nRow, nEndRow, pSearchStyle, bBack, bSelect, rMark );
762 std::swap( nRow, nEndRow );
793 OSL_FAIL(
"pReplaceStyle==0");
802 ScRangeList& rMatchedRanges, OUString& rUndoStr,
ScDocument* pUndoDoc,
bool& bMatchedRangesWereClamped)
807 ((nCommand == SvxSearchCmd::FIND || nCommand == SvxSearchCmd::REPLACE) &&
808 (((rCol ==
GetDoc().GetMaxColCount() || rCol == -1) &&
ValidRow(rRow)) ||
809 ((rRow ==
GetDoc().GetMaxRowCount() || rRow == -1) &&
ValidCol(rCol))
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)
823 else if (nCommand == SvxSearchCmd::REPLACE_ALL)
824 bFound =
ReplaceAllStyle(rSearchItem, rMark, rMatchedRanges, pUndoDoc);
842 TransliterationFlags::IGNORE_CASE |
843 TransliterationFlags::IGNORE_WIDTH;
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);
866 SCCOL nColStart, nColEnd;
867 SCROW nRowStart, nRowEnd;
882 for (
size_t i = 0,
n = aMarkedRanges.
size();
i <
n; ++
i )
884 ScRange & rRange = aMarkedRanges[
i ];
895 if (rRange.
aEnd.
Col() > nColEnd)
897 if (rRange.
aEnd.
Row() > nRowEnd)
902 aRanges = aNewRanges;
906 if (nCommand == SvxSearchCmd::FIND || nCommand == SvxSearchCmd::REPLACE)
910 for (
size_t i = aRanges.
size();
i > 0; --
i )
912 const ScRange & rRange = aRanges[
i - 1 ];
919 for (
size_t i = 0, nListSize = aRanges.
size();
i < nListSize; ++
i )
921 const ScRange & rRange = aRanges[
i ];
927 else if (nCommand == SvxSearchCmd::FIND_ALL || nCommand == SvxSearchCmd::REPLACE_ALL)
930 for (
size_t i = 0, nListSize = aRanges.
size();
i < nListSize; ++
i )
932 ScRange const & rRange = aRanges[
i ];
942bool lcl_maybeReplaceCellString(
951 if (rSearchItem.
GetCommand() == SvxSearchCmd::REPLACE &&
986 if (nRow == rRow && nBeginCol >= rCol)
988 nBeginCol = rCol - (nCmd == SvxSearchCmd::FIND ? 1 : 0);
992 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1001 for (
SCCOL nCol = nBeginCol; nCol >= rRange.
aStart.
Col(); --nCol)
1005 if (nCol == rCol && nBeginRow >= rRow)
1007 nBeginRow = rRow - (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1008 for (
SCROW nRow = nBeginRow; nRow >= rRange.
aStart.
Row(); --nRow)
1015 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1027 SCROW nLastNonFilteredRow = -1;
1029 for (
SCROW nRow = nBeginRow; nRow <= rRange.
aEnd.
Row(); ++nRow)
1037 if (nRow == rRow && nBeginCol <= rCol)
1039 nBeginCol = rCol + (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1040 for (
SCCOL nCol = nBeginCol; nCol <= rRange.
aEnd.
Col(); ++nCol)
1042 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1051 for (
SCCOL nCol = nBeginCol; nCol <= rRange.
aEnd.
Col(); ++nCol)
1053 SCROW nLastNonFilteredRow = -1;
1055 if (nCol == rCol && nBeginRow <= rRow)
1057 nBeginRow = rRow + (nCmd == SvxSearchCmd::FIND ? 1 : 0);
1058 for (
SCROW nRow = nBeginRow; nRow <= rRange.
aEnd.
Row(); ++nRow)
1065 if (lcl_maybeReplaceCellString(
aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
1078 bool bFound =
false;
1079 bool bReplace = (rSearchItem.
GetCommand() == SvxSearchCmd::REPLACE_ALL) &&
1085 SCROW nLastNonFilteredRow = -1;
1093 const bool bFiltered =
RowFiltered(nRow,
nullptr, &nLastRow);
1094 if (nLastRow > nEndRow)
1102 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
1104 aCol[nCol].SetRawString(
i, rNewStr);
OUString GetText(LineEnd eEnd=LINEEND_LF) const
std::unique_ptr< EditTextObject > CreateTextObject()
void SetText(const OUString &rStr)
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.
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 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