diff options
author | yogesh.bharate001 <yogesh.bharate@synerzip.com> | 2015-06-02 16:39:09 +0530 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2015-06-12 14:41:54 +0000 |
commit | beb8e2830dc9e1c771e196fcaf08cdfd6bf3dde3 (patch) | |
tree | f3569a3e838b1cd986e67d9bc7244236691504b8 | |
parent | 5afa25c62c73b84e3f334ce7fdd4d9fa260574d0 (diff) |
tdf#61908:XLSX formula cell range is not exported for MMULT.
Problem Description:
- Matrix multiplication cell formula range is not exported after roundtrip.
XML Difference:
Original : <f t="array" ref="G5:G6">MMULT(A1:C2,E1:E3)</f>
Roundtrip : <f aca="false">MMULT(A1:C2,E1:E3)</f>
Solution : Added formula cell range support for matrix multiplication.
Change-Id: Ic871f064a98a324bc16a4253b633c97417c3f900
Reviewed-on: https://gerrit.libreoffice.org/16033
Reviewed-by: David Tardon <dtardon@redhat.com>
Tested-by: David Tardon <dtardon@redhat.com>
-rw-r--r-- | sc/qa/unit/data/xlsx/matrix-multiplication.xlsx | bin | 0 -> 8849 bytes | |||
-rw-r--r-- | sc/qa/unit/subsequent_export-test.cxx | 31 | ||||
-rw-r--r-- | sc/source/filter/excel/xetable.cxx | 64 |
3 files changed, 80 insertions, 15 deletions
diff --git a/sc/qa/unit/data/xlsx/matrix-multiplication.xlsx b/sc/qa/unit/data/xlsx/matrix-multiplication.xlsx Binary files differnew file mode 100644 index 000000000000..f79d6b6e289b --- /dev/null +++ b/sc/qa/unit/data/xlsx/matrix-multiplication.xlsx diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index c194e31d53f9..ef9053df1592 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -147,6 +147,8 @@ public: void testHiddenShape(); void testHyperlinkXLSX(); void testMoveCellAnchoredShapes(); + void testMatrixMultiplication(); + CPPUNIT_TEST_SUITE(ScExportTest); CPPUNIT_TEST(test); @@ -203,6 +205,8 @@ public: CPPUNIT_TEST(testHiddenShape); CPPUNIT_TEST(testHyperlinkXLSX); CPPUNIT_TEST(testMoveCellAnchoredShapes); + CPPUNIT_TEST(testMatrixMultiplication); + CPPUNIT_TEST_SUITE_END(); @@ -2647,7 +2651,6 @@ void ScExportTest::testHiddenShape() CPPUNIT_ASSERT(pDoc); assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:nvSpPr/xdr:cNvPr", "hidden", "1"); } - void ScExportTest::testHyperlinkXLSX() { ScDocShellRef xDocSh = loadDoc("hyperlink.", XLSX); @@ -2821,6 +2824,32 @@ void ScExportTest::testMoveCellAnchoredShapes() xDocSh2->DoClose(); } +void ScExportTest::testMatrixMultiplication() +{ + ScDocShellRef xShell = loadDoc("matrix-multiplication.", XLSX); + CPPUNIT_ASSERT(xShell.Is()); + + ScDocShellRef xDocSh = saveAndReload(&(*xShell), XLSX); + CPPUNIT_ASSERT(xDocSh.Is()); + + xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/worksheets/sheet1.xml", XLSX); + CPPUNIT_ASSERT(pDoc); + + OUString CellFormulaRange = getXPath(pDoc, + "/x:worksheet/x:sheetData/x:row[4]/x:c/x:f","ref"); + + // make sure that the CellFormulaRange is G5:G6. + CPPUNIT_ASSERT_EQUAL(OUString("G5:G6"), CellFormulaRange); + + OUString CellFormulaType = getXPath(pDoc, + "/x:worksheet/x:sheetData/x:row[4]/x:c/x:f","t"); + + // make sure that the CellFormulaType is array. + CPPUNIT_ASSERT_EQUAL(OUString("array"), CellFormulaType); + + xDocSh->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx index 2ce7195ef4d9..38bb673daa59 100644 --- a/sc/source/filter/excel/xetable.cxx +++ b/sc/source/filter/excel/xetable.cxx @@ -932,23 +932,59 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm ) // OOXTODO: XML_cm, XML_vm, XML_ph FSEND ); - rWorksheet->startElement( XML_f, - // OOXTODO: XML_t, ST_CellFormulaType - XML_aca, XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || (mxAddRec && mxAddRec->IsVolatile()) ), - // OOXTODO: XML_ref, ST_Ref - // OOXTODO: XML_dt2D, bool - // OOXTODO: XML_dtr, bool - // OOXTODO: XML_del1, bool - // OOXTODO: XML_del2, bool - // OOXTODO: XML_r1, ST_CellRef - // OOXTODO: XML_r2, ST_CellRef - // OOXTODO: XML_ca, bool - // OOXTODO: XML_si, uint - // OOXTODO: XML_bx bool - FSEND ); + ScAddress aScPos( static_cast< SCCOL >( GetXclPos().mnCol ), static_cast< SCROW >( GetXclPos().mnRow ), rStrm.GetRoot().GetCurrScTab() ); + + if ( mrScFmlaCell.GetMatrixFlag() == MM_FORMULA) + { + // origin of the matrix - find the used matrix range + SCCOL nMatWidth; + SCROW nMatHeight; + mrScFmlaCell.GetMatColsRows( nMatWidth, nMatHeight ); + OSL_ENSURE( nMatWidth && nMatHeight, "XclExpFormulaCell::XclExpFormulaCell - empty matrix" ); + ScRange aMatScRange( aScPos ); + ScAddress& rMatEnd = aMatScRange.aEnd; + rMatEnd.IncCol( static_cast< SCsCOL >( nMatWidth - 1 ) ); + rMatEnd.IncRow( static_cast< SCsROW >( nMatHeight - 1 ) ); + // reduce to valid range (range keeps valid, because start position IS valid + rStrm.GetRoot().GetAddressConverter().ValidateRange( aMatScRange, true ); + + OStringBuffer sFmlaCellRange; + if (ValidRange(aMatScRange)) + { + // calculate the cell range. + sFmlaCellRange.append(XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), aMatScRange.aStart ).getStr()); + sFmlaCellRange.append(":"); + sFmlaCellRange.append(XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), aMatScRange.aEnd ).getStr()); + } + + if (aMatScRange.aStart.Col() == GetXclPos().mnCol && aMatScRange.aEnd.Row() > static_cast< SCROW >(GetXclPos().mnRow)) + { + rWorksheet->startElement( XML_f, + XML_aca, XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || (mxAddRec && mxAddRec->IsVolatile()) ), + XML_t, mxAddRec ? "array" : NULL, + XML_ref, !sFmlaCellRange.isEmpty()? sFmlaCellRange.getStr() : NULL, + // OOXTODO: XML_dt2D, bool + // OOXTODO: XML_dtr, bool + // OOXTODO: XML_del1, bool + // OOXTODO: XML_del2, bool + // OOXTODO: XML_r1, ST_CellRef + // OOXTODO: XML_r2, ST_CellRef + // OOXTODO: XML_ca, bool + // OOXTODO: XML_si, uint + // OOXTODO: XML_bx bool + FSEND ); + } + } + else + { + rWorksheet->startElement( XML_f, + XML_aca, XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || (mxAddRec && mxAddRec->IsVolatile()) ), + FSEND ); + } rWorksheet->writeEscaped( XclXmlUtils::ToOUString( rStrm.GetRoot().GetCompileFormulaContext(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode())); rWorksheet->endElement( XML_f ); + if( strcmp( sType, "inlineStr" ) == 0 ) { rWorksheet->startElement( XML_is, FSEND ); |