1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "xmloff/numehelp.hxx"
23 #include <xmloff/nmspmap.hxx>
24 #include "xmloff/xmlnmspe.hxx"
25 #include <xmloff/xmluconv.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/xmlexp.hxx>
28 #include <com/sun/star/uno/Reference.h>
29 #include <rtl/ustring.hxx>
30 #include <svl/zforlist.hxx>
31 #include <com/sun/star/util/NumberFormat.hpp>
32 #include <sax/tools/converter.hxx>
33 #include <rtl/math.hxx>
34 #include <rtl/ustrbuf.hxx>
36 using namespace com::sun::star
;
37 using namespace xmloff::token
;
39 #define XML_TYPE "Type"
40 #define XML_CURRENCYSYMBOL "CurrencySymbol"
41 #define XML_CURRENCYABBREVIATION "CurrencyAbbreviation"
42 #define XML_STANDARDFORMAT "StandardFormat"
44 XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
45 ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormatsSupplier
>& xTempNumberFormatsSupplier
)
46 : xNumberFormats(xTempNumberFormatsSupplier
.is() ? xTempNumberFormatsSupplier
->getNumberFormats() : ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormats
> ()),
48 sStandardFormat(XML_STANDARDFORMAT
),
50 msCurrencySymbol(XML_CURRENCYSYMBOL
),
51 msCurrencyAbbreviation(XML_CURRENCYABBREVIATION
),
56 XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
57 ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormatsSupplier
>& xTempNumberFormatsSupplier
,
58 SvXMLExport
& rTempExport
)
59 : xNumberFormats(xTempNumberFormatsSupplier
.is() ? xTempNumberFormatsSupplier
->getNumberFormats() : ::com::sun::star::uno::Reference
< ::com::sun::star::util::XNumberFormats
> ()),
60 pExport(&rTempExport
),
61 sStandardFormat(XML_STANDARDFORMAT
),
63 sAttrValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_VALUE
))),
64 sAttrDateValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_DATE_VALUE
))),
65 sAttrTimeValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_TIME_VALUE
))),
66 sAttrBooleanValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_BOOLEAN_VALUE
))),
67 sAttrStringValue(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_STRING_VALUE
))),
68 sAttrCurrency(rTempExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE
, GetXMLToken(XML_CURRENCY
))),
69 msCurrencySymbol(XML_CURRENCYSYMBOL
),
70 msCurrencyAbbreviation(XML_CURRENCYABBREVIATION
),
75 XMLNumberFormatAttributesExportHelper::~XMLNumberFormatAttributesExportHelper()
79 sal_Int16
XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat
, OUString
& sCurrency
, bool& bIsStandard
)
81 XMLNumberFormat
aFormat(sEmpty
, nNumberFormat
, 0);
82 XMLNumberFormatSet::iterator
aItr(aNumberFormats
.find(aFormat
));
83 XMLNumberFormatSet::iterator
aEndItr(aNumberFormats
.end());
86 bIsStandard
= aItr
->bIsStandard
;
87 sCurrency
= aItr
->sCurrency
;
92 aFormat
.nType
= GetCellType(nNumberFormat
, bIsStandard
);
93 aFormat
.bIsStandard
= bIsStandard
;
94 if ((aFormat
.nType
& ~util::NumberFormat::DEFINED
) == util::NumberFormat::CURRENCY
)
95 if (GetCurrencySymbol(nNumberFormat
, aFormat
.sCurrency
))
96 sCurrency
= aFormat
.sCurrency
;
97 aNumberFormats
.insert(aFormat
);
102 void XMLNumberFormatAttributesExportHelper::WriteAttributes(SvXMLExport
& rXMLExport
,
103 const sal_Int16 nTypeKey
,
104 const double& rValue
,
105 const OUString
& rCurrency
,
106 sal_Bool bExportValue
)
108 sal_Bool bWasSetTypeAttribute
= sal_False
;
109 switch(nTypeKey
& ~util::NumberFormat::DEFINED
)
112 case util::NumberFormat::NUMBER
:
113 case util::NumberFormat::SCIENTIFIC
:
114 case util::NumberFormat::FRACTION
:
116 if (!bWasSetTypeAttribute
)
118 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
119 bWasSetTypeAttribute
= sal_True
;
122 case util::NumberFormat::PERCENT
:
124 if (!bWasSetTypeAttribute
)
126 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_PERCENTAGE
);
127 bWasSetTypeAttribute
= sal_True
;
130 case util::NumberFormat::CURRENCY
:
132 if (!bWasSetTypeAttribute
)
134 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_CURRENCY
);
135 if (!rCurrency
.isEmpty())
136 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_CURRENCY
, rCurrency
);
137 bWasSetTypeAttribute
= sal_True
;
142 OUString
sValue( ::rtl::math::doubleToUString( rValue
,
143 rtl_math_StringFormat_Automatic
,
144 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
145 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE
, sValue
);
149 case util::NumberFormat::DATE
:
150 case util::NumberFormat::DATETIME
:
152 if (!bWasSetTypeAttribute
)
154 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_DATE
);
155 bWasSetTypeAttribute
= sal_True
;
159 if ( rXMLExport
.SetNullDateOnUnitConverter() )
161 OUStringBuffer sBuffer
;
162 rXMLExport
.GetMM100UnitConverter().convertDateTime(sBuffer
, rValue
);
163 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_DATE_VALUE
, sBuffer
.makeStringAndClear());
168 case util::NumberFormat::TIME
:
170 if (!bWasSetTypeAttribute
)
172 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_TIME
);
173 bWasSetTypeAttribute
= sal_True
;
177 OUStringBuffer sBuffer
;
178 ::sax::Converter::convertDuration(sBuffer
, rValue
);
179 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_TIME_VALUE
, sBuffer
.makeStringAndClear());
183 case util::NumberFormat::LOGICAL
:
185 if (!bWasSetTypeAttribute
)
187 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_BOOLEAN
);
188 bWasSetTypeAttribute
= sal_True
;
192 double fTempValue
= rValue
;
193 if (::rtl::math::approxEqual( fTempValue
, 1.0 ))
195 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_BOOLEAN_VALUE
, XML_TRUE
);
199 if (::rtl::math::approxEqual( rValue
, 0.0 ))
201 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_BOOLEAN_VALUE
, XML_FALSE
);
205 OUString
sValue( ::rtl::math::doubleToUString(
207 rtl_math_StringFormat_Automatic
,
208 rtl_math_DecimalPlaces_Max
, '.',
210 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_BOOLEAN_VALUE
, sValue
);
216 case util::NumberFormat::TEXT
:
218 if (!bWasSetTypeAttribute
)
220 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_FLOAT
);
221 bWasSetTypeAttribute
= sal_True
;
224 OUString
sValue( ::rtl::math::doubleToUString( rValue
,
225 rtl_math_StringFormat_Automatic
,
226 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
227 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE
, sValue
);
235 sal_Bool
XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat
, OUString
& sCurrencySymbol
,
236 uno::Reference
<util::XNumberFormatsSupplier
>& xNumberFormatsSupplier
)
238 if (xNumberFormatsSupplier
.is())
240 uno::Reference
<util::XNumberFormats
> xNumberFormats(xNumberFormatsSupplier
->getNumberFormats());
241 if (xNumberFormats
.is())
245 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
246 if ( xNumberPropertySet
->getPropertyValue(OUString(XML_CURRENCYSYMBOL
)) >>= sCurrencySymbol
)
248 OUString sCurrencyAbbreviation
;
249 if ( xNumberPropertySet
->getPropertyValue(OUString(XML_CURRENCYABBREVIATION
)) >>= sCurrencyAbbreviation
)
251 if ( !sCurrencyAbbreviation
.isEmpty())
252 sCurrencySymbol
= sCurrencyAbbreviation
;
255 if ( sCurrencySymbol
.getLength() == 1 && sCurrencySymbol
.toChar() == NfCurrencyEntry::GetEuroSymbol() )
256 sCurrencySymbol
= "EUR";
262 catch ( uno::Exception
& )
264 OSL_FAIL("Numberformat not found");
272 sal_Int16
XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat
, sal_Bool
& bIsStandard
,
273 uno::Reference
<util::XNumberFormatsSupplier
>& xNumberFormatsSupplier
)
275 if (xNumberFormatsSupplier
.is())
277 uno::Reference
<util::XNumberFormats
> xNumberFormats(xNumberFormatsSupplier
->getNumberFormats());
278 if (xNumberFormats
.is())
282 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
283 xNumberPropertySet
->getPropertyValue(OUString(XML_STANDARDFORMAT
)) >>= bIsStandard
;
284 sal_Int16 nNumberType
= sal_Int16();
285 if ( xNumberPropertySet
->getPropertyValue(OUString(XML_TYPE
)) >>= nNumberType
)
290 catch ( uno::Exception
& )
292 OSL_FAIL("Numberformat not found");
299 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport
& rXMLExport
,
300 const sal_Int32 nNumberFormat
, const double& rValue
, sal_Bool bExportValue
)
302 sal_Bool bIsStandard
;
303 sal_Int16 nTypeKey
= GetCellType(nNumberFormat
, bIsStandard
, rXMLExport
.GetNumberFormatsSupplier());
305 if ((nTypeKey
& ~util::NumberFormat::DEFINED
) == util::NumberFormat::CURRENCY
)
306 GetCurrencySymbol(nNumberFormat
, sCurrency
, rXMLExport
.GetNumberFormatsSupplier());
307 WriteAttributes(rXMLExport
, nTypeKey
, rValue
, sCurrency
, bExportValue
);
310 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport
& rXMLExport
,
311 const OUString
& rValue
, const OUString
& rCharacters
,
312 sal_Bool bExportValue
, sal_Bool bExportTypeAttribute
)
314 if (bExportTypeAttribute
)
315 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_VALUE_TYPE
, XML_STRING
);
316 if (bExportValue
&& !rValue
.isEmpty() && (rValue
!= rCharacters
))
317 rXMLExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_STRING_VALUE
, rValue
);
320 sal_Bool
XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat
, OUString
& rCurrencySymbol
)
322 if (!xNumberFormats
.is() && pExport
&& pExport
->GetNumberFormatsSupplier().is())
323 xNumberFormats
.set(pExport
->GetNumberFormatsSupplier()->getNumberFormats());
325 if (xNumberFormats
.is())
329 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
330 if ( xNumberPropertySet
->getPropertyValue(msCurrencySymbol
) >>= rCurrencySymbol
)
332 OUString sCurrencyAbbreviation
;
333 if ( xNumberPropertySet
->getPropertyValue(msCurrencyAbbreviation
) >>= sCurrencyAbbreviation
)
335 if ( !sCurrencyAbbreviation
.isEmpty())
336 rCurrencySymbol
= sCurrencyAbbreviation
;
339 if ( rCurrencySymbol
.getLength() == 1 && rCurrencySymbol
.toChar() == NfCurrencyEntry::GetEuroSymbol() )
340 rCurrencySymbol
= OUString("EUR");
346 catch ( uno::Exception
& )
348 OSL_FAIL("Numberformat not found");
354 sal_Int16
XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat
, bool& bIsStandard
)
356 if (!xNumberFormats
.is() && pExport
&& pExport
->GetNumberFormatsSupplier().is())
357 xNumberFormats
.set(pExport
->GetNumberFormatsSupplier()->getNumberFormats());
359 if (xNumberFormats
.is())
363 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xNumberFormats
->getByKey(nNumberFormat
));
364 if (xNumberPropertySet
.is())
366 xNumberPropertySet
->getPropertyValue(sStandardFormat
) >>= bIsStandard
;
367 sal_Int16 nNumberType
= sal_Int16();
368 if ( xNumberPropertySet
->getPropertyValue(sType
) >>= nNumberType
)
374 catch ( uno::Exception
& )
376 OSL_FAIL("Numberformat not found");
382 void XMLNumberFormatAttributesExportHelper::WriteAttributes(
383 const sal_Int16 nTypeKey
,
384 const double& rValue
,
385 const OUString
& rCurrency
,
386 sal_Bool bExportValue
, sal_uInt16 nNamespace
)
391 sal_Bool bWasSetTypeAttribute
= sal_False
;
392 OUString sAttrValType
= pExport
->GetNamespaceMap().GetQNameByKey( nNamespace
, GetXMLToken(XML_VALUE_TYPE
));
393 switch(nTypeKey
& ~util::NumberFormat::DEFINED
)
396 case util::NumberFormat::NUMBER
:
397 case util::NumberFormat::SCIENTIFIC
:
398 case util::NumberFormat::FRACTION
:
400 if (!bWasSetTypeAttribute
)
402 pExport
->AddAttribute(sAttrValType
, XML_FLOAT
);
403 bWasSetTypeAttribute
= sal_True
;
406 case util::NumberFormat::PERCENT
:
408 if (!bWasSetTypeAttribute
)
410 pExport
->AddAttribute(sAttrValType
, XML_PERCENTAGE
);
411 bWasSetTypeAttribute
= sal_True
;
414 case util::NumberFormat::CURRENCY
:
416 if (!bWasSetTypeAttribute
)
418 pExport
->AddAttribute(sAttrValType
, XML_CURRENCY
);
419 if (!rCurrency
.isEmpty())
420 pExport
->AddAttribute(sAttrCurrency
, rCurrency
);
421 bWasSetTypeAttribute
= sal_True
;
426 OUString
sValue( ::rtl::math::doubleToUString( rValue
,
427 rtl_math_StringFormat_Automatic
,
428 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
429 pExport
->AddAttribute(sAttrValue
, sValue
);
433 case util::NumberFormat::DATE
:
434 case util::NumberFormat::DATETIME
:
436 if (!bWasSetTypeAttribute
)
438 pExport
->AddAttribute(sAttrValType
, XML_DATE
);
439 bWasSetTypeAttribute
= sal_True
;
443 if ( pExport
->SetNullDateOnUnitConverter() )
445 OUStringBuffer sBuffer
;
446 pExport
->GetMM100UnitConverter().convertDateTime(sBuffer
, rValue
);
447 pExport
->AddAttribute(sAttrDateValue
, sBuffer
.makeStringAndClear());
452 case util::NumberFormat::TIME
:
454 if (!bWasSetTypeAttribute
)
456 pExport
->AddAttribute(sAttrValType
, XML_TIME
);
457 bWasSetTypeAttribute
= sal_True
;
461 OUStringBuffer sBuffer
;
462 ::sax::Converter::convertDuration(sBuffer
, rValue
);
463 pExport
->AddAttribute(sAttrTimeValue
, sBuffer
.makeStringAndClear());
467 case util::NumberFormat::LOGICAL
:
469 if (!bWasSetTypeAttribute
)
471 pExport
->AddAttribute(sAttrValType
, XML_BOOLEAN
);
472 bWasSetTypeAttribute
= sal_True
;
476 double fTempValue
= rValue
;
477 if (::rtl::math::approxEqual( fTempValue
, 1.0 ))
479 pExport
->AddAttribute(sAttrBooleanValue
, XML_TRUE
);
483 if (::rtl::math::approxEqual( rValue
, 0.0 ))
485 pExport
->AddAttribute(sAttrBooleanValue
, XML_FALSE
);
489 OUString
sValue( ::rtl::math::doubleToUString(
491 rtl_math_StringFormat_Automatic
,
492 rtl_math_DecimalPlaces_Max
, '.',
494 pExport
->AddAttribute(sAttrBooleanValue
, sValue
);
500 case util::NumberFormat::TEXT
:
502 if (!bWasSetTypeAttribute
)
504 pExport
->AddAttribute(sAttrValType
, XML_FLOAT
);
505 bWasSetTypeAttribute
= sal_True
;
508 OUString
sValue( ::rtl::math::doubleToUString( rValue
,
509 rtl_math_StringFormat_Automatic
,
510 rtl_math_DecimalPlaces_Max
, '.', sal_True
));
511 pExport
->AddAttribute(sAttrValue
, sValue
);
519 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
520 const sal_Int32 nNumberFormat
, const double& rValue
, sal_Bool bExportValue
,
521 sal_uInt16 nNamespace
, bool bExportCurrencySymbol
)
527 sal_Int16 nTypeKey
= GetCellType(nNumberFormat
, sCurrency
, bIsStandard
);
528 if(!bExportCurrencySymbol
)
529 sCurrency
= OUString();
531 WriteAttributes(nTypeKey
, rValue
, sCurrency
, bExportValue
, nNamespace
);
534 OSL_FAIL("no SvXMLExport given");
538 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
539 const OUString
& rValue
, const OUString
& rCharacters
,
540 sal_Bool bExportValue
, sal_Bool bExportTypeAttribute
,
541 sal_uInt16 nNamespace
)
545 if (bExportTypeAttribute
)
546 pExport
->AddAttribute(nNamespace
, XML_VALUE_TYPE
, XML_STRING
);
547 if (bExportValue
&& !rValue
.isEmpty() && (rValue
!= rCharacters
))
548 pExport
->AddAttribute(sAttrStringValue
, rValue
);
551 OSL_FAIL("no SvXMLExport given");
555 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */