nss: upgrade to release 3.73
[LibreOffice.git] / xmloff / source / style / numehelp.cxx
blob3d46adcb575e5f47df1f6ef3a78945dad9c3df85
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/namespacemap.hxx>
24 #include <xmloff/xmlnamespace.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 <com/sun/star/util/XNumberFormatsSupplier.hpp>
33 #include <sax/tools/converter.hxx>
34 #include <rtl/math.hxx>
35 #include <rtl/ustrbuf.hxx>
36 #include <osl/diagnose.h>
38 using namespace com::sun::star;
39 using namespace xmloff::token;
41 constexpr OUStringLiteral gsStandardFormat(u"StandardFormat");
42 constexpr OUStringLiteral gsType(u"Type");
43 constexpr OUStringLiteral gsCurrencySymbol(u"CurrencySymbol");
44 constexpr OUStringLiteral gsCurrencyAbbreviation(u"CurrencyAbbreviation");
46 XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
47 css::uno::Reference< css::util::XNumberFormatsSupplier > const & xTempNumberFormatsSupplier)
48 : xNumberFormats(xTempNumberFormatsSupplier.is() ? xTempNumberFormatsSupplier->getNumberFormats() : css::uno::Reference< css::util::XNumberFormats > ()),
49 pExport(nullptr),
50 aNumberFormats()
54 XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
55 css::uno::Reference< css::util::XNumberFormatsSupplier > const & xTempNumberFormatsSupplier,
56 SvXMLExport& rTempExport )
57 : xNumberFormats(xTempNumberFormatsSupplier.is() ? xTempNumberFormatsSupplier->getNumberFormats() : css::uno::Reference< css::util::XNumberFormats > ()),
58 pExport(&rTempExport),
59 sAttrValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE))),
60 sAttrDateValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_DATE_VALUE))),
61 sAttrTimeValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_TIME_VALUE))),
62 sAttrBooleanValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_BOOLEAN_VALUE))),
63 sAttrStringValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE))),
64 sAttrCurrency(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_CURRENCY))),
65 aNumberFormats()
69 XMLNumberFormatAttributesExportHelper::~XMLNumberFormatAttributesExportHelper()
73 sal_Int16 XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat, OUString& sCurrency, bool& bIsStandard)
75 XMLNumberFormat aFormat(nNumberFormat);
76 XMLNumberFormatSet::iterator aItr(aNumberFormats.find(aFormat));
77 XMLNumberFormatSet::iterator aEndItr(aNumberFormats.end());
78 if (aItr != aEndItr)
80 bIsStandard = aItr->bIsStandard;
81 sCurrency = aItr->sCurrency;
82 return aItr->nType;
84 else
86 aFormat.nType = GetCellType(nNumberFormat, bIsStandard);
87 aFormat.bIsStandard = bIsStandard;
88 if ((aFormat.nType & ~util::NumberFormat::DEFINED) == util::NumberFormat::CURRENCY)
89 if (GetCurrencySymbol(nNumberFormat, aFormat.sCurrency))
90 sCurrency = aFormat.sCurrency;
91 aNumberFormats.insert(aFormat);
92 return aFormat.nType;
96 void XMLNumberFormatAttributesExportHelper::WriteAttributes(SvXMLExport& rXMLExport,
97 const sal_Int16 nTypeKey,
98 const double& rValue,
99 const OUString& rCurrency,
100 bool bExportValue)
102 bool bWasSetTypeAttribute = false;
103 switch(nTypeKey & ~util::NumberFormat::DEFINED)
105 case 0:
106 case util::NumberFormat::NUMBER:
107 case util::NumberFormat::SCIENTIFIC:
108 case util::NumberFormat::FRACTION:
110 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
111 bWasSetTypeAttribute = true;
112 [[fallthrough]];
114 case util::NumberFormat::PERCENT:
116 if (!bWasSetTypeAttribute)
118 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_PERCENTAGE);
119 bWasSetTypeAttribute = true;
121 [[fallthrough]];
123 case util::NumberFormat::CURRENCY:
125 if (!bWasSetTypeAttribute)
127 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_CURRENCY);
128 if (!rCurrency.isEmpty())
129 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CURRENCY, rCurrency);
132 if (bExportValue)
134 OUString sValue( ::rtl::math::doubleToUString( rValue,
135 rtl_math_StringFormat_Automatic,
136 rtl_math_DecimalPlaces_Max, '.', true));
137 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sValue);
140 break;
141 case util::NumberFormat::DATE:
142 case util::NumberFormat::DATETIME:
144 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_DATE);
145 if (bExportValue)
147 if ( rXMLExport.SetNullDateOnUnitConverter() )
149 OUStringBuffer sBuffer;
150 rXMLExport.GetMM100UnitConverter().convertDateTime(sBuffer, rValue);
151 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DATE_VALUE, sBuffer.makeStringAndClear());
155 break;
156 case util::NumberFormat::TIME:
158 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TIME);
159 if (bExportValue)
161 OUStringBuffer sBuffer;
162 ::sax::Converter::convertDuration(sBuffer, rValue);
163 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TIME_VALUE, sBuffer.makeStringAndClear());
166 break;
167 case util::NumberFormat::LOGICAL:
169 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_BOOLEAN);
170 if (bExportValue)
172 double fTempValue = rValue;
173 if (::rtl::math::approxEqual( fTempValue, 1.0 ))
175 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TRUE);
177 else
179 if (rValue == 0.0)
181 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_FALSE);
183 else
185 OUString sValue( ::rtl::math::doubleToUString(
186 fTempValue,
187 rtl_math_StringFormat_Automatic,
188 rtl_math_DecimalPlaces_Max, '.',
189 true));
190 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, sValue);
195 break;
196 case util::NumberFormat::TEXT:
198 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
199 if (bExportValue)
201 OUString sValue( ::rtl::math::doubleToUString( rValue,
202 rtl_math_StringFormat_Automatic,
203 rtl_math_DecimalPlaces_Max, '.', true));
204 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sValue);
207 break;
211 bool XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat, OUString& sCurrencySymbol,
212 uno::Reference <util::XNumberFormatsSupplier> const & xNumberFormatsSupplier)
214 if (xNumberFormatsSupplier.is())
216 uno::Reference <util::XNumberFormats> xNumberFormats(xNumberFormatsSupplier->getNumberFormats());
217 if (xNumberFormats.is())
221 uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
222 if ( xNumberPropertySet->getPropertyValue(gsCurrencySymbol) >>= sCurrencySymbol)
224 OUString sCurrencyAbbreviation;
225 if ( xNumberPropertySet->getPropertyValue(gsCurrencyAbbreviation) >>= sCurrencyAbbreviation)
227 if ( !sCurrencyAbbreviation.isEmpty())
228 sCurrencySymbol = sCurrencyAbbreviation;
229 else
231 if ( sCurrencySymbol.getLength() == 1 && sCurrencySymbol.toChar() == NfCurrencyEntry::GetEuroSymbol() )
232 sCurrencySymbol = "EUR";
235 return true;
238 catch ( uno::Exception& )
240 OSL_FAIL("Numberformat not found");
244 return false;
248 sal_Int16 XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat, bool& bIsStandard,
249 uno::Reference <util::XNumberFormatsSupplier> const & xNumberFormatsSupplier)
251 if (xNumberFormatsSupplier.is())
253 uno::Reference <util::XNumberFormats> xNumberFormats(xNumberFormatsSupplier->getNumberFormats());
254 if (xNumberFormats.is())
258 uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
259 xNumberPropertySet->getPropertyValue(gsStandardFormat) >>= bIsStandard;
260 sal_Int16 nNumberType = sal_Int16();
261 if ( xNumberPropertySet->getPropertyValue(gsType) >>= nNumberType )
263 return nNumberType;
266 catch ( uno::Exception& )
268 OSL_FAIL("Numberformat not found");
272 return 0;
275 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport& rXMLExport,
276 const sal_Int32 nNumberFormat, const double& rValue, bool bExportValue)
278 bool bIsStandard;
279 sal_Int16 nTypeKey = GetCellType(nNumberFormat, bIsStandard, rXMLExport.GetNumberFormatsSupplier());
280 OUString sCurrency;
281 if ((nTypeKey & ~util::NumberFormat::DEFINED) == util::NumberFormat::CURRENCY)
282 GetCurrencySymbol(nNumberFormat, sCurrency, rXMLExport.GetNumberFormatsSupplier());
283 WriteAttributes(rXMLExport, nTypeKey, rValue, sCurrency, bExportValue);
286 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport& rXMLExport,
287 const OUString& rValue, const OUString& rCharacters,
288 bool bExportValue, bool bExportTypeAttribute)
290 if (bExportTypeAttribute)
291 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
292 if (bExportValue && !rValue.isEmpty() && (rValue != rCharacters))
293 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, rValue);
296 bool XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat, OUString& rCurrencySymbol)
298 if (!xNumberFormats.is() && pExport && pExport->GetNumberFormatsSupplier().is())
299 xNumberFormats.set(pExport->GetNumberFormatsSupplier()->getNumberFormats());
301 if (xNumberFormats.is())
305 uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
306 if ( xNumberPropertySet->getPropertyValue(gsCurrencySymbol) >>= rCurrencySymbol)
308 OUString sCurrencyAbbreviation;
309 if ( xNumberPropertySet->getPropertyValue(gsCurrencyAbbreviation) >>= sCurrencyAbbreviation)
311 if ( !sCurrencyAbbreviation.isEmpty())
312 rCurrencySymbol = sCurrencyAbbreviation;
313 else
315 if ( rCurrencySymbol.getLength() == 1 && rCurrencySymbol.toChar() == NfCurrencyEntry::GetEuroSymbol() )
316 rCurrencySymbol = "EUR";
319 return true;
322 catch ( uno::Exception& )
324 OSL_FAIL("Numberformat not found");
327 return false;
330 sal_Int16 XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat, bool& bIsStandard)
332 if (!xNumberFormats.is() && pExport && pExport->GetNumberFormatsSupplier().is())
333 xNumberFormats.set(pExport->GetNumberFormatsSupplier()->getNumberFormats());
335 if (xNumberFormats.is())
339 uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
340 if (xNumberPropertySet.is())
342 xNumberPropertySet->getPropertyValue(gsStandardFormat) >>= bIsStandard;
343 sal_Int16 nNumberType = sal_Int16();
344 if ( xNumberPropertySet->getPropertyValue(gsType) >>= nNumberType )
346 return nNumberType;
350 catch ( uno::Exception& )
352 OSL_FAIL("Numberformat not found");
355 return 0;
358 void XMLNumberFormatAttributesExportHelper::WriteAttributes(
359 const sal_Int16 nTypeKey,
360 const double& rValue,
361 const OUString& rCurrency,
362 bool bExportValue, sal_uInt16 nNamespace)
364 if (!pExport)
365 return;
367 bool bWasSetTypeAttribute = false;
368 OUString sAttrValType = pExport->GetNamespaceMap().GetQNameByKey( nNamespace, GetXMLToken(XML_VALUE_TYPE));
369 switch(nTypeKey & ~util::NumberFormat::DEFINED)
371 case 0:
372 case util::NumberFormat::NUMBER:
373 case util::NumberFormat::SCIENTIFIC:
374 case util::NumberFormat::FRACTION:
376 pExport->AddAttribute(sAttrValType, XML_FLOAT);
377 bWasSetTypeAttribute = true;
378 [[fallthrough]];
380 case util::NumberFormat::PERCENT:
382 if (!bWasSetTypeAttribute)
384 pExport->AddAttribute(sAttrValType, XML_PERCENTAGE);
385 bWasSetTypeAttribute = true;
387 [[fallthrough]];
389 case util::NumberFormat::CURRENCY:
391 if (!bWasSetTypeAttribute)
393 pExport->AddAttribute(sAttrValType, XML_CURRENCY);
394 if (!rCurrency.isEmpty())
395 pExport->AddAttribute(sAttrCurrency, rCurrency);
398 if (bExportValue)
400 OUString sValue( ::rtl::math::doubleToUString( rValue,
401 rtl_math_StringFormat_Automatic,
402 rtl_math_DecimalPlaces_Max, '.', true));
403 pExport->AddAttribute(sAttrValue, sValue);
406 break;
407 case util::NumberFormat::DATE:
408 case util::NumberFormat::DATETIME:
410 pExport->AddAttribute(sAttrValType, XML_DATE);
411 if (bExportValue)
413 if ( pExport->SetNullDateOnUnitConverter() )
415 OUStringBuffer sBuffer;
416 pExport->GetMM100UnitConverter().convertDateTime(sBuffer, rValue);
417 pExport->AddAttribute(sAttrDateValue, sBuffer.makeStringAndClear());
421 break;
422 case util::NumberFormat::TIME:
424 pExport->AddAttribute(sAttrValType, XML_TIME);
425 if (bExportValue)
427 OUStringBuffer sBuffer;
428 ::sax::Converter::convertDuration(sBuffer, rValue);
429 pExport->AddAttribute(sAttrTimeValue, sBuffer.makeStringAndClear());
432 break;
433 case util::NumberFormat::LOGICAL:
435 pExport->AddAttribute(sAttrValType, XML_BOOLEAN);
436 if (bExportValue)
438 double fTempValue = rValue;
439 if (::rtl::math::approxEqual( fTempValue, 1.0 ))
441 pExport->AddAttribute(sAttrBooleanValue, XML_TRUE);
443 else
445 if (rValue == 0.0)
447 pExport->AddAttribute(sAttrBooleanValue, XML_FALSE);
449 else
451 OUString sValue( ::rtl::math::doubleToUString(
452 fTempValue,
453 rtl_math_StringFormat_Automatic,
454 rtl_math_DecimalPlaces_Max, '.',
455 true));
456 pExport->AddAttribute(sAttrBooleanValue, sValue);
461 break;
462 case util::NumberFormat::TEXT:
464 pExport->AddAttribute(sAttrValType, XML_FLOAT);
465 if (bExportValue)
467 OUString sValue( ::rtl::math::doubleToUString( rValue,
468 rtl_math_StringFormat_Automatic,
469 rtl_math_DecimalPlaces_Max, '.', true));
470 pExport->AddAttribute(sAttrValue, sValue);
473 break;
477 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
478 const sal_Int32 nNumberFormat, const double& rValue, bool bExportValue,
479 sal_uInt16 nNamespace, bool bExportCurrencySymbol)
481 if (pExport)
483 bool bIsStandard;
484 OUString sCurrency;
485 sal_Int16 nTypeKey = GetCellType(nNumberFormat, sCurrency, bIsStandard);
486 if(!bExportCurrencySymbol)
487 sCurrency.clear();
489 WriteAttributes(nTypeKey, rValue, sCurrency, bExportValue, nNamespace);
491 else {
492 OSL_FAIL("no SvXMLExport given");
496 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
497 const OUString& rValue, const OUString& rCharacters,
498 bool bExportValue,
499 sal_uInt16 nNamespace)
501 if (pExport)
503 pExport->AddAttribute(nNamespace, XML_VALUE_TYPE, XML_STRING);
504 if (bExportValue && !rValue.isEmpty() && (rValue != rCharacters))
505 pExport->AddAttribute(sAttrStringValue, rValue);
507 else {
508 OSL_FAIL("no SvXMLExport given");
512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */