26#include <osl/diagnose.h>
27#include <rtl/math.hxx>
28#include <rtl/ustrbuf.hxx>
55struct SvXMLNumFmtEntry
61 SvXMLNumFmtEntry( OUString aN, sal_uInt32 nK,
bool bR ) :
62 aName(
std::move(aN)), nKey(nK), bRemoveAfterUse(bR) {}
78 const uno::Reference<uno::XComponentContext>& rxContext );
83 void AddKey( sal_uInt32 nKey,
const OUString& rName,
bool bRemoveAfterUse );
84 void SetUsed( sal_uInt32 nKey );
114enum class SvXMLStyleTokens;
119 SvXMLStyleTokens
nType;
120 OUStringBuffer aContent;
128 SvXMLNumFmtElementContext( SvXMLImport& rImport, sal_Int32 nElement,
130 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
133 sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList )
override;
134 virtual void SAL_CALL
characters(
const OUString& rChars )
override;
135 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
137 void AddEmbeddedElement( sal_Int32 nFormatPos,
const OUString& rContent );
142 SvXMLNumFmtElementContext& rParent;
143 OUStringBuffer aContent;
144 sal_Int32 nTextPosition;
147 SvXMLNumFmtEmbeddedTextContext( SvXMLImport& rImport, sal_Int32 nElement,
148 SvXMLNumFmtElementContext& rParentContext,
149 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
151 virtual void SAL_CALL
characters(
const OUString& rChars )
override;
152 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
162 SvXMLNumFmtMapContext( SvXMLImport& rImport, sal_Int32 nElement,
164 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
166 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
176 SvXMLNumFmtPropContext( SvXMLImport& rImport, sal_Int32 nElement,
178 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
180 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
183enum class SvXMLStyleTokens
211#define XML_NUMF_COLORCOUNT 10
249struct SvXMLDefaultDateFormat
291 const uno::Reference<uno::XComponentContext>& rxContext )
295 SAL_WARN_IF( !rxContext.is(),
"xmloff",
"got no service manager" );
302 if (rObj.aName == rName)
310 if ( bRemoveAfterUse )
317 if (rObj.nKey == nKey && !rObj.bRemoveAfterUse)
319 bRemoveAfterUse =
false;
337 if (rObj.nKey == nKey)
339 rObj.bRemoveAfterUse =
false;
359 if (rObj.bRemoveAfterUse )
362 if (pFormat && (pFormat->
GetType() & SvNumFormatType::DEFINED))
381SvXMLNumFmtMapContext::SvXMLNumFmtMapContext( SvXMLImport& rImport,
384 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
386 rParent( rParentContext )
390 OUString sValue = aIter.toString();
391 switch(aIter.getToken())
405void SvXMLNumFmtMapContext::endFastElement(sal_Int32 )
407 rParent.AddCondition( sCondition, sName );
414SvXMLNumFmtPropContext::SvXMLNumFmtPropContext( SvXMLImport& rImport,
417 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
419 rParent( rParentContext ),
425 switch ( aIter.getToken())
429 bColSet = ::
sax::Converter::convertColor( m_nColor, aIter.toView() );
437void SvXMLNumFmtPropContext::endFastElement(sal_Int32 )
440 rParent.AddColor( m_nColor );
447SvXMLNumFmtEmbeddedTextContext::SvXMLNumFmtEmbeddedTextContext( SvXMLImport& rImport,
449 SvXMLNumFmtElementContext& rParentContext,
450 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
452 rParent( rParentContext ),
462 nTextPosition = nAttrVal;
469void SvXMLNumFmtEmbeddedTextContext::characters(
const OUString& rChars )
471 aContent.append( rChars );
474void SvXMLNumFmtEmbeddedTextContext::endFastElement(sal_Int32 )
476 rParent.AddEmbeddedElement( nTextPosition, aContent.makeStringAndClear() );
490 (cChar ==
' ' && cTS == cNBSP)) )
507 if ( ( cChar ==
' ' ||
526 ( cChar ==
'(' || cChar ==
')' ) )
535 sal_Int32
nLength = rContent.getLength();
541 ((rContent[0] ==
' ' && rContent[1] ==
'-') ||
542 (rContent[1] ==
' ' &&
lcl_ValidChar( rContent[0], rParent))))))
556 sal_Int32
nPos = rContent.indexOf(
'%' );
568 rContent.insert(
nPos + 1,
'"' );
569 rContent.append(
'"' );
581 rContent.insert(
nPos,
'"' );
582 rContent.insert( 0,
'"' );
594 bool bEscape = ( rContent.indexOf(
'"' ) >= 0 );
599 OUString aInsert(
"\"\\\"" );
602 while (
nPos < rContent.getLength() )
604 if ( rContent[
nPos] ==
'"' )
606 rContent.insert(
nPos, aInsert );
607 nPos += aInsert.getLength();
614 rContent.insert( 0,
'"' );
615 rContent.append(
'"' );
621 if ( rContent.getLength() > 2 &&
622 rContent[0] ==
'"' &&
625 rContent.remove(0, 2);
628 sal_Int32 nLen = rContent.getLength();
630 rContent[nLen - 1] ==
'"' &&
631 rContent[nLen - 2] ==
'"' )
633 rContent.truncate(nLen - 2);
641SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
644 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
646 rParent( rParentContext ),
654 bool bAttrBool(
false);
655 bool bVarDecimals =
false;
656 bool bIsMaxDenominator =
false;
661 switch (aIter.getToken())
667 aNumInfo.nDecimals = std::min<sal_Int32>(nAttrVal, NF_MAX_FORMAT_SYMBOLS);
673 aNumInfo.nMinDecimalDigits = nAttrVal;
677 aNumInfo.nInteger = nAttrVal;
682 aNumInfo.nBlankInteger = nAttrVal;
685 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
686 aNumInfo.bGrouping = bAttrBool;
689 if (::
sax::Converter::convertDouble( fAttrDouble, aIter.toView() ))
690 aNumInfo.fDisplayFactor = fAttrDouble;
693 if ( aIter.toView() ==
" " )
695 aNumInfo.bDecAlign =
true;
699 if ( aIter.isEmpty() )
702 aNumInfo.bDecReplace =
true;
711 aNumInfo.nExpInterval = nAttrVal;
715 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
716 aNumInfo.bExpSign = bAttrBool;
720 aNumInfo.nMinNumerDigits = nAttrVal;
724 aNumInfo.nMinDenomDigits = nAttrVal;
728 aNumInfo.nMaxNumerDigits = nAttrVal;
733 aNumInfo.nFracDenominator = nAttrVal;
734 bIsMaxDenominator =
false;
739 if (::
sax::Converter::
convertNumber( nAttrVal, aIter.toView(), 1 ) && aNumInfo.nFracDenominator <= 0)
741 aNumInfo.nFracDenominator = nAttrVal;
742 bIsMaxDenominator =
true;
748 aNumInfo.nZerosNumerDigits = nAttrVal;
753 aNumInfo.nZerosDenomDigits = nAttrVal;
757 aNumInfo.aIntegerFractionDelimiter = aIter.
toString();
760 aLanguageTagODF.maRfcLanguageTag = aIter.
toString();
763 aLanguageTagODF.maLanguage = aIter.
toString();
766 aLanguageTagODF.maScript = aIter.
toString();
769 aLanguageTagODF.maCountry = aIter.
toString();
775 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
776 bTextual = bAttrBool;
785 if ( aNumInfo.nBlankInteger > aNumInfo.nInteger )
786 aNumInfo.nInteger = aNumInfo.nBlankInteger;
787 if ( aNumInfo.nMinDecimalDigits == -1)
789 if ( bVarDecimals || aNumInfo.bDecReplace )
790 aNumInfo.nMinDecimalDigits = 0;
792 aNumInfo.nMinDecimalDigits = aNumInfo.nDecimals;
794 if ( aNumInfo.nZerosDenomDigits > 0 )
796 if ( aNumInfo.nMinDenomDigits < aNumInfo.nZerosDenomDigits )
797 aNumInfo.nMinDenomDigits = aNumInfo.nZerosDenomDigits;
800 aNumInfo.nZerosDenomDigits = 0;
801 if ( aNumInfo.nMinDenomDigits >= 0 )
802 if ( aNumInfo.nMaxDenomDigits < aNumInfo.nMinDenomDigits )
803 aNumInfo.nMaxDenomDigits = ( aNumInfo.nMinDenomDigits ? aNumInfo.nMinDenomDigits : 1 );
804 if ( aNumInfo.nZerosNumerDigits > 0 )
806 if ( aNumInfo.nMinNumerDigits < aNumInfo.nZerosNumerDigits )
807 aNumInfo.nMinNumerDigits = aNumInfo.nZerosNumerDigits;
810 aNumInfo.nZerosNumerDigits = 0;
811 if ( aNumInfo.nMinNumerDigits >= 0 )
812 if ( aNumInfo.nMaxNumerDigits < aNumInfo.nMinNumerDigits )
813 aNumInfo.nMaxNumerDigits = ( aNumInfo.nMinNumerDigits ? aNumInfo.nMinNumerDigits : 1 );
814 if ( bIsMaxDenominator && aNumInfo.nFracDenominator > 0 )
816 aNumInfo.nMaxDenomDigits = floor( log10( aNumInfo.nFracDenominator ) ) + 1;
817 aNumInfo.nFracDenominator = -1;
819 if ( aNumInfo.nMaxDenomDigits > 0 )
821 if ( aNumInfo.nMinDenomDigits < 0 )
822 aNumInfo.nMinDenomDigits = 0;
823 else if ( aNumInfo.nMinDenomDigits > aNumInfo.nMaxDenomDigits )
824 aNumInfo.nMinDenomDigits = aNumInfo.nMaxDenomDigits;
827 if ( !aLanguageTagODF.
isEmpty() )
830 if ( nElementLang == LANGUAGE_DONTKNOW )
834 if ( aNumInfo.aIntegerFractionDelimiter.isEmpty() )
835 aNumInfo.aIntegerFractionDelimiter =
" ";
838css::uno::Reference< css::xml::sax::XFastContextHandler > SvXMLNumFmtElementContext::createFastChildContext(
840 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
844 if ( ( nType == SvXMLStyleTokens::Number || nType == SvXMLStyleTokens::ScientificNumber ) &&
847 return new SvXMLNumFmtEmbeddedTextContext( GetImport(), nElement, *
this, xAttrList );
854void SvXMLNumFmtElementContext::characters(
const OUString& rChars )
856 aContent.append( rChars );
859void SvXMLNumFmtElementContext::AddEmbeddedElement( sal_Int32 nFormatPos,
const OUString& rContent )
861 if (rContent.isEmpty())
864 auto iterPair = aNumInfo.m_EmbeddedElements.emplace(nFormatPos, rContent);
865 if (!iterPair.second)
867 iterPair.first->second += rContent;
870void SvXMLNumFmtElementContext::endFastElement(sal_Int32 )
872 bool bEffLong = bLong;
875 case SvXMLStyleTokens::Text:
876 if ( rParent.HasLongDoW() &&
877 std::u16string_view(aContent) == rParent.GetLocaleData().getLongDateDayOfWeekSep() )
882 if ( rParent.ReplaceNfKeyword( NF_KEY_NNN, NF_KEY_NNNN ) )
887 rParent.SetHasLongDoW(
false );
889 if ( !aContent.isEmpty() )
892 rParent.AddToCode( aContent );
893 aContent.setLength(0);
898 aContent.append(
"\"\"");
899 rParent.AddToCode( aContent );
900 aContent.setLength(0);
901 rParent.SetHasTrailingEmptyText(
true);
905 case SvXMLStyleTokens::Number:
906 rParent.AddNumber( aNumInfo );
909 case SvXMLStyleTokens::CurrencySymbol:
910 rParent.AddCurrency( aContent.makeStringAndClear(), nElementLang );
913 case SvXMLStyleTokens::TextContent:
914 rParent.AddToCode(
'@');
916 case SvXMLStyleTokens::FillCharacter:
917 if ( !aContent.isEmpty() )
919 rParent.AddToCode(
'*' );
920 rParent.AddToCode( aContent[0] );
923 case SvXMLStyleTokens::Boolean:
924 rParent.AddNfKeyword( NF_KEY_BOOLEAN );
927 case SvXMLStyleTokens::Day:
928 rParent.UpdateCalendar( sCalendar );
931 rParent.AddNfKeyword(
932 sal::static_int_cast< sal_uInt16 >(
933 bEffLong ? NF_KEY_DD : NF_KEY_D ) );
935 case SvXMLStyleTokens::Month:
936 rParent.UpdateCalendar( sCalendar );
939 rParent.AddNfKeyword(
940 sal::static_int_cast< sal_uInt16 >(
942 ? ( bEffLong ? NF_KEY_MMMM : NF_KEY_MMM )
943 : ( bEffLong ? NF_KEY_MM : NF_KEY_M ) ) );
945 case SvXMLStyleTokens::Year:
952 rParent.UpdateCalendar( sCalendar);
954 if (eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY
955 || eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY_FROM_OTHER)
957 rParent.AddNfKeyword(
958 sal::static_int_cast< sal_uInt16 >(
959 bEffLong ? NF_KEY_EEC : NF_KEY_EC ) );
963 rParent.AddNfKeyword(
964 sal::static_int_cast< sal_uInt16 >(
965 bEffLong ? NF_KEY_YYYY : NF_KEY_YY ) );
969 case SvXMLStyleTokens::Era:
970 rParent.UpdateCalendar( sCalendar );
972 rParent.AddNfKeyword(
973 sal::static_int_cast< sal_uInt16 >(
974 bEffLong ? NF_KEY_GGG : NF_KEY_G ) );
977 case SvXMLStyleTokens::DayOfWeek:
982 rParent.UpdateCalendar( sCalendar);
984 if (eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY
985 || eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY_FROM_OTHER)
987 rParent.AddNfKeyword(
988 sal::static_int_cast< sal_uInt16 >(
989 bEffLong ? NF_KEY_AAAA : NF_KEY_AAA ) );
993 rParent.AddNfKeyword(
994 sal::static_int_cast< sal_uInt16 >(
995 bEffLong ? NF_KEY_NNNN : NF_KEY_NN ) );
999 case SvXMLStyleTokens::WeekOfYear:
1000 rParent.UpdateCalendar( sCalendar );
1001 rParent.AddNfKeyword( NF_KEY_WW );
1003 case SvXMLStyleTokens::Quarter:
1004 rParent.UpdateCalendar( sCalendar );
1005 rParent.AddNfKeyword(
1006 sal::static_int_cast< sal_uInt16 >(
1007 bEffLong ? NF_KEY_QQ : NF_KEY_Q ) );
1009 case SvXMLStyleTokens::Hours:
1010 rParent.AddNfKeyword(
1011 sal::static_int_cast< sal_uInt16 >(
1012 bEffLong ? NF_KEY_HH : NF_KEY_H ) );
1014 case SvXMLStyleTokens::AmPm:
1016 rParent.AddNfKeyword( NF_KEY_AMPM );
1018 case SvXMLStyleTokens::Minutes:
1019 rParent.AddNfKeyword(
1020 sal::static_int_cast< sal_uInt16 >(
1021 bEffLong ? NF_KEY_MMI : NF_KEY_MI ) );
1023 case SvXMLStyleTokens::Seconds:
1024 rParent.AddNfKeyword(
1025 sal::static_int_cast< sal_uInt16 >(
1026 bEffLong ? NF_KEY_SS : NF_KEY_S ) );
1027 if ( aNumInfo.nDecimals > 0 )
1030 rParent.AddToCode(rParent.GetLocaleData().getNumDecimalSep());
1031 for (sal_Int32 i=0;
i<aNumInfo.nDecimals;
i++)
1033 rParent.AddToCode(
'0');
1038 case SvXMLStyleTokens::Fraction:
1040 if ( aNumInfo.nInteger >= 0 )
1043 aNumInfo.nDecimals = 0;
1044 rParent.AddNumber( aNumInfo );
1045 OUStringBuffer sIntegerFractionDelimiter(aNumInfo.aIntegerFractionDelimiter);
1047 rParent.AddToCode( sIntegerFractionDelimiter );
1053 for (i=aNumInfo.nMaxNumerDigits; i > 0; i--)
1055 if ( i > aNumInfo.nMinNumerDigits )
1056 rParent.AddToCode(
'#' );
1057 else if ( i > aNumInfo.nZerosNumerDigits )
1058 rParent.AddToCode(
'?' );
1060 rParent.AddToCode(
'0' );
1062 rParent.AddToCode(
'/' );
1063 if ( aNumInfo.nFracDenominator > 0 )
1065 rParent.AddToCode( OUString::number( aNumInfo.nFracDenominator ) );
1069 for (i=aNumInfo.nMaxDenomDigits; i > 0 ; i--)
1071 if ( i > aNumInfo.nMinDenomDigits )
1072 rParent.AddToCode(
'#' );
1073 else if ( i > aNumInfo.nZerosDenomDigits )
1074 rParent.AddToCode(
'?' );
1076 rParent.AddToCode(
'0' );
1082 case SvXMLStyleTokens::ScientificNumber:
1085 if( !aNumInfo.bGrouping && aNumInfo.nExpInterval > aNumInfo.nInteger )
1087 for (sal_Int32 i=aNumInfo.nInteger; i<aNumInfo.nExpInterval; i++)
1089 rParent.AddToCode(
'#' );
1092 rParent.AddNumber( aNumInfo );
1094 if ( aNumInfo.bExpSign )
1095 rParent.AddToCode( u
"E+" );
1097 rParent.AddToCode( u
"E" );
1098 for (sal_Int32 i=0;
i<aNumInfo.nExpDigits;
i++)
1100 rParent.AddToCode(
'0' );
1106 assert(
false &&
"invalid element ID");
1118 if ( bSystem == rEntry.bSystem &&
1127 return sal::static_int_cast< sal_uInt16 >(rEntry.eFormat);
1140 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList,
1144 m_pStyles( &rStyles ),
1145 m_nType( nNewType ),
1147 m_eImplicitCalendar(ImplicitCalendar::
DEFAULT),
1149 m_bAutoOrder( false ),
1150 m_bFromSystem( false ),
1151 m_bTruncate( true ),
1152 m_bAutoDec( false ),
1153 m_bAutoInt( false ),
1154 m_bHasExtraText( false ),
1155 m_bHasTrailingEmptyText( false ),
1156 m_bHasLongDoW( false ),
1157 m_bHasDateTime( false ),
1158 m_bRemoveAfterUse( false ),
1166 m_bDateNoDefault( false )
1169 css::i18n::NativeNumberXmlAttributes aNatNumAttr;
1171 bool bAttrBool(
false);
1175 switch (aIter.getToken())
1181 aLanguageTagODF.maRfcLanguageTag = aIter.
toString();
1184 aLanguageTagODF.maLanguage = aIter.
toString();
1187 aLanguageTagODF.maScript = aIter.
toString();
1190 aLanguageTagODF.maCountry = aIter.
toString();
1196 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
1197 m_bAutoOrder = bAttrBool;
1203 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
1204 m_bTruncate = bAttrBool;
1209 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
1210 m_bRemoveAfterUse = bAttrBool;
1233 if (!aLanguageTagODF.
isEmpty())
1236 if ( m_nFormatLang == LANGUAGE_DONTKNOW )
1240 if (aNatNumAttr.Format.isEmpty() && aSpellout.isEmpty())
1243 LanguageTag aLanguageTag( OUString(), aNatNumAttr.Locale.Language,
1244 std::u16string_view(), aNatNumAttr.Locale.Country);
1245 aNatNumAttr.Locale = aLanguageTag.getLocale(
false);
1248 if ( !aSpellout.isEmpty() )
1250 m_aFormatCode.append(
"[NatNum12 " );
1251 m_aFormatCode.append( aSpellout );
1254 if ( !pFormatter )
return;
1256 sal_Int32
nNatNum = pFormatter->
GetNatNum()->convertFromXmlAttributes( aNatNumAttr );
1257 m_aFormatCode.append(
"[NatNum" );
1258 m_aFormatCode.append( nNatNum );
1261 LanguageType eLang = aLanguageTag.getLanguageType(
false );
1262 if ( eLang == LANGUAGE_DONTKNOW )
1264 if ( eLang != m_nFormatLang && eLang != LANGUAGE_SYSTEM )
1266 m_aFormatCode.append(
"][$-" );
1268 m_aFormatCode.append(OUString::number(
static_cast<sal_uInt16
>(eLang), 16).toAsciiUpperCase());
1270 m_aFormatCode.append(
']' );
1274 const OUString& rName,
1275 const uno::Reference<xml::sax::XFastAttributeList>& ,
1280 m_pStyles( &rStyles ),
1283 m_eImplicitCalendar(ImplicitCalendar::
DEFAULT),
1284 m_nFormatLang( nLang ),
1285 m_bAutoOrder( false ),
1286 m_bFromSystem( false ),
1287 m_bTruncate( true ),
1288 m_bAutoDec( false ),
1289 m_bAutoInt( false ),
1290 m_bHasExtraText( false ),
1291 m_bHasTrailingEmptyText( false ),
1292 m_bHasLongDoW( false ),
1293 m_bHasDateTime( false ),
1294 m_bRemoveAfterUse( false ),
1302 m_bDateNoDefault( false )
1313 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
1321 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1322 *
this, SvXMLStyleTokens::Text, xAttrList );
1326 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1327 *
this, SvXMLStyleTokens::FillCharacter, xAttrList );
1330 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1331 *
this, SvXMLStyleTokens::Number, xAttrList );
1334 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1335 *
this, SvXMLStyleTokens::ScientificNumber, xAttrList );
1338 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1339 *
this, SvXMLStyleTokens::Fraction, xAttrList );
1342 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1343 *
this, SvXMLStyleTokens::CurrencySymbol, xAttrList );
1346 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1347 *
this, SvXMLStyleTokens::Day, xAttrList );
1350 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1351 *
this, SvXMLStyleTokens::Month, xAttrList );
1354 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1355 *
this, SvXMLStyleTokens::Year, xAttrList );
1358 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1359 *
this, SvXMLStyleTokens::Era, xAttrList );
1362 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1363 *
this, SvXMLStyleTokens::DayOfWeek, xAttrList );
1366 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1367 *
this, SvXMLStyleTokens::WeekOfYear, xAttrList );
1370 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1371 *
this, SvXMLStyleTokens::Quarter, xAttrList );
1374 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1375 *
this, SvXMLStyleTokens::Hours, xAttrList );
1378 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1379 *
this, SvXMLStyleTokens::AmPm, xAttrList );
1382 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1383 *
this, SvXMLStyleTokens::Minutes, xAttrList );
1386 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1387 *
this, SvXMLStyleTokens::Seconds, xAttrList );
1390 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1391 *
this, SvXMLStyleTokens::Boolean, xAttrList );
1394 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1395 *
this, SvXMLStyleTokens::TextContent, xAttrList );
1399 pContext =
new SvXMLNumFmtPropContext(
GetImport(), nElement,
1406 pContext =
new SvXMLNumFmtMapContext(
GetImport(), nElement,
1414 SAL_WARN(
"xmloff.core",
"No context for unknown-element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
1466 comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>( xFormatsSupplier );
1489 OSL_FAIL(
"no number formatter");
1501 SAL_INFO(
"xmloff.style",
"invalid style:map references containing style");
1577 OUString aFormatStr( sFormat );
1581 sal_Int32 nErrPos = 0;
1584 if ( !bOk && nErrPos == 0 && aFormatStr != sFormat )
1633 OSL_FAIL(
"invalid number format");
1679 sal_uInt16 nPrec = 0;
1680 sal_uInt16 nLeading = 0;
1682 nPrec =
static_cast<sal_uInt16
>(rInfo.
nDecimals);
1684 nLeading =
static_cast<sal_uInt16
>(rInfo.
nInteger);
1710 sal_uInt16 nGenPrec = nPrec;
1723 bGrouping,
false, nGenPrec, nLeading ));
1725 if ( rInfo.
nExpDigits >= 0 && nLeading == 0 && !bGrouping && nEmbeddedCount == 0 )
1730 aNumStr.stripStart(
'#');
1739 if ( nIntegerEnd < 0 )
1740 nIntegerEnd = aNumStr.getLength();
1741 while ( nIndex < nIntegerEnd && nBlanks > 0 )
1743 if ( aNumStr[
nIndex] ==
'0' )
1755 sal_Int32 nDigits = rInfo.
nInteger;
1757 if ( nIntegerEnd < 0 )
1758 nIntegerEnd = aNumStr.getLength();
1761 if ( (
nIndex = aNumStr.indexOf(
'#',
nIndex ) ) >= 0 )
1772 aNumStr.insert( 0,
'#' );
1784 aNumStr.append( cAdd );
1787 if ( nEmbeddedCount )
1796 nZeroPos = aNumStr.getLength();
1801 if ( nLastFormatPos >= nZeroPos )
1806 sal_Int32 nAddCount = nLastFormatPos + 1 - nZeroPos;
1809 aNumStr.insert(0,
'#');
1811 nZeroPos = nZeroPos + nAddCount;
1817 sal_Int32
const nFormatPos = it.first;
1818 sal_Int32 nInsertPos = nZeroPos - nFormatPos;
1819 if ( nInsertPos >= 0 )
1824 aNumStr.insert(nInsertPos, OUString::Concat(
"\"") + it.second +
"\"");
1839 sal_Int32 nSepCount =
static_cast<sal_Int32
>(::rtl::math::round( log10(rInfo.
fDisplayFactor) / 3.0 ));
1840 if ( nSepCount > 0 )
1843 for ( sal_Int32
i=0;
i<nSepCount;
i++ )
1850 bool bAutomatic =
false;
1851 OUString aSymbol = rContent;
1852 if ( aSymbol.isEmpty())
1858 OUString sCurString, sDummy;
1860 aSymbol = sCurString;
1883 sal_Int32 nFirst =
nLength - 2;
1908 m_aFormatCode.append(
"-" + OUString(OUString::number(sal_uInt16(nLang), 16)).toAsciiUpperCase());
1975static bool lcl_IsAtEnd( OUStringBuffer& rBuffer, std::u16string_view rToken )
1977 sal_Int32 nBufLen = rBuffer.getLength();
1978 sal_Int32 nTokLen = rToken.size();
1980 if ( nTokLen > nBufLen )
1983 sal_Int32 nStartPos = nBufLen - nTokLen;
1984 for ( sal_Int32 nTokPos = 0; nTokPos < nTokLen; nTokPos++ )
1985 if ( rToken[ nTokPos ] != rBuffer[nStartPos + nTokPos] )
2023 rCondition.startsWith(
"value()", &sRealCond)) )
2029 bool bDefaultCond =
false;
2034 bDefaultCond =
true;
2040 bDefaultCond =
true;
2046 sal_Int32
nPos = sRealCond.indexOf(
"!=" );
2049 sRealCond = sRealCond.replaceAt(
nPos, 2,
u"<>" );
2052 nPos = sRealCond.indexOf(
'.' );
2057 if ( rDecSep.getLength() > 1 || rDecSep[0] !=
'.' )
2059 sRealCond = sRealCond.replaceAt(
nPos, 1, rDecSep );
2086 OUStringBuffer aColName;
2094 if ( !aColName.isEmpty() )
2096 aColName.insert( 0,
'[' );
2097 aColName.append(
']' );
2110 ImplicitCalendar::DEFAULT_FROM_OTHER : ImplicitCalendar::DEFAULT);
2115 ImplicitCalendar::DEFAULT_FROM_OTHER : ImplicitCalendar::DEFAULT);
2121 ImplicitCalendar::SECONDARY_FROM_OTHER : ImplicitCalendar::SECONDARY);
2126 ImplicitCalendar::SECONDARY_FROM_OTHER : ImplicitCalendar::SECONDARY);
2138 bool bSameDefault =
false;
2139 if (
m_sCalendar.isEmpty() || rNewCalendar.isEmpty())
2146 bSameDefault = (rNewCalendar == rDefaultCalendar ||
m_sCalendar == rDefaultCalendar);
2151 if (rNewCalendar.isEmpty())
2178 const uno::Reference<util::XNumberFormatsSupplier>& rSupp,
2179 const uno::Reference<uno::XComponentContext>& rxContext )
2181 SAL_WARN_IF( !rxContext.is(),
"xmloff",
"got no service manager" );
2185 comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>( rSupp );
2189 m_pData = std::make_unique<SvXMLNumImpData>( pFormatter, rxContext );
2194 const uno::Reference<uno::XComponentContext>& rxContext )
2196 SAL_WARN_IF( !rxContext.is(),
"xmloff",
"got no service manager" );
2198 m_pData = std::make_unique<SvXMLNumImpData>( pNumberFormatter, rxContext );
2204 m_pData->RemoveVolatileFormats();
2210 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList,
2242 m_pData.get(), nStyleToken, xAttrList, rStyles );
2247 if (
m_pData->GetNumberFormatter())
const uno::Reference< uno::XComponentContext > m_xContext
LanguageType getLanguageType(bool bResolveSystem=true) const
const OUString & getNumThousandSep() const
const std::shared_ptr< css::i18n::Calendar2 > & getDefaultCalendar() const
const OUString & getNumDecimalSep() const
bool doesSecondaryCalendarUseEC(std::u16string_view rName) const
sal_uInt16 getCurrDigits() const
This class deliberately does not support XWeak, to improve performance when loading large documents.
virtual void SAL_CALL endFastElement(sal_Int32 Element) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
SvXMLImport & GetImport()
SvXMLImportContext(SvXMLImport &rImport)
A contexts constructor does anything that is required if an element starts.
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
virtual void SAL_CALL characters(const OUString &aChars) override
This method is called for all characters that are contained in the current element.
static sal_uInt16 GetDefaultDateFormat(SvXMLDateElementAttributes eDOW, SvXMLDateElementAttributes eDay, SvXMLDateElementAttributes eMonth, SvXMLDateElementAttributes eYear, SvXMLDateElementAttributes eHours, SvXMLDateElementAttributes eMins, SvXMLDateElementAttributes eSecs, bool bSystem)
LanguageType GetLanguageForKey(sal_Int32 nKey) const
std::unique_ptr< SvXMLNumImpData > m_pData
SvXMLStyleContext * CreateChildContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, SvXMLStylesContext &rStyles)
SvXMLNumFmtHelper(const css::uno::Reference< css::util::XNumberFormatsSupplier > &rSupp, const css::uno::Reference< css::uno::XComponentContext > &rxContext)
SvXMLDateElementAttributes m_eDateSecs
ImplicitCalendar m_eImplicitCalendar
OUString m_aImplicitCalendar[2]
SvXMLStylesContext * m_pStyles
const LocaleDataWrapper & GetLocaleData() const
void AddColor(Color nColor)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
SvXMLNumImpData * m_pData
std::vector< MyCondition > m_aMyConditions
OUStringBuffer m_aConditions
void AddNfKeyword(sal_uInt16 nIndex)
SvXMLNumFormatContext(SvXMLImport &rImport, sal_Int32 nElement, SvXMLNumImpData *pNewData, SvXMLStylesTokens nNewType, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, SvXMLStylesContext &rStyles)
SvXMLDateElementAttributes m_eDateDOW
SvXMLDateElementAttributes m_eDateDay
SvXMLStylesTokens m_nType
SvXMLDateElementAttributes m_eDateMonth
OUStringBuffer m_aFormatCode
SvXMLDateElementAttributes m_eDateHours
SvXMLDateElementAttributes m_eDateYear
void AddCondition(const sal_Int32 nIndex)
bool m_bHasTrailingEmptyText
SAL_DLLPRIVATE sal_Int32 PrivateGetKey()
virtual void CreateAndInsert(bool bOverwrite) override
SvXMLDateElementAttributes m_eDateMins
bool IsSystemLanguage() const
determine whether number format uses the system language
LanguageType m_nFormatLang
void AddToCode(std::u16string_view rString)
SvXMLStylesTokens GetType() const
bool ReplaceNfKeyword(sal_uInt16 nOld, sal_uInt16 nNew)
void AddCurrency(const OUString &rContent, LanguageType nLang)
void AddNumber(const SvXMLNumberInfo &rInfo)
void UpdateCalendar(const OUString &rNewCalendar)
virtual ~SvXMLNumFormatContext() override
uno::Reference< uno::XComponentContext > m_xContext
std::vector< SvXMLNumFmtEntry > m_NameEntries
void AddKey(sal_uInt32 nKey, const OUString &rName, bool bRemoveAfterUse)
SvNumberFormatter * pFormatter
std::unique_ptr< LocaleDataWrapper > pLocaleData
const LocaleDataWrapper & GetLocaleData(LanguageType nLang)
sal_uInt32 GetKeyForName(std::u16string_view rName)
SvXMLNumImpData(SvNumberFormatter *pFmt, const uno::Reference< uno::XComponentContext > &rxContext)
void RemoveVolatileFormats()
void SetUsed(sal_uInt32 nKey)
SvNumberFormatter * GetNumberFormatter() const
const OUString & GetName() const
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
constexpr ::Color COL_LIGHTRED(0xFF, 0x00, 0x00)
constexpr ::Color COL_GRAY(0x80, 0x80, 0x80)
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTCYAN(0x00, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTMAGENTA(0xFF, 0x00, 0xFF)
constexpr ::Color COL_BROWN(0x80, 0x80, 0x00)
constexpr ::Color COL_YELLOW(0xFF, 0xFF, 0x00)
constexpr ::Color COL_LIGHTBLUE(0x00, 0x00, 0xFF)
constexpr ::Color COL_LIGHTGREEN(0x00, 0xFF, 0x00)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
OUString toString(OptionInfo const *info)
Handling of tokens in XML:
@ XML_DECIMAL_REPLACEMENT
@ XML_INTEGER_FRACTION_DELIMITER
@ XML_FORCED_EXPONENT_SIGN
@ XML_ZEROS_NUMERATOR_DIGITS
@ XML_MAX_NUMERATOR_DIGITS
@ XML_TRUNCATE_ON_OVERFLOW
@ XML_MAX_DENOMINATOR_VALUE
@ XML_TRANSLITERATION_STYLE
@ XML_ZEROS_DENOMINATOR_DIGITS
@ XML_TRANSLITERATION_FORMAT
@ XML_MAX_BLANK_INTEGER_DIGITS
@ XML_TRANSLITERATION_COUNTRY
@ XML_MIN_NUMERATOR_DIGITS
@ XML_TRANSLITERATION_SPELLOUT
@ XML_MIN_EXPONENT_DIGITS
@ XML_MIN_DENOMINATOR_DIGITS
@ XML_TRANSLITERATION_LANGUAGE
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Helper to gather the single language tag relevant attributes during reading ODF and form a resulting ...
LanguageTag getLanguageTag() const
Best call this only once per instance, it recreates a LanguageTag instance on every call.
sal_Int32 nMinNumerDigits
sal_Int32 nMinDecimalDigits
sal_Int32 nZerosNumerDigits
sal_Int32 nExpDigits
Number of '?' in integer part.
OUString aIntegerFractionDelimiter
sal_Int32 nZerosDenomDigits
sal_Int32 nBlankInteger
Total min number of digits in integer part ('0' + '?')
sal_Int32 nMaxNumerDigits
sal_Int32 nFracDenominator
std::map< sal_Int32, OUString > m_EmbeddedElements
sal_Int32 nMinDenomDigits
sal_Int32 nMaxDenomDigits
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
#define XMLOFF_WARN_UNKNOWN(area, rIter)
#define XML_ELEMENT(prefix, name)
const SvXMLDefaultDateFormat aDefaultDateFormats[]
#define XML_NUMF_COLORCOUNT
const SvXMLEnumMapEntry< bool > aStyleValueMap[]
const SvXMLEnumMapEntry< bool > aFormatSourceMap[]
static bool lcl_ValidChar(sal_Unicode cChar, const SvXMLNumFormatContext &rParent)
static bool lcl_IsAtEnd(OUStringBuffer &rBuffer, std::u16string_view rToken)
const Color aNumFmtStdColors[XML_NUMF_COLORCOUNT]
static void lcl_EnquoteIfNecessary(OUStringBuffer &rContent, const SvXMLNumFormatContext &rParent)
SvXMLDateElementAttributes
constexpr size_t NF_MAX_FORMAT_SYMBOLS
NF_DATETIME_SYS_DDMMYYYY_HHMMSS
NF_INDEX_TABLE_RESERVED_START
NF_DATE_SYS_NNNNDMMMMYYYY
NF_DATETIME_SYS_DDMMYYYY_HHMM
NF_DATETIME_SYSTEM_SHORT_HHMM
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND