Kaydet (Commit) beb8e283 authored tarafından yogesh.bharate001's avatar yogesh.bharate001 Kaydeden (comit) David Tardon

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/16033Reviewed-by: 's avatarDavid Tardon <dtardon@redhat.com>
Tested-by: 's avatarDavid Tardon <dtardon@redhat.com>
üst 5afa25c6
......@@ -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();
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment