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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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; } _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
