27#include <com/sun/star/util/DateTime.hpp>
28#include <com/sun/star/util/Date.hpp>
29#include <rtl/ustrbuf.hxx>
30#include <osl/diagnose.h>
34#include <rtl/math.hxx>
40#include <com/sun/star/drawing/Position3D.hpp>
41#include <com/sun/star/frame/XModel.hpp>
42#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
43#include <com/sun/star/style/NumberingType.hpp>
44#include <com/sun/star/text/DefaultNumberingProvider.hpp>
45#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
46#include <com/sun/star/text/XNumberingTypeInfo.hpp>
47#include <com/sun/star/i18n/CharacterClassification.hpp>
48#include <com/sun/star/i18n/UnicodeType.hpp>
73 mutable uno::Reference< i18n::XCharacterClassification >
m_xCharClass;
76 Impl(uno::Reference<uno::XComponentContext> xContext,
77 sal_Int16
const eCoreMeasureUnit,
78 sal_Int16
const eXMLMeasureUnit,
86 OSL_ENSURE(
m_xContext.is(),
"got no service manager" );
99const uno::Reference< text::XNumberingTypeInfo >&
102 if (!
m_pImpl->m_xNumTypeInfo.is())
106 return m_pImpl->m_xNumTypeInfo;
111 m_pImpl->m_eCoreMeasureUnit = eCoreMeasureUnit;
116 m_pImpl->m_eXMLMeasureUnit = eXMLMeasureUnit;
121 return m_pImpl->m_eXMLMeasureUnit;
132 m_pImpl->m_eODFVersion = nODFVersion;
141 const uno::Reference<uno::XComponentContext>& xContext,
142 sal_Int16
const eCoreMeasureUnit,
143 sal_Int16
const eXMLMeasureUnit,
145:
m_pImpl(new
Impl(xContext, eCoreMeasureUnit, eXMLMeasureUnit, nODFVersion))
155 sal_Int16 eUnit = util::MeasureUnit::INCH;
159 eUnit = util::MeasureUnit::MM;
164 eUnit = util::MeasureUnit::CM;
166 case FieldUnit::TWIP:
167 eUnit = util::MeasureUnit::TWIP;
169 case FieldUnit::POINT:
170 case FieldUnit::PICA:
171 eUnit = util::MeasureUnit::POINT;
173 case FieldUnit::MM_100TH:
174 eUnit = util::MeasureUnit::MM_100TH;
176 case FieldUnit::INCH:
177 eUnit = util::MeasureUnit::INCH;
188 std::u16string_view rString,
189 sal_Int32 nMin, sal_Int32 nMax )
const
191 return ::sax::Converter::convertMeasure(
nValue, rString,
198 std::string_view rString,
199 sal_Int32 nMin, sal_Int32 nMax )
const
201 return ::sax::Converter::convertMeasure(
nValue, rString,
208 sal_Int32 nMeasure )
const
222 return s.makeStringAndClear();
229 std::u16string_view rValue,
235 if(
static_cast<sal_Int32
>(rValue.size()) == nameLength &&
236 rtl_ustr_asciil_reverseEquals_WithLength(
237 rValue.data(), pMap->
GetName(), nameLength ) )
252 std::u16string_view rValue,
259 rEnum = pMap->GetValue();
271 std::string_view rValue,
278 rEnum = pMap->GetValue();
291 OUStringBuffer& rBuffer,
300 if( pMap->GetValue() == nValue )
302 eTok = pMap->GetToken();
320 if( nChar >=
'0' && nChar <=
'9' )
322 else if( nChar >=
'a' && nChar <=
'f' )
323 return nChar -
'a' + 10;
324 else if( nChar >=
'A' && nChar <=
'F' )
325 return nChar -
'A' + 10;
335 double fNumber)
const
343 std::u16string_view rString)
const
346 rString,
m_pImpl->m_eCoreMeasureUnit);
348 return ::sax::Converter::convertDouble(rValue, rString,
349 eSrcUnit,
m_pImpl->m_eCoreMeasureUnit);
354 std::string_view rString)
const
357 rString,
m_pImpl->m_eCoreMeasureUnit);
359 return ::sax::Converter::convertDouble(rValue, rString,
360 eSrcUnit,
m_pImpl->m_eCoreMeasureUnit);
366 css::uno::Reference <css::util::XNumberFormatsSupplier> xNumberFormatsSupplier (
xModel, css::uno::UNO_QUERY);
367 if (xNumberFormatsSupplier.is())
369 const css::uno::Reference <css::beans::XPropertySet> xPropertySet = xNumberFormatsSupplier->getNumberFormatSettings();
370 return xPropertySet.is() && (xPropertySet->getPropertyValue(
XML_NULLDATE) >>=
m_pImpl->m_aNullDate);
377 const double& fDateTime,
bool const bAddTimeIf0AM)
384 std::u16string_view rString)
const
391 std::string_view rString)
const
398 const double& fDateTime,
399 const css::util::Date& aTempNullDate,
402 double fValue = fDateTime;
403 const sal_Int32 nDays =
static_cast <sal_Int32
> (::rtl::math::approxFloor (fValue));
404 Date aDate (aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year);
407 const bool bHasTime = (fValue > 0.0);
409 sal_Int16 nTempYear = aDate.
GetYear();
410 assert(nTempYear != 0);
413 rBuffer.append(
'-');
414 nTempYear = -nTempYear;
416 if (nTempYear < 1000)
417 rBuffer.append(
'0');
419 rBuffer.append(
'0');
421 rBuffer.append(
'0');
422 rBuffer.append( sal_Int32( nTempYear));
423 rBuffer.append(
'-');
424 sal_uInt16 nTemp = aDate.
GetMonth();
425 assert(1 <= nTemp && nTemp <= 12);
427 rBuffer.append(
'0');
428 rBuffer.append( sal_Int32( nTemp));
429 rBuffer.append(
'-');
431 assert(1 <= nTemp && nTemp <= 31);
433 rBuffer.append(
'0');
434 rBuffer.append( sal_Int32( nTemp));
435 if (!(bHasTime || bAddTimeIf0AM))
440 fCount = ::rtl::math::approxFloor (log10(
static_cast<double>(nDays))) + 1;
442 fCount = ::rtl::math::approxFloor (log10(
static_cast<double>(nDays * -1))) + 1;
445 const int nDigits = sal_Int16(fCount) + 4;
448 sal_uInt16 nHour, nMinute, nSecond;
449 double fFractionOfSecond;
453 rBuffer.append(
'T');
455 rBuffer.append(
'0');
456 rBuffer.append( sal_Int32( nHour));
457 rBuffer.append(
':');
459 rBuffer.append(
'0');
460 rBuffer.append( sal_Int32( nMinute));
461 rBuffer.append(
':');
463 rBuffer.append(
'0');
464 rBuffer.append( sal_Int32( nSecond));
465 if (!nFractionDecimals)
470 OUString aFraction( ::rtl::math::doubleToUString( fFractionOfSecond,
471 rtl_math_StringFormat_F,
472 nFractionDecimals + 1,
'.',
true));
473 const sal_Int32 nLen = aFraction.getLength();
477 const sal_Int32
nCount = nLen - 2 -
static_cast<int>(nLen > nFractionDecimals + 2);
478 rBuffer.append(
'.');
479 rBuffer.append( aFraction.subView(2,
nCount));
486 V rString,
const css::util::Date& aTempNullDate)
488 css::util::DateTime aDateTime;
493 const Date aTmpNullDate(aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year);
494 const Date aTempDate(aDateTime.Day, aDateTime.Month, aDateTime.Year);
495 const sal_Int32 nTage = aTempDate - aTmpNullDate;
496 double fTempDateTime = nTage;
497 double Hour = aDateTime.Hours;
498 double Min = aDateTime.Minutes;
499 double Sec = aDateTime.Seconds;
500 double NanoSec = aDateTime.NanoSeconds;
505 fDateTime = fTempDateTime;
511 std::u16string_view rString,
const css::util::Date& aTempNullDate)
517 std::string_view rString,
const css::util::Date& aTempNullDate)
524: maTokenString( rString ), mnNextTokenPos(0), mcSeparator( cSeparator )
534 if( nTokenEndPos != std::u16string_view::npos )
554static bool lcl_getPositions(std::string_view _sValue, std::string_view& _rContentX, std::string_view& _rContentY, std::string_view& _rContentZ)
556 if(_sValue.empty() || _sValue[0] !=
'(')
560 size_t nFound = _sValue.find(
' ',
nPos);
562 if(nFound == std::string_view::npos || nFound <=
nPos)
565 _rContentX = _sValue.substr(
nPos, nFound -
nPos);
568 nFound = _sValue.find(
' ',
nPos);
570 if(nFound == std::string_view::npos || nFound <=
nPos)
573 _rContentY = _sValue.substr(
nPos, nFound -
nPos);
576 nFound = _sValue.find(
')',
nPos);
578 if(nFound == std::string_view::npos || nFound <=
nPos)
581 _rContentZ = _sValue.substr(
nPos, nFound -
nPos);
589 std::string_view aContentX,aContentY,aContentZ;
593 rtl_math_ConversionStatus eStatus;
595 rVector.
setX(::rtl::math::stringToDouble(aContentX,
'.',
598 if( eStatus != rtl_math_ConversionStatus_Ok )
601 rVector.
setY(::rtl::math::stringToDouble(aContentY,
'.',
604 if( eStatus != rtl_math_ConversionStatus_Ok )
607 rVector.
setZ(::rtl::math::stringToDouble(aContentZ,
'.',
611 return ( eStatus == rtl_math_ConversionStatus_Ok );
628 std::string_view rValue )
const
630 std::string_view aContentX,aContentY,aContentZ;
643 const drawing::Position3D& rPosition )
645 rBuffer.append(
'(' );
647 rBuffer.append(
' ' );
649 rBuffer.append(
' ' );
651 rBuffer.append(
')' );
656 const OUString& rNumFmt,
657 std::u16string_view rNumLetterSync,
658 bool bNumberNone )
const
663 sal_Int32 nLen = rNumFmt.getLength();
667 rType = NumberingType::NUMBER_NONE;
675 case '1': rType = NumberingType::ARABIC;
break;
676 case 'a': rType = NumberingType::CHARS_LOWER_LETTER;
break;
677 case 'A': rType = NumberingType::CHARS_UPPER_LETTER;
break;
678 case 'i': rType = NumberingType::ROMAN_LOWER;
break;
679 case 'I': rType = NumberingType::ROMAN_UPPER;
break;
680 default: bExt =
true;
break;
686 case NumberingType::CHARS_LOWER_LETTER:
687 rType = NumberingType::CHARS_LOWER_LETTER_N;
689 case NumberingType::CHARS_UPPER_LETTER:
690 rType = NumberingType::CHARS_UPPER_LETTER_N;
702 if( xInfo.is() && xInfo->hasNumberingType( rNumFmt ) )
704 rType = xInfo->getNumberingType( rNumFmt );
708 rType = NumberingType::ARABIC;
716 sal_Int16 nType )
const
721 case NumberingType::CHARS_UPPER_LETTER: eFormat =
XML_A_UPCASE;
break;
722 case NumberingType::CHARS_LOWER_LETTER: eFormat =
XML_A;
break;
723 case NumberingType::ROMAN_UPPER: eFormat =
XML_I_UPCASE;
break;
724 case NumberingType::ROMAN_LOWER: eFormat =
XML_I;
break;
725 case NumberingType::ARABIC: eFormat =
XML_1;
break;
726 case NumberingType::CHARS_UPPER_LETTER_N: eFormat =
XML_A_UPCASE;
break;
727 case NumberingType::CHARS_LOWER_LETTER_N: eFormat =
XML_A;
break;
728 case NumberingType::NUMBER_NONE: eFormat =
XML__EMPTY;
break;
730 case NumberingType::CHAR_SPECIAL:
731 case NumberingType::PAGE_DESCRIPTOR:
732 case NumberingType::BITMAP:
747 rBuffer.append( xInfo->getNumberingIdentifier(
nType ) );
757 case NumberingType::CHARS_UPPER_LETTER:
758 case NumberingType::CHARS_LOWER_LETTER:
759 case NumberingType::ROMAN_UPPER:
760 case NumberingType::ROMAN_LOWER:
761 case NumberingType::ARABIC:
762 case NumberingType::NUMBER_NONE:
765 case NumberingType::CHARS_UPPER_LETTER_N:
766 case NumberingType::CHARS_LOWER_LETTER_N:
770 case NumberingType::CHAR_SPECIAL:
771 case NumberingType::PAGE_DESCRIPTOR:
772 case NumberingType::BITMAP:
781 const uno::Reference<beans::XPropertySet>& aProperties)
783 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
aProperties->getPropertySetInfo();
784 if (!xPropertySetInfo.is())
787 const uno::Sequence< beans::Property > aProps = xPropertySetInfo->getProperties();
788 if (aProps.hasElements())
790 rProps.realloc(aProps.getLength());
791 beans::PropertyValue* pProps = rProps.getArray();
792 for (
const auto& rProp : aProps)
794 pProps->Name = rProp.Name;
795 pProps->Value =
aProperties->getPropertyValue(rProp.Name);
802 const uno::Sequence<beans::PropertyValue>& aProps)
804 if (aProps.hasElements())
806 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = rProperties->getPropertySetInfo();
807 if (xPropertySetInfo.is())
809 for (
const auto& rProp : aProps)
811 if (xPropertySetInfo->hasPropertyByName(rProp.Name))
812 rProperties->setPropertyValue(rProp.Name, rProp.Value);
820 const OUString& rName,
821 bool *pEncoded )
const
826 sal_Int32 nLen = rName.getLength();
827 OUStringBuffer
aBuffer( nLen*2 );
829 for( sal_Int32
i = 0;
i < nLen;
i++ )
832 bool bValidChar =
false;
836 (c >= 0x0041 && c <= 0x005a) ||
837 (c >= 0x0061 && c <= 0x007a) ||
838 (c >= 0x00c0 && c <= 0x00d6) ||
839 (c >= 0x00d8 && c <= 0x00f6) ||
840 (c >= 0x00f8 && c <= 0x00ff) ||
841 (
i > 0 && ( (c >= 0x0030 && c <= 0x0039) ||
842 c == 0x00b7 || c ==
'-' || c ==
'.') );
846 if( (c >= 0xf900U && c <= 0xfffeU) ||
847 (c >= 0x20ddU && c <= 0x20e0U))
851 else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 ||
852 c == 0x06e5 || c == 0x06e6 )
856 else if( c == 0x0387 )
862 if (!
m_pImpl->m_xCharClass.is())
864 m_pImpl->m_xCharClass = CharacterClassification::create(
m_pImpl->m_xContext );
870 case UnicodeType::UPPERCASE_LETTER:
871 case UnicodeType::LOWERCASE_LETTER:
872 case UnicodeType::TITLECASE_LETTER:
873 case UnicodeType::OTHER_LETTER:
874 case UnicodeType::LETTER_NUMBER:
877 case UnicodeType::NON_SPACING_MARK:
878 case UnicodeType::ENCLOSING_MARK:
879 case UnicodeType::COMBINING_SPACING_MARK:
880 case UnicodeType::MODIFIER_LETTER:
881 case UnicodeType::DECIMAL_DIGIT_NUMBER:
896 aHexTab[ (c >> 12) & 0x0f ] ) );
899 aHexTab[ (c >> 8) & 0x0f ] ) );
902 aHexTab[ (c >> 4) & 0x0f ] ) );
912 if(
aBuffer.getLength() > ((1<<15)-1) )
920 return aBuffer.makeStringAndClear();
926 if( rValue.size() != 8 )
930 for (
int i = 0;
i < 8;
i++ )
933 | sal::static_int_cast< sal_uInt32 >(
lcl_gethex( rValue[
i] ) );
943 for (
int i = 0;
i < 8;
i++ )
PropertiesInfo aProperties
void AddDays(sal_Int32 nAddDays)
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
std::u16string_view maTokenString
bool getNextToken(std::u16string_view &rToken)
SvXMLTokenEnumerator(std::u16string_view rString, sal_Unicode cSeparator=u' ')
bool convertPosition3D(css::drawing::Position3D &rPosition, std::string_view rValue) const
convert string to Position3D
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
ODF version, only when exporting.
bool convertNumFormat(sal_Int16 &rType, const OUString &rNumFormat, std::u16string_view rNumLetterSync, bool bNumberNone=false) const
convert num-format and num-letter-sync values to NumberingType
struct SAL_DLLPRIVATE Impl
bool convertMeasureToCore(sal_Int32 &rValue, std::u16string_view rString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32) const
convert string to measure with meCoreMeasureUnit, using optional min and max values
SvXMLUnitConverter(const SvXMLUnitConverter &)=delete
void convertDateTime(OUStringBuffer &rBuffer, const double &fDateTime, bool const bAddTimeIf0AM=false)
convert double to ISO Date Time String
OUString encodeStyleName(const OUString &rName, bool *pEncoded=nullptr) const
void SetCoreMeasureUnit(sal_Int16 const eCoreMeasureUnit)
sets the default unit for numerical measures
static void convertPropertySet(css::uno::Sequence< css::beans::PropertyValue > &rProps, const css::uno::Reference< css::beans::XPropertySet > &aProperties)
void SetXMLMeasureUnit(sal_Int16 const eXMLMeasureUnit)
sets the default unit for textual measures
static bool convertHex(sal_uInt32 &nVal, std::u16string_view rValue)
convert string (hex) to number (sal_uInt32)
::std::unique_ptr< Impl > m_pImpl
static sal_Int16 GetMeasureUnit(FieldUnit const nFieldUnit)
sal_Int16 GetXMLMeasureUnit() const
gets the default unit for textual measures
void convertDouble(OUStringBuffer &rBuffer, double fNumber) const
convert double number to string (using ::rtl::math) and DO convert to export MapUnit using meCoreMeas...
bool setNullDate(const css::uno::Reference< css::frame::XModel > &xModel)
get the Null Date of the XModel and set it to the UnitConverter
static bool convertB3DVector(::basegfx::B3DVector &rVector, std::string_view rValue)
convert string to basegfx::B3DVector
void convertMeasureToXML(OUStringBuffer &rBuffer, sal_Int32 nMeasure) const
convert measure to string: from meCoreMeasureUnit to meXMLMeasureUnit
void overrideSaneDefaultVersion(SvtSaveOptions::ODFSaneDefaultVersion const)
static void convertNumLetterSync(OUStringBuffer &rBuffer, sal_Int16 nType)
static bool convertEnumImpl(sal_uInt16 &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< sal_uInt16 > *pMap)
convert string to enum using given token map, if the enum is not found in the map,...
const css::uno::Reference< css::text::XNumberingTypeInfo > & getNumTypeInfo() const
gets XNumberingTypeInfo
static void convertDouble(OUStringBuffer &rBuffer, double fNumber, bool bWriteUnits, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
static bool convertMeasure(sal_Int32 &rValue, std::u16string_view rString, sal_Int16 nTargetUnit=css::util::MeasureUnit::MM_100TH, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
static bool parseDateTime(css::util::DateTime &rDateTime, std::u16string_view rString)
static sal_Int16 GetUnitFromString(std::u16string_view rString, sal_Int16 nDefaultUnit)
#define SAL_WARN_IF(condition, area, stream)
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
compare eToken to the string
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Map a const char* (with length) to a sal_uInt16 value.
const char * GetName() const
sal_Int32 GetNameLength() const
Impl(uno::Reference< uno::XComponentContext > xContext, sal_Int16 const eCoreMeasureUnit, sal_Int16 const eXMLMeasureUnit, SvtSaveOptions::ODFSaneDefaultVersion const nODFVersion)
sal_Int16 m_eCoreMeasureUnit
uno::Reference< uno::XComponentContext > m_xContext
uno::Reference< text::XNumberingTypeInfo > m_xNumTypeInfo
uno::Reference< i18n::XCharacterClassification > m_xCharClass
void createNumTypeInfo() const
sal_Int16 m_eXMLMeasureUnit
SvtSaveOptions::ODFSaneDefaultVersion m_eODFVersion
Reference< XModel > xModel
std::unique_ptr< char[]> aBuffer
constexpr OUStringLiteral XML_NULLDATE
static bool lcl_convertDateTime(double &fDateTime, V rString, const css::util::Date &aTempNullDate)
convert ISO Date Time String to double
const sal_Int8 XML_MAXDIGITSCOUNT_TIME
static int lcl_gethex(int nChar)
static bool lcl_getPositions(std::string_view _sValue, std::string_view &_rContentX, std::string_view &_rContentY, std::string_view &_rContentZ)