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>
74 mutable uno::Reference< i18n::XCharacterClassification >
m_xCharClass;
77 Impl(uno::Reference<uno::XComponentContext> xContext,
78 sal_Int16
const eCoreMeasureUnit,
79 sal_Int16
const eXMLMeasureUnit,
87 OSL_ENSURE(
m_xContext.is(),
"got no service manager" );
100const uno::Reference< text::XNumberingTypeInfo >&
103 if (!
m_pImpl->m_xNumTypeInfo.is())
107 return m_pImpl->m_xNumTypeInfo;
112 m_pImpl->m_eCoreMeasureUnit = eCoreMeasureUnit;
117 m_pImpl->m_eXMLMeasureUnit = eXMLMeasureUnit;
122 return m_pImpl->m_eXMLMeasureUnit;
133 m_pImpl->m_eODFVersion = nODFVersion;
142 const uno::Reference<uno::XComponentContext>& xContext,
143 sal_Int16
const eCoreMeasureUnit,
144 sal_Int16
const eXMLMeasureUnit,
146:
m_pImpl(new
Impl(xContext, eCoreMeasureUnit, eXMLMeasureUnit, nODFVersion))
156 sal_Int16 eUnit = util::MeasureUnit::INCH;
160 eUnit = util::MeasureUnit::MM;
165 eUnit = util::MeasureUnit::CM;
167 case FieldUnit::TWIP:
168 eUnit = util::MeasureUnit::TWIP;
170 case FieldUnit::POINT:
171 case FieldUnit::PICA:
172 eUnit = util::MeasureUnit::POINT;
174 case FieldUnit::MM_100TH:
175 eUnit = util::MeasureUnit::MM_100TH;
177 case FieldUnit::INCH:
178 eUnit = util::MeasureUnit::INCH;
189 std::u16string_view rString,
190 sal_Int32 nMin, sal_Int32 nMax )
const
192 return ::sax::Converter::convertMeasure(
nValue, rString,
199 std::string_view rString,
200 sal_Int32 nMin, sal_Int32 nMax )
const
202 return ::sax::Converter::convertMeasure(
nValue, rString,
209 sal_Int32 nMeasure )
const
223 return s.makeStringAndClear();
230 std::u16string_view rValue,
236 if(
static_cast<sal_Int32
>(rValue.size()) == nameLength &&
237 rtl_ustr_asciil_reverseEquals_WithLength(
238 rValue.data(), pMap->
GetName(), nameLength ) )
253 std::u16string_view rValue,
260 rEnum = pMap->GetValue();
272 std::string_view rValue,
279 rEnum = pMap->GetValue();
292 OUStringBuffer& rBuffer,
301 if( pMap->GetValue() == nValue )
303 eTok = pMap->GetToken();
321 if( nChar >=
'0' && nChar <=
'9' )
323 else if( nChar >=
'a' && nChar <=
'f' )
324 return nChar -
'a' + 10;
325 else if( nChar >=
'A' && nChar <=
'F' )
326 return nChar -
'A' + 10;
336 double fNumber)
const
344 std::u16string_view rString)
const
347 rString,
m_pImpl->m_eCoreMeasureUnit);
349 return ::sax::Converter::convertDouble(rValue, rString,
350 eSrcUnit,
m_pImpl->m_eCoreMeasureUnit);
355 std::string_view rString)
const
358 rString,
m_pImpl->m_eCoreMeasureUnit);
360 return ::sax::Converter::convertDouble(rValue, rString,
361 eSrcUnit,
m_pImpl->m_eCoreMeasureUnit);
367 css::uno::Reference <css::util::XNumberFormatsSupplier> xNumberFormatsSupplier (
xModel, css::uno::UNO_QUERY);
368 if (xNumberFormatsSupplier.is())
370 const css::uno::Reference <css::beans::XPropertySet> xPropertySet = xNumberFormatsSupplier->getNumberFormatSettings();
371 return xPropertySet.is() && (xPropertySet->getPropertyValue(
XML_NULLDATE) >>=
m_pImpl->m_aNullDate);
378 const double& fDateTime,
bool const bAddTimeIf0AM)
385 std::u16string_view rString)
const
392 std::string_view rString)
const
399 const double& fDateTime,
400 const css::util::Date& aTempNullDate,
403 double fValue = fDateTime;
404 const sal_Int32 nDays =
static_cast <sal_Int32
> (::rtl::math::approxFloor (fValue));
405 Date aDate (aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year);
408 const bool bHasTime = (fValue > 0.0);
410 sal_Int16 nTempYear = aDate.
GetYear();
411 assert(nTempYear != 0);
414 rBuffer.append(
'-');
415 nTempYear = -nTempYear;
417 if (nTempYear < 1000)
418 rBuffer.append(
'0');
420 rBuffer.append(
'0');
422 rBuffer.append(
'0');
423 rBuffer.append( sal_Int32( nTempYear));
424 rBuffer.append(
'-');
425 sal_uInt16 nTemp = aDate.
GetMonth();
426 assert(1 <= nTemp && nTemp <= 12);
428 rBuffer.append(
'0');
429 rBuffer.append( sal_Int32( nTemp));
430 rBuffer.append(
'-');
432 assert(1 <= nTemp && nTemp <= 31);
434 rBuffer.append(
'0');
435 rBuffer.append( sal_Int32( nTemp));
436 if (!(bHasTime || bAddTimeIf0AM))
441 fCount = ::rtl::math::approxFloor (log10(
static_cast<double>(nDays))) + 1;
443 fCount = ::rtl::math::approxFloor (log10(
static_cast<double>(nDays * -1))) + 1;
446 const int nDigits = sal_Int16(fCount) + 4;
449 sal_uInt16 nHour, nMinute, nSecond;
450 double fFractionOfSecond;
454 rBuffer.append(
'T');
456 rBuffer.append(
'0');
457 rBuffer.append( sal_Int32( nHour));
458 rBuffer.append(
':');
460 rBuffer.append(
'0');
461 rBuffer.append( sal_Int32( nMinute));
462 rBuffer.append(
':');
464 rBuffer.append(
'0');
465 rBuffer.append( sal_Int32( nSecond));
466 if (!nFractionDecimals)
471 OUString aFraction( ::rtl::math::doubleToUString( fFractionOfSecond,
472 rtl_math_StringFormat_F,
473 nFractionDecimals + 1,
'.',
true));
474 const sal_Int32 nLen = aFraction.getLength();
478 const sal_Int32
nCount = nLen - 2 -
static_cast<int>(nLen > nFractionDecimals + 2);
479 rBuffer.append(
'.');
480 rBuffer.append( aFraction.subView(2,
nCount));
487 V rString,
const css::util::Date& aTempNullDate)
489 css::util::DateTime aDateTime;
494 const Date aTmpNullDate(aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year);
495 const Date aTempDate(aDateTime.Day, aDateTime.Month, aDateTime.Year);
496 const sal_Int32 nTage = aTempDate - aTmpNullDate;
497 double fTempDateTime = nTage;
498 double Hour = aDateTime.Hours;
499 double Min = aDateTime.Minutes;
500 double Sec = aDateTime.Seconds;
501 double NanoSec = aDateTime.NanoSeconds;
506 fDateTime = fTempDateTime;
512 std::u16string_view rString,
const css::util::Date& aTempNullDate)
518 std::string_view rString,
const css::util::Date& aTempNullDate)
525: maTokenString( rString ), mnNextTokenPos(0), mcSeparator( cSeparator )
535 if( nTokenEndPos != std::u16string_view::npos )
555static bool lcl_getPositions(std::string_view _sValue, std::string_view& _rContentX, std::string_view& _rContentY, std::string_view& _rContentZ)
557 if(_sValue.empty() || _sValue[0] !=
'(')
561 size_t nFound = _sValue.find(
' ',
nPos);
563 if(nFound == std::string_view::npos || nFound <=
nPos)
566 _rContentX = _sValue.substr(
nPos, nFound -
nPos);
569 nFound = _sValue.find(
' ',
nPos);
571 if(nFound == std::string_view::npos || nFound <=
nPos)
574 _rContentY = _sValue.substr(
nPos, nFound -
nPos);
577 nFound = _sValue.find(
')',
nPos);
579 if(nFound == std::string_view::npos || nFound <=
nPos)
582 _rContentZ = _sValue.substr(
nPos, nFound -
nPos);
590 std::string_view aContentX,aContentY,aContentZ;
594 rtl_math_ConversionStatus eStatus;
596 rVector.
setX(::rtl::math::stringToDouble(aContentX,
'.',
599 if( eStatus != rtl_math_ConversionStatus_Ok )
602 rVector.
setY(::rtl::math::stringToDouble(aContentY,
'.',
605 if( eStatus != rtl_math_ConversionStatus_Ok )
608 rVector.
setZ(::rtl::math::stringToDouble(aContentZ,
'.',
612 return ( eStatus == rtl_math_ConversionStatus_Ok );
629 std::string_view rValue )
const
631 std::string_view aContentX,aContentY,aContentZ;
644 const drawing::Position3D& rPosition )
646 rBuffer.append(
'(' );
648 rBuffer.append(
' ' );
650 rBuffer.append(
' ' );
652 rBuffer.append(
')' );
657 const OUString& rNumFmt,
658 std::u16string_view rNumLetterSync,
659 bool bNumberNone )
const
664 sal_Int32 nLen = rNumFmt.getLength();
668 rType = NumberingType::NUMBER_NONE;
676 case '1': rType = NumberingType::ARABIC;
break;
677 case 'a': rType = NumberingType::CHARS_LOWER_LETTER;
break;
678 case 'A': rType = NumberingType::CHARS_UPPER_LETTER;
break;
679 case 'i': rType = NumberingType::ROMAN_LOWER;
break;
680 case 'I': rType = NumberingType::ROMAN_UPPER;
break;
681 default: bExt =
true;
break;
687 case NumberingType::CHARS_LOWER_LETTER:
688 rType = NumberingType::CHARS_LOWER_LETTER_N;
690 case NumberingType::CHARS_UPPER_LETTER:
691 rType = NumberingType::CHARS_UPPER_LETTER_N;
703 if( xInfo.is() && xInfo->hasNumberingType( rNumFmt ) )
705 rType = xInfo->getNumberingType( rNumFmt );
709 rType = NumberingType::ARABIC;
717 sal_Int16 nType )
const
722 case NumberingType::CHARS_UPPER_LETTER: eFormat =
XML_A_UPCASE;
break;
723 case NumberingType::CHARS_LOWER_LETTER: eFormat =
XML_A;
break;
724 case NumberingType::ROMAN_UPPER: eFormat =
XML_I_UPCASE;
break;
725 case NumberingType::ROMAN_LOWER: eFormat =
XML_I;
break;
726 case NumberingType::ARABIC: eFormat =
XML_1;
break;
727 case NumberingType::CHARS_UPPER_LETTER_N: eFormat =
XML_A_UPCASE;
break;
728 case NumberingType::CHARS_LOWER_LETTER_N: eFormat =
XML_A;
break;
729 case NumberingType::NUMBER_NONE: eFormat =
XML__EMPTY;
break;
731 case NumberingType::CHAR_SPECIAL:
732 case NumberingType::PAGE_DESCRIPTOR:
733 case NumberingType::BITMAP:
748 rBuffer.append( xInfo->getNumberingIdentifier(
nType ) );
758 case NumberingType::CHARS_UPPER_LETTER:
759 case NumberingType::CHARS_LOWER_LETTER:
760 case NumberingType::ROMAN_UPPER:
761 case NumberingType::ROMAN_LOWER:
762 case NumberingType::ARABIC:
763 case NumberingType::NUMBER_NONE:
766 case NumberingType::CHARS_UPPER_LETTER_N:
767 case NumberingType::CHARS_LOWER_LETTER_N:
771 case NumberingType::CHAR_SPECIAL:
772 case NumberingType::PAGE_DESCRIPTOR:
773 case NumberingType::BITMAP:
782 const uno::Reference<beans::XPropertySet>& aProperties,
783 const std::initializer_list<std::u16string_view>* pOmitFalseValues)
785 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
aProperties->getPropertySetInfo();
786 if (!xPropertySetInfo.is())
789 const uno::Sequence< beans::Property > aProps = xPropertySetInfo->getProperties();
790 if (aProps.hasElements())
792 std::vector<beans::PropertyValue> aPropsVec;
793 for (
const auto& rProp : aProps)
796 if (pOmitFalseValues && aPropertyValue.has<
bool>() && !aPropertyValue.get<
bool>())
798 const std::initializer_list<std::u16string_view>& rOmitFalseValues = *pOmitFalseValues;
799 if (std::find(rOmitFalseValues.begin(), rOmitFalseValues.end(), rProp.Name) != rOmitFalseValues.end())
805 beans::PropertyValue aValue;
806 aValue.Name = rProp.Name;
807 aValue.Value = aPropertyValue;
808 aPropsVec.push_back(aValue);
815 const uno::Sequence<beans::PropertyValue>& aProps)
817 if (aProps.hasElements())
819 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = rProperties->getPropertySetInfo();
820 if (xPropertySetInfo.is())
822 for (
const auto& rProp : aProps)
824 if (xPropertySetInfo->hasPropertyByName(rProp.Name))
825 rProperties->setPropertyValue(rProp.Name, rProp.Value);
833 const OUString& rName,
834 bool *pEncoded )
const
839 sal_Int32 nLen = rName.getLength();
840 OUStringBuffer
aBuffer( nLen*2 );
842 for( sal_Int32
i = 0;
i < nLen;
i++ )
845 bool bValidChar =
false;
849 (c >= 0x0041 && c <= 0x005a) ||
850 (c >= 0x0061 && c <= 0x007a) ||
851 (c >= 0x00c0 && c <= 0x00d6) ||
852 (c >= 0x00d8 && c <= 0x00f6) ||
853 (c >= 0x00f8 && c <= 0x00ff) ||
854 (
i > 0 && ( (c >= 0x0030 && c <= 0x0039) ||
855 c == 0x00b7 || c ==
'-' || c ==
'.') );
859 if( (c >= 0xf900U && c <= 0xfffeU) ||
860 (c >= 0x20ddU && c <= 0x20e0U))
864 else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 ||
865 c == 0x06e5 || c == 0x06e6 )
869 else if( c == 0x0387 )
875 if (!
m_pImpl->m_xCharClass.is())
877 m_pImpl->m_xCharClass = CharacterClassification::create(
m_pImpl->m_xContext );
883 case UnicodeType::UPPERCASE_LETTER:
884 case UnicodeType::LOWERCASE_LETTER:
885 case UnicodeType::TITLECASE_LETTER:
886 case UnicodeType::OTHER_LETTER:
887 case UnicodeType::LETTER_NUMBER:
890 case UnicodeType::NON_SPACING_MARK:
891 case UnicodeType::ENCLOSING_MARK:
892 case UnicodeType::COMBINING_SPACING_MARK:
893 case UnicodeType::MODIFIER_LETTER:
894 case UnicodeType::DECIMAL_DIGIT_NUMBER:
909 aHexTab[ (c >> 12) & 0x0f ] ) );
912 aHexTab[ (c >> 8) & 0x0f ] ) );
915 aHexTab[ (c >> 4) & 0x0f ] ) );
925 if(
aBuffer.getLength() > ((1<<15)-1) )
933 return aBuffer.makeStringAndClear();
939 if( rValue.size() != 8 )
943 for (
int i = 0;
i < 8;
i++ )
946 | sal::static_int_cast< sal_uInt32 >(
lcl_gethex( rValue[
i] ) );
956 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, const std::initializer_list< std::u16string_view > *pOmitFalseValues=nullptr)
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)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
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)