[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - sc/source

Eike Rathke erack at redhat.com
Thu Sep 17 01:08:43 PDT 2015


 sc/source/filter/excel/xetable.cxx |   93 ++++++++++++++++++++++++++++++-------
 1 file changed, 76 insertions(+), 17 deletions(-)

New commits:
commit 464d1ef1868ce879e1bd7542167df8e4b9c68d1e
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Sep 15 16:41:07 2015 +0200

    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 at redhat.com>
    Tested-by: David Tardon <dtardon at 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 at 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 at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 53a3c86..ce56158 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 );


More information about the Libreoffice-commits mailing list