26#include <document.hxx>
28#include <compiler.hxx>
35using ::formula::FormulaGrammar;
40class FindEnclosingRange
43 explicit FindEnclosingRange(
const T& rTest) : mrTest(rTest) {}
44 bool operator() (
const ScRange & rRange)
const
53class FindIntersectingRange
56 explicit FindIntersectingRange(
const T& rTest) : mrTest(rTest) {}
57 bool operator() (
const ScRange & rRange)
const
68 CountCells() : mnCellCount(0) {}
70 void operator() (
const ScRange & r)
78 sal_uInt64 getCellCount()
const {
return mnCellCount; }
81 sal_uInt64 mnCellCount;
103 const SCTAB nTab = nDefaultTab;
147 aBuf.append(r.Format(rDoc, nFlags, eConv, bFullAddressNotation));
149 rStr =
aBuf.makeStringAndClear();
181 if (rLast.
aEnd.
Row() + 1 == nRow1 &&
193 bool bJoinedInput =
false;
194 const ScRange* pOver = &rNewRange;
206 size_t nOverPos = std::numeric_limits<size_t>::max();
210 if ( &rRange == pOver )
215 bool bJoined =
false;
229 else if ( pOver->
Contains( rRange ) )
234 if ( !bJoined && rRange.
aStart.
Tab() == nTab1 && rRange.
aEnd.
Tab() == nTab2 )
244 else if ( rRange.
aEnd.
Row() >= nRow1-1 &&
259 else if ( rRange.
aEnd.
Col() >= nCol1-1 &&
271 if (nOverPos != std::numeric_limits<size_t>::max())
279 for (
size_t nOver = 0, nRanges =
maRanges.size(); nOver < nRanges; ++nOver)
292 goto Label_Range_Join;
295 if ( !bIsInList && !bJoinedInput )
325 while (it !=
maRanges.rend() && it->aStart.Row() >= (rNewRange.
aStart.
Row() - 2))
329 if (rLast.
aEnd.
Row() + 1 == nRow1 &&
370 bool bChanged =
false;
377 rWhere.
GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
386 bChanged =
DeleteArea(nCol1+nDx, nRow1, nTab1, nCol1-1, nRow2, nTab2);
390 bChanged =
DeleteArea(nCol1, nRow1+nDy, nTab1, nCol2, nRow1-1, nTab2);
392 SAL_WARN_IF(nDx < 0 && nDy < 0,
"sc",
"nDx and nDy are negative, check why");
407 rR.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
409 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
411 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 )
415 rR.aStart.Set( theCol1, theRow1, theTab1 );
416 rR.aEnd.Set( theCol2, theRow2, theTab2 );
424 if( nDx < 0 || nDy < 0 )
427 for(
size_t i =
n-1;
i > 0;)
444 std::vector<ScRange> aNewRanges;
447 if(rRange.aStart.Tab() <= nTab && rRange.aEnd.Tab() >= nTab)
449 if(rRange.aEnd.Row() == nRowPos - 1 && (nColStart <= rRange.aEnd.Col() || nColEnd >= rRange.aStart.Col()))
451 SCCOL nNewRangeStartCol = std::max<SCCOL>(nColStart, rRange.aStart.Col());
452 SCCOL nNewRangeEndCol = std::min<SCCOL>(nColEnd, rRange.aEnd.Col());
453 SCROW nNewRangeStartRow = rRange.aEnd.Row() + 1;
454 SCROW nNewRangeEndRow = nRowPos + nSize - 1;
455 aNewRanges.emplace_back(nNewRangeStartCol, nNewRangeStartRow, nTab, nNewRangeEndCol,
456 nNewRangeEndRow, nTab);
463 for(
const auto & rRange : aNewRanges)
465 if(!rRange.IsValid())
474 std::vector<ScRange> aNewRanges;
477 if(rRange.aStart.Tab() <= nTab && rRange.aEnd.Tab() >= nTab)
479 if(rRange.aEnd.Col() == nColPos - 1 && (nRowStart <= rRange.aEnd.Row() || nRowEnd >= rRange.aStart.Row()))
481 SCROW nNewRangeStartRow = std::max<SCROW>(nRowStart, rRange.aStart.Row());
482 SCROW nNewRangeEndRow = std::min<SCROW>(nRowEnd, rRange.aEnd.Row());
483 SCCOL nNewRangeStartCol = rRange.aEnd.Col() + 1;
484 SCCOL nNewRangeEndCol = nColPos + nSize - 1;
485 aNewRanges.emplace_back(nNewRangeStartCol, nNewRangeStartRow, nTab, nNewRangeEndCol,
486 nNewRangeEndRow, nTab);
491 for(
const auto & rRange : aNewRanges)
493 if(!rRange.IsValid())
502 std::vector<ScRange> aNewRanges;
505 if(rRange.aStart.Tab() <= nTab && rRange.aEnd.Tab() >= nTab)
507 if(rRange.aEnd.Col() == nCol - 1)
509 SCCOL nNewRangeStartCol = rRange.aEnd.Col() + 1;
510 SCCOL nNewRangeEndCol = nCol;
511 aNewRanges.emplace_back(nNewRangeStartCol, rRange.aStart.Row(), nTab, nNewRangeEndCol,
512 rRange.aEnd.Row(), nTab);
517 for(
const auto & rRange : aNewRanges)
519 if(!rRange.IsValid())
547template<
typename X,
typename Y>
548bool checkForOneRange(
549 X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
551 return nDeleteX1 <= nX1 && nX2 <= nDeleteX2 && (nDeleteY1 <= nY1 || nY2 <= nDeleteY2);
560 SCCOL nDeleteCol1 = rDelStart.
Col();
562 SCROW nDeleteRow1 = rDelStart.
Row();
569 if (checkForOneRange(nDeleteCol1, nDeleteCol2, nDeleteRow1, nDeleteRow2, nCol1, nCol2, nRow1, nRow2))
572 if (nDeleteRow1 <= nRow1)
583 else if (nRow2 <= nDeleteRow2)
595 else if (checkForOneRange(nDeleteRow1, nDeleteRow2, nDeleteCol1, nDeleteCol2, nRow1, nRow2, nCol1, nCol2))
598 if (nDeleteCol1 <= nCol1)
609 else if (nCol2 <= nDeleteCol2)
624bool handleTwoRanges(
const ScRange& rDeleteRange,
ScRange& r, std::vector<ScRange>& rNewRanges )
630 SCCOL nDeleteCol1 = rDelStart.
Col();
632 SCROW nDeleteRow1 = rDelStart.
Row();
640 if (nCol1 < nDeleteCol1 && nDeleteCol1 <= nCol2 && nCol2 <= nDeleteCol2)
644 if (nRow1 < nDeleteRow1 && nDeleteRow1 <= nRow2 && nRow2 <= nDeleteRow2)
657 ScRange aNewRange( nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nRow2, nTab );
658 rNewRanges.push_back(aNewRange);
663 else if (nRow1 <= nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
677 rNewRanges.push_back(aNewRange);
683 else if (nCol1 <= nDeleteCol2 && nDeleteCol2 < nCol2 && nDeleteCol1 <= nCol1)
687 if (nRow1 < nDeleteRow1 && nDeleteRow1 <= nRow2 && nRow2 <= nDeleteRow2)
702 rNewRanges.push_back(aNewRange);
707 else if (nRow1 <= nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
720 ScRange aNewRange(nDeleteCol2+1, nRow1, nTab, nCol2, nDeleteRow2, nTab);
721 rNewRanges.push_back(aNewRange);
727 else if (nRow1 < nDeleteRow1 && nDeleteRow2 < nRow2 && nDeleteCol1 <= nCol1 && nCol2 <= nDeleteCol2)
738 rNewRanges.push_back(aNewRange);
743 else if (nCol1 < nDeleteCol1 && nDeleteCol2 < nCol2 && nDeleteRow1 <= nRow1 && nRow2 <= nDeleteRow2)
754 rNewRanges.push_back(aNewRange);
787template<
typename X,
typename Y>
788bool checkForThreeRanges(
789 X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
791 if (nX1 <= nDeleteX1 && nX2 <= nDeleteX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
794 if (nDeleteX1 <= nX1 && nDeleteX2 <= nX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
800bool handleThreeRanges(
const ScRange& rDeleteRange,
ScRange& r, std::vector<ScRange>& rNewRanges )
806 SCCOL nDeleteCol1 = rDelStart.
Col();
808 SCROW nDeleteRow1 = rDelStart.
Row();
816 if (checkForThreeRanges(nDeleteCol1, nDeleteCol2, nDeleteRow1, nDeleteRow2, nCol1, nCol2, nRow1, nRow2))
818 if (nCol1 < nDeleteCol1)
828 ScRange aNewRange(nDeleteCol1, nRow1, nTab, nCol2, nDeleteRow1-1, nTab);
829 rNewRanges.push_back(aNewRange);
832 rNewRanges.push_back(aNewRange);
847 rNewRanges.push_back(aNewRange);
849 aNewRange =
ScRange(nCol1, nDeleteRow2+1, nTab, nDeleteCol2, nRow2, nTab);
850 rNewRanges.push_back(aNewRange);
856 else if (checkForThreeRanges(nDeleteRow1, nDeleteRow2, nDeleteCol1, nDeleteCol2, nRow1, nRow2, nCol1, nCol2))
858 if (nRow1 < nDeleteRow1)
870 ScRange aNewRange(nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nRow2, nTab);
871 rNewRanges.push_back( aNewRange );
874 rNewRanges.push_back( aNewRange );
890 rNewRanges.push_back(aNewRange);
892 aNewRange =
ScRange(nDeleteCol2+1, nRow1, nTab, nCol2, nDeleteRow2, nTab);
893 rNewRanges.push_back( aNewRange );
903bool handleFourRanges(
const ScRange& rDelRange,
ScRange& r, std::vector<ScRange>& rNewRanges )
909 SCCOL nDeleteCol1 = rDelStart.
Col();
911 SCROW nDeleteRow1 = rDelStart.
Row();
919 if (nCol1 < nDeleteCol1 && nDeleteCol2 < nCol2 && nRow1 < nDeleteRow1 && nDeleteRow2 < nRow2)
933 rNewRanges.push_back( aNewRange );
935 aNewRange =
ScRange(nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nDeleteRow2, nTab);
936 rNewRanges.push_back( aNewRange );
938 aNewRange =
ScRange(nDeleteCol2+1, nDeleteRow1, nTab, nCol2, nDeleteRow2, nTab);
939 rNewRanges.push_back( aNewRange );
954 bool bChanged =
false;
955 ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
967 std::vector<ScRange> aNewRanges;
975 if(!rRange.Intersects(aRange))
986 if(handleOneRange( aRange, rRange ))
994 else if(handleTwoRanges( aRange, rRange, aNewRanges ))
1006 else if(handleThreeRanges( aRange, rRange, aNewRanges ))
1015 else if(handleFourRanges( aRange, rRange, aNewRanges ))
1021 for(
const auto & rRange : aNewRanges)
1031 return itr ==
maRanges.end() ? nullptr : &*itr;
1038 return itr ==
maRanges.end() ? nullptr : &*itr;
1045 maRanges(rList.maRanges),
1046 mnMaxRowUsed(rList.mnMaxRowUsed)
1051 maRanges(std::move(rList.maRanges)),
1052 mnMaxRowUsed(rList.mnMaxRowUsed)
1072 maRanges = std::move(rList.maRanges);
1073 mnMaxRowUsed = rList.mnMaxRowUsed;
1079 return std::any_of(
maRanges.begin(),
maRanges.end(), FindIntersectingRange<ScRange>(rRange));
1084 return std::any_of(
maRanges.begin(),
maRanges.end(), FindEnclosingRange<ScRange>(rRange));
1115 for (; itr != itrEnd; ++itr)
1156 for(
size_t i = 1,
n =
size();
i <
n; ++
i)
1170 if(rR.Intersects(rRange))
1172 SCCOL nColStart1, nColEnd1, nColStart2, nColEnd2;
1173 SCROW nRowStart1, nRowEnd1, nRowStart2, nRowEnd2;
1174 SCTAB nTabStart1, nTabEnd1, nTabStart2, nTabEnd2;
1175 rR.GetVars(nColStart1, nRowStart1, nTabStart1,
1176 nColEnd1, nRowEnd1, nTabEnd1);
1177 rRange.
GetVars(nColStart2, nRowStart2, nTabStart2,
1178 nColEnd2, nRowEnd2, nTabEnd2);
1180 ScRange aNewRange(std::max<SCCOL>(nColStart1, nColStart2), std::max<SCROW>(nRowStart1, nRowStart2),
1181 std::max<SCTAB>(nTabStart1, nTabStart2), std::min<SCCOL>(nColEnd1, nColEnd2),
1182 std::min<SCROW>(nRowEnd1, nRowEnd2), std::min<SCTAB>(nTabEnd1, nTabEnd2));
1183 aReturn.
Join(aNewRange);
1242 rWhere.
GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
1245 for ( sal_uInt16 j=0; j<2; j++ )
1247 ScRange& rRange = rR.GetRange(j);
1254 rRange.
GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 );
1256 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
1258 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 )
1261 rRange.
aStart.
Set( theCol1, theRow1, theTab1 );
1262 rRange.
aEnd.
Set( theCol2, theRow2, theTab2 );
1273 const ScRange & rRange = rR.GetRange(0);
1274 return (rRange.aStart.Tab() == nTab) && (rRange.aEnd.Tab() == nTab);
1283 if ( rR.GetRange(0).Contains( rAdr ) )
1293 if ( rR.GetRange(0) == rRange )
1311class ScRangePairList_sortNameCompare
1314 ScRangePairList_sortNameCompare(
ScDocument& rDoc) : mrDoc(rDoc) {}
1320 OUString aStr1, aStr2;
1322 if ( rStartPos1.
Tab() == rStartPos2.
Tab() )
1326 mrDoc.GetName( rStartPos1.
Tab(), aStr1 );
1327 mrDoc.GetName( rStartPos2.
Tab(), aStr2 );
1340 if ( rStartPos1.
Col() < rStartPos2.
Col() )
1342 if ( rStartPos1.
Col() > rStartPos2.
Col() )
1345 if ( rStartPos1.
Row() < rStartPos2.
Row() )
1347 if ( rStartPos1.
Row() > rStartPos2.
Row() )
1353 if ( rEndPos1.
Tab() == rEndPos2.
Tab() )
1357 mrDoc.GetName( rEndPos1.
Tab(), aStr1 );
1358 mrDoc.GetName( rEndPos2.
Tab(), aStr2 );
1371 if ( rEndPos1.
Col() < rEndPos2.
Col() )
1373 if ( rEndPos1.
Col() > rEndPos2.
Col() )
1376 if ( rEndPos1.
Row() < rEndPos2.
Row() )
1378 if ( rEndPos1.
Row() > rEndPos2.
Row() )
1397 bool bJoinedInput =
false;
1400Label_RangePair_Join:
1412 size_t nOverPos = std::numeric_limits<size_t>::max();
1416 if ( &rPair == pOver )
1421 bool bJoined =
false;
1432 bJoinedInput =
true;
1457 else if ( rp1.
aEnd.
Row() == nRow1-1
1476 else if ( rp1.
aEnd.
Col() == nCol1-1
1489 if (nOverPos != std::numeric_limits<size_t>::max())
1497 for (
size_t nOver = 0, nRangePairs =
maPairs.size(); nOver < nRangePairs; ++nOver)
1508 bJoinedInput =
true;
1511 goto Label_RangePair_Join;
1514 if ( !bIsInList && !bJoinedInput )
1520 std::vector<const ScRangePair*> aSortedVec(
maPairs.size());
1522 for (
auto const & rPair :
maPairs)
1524 aSortedVec[
i++] = &rPair;
1527 std::sort( aSortedVec.begin(), aSortedVec.end(), ScRangePairList_sortNameCompare(rDoc) );
void applyStartToEndFlags(ScRefFlags &target, const ScRefFlags source)
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 ...
sal_Int32 compareString(const OUString &s1, const OUString &s2) const
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
static SC_DLLPUBLIC CollatorWrapper & GetCollator()
case-insensitive collator
bool Intersects(const ScRange &) const
ScRangeList & operator=(const ScRangeList &rList)
::std::vector< ScRange > maRanges
void AddAndPartialCombine(const ScRange &)
bool operator==(const ScRangeList &) const
sal_uInt64 GetCellCount() const
void InsertRow(SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, SCROW nRowPos, SCSIZE nSize)
bool operator!=(const ScRangeList &r) const
void swap(ScRangeList &r)
const ScRange * Find(const ScAddress &) const
ScAddress GetTopLeftCorner() const
void Format(OUString &, ScRefFlags nFlags, const ScDocument &, formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_OOO, sal_Unicode cDelimiter=0, bool bFullAddressNotation=false) const
void InsertCol(SCTAB nTab, SCROW nRowStart, SCROW nRowEnd, SCCOL nColPos, SCSIZE nSize)
void Join(const ScRange &, bool bIsInList=false)
bool DeleteArea(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
For now this method assumes that nTab1 == nTab2 The algorithm will be much more complicated if nTab1 ...
bool Contains(const ScRange &) const
virtual ~ScRangeList() override
ScRangeList GetIntersectedRange(const ScRange &rRange) const
void push_back(const ScRange &rRange)
bool UpdateReference(UpdateRefMode, const ScDocument *, const ScRange &rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz)
ScRefFlags Parse(std::u16string_view, const ScDocument &, formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_OOO, SCTAB nDefaultTab=0, sal_Unicode cDelimiter=0)
ScRangePair * Find(const ScAddress &)
ScRangePairList * Clone() const
void Append(const ScRangePair &rRangePair)
void UpdateReference(UpdateRefMode, const ScDocument *, const ScRange &rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz)
::std::vector< ScRangePair > maPairs
void DeleteOnTab(SCTAB nTab)
void Join(const ScRangePair &, bool bIsInList=false)
ScRangePair & operator[](size_t idx)
std::vector< const ScRangePair * > CreateNameSortedArray(ScDocument &) const
virtual ~ScRangePairList() override
const ScRange & GetRange(sal_uInt16 n) const
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
bool Intersects(const ScRange &rRange) const
bool Contains(const ScAddress &) const
is Address& fully in Range?
ScRefFlags ParseAny(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
static ScRefUpdateRes Update(const ScDocument *pDoc, UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCCOL nDx, SCROW nDy, SCTAB nDz, SCCOL &theCol1, SCROW &theRow1, SCTAB &theTab1, SCCOL &theCol2, SCROW &theRow2, SCTAB &theTab2)
#define SAL_WARN_IF(condition, area, stream)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
@ UR_NOTHING
Reference not affected, no change at all.
const sal_Unicode cDelimiter