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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user