1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: numehelp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include "numehelp.hxx"
36 #include <xmloff/nmspmap.hxx>
37 #include "xmlnmspe.hxx"
38 #include <xmloff/xmluconv.hxx>
39 #include <xmloff/xmltoken.hxx>
40 #include <xmloff/xmlexp.hxx>
41 #include <com/sun/star/uno/Reference.h>
42 #include <rtl/ustring.hxx>
43 #include <svtools/zforlist.hxx>
44 #include <com/sun/star/util/NumberFormat.hpp>
45 #include <rtl/math.hxx>
46 #include <tools/debug.hxx>
47 #include <rtl/ustrbuf.hxx>
49 using namespace com::sun::star
;
50 using namespace xmloff::token
;
52 #define XML_TYPE "Type"
53 #define XML_CURRENCYSYMBOL "CurrencySymbol"
54 #define XML_CURRENCYABBREVIATION "CurrencyAbbreviation"
55 #define XML_STANDARDFORMAT "StandardFormat"
57 XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
58 ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormatsSupplier
>& xTempNumberFormatsSupplier
)
59 : xNumberFormats(xTempNumberFormatsSupplier
.is() ? xTempNumberFormatsSupplier
->getNumberFormats() : ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormats
> ()),
61 sStandardFormat(RTL_CONSTASCII_USTRINGPARAM(XML_STANDARDFORMAT
)),
62 sType(RTL_CONSTASCII_USTRINGPARAM(XML_TYPE
)),
63 msCurrencySymbol(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYSYMBOL
)),
64 msCurrencyAbbreviation(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYABBREVIATION
)),
69 XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
70 ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormatsSupplier
>& xTempNumberFormatsSupplier
,
71 SvXMLExport
& rTempExport
)
72 : xNumberFormats(xTempNumberFormatsSupplier
.is() ? xTempNumberFormatsSupplier
->getNumberFormats() : ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormats
> ()),
73 pExport(&rTempExport
),
74 sStandardFormat(RTL_CONSTASCII_USTRINGPARAM(XML_STANDARDFORMAT
)),
75 sType(RTL_CONSTASCII_USTRINGPARAM(XML_TYPE
)),
76 sAttrValueType(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_VALUE_TYPE
))),
77 sAttrValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_VALUE
))),
78 sAttrDateValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_DATE_VALUE
))),
79 sAttrTimeValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_TIME_VALUE
))),
80 sAttrBooleanValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_BOOLEAN_VALUE
))),
81 sAttrStringValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_STRING_VALUE
))),
82 sAttrCurrency(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_CURRENCY
))),
83 msCurrencySymbol(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYSYMBOL
)),
84 msCurrencyAbbreviation(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYABBREVIATION
)),
89 XMLNumberFormatAttributesExportHelper::~XMLNumberFormatAttributesExportHelper()
93 sal_Int16
XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat
, rtl::OUString
& sCurrency
, sal_Bool
& bIsStandard
)
95 XMLNumberFormat
aFormat(sEmpty
, nNumberFormat
, 0);
96 XMLNumberFormatSet::iterator
aItr(aNumberFormats
.find(aFormat
));
97 XMLNumberFormatSet::iterator
aEndItr(aNumberFormats
.end());
100 bIsStandard
= aItr
->bIsStandard
;
101 sCurrency
= aItr
->sCurrency
;
106 aFormat
.nType
= GetCellType(nNumberFormat
, bIsStandard
);
107 aFormat
.bIsStandard
= bIsStandard
;
108 if ((aFormat
.nType
& ~util::NumberFormat::DEFINED
) == util::NumberFormat::CURRENCY
)
109 if (GetCurrencySymbol(nNumberFormat
, aFormat
.sCurrency
))
110 sCurrency
= aFormat
.sCurrency
;
111 aNumberFormats
.insert(aFormat
);
112 return aFormat
.nType
;
116 void XMLNumberFormatAttributesExportHelper::WriteAttributes(SvXMLExport
& rXMLExport
,
117 const sal_Int16 nTypeKey
,
118 const double& rValue
,
119 const rtl::OUString
& rCurrency
,
120 sal_Bool bExportValue
)
122 sal_Bool bWasSetTypeAttribute
= sal_False
;
123 switch(nTypeKey
& ~util::NumberFormat::DEFINED
)
126 case util::NumberFormat::NUMBER
:
127 case util::NumberFormat::SCIENTIFIC
:
128 case util::NumberFormat::FRACTION
:
130 if (!bWasSetTypeAttribute
)
132 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
133 bWasSetTypeAttribute
= sal_True
;
136 case util::NumberFormat::PERCENT
:
138 if (!bWasSetTypeAttribute
)
140 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_PERCENTAGE
);
141 bWasSetTypeAttribute
= sal_True
;
144 case util::NumberFormat::CURRENCY
:
146 if (!bWasSetTypeAttribute
)
148 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_CURRENCY
);
149 if (rCurrency
.getLength() > 0)
150 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_CURRENCY
, rCurrency
);
151 bWasSetTypeAttribute
= sal_True
;
156 rtl::OUString
sValue( ::rtl::math::doubleToUString( rValue
,
157 rtl_math_StringFormat_Automatic
,
158 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
159 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE
, sValue
);
163 case util::NumberFormat::DATE
:
164 case util::NumberFormat::DATETIME
:
166 if (!bWasSetTypeAttribute
)
168 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_DATE
);
169 bWasSetTypeAttribute
= sal_True
;
173 if ( rXMLExport
.SetNullDateOnUnitConverter() )
175 rtl::OUStringBuffer sBuffer
;
176 rXMLExport
.GetMM100UnitConverter().convertDateTime(sBuffer
, rValue
);
177 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_DATE_VALUE
, sBuffer
.makeStringAndClear());
182 case util::NumberFormat::TIME
:
184 if (!bWasSetTypeAttribute
)
186 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_TIME
);
187 bWasSetTypeAttribute
= sal_True
;
191 rtl::OUStringBuffer sBuffer
;
192 rXMLExport
.GetMM100UnitConverter().convertTime(sBuffer
, rValue
);
193 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_TIME_VALUE
, sBuffer
.makeStringAndClear());
197 case util::NumberFormat::LOGICAL
:
199 if (!bWasSetTypeAttribute
)
201 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_BOOLEAN
);
202 bWasSetTypeAttribute
= sal_True
;
206 double fTempValue
= rValue
;
207 if (::rtl::math::approxEqual( fTempValue
, 1.0 ))
209 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_BOOLEAN_VALUE
, XML_TRUE
);
213 if (::rtl::math::approxEqual( rValue
, 0.0 ))
215 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_BOOLEAN_VALUE
, XML_FALSE
);
219 rtl::OUString
sValue( ::rtl::math::doubleToUString(
221 rtl_math_StringFormat_Automatic
,
222 rtl_math_DecimalPlaces_Max
, '.',
224 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_BOOLEAN_VALUE
, sValue
);
230 case util::NumberFormat::TEXT
:
232 if (!bWasSetTypeAttribute
)
234 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
235 bWasSetTypeAttribute
= sal_True
;
238 rtl::OUString
sValue( ::rtl::math::doubleToUString( rValue
,
239 rtl_math_StringFormat_Automatic
,
240 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
241 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE
, sValue
);
249 sal_Bool
XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat
, rtl::OUString
& sCurrencySymbol
,
250 uno::Reference
<util::XNumberFormatsSupplier
>& xNumberFormatsSupplier
)
252 if (xNumberFormatsSupplier
.is())
254 uno::Reference
<util::XNumberFormats
> xNumberFormats(xNumberFormatsSupplier
->getNumberFormats());
255 if (xNumberFormats
.is())
259 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
260 if ( xNumberPropertySet
->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYSYMBOL
))) >>= sCurrencySymbol
)
262 rtl::OUString sCurrencyAbbreviation
;
263 if ( xNumberPropertySet
->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYABBREVIATION
))) >>= sCurrencyAbbreviation
)
265 if ( sCurrencyAbbreviation
.getLength() != 0 )
266 sCurrencySymbol
= sCurrencyAbbreviation
;
269 if ( sCurrencySymbol
.getLength() == 1 && sCurrencySymbol
.toChar() == NfCurrencyEntry::GetEuroSymbol() )
270 sCurrencySymbol
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EUR"));
276 catch ( uno::Exception
& )
278 DBG_ERROR("Numberformat not found");
286 sal_Int16
XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat
, sal_Bool
& bIsStandard
,
287 uno::Reference
<util::XNumberFormatsSupplier
>& xNumberFormatsSupplier
)
289 if (xNumberFormatsSupplier
.is())
291 uno::Reference
<util::XNumberFormats
> xNumberFormats(xNumberFormatsSupplier
->getNumberFormats());
292 if (xNumberFormats
.is())
296 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
297 xNumberPropertySet
->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STANDARDFORMAT
))) >>= bIsStandard
;
298 sal_Int16 nNumberType
= sal_Int16();
299 if ( xNumberPropertySet
->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_TYPE
))) >>= nNumberType
)
304 catch ( uno::Exception
& )
306 DBG_ERROR("Numberformat not found");
313 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport
& rXMLExport
,
314 const sal_Int32 nNumberFormat
, const double& rValue
, sal_Bool bExportValue
)
316 sal_Bool bIsStandard
;
317 sal_Int16 nTypeKey
= GetCellType(nNumberFormat
, bIsStandard
, rXMLExport
.GetNumberFormatsSupplier());
318 rtl::OUString sCurrency
;
319 if ((nTypeKey
& ~util::NumberFormat::DEFINED
) == util::NumberFormat::CURRENCY
)
320 GetCurrencySymbol(nNumberFormat
, sCurrency
, rXMLExport
.GetNumberFormatsSupplier());
321 WriteAttributes(rXMLExport
, nTypeKey
, rValue
, sCurrency
, bExportValue
);
324 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport
& rXMLExport
,
325 const rtl::OUString
& rValue
, const rtl::OUString
& rCharacters
,
326 sal_Bool bExportValue
, sal_Bool bExportTypeAttribute
)
328 if (bExportTypeAttribute
)
329 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
330 if (bExportValue
&& rValue
.getLength() && (rValue
!= rCharacters
))
331 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_STRING_VALUE
, rValue
);
334 sal_Bool
XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat
, rtl::OUString
& rCurrencySymbol
)
336 if (!xNumberFormats
.is() && pExport
&& pExport
->GetNumberFormatsSupplier().is())
337 xNumberFormats
.set(pExport
->GetNumberFormatsSupplier()->getNumberFormats());
339 if (xNumberFormats
.is())
343 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
344 if ( xNumberPropertySet
->getPropertyValue(msCurrencySymbol
) >>= rCurrencySymbol
)
346 rtl::OUString sCurrencyAbbreviation
;
347 if ( xNumberPropertySet
->getPropertyValue(msCurrencyAbbreviation
) >>= sCurrencyAbbreviation
)
349 if ( sCurrencyAbbreviation
.getLength() != 0 )
350 rCurrencySymbol
= sCurrencyAbbreviation
;
353 if ( rCurrencySymbol
.getLength() == 1 && rCurrencySymbol
.toChar() == NfCurrencyEntry::GetEuroSymbol() )
354 rCurrencySymbol
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EUR"));
360 catch ( uno::Exception
& )
362 DBG_ERROR("Numberformat not found");
368 sal_Int16
XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat
, sal_Bool
& bIsStandard
)
370 if (!xNumberFormats
.is() && pExport
&& pExport
->GetNumberFormatsSupplier().is())
371 xNumberFormats
.set(pExport
->GetNumberFormatsSupplier()->getNumberFormats());
373 if (xNumberFormats
.is())
377 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
378 if (xNumberPropertySet
.is())
380 xNumberPropertySet
->getPropertyValue(sStandardFormat
) >>= bIsStandard
;
381 sal_Int16 nNumberType
= sal_Int16();
382 if ( xNumberPropertySet
->getPropertyValue(sType
) >>= nNumberType
)
388 catch ( uno::Exception
& )
390 DBG_ERROR("Numberformat not found");
396 void XMLNumberFormatAttributesExportHelper::WriteAttributes(
397 const sal_Int16 nTypeKey
,
398 const double& rValue
,
399 const rtl::OUString
& rCurrency
,
400 sal_Bool bExportValue
)
405 sal_Bool bWasSetTypeAttribute
= sal_False
;
406 switch(nTypeKey
& ~util::NumberFormat::DEFINED
)
409 case util::NumberFormat::NUMBER
:
410 case util::NumberFormat::SCIENTIFIC
:
411 case util::NumberFormat::FRACTION
:
413 if (!bWasSetTypeAttribute
)
415 pExport
->AddAttribute(sAttrValueType
, XML_FLOAT
);
416 bWasSetTypeAttribute
= sal_True
;
419 case util::NumberFormat::PERCENT
:
421 if (!bWasSetTypeAttribute
)
423 pExport
->AddAttribute(sAttrValueType
, XML_PERCENTAGE
);
424 bWasSetTypeAttribute
= sal_True
;
427 case util::NumberFormat::CURRENCY
:
429 if (!bWasSetTypeAttribute
)
431 pExport
->AddAttribute(sAttrValueType
, XML_CURRENCY
);
432 if (rCurrency
.getLength() > 0)
433 pExport
->AddAttribute(sAttrCurrency
, rCurrency
);
434 bWasSetTypeAttribute
= sal_True
;
439 rtl::OUString
sValue( ::rtl::math::doubleToUString( rValue
,
440 rtl_math_StringFormat_Automatic
,
441 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
442 pExport
->AddAttribute(sAttrValue
, sValue
);
446 case util::NumberFormat::DATE
:
447 case util::NumberFormat::DATETIME
:
449 if (!bWasSetTypeAttribute
)
451 pExport
->AddAttribute(sAttrValueType
, XML_DATE
);
452 bWasSetTypeAttribute
= sal_True
;
456 if ( pExport
->SetNullDateOnUnitConverter() )
458 rtl::OUStringBuffer sBuffer
;
459 pExport
->GetMM100UnitConverter().convertDateTime(sBuffer
, rValue
);
460 pExport
->AddAttribute(sAttrDateValue
, sBuffer
.makeStringAndClear());
465 case util::NumberFormat::TIME
:
467 if (!bWasSetTypeAttribute
)
469 pExport
->AddAttribute(sAttrValueType
, XML_TIME
);
470 bWasSetTypeAttribute
= sal_True
;
474 rtl::OUStringBuffer sBuffer
;
475 pExport
->GetMM100UnitConverter().convertTime(sBuffer
, rValue
);
476 pExport
->AddAttribute(sAttrTimeValue
, sBuffer
.makeStringAndClear());
480 case util::NumberFormat::LOGICAL
:
482 if (!bWasSetTypeAttribute
)
484 pExport
->AddAttribute(sAttrValueType
, XML_BOOLEAN
);
485 bWasSetTypeAttribute
= sal_True
;
489 double fTempValue
= rValue
;
490 if (::rtl::math::approxEqual( fTempValue
, 1.0 ))
492 pExport
->AddAttribute(sAttrBooleanValue
, XML_TRUE
);
496 if (::rtl::math::approxEqual( rValue
, 0.0 ))
498 pExport
->AddAttribute(sAttrBooleanValue
, XML_FALSE
);
502 rtl::OUString
sValue( ::rtl::math::doubleToUString(
504 rtl_math_StringFormat_Automatic
,
505 rtl_math_DecimalPlaces_Max
, '.',
507 pExport
->AddAttribute(sAttrBooleanValue
, sValue
);
513 case util::NumberFormat::TEXT
:
515 if (!bWasSetTypeAttribute
)
517 pExport
->AddAttribute(sAttrValueType
, XML_FLOAT
);
518 bWasSetTypeAttribute
= sal_True
;
521 rtl::OUString
sValue( ::rtl::math::doubleToUString( rValue
,
522 rtl_math_StringFormat_Automatic
,
523 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
524 pExport
->AddAttribute(sAttrValue
, sValue
);
532 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
533 const sal_Int32 nNumberFormat
, const double& rValue
, sal_Bool bExportValue
)
537 sal_Bool bIsStandard
;
538 rtl::OUString sCurrency
;
539 sal_Int16 nTypeKey
= GetCellType(nNumberFormat
, sCurrency
, bIsStandard
);
540 WriteAttributes(nTypeKey
, rValue
, sCurrency
, bExportValue
);
543 DBG_ERROR("no SvXMLExport given");
547 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
548 const rtl::OUString
& rValue
, const rtl::OUString
& rCharacters
,
549 sal_Bool bExportValue
, sal_Bool bExportTypeAttribute
)
553 if (bExportTypeAttribute
)
554 pExport
->AddAttribute(sAttrValueType
, XML_STRING
);
555 if (bExportValue
&& rValue
.getLength() && (rValue
!= rCharacters
))
556 pExport
->AddAttribute(sAttrStringValue
, rValue
);
559 DBG_ERROR("no SvXMLExport given");