14#include <document.hxx>
25#include <tokenarray.hxx>
30#include <compiler.hxx>
49 sc::CellStoreType::const_position_type aPos =
maCells.position(nRow1);
50 sc::CellStoreType::const_iterator it = aPos.first;
51 size_t nOffset = aPos.second;
55 for (; it !=
maCells.end() && nRow <= nRow2; ++it)
61 size_t nSize = it->size - nOffset;
63 SCROW nLastRow = nRow + nSize - 1;
66 nSize -= nLastRow - nRow2;
87 nRow += it->size - nOffset;
152 SCROW nClipRowLen = nClipRow2 - nClipRow1 + 1;
156 aSpanSet.
scan(rClipCol, nClipRow1, nClipRow2);
165 std::vector<sc::RowSpan> aDestSpans;
167 bool bContinue =
true;
172 SCROW nDestRow1 = r.mnRow1 + nDestOffset;
173 SCROW nDestRow2 = r.mnRow2 + nDestOffset;
175 if (nDestRow1 > aRange.
mnRow2)
182 if (nDestRow2 > aRange.
mnRow2)
185 nDestRow2 = aRange.
mnRow2;
189 aDestSpans.emplace_back(nDestRow1, nDestRow2);
195 nDestOffset += nClipRowLen;
198 for (
const auto& rDestSpan : aDestSpans)
200 SCROW nRow1 = rDestSpan.mnRow1;
201 SCROW nRow2 = rDestSpan.mnRow2;
206 DeleteCells(*pBlockPos, nRow1, nRow2, nDelFlag, aDeletedRows);
242 assert(nRow1 <= nRow2);
244 size_t nDestSize = nRow2 - nRow1 + 1;
264 auto pNewPattern = std::make_unique<ScPatternAttr>(*pAttr);
265 sal_uInt16 pItems[2];
268 pNewPattern->ClearItems(pItems);
269 pAttrArray->SetPatternArea(nRow1, nRow2, std::move(pNewPattern),
true);
275 std::vector<sc::CellTextAttr> aTextAttrs(nDestSize, rSrcAttr);
281 std::vector<double> aVals(nDestSize, rSrcCell.
getDouble());
298 std::vector<svl::SharedString> aStrs(nDestSize,
aStr);
308 std::vector<EditTextObject*> aStrs;
309 aStrs.reserve(nDestSize);
310 for (
size_t i = 0;
i < nDestSize; ++
i)
322 std::vector<sc::RowSpan> aRanges;
324 aRanges.emplace_back(nRow1, nRow2);
346 std::vector<ScPostIt*> aNotes;
347 aNotes.reserve(nDestSize);
348 for (
size_t i = 0;
i < nDestSize; ++
i)
351 aNotes.push_back(pNote->
Clone(aSrcPos, rDocument, aDestPosition, bCloneCaption).release());
357 pBlockPos->
miCellNotePos, nRow1, aNotes.begin(), aNotes.end());
360 aDestPosition.
SetRow(nRow1);
361 for (
size_t i = 0;
i < nDestSize; ++
i)
369 size_t nColOffset,
size_t nDestSize,
ScAddress aDestPosition)
377 auto const& pSparklineGroup = pSparkline->getSparklineGroup();
380 if (!pDuplicatedGroup)
381 pDuplicatedGroup = std::make_shared<sc::SparklineGroup>(*pSparklineGroup);
383 std::vector<sc::SparklineCell*> aSparklines(nDestSize,
nullptr);
384 ScAddress aCurrentPosition = aDestPosition;
385 for (
size_t i = 0;
i < nDestSize; ++
i)
387 auto pNewSparkline = std::make_shared<sc::Sparkline>(aCurrentPosition.
Col(), aCurrentPosition.
Row(), pDuplicatedGroup);
388 pNewSparkline->setInputRange(pSparkline->getInputRange());
390 aCurrentPosition.
IncRow();
402 SCROW nLastRow = nRow + rVals.size() - 1;
403 if (nLastRow >
GetDoc().MaxRow())
407 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
408 std::vector<SCROW> aNewSharedRows;
411 maCells.set(nRow, rVals.begin(), rVals.end());
412 std::vector<sc::CellTextAttr> aDefaults(rVals.size());
419 std::vector<SCROW> aRows;
420 aRows.reserve(rVals.size());
421 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
432 SCROW nLastRow = nRow + nLen - 1;
433 if (nLastRow >
GetDoc().MaxRow())
437 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
444 std::vector<SCROW> aRows;
446 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
458 if (nLastRow >
GetDoc().MaxRow())
462 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
469 std::vector<SCROW> aRows;
470 aRows.reserve(rSrc.
size());
471 for (
SCROW i = nRow;
i <= nLastRow; ++
i)
479class ConvertFormulaToValueHandler
486 ConvertFormulaToValueHandler(
ScDocument& rDoc) :
505 maResValues.
setValue(nRow, std::move(pObj));
521 bool isModified()
const {
return mbModified; }
534 std::vector<SCROW> aBounds { nRow1 };
535 if (nRow2 <
GetDoc().MaxRow()-1)
536 aBounds.push_back(nRow2+1);
542 ConvertFormulaToValueHandler aFunc(
GetDoc());
544 if (!aFunc.isModified())
552 aFunc.getResValues().swap(aUndoCells);
560class StartListeningHandler
574class EndListeningHandler
594 std::vector<SCROW> aBounds { rRange.
aStart.
Row() };
596 aBounds.push_back(rRange.
aEnd.
Row()+1);
603 EndListeningHandler aEndLisFunc(rEndCxt);
604 sc::CellStoreType::iterator itPos =
maCells.begin();
605 for (
const auto& rSpan : aSpans)
607 SCROW nRow1 = rSpan.mnRow1;
608 SCROW nRow2 = rSpan.mnRow2;
616 StartListeningHandler aStartLisFunc(rStartCxt);
618 for (
const auto& rSpan : aSpans)
620 SCROW nRow1 = rSpan.mnRow1;
621 SCROW nRow2 = rSpan.mnRow2;
630 for (
const auto& rSpan : rRanges)
631 DeleteArea(rSpan.mnRow1, rSpan.mnRow2, nDelFlag,
false);
637 const std::vector<sc::RowSpan>& rRanges )
639 SCCOL nMatrixCols = 0;
640 SCROW nMatrixRows = 0;
645 SAL_WARN_IF( nMatrixCols != 1 || nMatrixRows != 1,
"sc.core",
646 "ScColumn::CloneFormulaCell - cloning array/matrix with not exactly one column or row as single cell");
650 std::vector<ScFormulaCell*> aFormulas;
651 for (
const auto& rSpan : rRanges)
653 SCROW nRow1 = rSpan.mnRow1, nRow2 = rSpan.mnRow2;
654 size_t nLen = nRow2 - nRow1 + 1;
657 aFormulas.reserve(nLen);
665 for (
size_t i = 0;
i < nLen; ++
i, aPos.
IncRow())
668 aFormulas.push_back(pCell);
675 xGroup->setCode(*rSrc.
GetCode());
676 xGroup->compileCode(rDocument, aPos, rDocument.
GetGrammar());
677 for (
size_t i = 0;
i < nLen; ++
i, aPos.
IncRow())
684 xGroup->mpTopCell = pCell;
685 xGroup->mnLength = nLen;
687 aFormulas.push_back(pCell);
694 sc::CellStoreType::position_type aPosObj =
maCells.position(rBlockPos.
miCellPos, nRow1);
697 ScFormulaCell* pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
700 aPosObj =
maCells.position(aPosObj.first, nRow2);
702 pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
705 std::vector<sc::CellTextAttr> aTextAttrs(nLen, rAttr);
715 const std::vector<sc::RowSpan>& rRanges )
729 return std::unique_ptr<ScPostIt>(
p);
735 [](
const size_t& rCount,
const auto& rCellNote) {
736 if (rCellNote.type != sc::element_type_cellnote)
738 return rCount + rCellNote.size;
744class NoteCaptionCreator
748 NoteCaptionCreator(
SCTAB nTab,
SCCOL nCol ) : maPos(nCol,0,nTab) {}
750 void operator() (
size_t nRow,
const ScPostIt* p )
753 p->GetOrCreateCaption(maPos);
757class NoteCaptionCleaner
761 explicit NoteCaptionCleaner(
bool bPreserveData ) : mbPreserveData(bPreserveData) {}
763 void operator() (
size_t ,
ScPostIt* p )
765 p->ForgetCaption(mbPreserveData);
773 NoteCaptionCreator aFunc(
nTab,
nCol);
785 NoteCaptionCleaner aFunc(bPreserveData);
786 sc::CellNoteStoreType::iterator it =
maCellNotes.begin();
805 return rCellNote.position + nOffset;
816class NoteEntryCollector
818 std::vector<sc::NoteEntry>& mrNotes;
824 NoteEntryCollector( std::vector<sc::NoteEntry>& rNotes,
SCTAB nTab,
SCCOL nCol,
826 mrNotes(rNotes), mnTab(nTab),
mnCol(nCol),
827 mnStartRow(nStartRow), mnEndRow(nEndRow) {}
829 void operator() (
const sc::CellNoteStoreType::value_type& node)
const
834 size_t nTopRow = node.position;
835 sc::cellnote_block::const_iterator it = sc::cellnote_block::begin(*node.data);
836 sc::cellnote_block::const_iterator itEnd = sc::cellnote_block::end(*node.data);
840 std::advance(it, mnStartRow - nTopRow);
841 nOffset = mnStartRow - nTopRow;
848 mrNotes.emplace_back(aPos, *it);
861 std::vector<sc::NoteEntry>& rNotes )
const
863 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aPos =
maCellNotes.position(nStartRow);
864 sc::CellNoteStoreType::const_iterator it = aPos.first;
869 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aEndPos =
871 sc::CellNoteStoreType::const_iterator itEnd = aEndPos.first;
873 std::for_each(it, ++itEnd, NoteEntryCollector(rNotes,
nTab,
nCol, nStartRow, nEndRow));
878 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aStartPos =
884 std::pair<sc::CellNoteStoreType::const_iterator,size_t> aEndPos =
887 for (sc::CellNoteStoreType::const_iterator it = aStartPos.first; it != aEndPos.first; ++it)
891 size_t nTopRow = it->position;
892 sc::cellnote_block::const_iterator blockIt = sc::cellnote_block::begin(*(it->data));
893 sc::cellnote_block::const_iterator blockItEnd = sc::cellnote_block::end(*(it->data));
897 std::advance(blockIt, nStartRow - nTopRow);
898 nOffset = nStartRow - nTopRow;
910 SCROW nTmpStartRow = nStartRow, nTmpEndRow = nEndRow;
916 if (nTmpStartRow < nStartRow)
917 nTmpStartRow = nStartRow;
918 if (nTmpEndRow > nEndRow)
919 nTmpEndRow = nEndRow;
922 while (nEndRow > nTmpEndRow)
924 nStartRow = nTmpEndRow + 1;
925 pPattern =
pAttrArray->GetPatternRange(nTmpStartRow, nTmpEndRow, nStartRow);
932 if (nTmpEndRow > nEndRow)
933 nTmpEndRow = nEndRow;
941class RecompileByOpcodeHandler
949 RecompileByOpcodeHandler(
954 mrEndListenCxt(rEndListenCxt),
955 mrCompileFormulaCxt(rCompileCxt) {}
979 OUString aFormula = pTop->
GetFormula(mrCompileFormulaCxt);
980 sal_Int32
n = aFormula.getLength();
983 if (aFormula[0] ==
'{' && aFormula[n-1] ==
'}')
984 aFormula = aFormula.copy(1, n-2);
991 for (; pp != ppEnd; ++pp)
994 p->EndListeningTo(mrEndListenCxt);
1009class CompileHybridFormulaHandler
1018 mrStartListenCxt(rStartListenCxt),
1019 mrCompileFormulaCxt(rCompileCxt) {}
1028 if (!aFormula.isEmpty())
1033 std::unique_ptr<ScTokenArray> pNewCode = aComp.CompileString(aFormula);
1036 xGroup->setCode(std::move(*pNewCode));
1042 for (; pp != ppEnd; ++pp)
1045 p->SyncSharedCode();
1046 p->StartListeningTo(mrStartListenCxt);
1056 if (!aFormula.isEmpty())
1060 std::unique_ptr<ScTokenArray> pNewCode = aComp.CompileString(aFormula);
1065 aComp2.CompileTokenArray();
1067 pCell->
SetCode(std::move(pNewCode));
1087 RecompileByOpcodeHandler aFunc(&
GetDoc(), aOps, rEndListenCxt, rCompileCxt);
1088 std::for_each(aGroups.begin(), aGroups.end(), aFunc);
1102 RecompileByOpcodeHandler aFunc(&
GetDoc(), aOps, rEndListenCxt, rCompileCxt);
1103 std::for_each(aGroups.begin(), aGroups.end(), aFunc);
1112 CompileHybridFormulaHandler aFunc(
GetDoc(), rStartListenCxt, rCompileCxt);
1113 std::for_each(aGroups.begin(), aGroups.end(), aFunc);
1118class ScriptTypeUpdater
1122 sc::CellTextAttrStoreType::iterator miPosAttr;
1131 sc::CellTextAttrStoreType::position_type aAttrPos = mrTextAttrs.position(miPosAttr, nRow);
1132 miPosAttr = aAttrPos.first;
1137 sc::CellTextAttr& rAttr = sc::celltextattr_block::at(*aAttrPos.first->data, aAttrPos.second);
1156 const Color* pColor;
1165 explicit ScriptTypeUpdater(
ScColumn& rCol ) :
1167 mrTextAttrs(rCol.GetCellAttrStore()),
1168 miPosAttr(mrTextAttrs.
begin()),
1169 mpCFList(rCol.GetDoc().GetCondFormList(rCol.GetTab())),
1170 mpFormatter(rCol.GetDoc().GetFormatTable()),
1171 maPos(rCol.GetCol(), 0, rCol.GetTab()),
1175 void operator() (
size_t nRow,
double fVal )
1178 updateScriptType(nRow, aCell);
1184 updateScriptType(nRow, aCell);
1190 updateScriptType(nRow, aCell);
1196 updateScriptType(nRow, aCell);
1199 bool isUpdated()
const {
return mbUpdated; }
1209 ScriptTypeUpdater aFunc(*
this);
1211 if (aFunc.isUpdated())
1226 std::map<SCROW, std::vector<SdrObject*>> aThisColRowDrawObjects
1228 std::map<SCROW, std::vector<SdrObject*>> aOtherColRowDrawObjects
1230 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
1232 std::vector<SdrObject*>& rThisCellDrawObjects = aThisColRowDrawObjects[nRow];
1233 if (!rThisCellDrawObjects.empty())
1235 std::vector<SdrObject*>& rOtherCellDrawObjects = aOtherColRowDrawObjects[nRow];
1236 if (!rOtherCellDrawObjects.empty())
1243 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
1263class FormulaColPosSetter
1268 FormulaColPosSetter(
SCCOL nCol,
bool bUpdateRefs ) :
mnCol(nCol), mbUpdateRefs(bUpdateRefs) {}
1296 FormulaColPosSetter aFunc(
nCol, bUpdateRefs);
1302class RelativeRefBoundChecker
1308 explicit RelativeRefBoundChecker(
const ScRange& rBoundRange ) :
1309 maBoundRange(rBoundRange) {}
1320 void swapBounds( std::vector<SCROW>& rBounds )
1322 rBounds.swap(maBounds);
1334 std::vector<SCROW> aBounds;
1337 aBounds.push_back(rBoundRange.
aStart.
Row());
1339 aBounds.push_back(rBoundRange.
aEnd.
Row()+1);
1342 RelativeRefBoundChecker aFunc(rBoundRange);
1345 aFunc.swapBounds(aBounds);
1351class ListenerCollector
1353 std::vector<SvtListener*>& mrListeners;
1355 explicit ListenerCollector( std::vector<SvtListener*>& rListener ) :
1356 mrListeners(rListener) {}
1361 mrListeners.insert(mrListeners.end(), rLis.begin(), rLis.end());
1365class FormulaCellCollector
1367 std::vector<ScFormulaCell*>&
mrCells;
1369 explicit FormulaCellCollector( std::vector<ScFormulaCell*>& rCells ) :
mrCells(rCells) {}
1384 ListenerCollector aFunc(rListeners);
1393 FormulaCellCollector aFunc(rCells);
1404struct FindAnyFormula
1422 if (nRow1 == 0 && nRow2 ==
GetDoc().MaxRow())
1425 FindAnyFormula aFunc;
1426 std::pair<sc::CellStoreType::const_iterator, size_t> aRet =
1429 return aRet.first !=
maCells.end();
1436 for (; pp != ppEnd; ++pp)
1443class StartListeningFormulaCellsHandler
1451 mrStartCxt(rStartCxt), mrEndCxt(rEndCxt), mnStartRow(-1) {}
1453 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize )
1459 mnStartRow = node.position + nOffset;
1461 ScFormulaCell** ppBeg = &sc::formula_block::at(*node.data, nOffset);
1474 if (nBackTrackSize > 0)
1477 for (
SCROW i = 0;
i < nBackTrackSize; ++
i)
1479 endListening(mrEndCxt, pp, ppBeg);
1480 mnStartRow -= nBackTrackSize;
1484 for (; pp != ppEnd; ++pp)
1499 if (nEndGroupPos > nDataSize)
1501 size_t nExcessSize = nEndGroupPos - nDataSize;
1504 endListening(mrEndCxt, ppGrp, ppGrpEnd);
1521class EndListeningFormulaCellsHandler
1529 mrEndCxt(rEndCxt), mnStartRow(-1), mnEndRow(-1) {}
1531 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize )
1537 mnStartRow = node.position + nOffset;
1539 ScFormulaCell** ppBeg = &sc::formula_block::at(*node.data, nOffset);
1551 if (nBackTrackSize > 0)
1554 for (
SCROW i = 0;
i < nBackTrackSize; ++
i)
1556 mnStartRow -= nBackTrackSize;
1560 for (; pp != ppEnd; ++pp)
1572 mnEndRow = node.position + nOffset + nEndGroupPos - 1;
1575 endListening(mrEndCxt, pp, ppGrpEnd);
1577 if (nEndGroupPos > nDataSize)
1591 SCROW getStartRow()
const
1596 SCROW getEndRow()
const
1611 StartListeningFormulaCellsHandler aFunc(rStartCxt, rEndCxt);
1622 EndListeningFormulaCellsHandler aFunc(rCxt);
1626 *pStartRow = aFunc.getStartRow();
1629 *pEndRow = aFunc.getEndRow();
1638 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
1639 sc::CellStoreType::iterator it = aPos.first;
1644 ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
1657 pGroupPos->push_back(xGroup->mpTopCell->aPos);
1660 if (nRow < nGrpLastRow)
1670 sc::CellStoreType::position_type aPos =
maCells.position(nRow1);
1671 sc::CellStoreType::iterator it = aPos.first;
1674 ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
1684 pGroupPos->push_back(xGroup->mpTopCell->aPos);
1688 aPos =
maCells.position(it, nRow2);
1693 ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
1705 ScAddress aPosLast = xGroup->mpTopCell->aPos;
1706 aPosLast.
IncRow(xGroup->mnLength-1);
1707 pGroupPos->push_back(aPosLast);
1713 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
1718 ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
1724 (*pp)->EndListeningTo(rCxt);
1729 SCROW nTopDelta = (*pp)->aPos.Row() - xGroup->mpTopCell->aPos.Row();
1730 assert(nTopDelta >= 0);
1735 assert(*pp == xGroup->mpTopCell);
1737 for (; pp != ppEnd; ++pp)
1743 sc::CellStoreType::position_type aPos =
maCells.position(nRow);
1748 ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
1754 (*pp)->SetNeedsListening(
true);
1759 SCROW nTopDelta = (*pp)->aPos.Row() - xGroup->mpTopCell->aPos.Row();
1760 assert(nTopDelta >= 0);
1765 assert(*pp == xGroup->mpTopCell);
1767 for (; pp != ppEnd; ++pp)
1782 bAllowThreading =
true;
1784 SCROW nSpanStart = -1;
1785 SCROW nSpanEnd = -1;
1786 sc::formula_block::const_iterator itSpanStart;
1787 bool bAnyDirty =
false;
1788 for (
SCROW nFGOffset = nStartOffset; nFGOffset <= nEndOffset; ++rSpanIter, ++nFGOffset)
1791 if (!pCellStart && bThisDirty)
1793 pCellStart = *rSpanIter;
1794 itSpanStart = rSpanIter;
1795 nSpanStart = nFGOffset;
1799 if (pCellStart && (!bThisDirty || nFGOffset == nEndOffset))
1801 nSpanEnd = bThisDirty ? nFGOffset : nFGOffset - 1;
1802 assert(nSpanStart >= nStartOffset && nSpanStart <= nSpanEnd && nSpanEnd <= nEndOffset);
1805 bool bGroupInterpreted = pCellStart->
Interpret(nSpanStart, nSpanEnd);
1807 if (bGroupInterpreted)
1808 for (
SCROW nIdx = nSpanStart; nIdx <= nSpanEnd; ++nIdx, ++itSpanStart)
1809 assert(!(*itSpanStart)->NeedsInterpret());
1818 if ((mxParentGroup && mxParentGroup->mbPartOfCycle) || !rRecursionHelper.
AreGroupsIndependent())
1820 bAllowThreading =
false;
1824 if (!bGroupInterpreted)
1828 for (
SCROW nIdx = nSpanStart+1; nIdx <= nSpanEnd; ++nIdx, ++itSpanStart)
1830 (*itSpanStart)->Interpret();
1831 if ((*itSpanStart)->NeedsInterpret())
1833 SAL_WARN(
"sc.core.formulagroup",
"Internal error, cell " << (*itSpanStart)->aPos
1834 <<
" failed running Interpret(), not allowing threading");
1835 bAllowThreading =
false;
1840 if ((mxParentGroup && mxParentGroup->mbPartOfCycle) || !rRecursionHelper.
AreGroupsIndependent())
1844 bAllowThreading =
false;
1850 pCellStart =
nullptr;
1859 bool& bIsDirty,
bool& bAllowThreading)
1862 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = rCells.position(nRow1);
1863 sc::CellStoreType::const_iterator it = aPos.first;
1864 size_t nOffset = aPos.second;
1869 for (;it != rCells.end() && nRow <= nRow2; ++it, nOffset = 0)
1876 if (bThreadingDepEval)
1878 bAllowThreading =
false;
1884 size_t nRowsToRead = nRow2 - nRow + 1;
1885 const size_t nEnd = std::min(it->size, nOffset+nRowsToRead);
1886 sc::formula_block::const_iterator itCell = sc::formula_block::begin(*it->data);
1887 std::advance(itCell, nOffset);
1890 size_t nCellIdx = nOffset;
1891 while (nCellIdx < nEnd)
1894 ScFormulaCell* pChildTopCell = mxGroupChild ? mxGroupChild->mpTopCell : *itCell;
1902 bAllowThreading =
false;
1906 if (bSkipRunning && (*itCell)->IsRunning())
1918 const SCROW nFGStartOffset = (*itCell)->aPos.Row() - pChildTopCell->
aPos.
Row();
1919 const SCROW nFGEndOffset = std::min(nFGStartOffset +
static_cast<SCROW>(nRowsToRead) - 1, mxGroupChild->mnLength - 1);
1920 assert(nFGEndOffset >= nFGStartOffset);
1921 const SCROW nSpanLen = nFGEndOffset - nFGStartOffset + 1;
1925 bool bAnyDirtyInSpan =
lcl_InterpretSpan(itCell, nFGStartOffset, nFGEndOffset, mxGroup, bAllowThreading, rDoc);
1926 if (!bAllowThreading)
1929 bIsDirty = bIsDirty || bAnyDirtyInSpan;
1933 nCellIdx += nSpanLen;
1935 nRowsToRead -= nSpanLen;
1940 bool bDirtyFlag =
false;
1941 if( (*itCell)->NeedsInterpret())
1944 (*itCell)->Interpret();
1945 if ((*itCell)->NeedsInterpret())
1947 SAL_WARN(
"sc.core.formulagroup",
"Internal error, cell " << (*itCell)->aPos
1948 <<
" failed running Interpret(), not allowing threading");
1949 bAllowThreading =
false;
1953 bIsDirty = bIsDirty || bDirtyFlag;
1960 if (bThreadingDepEval && mxGroup &&
1964 (*itCell)->SetDirtyVar();
1965 bAllowThreading =
false;
1980 nRow += it->size - nOffset;
1985 if (bThreadingDepEval)
1986 bAllowThreading =
true;
1999 bool bAnyDirty =
false, bTmp =
false;
2009 bool bAllowThreading =
true, bTmp =
false;
2012 return bAllowThreading;
2017class StoreToCacheFunc
2027 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize )
2029 SCROW nStartRow = node.position + nOffset;
2042 sc::numeric_block::const_iterator it = sc::numeric_block::begin(*node.data);
2043 std::advance(it, nOffset);
2044 sc::numeric_block::const_iterator itEnd = it;
2045 std::advance(itEnd, nDataSize);
2047 for (; it != itEnd; ++it)
2056 sc::string_block::const_iterator it = sc::string_block::begin(*node.data);
2057 std::advance(it, nOffset);
2058 sc::string_block::const_iterator itEnd = it;
2059 std::advance(itEnd, nDataSize);
2061 for (; it != itEnd; ++it)
2064 sal_Int32 nStrLength =
aStr.getLength();
2073 sc::formula_block::const_iterator it = sc::formula_block::begin(*node.data);
2074 std::advance(it, nOffset);
2075 sc::formula_block::const_iterator itEnd = it;
2076 std::advance(itEnd, nDataSize);
2078 for (; it != itEnd; )
2083 sal_uInt64 nGroupLength = 0;
2086 nGroupLength = xCellGroup->mnLength;
2097 std::advance(it, nGroupLength);
2113 StoreToCacheFunc aFunc(
rStrm);
2119 sal_uInt64 nStoredCol = 0;
2121 if (nStoredCol !=
static_cast<sal_uInt64
>(
nCol))
2122 throw std::exception();
2124 sal_uInt64 nLastRow = 0;
2126 sal_uInt64 nReadRow = 0;
2128 while (nReadRow < nLastRow)
2130 sal_uInt64 nStartRow = 0;
2131 sal_uInt64 nDataSize = 0;
2140 maCells.set_empty(nStartRow, nDataSize);
2145 std::vector<double> aValues(nDataSize);
2146 for (
auto& rValue : aValues)
2150 maCells.set(nStartRow, aValues.begin(), aValues.end());
2155 std::vector<svl::SharedString> aStrings(nDataSize);
2157 for (
auto& rString : aStrings)
2159 sal_Int32 nStrLength = 0;
2161 std::unique_ptr<char[]> pStr(
new char[nStrLength]);
2163 OString aOStr(pStr.get(), nStrLength);
2164 OUString
aStr = OStringToOUString(aOStr, RTL_TEXTENCODING_UTF8);
2167 maCells.set(nStartRow, aStrings.begin(), aStrings.end());
2173 std::vector<ScFormulaCell*> aFormulaCells(nDataSize);
2177 for (
SCROW nRow = 0; nRow < static_cast<SCROW>(nDataSize);)
2179 sal_uInt64 nFormulaGroupSize = 0;
2181 sal_Int32 nStrLength = 0;
2183 std::unique_ptr<char[]> pStr(
new char[nStrLength]);
2185 OString aOStr(pStr.get(), nStrLength);
2186 OUString
aStr = OStringToOUString(aOStr, RTL_TEXTENCODING_UTF8);
2187 for (sal_uInt64
i = 0;
i < nFormulaGroupSize; ++
i)
2193 nRow += nFormulaGroupSize;
2196 maCells.set(nStartRow, aFormulaCells.begin(), aFormulaCells.end());
2201 nReadRow += nDataSize;
2209 if (pColTest !=
this)
2211 std::ostringstream os;
2212 os <<
"cell store's event handler references wrong column instance (this=" <<
this
2213 <<
"; stored=" << pColTest <<
")";
2214 throw std::runtime_error(os.str());
2218 [](
const auto& blk) { return blk.type == sc::element_type_formula; }
2223 std::ostringstream os;
2224 os <<
"incorrect cached formula block count (expected=" <<
nCount <<
"; actual="
2226 throw std::runtime_error(os.str());
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)
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
void DeleteCells(sc::ColumnBlockPosition &rBlockPos, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nDelFlag, sc::SingleColumnSpanSet &rDeleted)
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 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
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
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()
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 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
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