24 #include <document.hxx>
38 #include <tokenarray.hxx>
48 #include <com/sun/star/i18n/LocaleDataItem2.hpp>
49 #include <com/sun/star/lang/IllegalArgumentException.hpp>
53 #include <rtl/tencinfo.h>
62 using ::com::sun::star::i18n::LocaleDataItem2;
69 GetDoc().Broadcast(aHint);
80 for (
const auto& rRow : rRows)
90 aSpanSet.
scan(*
this, nStartRow, nEndRow);
91 std::vector<SCROW> aRows;
93 BroadcastCells(aRows, nHint);
98 struct DirtyCellInterpreter
111 if (!GetDoc().
ValidRow(nRow1) || !GetDoc().
ValidRow(nRow2) || nRow1 > nRow2)
114 DirtyCellInterpreter aFunc;
120 sc::CellStoreType::position_type aPos = maCells.position(nRow);
121 sc::CellStoreType::iterator it = aPos.first;
122 if (it == maCells.end())
131 maCells.set_empty(nRow, nRow);
136 CellStorageModified();
142 DeleteContent(nRow,
false);
143 maCellTextAttrs.set_empty(nRow, nRow);
144 maCellNotes.set_empty(nRow, nRow);
147 CellStorageModified();
152 auto maxRowCount = GetDoc().GetSheetLimits().GetMaxRowCount();
155 maCells.resize(maxRowCount);
156 maCellTextAttrs.clear();
157 maCellTextAttrs.resize(maxRowCount);
159 maCellNotes.resize(maxRowCount);
160 CellStorageModified();
166 maCellNotes.resize(GetDoc().GetSheetLimits().GetMaxRowCount());
171 class ShiftFormulaPosHandler
185 pAttrArray->DeleteRow( nStartRow, nSize );
187 SCROW nEndRow = nStartRow + nSize - 1;
189 maBroadcasters.erase(nStartRow, nEndRow);
190 maBroadcasters.resize(GetDoc().GetSheetLimits().GetMaxRowCount());
192 CellNotesDeleting(nStartRow, nEndRow,
false);
193 maCellNotes.erase(nStartRow, nEndRow);
194 maCellNotes.resize(GetDoc().GetSheetLimits().GetMaxRowCount());
197 sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
198 sc::CellStoreType::iterator itCell = aPos.first;
202 sc::CellStoreType::iterator itTest = itCell;
204 if (itTest == maCells.end())
207 CellStorageModified();
213 bool bShiftCells =
false;
214 if (nEndRow < GetDoc().MaxRow())
216 aPos = maCells.position(itCell, nEndRow+1);
221 sc::CellStoreType::iterator itTest = itCell;
223 if (itTest != maCells.end())
237 aNonEmptySpans.
scan(aBlockPos, *
this, nEndRow+1, GetDoc().MaxRow());
243 maCells.erase(nStartRow, nEndRow);
244 maCells.resize(GetDoc().GetSheetLimits().GetMaxRowCount());
247 aPos = maCells.position(nStartRow);
250 ShiftFormulaPosHandler aShiftFormulaFunc;
251 sc::ProcessFormula(aPos.first, maCells, nStartRow, GetDoc().MaxRow(), aShiftFormulaFunc);
254 if (bJoined && pGroupPos)
255 pGroupPos->push_back(
ScAddress(nCol, nStartRow, nTab));
258 maCellTextAttrs.erase(nStartRow, nEndRow);
259 maCellTextAttrs.resize(GetDoc().GetSheetLimits().GetMaxRowCount());
261 CellStorageModified();
265 bool bInsertFormula )
267 return GetPositionToInsert(maCells.begin(), nRow, rNewSharedRows, bInsertFormula);
271 const sc::CellStoreType::position_type& aPos,
ScFormulaCell& rCell )
276 ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
277 sc::CellStoreType::position_type aPosPrev = aPos;
285 ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1);
291 const sc::CellStoreType::position_type& aPos,
ScFormulaCell& rCell, std::vector<SCROW>& rNewSharedRows )
293 if (!GetDoc().IsClipOrUndo())
295 #if USE_FORMULA_GROUP_LISTENER
307 if (rCell.
aPos.
Row() == nSharedTopRow)
311 rNewSharedRows.push_back( nSharedTopRow + 1);
312 rNewSharedRows.push_back( nSharedTopRow + nSharedLength - 1);
314 else if (rCell.
aPos.
Row() == nSharedTopRow + nSharedLength - 1)
319 rNewSharedRows.push_back( nSharedTopRow);
320 rNewSharedRows.push_back( rCell.
aPos.
Row() - 1);
327 rNewSharedRows.push_back( nSharedTopRow);
328 rNewSharedRows.push_back( rCell.
aPos.
Row() - 1);
329 rNewSharedRows.push_back( rCell.
aPos.
Row() + 1);
330 rNewSharedRows.push_back( nSharedTopRow + nSharedLength - 1);
345 assert(rNewSharedRows.empty() || rNewSharedRows.size() == 2 || rNewSharedRows.size() == 4);
347 if (rNewSharedRows.empty() || rDoc.IsDelayedFormulaGrouping())
350 auto pPosSet = std::make_shared<sc::ColumnBlockPositionSet>(rDoc);
353 if (rNewSharedRows.size() >= 2)
355 if(!rDoc.CanDelayStartListeningFormulaCells(
this, rNewSharedRows[0], rNewSharedRows[1]))
356 StartListeningFormulaCells(aStartCxt, aEndCxt, rNewSharedRows[0], rNewSharedRows[1]);
358 if (rNewSharedRows.size() >= 4)
360 if(!rDoc.CanDelayStartListeningFormulaCells(
this, rNewSharedRows[2], rNewSharedRows[3]))
361 StartListeningFormulaCells(aStartCxt, aEndCxt, rNewSharedRows[2], rNewSharedRows[3]);
367 class AttachFormulaCellsHandler
381 class DetachFormulaCellsHandler
388 mrDoc(rDoc), mpCxt(pCxt) {}
402 const sc::CellStoreType::position_type& aPos,
size_t nLength, std::vector<SCROW>* pNewSharedRows )
404 const size_t nRow = aPos.first->position + aPos.second;
405 const size_t nNextTopRow = nRow + nLength;
407 bool bLowerSplitOff =
false;
408 if (pNewSharedRows && !GetDoc().IsClipOrUndo())
416 if (nTopRow < static_cast<SCROW>(nRow))
419 pNewSharedRows->push_back(nTopRow);
420 pNewSharedRows->push_back(nRow - 1);
422 if (static_cast<SCROW>(nNextTopRow) <= nBotRow)
425 pNewSharedRows->push_back(nNextTopRow);
426 pNewSharedRows->push_back(nBotRow);
427 bLowerSplitOff =
true;
435 if (nLength > 0 && GetDoc().
ValidRow(nNextTopRow))
437 if (pNewSharedRows && !bLowerSplitOff && !GetDoc().IsClipOrUndo())
439 sc::CellStoreType::position_type aPos2 = maCells.position(aPos.first, nNextTopRow-1);
446 if (static_cast<SCROW>(nNextTopRow) <= nBotRow)
449 pNewSharedRows->push_back(nNextTopRow);
450 pNewSharedRows->push_back(nBotRow);
455 sc::CellStoreType::position_type aPos2 = maCells.position(aPos.first, nNextTopRow);
459 if (GetDoc().IsClipOrUndo())
462 DetachFormulaCellsHandler aFunc(GetDoc(),
nullptr);
468 sc::CellStoreType::position_type aPos = maCells.position(nRow1);
469 sc::CellStoreType::iterator it = aPos.first;
474 aPos = maCells.position(it, nRow2+1);
478 if (GetDoc().IsClipOrUndo())
481 AttachFormulaCellsHandler aFunc(rCxt);
486 std::vector<SCROW>* pNewSharedRows )
488 sc::CellStoreType::position_type aPos = maCells.position(nRow1);
489 sc::CellStoreType::iterator it = aPos.first;
491 bool bLowerSplitOff =
false;
492 if (pNewSharedRows && !GetDoc().IsClipOrUndo())
503 pNewSharedRows->push_back(nTopRow);
504 pNewSharedRows->push_back(nRow1 - 1);
509 pNewSharedRows->push_back(nRow2 + 1);
510 pNewSharedRows->push_back(nBotRow);
511 bLowerSplitOff =
true;
520 if (pNewSharedRows && !bLowerSplitOff && !GetDoc().IsClipOrUndo())
522 sc::CellStoreType::position_type aPos2 = maCells.position(aPos.first, nRow2);
532 pNewSharedRows->push_back(nRow2 + 1);
533 pNewSharedRows->push_back(nBotRow);
538 aPos = maCells.position(it, nRow2+1);
542 if (GetDoc().IsClipOrUndo())
545 DetachFormulaCellsHandler aFunc(GetDoc(), &rCxt);
550 std::vector<SCROW>& rNewSharedRows )
552 sc::CellStoreType::iterator itRet = rPos.first;
556 ScFormulaCell& rFC = *sc::formula_block::at(*itRet->data, rPos.second);
561 rNewSharedRows.push_back( nSharedTopRow);
562 rNewSharedRows.push_back( nSharedTopRow + nSharedLength - 1);
567 rNewSharedRows.push_back( nRow);
568 rNewSharedRows.push_back( nRow);
573 std::vector<SCROW>& rNewSharedRows,
bool bInsertFormula )
576 sc::CellStoreType::position_type aPos = maCells.position(it, nRow);
577 sc::CellStoreType::iterator itRet = aPos.first;
581 ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second);
582 DetachFormulaCell(aPos, rCell, rNewSharedRows);
584 else if (bInsertFormula && !GetDoc().IsClipOrUndo())
588 sc::CellStoreType::position_type aPosBefore = maCells.position(maCells.begin(), nRow-1);
591 if (nRow < GetDoc().MaxRow())
593 sc::CellStoreType::position_type aPosAfter = maCells.position(maCells.begin(), nRow+1);
603 const std::vector<SCROW>& rNewSharedRows,
606 AttachNewFormulaCell(maCells.position(itPos, nRow), rCell, rNewSharedRows, bJoin, eListenType);
610 const sc::CellStoreType::position_type& aPos,
ScFormulaCell& rCell,
611 const std::vector<SCROW>& rNewSharedRows,
616 JoinNewFormulaCell(aPos, rCell);
631 auto pPosSet = std::make_shared<sc::ColumnBlockPositionSet>(rDocument);
634 SCROW nStartRow, nEndRow;
635 nStartRow = nEndRow = aPos.first->position + aPos.second;
636 for (
const SCROW nR : rNewSharedRows)
643 StartListeningFormulaCells(aStartCxt, aEndCxt, nStartRow, nEndRow);
648 StartListeningUnshared( rNewSharedRows);
652 if (!rNewSharedRows.empty())
654 assert(rNewSharedRows.size() == 2 || rNewSharedRows.size() == 4);
657 const ScFormulaCell* pFC = GetFormulaCell( rNewSharedRows[0]);
659 if (pFC && !pFC->NeedsListening())
660 SetNeedsListeningGroup( rNewSharedRows[0]);
661 if (rNewSharedRows.size() > 2)
663 pFC = GetFormulaCell( rNewSharedRows[2]);
665 if (pFC && !pFC->NeedsListening())
666 SetNeedsListeningGroup( rNewSharedRows[2]);
677 std::vector<SCROW>& rNewSharedRows )
683 if (aPos.first->size < aPos.second + nLength)
688 ScFormulaCell* pCell1 = sc::formula_block::at(*aPos.first->data, aPos.second);
689 JoinNewFormulaCell(aPos, *pCell1);
691 sc::CellStoreType::position_type aPosLast = aPos;
692 aPosLast.second += nLength - 1;
693 ScFormulaCell* pCell2 = sc::formula_block::at(*aPosLast.first->data, aPosLast.second);
694 JoinNewFormulaCell(aPosLast, *pCell2);
706 if (rNewSharedRows.empty())
708 rNewSharedRows.push_back( nTopRow);
709 rNewSharedRows.push_back( nBotRow);
711 else if (rNewSharedRows.size() == 2)
714 if (rNewSharedRows[0] > nTopRow)
715 rNewSharedRows[0] = nTopRow;
716 if (rNewSharedRows[1] < nBotRow)
717 rNewSharedRows[1] = nBotRow;
719 else if (rNewSharedRows.size() == 4)
723 std::vector<SCROW> aRows(2);
724 aRows[0] = std::min( rNewSharedRows[0], nTopRow);
725 aRows[1] = std::max( rNewSharedRows[3], nBotRow);
726 rNewSharedRows.swap( aRows);
730 assert(!
"rNewSharedRows?");
733 StartListeningUnshared( rNewSharedRows);
736 ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
738 for (; pp != ppEnd; ++pp)
754 if (GetDoc().IsClipOrUndo() || GetDoc().IsInsertingFromOtherDoc() || GetDoc().IsCalcingAfterLoad())
772 sc::CellStoreType::position_type
pos = maCells.position(itr, nRow);
774 size_t nOffset = pos.second;
786 pCondSet = rDocument.
GetCondResult(aCell, aPos, *pCFList, rData);
803 class DeleteAreaHandler
806 std::vector<ScFormulaCell*> maFormulaCells;
818 maDeleteRanges(rDoc.GetSheetLimits()),
825 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize)
831 if (!mbNumeric && !mbDateTime)
835 if (mbNumeric && mbDateTime)
838 deleteNumeric(node, nOffset, nDataSize);
851 sc::formula_block::iterator it = sc::formula_block::begin(*node.data);
852 std::advance(it, nOffset);
853 sc::formula_block::iterator itEnd = it;
854 std::advance(itEnd, nDataSize);
856 for (; it != itEnd; ++it)
857 maFormulaCells.push_back(*it);
866 SCROW nRow1 = node.position + nOffset;
867 SCROW nRow2 = nRow1 + nDataSize - 1;
868 maDeleteRanges.
set(nRow1, nRow2,
true);
871 void deleteNumeric(
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize)
873 size_t nStart = node.position + nOffset;
875 bool bLastTypeDateTime = isDateTime(nStart);
876 size_t nCount = nStart + nDataSize;
878 for (
size_t i = nStart + 1;
i < nCount;
i++)
880 bool bIsDateTime = isDateTime(i);
883 if (bIsDateTime == bLastTypeDateTime)
890 deleteNumberOrDateTime(nStart, nStart + nElements - 1, bLastTypeDateTime);
895 bLastTypeDateTime = bIsDateTime;
899 deleteNumberOrDateTime(nStart, nStart + nElements - 1, bLastTypeDateTime);
902 void deleteNumberOrDateTime(
SCROW nRow1,
SCROW nRow2,
bool dateTime)
904 if (!dateTime && !mbNumeric)
906 if (dateTime && !mbDateTime)
908 maDeleteRanges.
set(nRow1, nRow2,
true);
911 bool isDateTime(
size_t position)
916 return (nType == SvNumFormatType::DATE) || (nType == SvNumFormatType::TIME) ||
917 (nType == SvNumFormatType::DATETIME);
927 return maDeleteRanges;
936 static void splitFormulaGrouping(
const sc::CellStoreType::position_type& rPos)
940 ScFormulaCell& rCell = *sc::formula_block::at(*rPos.first->data, rPos.second);
947 mrColumn(rColumn), mrPos(rPos) {}
955 sc::CellStoreType::position_type aPos = rCells.position(mrPos.
miCellPos, rSpan.
mnRow1);
956 splitFormulaGrouping(aPos);
957 aPos = rCells.position(aPos.first, rSpan.
mnRow2);
958 splitFormulaGrouping(aPos);
972 DeleteAreaHandler aFunc(GetDoc(), nDelFlag, *
this);
973 sc::CellStoreType::iterator itPos = maCells.position(rBlockPos.
miCellPos, nRow1).first;
979 aFunc.getSpans().getSpans(aSpans);
982 std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(rBlockPos, *
this));
983 CellStorageModified();
985 aFunc.getSpans().swap(rDeleted);
1001 InitBlockPosition(aBlockPos);
1005 DeleteCells(aBlockPos, nStartRow, nEndRow, nDelFlag, aDeletedRows);
1006 if (pBroadcastSpans)
1010 for (
const auto& rSpan : aSpans)
1011 pBroadcastSpans->
set(GetDoc(), nTab, nCol, rSpan.
mnRow1, rSpan.
mnRow2,
true);
1015 if (nDelFlag & InsertDeleteFlags::NOTE)
1018 DeleteCellNotes(aBlockPos, nStartRow, nEndRow, bForgetCaptionOwnership);
1024 RemoveEditAttribs( nStartRow, nEndRow );
1029 pAttrArray->DeleteArea( nStartRow, nEndRow );
1031 pAttrArray->DeleteHardAttr( nStartRow, nEndRow );
1037 std::vector<SCROW> aRows;
1039 BroadcastCells(aRows, SfxHintId::ScDataChanged);
1060 class CopyAttrArrayByRange
1067 mrDestAttrArray(rDestAttrArray), mrSrcAttrArray(rSrcAttrArray), mnRowOffset(nRowOffset) {}
1072 rSpan.
mnRow1+mnRowOffset, rSpan.
mnRow2+mnRowOffset, mnRowOffset, mrSrcAttrArray);
1076 class CopyCellsFromClipHandler
1090 void insertRefCell(
SCROW nSrcRow,
SCROW nDestRow)
1092 ScAddress aSrcPos(mnSrcCol, nSrcRow, mnSrcTab);
1093 ScAddress aDestPos(mnCol, nDestRow, mnTab);
1099 aArr.AddSingleReference(aRef);
1105 void duplicateNotes(
SCROW nStartRow,
size_t nDataSize,
bool bCloneCaption )
1107 mrSrcCol.
DuplicateNotes(nStartRow, nDataSize, mrDestCol, maDestBlockPos, bCloneCaption, mnRowOffset);
1114 mrDestCol(rDestCol),
1117 mnSrcTab(rSrcCol.GetTab()),
1118 mnSrcCol(rSrcCol.GetCol()),
1119 mnRowOffset(nRowOffset),
1120 mpDestBlockPos(mrCxt.getBlockPosition(nDestTab, nDestCol)),
1121 mpSharedStringPool(pSharedStringPool)
1124 maDestBlockPos = *mpDestBlockPos;
1129 ~CopyCellsFromClipHandler()
1133 *mpDestBlockPos = maDestBlockPos;
1136 void operator() (
const sc::CellStoreType::value_type& node,
size_t nOffset,
size_t nDataSize)
1138 SCROW nSrcRow1 = node.position + nOffset;
1148 duplicateNotes(nSrcRow1, nDataSize, bCloneCaption );
1166 sc::numeric_block::const_iterator it = sc::numeric_block::begin(*node.data);
1167 std::advance(it, nOffset);
1168 sc::numeric_block::const_iterator itEnd = it;
1169 std::advance(itEnd, nDataSize);
1170 for (
SCROW nSrcRow = nSrcRow1; it != itEnd; ++it, ++nSrcRow)
1172 bool bCopy = mrCxt.
isDateCell(mrSrcCol, nSrcRow) ? bDateTime : bNumeric;
1177 insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
1179 mrDestCol.
SetValue(maDestBlockPos, nSrcRow + mnRowOffset, *it);
1188 sc::string_block::const_iterator it = sc::string_block::begin(*node.data);
1189 std::advance(it, nOffset);
1190 sc::string_block::const_iterator itEnd = it;
1191 std::advance(itEnd, nDataSize);
1192 for (
SCROW nSrcRow = nSrcRow1; it != itEnd; ++it, ++nSrcRow)
1195 insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
1196 else if (mpSharedStringPool)
1200 mrDestCol.
SetRawString(maDestBlockPos, nSrcRow + mnRowOffset, aInterned);
1203 mrDestCol.
SetRawString(maDestBlockPos, nSrcRow + mnRowOffset, *it);
1212 sc::edittext_block::const_iterator it = sc::edittext_block::begin(*node.data);
1213 std::advance(it, nOffset);
1214 sc::edittext_block::const_iterator itEnd = it;
1215 std::advance(itEnd, nDataSize);
1216 for (
SCROW nSrcRow = nSrcRow1; it != itEnd; ++it, ++nSrcRow)
1220 insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
1222 mrDestCol.
SetEditText(maDestBlockPos, nSrcRow + mnRowOffset, **it);
1228 sc::formula_block::const_iterator it = sc::formula_block::begin(*node.data);
1229 std::advance(it, nOffset);
1230 sc::formula_block::const_iterator itEnd = it;
1231 std::advance(itEnd, nDataSize);
1232 for (
SCROW nSrcRow = nSrcRow1; it != itEnd; ++it, ++nSrcRow)
1235 bool bForceFormula =
false;
1240 if (pCode && pCode->
GetLen() == 1)
1245 bForceFormula =
true;
1249 ScAddress aDestPos(mnCol, nSrcRow + mnRowOffset, mnTab);
1250 if (bFormula || bForceFormula)
1253 insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
1257 maDestBlockPos, nSrcRow + mnRowOffset,
1263 else if (bNumeric || bDateTime || bString)
1269 if (nErr != FormulaError::NONE)
1275 insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
1281 maDestBlockPos, nSrcRow + mnRowOffset, pErrCell);
1292 bool bCopy = mrCxt.
isDateCell(mrSrcCol, nSrcRow) ? bDateTime : bNumeric;
1297 insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
1299 mrDestCol.
SetValue(maDestBlockPos, nSrcRow + mnRowOffset, rSrcCell.
GetValue());
1309 insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
1317 else if (mpSharedStringPool)
1321 mrDestCol.
SetRawString(maDestBlockPos, nSrcRow + mnRowOffset, aInterned);
1325 mrDestCol.
SetRawString(maDestBlockPos, nSrcRow + mnRowOffset, aStr);
1338 duplicateNotes(nSrcRow1, nDataSize, bCloneCaption );
1343 class CopyTextAttrsFromClipHandler
1355 mpDestBlockPos(rCxt.getBlockPosition(nDestTab, nDestCol))
1358 maDestBlockPos = *mpDestBlockPos;
1363 ~CopyTextAttrsFromClipHandler()
1367 *mpDestBlockPos = maDestBlockPos;
1370 void operator() (
const sc::CellTextAttrStoreType::value_type& aNode,
size_t nOffset,
size_t nDataSize )
1375 sc::celltextattr_block::const_iterator it = sc::celltextattr_block::begin(*aNode.data);
1376 std::advance(it, nOffset);
1377 sc::celltextattr_block::const_iterator itEnd = it;
1378 std::advance(itEnd, nDataSize);
1380 size_t nPos = aNode.position + nOffset + mnDelta;
1399 aSpanSet.
scan(rColumn, nRow1-nDy, nRow2-nDy);
1403 aSpans.begin(), aSpans.end(), CopyAttrArrayByRange(*rColumn.
pAttrArray, *pAttrArray, nDy));
1406 rColumn.
pAttrArray->CopyAreaSafe( nRow1, nRow2, nDy, *pAttrArray );
1427 for (
SCROW nDestRow = nRow1; nDestRow <= nRow2; nDestRow++)
1430 aDestPos.
SetRow( nDestRow );
1434 SetFormulaCell(nDestRow,
new ScFormulaCell(rDocument, aDestPos, aArr));
1438 CopyTextAttrsFromClipHandler aFunc(rCxt, maCellTextAttrs, *
this, nTab, nCol, nDy);
1452 CopyCellsFromClipHandler aFunc(rCxt, rColumn, *
this, nTab, nCol, nDy, pSharedStringPool);
1458 CopyTextAttrsFromClipHandler aFunc(rCxt, maCellTextAttrs, *
this, nTab, nCol, nDy);
1465 bool bSkipEmpty,
const ScColumn& rSrcCol )
1472 while (aIter.Next( nRow1, nRow2 ))
1473 MixData(rCxt, nRow1, nRow2, nFunction, bSkipEmpty, rSrcCol);
1480 bool lcl_DoFunction(
double& rVal1,
double nVal2,
ScPasteFunc nFunction )
1515 pToken = aIter.Next();
1522 class MixDataHandler
1528 sc::CellStoreType::iterator miNewCellsPos;
1535 void doFunction(
size_t nDestRow,
double fVal1,
double fVal2 )
1537 bool bOk = lcl_DoFunction(fVal1, fVal2, mnFunction);
1540 miNewCellsPos = maNewCells.set(miNewCellsPos, nDestRow-mnRowOffset, fVal1);
1548 miNewCellsPos = maNewCells.set(miNewCellsPos, nDestRow-mnRowOffset, pFC);
1558 mrDestColumn(rDestColumn),
1559 mrBlockPos(rBlockPos),
1560 maNewCells(nRow2 - nRow1 + 1),
1561 miNewCellsPos(maNewCells.
begin()),
1563 mnFunction(nFunction),
1564 mbSkipEmpty(bSkipEmpty)
1568 void operator() (
size_t nRow,
double f)
1570 sc::CellStoreType::position_type aPos = mrDestColumn.
GetCellStore().position(mrBlockPos.
miCellPos, nRow);
1572 switch (aPos.first->type)
1577 double fSrcVal = 0.0;
1579 fSrcVal = sc::numeric_block::at(*aPos.first->data, aPos.second);
1582 doFunction(nRow, f, fSrcVal);
1603 aArr.AddOpCode(eOp);
1606 ScFormulaCell* pDest = sc::formula_block::at(*aPos.first->data, aPos.second);
1607 lcl_AddCode(aArr, pDest);
1609 miNewCellsPos = maNewCells.set(
1610 miNewCellsPos, nRow-mnRowOffset,
1619 miNewCellsPos = maNewCells.set(miNewCellsPos, nRow-mnRowOffset, f);
1629 miNewCellsPos = maNewCells.set(miNewCellsPos, nRow-mnRowOffset, rStr);
1634 miNewCellsPos = maNewCells.set(miNewCellsPos, nRow-mnRowOffset, p->
Clone().release());
1639 sc::CellStoreType::position_type aPos = mrDestColumn.
GetCellStore().position(mrBlockPos.
miCellPos, nRow);
1641 switch (aPos.first->type)
1649 lcl_AddCode(aArr, p);
1661 aArr.AddOpCode(eOp);
1664 aArr.AddDouble(sc::numeric_block::at(*aPos.first->data, aPos.second));
1666 miNewCellsPos = maNewCells.set(
1667 miNewCellsPos, nRow-mnRowOffset,
1678 lcl_AddCode(aArr, p);
1690 aArr.AddOpCode(eOp);
1693 ScFormulaCell* pDest = sc::formula_block::at(*aPos.first->data, aPos.second);
1694 lcl_AddCode(aArr, pDest);
1696 miNewCellsPos = maNewCells.set(
1697 miNewCellsPos, nRow-mnRowOffset,
1708 miNewCellsPos = maNewCells.set(
1720 void operator() (mdds::mtv::element_t,
size_t nTopRow,
size_t nDataSize)
1726 for (
size_t i = 0;
i < nDataSize; ++
i)
1728 size_t nDestRow = nTopRow +
i;
1729 sc::CellStoreType::position_type aPos = mrDestColumn.
GetCellStore().position(mrBlockPos.
miCellPos, nDestRow);
1731 switch (aPos.first->type)
1735 double fVal2 = sc::numeric_block::at(*aPos.first->data, aPos.second);
1736 doFunction(nDestRow, 0.0, fVal2);
1741 const svl::SharedString& aVal = sc::string_block::at(*aPos.first->data, aPos.second);
1742 miNewCellsPos = maNewCells.set(
1743 miNewCellsPos, nDestRow-mnRowOffset, aVal);
1748 EditTextObject* pObj = sc::edittext_block::at(*aPos.first->data, aPos.second);
1749 miNewCellsPos = maNewCells.set(
1750 miNewCellsPos, nDestRow-mnRowOffset, pObj->
Clone().release());
1758 ScFormulaCell* pSrc = sc::formula_block::at(*aPos.first->data, aPos.second);
1759 lcl_AddCode( aArr, pSrc);
1772 aArr.AddOpCode(eOp);
1773 aArr.AddDouble(0.0);
1775 miNewCellsPos = maNewCells.set(
1776 miNewCellsPos, nDestRow-mnRowOffset,
1795 sc::CellStoreType::position_type aPos = rDestCells.position(mrBlockPos.
miCellPos, mnRowOffset);
1799 sc::CellStoreType::iterator& itDestPos = mrBlockPos.
miCellPos;
1800 sc::CellTextAttrStoreType::iterator& itDestAttrPos = mrBlockPos.
miCellTextAttrPos;
1802 for (
const auto& rNewCell : maNewCells)
1804 bool bHasContent =
true;
1805 size_t nDestRow = mnRowOffset + rNewCell.position;
1807 switch (rNewCell.type)
1811 sc::numeric_block::iterator itData = sc::numeric_block::begin(*rNewCell.data);
1812 sc::numeric_block::iterator itDataEnd = sc::numeric_block::end(*rNewCell.data);
1813 itDestPos = mrDestColumn.
GetCellStore().set(itDestPos, nDestRow, itData, itDataEnd);
1818 sc::string_block::iterator itData = sc::string_block::begin(*rNewCell.data);
1819 sc::string_block::iterator itDataEnd = sc::string_block::end(*rNewCell.data);
1820 itDestPos = rDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
1825 sc::edittext_block::iterator itData = sc::edittext_block::begin(*rNewCell.data);
1826 sc::edittext_block::iterator itDataEnd = sc::edittext_block::end(*rNewCell.data);
1827 itDestPos = rDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
1832 sc::formula_block::iterator itData = sc::formula_block::begin(*rNewCell.data);
1833 sc::formula_block::iterator itDataEnd = sc::formula_block::end(*rNewCell.data);
1839 itDestPos = rDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
1842 aPos = rDestCells.position(itDestPos, nDestRow);
1846 size_t nNextRow = nDestRow + rNewCell.size;
1849 aPos = rDestCells.position(aPos.first, nNextRow);
1856 itDestPos = rDestCells.set_empty(itDestPos, nDestRow, nDestRow+rNewCell.size-1);
1857 bHasContent =
false;
1868 itDestAttrPos = rDestAttrs.set(itDestAttrPos, nDestRow, aAttrs.begin(), aAttrs.end());
1871 itDestAttrPos = rDestAttrs.set_empty(itDestAttrPos, nDestRow, nDestRow+rNewCell.size-1);
1874 maNewCells.release();
1882 bool bSkipEmpty,
const ScColumn& rSrcCol )
1890 MixDataHandler aFunc(*p, *
this, nRow1, nRow2, nFunction, bSkipEmpty);
1894 CellStorageModified();
1899 return std::make_unique<ScAttrIterator>( pAttrArray.get(), nStartRow, nEndRow, GetDoc().GetDefPattern() );
1904 class StartListenersHandler
1907 bool mbAllListeners;
1911 mpCxt(&rCxt), mbAllListeners(bAllListeners) {}
1913 void operator() ( sc::CellStoreType::value_type& aBlk )
1921 for (; pp != ppEnd; ++pp)
1942 std::for_each(maCells.begin(), maCells.end(), StartListenersHandler(rCxt, bAll));
1963 if (rString.isEmpty())
1966 bool bNumFmtSet =
false;
1974 sal_uInt32 nOldIndex = 0;
1980 nIndex = nOldIndex = GetNumberFormat( GetDoc().GetNonThreadedContext(), nRow );
1981 if ( rString.getLength() > 1 )
1984 if ( eNumFormatType != SvNumFormatType::TEXT )
1985 cFirstChar = rString[0];
1990 if ( cFirstChar ==
'=' )
1992 if ( rString.getLength() == 1 )
2005 GetDoc(),
ScAddress(nCol, nRow, nTabP), rString,
2009 GetDoc().CheckLinkFormulaNeedingCheck( *pFormulaCell->
GetCode());
2010 rCell.
set( pFormulaCell);
2013 else if ( cFirstChar ==
'\'')
2015 bool bNumeric =
false;
2020 OUString aTest = rString.copy(1);
2046 if (eNumFormatType == SvNumFormatType::ALL)
2048 bool bForceFormatDate = (eNumFormatType == SvNumFormatType::DATE
2049 || eNumFormatType == SvNumFormatType::DATETIME);
2052 if (bForceFormatDate)
2063 bForceFormatDate =
false;
2074 bForceFormatDate =
false;
2080 if (bForceFormatDate)
2083 if (!bIsNumberFormat)
2105 if ( nIndex != nOldIndex)
2111 bool bOverwrite =
false;
2115 if ( nOldType == SvNumFormatType::NUMBER || nOldType == SvNumFormatType::DATE ||
2116 nOldType == SvNumFormatType::TIME || nOldType == SvNumFormatType::LOGICAL )
2146 const LocaleDataItem2& aLocaleItem = pLocale->
getLocaleItem();
2147 const OUString& rDecSep = aLocaleItem.decimalSeparator;
2148 const OUString& rGroupSep = aLocaleItem.thousandSeparator;
2149 const OUString& rDecSepAlt = aLocaleItem.decimalSeparatorAlternative;
2150 if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1 || rDecSepAlt.getLength() > 1)
2198 bool bNumFmtSet = ParseString(aNewCell, nRow, nTabP, rString, eConv, pParam);
2202 aNewCell.
release(*
this, nRow);
2212 pEditText->NormalizeString(GetDoc().GetSharedStringPool());
2213 std::vector<SCROW> aNewSharedRows;
2214 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows,
false);
2215 maCells.set(it, nRow, pEditText.release());
2217 CellStorageModified();
2219 StartListeningUnshared( aNewSharedRows);
2221 BroadcastNewCell(nRow);
2226 pEditText->NormalizeString(GetDoc().GetSharedStringPool());
2227 std::vector<SCROW> aNewSharedRows;
2228 rBlockPos.
miCellPos = GetPositionToInsert(rBlockPos.
miCellPos, nRow, aNewSharedRows,
false);
2233 CellStorageModified();
2235 StartListeningUnshared( aNewSharedRows);
2237 BroadcastNewCell(nRow);
2242 if (GetDoc().GetEditPool() == rEditText.
GetPool())
2244 SetEditText(rBlockPos, nRow, rEditText.
Clone());
2251 EditEngine& rEngine = GetDoc().GetEditEngine();
2258 if (pEditPool && GetDoc().GetEditPool() == pEditPool)
2260 SetEditText(nRow, rEditText.
Clone());
2267 EditEngine& rEngine = GetDoc().GetEditEngine();
2276 std::vector<SCROW> aNewSharedRows;
2277 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows,
true);
2279 sal_uInt32 nCellFormat = GetNumberFormat(GetDoc().GetNonThreadedContext(), nRow);
2282 it = maCells.set(it, nRow, pCell);
2285 CellStorageModified();
2287 AttachNewFormulaCell(it, nRow, *pCell, aNewSharedRows);
2294 std::vector<SCROW> aNewSharedRows;
2295 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows,
true);
2297 sal_uInt32 nCellFormat = GetNumberFormat(GetDoc().GetNonThreadedContext(), nRow);
2300 it = maCells.set(it, nRow, pCell);
2303 CellStorageModified();
2305 AttachNewFormulaCell(it, nRow, *pCell, aNewSharedRows);
2310 bool bInheritNumFormatIfNeeded )
2312 std::vector<SCROW> aNewSharedRows;
2313 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows,
true);
2314 sal_uInt32 nCellFormat = GetNumberFormat(GetDoc().GetNonThreadedContext(), nRow);
2317 it = maCells.set(it, nRow, pCell);
2320 CellStorageModified();
2322 AttachNewFormulaCell(it, nRow, *pCell, aNewSharedRows,
true, eListenType);
2330 bool bInheritNumFormatIfNeeded )
2332 std::vector<SCROW> aNewSharedRows;
2333 rBlockPos.
miCellPos = GetPositionToInsert(rBlockPos.
miCellPos, nRow, aNewSharedRows,
true);
2334 sal_uInt32 nCellFormat = GetNumberFormat(GetDoc().GetNonThreadedContext(), nRow);
2341 CellStorageModified();
2343 AttachNewFormulaCell(rBlockPos.
miCellPos, nRow, *pCell, aNewSharedRows,
true, eListenType);
2351 SCROW nEndRow = nRow + rCells.size() - 1;
2355 sc::CellStoreType::position_type aPos = maCells.position(nRow);
2358 std::vector<SCROW> aNewSharedRows;
2359 DetachFormulaCells(aPos, rCells.size(), &aNewSharedRows);
2361 if (!GetDoc().IsClipOrUndo())
2363 for (
size_t i = 0,
n = rCells.size(); i <
n; ++i)
2365 SCROW nThisRow = nRow + i;
2366 sal_uInt32 nFmt = GetNumberFormat(GetDoc().GetNonThreadedContext(), nThisRow);
2368 rCells[i]->SetNeedNumberFormat(
true);
2372 std::vector<sc::CellTextAttr> aDefaults(rCells.size(),
sc::CellTextAttr());
2373 maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
2375 maCells.set(aPos.first, nRow, rCells.begin(), rCells.end());
2377 CellStorageModified();
2381 aPos = maCells.position(nRow);
2382 AttachNewFormulaCells(aPos, rCells.size(), aNewSharedRows);
2389 sc::CellStoreType::const_position_type aPos = maCells.position(nRow);
2390 switch (aPos.first->type)
2393 return sc::string_block::at(*aPos.first->data, aPos.second);
2396 const EditTextObject* pObj = sc::edittext_block::at(*aPos.first->data, aPos.second);
2398 if (aSSs.size() != 1)
2413 class FilterEntriesHandler
2443 if (nErr != FormulaError::NONE)
2447 if (!aErr.isEmpty())
2463 if ((nType & SvNumFormatType::DATE) && !(nType & SvNumFormatType::TIME))
2467 fVal = rtl::math::approxFloor(fVal);
2481 mrColumn(rColumn), mrFilterEntries(rFilterEntries) {}
2483 void operator() (
size_t nRow,
double fVal)
2486 processCell(nRow, aCell);
2492 processCell(nRow, aCell);
2498 processCell(nRow, aCell);
2504 processCell(nRow, aCell);
2507 void operator() (
const int nElemType,
size_t nRow,
size_t )
2519 processCell(nRow, aCell);
2529 FilterEntriesHandler aFunc(*
this, rFilterEntries);
2539 class StrCellIterator
2541 typedef std::pair<sc::CellStoreType::const_iterator,size_t> PosType;
2543 sc::CellStoreType::const_iterator miBeg;
2544 sc::CellStoreType::const_iterator miEnd;
2548 miBeg(rCells.
begin()), miEnd(rCells.
end()), mpDoc(pDoc)
2551 maPos = rCells.position(nStart);
2554 maPos.first = miEnd;
2557 bool valid()
const {
return (maPos.first != miEnd); }
2571 if (maPos.first == miBeg)
2575 maPos.second = maPos.first->size - 1;
2581 if (maPos.second > 0)
2591 if (maPos.first == miBeg)
2596 maPos.second = maPos.first->size - 1;
2612 if (maPos.first == miEnd)
2622 if (maPos.second >= maPos.first->size)
2628 if (maPos.first == miEnd)
2639 OUString
get()
const
2641 switch (maPos.first->type)
2644 return sc::string_block::at(*maPos.first->data, maPos.second).getString();
2647 const EditTextObject* p = sc::edittext_block::at(*maPos.first->data, maPos.second);
2663 #define DATENT_MAX 200
2664 #define DATENT_SEARCH 2000
2667 SCROW nStartRow, std::set<ScTypedStrData>& rStrings,
bool bLimit )
const
2673 StrCellIterator aItrUp(maCells, nStartRow, &GetDoc());
2674 StrCellIterator aItrDown(maCells, nStartRow+1, &GetDoc());
2676 bool bMoveUp = aItrUp.valid();
2682 bMoveUp = aItrUp.prev();
2684 bool bMoveDown = aItrDown.valid();
2685 if (bMoveDown && !aItrDown.has())
2686 bMoveDown = aItrDown.next();
2688 bool bFound =
false;
2689 size_t nCellsSearched = 0;
2690 while (bMoveUp || bMoveDown)
2695 OUString aStr = aItrUp.get();
2696 if (!aStr.isEmpty())
2699 if (bInserted && bLimit && rStrings.size() >=
DATENT_MAX)
2707 bMoveUp = aItrUp.prev();
2713 OUString aStr = aItrDown.get();
2714 if (!aStr.isEmpty())
2717 if (bInserted && bLimit && rStrings.size() >=
DATENT_MAX)
2725 bMoveDown = aItrDown.next();
2734 class FormulaToValueHandler
2741 Entry(
SCROW nRow,
double f) : mnRow(nRow), maValue(f) {}
2745 typedef std::vector<Entry> EntriesType;
2746 EntriesType maEntries;
2754 maEntries.emplace_back(nRow, p2->
GetValue());
2756 maEntries.emplace_back(nRow, p2->
GetString());
2759 void commitCells(
ScColumn& rColumn)
2764 for (
const Entry& r : maEntries)
2766 switch (r.maValue.meType)
2769 rColumn.
SetValue(aBlockPos, r.mnRow, r.maValue.mfValue,
false);
2772 rColumn.
SetRawString(aBlockPos, r.mnRow, *r.maValue.mpString,
false);
2785 FormulaToValueHandler aFunc;
2786 sc::CellStoreType::const_iterator itPos = maCells.begin();
2788 ScAttrIterator aAttrIter( pAttrArray.get(), nStartRow, nEndRow, GetDoc().GetDefPattern() );
2791 const ScPatternAttr* pPattern = aAttrIter.Next( nTop, nBottom );
2803 pPattern = aAttrIter.Next( nTop, nBottom );
2806 aFunc.commitCells(*
this);
2817 std::vector<SCROW> aNewSharedRows;
2818 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows,
true);
2819 it = maCells.set(it, nRow, pCell);
2822 CellStorageModified();
2824 AttachNewFormulaCell(it, nRow, *pCell, aNewSharedRows);
2836 SetRawString(nRow, aSS);
2844 std::vector<SCROW> aNewSharedRows;
2845 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows,
false);
2846 maCells.set(it, nRow, rStr);
2849 CellStorageModified();
2851 StartListeningUnshared( aNewSharedRows);
2853 BroadcastNewCell(nRow);
2862 std::vector<SCROW> aNewSharedRows;
2863 rBlockPos.
miCellPos = GetPositionToInsert(rBlockPos.
miCellPos, nRow, aNewSharedRows,
false);
2868 CellStorageModified();
2870 StartListeningUnshared( aNewSharedRows);
2873 BroadcastNewCell(nRow);
2881 std::vector<SCROW> aNewSharedRows;
2882 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows,
false);
2883 maCells.set(it, nRow, fVal);
2886 CellStorageModified();
2888 StartListeningUnshared( aNewSharedRows);
2890 BroadcastNewCell(nRow);
2899 std::vector<SCROW> aNewSharedRows;
2900 rBlockPos.
miCellPos = GetPositionToInsert(rBlockPos.
miCellPos, nRow, aNewSharedRows,
false);
2905 CellStorageModified();
2907 StartListeningUnshared( aNewSharedRows);
2910 BroadcastNewCell(nRow);
2919 sal_uInt32 nFormat = GetNumberFormat( pContext ? *pContext : GetDoc().GetNonThreadedContext(), nRow);
2920 const Color* pColor =
nullptr;
2922 pContext ? *(pContext->
GetFormatTable()) : *(GetDoc().GetFormatTable()), GetDoc());
2927 std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nRow);
2928 sc::CellStoreType::iterator it = aPos.first;
2929 if (it == maCells.end())
2935 return &sc::numeric_block::at(*it->data, aPos.second);
2940 sal_uLong nFormat = GetNumberFormat(GetDoc().GetNonThreadedContext(), nRow);
2946 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
2947 sc::CellStoreType::const_iterator it = aPos.first;
2951 return sc::numeric_block::at(*it->data, aPos.second);
2954 const ScFormulaCell* p = sc::formula_block::at(*it->data, aPos.second);
2967 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
2968 sc::CellStoreType::const_iterator it = aPos.first;
2969 if (it == maCells.end())
2975 return sc::edittext_block::at(*it->data, aPos.second);
2980 std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nRow);
2981 sc::CellStoreType::iterator it = aPos.first;
2982 if (it == maCells.end())
2988 EditTextObject* p = sc::edittext_block::at(*it->data, aPos.second);
3003 return FetchFormulaCell(nRow);
3013 switch (maCells.get_type(nRow))
3038 CellCounter() : mnCount(0) {}
3040 void operator() (
const sc::CellStoreType::value_type& node)
3045 mnCount += node.size;
3048 size_t getCount()
const {
return mnCount; }
3056 aFunc = std::for_each(maCells.begin(), maCells.end(), aFunc);
3057 return aFunc.getCount();
3062 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
3063 sc::CellStoreType::const_iterator it = aPos.first;
3064 if (it == maCells.end())
3065 return FormulaError::NONE;
3068 return FormulaError::NONE;
3070 const ScFormulaCell* p = sc::formula_block::at(*it->data, aPos.second);
3076 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
3077 switch (aPos.first->type)
3084 const ScFormulaCell* p = sc::formula_block::at(*aPos.first->data, aPos.second);
3096 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
3097 switch (aPos.first->type)
3103 const ScFormulaCell* p = sc::formula_block::at(*aPos.first->data, aPos.second);
3118 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nStartRow);
3119 sc::CellStoreType::const_iterator it = aPos.first;
3120 size_t nOffset = aPos.second;
3121 SCROW nRow = nStartRow;
3122 for (; it != maCells.end() && nRow <= nEndRow; ++it)
3127 nRow += it->size - nOffset;
3136 class MaxStringLenHandler
3141 rtl_TextEncoding meCharSet;
3142 bool mbOctetEncoding;
3146 const Color* pColor;
3151 if (mbOctetEncoding)
3154 if (!aString.convertToString(&aOString, meCharSet,
3155 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
3156 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
3163 nLen = aOString.getLength();
3168 if (mnMaxLen < nLen)
3173 MaxStringLenHandler(
const ScColumn& rColumn, rtl_TextEncoding eCharSet) :
3176 mpFormatter(rColumn.GetDoc().GetFormatTable()),
3177 meCharSet(eCharSet),
3178 mbOctetEncoding(rtl_isOctetTextEncoding(eCharSet))
3182 void operator() (
size_t nRow,
double fVal)
3185 processCell(nRow, aCell);
3191 processCell(nRow, aCell);
3197 processCell(nRow, aCell);
3203 processCell(nRow, aCell);
3206 sal_Int32 getMaxLen()
const {
return mnMaxLen; }
3213 MaxStringLenHandler aFunc(*
this, eCharSet);
3215 return aFunc.getMaxLen();
3220 class MaxNumStringLenHandler
3225 sal_uInt16 mnPrecision;
3226 sal_uInt16 mnMaxGeneralPrecision;
3231 sal_uInt16 nCellPrecision = mnMaxGeneralPrecision;
3242 nCellPrecision = mnPrecision;
3244 nCellPrecision = (mnMaxGeneralPrecision >= 15) ? 4 : mnMaxGeneralPrecision;
3248 if (!mbHaveSigned && fVal < 0.0)
3249 mbHaveSigned =
true;
3254 sal_uInt32 nFormat =
3256 if (nFormat % SV_COUNTRY_LANGUAGE_OFFSET)
3263 bool bThousand, bNegRed;
3264 sal_uInt16 nLeading;
3272 if (mnPrecision >= mnMaxGeneralPrecision)
3286 aString = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_F, nCellPrecision,
'.',
true);
3290 sal_Int32 nLen = aString.getLength();
3297 if (nFormat % SV_COUNTRY_LANGUAGE_OFFSET)
3302 aString = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_F, nCellPrecision,
'.',
true);
3303 nLen = aString.getLength();
3305 sal_Int32 nSep = aString.indexOf( aSep);
3307 nPrec = aString.getLength() - nSep - 1;
3312 mnPrecision = nPrec;
3317 sal_Int32 nTmp = aString.indexOf(aSep);
3319 nLen += mnPrecision + aSep.getLength();
3322 nTmp = aString.getLength() - (nTmp + aSep.getLength());
3323 if (nTmp != mnPrecision)
3324 nLen += mnPrecision - nTmp;
3334 if (mbHaveSigned && fVal >= 0.0)
3337 if (mnMaxLen < nLen)
3342 MaxNumStringLenHandler(
const ScColumn& rColumn, sal_uInt16 nMaxGeneralPrecision) :
3343 mrColumn(rColumn), mpFormatter(rColumn.GetDoc().GetFormatTable()),
3344 mnMaxLen(0), mnPrecision(0), mnMaxGeneralPrecision(nMaxGeneralPrecision),
3349 if (mnMaxGeneralPrecision > 15)
3350 mnMaxGeneralPrecision = 15;
3353 void operator() (
size_t nRow,
double fVal)
3356 processCell(nRow, aCell);
3362 processCell(nRow, aCell);
3365 sal_Int32 getMaxLen()
const {
return mnMaxLen; }
3367 sal_uInt16 getPrecision()
const {
return mnPrecision; }
3373 sal_uInt16& nPrecision,
SCROW nRowStart,
SCROW nRowEnd )
const
3375 sal_uInt16 nMaxGeneralPrecision = GetDoc().GetDocOptions().GetStdPrecision();
3376 MaxNumStringLenHandler aFunc(*
this, nMaxGeneralPrecision);
3378 nPrecision = aFunc.getPrecision();
3379 return aFunc.getMaxLen();
3384 class GroupFormulaCells
3386 std::vector<ScAddress>* mpGroupPos;
3389 explicit GroupFormulaCells(std::vector<ScAddress>* pGroupPos)
3390 : mpGroupPos(pGroupPos) {}
3392 void operator() (sc::CellStoreType::value_type& node)
3398 size_t nRow = node.position;
3400 sc::formula_block::iterator it = sc::formula_block::begin(*node.data);
3401 sc::formula_block::iterator itEnd = sc::formula_block::end(*node.data);
3410 std::advance(it, xPrevGrp->mnLength);
3411 nRow += xPrevGrp->mnLength;
3421 for (; it != itEnd; pPrev = pCur, xPrevGrp = xCurGrp)
3433 if (xCurGrp->mnLength > std::distance(it, itEnd))
3434 throw css::lang::IllegalArgumentException();
3435 std::advance(it, xCurGrp->mnLength);
3436 nRow += xCurGrp->mnLength;
3454 xPrevGrp->mnLength += xCurGrp->mnLength;
3456 sc::formula_block::iterator itGrpEnd = it;
3457 if (xCurGrp->mnLength > std::distance(itGrpEnd, itEnd))
3458 throw css::lang::IllegalArgumentException();
3459 std::advance(itGrpEnd, xCurGrp->mnLength);
3460 for (++it; it != itGrpEnd; ++it)
3465 nRow += xCurGrp->mnLength;
3471 ++xPrevGrp->mnLength;
3480 nRow += xCurGrp->mnLength;
3481 if (xCurGrp->mnLength > std::distance(it, itEnd))
3482 throw css::lang::IllegalArgumentException();
3483 std::advance(it, xCurGrp->mnLength);
3485 xCurGrp->mpTopCell = pPrev;
3486 ++xCurGrp->mnLength;
3500 mpGroupPos->push_back(pCur->
aPos);
3513 std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells(pGroupPos));
static bool parseSimpleNumber(const OUString &rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double &rVal)
Check if a given string is a simple decimal number (e.g.
Numeric values (and numeric results if InsertDeleteFlags::FORMULA is not set).
void InterpretDirtyCells(SCROW nRow1, SCROW nRow2)
const SfxItemPool * GetPool() const
Temporarily switch on/off auto calculation mode.
CellTextAttrStoreType::const_iterator miCellTextAttrPos
void MixMarked(sc::MixDocContext &rCxt, const ScMarkData &rMark, ScPasteFunc nFunction, bool bSkipEmpty, const ScColumn &rSrcCol)
::boost::intrusive_ptr< ScFormulaCellGroup > ScFormulaCellGroupRef
void DeleteRow(SCROW nStartRow, SCSIZE nSize, std::vector< ScAddress > *pGroupPos)
OUString getString() const
CellStoreType::const_iterator miCellPos
void CopyFromClip(sc::CopyFromClipContext &rCxt, SCROW nRow1, SCROW nRow2, tools::Long nDy, ScColumn &rColumn)
SharedString intern(const OUString &rStr)
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
void DeleteArea(SCROW nStartRow, SCROW nEndRow, InsertDeleteFlags nDelFlag, bool bBroadcast=true, sc::ColumnSpanSet *pBroadcastSpans=nullptr)
Store parameters used in the ScDocument::SetString() method.
std::unique_ptr< ScAttrArray > pAttrArray
bool mbHandleApostrophe
When true, treat input with a leading apostrophe as an escape character for a numeric value content...
ScDocument & GetDoc() const
void SetError(SCROW nRow, const FormulaError nError)
const SfxPoolItem & GetAttr(SCROW nRow, sal_uInt16 nWhich) const
Sheet / outlining (grouping) information.
SvNumberFormatter * mpNumFormatter
Stores the pointer to the number formatter instance to be used during number format detection...
Single reference (one address) into the sheet.
CellTextAttrStoreType::iterator miCellTextAttrPos
static void lcl_AddFormulaGroupBoundaries(const sc::CellStoreType::position_type &rPos, std::vector< SCROW > &rNewSharedRows)
const mdds::mtv::element_t element_type_celltextattr
FormulaError GetErrCode(SCROW nRow) const
bool mbCheckLinkFormula
When true and the string results in a compiled formula, check the formula tokens for presence of func...
void DuplicateNotes(SCROW nStartRow, size_t nDataSize, ScColumn &rDestCol, sc::ColumnBlockPosition &maDestBlockPos, bool bCloneCaption, SCROW nRowOffsetDest=0) const
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. ...
void SetEditText(SCROW nRow, std::unique_ptr< EditTextObject > pEditText)
CellStoreType::const_iterator ParseFormulaNumeric(const CellStoreType::const_iterator &itPos, const CellStoreType &rCells, SCROW nRow1, SCROW nRow2, Func &rFunc)
void BroadcastNewCell(SCROW nRow)
formula::FormulaToken * AddSingleReference(const ScSingleRefData &rRef)
ScSingleRefToken with ocPush.
void Broadcast(SCROW nRow)
Store position data for column array storage.
const ContentProperties & rData
InsertDeleteFlags getInsertFlag() const
bool IsClipOrUndo() const
bool isSkipAttrForEmptyCells() const
CellType GetCellType(SCROW nRow) const
void SetAbsRow(SCROW nVal)
CellStoreType::const_iterator ParseAllNonEmpty(const typename CellStoreType::const_iterator &itPos, const CellStoreType &rCells, SCROW nRow1, SCROW nRow2, Func &rFunc)
void BroadcastRows(SCROW nStartRow, SCROW nEndRow, SfxHintId nHint)
This is very similar to ScCellValue, except that it references the original value instead of copying ...
constexpr TypedWhichId< ScProtectionAttr > ATTR_PROTECTION(149)
mdds::multi_type_vector< CellFunc, CellStoreEvent > CellStoreType
void RemoveEditTextCharAttribs(SCROW nRow, const ScPatternAttr &rAttr)
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.
SC_DLLPUBLIC SvtScriptType GetStringScriptType(const OUString &rString)
const ScAddress & GetAddress() const
void StartListeners(sc::StartListeningContext &rCxt, bool bAll)
void GetFormula(SCROW nRow, OUString &rFormula) const
Internal use only (d&d undo): do not delete caption objects of cell notes.
TextFormatPolicy meSetTextNumFormat
Determine when to set the 'Text' number format to the cell where the input string is being set...
SC_DLLPUBLIC ScDocumentPool * GetPool()
void ParseFormula(const CellStoreType &rStore, Func &rFunc)
BroadcasterStoreType::iterator miBroadcasterPos
Store arbitrary cell value of any kind.
sal_Int32 GetMaxStringLen(SCROW nRowStart, SCROW nRowEnd, rtl_TextEncoding eCharSet) const
ScFormulaCell * SetFormulaCell(SCROW nRow, ScFormulaCell *pCell, sc::StartListeningType eListenType=sc::SingleCellListening, bool bInheritNumFormatIfNeeded=true)
Takes ownership of pCell.
SC_DLLPUBLIC ScConditionalFormatList * GetCondFormList(SCTAB nTab) const
const mdds::mtv::element_t element_type_formula
sc::CellStoreType::iterator GetPositionToInsert(SCROW nRow, std::vector< SCROW > &rNewSharedRows, bool bInsertFormula)
Keep track of spans in a single column only.
void SetText(const OUString &rStr)
ScRefCellValue GetCellValue(SCROW nRow) const
enumrange< T >::Iterator begin(enumrange< T >)
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const css::i18n::LocaleDataItem2 & getLocaleItem() const
bool IsMultiMarked() const
sc::CellStoreType maCells
ScDocument * getDestDoc()
static bool SafeMult(double &fVal1, double fVal2)
void push_back(const ScTypedStrData &r)
void set(const ScDocument &rDoc, SCTAB nTab, SCCOL nCol, SCROW nRow, bool bVal)
void CopyAreaSafe(SCROW nStartRow, SCROW nEndRow, tools::Long nDy, ScAttrArray &rAttrArray)
Leave flags summarized with CopyArea.
ScFormulaCell * mpFormula
void release(ScDocument &rDoc, const ScAddress &rPos)
Set cell value at specified position in specified document.
bool SetFormulaCells(SCROW nRow, std::vector< ScFormulaCell * > &rCells)
sal_uInt32 GetNumberFormat(const ScInterpreterContext &rContext, SCROW nRow) const
void EndListeningFormulaCells(std::vector< ScFormulaCell * > &rCells)
void DeleteContent(SCROW nRow, bool bBroadcast=true)
void AttachNewFormulaCells(const sc::CellStoreType::position_type &aPos, size_t nLength, std::vector< SCROW > &rNewSharedRows)
Internal use only (copy from clip): do not delete existing cell contents when pasting notes...
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
bool SetString(SCROW nRow, SCTAB nTab, const OUString &rString, formula::FormulaGrammar::AddressConvention eConv, const ScSetStringParam *pParam=nullptr)
Returns true if the cell format was set as well.
double GetValue(SCROW nRow) const
svl::SharedString GetSharedString(SCROW nRow) const
void getSpans(SpansType &rSpans) const
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
bool IsInsertingFromOtherDoc() const
void InitBlockPosition(sc::ColumnBlockPosition &rBlockPos)
void AttachNewFormulaCell(const sc::CellStoreType::iterator &itPos, SCROW nRow, ScFormulaCell &rCell, const std::vector< SCROW > &rNewSharedRows, bool bJoin=true, sc::StartListeningType eListenType=sc::SingleCellListening)
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
void SetRawString(SCROW nRow, const OUString &rStr)
void SetFlag3D(bool bVal)
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
void RegroupFormulaCells(std::vector< ScAddress > *pGroupPos=nullptr)
Regroup formula cells for the entire column.
SvtScriptType mnScriptType
Set Text number format only when the input string is considered a special number but we only want to ...
void SetAbsCol(SCCOL nVal)
bool GetHideFormula() const
sc::CellTextAttrStoreType maCellTextAttrs
SvNumberFormatter * GetFormatTable() const
void getRows(std::vector< SCROW > &rRows) const
static void JoinNewFormulaCell(const sc::CellStoreType::position_type &aPos, ScFormulaCell &rCell)
std::unique_ptr< EditTextObject > CreateTextObject()
const mdds::mtv::element_t element_type_empty
void set(SCROW nRow1, SCROW nRow2, bool bVal)
Structure that stores segments of boolean flags per column, and perform custom action on those segmen...
bool HasValueData(SCROW nRow) const
CellStoreType::const_iterator ParseAll(const typename CellStoreType::const_iterator &itPos, const CellStoreType &rCells, SCROW nRow1, SCROW nRow2, FuncElem &rFuncElem, FuncElse &rFuncElse)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
const mdds::mtv::element_t element_type_numeric
Mapped standard element types (for convenience).
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
bool HasStringData(SCROW nRow) const
double * GetValueCell(SCROW nRow)
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.
#define SV_COUNTRY_LANGUAGE_OFFSET
void SetAbsTab(SCTAB nVal)
void DetachFormulaCells(const sc::CellStoreType::position_type &aPos, size_t nLength, std::vector< SCROW > *pNewSharedRows)
SC_DLLPUBLIC const SfxItemSet * GetCondResult(SCCOL nCol, SCROW nRow, SCTAB nTab, ScRefCellValue *pCell=nullptr) const
void Broadcast(const ScHint &rHint)
Broadcast wrapper, calls rHint.GetCell()->Broadcast() and AreaBroadcast() and TrackFormulas() Preferr...
enumrange< T >::Iterator end(enumrange< T >)
CellStoreType::iterator miCellPos
void MixData(sc::MixDocContext &rCxt, SCROW nRow1, SCROW nRow2, ScPasteFunc nFunction, bool bSkipEmpty, const ScColumn &rSrcCol)
static bool SafePlus(double &fVal1, double fVal2)
virtual formula::FormulaToken * AddOpCode(OpCode eCode) override
static bool SafeDiv(double &fVal1, double fVal2)
NF_EVALDATEFORMAT_INTL_FORMAT
bool ParseString(ScCellValue &rCell, SCROW nRow, SCTAB nTab, const OUString &rString, formula::FormulaGrammar::AddressConvention eConv, const ScSetStringParam *pParam)
const EditTextObject * GetEditText(SCROW nRow) const
bool ValidRow(SCROW nRow) const
void SetFormula(SCROW nRow, const ScTokenArray &rArray, formula::FormulaGrammar::Grammar eGram)
bool mbDetectNumberFormat
When true, we try to detect special number format (dates etc) from the input string, when false, we only try to detect a basic decimal number format.
void RemoveProtected(SCROW nStartRow, SCROW nEndRow)
void AttachFormulaCells(sc::StartListeningContext &rCxt, SCROW nRow1, SCROW nRow2)
std::unique_ptr< ScAttrIterator > CreateAttrIterator(SCROW nStartRow, SCROW nEndRow) const
sc::CellTextAttrStoreType & GetCellAttrStore()
const mdds::mtv::element_t element_type_edittext
void InitFlags()
No default ctor, because used in ScRawToken union, set InitFlags!
Dates, times, datetime values.
void GetString(SCROW nRow, OUString &rString, const ScInterpreterContext *pContext=nullptr) const
CellNoteStoreType::iterator miCellNotePos
void ApplyPattern(SCROW nRow, const ScPatternAttr &rPatAttr)
void GetFilterEntries(sc::ColumnBlockConstPosition &rBlockPos, SCROW nStartRow, SCROW nEndRow, ScFilterEntries &rFilterEntries)
const ScFormulaCell * GetFormulaCell(SCROW nRow) const
bool isDateCell(const ScColumn &rCol, SCROW nRow) const
constexpr TypedWhichId< ScCondFormatItem > ATTR_CONDITIONAL(154)
std::vector< RowSpan > SpansType
Set Text number format if the input string can be parsed as a number or formula text.
static void RemoveCharAttribs(EditTextObject &rEditText, const ScPatternAttr &rAttr)
sal_Int32 GetMaxNumberStringLen(sal_uInt16 &nPrecision, SCROW nRowStart, SCROW nRowEnd) const
SCSIZE GetCellCount() const
void scan(const ScColumn &rColumn)
Scan an entire column and tag all non-empty cell positions.
void BroadcastCells(const std::vector< SCROW > &rRows, SfxHintId nHint)
sc::StartListeningType meStartListening
static SC_DLLPUBLIC OUString GetString(const EditTextObject &rEditText, const ScDocument *pDoc)
Retrieves string with paragraphs delimited by new lines (' ').
ScInterpreterContext & GetNonThreadedContext() const
void GetInputString(SCROW nRow, OUString &rString) const
bool ValidRow(SCROW nRow, SCROW nMaxRow)
const ScMultiSel & GetMultiSelData() const
void SetValue(SCROW nRow, double fVal)
Never set Text number format.
void DeleteCells(sc::ColumnBlockPosition &rBlockPos, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nDelFlag, sc::SingleColumnSpanSet &rDeleted)
bool IsCalcingAfterLoad() const
bool HasStringCells(SCROW nStartRow, SCROW nEndRow) const
Return true if there is a string or editcell in the range.
CellNoteStoreType::const_iterator miCellNotePos
NF_EVALDATEFORMAT_FORMAT_INTL
std::unique_ptr< EditTextObject > Clone() const
bool GetDataEntries(SCROW nRow, std::set< ScTypedStrData > &rStrings, bool bLimit) const
const mdds::mtv::element_t element_type_string
mdds::multi_type_vector< CTAttrFunc > CellTextAttrStoreType
sc::CellStoreType & GetCellStore()
static OUString GetErrorString(FormulaError nErrNumber)
Strings (and string results if InsertDeleteFlags::FORMULA is not set).
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
std::vector< svl::SharedString > GetSharedStrings() const
void StartListeningUnshared(const std::vector< SCROW > &rNewSharedRows)
Re-establish listeners on unshared formula groups.
ColumnBlockPosition * getBlockPosition(SCTAB nTab, SCCOL nCol)
void DetachFormulaCell(const sc::CellStoreType::position_type &aPos, ScFormulaCell &rCell, std::vector< SCROW > &rNewSharedRows)
Detach a formula cell that's about to be deleted, or removed from document storage (if that ever happ...
bool UpdateScriptType(sc::CellTextAttr &rAttr, SCROW nRow, sc::CellStoreType::iterator &itr)
bool isCloneNotes() const