tdf#173608: reapply "sc: Fix backward reference when copying a sheet"

This reverts commit 3da93d717e.

tdf#173608 is going to be fixed in a follow-up patch

Change-Id: Ib742c5df90f26e0be05ed0dfa696ff2f398000eb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211514
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Xisco Fauli
2026-09-28 17:38:33 +02:00
parent 689334c8b9
commit c2e373869e
10 changed files with 185 additions and 96 deletions
+1
View File
@@ -600,6 +600,7 @@ public:
bool GetDataEntries( SCROW nRow, std::set<ScTypedStrData>& rStrings) const;
void UpdateInsertTabAbs(SCTAB nNewPos);
void AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode);
bool TestTabRefAbs(SCTAB nTable) const;
bool GetNextSpellingCell(SCROW& nRow, bool bInSel, const ScMarkData& rData) const;
+1
View File
@@ -326,6 +326,7 @@ public:
void UpdateInsertTab( const sc::RefUpdateInsertTabContext& rCxt );
void UpdateInsertTabAbs(SCTAB nTable);
void AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode);
void UpdateDeleteTab( const sc::RefUpdateDeleteTabContext& rCxt );
void UpdateMoveTab( const sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo );
bool TestTabRefAbs(SCTAB nTable);
+1
View File
@@ -1326,6 +1326,7 @@ private:
void FillFormula(
const ScFormulaCell* pSrcCell, SCCOL nDestCol, SCROW nDestRow, bool bLast );
void UpdateInsertTabAbs(SCTAB nNewPos);
void AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode);
bool GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, bool bInSel,
const ScMarkData& rMark) const;
bool GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const;
+16 -6
View File
@@ -39,6 +39,13 @@ struct RefUpdateResult;
struct TokenStringContext;
class ColRowReorderMapType;
/** If the target tab was inserted, or an existing tab was used. */
enum class TargetTabState
{
Existing,
Inserted,
};
}
struct ScRawToken;
@@ -151,12 +158,15 @@ public:
*/
void AdjustAbsoluteRefs( const ScDocument& rOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCheckCopyArea );
/** Adjust relative tab references when copying a formula between tabs when
overwriting a tab. Non-zero relative tab offsets are decremented by
input delta value so they still resolve to the original target sheet
from the new position. Same-sheet relative refs with offset 0 are left
unchanged. */
void AdjustRelativeTabRefs(SCTAB nDelta);
/** Adjust relative tab references when copying a formula to a new table.
Non-zero relative tab offsets are recalculated so they still resolve
to the original target sheet from the new position. Same-sheet
relative refs (offset 0) are not modified.
If the target tab was newly inserted, the references pointing to
tabs at or after the insertion point are additionally shifted by
one. */
void AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab,
sc::TargetTabState eMode = sc::TargetTabState::Existing);
/** When copying a sheet-local named expression, move sheet references that
point to the originating sheet to point to the new sheet instead.
+103 -81
View File
@@ -7923,19 +7923,22 @@ CPPUNIT_TEST_FIXTURE(Test, testAutoFilterFlagsAfterColumnDeleteUndoRedo)
CPPUNIT_TEST_FIXTURE(Test, testCopyTabContent)
{
m_pDoc->InsertTab(0, u"Tab1"_ustr);
m_pDoc->InsertTab(1, u"Tab2"_ustr);
m_pDoc->InsertTab(2, u"Tab3"_ustr);
m_pDoc->InsertTab(0, u"Tab0"_ustr);
m_pDoc->InsertTab(1, u"Tab1"_ustr);
m_pDoc->InsertTab(2, u"Tab2"_ustr);
m_pDoc->InsertTab(3, u"Tab3"_ustr);
// For cross-sheet formula checking
m_pDoc->SetValue(ScAddress(0, 0, 2), 66.0);
// For cross-sheet formula checking (forward and backward)
m_pDoc->SetValue(ScAddress(0, 0, 0), 99.0); // Tab0.A1
m_pDoc->SetValue(ScAddress(0, 0, 3), 66.0); // Tab3.A1
std::vector<std::vector<OUString>> aData = {
{ u"Column 1"_ustr, u"Column 2"_ustr, u"Column 3"_ustr },
{ u"7"_ustr, u"A"_ustr, u"=A2+5"_ustr },
{ u"=2+2"_ustr, u"C"_ustr, u"=Tab3.A1"_ustr },
{ u"=A3-2"_ustr, u"D"_ustr, u"=SUM(A2:A5)"_ustr },
{ u"3"_ustr, u"B"_ustr, u"=C3-60"_ustr }
{ u"=2+2"_ustr, u"C"_ustr, u"=Tab3.A1"_ustr }, // forward cross-tab reference
{ u"=A3-2"_ustr, u"D"_ustr, u"=SUM(A2:A6)"_ustr },
{ u"3"_ustr, u"B"_ustr, u"=C3-60"_ustr },
{ u"5"_ustr, u"E"_ustr, u"=Tab0.A1"_ustr }, // backward cross-tab reference
};
for (size_t i = 0; i < aData.size(); ++i)
@@ -7944,123 +7947,142 @@ CPPUNIT_TEST_FIXTURE(Test, testCopyTabContent)
{
if (!aData[i][j].isEmpty())
{
m_pDoc->SetString(j, i, 0, aData[i][j]);
m_pDoc->SetString(j, i, 1, aData[i][j]);
}
}
}
m_pDoc->CalcAll();
// Verify Tab1 values and formulas before copy
{
CPPUNIT_ASSERT_EQUAL(7.0, m_pDoc->GetValue(ScAddress(0, 1, 0)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 0)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 0)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 0)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 0)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 0)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 0)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 0)));
CPPUNIT_ASSERT_EQUAL(12.0, m_pDoc->GetValue(ScAddress(2, 1, 0)));
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 0)));
CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(2, 3, 0)));
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 0)));
}
// Copy Tab1 to index 1 - Tab1_2
m_pDoc->CopyTab(0, 1);
CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(4), m_pDoc->GetTableCount());
// Tab3 value shifted from index 2 to index 3
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(0, 0, 3)));
// Tab1 (tab index 0) should be unchanged
{
CPPUNIT_ASSERT_EQUAL(7.0, m_pDoc->GetValue(ScAddress(0, 1, 0)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 0)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 0)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 0)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 0)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 0)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 0)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 0)));
CPPUNIT_ASSERT_EQUAL(12.0, m_pDoc->GetValue(ScAddress(2, 1, 0)));
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 0)));
CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(2, 3, 0)));
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 0)));
}
// The copy Tab1_2 (tab index 1) should have the same data as Tab1
{
CPPUNIT_ASSERT_EQUAL(7.0, m_pDoc->GetValue(ScAddress(0, 1, 1)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 1)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 1)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 1)));
CPPUNIT_ASSERT_EQUAL(5.0, m_pDoc->GetValue(ScAddress(0, 5, 1)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 1)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 1)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 1)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 1)));
CPPUNIT_ASSERT_EQUAL(u"E"_ustr, m_pDoc->GetString(ScAddress(1, 5, 1)));
CPPUNIT_ASSERT_EQUAL(12.0, m_pDoc->GetValue(ScAddress(2, 1, 1))); // =A2+5=12
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 1))); // =Tab3.A1
CPPUNIT_ASSERT_EQUAL(21.0, m_pDoc->GetValue(ScAddress(2, 3, 1))); // =SUM(A2:A6)
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 1))); // =C3-60
CPPUNIT_ASSERT_EQUAL(99.0, m_pDoc->GetValue(ScAddress(2, 5, 1))); // =Tab0.A1
}
// Copy Tab1 to index 2 - Tab1_2
m_pDoc->CopyTab(1, 2);
CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(5), m_pDoc->GetTableCount());
// Tab3 value shifted from index 3 to index 4
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(0, 0, 4)));
// Tab0 value stays at index 0
CPPUNIT_ASSERT_EQUAL(99.0, m_pDoc->GetValue(ScAddress(0, 0, 0)));
// Tab1 (tab index 1) should be unchanged
{
CPPUNIT_ASSERT_EQUAL(7.0, m_pDoc->GetValue(ScAddress(0, 1, 1)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 1)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 1)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 1)));
CPPUNIT_ASSERT_EQUAL(5.0, m_pDoc->GetValue(ScAddress(0, 5, 1)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 1)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 1)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 1)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 1)));
CPPUNIT_ASSERT_EQUAL(u"E"_ustr, m_pDoc->GetString(ScAddress(1, 5, 1)));
CPPUNIT_ASSERT_EQUAL(12.0, m_pDoc->GetValue(ScAddress(2, 1, 1)));
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 1)));
CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(2, 3, 1)));
CPPUNIT_ASSERT_EQUAL(21.0, m_pDoc->GetValue(ScAddress(2, 3, 1)));
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 1)));
CPPUNIT_ASSERT_EQUAL(99.0, m_pDoc->GetValue(ScAddress(2, 5, 1)));
}
// The copy Tab1_2 (tab index 2) should have the same data as Tab1
{
CPPUNIT_ASSERT_EQUAL(7.0, m_pDoc->GetValue(ScAddress(0, 1, 2)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 2)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 2)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 2)));
CPPUNIT_ASSERT_EQUAL(5.0, m_pDoc->GetValue(ScAddress(0, 5, 2)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 2)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 2)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 2)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 2)));
CPPUNIT_ASSERT_EQUAL(u"E"_ustr, m_pDoc->GetString(ScAddress(1, 5, 2)));
CPPUNIT_ASSERT_EQUAL(12.0, m_pDoc->GetValue(ScAddress(2, 1, 2)));
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 2)));
CPPUNIT_ASSERT_EQUAL(21.0, m_pDoc->GetValue(ScAddress(2, 3, 2)));
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 2)));
CPPUNIT_ASSERT_EQUAL(99.0, m_pDoc->GetValue(ScAddress(2, 5, 2)));
}
// Check the formulas in Tab1_2
{
CPPUNIT_ASSERT_EQUAL(u"=2+2"_ustr, m_pDoc->GetFormula(0, 2, 1));
CPPUNIT_ASSERT_EQUAL(u"=A3-2"_ustr, m_pDoc->GetFormula(0, 3, 1));
CPPUNIT_ASSERT_EQUAL(u"=A2+5"_ustr, m_pDoc->GetFormula(2, 1, 1));
CPPUNIT_ASSERT_EQUAL(u"='Tab3'.A1"_ustr, m_pDoc->GetFormula(2, 2, 1));
CPPUNIT_ASSERT_EQUAL(u"=SUM(A2:A5)"_ustr, m_pDoc->GetFormula(2, 3, 1));
CPPUNIT_ASSERT_EQUAL(u"=C3-60"_ustr, m_pDoc->GetFormula(2, 4, 1));
CPPUNIT_ASSERT_EQUAL(u"=2+2"_ustr, m_pDoc->GetFormula(0, 2, 2));
CPPUNIT_ASSERT_EQUAL(u"=A3-2"_ustr, m_pDoc->GetFormula(0, 3, 2));
CPPUNIT_ASSERT_EQUAL(u"=A2+5"_ustr, m_pDoc->GetFormula(2, 1, 2));
CPPUNIT_ASSERT_EQUAL(u"='Tab3'.A1"_ustr, m_pDoc->GetFormula(2, 2, 2));
CPPUNIT_ASSERT_EQUAL(u"=SUM(A2:A6)"_ustr, m_pDoc->GetFormula(2, 3, 2));
CPPUNIT_ASSERT_EQUAL(u"=C3-60"_ustr, m_pDoc->GetFormula(2, 4, 2));
CPPUNIT_ASSERT_EQUAL(u"=Tab0.A1"_ustr, m_pDoc->GetFormula(2, 5, 2));
}
// Change Tab1 and verify the copy is independent
m_pDoc->SetValue(ScAddress(0, 1, 0), 10.0); // 7 -> 10
m_pDoc->SetValue(ScAddress(0, 1, 1), 10.0); // 7 -> 10
m_pDoc->CalcAll();
// Tab1 should be changed
{
CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0, 1, 0)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 0)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 0)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 0)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 0)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 0)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 0)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 0)));
CPPUNIT_ASSERT_EQUAL(15.0, m_pDoc->GetValue(ScAddress(2, 1, 0)));
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 0)));
CPPUNIT_ASSERT_EQUAL(19.0, m_pDoc->GetValue(ScAddress(2, 3, 0)));
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 0)));
}
// No change in Tab1_2
{
CPPUNIT_ASSERT_EQUAL(7.0, m_pDoc->GetValue(ScAddress(0, 1, 1)));
CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0, 1, 1)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 1)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 1)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 1)));
CPPUNIT_ASSERT_EQUAL(5.0, m_pDoc->GetValue(ScAddress(0, 5, 1)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 1)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 1)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 1)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 1)));
CPPUNIT_ASSERT_EQUAL(u"E"_ustr, m_pDoc->GetString(ScAddress(1, 5, 1)));
CPPUNIT_ASSERT_EQUAL(12.0, m_pDoc->GetValue(ScAddress(2, 1, 1)));
CPPUNIT_ASSERT_EQUAL(15.0, m_pDoc->GetValue(ScAddress(2, 1, 1)));
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 1)));
CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(2, 3, 1)));
CPPUNIT_ASSERT_EQUAL(24.0, m_pDoc->GetValue(ScAddress(2, 3, 1))); // =SUM(A2:A6)=10+4+2+3+5
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 1)));
CPPUNIT_ASSERT_EQUAL(99.0, m_pDoc->GetValue(ScAddress(2, 5, 1)));
}
// No change in Tab1_2
{
CPPUNIT_ASSERT_EQUAL(7.0, m_pDoc->GetValue(ScAddress(0, 1, 2)));
CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(ScAddress(0, 2, 2)));
CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 3, 2)));
CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 4, 2)));
CPPUNIT_ASSERT_EQUAL(5.0, m_pDoc->GetValue(ScAddress(0, 5, 2)));
CPPUNIT_ASSERT_EQUAL(u"A"_ustr, m_pDoc->GetString(ScAddress(1, 1, 2)));
CPPUNIT_ASSERT_EQUAL(u"C"_ustr, m_pDoc->GetString(ScAddress(1, 2, 2)));
CPPUNIT_ASSERT_EQUAL(u"D"_ustr, m_pDoc->GetString(ScAddress(1, 3, 2)));
CPPUNIT_ASSERT_EQUAL(u"B"_ustr, m_pDoc->GetString(ScAddress(1, 4, 2)));
CPPUNIT_ASSERT_EQUAL(u"E"_ustr, m_pDoc->GetString(ScAddress(1, 5, 2)));
CPPUNIT_ASSERT_EQUAL(12.0, m_pDoc->GetValue(ScAddress(2, 1, 2)));
CPPUNIT_ASSERT_EQUAL(66.0, m_pDoc->GetValue(ScAddress(2, 2, 2)));
CPPUNIT_ASSERT_EQUAL(21.0, m_pDoc->GetValue(ScAddress(2, 3, 2)));
CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2, 4, 2)));
CPPUNIT_ASSERT_EQUAL(99.0, m_pDoc->GetValue(ScAddress(2, 5, 2)));
}
m_pDoc->DeleteTab(4);
m_pDoc->DeleteTab(3);
m_pDoc->DeleteTab(2);
m_pDoc->DeleteTab(1);
@@ -91,6 +91,7 @@ void sc::TableContentCopier::updateReferencesAfterTabInsertion(
sc::RefUpdateInsertTabContext& rContext)
{
mpTargetTab->UpdateInsertTabAbs(mnTargetTabNo);
mpTargetTab->AdjustRelativeTabRefs(mnSourceTabNo, mnTargetTabNo, sc::TargetTabState::Inserted);
mpSourceTab->UpdateInsertTab(rContext);
mpSourceTab->UpdateCompile();
}
+22
View File
@@ -2634,6 +2634,22 @@ public:
}
};
/** For adjusting relative tab references. */
class RelativeTabRefUpdater
{
SCTAB mnOldTab;
SCTAB mnNewTab;
sc::TargetTabState meMode;
public:
RelativeTabRefUpdater(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode) :
mnOldTab(nOldTab), mnNewTab(nNewTab), meMode(eMode) {}
void operator() (size_t /*nRow*/, ScFormulaCell* pCell)
{
pCell->AdjustRelativeTabRefs(mnOldTab, mnNewTab, meMode);
}
};
class UsedRangeNameFinder
{
sc::UpdatedRangeNames& mrIndexes;
@@ -3064,6 +3080,12 @@ void ScColumn::UpdateInsertTabAbs(SCTAB nNewPos)
CellStorageModified();
}
void ScColumn::AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode)
{
RelativeTabRefUpdater aFunc(nOldTab, nNewTab, eMode);
sc::ProcessFormula(maCells, aFunc);
}
void ScColumn::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo )
{
nTab = nTabNo;
+13 -2
View File
@@ -895,8 +895,7 @@ ScFormulaCell::ScFormulaCell(const ScFormulaCell& rCell, ScDocument& rDoc, const
if ((nCloneFlags & ScCloneFlags::AdjustCrossSheetRefs) != ScCloneFlags::Default)
{
SCTAB nDelta = aPos.Tab() - rCell.aPos.Tab();
pCode->AdjustRelativeTabRefs(nDelta);
pCode->AdjustRelativeTabRefs(rCell.aPos.Tab(), aPos.Tab());
}
}
@@ -4185,6 +4184,18 @@ void ScFormulaCell::UpdateInsertTabAbs(SCTAB nTable)
}
}
void ScFormulaCell::AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode)
{
if (rDocument.IsClipOrUndo())
return;
bool bAdjustCode = !mxGroup || mxGroup->mpTopCell == this;
if (!bAdjustCode)
return;
pCode->AdjustRelativeTabRefs(nOldTab, nNewTab, eMode);
}
bool ScFormulaCell::TestTabRefAbs(SCTAB nTable)
{
if (rDocument.IsClipOrUndo())
+6
View File
@@ -2756,6 +2756,12 @@ void ScTable::UpdateInsertTabAbs(SCTAB nTable)
aCol[i].UpdateInsertTabAbs(nTable);
}
void ScTable::AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode)
{
for (SCCOL i=0; i < aCol.size(); i++)
aCol[i].AdjustRelativeTabRefs(nOldTab, nNewTab, eMode);
}
bool ScTable::GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, bool bInSel,
const ScMarkData& rMark) const
{
+21 -7
View File
@@ -2627,8 +2627,25 @@ void ScTokenArray::AdjustAbsoluteRefs( const ScDocument& rOldDoc, const ScAddres
}
}
void ScTokenArray::AdjustRelativeTabRefs( SCTAB nDelta )
namespace
{
void adjustRelativeTabRef(ScSingleRefData& rRef, SCTAB nOldTab, SCTAB nNewTab, bool bInsertedTab)
{
if (!rRef.IsTabRel() || rRef.Tab() == 0)
return;
SCTAB nAbsTarget = nOldTab + rRef.Tab();
if (bInsertedTab && nAbsTarget >= nNewTab)
nAbsTarget++;
SCTAB nNewOffset = nAbsTarget - nNewTab;
rRef.IncTab(nNewOffset - rRef.Tab());
}
} // anonymous namespace
void ScTokenArray::AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, sc::TargetTabState eMode)
{
const bool bInsertedTab = (eMode == sc::TargetTabState::Inserted);
TokenPointers aPtrs( pCode.get(), nLen, pRPN.get(), nRPN, true);
for (size_t j=0; j<2; ++j)
{
@@ -2645,17 +2662,14 @@ void ScTokenArray::AdjustRelativeTabRefs( SCTAB nDelta )
case svDoubleRef:
{
ScComplexRefData& rRef = static_cast<ScDoubleRefToken*>(p)->GetDoubleRef();
if (rRef.Ref1.IsTabRel() && rRef.Ref1.Tab() != 0)
rRef.Ref1.IncTab(-nDelta);
if (rRef.Ref2.IsTabRel() && rRef.Ref2.Tab() != 0)
rRef.Ref2.IncTab(-nDelta);
adjustRelativeTabRef(rRef.Ref1, nOldTab, nNewTab, bInsertedTab);
adjustRelativeTabRef(rRef.Ref2, nOldTab, nNewTab, bInsertedTab);
break;
}
case svSingleRef:
{
ScSingleRefData& rRef = static_cast<ScSingleRefToken*>(p)->GetSingleRef();
if (rRef.IsTabRel() && rRef.Tab() != 0)
rRef.IncTab(-nDelta);
adjustRelativeTabRef(rRef, nOldTab, nNewTab, bInsertedTab);
break;
}
default: