14#include <document.hxx>
25#include <tokenarray.hxx>
30#include <compiler.hxx>
34#include <broadcast.hxx>
50 sc::CellStoreType::const_position_type aPos =
maCells.position(nRow1);
51 sc::CellStoreType::const_iterator it = aPos.first;
52 size_t nOffset = aPos.second;
56 for (; it !=
maCells.end() && nRow <= nRow2; ++it)
62 size_t nSize = it->size - nOffset;
64 SCROW nLastRow = nRow + nSize - 1;
67 nSize -= nLastRow - nRow2;
88 nRow += it->size - nOffset;
118 for (
const auto& rRange : xResult->aFormulaRanges)
156 SCROW nClipRowLen = nClipRow2 - nClipRow1 + 1;
160 aSpanSet.
scan(rClipCol, nClipRow1, nClipRow2);
169 std::vector<sc::RowSpan> aDestSpans;
171 bool bContinue =
true;
176 SCROW nDestRow1 = r.mnRow1 + nDestOffset;
177 SCROW nDestRow2 = r.mnRow2 + nDestOffset;
179 if (nDestRow1 > aRange.
mnRow2)
186 if (nDestRow2 > aRange.
mnRow2)
189 nDestRow2 = aRange.
mnRow2;
193 aDestSpans.emplace_back(nDestRow1, nDestRow2);
199 nDestOffset += nClipRowLen;
202 for (
const auto& rDestSpan : aDestSpans)
204 SCROW nRow1 = rDestSpan.mnRow1;
205 SCROW nRow2 = rDestSpan.mnRow2;
209 auto xResult =
DeleteCells(*pBlockPos, nRow1, nRow2, nDelFlag);
212 for (
const auto& rRange : xResult->aFormulaRanges)
249 assert(nRow1 <= nRow2);
251 size_t nDestSize = nRow2 - nRow1 + 1;
271 pAttrArray->SetPatternArea(nRow1, nRow2, pAttr,
true);
277 std::vector<sc::CellTextAttr> aTextAttrs(nDestSize, rSrcAttr);
283 std::vector<double> aVals(nDestSize, rSrcCell.
getDouble());
300 std::vector<svl::SharedString> aStrs(nDestSize,
aStr);
310 std::vector<EditTextObject*> aStrs;
311 aStrs.reserve(nDestSize);
312 for (
size_t i = 0;
i < nDestSize; ++
i)
324 std::vector<sc::RowSpan> aRanges;
326 aRanges.emplace_back(nRow1, nRow2);
348 std::vector<ScPostIt*> aNotes;
349 aNotes.reserve(nDestSize);
350 for (
size_t i = 0;
i < nDestSize; ++
i)
353 aNotes.push_back(pNote->
Clone(aSrcPos, rDocument, aDestPosition, bCloneCaption).release());
359 pBlockPos->
miCellNotePos, nRow1, aNotes.begin(), aNotes.end());
362 aDestPosition.
SetRow(nRow1);
363 for (
size_t i = 0;
i < nDestSize; ++
i)
371 size_t nColOffset,
size_t nDestSize,
ScAddress aDestPosition)
379 auto const& pSparklineGroup = pSparkline->getSparklineGroup();
382 if (!pDuplicatedGroup)
383 pDuplicatedGroup = std::make_shared<sc::SparklineGroup>(*pSparklineGroup);
385 std::vector<sc::SparklineCell*> aSparklines(nDestSize,
nullptr);
386 ScAddress aCurrentPosition = aDestPosition;
387 for (
size_t i = 0;
i < nDestSize; ++
i)
389 auto pNewSparkline = std::make_shared<sc::Sparkline>(aCurrentPosition.
Col(), aCurrentPosition.
Row(), pDuplicatedGroup);
390 pNewSparkline->setInputRange(pSparkline->getInputRange());
392 aCurrentPosition.
IncRow();
404 SCROW nLastRow = nRow + rVals.size() - 1;
405 if (nLastRow >
GetDoc().MaxRow())
409 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
410 std::vector<SCROW> aNewSharedRows;
413 maCells.set(nRow, rVals.begin(), rVals.end());
414 std::vector<sc::CellTextAttr> aDefaults(rVals.size());
421 std::vector<SCROW> aRows;
422 aRows.reserve(rVals.size());
423 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
434 SCROW nLastRow = nRow + nLen - 1;
435 if (nLastRow >
GetDoc().MaxRow())
439 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
446 std::vector<SCROW> aRows;
448 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
460 if (nLastRow >
GetDoc().MaxRow())
464 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
471 std::vector<SCROW> aRows;
472 aRows.reserve(rSrc.
size());
473 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
481class ConvertFormulaToValueHandler
488 ConvertFormulaToValueHandler(
ScDocument& rDoc) :
507 maResValues.
setValue(nRow, std::move(pObj));
523 bool isModified()
const {
return mbModified; }
536 std::vector<SCROW> aBounds { nRow1 };
537 if (nRow2 <
GetDoc().MaxRow()-1)
538 aBounds.push_back(nRow2+1);
544 ConvertFormulaToValueHandler aFunc(
GetDoc());
546 if (!aFunc.isModified())
554 aFunc.getResValues().swap(aUndoCells);
562class StartListeningHandler
576class EndListeningHandler
596 std::vector<SCROW> aBounds { rRange.
aStart.
Row() };
598 aBounds.push_back(rRange.
aEnd.
Row()+1);
605 EndListeningHandler aEndLisFunc(rEndCxt);
606 sc::CellStoreType::iterator itPos =
maCells.begin();
607 for (
const auto& rSpan : aSpans)
609 SCROW nRow1 = rSpan.mnRow1;
610 SCROW nRow2 = rSpan.mnRow2;
618 StartListeningHandler aStartLisFunc(rStartCxt);
620 for (
const auto& rSpan : aSpans)
622 SCROW nRow1 = rSpan.mnRow1;
623 SCROW nRow2 = rSpan.mnRow2;
632 for (
const auto& rSpan : rRanges)
633 DeleteArea(rSpan.mnRow1, rSpan.mnRow2, nDelFlag,
false);
639 const std::vector<sc::RowSpan>& rRanges )
641 SCCOL nMatrixCols = 0;
642 SCROW nMatrixRows = 0;
647 SAL_WARN_IF( nMatrixCols != 1 || nMatrixRows != 1,
"sc.core",
648 "ScColumn::CloneFormulaCell - cloning array/matrix with not exactly one column or row as single cell");
652 std::vector<ScFormulaCell*> aFormulas;
653 for (
const auto& rSpan : rRanges)
655 SCROW nRow1 = rSpan.mnRow1, nRow2 = rSpan.mnRow2;
656 size_t nLen = nRow2 - nRow1 + 1;
659 aFormulas.reserve(nLen);
667 for (
size_t i = 0;
i < nLen; ++
i, aPos.
IncRow())
670 aFormulas.push_back(pCell);
677 xGroup->setCode(*rSrc.
GetCode());
678 xGroup->compileCode(rDocument, aPos, rDocument.
GetGrammar());
679 for (
size_t i = 0;
i < nLen; ++
i, aPos.
IncRow())
686 xGroup->mpTopCell = pCell;
687 xGroup->mnLength = nLen;
689 aFormulas.push_back(pCell);
696 sc::CellStoreType::position_type aPosObj =
maCells.position(rBlockPos.
miCellPos, nRow1);
699 ScFormulaCell* pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
702 aPosObj =
maCells.position(aPosObj.first, nRow2);
704 pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
707 std::vector<sc::CellTextAttr> aTextAttrs(nLen, rAttr);
717 const std::vector<sc::RowSpan>& rRanges )
731 return std::unique_ptr<ScPostIt>(
p);
737 [](
const size_t& rCount,
const auto& rCellNote) {
738 if (rCellNote.type != sc::element_type_cellnote)
740 return rCount + rCellNote.size;
746class NoteCaptionCreator
750 NoteCaptionCreator(
SCTAB nTab,
SCCOL nCol ) : maPos(nCol,0,nTab) {}
752 void operator() (
size_t nRow,
const ScPostIt* p )
755 p->GetOrCreateCaption(maPos);
759class NoteCaptionCleaner
763 explicit NoteCaptionCleaner(
bool bPreserveData ) : mbPreserveData(bPreserveData) {}
765 void operator() (
size_t ,
ScPostIt* p )
767 p->ForgetCaption(mbPreserveData);
775 NoteCaptionCreator aFunc(
nTab,
nCol);
787 NoteCaptionCleaner aFunc(bPreserveData);
788 sc::CellNoteStoreType::iterator it =
maCellNotes.begin();
807 return rCellNote.position + nOffset;
818class NoteEntryCollector
820 std::vector<sc::NoteEntry>& mrNotes;
826 NoteEntryCollector( std::vector<sc::NoteEntry>& rNotes,
SCTAB nTab,
SCCOL nCol,
828 mrNotes(rNotes), mnTab(nTab),
mnCol(nCol),
829 mnStartRow(nStartRow), mnEndRow(nEndRow) {}
831 void operator() (
const sc::CellNoteStoreType::value_type& node)
const
836 size_t nTopRow = node.position;
837 sc::cellnote_block::const_iterator it = sc::cellnote_block::begin(*node.data);
838 sc::cellnote_block::const_iterator itEnd = sc::cellnote_block::end(*node.data);
842 std::advance(it, mnStartRow - nTopRow);
843 nOffset = mnStartRow - nTopRow;
850 mrNotes.emplace_back(aPos, *it);
863 std::vector<sc::NoteEntry>& rNotes )
const
865 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aPos =
maCellNotes.position(nStartRow);
866 sc::CellNoteStoreType::const_iterator it = aPos.first;
871 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aEndPos =
873 sc::CellNoteStoreType::const_iterator itEnd = aEndPos.first;
875 std::for_each(it, ++itEnd, NoteEntryCollector(rNotes,
nTab,
nCol, nStartRow, nEndRow));
880 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aStartPos =
886 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aEndPos =
889 for (sc::CellNoteStoreType::const_iterator it = aStartPos.first; it != aEndPos.first; ++it)
893 size_t nTopRow = it->position;
894 sc::cellnote_block::const_iterator blockIt = sc::cellnote_block::begin(*(it->data));
895 sc::cellnote_block::const_iterator blockItEnd = sc::cellnote_block::end(*(it->data));
899 std::advance(blockIt, nStartRow - nTopRow);
900 nOffset = nStartRow - nTopRow;
912 SCROW nTmpStartRow = nStartRow, nTmpEndRow = nEndRow;
918 if (nTmpStartRow < nStartRow)
919 nTmpStartRow = nStartRow;
920 if (nTmpEndRow > nEndRow)
921 nTmpEndRow = nEndRow;
924 while (nEndRow > nTmpEndRow)
926 nStartRow = nTmpEndRow + 1;
927 pPattern =
pAttrArray->GetPatternRange(nTmpStartRow, nTmpEndRow, nStartRow);
934 if (nTmpEndRow > nEndRow)
935 nTmpEndRow = nEndRow;
943class RecompileByOpcodeHandler
951 RecompileByOpcodeHandler(
956 mrEndListenCxt(rEndListenCxt),
957 mrCompileFormulaCxt(rCompileCxt) {}
981 OUString aFormula = pTop->
GetFormula(mrCompileFormulaCxt);
982 sal_Int32
n = aFormula.getLength();
985 if (aFormula[0] ==
'{' && aFormula[n-1] ==
'}')
986 aFormula = aFormula.copy(1, n-2);
993 for (; pp != ppEnd; ++pp)
996 p->EndListeningTo(mrEndListenCxt);
1011class CompileHybridFormulaHandler
1020 mrStartListenCxt(rStartListenCxt),
1021 mrCompileFormulaCxt(rCompileCxt) {}
1030 if (!aFormula.isEmpty())
1035 std::unique_ptr<ScTokenArray> pNewCode = aComp.CompileString(aFormula);
1038 xGroup->setCode(std::move(*pNewCode));
1044 for (; pp != ppEnd; ++pp)
1047 p->SyncSharedCode();
1048 p->StartListeningTo(mrStartListenCxt);
1058 if (!aFormula.isEmpty())
1062 std::unique_ptr<ScTokenArray> pNewCode = aComp.CompileString(aFormula);
1067 aComp2.CompileTokenArray();
1069 pCell->
SetCode(std::move(pNewCode));
1089 RecompileByOpcodeHandler aFunc(&
GetDoc(), aOps, rEndListenCxt, rCompileCxt);
1090 std::for_each(aGroups.begin(), aGroups.end(), aFunc);
1104 RecompileByOpcodeHandler aFunc(&
GetDoc(), aOps, rEndListenCxt, rCompileCxt);
1105 std::for_each(aGroups.begin(), aGroups.end(), aFunc);
1114 CompileHybridFormulaHandler aFunc(
GetDoc(), rStartListenCxt, rCompileCxt);
1115 std::for_each(aGroups.begin(), aGroups.end(), aFunc);
1120class ScriptTypeUpdater
1124 sc::CellTextAttrStoreType::iterator miPosAttr;
1133 sc::CellTextAttrStoreType::position_type aAttrPos = mrTextAttrs.position(miPosAttr, nRow);
1134 miPosAttr = aAttrPos.first;
1139 sc::CellTextAttr& rAttr = sc::celltextattr_block::at(*aAttrPos.first->data, aAttrPos.second);
1158 const Color* pColor;
1167 explicit ScriptTypeUpdater(
ScColumn& rCol ) :
1169 mrTextAttrs(rCol.GetCellAttrStore()),
1170 miPosAttr(mrTextAttrs.
begin()),
1171 mpCFList(rCol.GetDoc().GetCondFormList(rCol.GetTab())),
1172 mpFormatter(rCol.GetDoc().GetFormatTable()),
1173 maPos(rCol.GetCol(), 0, rCol.GetTab()),
1177 void operator() (
size_t nRow,
double fVal )
1180 updateScriptType(nRow, aCell);
1186 updateScriptType(nRow, aCell);
1192 updateScriptType(nRow, aCell);
1198 updateScriptType(nRow, aCell);
1201 bool isUpdated()
const {
return mbUpdated; }
1211 ScriptTypeUpdater aFunc(*
this);
1213 if (aFunc.isUpdated())
1228 std::map<SCROW, std::vector<SdrObject*>> aThisColRowDrawObjects
1230 std::map<SCROW, std::vector<SdrObject*>> aOtherColRowDrawObjects
1232 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
1234 std::vector<SdrObject*>& rThisCellDrawObjects = aThisColRowDrawObjects[nRow];
1235 if (!rThisCellDrawObjects.empty())
1237 std::vector<SdrObject*>& rOtherCellDrawObjects = aOtherColRowDrawObjects[nRow];
1238 if (!rOtherCellDrawObjects.empty())
1245 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
1265class FormulaColPosSetter
1270 FormulaColPosSetter(
SCCOL nCol,
bool bUpdateRefs ) :
mnCol(nCol), mbUpdateRefs(bUpdateRefs) {}
1298 FormulaColPosSetter aFunc(
nCol, bUpdateRefs);
1304class RelativeRefBoundChecker
1310 explicit RelativeRefBoundChecker(
const ScRange& rBoundRange ) :
1311 maBoundRange(rBoundRange) {}
1322 void swapBounds( std::vector<SCROW>& rBounds )
1324 rBounds.swap(maBounds);
1336 std::vector<SCROW> aBounds;
1339 aBounds.push_back(rBoundRange.
aStart.
Row());
1341 aBounds.push_back(rBoundRange.
aEnd.
Row()+1);
1344 RelativeRefBoundChecker aFunc(rBoundRange);
1347 aFunc.swapBounds(aBounds);
1353class ListenerCollector
1355 std::vector<SvtListener*>& mrListeners;
1357 explicit ListenerCollector( std::vector<SvtListener*>& rListener ) :
1358 mrListeners(rListener) {}
1363 mrListeners.insert(mrListeners.end(), rLis.begin(), rLis.end());
1367class FormulaCellCollector
1369 std::vector<ScFormulaCell*>&
mrCells;
1371 explicit FormulaCellCollector( std::vector<ScFormulaCell*>& rCells ) :
mrCells(rCells) {}
1386 ListenerCollector aFunc(rListeners);
1395 FormulaCellCollector aFunc(rCells);
1406struct FindAnyFormula
1424 if (nRow1 == 0 && nRow2 ==
GetDoc().MaxRow())
1427 FindAnyFormula aFunc;
1428 std::pair<sc::CellStoreType::const_iterator, size_t> aRet =
1431 return aRet.first !=
maCells.end();
1438 for (; pp != ppEnd; ++pp)
1445class StartListeningFormulaCellsHandler
1455 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize )
1461 mnStartRow = node.position + nOffset;
1463 ScFormulaCell** ppBeg = &sc::formula_block::at(*node.data, nOffset);
1476 if (nBackTrackSize > 0)
1479 for (
SCROW i = 0;
i < nBackTrackSize; ++
i)
1482 mnStartRow -= nBackTrackSize;
1486 for (; pp != ppEnd; ++pp)
1501 if (nEndGroupPos > nDataSize)
1503 size_t nExcessSize = nEndGroupPos - nDataSize;
1506 endListening(
mrEndCxt, ppGrp, ppGrpEnd);
1523class EndListeningFormulaCellsHandler
1531 mrEndCxt(rEndCxt), mnStartRow(-1), mnEndRow(-1) {}
1533 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize )
1539 mnStartRow = node.position + nOffset;
1541 ScFormulaCell** ppBeg = &sc::formula_block::at(*node.data, nOffset);
1553 if (nBackTrackSize > 0)
1556 for (
SCROW i = 0;
i < nBackTrackSize; ++
i)
1558 mnStartRow -= nBackTrackSize;
1562 for (; pp != ppEnd; ++pp)
1574 mnEndRow = node.position + nOffset + nEndGroupPos - 1;
1577 endListening(
mrEndCxt, pp, ppGrpEnd);
1579 if (nEndGroupPos > nDataSize)
1593 SCROW getStartRow()
const
1598 SCROW getEndRow()
const
1613 StartListeningFormulaCellsHandler aFunc(rStartCxt, rEndCxt);
1624 EndListeningFormulaCellsHandler aFunc(rCxt);
1628 *pStartRow = aFunc.getStartRow();
1631 *pEndRow = aFunc.getEndRow();
1640 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
1641 sc::CellStoreType::iterator it = aPos.first;
1646 ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
1659 pGroupPos->push_back(xGroup->mpTopCell->aPos);
1662 if (nRow < nGrpLastRow)
1672 sc::CellStoreType::position_type aPos =
maCells.position(nRow1);
1673 sc::CellStoreType::iterator it = aPos.first;
1676 ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
1686 pGroupPos->push_back(xGroup->mpTopCell->aPos);
1690 aPos =
maCells.position(it, nRow2);
1695 ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
1707 ScAddress aPosLast = xGroup->mpTopCell->aPos;
1708 aPosLast.
IncRow(xGroup->mnLength-1);
1709 pGroupPos->push_back(aPosLast);
1715 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
1720 ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
1726 (*pp)->EndListeningTo(rCxt);
1731 SCROW nTopDelta = (*pp)->aPos.Row() - xGroup->mpTopCell->aPos.Row();
1732 assert(nTopDelta >= 0);
1737 assert(*pp == xGroup->mpTopCell);
1739 for (; pp != ppEnd; ++pp)
1745 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
1750 ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
1756 (*pp)->SetNeedsListening(
true);
1761 SCROW nTopDelta = (*pp)->aPos.Row() - xGroup->mpTopCell->aPos.Row();
1762 assert(nTopDelta >= 0);
1767 assert(*pp == xGroup->mpTopCell);
1769 for (; pp != ppEnd; ++pp)
1784 bAllowThreading =
true;
1786 SCROW nSpanStart = -1;
1787 SCROW nSpanEnd = -1;
1788 sc::formula_block::const_iterator itSpanStart;
1789 bool bAnyDirty =
false;
1790 for (
SCROW nFGOffset = nStartOffset; nFGOffset <= nEndOffset; ++rSpanIter, ++nFGOffset)
1793 if (!pCellStart && bThisDirty)
1795 pCellStart = *rSpanIter;
1796 itSpanStart = rSpanIter;
1797 nSpanStart = nFGOffset;
1801 if (pCellStart && (!bThisDirty || nFGOffset == nEndOffset))
1803 nSpanEnd = bThisDirty ? nFGOffset : nFGOffset - 1;
1804 assert(nSpanStart >= nStartOffset && nSpanStart <= nSpanEnd && nSpanEnd <= nEndOffset);
1807 bool bGroupInterpreted = pCellStart->
Interpret(nSpanStart, nSpanEnd);
1809 if (bGroupInterpreted)
1810 for (
SCROW nIdx = nSpanStart; nIdx <= nSpanEnd; ++nIdx, ++itSpanStart)
1811 assert(!(*itSpanStart)->NeedsInterpret());
1820 if ((mxParentGroup && mxParentGroup->mbPartOfCycle) || !rRecursionHelper.
AreGroupsIndependent())
1822 bAllowThreading =
false;
1826 if (!bGroupInterpreted)
1830 for (
SCROW nIdx = nSpanStart+1; nIdx <= nSpanEnd; ++nIdx, ++itSpanStart)
1832 (*itSpanStart)->Interpret();
1833 if ((*itSpanStart)->NeedsInterpret())
1835 SAL_WARN(
"sc.core.formulagroup",
"Internal error, cell " << (*itSpanStart)->aPos
1836 <<
" failed running Interpret(), not allowing threading");
1837 bAllowThreading =
false;
1842 if ((mxParentGroup && mxParentGroup->mbPartOfCycle) || !rRecursionHelper.
AreGroupsIndependent())
1846 bAllowThreading =
false;
1852 pCellStart =
nullptr;
1861 bool& bIsDirty,
bool& bAllowThreading)
1864 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = rCells.position(nRow1);
1865 sc::CellStoreType::const_iterator it = aPos.first;
1866 size_t nOffset = aPos.second;
1871 for (;it != rCells.end() && nRow <= nRow2; ++it, nOffset = 0)
1878 if (bThreadingDepEval)
1880 bAllowThreading =
false;
1886 size_t nRowsToRead = nRow2 - nRow + 1;
1887 const size_t nEnd = std::min(it->size, nOffset+nRowsToRead);
1888 sc::formula_block::const_iterator itCell = sc::formula_block::begin(*it->data);
1889 std::advance(itCell, nOffset);
1892 size_t nCellIdx = nOffset;
1893 while (nCellIdx < nEnd)
1896 ScFormulaCell* pChildTopCell = mxGroupChild ? mxGroupChild->mpTopCell : *itCell;
1904 bAllowThreading =
false;
1908 if (bSkipRunning && (*itCell)->IsRunning())
1920 const SCROW nFGStartOffset = (*itCell)->aPos.Row() - pChildTopCell->
aPos.
Row();
1921 const SCROW nFGEndOffset = std::min(nFGStartOffset +
static_cast<SCROW>(nRowsToRead) - 1, mxGroupChild->mnLength - 1);
1922 assert(nFGEndOffset >= nFGStartOffset);
1923 const SCROW nSpanLen = nFGEndOffset - nFGStartOffset + 1;
1927 bool bAnyDirtyInSpan =
lcl_InterpretSpan(itCell, nFGStartOffset, nFGEndOffset, mxGroup, bAllowThreading, rDoc);
1928 if (!bAllowThreading)
1931 bIsDirty = bIsDirty || bAnyDirtyInSpan;
1935 nCellIdx += nSpanLen;
1937 nRowsToRead -= nSpanLen;
1942 bool bDirtyFlag =
false;
1943 if( (*itCell)->NeedsInterpret())
1946 (*itCell)->Interpret();
1947 if ((*itCell)->NeedsInterpret())
1949 SAL_WARN(
"sc.core.formulagroup",
"Internal error, cell " << (*itCell)->aPos
1950 <<
" failed running Interpret(), not allowing threading");
1951 bAllowThreading =
false;
1955 bIsDirty = bIsDirty || bDirtyFlag;
1962 if (bThreadingDepEval && mxGroup &&
1966 (*itCell)->SetDirtyVar();
1967 bAllowThreading =
false;
1982 nRow += it->size - nOffset;
1987 if (bThreadingDepEval)
1988 bAllowThreading =
true;
2001 bool bAnyDirty =
false, bTmp =
false;
2011 bool bAllowThreading =
true, bTmp =
false;
2014 return bAllowThreading;
2019class StoreToCacheFunc
2029 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize )
2031 SCROW nStartRow = node.position + nOffset;
2044 sc::numeric_block::const_iterator it = sc::numeric_block::begin(*node.data);
2045 std::advance(it, nOffset);
2046 sc::numeric_block::const_iterator itEnd = it;
2047 std::advance(itEnd, nDataSize);
2049 for (; it != itEnd; ++it)
2058 sc::string_block::const_iterator it = sc::string_block::begin(*node.data);
2059 std::advance(it, nOffset);
2060 sc::string_block::const_iterator itEnd = it;
2061 std::advance(itEnd, nDataSize);
2063 for (; it != itEnd; ++it)
2066 sal_Int32 nStrLength =
aStr.getLength();
2075 sc::formula_block::const_iterator it = sc::formula_block::begin(*node.data);
2076 std::advance(it, nOffset);
2077 sc::formula_block::const_iterator itEnd = it;
2078 std::advance(itEnd, nDataSize);
2080 for (; it != itEnd; )
2085 sal_uInt64 nGroupLength = 0;
2088 nGroupLength = xCellGroup->mnLength;
2099 std::advance(it, nGroupLength);
2115 StoreToCacheFunc aFunc(
rStrm);
2121 sal_uInt64 nStoredCol = 0;
2123 if (nStoredCol !=
static_cast<sal_uInt64
>(
nCol))
2124 throw std::exception();
2126 sal_uInt64 nLastRow = 0;
2128 sal_uInt64 nReadRow = 0;
2130 while (nReadRow < nLastRow)
2132 sal_uInt64 nStartRow = 0;
2133 sal_uInt64 nDataSize = 0;
2142 maCells.set_empty(nStartRow, nDataSize);
2147 std::vector<double> aValues(nDataSize);
2148 for (
auto& rValue : aValues)
2152 maCells.set(nStartRow, aValues.begin(), aValues.end());
2157 std::vector<svl::SharedString> aStrings(nDataSize);
2159 for (
auto& rString : aStrings)
2161 sal_Int32 nStrLength = 0;
2163 std::unique_ptr<char[]> pStr(
new char[nStrLength]);
2165 std::string_view aOStr(pStr.get(), nStrLength);
2166 OUString
aStr = OStringToOUString(aOStr, RTL_TEXTENCODING_UTF8);
2169 maCells.set(nStartRow, aStrings.begin(), aStrings.end());
2175 std::vector<ScFormulaCell*> aFormulaCells(nDataSize);
2179 for (
SCROW nRow = 0; nRow < static_cast<SCROW>(nDataSize);)
2181 sal_uInt64 nFormulaGroupSize = 0;
2183 sal_Int32 nStrLength = 0;
2185 std::unique_ptr<char[]> pStr(
new char[nStrLength]);
2187 std::string_view aOStr(pStr.get(), nStrLength);
2188 OUString
aStr = OStringToOUString(aOStr, RTL_TEXTENCODING_UTF8);
2189 for (sal_uInt64
i = 0;
i < nFormulaGroupSize; ++
i)
2195 nRow += nFormulaGroupSize;
2198 maCells.set(nStartRow, aFormulaCells.begin(), aFormulaCells.end());
2203 nReadRow += nDataSize;
2211 if (pColTest !=
this)
2213 std::ostringstream os;
2214 os <<
"cell store's event handler references wrong column instance (this=" <<
this
2215 <<
"; stored=" << pColTest <<
")";
2216 throw std::runtime_error(os.str());
2220 [](
const auto& blk) { return blk.type == sc::element_type_formula; }
2225 std::ostringstream os;
2226 os <<
"incorrect cached formula block count (expected=" <<
nCount <<
"; actual="
2228 throw std::runtime_error(os.str());
2239 auto itBeg = sc::broadcaster_block::begin(*block.data);
2240 auto itEnd = sc::broadcaster_block::end(*block.data);
2242 for (
auto it = itBeg; it != itEnd; ++it)
2247 auto& rLisStore = aRes.first->second;
2254 rLisStore.emplace_back(pFC);
2256 rLisStore.emplace_back(pLis);
bool ValidRow(SCROW nRow, SCROW nMaxRow)
::basegfx::B2DRectangle maBounds
virtual std::unique_ptr< EditTextObject > Clone() const=0
void IncRow(SCROW nDelta=1)
std::unique_ptr< ScAttrArray > pAttrArray
void ApplyPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr &rPatAttr, ScEditDataArray *pDataArray=nullptr, bool *const pIsChanged=nullptr)
void DeleteCellNotes(sc::ColumnBlockPosition &rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership)
void CollectFormulaCells(std::vector< ScFormulaCell * > &rCells, SCROW nRow1, SCROW nRow2)
void CellStorageModified()
Called whenever the state of cell array gets modified i.e.
void DeleteBeforeCopyFromClip(sc::CopyFromClipContext &rCxt, const ScColumn &rClipCol, sc::ColumnSpanSet &rBroadcastSpans)
SCROW GetNotePosition(size_t nIndex) const
bool HasCellNote(SCROW nStartRow, SCROW nEndRow) const
void PreprocessDBDataUpdate(sc::EndListeningContext &rEndListenCxt, sc::CompileFormulaContext &rCompileCxt)
sc::CellTextAttrStoreType maCellTextAttrs
void GetAllNoteEntries(std::vector< sc::NoteEntry > &rNotes) const
bool HasFormulaCell() const
void EndListeningGroup(sc::EndListeningContext &rCxt, SCROW nRow)
const ScPatternAttr * GetPattern(SCROW nRow) const
void SplitFormulaGroupByRelativeRef(const ScRange &rBoundRange)
void PreprocessRangeNameUpdate(sc::EndListeningContext &rEndListenCxt, sc::CompileFormulaContext &rCompileCxt)
void TransferCellValuesTo(SCROW nRow, size_t nLen, sc::CellValues &rDest)
void GetUnprotectedCells(SCROW nStartRow, SCROW nEndRow, ScRangeList &rRangeList) const
void RegroupFormulaCells(std::vector< ScAddress > *pGroupPos=nullptr)
Regroup formula cells for the entire column.
void CloneFormulaCell(sc::ColumnBlockPosition &rBlockPos, const ScFormulaCell &rSrc, const sc::CellTextAttr &rAttr, const std::vector< sc::RowSpan > &rRanges)
void UpdateDrawObjectsForRow(std::vector< SdrObject * > &pObjects, SCCOL nTargetCol, SCROW nTargetRow)
void CollectListeners(std::vector< SvtListener * > &rListeners, SCROW nRow1, SCROW nRow2)
void BroadcastCells(const std::vector< SCROW > &rRows, SfxHintId nHint)
void CheckIntegrity() const
void DeleteRanges(const std::vector< sc::RowSpan > &rRanges, InsertDeleteFlags nDelFlag)
void RestoreFromCache(SvStream &rStrm)
void InitBlockPosition(sc::ColumnBlockPosition &rBlockPos)
std::vector< sc::FormulaGroupEntry > GetFormulaGroupEntries()
Get all non-grouped formula cells and formula cell groups in the whole column.
void ConvertFormulaToValue(sc::EndListeningContext &rCxt, SCROW nRow1, SCROW nRow2, sc::TableValues *pUndo)
std::unique_ptr< DeleteCellsResult > DeleteCells(sc::ColumnBlockPosition &rBlockPos, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nDelFlag)
void RemoveEditAttribs(sc::ColumnBlockPosition &rBlockPos, SCROW nStartRow, SCROW nEndRow)
sc::CellNoteStoreType maCellNotes
std::optional< sc::ColumnIterator > GetColumnIterator(SCROW nRow1, SCROW nRow2) const
void EndListeningFormulaCells(sc::EndListeningContext &rCxt, SCROW nRow1, SCROW nRow2, SCROW *pStartRow, SCROW *pEndRow)
sc::MultiDataCellState::StateType HasDataCellsInRange(SCROW nRow1, SCROW nRow2, SCROW *pRow1) const
void SwapNonEmpty(sc::TableValues &rValues, sc::StartListeningContext &rStartCxt, sc::EndListeningContext &rEndCxt)
void ResetFormulaCellPositions(SCROW nRow1, SCROW nRow2, bool bUpdateRefs)
Reset column position of formula cells within specified row range.
void StoreToCache(SvStream &rStrm) const
std::unique_ptr< ScPostIt > ReleaseNote(SCROW nRow)
void EndListeningIntersectedGroup(sc::EndListeningContext &rCxt, SCROW nRow, std::vector< ScAddress > *pGroupPos)
void EndListeningIntersectedGroups(sc::EndListeningContext &rCxt, SCROW nRow1, SCROW nRow2, std::vector< ScAddress > *pGroupPos)
void Swap(ScColumn &rOther, SCROW nRow1, SCROW nRow2, bool bPattern)
void UpdateScriptTypes(SCROW nRow1, SCROW nRow2)
void SetNeedsListeningGroup(SCROW nRow)
void CompileHybridFormula(sc::StartListeningContext &rStartListenCxt, sc::CompileFormulaContext &rCompileCxt)
void CopyOneCellFromClip(sc::CopyFromClipContext &rCxt, SCROW nRow1, SCROW nRow2, size_t nColOffset)
const ScPatternAttr * SetPattern(SCROW nRow, std::unique_ptr< ScPatternAttr >)
sc::CellStoreType maCells
void DetachFormulaCells(const sc::CellStoreType::position_type &aPos, size_t nLength, std::vector< SCROW > *pNewSharedRows)
void SetValues(const SCROW nRow, const std::vector< double > &rVals)
void CollectBroadcasterState(sc::BroadcasterState &rState) const
void StartListeningUnshared(const std::vector< SCROW > &rNewSharedRows)
Re-establish listeners on unshared formula groups.
void ForgetNoteCaptions(SCROW nRow1, SCROW nRow2, bool bPreserveData)
void CreateAllNoteCaptions()
void StartListeningFormulaCells(sc::StartListeningContext &rStartCxt, sc::EndListeningContext &rEndCxt, SCROW nRow1, SCROW nRow2)
void CopyCellValuesFrom(SCROW nRow, const sc::CellValues &rSrc)
void DeleteSparklineCells(sc::ColumnBlockPosition &rBlockPos, SCROW nRow1, SCROW nRow2)
void GetNotesInRange(SCROW nStartRow, SCROW nEndRow, std::vector< sc::NoteEntry > &rNotes) const
void DeleteArea(SCROW nStartRow, SCROW nEndRow, InsertDeleteFlags nDelFlag, bool bBroadcast=true, sc::ColumnSpanSet *pBroadcastSpans=nullptr)
size_t GetNoteCount() const
bool HandleRefArrayForParallelism(SCROW nRow1, SCROW nRow2, const ScFormulaCellGroupRef &mxGroup)
static void JoinNewFormulaCell(const sc::CellStoreType::position_type &aPos, ScFormulaCell &rCell)
void duplicateSparkline(sc::CopyFromClipContext &rContext, sc::ColumnBlockPosition *pBlockPos, size_t nColOffset, size_t nDestSize, ScAddress aDestPosition)
sc::BroadcasterStoreType maBroadcasters
SCROW GetLastDataPos() const
ScDocument & GetDoc() const
sc::SparklineStoreType maSparklines
bool EnsureFormulaCellResults(SCROW nRow1, SCROW nRow2, bool bSkipRunning=false)
static void LOKCommentNotify(LOKCommentNotificationType nType, const ScDocument *pDocument, const ScAddress &rPos, const ScPostIt *pNote)
ScSheetLimits & GetSheetLimits() const
bool ValidRow(SCROW nRow) const
ScClipParam & GetClipParam()
SC_DLLPUBLIC ScDocumentPool * GetPool()
void RemoveFromFormulaTree(ScFormulaCell *pCell)
SC_DLLPUBLIC SvtScriptType GetStringScriptType(const OUString &rString)
ScRecursionHelper & GetRecursionHelper()
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
std::unique_ptr< EditTextObject > CreateSharedStringTextObject(const svl::SharedString &rSS)
SC_DLLPUBLIC std::shared_ptr< sc::SparklineGroup > SearchSparklineGroup(tools::Guid const &rGuid)
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
SC_DLLPUBLIC const SfxItemSet * GetCondResult(SCCOL nCol, SCROW nRow, SCTAB nTab, ScRefCellValue *pCell=nullptr) const
std::map< SCROW, std::vector< SdrObject * > > GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow)
ScPatternAttr * PutInPool(ScDocument *pDestDoc, ScDocument *pSrcDoc) const
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
SfxItemSet & GetItemSet()
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Additional class containing cell annotation data.
std::unique_ptr< ScPostIt > Clone(const ScAddress &rOwnPos, ScDocument &rDestDoc, const ScAddress &rDestPos, bool bCloneCaption) const
Clones this note and its caption object, if specified.
void Join(const ScRange &, bool bIsInList=false)
bool AreGroupsIndependent()
void CheckRelativeReferenceBounds(const sc::RefUpdateContext &rCxt, const ScAddress &rPos, SCROW nGroupLen, std::vector< SCROW > &rBounds) const
void AdjustReferenceOnMovedOriginIfOtherSheet(const ScAddress &rOldPos, const ScAddress &rNewPos)
Adjust all internal references on base position change if they point to a sheet other than the one of...
void AdjustReferenceOnMovedOrigin(const ScAddress &rOldPos, const ScAddress &rNewPos)
Adjust all internal references on base position change.
virtual void Clear() override
const T & Put(std::unique_ptr< T > xItem, sal_uInt16 nWhich=0)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_uInt32 GetRefCount() const
SvStream & WriteDouble(const double &rDouble)
SvStream & ReadUInt64(sal_uInt64 &rUInt64)
SvStream & WriteInt32(sal_Int32 nInt32)
SvStream & ReadDouble(double &rDouble)
SvStream & WriteUChar(unsigned char nChar)
SvStream & WriteOString(std::string_view rStr)
SvStream & WriteUInt64(sal_uInt64 nuInt64)
SvStream & ReadInt32(sal_Int32 &rInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
SvStream & ReadUChar(unsigned char &rChar)
std::vector< SvtListener * > ListenersType
ListenersType & GetAllListeners()
Think of this as a mini-ScColumn like storage that only stores cell values in a column.
void transferFrom(ScColumn &rCol, SCROW nRow, size_t nLen)
Transfer values from specified column.
void copyTo(ScColumn &rCol, SCROW nRow) const
void swapNonEmpty(ScColumn &rCol)
void setValue(size_t nRow, double fVal)
ColumnBlockPosition * getBlockPosition(SCTAB nTab, SCCOL nCol)
This iterator lets you iterate over cells over specified range in a single column.
Structure that stores segments of boolean flags per column, and perform custom action on those segmen...
void set(const ScDocument &rDoc, SCTAB nTab, SCCOL nCol, SCROW nRow, bool bVal)
sc::CellTextAttr & getSingleCellAttr(size_t nColOffset)
InsertDeleteFlags getDeleteFlag() const
void setListeningFormulaSpans(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Record a range of formula cells that need to start listening after the copy-from-clip is complete.
ScConditionalFormatList * getCondFormatList()
bool isSkipEmptyCells() const
Get the flag that indicates whether the "skip empty cells" paste option is selected.
ScCellValue & getSingleCell(size_t nColOffset)
InsertDeleteFlags getInsertFlag() const
std::shared_ptr< sc::Sparkline > const & getSingleSparkline(size_t nColOffset) const
const ScPatternAttr * getSingleCellPattern(size_t nColOffset) const
bool isTableProtected() const
Range getDestRange() const
const ScPostIt * getSingleCellNote(size_t nColOffset) const
ScDocument * getClipDoc()
Keep track of spans in a single column only.
void scan(const ScColumn &rColumn)
Scan an entire column and tag all non-empty cell positions.
std::vector< RowSpan > SpansType
void getSpans(SpansType &rSpans) const
Holder of a sparkline, that is connected to a cell specific.
Stores cell values for multiple tables.
void swap(SCTAB nTab, SCCOL nCol, CellValues &rColValue)
Swap the entire column.
std::vector< CellValueSpan > getNonEmptySpans(SCTAB nTab, SCCOL nCol) const
const ScRange & getRange() const
void swapNonEmpty(SCTAB nTab, SCCOL nCol, ScColumn &rCol)
Swap non-empty blocks with the column storage.
SharedString intern(const OUString &rStr)
const OUString & getString() const
static const SharedString & getEmptyString()
sc::StartListeningContext & mrStartCxt
sc::EndListeningContext & mrEndCxt
static void lcl_EvalDirty(sc::CellStoreType &rCells, SCROW nRow1, SCROW nRow2, ScDocument &rDoc, const ScFormulaCellGroupRef &mxGroup, bool bThreadingDepEval, bool bSkipRunning, bool &bIsDirty, bool &bAllowThreading)
static bool lcl_InterpretSpan(sc::formula_block::const_iterator &rSpanIter, SCROW nStartOffset, SCROW nEndOffset, const ScFormulaCellGroupRef &mxParentGroup, bool &bAllowThreading, ScDocument &rDoc)
@ SPARKLINES
Sheet / outlining (grouping) information.
@ NOTE
Strings (and string results if InsertDeleteFlags::FORMULA is not set).
@ NOCAPTIONS
Sparklines in a cell.
@ EDITATTR
Drawing objects.
@ ADDNOTES
Internal use only (undo etc.): do not copy/delete caption objects of cell notes.
@ ATTRIB
Internal use only (d&d undo): do not delete caption objects of cell notes.
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
enumrange< T >::Iterator begin(enumrange< T >)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
CellStoreType::const_iterator ParseAllNonEmpty(const typename CellStoreType::const_iterator &itPos, const CellStoreType &rCells, SCROW nRow1, SCROW nRow2, Func &rFunc)
StoreT::const_iterator ParseBlock(const typename StoreT::const_iterator &itPos, const StoreT &rStore, Func &rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd)
Generic algorithm to parse blocks of multi_type_vector either partially or fully.
const mdds::mtv::element_t element_type_celltextattr
const mdds::mtv::element_t element_type_edittext
CellStoreType::iterator ProcessFormula(const CellStoreType::iterator &it, CellStoreType &rStore, SCROW nRow1, SCROW nRow2, std::function< void(size_t, ScFormulaCell *)> aFuncElem)
Process formula cells found within specified row range.
std::pair< CellStoreType::const_iterator, size_t > FindFormula(const CellStoreType &rStore, SCROW nRow1, SCROW nRow2, Func &rFunc)
const mdds::mtv::element_t element_type_formula
StoreT::iterator ProcessBlock(const typename StoreT::iterator &itPos, StoreT &rStore, Func &rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd)
Non-const variant of the above function.
BroadcasterStoreType::iterator ProcessBroadcaster(const BroadcasterStoreType::iterator &it, BroadcasterStoreType &rStore, SCROW nRow1, SCROW nRow2, FuncElem &rFuncElem)
void ParseFormula(const CellStoreType &rStore, Func &rFunc)
mdds::mtv::soa::multi_type_vector< CellStoreTraits > CellStoreType
Cell container.
const mdds::mtv::element_t element_type_numeric
Mapped standard element types (for convenience).
mdds::mtv::soa::multi_type_vector< CellTextAttrTraits > CellTextAttrStoreType
Cell text attribute container.
void ProcessNote(CellNoteStoreType &rStore, Func &rFunc)
const mdds::mtv::element_t element_type_string
const mdds::mtv::element_t element_type_cellnote
const mdds::mtv::element_t element_type_empty
const mdds::mtv::element_t element_type_broadcaster
Custom element type IDs for multi_type_vector.
const sc::CellStoreType & mrCells
constexpr TypedWhichId< ScProtectionAttr > ATTR_PROTECTION(149)
constexpr TypedWhichId< ScCondFormatItem > ATTR_CONDITIONAL(154)
Store arbitrary cell value of any kind.
const svl::SharedString * getSharedString() const
ScFormulaCell * getFormula() const
EditTextObject * getEditText() const
ScRange getWholeRange() const
Return a single range that encompasses all individual ranges.
This is very similar to ScCellValue, except that it references the original value instead of copying ...
SCROW GetMaxRowCount() const
std::map< ScAddress, std::vector< CellListener > > aCellListenerStore
SvtScriptType mnScriptType
Store position data for column array storage.
SparklineStoreType::iterator miSparklinePos
CellTextAttrStoreType::iterator miCellTextAttrPos
CellStoreType::iterator miCellPos
CellNoteStoreType::iterator miCellNotePos
::boost::intrusive_ptr< ScFormulaCellGroup > ScFormulaCellGroupRef