bump product version to 4.1.6.2
[LibreOffice.git] / xmloff / source / style / numehelp.cxx
blob33396f1ce78bc657d5382b9fcc0e0a2b1a194ee8
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/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 > ()),
47 pExport(NULL),
48 sStandardFormat(XML_STANDARDFORMAT),
49 sType(XML_TYPE),
50 msCurrencySymbol(XML_CURRENCYSYMBOL),
51 msCurrencyAbbreviation(XML_CURRENCYABBREVIATION),
52 aNumberFormats()
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),
62 sType(XML_TYPE),
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),
71 aNumberFormats()
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());
84 if (aItr != aEndItr)
86 bIsStandard = aItr->bIsStandard;
87 sCurrency = aItr->sCurrency;
88 return aItr->nType;
90 else
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);
98 return aFormat.nType;
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)
111 case 0:
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;
121 } // No Break
122 case util::NumberFormat::PERCENT:
124 if (!bWasSetTypeAttribute)
126 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_PERCENTAGE);
127 bWasSetTypeAttribute = sal_True;
129 } // No Break
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;
140 if (bExportValue)
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);
148 break;
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;
157 if (bExportValue)
159 if ( rXMLExport.SetNullDateOnUnitConverter() )
161 OUStringBuffer sBuffer;
162 rXMLExport.GetMM100UnitConverter().convertDateTime(sBuffer, rValue);
163 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DATE_VALUE, sBuffer.makeStringAndClear());
167 break;
168 case util::NumberFormat::TIME:
170 if (!bWasSetTypeAttribute)
172 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TIME);
173 bWasSetTypeAttribute = sal_True;
175 if (bExportValue)
177 OUStringBuffer sBuffer;
178 ::sax::Converter::convertDuration(sBuffer, rValue);
179 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TIME_VALUE, sBuffer.makeStringAndClear());
182 break;
183 case util::NumberFormat::LOGICAL:
185 if (!bWasSetTypeAttribute)
187 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_BOOLEAN);
188 bWasSetTypeAttribute = sal_True;
190 if (bExportValue)
192 double fTempValue = rValue;
193 if (::rtl::math::approxEqual( fTempValue, 1.0 ))
195 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TRUE);
197 else
199 if (::rtl::math::approxEqual( rValue, 0.0 ))
201 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_FALSE);
203 else
205 OUString sValue( ::rtl::math::doubleToUString(
206 fTempValue,
207 rtl_math_StringFormat_Automatic,
208 rtl_math_DecimalPlaces_Max, '.',
209 sal_True));
210 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, sValue);
215 break;
216 case util::NumberFormat::TEXT:
218 if (!bWasSetTypeAttribute)
220 rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
221 bWasSetTypeAttribute = sal_True;
222 if (bExportValue)
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);
231 break;
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;
253 else
255 if ( sCurrencySymbol.getLength() == 1 && sCurrencySymbol.toChar() == NfCurrencyEntry::GetEuroSymbol() )
256 sCurrencySymbol = "EUR";
259 return sal_True;
262 catch ( uno::Exception& )
264 OSL_FAIL("Numberformat not found");
268 return sal_False;
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 )
287 return nNumberType;
290 catch ( uno::Exception& )
292 OSL_FAIL("Numberformat not found");
296 return 0;
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());
304 OUString sCurrency;
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;
337 else
339 if ( rCurrencySymbol.getLength() == 1 && rCurrencySymbol.toChar() == NfCurrencyEntry::GetEuroSymbol() )
340 rCurrencySymbol = OUString("EUR");
343 return sal_True;
346 catch ( uno::Exception& )
348 OSL_FAIL("Numberformat not found");
351 return sal_False;
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 )
370 return nNumberType;
374 catch ( uno::Exception& )
376 OSL_FAIL("Numberformat not found");
379 return 0;
382 void XMLNumberFormatAttributesExportHelper::WriteAttributes(
383 const sal_Int16 nTypeKey,
384 const double& rValue,
385 const OUString& rCurrency,
386 sal_Bool bExportValue, sal_uInt16 nNamespace)
388 if (!pExport)
389 return;
391 sal_Bool bWasSetTypeAttribute = sal_False;
392 OUString sAttrValType = pExport->GetNamespaceMap().GetQNameByKey( nNamespace, GetXMLToken(XML_VALUE_TYPE));
393 switch(nTypeKey & ~util::NumberFormat::DEFINED)
395 case 0:
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;
405 } // No Break
406 case util::NumberFormat::PERCENT:
408 if (!bWasSetTypeAttribute)
410 pExport->AddAttribute(sAttrValType, XML_PERCENTAGE);
411 bWasSetTypeAttribute = sal_True;
413 } // No Break
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;
424 if (bExportValue)
426 OUString sValue( ::rtl::math::doubleToUString( rValue,
427 rtl_math_StringFormat_Automatic,
428 rtl_math_DecimalPlaces_Max, '.', sal_True));
429 pExport->AddAttribute(sAttrValue, sValue);
432 break;
433 case util::NumberFormat::DATE:
434 case util::NumberFormat::DATETIME:
436 if (!bWasSetTypeAttribute)
438 pExport->AddAttribute(sAttrValType, XML_DATE);
439 bWasSetTypeAttribute = sal_True;
441 if (bExportValue)
443 if ( pExport->SetNullDateOnUnitConverter() )
445 OUStringBuffer sBuffer;
446 pExport->GetMM100UnitConverter().convertDateTime(sBuffer, rValue);
447 pExport->AddAttribute(sAttrDateValue, sBuffer.makeStringAndClear());
451 break;
452 case util::NumberFormat::TIME:
454 if (!bWasSetTypeAttribute)
456 pExport->AddAttribute(sAttrValType, XML_TIME);
457 bWasSetTypeAttribute = sal_True;
459 if (bExportValue)
461 OUStringBuffer sBuffer;
462 ::sax::Converter::convertDuration(sBuffer, rValue);
463 pExport->AddAttribute(sAttrTimeValue, sBuffer.makeStringAndClear());
466 break;
467 case util::NumberFormat::LOGICAL:
469 if (!bWasSetTypeAttribute)
471 pExport->AddAttribute(sAttrValType, XML_BOOLEAN);
472 bWasSetTypeAttribute = sal_True;
474 if (bExportValue)
476 double fTempValue = rValue;
477 if (::rtl::math::approxEqual( fTempValue, 1.0 ))
479 pExport->AddAttribute(sAttrBooleanValue, XML_TRUE);
481 else
483 if (::rtl::math::approxEqual( rValue, 0.0 ))
485 pExport->AddAttribute(sAttrBooleanValue, XML_FALSE);
487 else
489 OUString sValue( ::rtl::math::doubleToUString(
490 fTempValue,
491 rtl_math_StringFormat_Automatic,
492 rtl_math_DecimalPlaces_Max, '.',
493 sal_True));
494 pExport->AddAttribute(sAttrBooleanValue, sValue);
499 break;
500 case util::NumberFormat::TEXT:
502 if (!bWasSetTypeAttribute)
504 pExport->AddAttribute(sAttrValType, XML_FLOAT);
505 bWasSetTypeAttribute = sal_True;
506 if (bExportValue)
508 OUString sValue( ::rtl::math::doubleToUString( rValue,
509 rtl_math_StringFormat_Automatic,
510 rtl_math_DecimalPlaces_Max, '.', sal_True));
511 pExport->AddAttribute(sAttrValue, sValue);
515 break;
519 void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
520 const sal_Int32 nNumberFormat, const double& rValue, sal_Bool bExportValue,
521 sal_uInt16 nNamespace, bool bExportCurrencySymbol)
523 if (pExport)
525 bool bIsStandard;
526 OUString sCurrency;
527 sal_Int16 nTypeKey = GetCellType(nNumberFormat, sCurrency, bIsStandard);
528 if(!bExportCurrencySymbol)
529 sCurrency = OUString();
531 WriteAttributes(nTypeKey, rValue, sCurrency, bExportValue, nNamespace);
533 else {
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)
543 if (pExport)
545 if (bExportTypeAttribute)
546 pExport->AddAttribute(nNamespace, XML_VALUE_TYPE, XML_STRING);
547 if (bExportValue && !rValue.isEmpty() && (rValue != rCharacters))
548 pExport->AddAttribute(sAttrStringValue, rValue);
550 else {
551 OSL_FAIL("no SvXMLExport given");
555 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */