[Libreoffice-commits] core.git: 4 commits - offapi/com svl/source xmloff/source

Eike Rathke erack at redhat.com
Fri Jul 10 18:09:26 PDT 2015


 offapi/com/sun/star/util/NumberFormat.idl |    6 ++
 svl/source/numbers/zformat.cxx            |   11 ++--
 xmloff/source/style/xmlnumfe.cxx          |   75 ++++++++++++++++++++----------
 xmloff/source/style/xmlnumfi.cxx          |    6 +-
 4 files changed, 67 insertions(+), 31 deletions(-)

New commits:
commit dad6be8af0e670a56d3d399a1b0a35859bd7b093
Author: Eike Rathke <erack at redhat.com>
Date:   Sat Jul 11 02:52:42 2015 +0200

    write trailing text subformat also to Excel .xls and .xlsx, tdf#92457
    
    ... without generating  0;;;@  from  0;@  that has different semantics.
    
    Introduce css::util::NumberFormat::EMPTY to properly flag empty
    subformats and distinguish from UNDEFINED, everything else would be an
    ugly hack.
    
    SvNumberformat::GetMappedFormatstring() now correctly supports the
    trailing text subformat, so exports using it should get that
    automatically.
    
    Change-Id: If9a1bcc5ec5dfcf46688035e2b1428ab4747a68d

diff --git a/offapi/com/sun/star/util/NumberFormat.idl b/offapi/com/sun/star/util/NumberFormat.idl
index 927bdf8..2bc297a 100644
--- a/offapi/com/sun/star/util/NumberFormat.idl
+++ b/offapi/com/sun/star/util/NumberFormat.idl
@@ -93,6 +93,12 @@ published constants NumberFormat
      */
     const short UNDEFINED = 2048;
 
+
+    /** @internal is used to flag an empty sub format.
+        @since LibreOffice 5.1
+     */
+    const short EMPTY = 4096;
+
 };
 
 
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index c645034..03c2078 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -893,7 +893,8 @@ SvNumberformat::SvNumberformat(OUString& rString,
                 }
                 if (sStr.isEmpty())
                 {
-                    // empty sub format
+                    // Empty sub format.
+                    NumFor[nIndex].Info().eScannedType = css::util::NumberFormat::EMPTY;
                 }
                 else
                 {
@@ -2202,7 +2203,7 @@ bool SvNumberformat::GetOutputString(double fNumber,
         *ppColor = NumFor[nIx].GetColor();
         const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info();
         const sal_uInt16 nAnz = NumFor[nIx].GetCount();
-        if (nAnz == 0 && rInfo.eScannedType == css::util::NumberFormat::UNDEFINED)
+        if (nAnz == 0 && rInfo.eScannedType == css::util::NumberFormat::EMPTY)
         {
             return false; // Empty => nothing
         }
@@ -4722,7 +4723,7 @@ OUString SvNumberformat::GetMappedFormatstring( const NfKeywordTable& rKeywords,
                     eOp1 == NUMBERFORMAT_OP_GE && fLimit1 == 0.0 &&
                     eOp2 == NUMBERFORMAT_OP_NO && fLimit2 == 0.0 );
     // with 3 or more subformats [>0];[<0];[=0] is implied if no condition specified,
-    // note that subformats may be empty (;;;) and NumFor[2].GetnAnz()>0 is not checked.
+    // note that subformats may be empty (;;;) and NumFor[2].GetCount()>0 is not checked.
     bDefault[2] = ( !bDefault[0] && !bDefault[1] &&
                     eOp1 == NUMBERFORMAT_OP_GT && fLimit1 == 0.0 &&
                     eOp2 == NUMBERFORMAT_OP_LT && fLimit2 == 0.0 );
@@ -4762,7 +4763,7 @@ OUString SvNumberformat::GetMappedFormatstring( const NfKeywordTable& rKeywords,
     int nSub = 0; // subformats delimited so far
     for ( int n=0; n<4; n++ )
     {
-        if ( n > 0 )
+        if ( n > 0 && NumFor[n].Info().eScannedType != css::util::NumberFormat::UNDEFINED )
         {
             nSem++;
         }
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index 3ccf074..d0da09b 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -1006,9 +1006,6 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
 
     // #101606# An empty subformat is a valid number-style resulting in an
     // empty display string for the condition of the subformat.
-    if ( nFmtType == css::util::NumberFormat::UNDEFINED && rFormat.GetNumForType( nPart,
-                0, false ) == 0 )
-        nFmtType = 0;
 
     XMLTokenEnum eType = XML_TOKEN_INVALID;
     switch ( nFmtType )
@@ -1016,6 +1013,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
         // type is 0 if a format contains no recognized elements
         // (like text only) - this is handled as a number-style.
         case 0:
+        case css::util::NumberFormat::EMPTY:
         case css::util::NumberFormat::NUMBER:
         case css::util::NumberFormat::SCIENTIFIC:
         case css::util::NumberFormat::FRACTION:
commit 934e35c62525a7541e6a5b2d05b557a6fcc35abb
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Jul 10 23:49:43 2015 +0200

    store trailing text format in ODF, e.g. 0;@ tdf#92457
    
    A clumsy kludge, but since there is no "all others" condition..
    
    Change-Id: Ie89b786585fdee6688f66f5a7af47ec84409eefa

diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index f580dfa..3ccf074 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -52,8 +52,6 @@ using namespace ::com::sun::star;
 using namespace ::xmloff::token;
 using namespace ::svt;
 
-#define XMLNUM_MAX_PARTS    3
-
 struct LessuInt32
 {
     bool operator() (const sal_uInt32 rValue1, const sal_uInt32 rValue2) const
@@ -1644,11 +1642,23 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
         if ( rFormat.HasTextFormat() )
         {
             //  4th part is for text -> make an "all other numbers" condition for the 3rd part
-            //  by reversing the 2nd condition
+            //  by reversing the 2nd condition.
+            //  For a trailing text format like  0;@  that has no conditions
+            //  use a "less or equal than biggest" condition for the number
+            //  part, ODF can't store subformats (style maps) without
+            //  conditions.
 
             SvNumberformatLimitOps eOp3 = NUMBERFORMAT_OP_NO;
             double fLimit3 = fLimit2;
-            switch ( eOp2 )
+            sal_uInt16 nLastPart = 2;
+            SvNumberformatLimitOps eOpLast = eOp2;
+            if (eOp2 == NUMBERFORMAT_OP_NO)
+            {
+                eOpLast = eOp1;
+                fLimit3 = fLimit1;
+                nLastPart = (eOp1 == NUMBERFORMAT_OP_NO) ? 0 : 1;
+            }
+            switch ( eOpLast )
             {
                 case NUMBERFORMAT_OP_EQ: eOp3 = NUMBERFORMAT_OP_NE; break;
                 case NUMBERFORMAT_OP_NE: eOp3 = NUMBERFORMAT_OP_EQ; break;
@@ -1656,8 +1666,8 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
                 case NUMBERFORMAT_OP_LE: eOp3 = NUMBERFORMAT_OP_GT; break;
                 case NUMBERFORMAT_OP_GT: eOp3 = NUMBERFORMAT_OP_LE; break;
                 case NUMBERFORMAT_OP_GE: eOp3 = NUMBERFORMAT_OP_LT; break;
-                default:
-                    break;
+                case NUMBERFORMAT_OP_NO: eOp3 = NUMBERFORMAT_OP_LE;
+                                         fLimit3 = ::std::numeric_limits<double>::max(); break;
             }
 
             if ( fLimit1 == fLimit2 &&
@@ -1670,7 +1680,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
                 eOp3 = NUMBERFORMAT_OP_EQ;
             }
 
-            WriteMapElement_Impl( eOp3, fLimit3, nKey, 2 );
+            WriteMapElement_Impl( eOp3, fLimit3, nKey, nLastPart );
         }
     }
 }
@@ -1679,11 +1689,17 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
 
 void SvXMLNumFmtExport::ExportFormat_Impl( const SvNumberformat& rFormat, sal_uInt32 nKey )
 {
+    const sal_uInt16 XMLNUM_MAX_PARTS = 4;
+    bool bParts[XMLNUM_MAX_PARTS] = { false, false, false, false };
     sal_uInt16 nUsedParts = 0;
-    sal_uInt16 nPart;
-    for (nPart=0; nPart<XMLNUM_MAX_PARTS; nPart++)
-        if (rFormat.GetNumForType( nPart, 0, false ) != 0)
-            nUsedParts = nPart+1;
+    for (sal_uInt16 nPart=0; nPart<XMLNUM_MAX_PARTS; ++nPart)
+    {
+        if (rFormat.GetNumForInfoScannedType( nPart) != css::util::NumberFormat::UNDEFINED)
+        {
+            bParts[nPart] = true;
+            nUsedParts = nPart + 1;
+        }
+    }
 
     SvNumberformatLimitOps eOp1, eOp2;
     double fLimit1, fLimit2;
@@ -1691,17 +1707,32 @@ void SvXMLNumFmtExport::ExportFormat_Impl( const SvNumberformat& rFormat, sal_uI
 
     //  if conditions are set, even empty formats must be written
 
-    if ( eOp1 != NUMBERFORMAT_OP_NO && nUsedParts < 2 )
-        nUsedParts = 2;
-    if ( eOp2 != NUMBERFORMAT_OP_NO && nUsedParts < 3 )
-        nUsedParts = 3;
-    if ( rFormat.HasTextFormat() && nUsedParts < 4 )
-        nUsedParts = 4;
+    if ( eOp1 != NUMBERFORMAT_OP_NO )
+    {
+        bParts[1] = true;
+        if (nUsedParts < 2)
+            nUsedParts = 2;
+    }
+    if ( eOp2 != NUMBERFORMAT_OP_NO )
+    {
+        bParts[2] = true;
+        if (nUsedParts < 3)
+            nUsedParts = 3;
+    }
+    if ( rFormat.HasTextFormat() )
+    {
+        bParts[3] = true;
+        if (nUsedParts < 4)
+            nUsedParts = 4;
+    }
 
-    for (nPart=0; nPart<nUsedParts; nPart++)
+    for (sal_uInt16 nPart=0; nPart<XMLNUM_MAX_PARTS; ++nPart)
     {
-        bool bDefault = ( nPart+1 == nUsedParts );          // last = default
-        ExportPart_Impl( rFormat, nKey, nPart, bDefault );
+        if (bParts[nPart])
+        {
+            bool bDefault = ( nPart+1 == nUsedParts );          // last = default
+            ExportPart_Impl( rFormat, nKey, nPart, bDefault );
+        }
     }
 }
 
commit f52aa4d13b7f262a4c54f4e554f45d64a545bce7
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Jul 10 23:46:30 2015 +0200

    fix string access out of bounds
    
    Could happen with a malformed subformat string like "[<0-0".
    
    Change-Id: I8eaab2bcb469d91432a41dc349060c273a6575a4

diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index e725d1d..c645034 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -697,7 +697,7 @@ SvNumberformat::SvNumberformat(OUString& rString,
                     {
                         fLimit2 = fNumber;
                     }
-                    if ( sBuff[nPos] == ']' )
+                    if ( nPos < sBuff.getLength() && sBuff[nPos] == ']' )
                     {
                         nPos++;
                     }
commit b3c11e2b3ef4bad8c2b5f92ba00ac805fb68786f
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Jul 10 23:20:28 2015 +0200

    the last condition is "all other numbers", not the third, tdf#92457
    
    Change-Id: Ic9571d938c4a8837c5712bafbfb2ebf9f32011df

diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 0c59c7e..b1a59ae 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -2129,10 +2129,10 @@ void SvXMLNumFormatContext::AddCondition( const sal_Int32 nIndex )
         if ( aConditions.isEmpty() && aMyConditions.size() == 1 && sRealCond == ">=0" )
             bDefaultCond = true;
 
-        if ( nType == XML_TOK_STYLES_TEXT_STYLE && nIndex == 2 )
+        if ( nType == XML_TOK_STYLES_TEXT_STYLE && static_cast<size_t>(nIndex) == aMyConditions.size() - 1 )
         {
-            //  The third condition in a number format with a text part can only be
-            //  "all other numbers", the condition string must be empty.
+            //  The last condition in a number format with a text part can only
+            //  be "all other numbers", the condition string must be empty.
             bDefaultCond = true;
         }
 


More information about the Libreoffice-commits mailing list