summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-09-15 16:41:07 +0200
committerCaolán McNamara <caolanm@redhat.com>2015-09-17 08:08:15 +0000
commit464d1ef1868ce879e1bd7542167df8e4b9c68d1e (patch)
treee6b4afe297b9c960796175ad4f94ba30c9e2df62 /sc
parentdcc71bb4a282678a815eb894b52fd062ff0aa1c6 (diff)
tdf#61908 OOXML export cell range for matrix/array formula
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. Reviewed-on: https://gerrit.libreoffice.org/16033 Reviewed-by: David Tardon <dtardon@redhat.com> Tested-by: David Tardon <dtardon@redhat.com> (cherry picked from commit beb8e2830dc9e1c771e196fcaf08cdfd6bf3dde3) Conflicts: sc/qa/unit/subsequent_export-test.cxx Omitted test case and document from commit. fix 176 unbalanced XML_f xlsx export failuires regression from commit beb8e2830dc9e1c771e196fcaf08cdfd6bf3dde3 Author: yogesh.bharate001 <yogesh.bharate@synerzip.com> Date: Tue Jun 2 16:39:09 2015 +0530 tdf#61908:XLSX formula cell range is not exported for MMULT. (cherry picked from commit 103b619401f06697255167c788192601e87758b9) array formulas do not consist only of multiple rows, tdf#61908 follow-up For example, {={1,2}*3} is a two columns one row vector, or even a single cell could hold an array formula. (cherry picked from commit 92df7db85a3da10f18a5a06fb53a9cb69910e835) a54ce5ce437e592378fe930b779c518de9670995 14a44ac8356fdffc98b7097f48319755f5f2f317 do not write MM_REFERENCE formulas to OOXML, tdf#61908 follow-up The array range is covered by MM_FORMULA. Excel even complained when loading such a document. (cherry picked from commit f501fe4da88e1d64fcc88a492a52911113d28f6a) Change-Id: Ic871f064a98a324bc16a4253b633c97417c3f900 10e1b19fbfb8ea849ffe3d46504fdf3389633c5f Reviewed-on: https://gerrit.libreoffice.org/18593 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/source/filter/excel/xetable.cxx93
1 files changed, 76 insertions, 17 deletions
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 53a3c860dc5a..ce561589ba34 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -932,23 +932,82 @@ 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 );
- rWorksheet->writeEscaped( XclXmlUtils::ToOUString(
- rStrm.GetRoot().GetCompileFormulaContext(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode()));
- rWorksheet->endElement( XML_f );
+ bool bWriteFormula = true;
+ bool bTagStarted = false;
+ ScAddress aScPos( static_cast< SCCOL >( GetXclPos().mnCol ),
+ static_cast< SCROW >( GetXclPos().mnRow ), rStrm.GetRoot().GetCurrScTab() );
+
+ switch (mrScFmlaCell.GetMatrixFlag())
+ {
+ case MM_NONE:
+ break;
+ case MM_REFERENCE:
+ bWriteFormula = false;
+ break;
+ case MM_FORMULA:
+ case MM_FAKE:
+ {
+ // 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.aStart.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 );
+ bTagStarted = true;
+ }
+ }
+ break;
+ }
+
+ if (bWriteFormula)
+ {
+ if (!bTagStarted)
+ {
+ 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 );