sc/inc/tokenarray.hxx | 2 sc/qa/unit/data/xls/shared-formula/wrapped-refs.xls |binary sc/qa/unit/subsequent_filters-test.cxx | 30 +++++++++++++ sc/source/core/tool/token.cxx | 46 ++++++++++++++++++++ sc/source/filter/excel/excform.cxx | 4 + sc/source/filter/excel/impop.cxx | 1 6 files changed, 82 insertions(+), 1 deletion(-)
New commits: commit c6c286f14468d341f5fd88edc39a37175a1b6caa Author: Kohei Yoshida <[email protected]> Date: Fri Apr 25 23:21:22 2014 -0400 fdo#76611: Wrap reference addresses at max boundaries. When importing shared formula tokens. Change-Id: I7e1a05a78c3a93330476516e0459cffb668e3f66 diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index c7f2242..7244790 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -204,6 +204,8 @@ public: */ OUString CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const; + void WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ); + #if DEBUG_FORMULA_COMPILER void Dump() const; #endif diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 58f64cc..8bb53c3 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3737,6 +3737,52 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre return aBuf.makeStringAndClear(); } +namespace { + +void wrapAddress( ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ) +{ + if (rPos.Col() > nMaxCol) + rPos.SetCol(rPos.Col() - nMaxCol - 1); + if (rPos.Row() > nMaxRow) + rPos.SetRow(rPos.Row() - nMaxRow - 1); +} + +} + +void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ) +{ + FormulaToken** p = pCode; + FormulaToken** pEnd = p + static_cast<size_t>(nLen); + for (; p != pEnd; ++p) + { + switch ((*p)->GetType()) + { + case svSingleRef: + { + ScToken* pToken = static_cast<ScToken*>(*p); + ScSingleRefData& rRef = pToken->GetSingleRef(); + ScAddress aAbs = rRef.toAbs(rPos); + wrapAddress(aAbs, nMaxCol, nMaxRow); + rRef.SetAddress(aAbs, rPos); + } + break; + case svDoubleRef: + { + ScToken* pToken = static_cast<ScToken*>(*p); + ScComplexRefData& rRef = pToken->GetDoubleRef(); + ScRange aAbs = rRef.toAbs(rPos); + wrapAddress(aAbs.aStart, nMaxCol, nMaxRow); + wrapAddress(aAbs.aEnd, nMaxCol, nMaxRow); + aAbs.PutInOrder(); + rRef.SetRange(aAbs, rPos); + } + break; + default: + ; + } + } +} + #if DEBUG_FORMULA_COMPILER void ScTokenArray::Dump() const { diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx index cc85f4f..07174ea 100644 --- a/sc/source/filter/excel/excform.cxx +++ b/sc/source/filter/excel/excform.cxx @@ -128,7 +128,8 @@ void ImportExcel::Formula( const ScTokenArray* pSharedCode = pFormConv->GetSharedFormula(aRefPos); if (pSharedCode) { - ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, *pSharedCode); + ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, pSharedCode->Clone()); + pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8); rDoc.getDoc().EnsureTable(aScPos.Tab()); rDoc.setFormulaCell(aScPos, pCell); pCell->SetNeedNumberFormat(false); @@ -156,6 +157,7 @@ void ImportExcel::Formula( if (pResult) { pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, *pResult); + pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8); rDoc.getDoc().EnsureTable(aScPos.Tab()); rDoc.setFormulaCell(aScPos, pCell); SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell); diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx index bf55311..27cf7de 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -877,6 +877,7 @@ void ImportExcel::Shrfmla( void ) ScDocumentImport& rDoc = GetDocImport(); ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis); + pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8); rDoc.getDoc().EnsureTable(aPos.Tab()); rDoc.setFormulaCell(aPos, pCell); pCell->SetNeedNumberFormat(false); commit 1f70bfcd415cde8d0e0423525b3bdc1f471f1894 Author: Kohei Yoshida <[email protected]> Date: Fri Apr 25 23:32:03 2014 -0400 fdo#76611: Write test for this. Change-Id: Ib2852ccf8c19f9ed0fc5edda0b197d9801affae6 diff --git a/sc/qa/unit/data/xls/shared-formula/wrapped-refs.xls b/sc/qa/unit/data/xls/shared-formula/wrapped-refs.xls new file mode 100644 index 0000000..72487ce Binary files /dev/null and b/sc/qa/unit/data/xls/shared-formula/wrapped-refs.xls differ diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index 7482bed..8870b9b 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -169,6 +169,7 @@ public: void testColumnStyleXLSX(); void testSharedFormulaHorizontalXLS(); + void testSharedFormulaWrappedRefsXLS(); void testExternalRefCacheXLSX(); void testExternalRefCacheODS(); @@ -244,6 +245,7 @@ public: CPPUNIT_TEST(testOutlineODS); CPPUNIT_TEST(testColumnStyleXLSX); CPPUNIT_TEST(testSharedFormulaHorizontalXLS); + CPPUNIT_TEST(testSharedFormulaWrappedRefsXLS); CPPUNIT_TEST(testExternalRefCacheXLSX); CPPUNIT_TEST(testExternalRefCacheODS); CPPUNIT_TEST_SUITE_END(); @@ -2481,6 +2483,34 @@ void ScFiltersTest::testSharedFormulaHorizontalXLS() xDocSh->DoClose(); } +void ScFiltersTest::testSharedFormulaWrappedRefsXLS() +{ + ScDocShellRef xDocSh = loadDoc("shared-formula/wrapped-refs.", XLS); + CPPUNIT_ASSERT(xDocSh.Is()); + ScDocument* pDoc = xDocSh->GetDocument(); + pDoc->CalcAll(); + + // Check the values of H7:H10. + CPPUNIT_ASSERT_EQUAL(7.0, pDoc->GetValue(ScAddress(7,6,0))); + CPPUNIT_ASSERT_EQUAL(8.0, pDoc->GetValue(ScAddress(7,7,0))); + CPPUNIT_ASSERT_EQUAL(9.0, pDoc->GetValue(ScAddress(7,8,0))); + CPPUNIT_ASSERT_EQUAL(10.0, pDoc->GetValue(ScAddress(7,9,0))); + + // EM7:EM10 should reference H7:H10. + CPPUNIT_ASSERT_EQUAL(7.0, pDoc->GetValue(ScAddress(142,6,0))); + CPPUNIT_ASSERT_EQUAL(8.0, pDoc->GetValue(ScAddress(142,7,0))); + CPPUNIT_ASSERT_EQUAL(9.0, pDoc->GetValue(ScAddress(142,8,0))); + CPPUNIT_ASSERT_EQUAL(10.0, pDoc->GetValue(ScAddress(142,9,0))); + + // Make sure EM7:EM10 are grouped. + const ScFormulaCell *pFC = pDoc->GetFormulaCell(ScAddress(142,6,0)); + CPPUNIT_ASSERT(pFC); + CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(6), pFC->GetSharedTopRow()); + CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength()); + + xDocSh->DoClose(); +} + void ScFiltersTest::testExternalRefCacheXLSX() { ScDocShellRef xDocSh = loadDoc("external-refs.", XLSX); _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
