26 #include <osl/diagnose.h>
27 #include <rtl/math.hxx>
28 #include <rtl/ustrbuf.hxx>
46 #include <string_view>
54 struct SvXMLNumFmtEntry
60 SvXMLNumFmtEntry(
const OUString& rN, sal_uInt32 nK,
bool bR ) :
61 aName(rN), nKey(nK), bRemoveAfterUse(bR) {}
77 const uno::Reference<uno::XComponentContext>& rxContext );
82 void AddKey( sal_uInt32 nKey,
const OUString& rName,
bool bRemoveAfterUse );
83 void SetUsed( sal_uInt32 nKey );
118 OUStringBuffer aContent;
126 SvXMLNumFmtElementContext(
SvXMLImport& rImport, sal_Int32 nElement,
128 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
131 sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList )
override;
132 virtual void SAL_CALL
characters(
const OUString& rChars )
override;
133 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
135 void AddEmbeddedElement( sal_Int32 nFormatPos,
const OUString& rContent );
140 SvXMLNumFmtElementContext& rParent;
141 OUStringBuffer aContent;
142 sal_Int32 nTextPosition;
145 SvXMLNumFmtEmbeddedTextContext(
SvXMLImport& rImport, sal_Int32 nElement,
146 SvXMLNumFmtElementContext& rParentContext,
147 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
149 virtual void SAL_CALL
characters(
const OUString& rChars )
override;
150 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
160 SvXMLNumFmtMapContext(
SvXMLImport& rImport, sal_Int32 nElement,
162 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
164 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
174 SvXMLNumFmtPropContext(
SvXMLImport& rImport, sal_Int32 nElement,
176 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
178 virtual void SAL_CALL
endFastElement(sal_Int32 nElement)
override;
209 #define XML_NUMF_COLORCOUNT 10
247 struct SvXMLDefaultDateFormat
289 const uno::Reference<uno::XComponentContext>& rxContext )
293 SAL_WARN_IF( !rxContext.is(),
"xmloff",
"got no service manager" );
300 if (rObj.aName == rName)
308 if ( bRemoveAfterUse )
315 if (rObj.nKey == nKey && !rObj.bRemoveAfterUse)
317 bRemoveAfterUse =
false;
335 if (rObj.nKey == nKey)
337 rObj.bRemoveAfterUse =
false;
357 if (rObj.bRemoveAfterUse )
360 if (pFormat && (pFormat->
GetType() & SvNumFormatType::DEFINED))
381 SvXMLNumFmtMapContext::SvXMLNumFmtMapContext(
SvXMLImport& rImport,
384 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
386 rParent( rParentContext )
390 OUString sValue = aIter.toString();
391 switch(aIter.getToken())
405 void SvXMLNumFmtMapContext::endFastElement(sal_Int32 )
407 rParent.AddCondition( sCondition, sName );
414 SvXMLNumFmtPropContext::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.
toString() );
437 void SvXMLNumFmtPropContext::endFastElement(sal_Int32 )
440 rParent.AddColor( m_nColor );
447 SvXMLNumFmtEmbeddedTextContext::SvXMLNumFmtEmbeddedTextContext(
SvXMLImport& rImport,
449 SvXMLNumFmtElementContext& rParentContext,
450 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
452 rParent( rParentContext ),
462 nTextPosition = nAttrVal;
469 void SvXMLNumFmtEmbeddedTextContext::characters(
const OUString& rChars )
471 aContent.append( rChars );
474 void SvXMLNumFmtEmbeddedTextContext::endFastElement(sal_Int32 )
476 rParent.AddEmbeddedElement( nTextPosition, aContent.makeStringAndClear() );
490 (cChar ==
' ' && cTS == cNBSP)) )
504 if ( ( cChar ==
' ' ||
523 ( cChar ==
'(' || cChar ==
')' ) )
532 sal_Int32
nLength = rContent.getLength();
534 if ((nLength == 1 &&
lcl_ValidChar( rContent[0], rParent)) ||
536 ((rContent[0] ==
' ' && rContent[1] ==
'-') ||
537 (rContent[1] ==
' ' &&
lcl_ValidChar( rContent[0], rParent)))))
551 OUString aString( rContent.toString() );
552 sal_Int32
nPos = aString.indexOf(
'%' );
555 if ( nPos + 1 < nLength )
557 if ( nPos + 2 == nLength &&
lcl_ValidChar( rContent[nPos + 1], rParent ) )
564 rContent.insert( nPos + 1,
'"' );
565 rContent.append(
'"' );
577 rContent.insert( nPos,
'"' );
578 rContent.insert( 0,
'"' );
590 bool bEscape = ( rContent.indexOf(
'"' ) >= 0 );
595 OUString aInsert(
"\"\\\"" );
598 while ( nPos < rContent.getLength() )
600 if ( rContent[nPos] ==
'"' )
602 rContent.insert( nPos, aInsert );
603 nPos += aInsert.getLength();
610 rContent.insert( 0,
'"' );
611 rContent.append(
'"' );
617 if ( rContent.getLength() > 2 &&
618 rContent[0] ==
'"' &&
621 rContent.remove(0, 2);
624 sal_Int32 nLen = rContent.getLength();
626 rContent[nLen - 1] ==
'"' &&
627 rContent[nLen - 2] ==
'"' )
629 rContent.truncate(nLen - 2);
637 SvXMLNumFmtElementContext::SvXMLNumFmtElementContext(
SvXMLImport& rImport,
640 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
642 rParent( rParentContext ),
650 bool bAttrBool(
false);
651 bool bVarDecimals =
false;
652 bool bIsMaxDenominator =
false;
657 switch (aIter.getToken())
669 aNumInfo.nMinDecimalDigits = nAttrVal;
673 aNumInfo.nInteger = nAttrVal;
676 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
677 aNumInfo.bGrouping = bAttrBool;
680 if (::
sax::Converter::convertDouble( fAttrDouble, aIter.toView() ))
681 aNumInfo.fDisplayFactor = fAttrDouble;
684 if ( aIter.toView() ==
" " )
686 aNumInfo.bDecAlign =
true;
690 if ( aIter.isEmpty() )
693 aNumInfo.bDecReplace =
true;
702 aNumInfo.nExpInterval = nAttrVal;
706 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
707 aNumInfo.bExpSign = bAttrBool;
711 aNumInfo.nMinNumerDigits = nAttrVal;
715 aNumInfo.nMinDenomDigits = nAttrVal;
719 aNumInfo.nMaxNumerDigits = nAttrVal;
724 aNumInfo.nFracDenominator = nAttrVal;
725 bIsMaxDenominator =
false;
730 if (::
sax::Converter::
convertNumber( nAttrVal, aIter.toView(), 1 ) && aNumInfo.nFracDenominator <= 0)
732 aNumInfo.nFracDenominator = nAttrVal;
733 bIsMaxDenominator =
true;
739 aNumInfo.nZerosNumerDigits = nAttrVal;
744 aNumInfo.nZerosDenomDigits = nAttrVal;
748 aNumInfo.aIntegerFractionDelimiter = aIter.
toString();
751 aLanguageTagODF.maRfcLanguageTag = aIter.
toString();
754 aLanguageTagODF.maLanguage = aIter.
toString();
757 aLanguageTagODF.maScript = aIter.
toString();
760 aLanguageTagODF.maCountry = aIter.
toString();
766 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
767 bTextual = bAttrBool;
776 if ( aNumInfo.nMinDecimalDigits == -1)
778 if ( bVarDecimals || aNumInfo.bDecReplace )
779 aNumInfo.nMinDecimalDigits = 0;
781 aNumInfo.nMinDecimalDigits = aNumInfo.nDecimals;
783 if ( aNumInfo.nZerosDenomDigits > 0 )
785 if ( aNumInfo.nMinDenomDigits < aNumInfo.nZerosDenomDigits )
786 aNumInfo.nMinDenomDigits = aNumInfo.nZerosDenomDigits;
789 aNumInfo.nZerosDenomDigits = 0;
790 if ( aNumInfo.nMinDenomDigits >= 0 )
791 if ( aNumInfo.nMaxDenomDigits < aNumInfo.nMinDenomDigits )
792 aNumInfo.nMaxDenomDigits = ( aNumInfo.nMinDenomDigits ? aNumInfo.nMinDenomDigits : 1 );
793 if ( aNumInfo.nZerosNumerDigits > 0 )
795 if ( aNumInfo.nMinNumerDigits < aNumInfo.nZerosNumerDigits )
796 aNumInfo.nMinNumerDigits = aNumInfo.nZerosNumerDigits;
799 aNumInfo.nZerosNumerDigits = 0;
800 if ( aNumInfo.nMinNumerDigits >= 0 )
801 if ( aNumInfo.nMaxNumerDigits < aNumInfo.nMinNumerDigits )
802 aNumInfo.nMaxNumerDigits = ( aNumInfo.nMinNumerDigits ? aNumInfo.nMinNumerDigits : 1 );
803 if ( bIsMaxDenominator && aNumInfo.nFracDenominator > 0 )
805 aNumInfo.nMaxDenomDigits = floor( log10( aNumInfo.nFracDenominator ) ) + 1;
806 aNumInfo.nFracDenominator = -1;
808 if ( aNumInfo.nMaxDenomDigits > 0 )
810 if ( aNumInfo.nMinDenomDigits < 0 )
811 aNumInfo.nMinDenomDigits = 0;
812 else if ( aNumInfo.nMinDenomDigits > aNumInfo.nMaxDenomDigits )
813 aNumInfo.nMinDenomDigits = aNumInfo.nMaxDenomDigits;
816 if ( !aLanguageTagODF.
isEmpty() )
819 if ( nElementLang == LANGUAGE_DONTKNOW )
823 if ( aNumInfo.aIntegerFractionDelimiter.isEmpty() )
824 aNumInfo.aIntegerFractionDelimiter =
" ";
827 css::uno::Reference< css::xml::sax::XFastContextHandler > SvXMLNumFmtElementContext::createFastChildContext(
829 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
833 if ( nType == SvXMLStyleTokens::Number &&
836 return new SvXMLNumFmtEmbeddedTextContext( GetImport(), nElement, *
this, xAttrList );
843 void SvXMLNumFmtElementContext::characters(
const OUString& rChars )
845 aContent.append( rChars );
848 void SvXMLNumFmtElementContext::AddEmbeddedElement( sal_Int32 nFormatPos,
const OUString& rContent )
850 if (rContent.isEmpty())
853 auto iterPair = aNumInfo.m_EmbeddedElements.emplace(nFormatPos, rContent);
854 if (!iterPair.second)
856 iterPair.first->second += rContent;
859 void SvXMLNumFmtElementContext::endFastElement(sal_Int32 )
861 bool bEffLong = bLong;
864 case SvXMLStyleTokens::Text:
865 if ( rParent.HasLongDoW() &&
866 aContent.toString() == rParent.GetLocaleData().getLongDateDayOfWeekSep() )
871 if ( rParent.ReplaceNfKeyword( NF_KEY_NNN, NF_KEY_NNNN ) )
876 rParent.SetHasLongDoW(
false );
878 if ( !aContent.isEmpty() )
881 rParent.AddToCode( aContent.makeStringAndClear() );
885 case SvXMLStyleTokens::Number:
886 rParent.AddNumber( aNumInfo );
889 case SvXMLStyleTokens::CurrencySymbol:
890 rParent.AddCurrency( aContent.makeStringAndClear(), nElementLang );
893 case SvXMLStyleTokens::TextContent:
894 rParent.AddToCode(
'@');
896 case SvXMLStyleTokens::FillCharacter:
897 if ( !aContent.isEmpty() )
899 rParent.AddToCode(
'*' );
900 rParent.AddToCode( aContent[0] );
903 case SvXMLStyleTokens::Boolean:
907 case SvXMLStyleTokens::Day:
908 rParent.UpdateCalendar( sCalendar );
911 rParent.AddNfKeyword(
912 sal::static_int_cast< sal_uInt16 >(
913 bEffLong ? NF_KEY_DD : NF_KEY_D ) );
915 case SvXMLStyleTokens::Month:
916 rParent.UpdateCalendar( sCalendar );
919 rParent.AddNfKeyword(
920 sal::static_int_cast< sal_uInt16 >(
922 ? ( bEffLong ? NF_KEY_MMMM : NF_KEY_MMM )
923 : ( bEffLong ? NF_KEY_MM : NF_KEY_M ) ) );
925 case SvXMLStyleTokens::Year:
932 rParent.UpdateCalendar( sCalendar);
934 if (eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY
935 || eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY_FROM_OTHER)
937 rParent.AddNfKeyword(
938 sal::static_int_cast< sal_uInt16 >(
939 bEffLong ? NF_KEY_EEC : NF_KEY_EC ) );
943 rParent.AddNfKeyword(
944 sal::static_int_cast< sal_uInt16 >(
945 bEffLong ? NF_KEY_YYYY : NF_KEY_YY ) );
949 case SvXMLStyleTokens::Era:
950 rParent.UpdateCalendar( sCalendar );
952 rParent.AddNfKeyword(
953 sal::static_int_cast< sal_uInt16 >(
954 bEffLong ? NF_KEY_GGG : NF_KEY_G ) );
957 case SvXMLStyleTokens::DayOfWeek:
962 rParent.UpdateCalendar( sCalendar);
964 if (eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY
965 || eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY_FROM_OTHER)
967 rParent.AddNfKeyword(
968 sal::static_int_cast< sal_uInt16 >(
969 bEffLong ? NF_KEY_AAAA : NF_KEY_AAA ) );
973 rParent.AddNfKeyword(
974 sal::static_int_cast< sal_uInt16 >(
975 bEffLong ? NF_KEY_NNNN : NF_KEY_NN ) );
979 case SvXMLStyleTokens::WeekOfYear:
980 rParent.UpdateCalendar( sCalendar );
981 rParent.AddNfKeyword( NF_KEY_WW );
983 case SvXMLStyleTokens::Quarter:
984 rParent.UpdateCalendar( sCalendar );
985 rParent.AddNfKeyword(
986 sal::static_int_cast< sal_uInt16 >(
987 bEffLong ? NF_KEY_QQ : NF_KEY_Q ) );
989 case SvXMLStyleTokens::Hours:
990 rParent.AddNfKeyword(
991 sal::static_int_cast< sal_uInt16 >(
992 bEffLong ? NF_KEY_HH : NF_KEY_H ) );
994 case SvXMLStyleTokens::AmPm:
996 rParent.AddNfKeyword( NF_KEY_AMPM );
998 case SvXMLStyleTokens::Minutes:
999 rParent.AddNfKeyword(
1000 sal::static_int_cast< sal_uInt16 >(
1001 bEffLong ? NF_KEY_MMI : NF_KEY_MI ) );
1003 case SvXMLStyleTokens::Seconds:
1004 rParent.AddNfKeyword(
1005 sal::static_int_cast< sal_uInt16 >(
1006 bEffLong ? NF_KEY_SS : NF_KEY_S ) );
1007 if ( aNumInfo.nDecimals > 0 )
1010 rParent.AddToCode(rParent.GetLocaleData().getNumDecimalSep());
1011 for (sal_Int32 i=0;
i<aNumInfo.nDecimals;
i++)
1013 rParent.AddToCode(
'0');
1018 case SvXMLStyleTokens::Fraction:
1020 if ( aNumInfo.nInteger >= 0 )
1023 aNumInfo.nDecimals = 0;
1024 rParent.AddNumber( aNumInfo );
1025 OUStringBuffer sIntegerFractionDelimiter = aNumInfo.aIntegerFractionDelimiter;
1027 rParent.AddToCode( sIntegerFractionDelimiter.makeStringAndClear() );
1033 for (i=aNumInfo.nMaxNumerDigits; i > 0; i--)
1035 if ( i > aNumInfo.nMinNumerDigits )
1036 rParent.AddToCode(
'#' );
1037 else if ( i > aNumInfo.nZerosNumerDigits )
1038 rParent.AddToCode(
'?' );
1040 rParent.AddToCode(
'0' );
1042 rParent.AddToCode(
'/' );
1043 if ( aNumInfo.nFracDenominator > 0 )
1045 rParent.AddToCode( OUString::number( aNumInfo.nFracDenominator ) );
1049 for (i=aNumInfo.nMaxDenomDigits; i > 0 ; i--)
1051 if ( i > aNumInfo.nMinDenomDigits )
1052 rParent.AddToCode(
'#' );
1053 else if ( i > aNumInfo.nZerosDenomDigits )
1054 rParent.AddToCode(
'?' );
1056 rParent.AddToCode(
'0' );
1062 case SvXMLStyleTokens::ScientificNumber:
1065 if( !aNumInfo.bGrouping && aNumInfo.nExpInterval > aNumInfo.nInteger )
1067 for (sal_Int32 i=aNumInfo.nInteger; i<aNumInfo.nExpInterval; i++)
1069 rParent.AddToCode(
'#' );
1072 rParent.AddNumber( aNumInfo );
1074 if ( aNumInfo.bExpSign )
1075 rParent.AddToCode( u
"E+" );
1077 rParent.AddToCode( u
"E" );
1078 for (sal_Int32 i=0; i<aNumInfo.nExpDigits; i++)
1080 rParent.AddToCode(
'0' );
1086 assert(
false &&
"invalid element ID");
1096 for (
const auto & rEntry : aDefaultDateFormats)
1098 if ( bSystem == rEntry.bSystem &&
1107 return sal::static_int_cast< sal_uInt16 >(rEntry.eFormat);
1120 const uno::Reference<xml::sax::XFastAttributeList>& xAttrList,
1124 pStyles( &rStyles ),
1128 eImplicitCalendar(ImplicitCalendar::
DEFAULT),
1130 bAutoOrder( false ),
1131 bFromSystem( false ),
1135 bHasExtraText( false ),
1136 bHasLongDoW( false ),
1137 bHasDateTime( false ),
1138 bRemoveAfterUse( false ),
1146 bDateNoDefault( false )
1149 css::i18n::NativeNumberXmlAttributes aNatNumAttr;
1151 bool bAttrBool(
false);
1155 switch (aIter.getToken())
1161 aLanguageTagODF.maRfcLanguageTag = aIter.
toString();
1164 aLanguageTagODF.maLanguage = aIter.
toString();
1167 aLanguageTagODF.maScript = aIter.
toString();
1170 aLanguageTagODF.maCountry = aIter.
toString();
1176 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
1177 bAutoOrder = bAttrBool;
1183 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
1184 bTruncate = bAttrBool;
1189 if (::
sax::Converter::convertBool( bAttrBool, aIter.toView() ))
1190 bRemoveAfterUse = bAttrBool;
1213 if (!aLanguageTagODF.
isEmpty())
1216 if ( nFormatLang == LANGUAGE_DONTKNOW )
1220 if (aNatNumAttr.Format.isEmpty() && aSpellout.isEmpty())
1223 LanguageTag aLanguageTag( OUString(), aNatNumAttr.Locale.Language,
1224 std::u16string_view(), aNatNumAttr.Locale.Country);
1225 aNatNumAttr.Locale = aLanguageTag.getLocale(
false);
1228 if ( !aSpellout.isEmpty() )
1230 aFormatCode.append(
"[NatNum12 " );
1231 aFormatCode.append( aSpellout );
1234 if ( !pFormatter )
return;
1236 sal_Int32
nNatNum = pFormatter->
GetNatNum()->convertFromXmlAttributes( aNatNumAttr );
1237 aFormatCode.append(
"[NatNum" );
1238 aFormatCode.append( nNatNum );
1241 LanguageType eLang = aLanguageTag.getLanguageType(
false );
1242 if ( eLang == LANGUAGE_DONTKNOW )
1244 if ( eLang != nFormatLang && eLang != LANGUAGE_SYSTEM )
1246 aFormatCode.append(
"][$-" );
1248 aFormatCode.append(OUString::number(static_cast<sal_uInt16>(eLang), 16).toAsciiUpperCase());
1250 aFormatCode.append(
']' );
1254 const OUString& rName,
1255 const uno::Reference<xml::sax::XFastAttributeList>& ,
1260 pStyles( &rStyles ),
1264 eImplicitCalendar(ImplicitCalendar::
DEFAULT),
1265 nFormatLang( nLang ),
1266 bAutoOrder( false ),
1267 bFromSystem( false ),
1271 bHasExtraText( false ),
1272 bHasLongDoW( false ),
1273 bHasDateTime( false ),
1274 bRemoveAfterUse( false ),
1282 bDateNoDefault( false )
1293 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
1301 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1302 *
this, SvXMLStyleTokens::Text, xAttrList );
1306 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1307 *
this, SvXMLStyleTokens::FillCharacter, xAttrList );
1310 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1311 *
this, SvXMLStyleTokens::Number, xAttrList );
1314 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1315 *
this, SvXMLStyleTokens::ScientificNumber, xAttrList );
1318 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1319 *
this, SvXMLStyleTokens::Fraction, xAttrList );
1322 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1323 *
this, SvXMLStyleTokens::CurrencySymbol, xAttrList );
1326 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1327 *
this, SvXMLStyleTokens::Day, xAttrList );
1330 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1331 *
this, SvXMLStyleTokens::Month, xAttrList );
1334 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1335 *
this, SvXMLStyleTokens::Year, xAttrList );
1338 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1339 *
this, SvXMLStyleTokens::Era, xAttrList );
1342 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1343 *
this, SvXMLStyleTokens::DayOfWeek, xAttrList );
1346 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1347 *
this, SvXMLStyleTokens::WeekOfYear, xAttrList );
1350 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1351 *
this, SvXMLStyleTokens::Quarter, xAttrList );
1354 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1355 *
this, SvXMLStyleTokens::Hours, xAttrList );
1358 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1359 *
this, SvXMLStyleTokens::AmPm, xAttrList );
1362 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1363 *
this, SvXMLStyleTokens::Minutes, xAttrList );
1366 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1367 *
this, SvXMLStyleTokens::Seconds, xAttrList );
1370 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1371 *
this, SvXMLStyleTokens::Boolean, xAttrList );
1374 pContext =
new SvXMLNumFmtElementContext(
GetImport(), nElement,
1375 *
this, SvXMLStyleTokens::TextContent, xAttrList );
1379 pContext =
new SvXMLNumFmtPropContext(
GetImport(), nElement,
1386 pContext =
new SvXMLNumFmtMapContext(
GetImport(), nElement,
1446 comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>( xFormatsSupplier );
1469 OSL_FAIL(
"no number formatter");
1481 SAL_INFO(
"xmloff.style",
"invalid style:map references containing style");
1499 OUString sFormat =
aFormatCode.makeStringAndClear();
1547 OUString aFormatStr( sFormat );
1551 sal_Int32 nErrPos = 0;
1554 if ( !bOk && nErrPos == 0 && aFormatStr != sFormat )
1603 OSL_FAIL(
"invalid number format");
1648 sal_uInt16 nPrec = 0;
1649 sal_uInt16 nLeading = 0;
1651 nPrec =
static_cast<sal_uInt16
>(rInfo.
nDecimals);
1653 nLeading =
static_cast<sal_uInt16
>(rInfo.
nInteger);
1679 sal_uInt16 nGenPrec = nPrec;
1687 if ( nEmbeddedCount )
1692 bGrouping,
false, nGenPrec, nLeading );
1694 if ( rInfo.
nExpDigits >= 0 && nLeading == 0 && !bGrouping && nEmbeddedCount == 0 )
1699 aNumStr.stripStart(
'#');
1705 sal_Int32 nDigits = rInfo.
nInteger;
1707 if ( nIntegerEnd < 0 )
1708 nIntegerEnd = aNumStr.getLength();
1709 while ( nIndex >= 0 && nIndex < nIntegerEnd )
1711 if ( ( nIndex = aNumStr.indexOf(
'#', nIndex ) ) >= 0 )
1722 aNumStr.insert( 0,
'#' );
1726 if ( nEmbeddedCount )
1735 nZeroPos = aNumStr.getLength();
1740 if ( nLastFormatPos >= nZeroPos )
1745 sal_Int32 nAddCount = nLastFormatPos + 1 - nZeroPos;
1748 aNumStr.insert(0,
'#');
1750 nZeroPos = nZeroPos + nAddCount;
1756 sal_Int32
const nFormatPos = it.first;
1757 sal_Int32 nInsertPos = nZeroPos - nFormatPos;
1758 if ( nFormatPos >= 0 && nInsertPos >= 0 )
1763 aNumStr.insert(nInsertPos,
'"');
1764 aNumStr.insert(nInsertPos, it.second);
1765 aNumStr.insert(nInsertPos,
'"');
1770 aFormatCode.append( aNumStr.makeStringAndClear() );
1791 sal_Int32 nSepCount =
static_cast<sal_Int32
>(::rtl::math::round( log10(rInfo.
fDisplayFactor) / 3.0 ));
1792 if ( nSepCount > 0 )
1795 for ( sal_Int32 i=0; i<nSepCount; i++ )
1802 bool bAutomatic =
false;
1803 OUString aSymbol = rContent;
1804 if ( aSymbol.isEmpty())
1810 OUString sCurString, sDummy;
1812 aSymbol = sCurString;
1829 if ( nLength > 1 &&
aFormatCode[nLength - 1] ==
'"' )
1835 sal_Int32 nFirst = nLength - 2;
1836 while ( nFirst >= 0 &&
aFormatCode[nFirst] !=
'"' )
1844 if ( nLength > nFirst + 2 )
1845 aFormatCode.append( aOld.subView( nFirst + 1, nLength - nFirst - 2 ) );
1860 aFormatCode.append(
"-").append(OUString(OUString::number(sal_uInt16(nLang), 16)).toAsciiUpperCase());
1881 if ( nIndex == NF_KEY_H || nIndex ==
NF_KEY_HH ||
1882 nIndex == NF_KEY_MI || nIndex ==
NF_KEY_MMI ||
1883 nIndex == NF_KEY_S || nIndex ==
NF_KEY_SS )
1888 aFormatCode.append(
"[").append(sKeyword).append(
"]");
1927 static bool lcl_IsAtEnd( OUStringBuffer& rBuffer,
const OUString& rToken )
1929 sal_Int32 nBufLen = rBuffer.getLength();
1930 sal_Int32 nTokLen = rToken.getLength();
1932 if ( nTokLen > nBufLen )
1935 sal_Int32 nStartPos = nBufLen - nTokLen;
1936 for ( sal_Int32 nTokPos = 0; nTokPos < nTokLen; nTokPos++ )
1937 if ( rToken[ nTokPos ] != rBuffer[nStartPos + nTokPos] )
1975 rCondition.startsWith(
"value()", &sRealCond)) )
1981 bool bDefaultCond =
false;
1986 bDefaultCond =
true;
1992 bDefaultCond =
true;
1998 sal_Int32
nPos = sRealCond.indexOf(
"!=" );
2001 sRealCond = sRealCond.replaceAt( nPos, 2,
"<>" );
2004 nPos = sRealCond.indexOf(
'.' );
2009 if ( rDecSep.getLength() > 1 || rDecSep[0] !=
'.' )
2011 sRealCond = sRealCond.replaceAt( nPos, 1, rDecSep );
2014 aConditions.append(
"[").append(sRealCond).append(
"]");
2038 OUStringBuffer aColName;
2040 if (nColor == aNumFmtStdColors[i])
2046 if ( !aColName.isEmpty() )
2048 aColName.insert( 0,
'[' );
2049 aColName.append(
']' );
2050 aFormatCode.insert( 0, aColName.makeStringAndClear() );
2061 ImplicitCalendar::DEFAULT_FROM_OTHER : ImplicitCalendar::DEFAULT);
2066 ImplicitCalendar::DEFAULT_FROM_OTHER : ImplicitCalendar::DEFAULT);
2072 ImplicitCalendar::SECONDARY_FROM_OTHER : ImplicitCalendar::SECONDARY);
2077 ImplicitCalendar::SECONDARY_FROM_OTHER : ImplicitCalendar::SECONDARY);
2089 bool bSameDefault =
false;
2090 if (
sCalendar.isEmpty() || rNewCalendar.isEmpty())
2097 bSameDefault = (rNewCalendar == rDefaultCalendar ||
sCalendar == rDefaultCalendar);
2102 if (rNewCalendar.isEmpty())
2130 const uno::Reference<util::XNumberFormatsSupplier>& rSupp,
2131 const uno::Reference<uno::XComponentContext>& rxContext )
2133 SAL_WARN_IF( !rxContext.is(),
"xmloff",
"got no service manager" );
2137 comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>( rSupp );
2141 pData = std::make_unique<SvXMLNumImpData>( pFormatter, rxContext );
2146 const uno::Reference<uno::XComponentContext>& rxContext )
2148 SAL_WARN_IF( !rxContext.is(),
"xmloff",
"got no service manager" );
2150 pData = std::make_unique<SvXMLNumImpData>( pNumberFormatter, rxContext );
2156 pData->RemoveVolatileFormats();
2162 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList,
2194 pData.get(), nStyleToken, xAttrList, rStyles );
2199 if (
pData->GetNumberFormatter())
const Color aNumFmtStdColors[XML_NUMF_COLORCOUNT]
void AddNumber(const SvXMLNumberInfo &rInfo)
NF_INDEX_TABLE_RESERVED_START
sal_Int32 nMinDecimalDigits
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTMAGENTA
std::unique_ptr< ContentProperties > pData
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
sal_uInt16 getCurrDigits() const
LanguageType getLanguageType(bool bResolveSystem=true) const
NF_DATETIME_SYS_DDMMYYYY_HHMMSS
ImplicitCalendar eImplicitCalendar
SvXMLDateElementAttributes eDateSecs
constexpr size_t NF_MAX_FORMAT_SYMBOLS
virtual ~SvXMLNumFormatContext() override
sal_Int32 nZerosDenomDigits
SvXMLNumFormatContext(SvXMLImport &rImport, sal_Int32 nElement, SvXMLNumImpData *pNewData, SvXMLStylesTokens nNewType, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, SvXMLStylesContext &rStyles)
SvXMLImport & GetImport()
SvXMLDateElementAttributes eDateDay
const std::shared_ptr< css::i18n::Calendar2 > & getDefaultCalendar() const
OUString aIntegerFractionDelimiter
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
LanguageTag getLanguageTag() const
Best call this only once per instance, it recreates a LanguageTag instance on every call...
SvNumberFormatter * pFormatter
SvXMLStyleContext * CreateChildContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, SvXMLStylesContext &rStyles)
sal_Int32 nMinNumerDigits
const LocaleDataWrapper & GetLocaleData(LanguageType nLang)
sal_uInt32 GetKeyForName(std::u16string_view rName)
sal_Int32 nMaxNumerDigits
sal_Int32 nZerosNumerDigits
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
void RemoveVolatileFormats()
#define XMLOFF_WARN_UNKNOWN(area, rIter)
std::vector< MyCondition > aMyConditions
static OUString getPrefixAndNameFromToken(sal_Int32 nToken)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTRED
SvXMLStylesContext * pStyles
LanguageType GetLanguageForKey(sal_Int32 nKey)
const OUString & getNumDecimalSep() const
void SetUsed(sal_uInt32 nKey)
SvXMLDateElementAttributes eDateMonth
#define XML_NUMF_COLORCOUNT
void AddCurrency(const OUString &rContent, LanguageType nLang)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
SvXMLDateElementAttributes
std::map< sal_Int32, OUString > m_EmbeddedElements
bool doesSecondaryCalendarUseEC(std::u16string_view rName) const
sal_Int32 nMaxDenomDigits
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_GRAY
SvXMLDateElementAttributes eDateDOW
NF_DATETIME_SYS_DDMMYYYY_HHMM
bool ReplaceNfKeyword(sal_uInt16 nOld, sal_uInt16 nNew)
sal_Int32 nMinDenomDigits
OUStringBuffer aConditions
SvXMLImportContext(SvXMLImport &rImport)
A contexts constructor does anything that is required if an element starts.
OUStringBuffer aFormatCode
std::vector< SvXMLNumFmtEntry > m_NameEntries
const uno::Reference< uno::XComponentContext > m_xContext
SvXMLDateElementAttributes eDateHours
void AddColor(Color nColor)
SvXMLNumFmtHelper(const css::uno::Reference< css::util::XNumberFormatsSupplier > &rSupp, const css::uno::Reference< css::uno::XComponentContext > &rxContext)
const SvXMLDefaultDateFormat aDefaultDateFormats[]
This class deliberately does not support XWeak, to improve performance when loading large documents...
const SvXMLEnumMapEntry< bool > aStyleValueMap[]
Map an XMLTokenEnum to an enum value.
void UpdateCalendar(const OUString &rNewCalendar)
void AddCondition(const sal_Int32 nIndex)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTCYAN
const SvXMLEnumMapEntry< bool > aFormatSourceMap[]
#define SAL_WARN_IF(condition, area, stream)
const OUString & GetName() const
SvXMLNumImpData(SvNumberFormatter *pFmt, const uno::Reference< uno::XComponentContext > &rxContext)
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 ...
NF_DATE_SYS_NNNNDMMMMYYYY
std::unique_ptr< SvXMLNumImpData > pData
Handling of tokens in XML:
void AddKey(sal_uInt32 nKey, const OUString &rName, bool bRemoveAfterUse)
void AddNumberStyle(sal_Int32 nKey, const OUString &sName)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
#define SAL_INFO(area, stream)
std::unique_ptr< LocaleDataWrapper > pLocaleData
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
sal_Int32 nFracDenominator
OUString aImplicitCalendar[2]
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BROWN
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTGREEN
static sal_uInt16 GetDefaultDateFormat(SvXMLDateElementAttributes eDOW, SvXMLDateElementAttributes eDay, SvXMLDateElementAttributes eMonth, SvXMLDateElementAttributes eYear, SvXMLDateElementAttributes eHours, SvXMLDateElementAttributes eMins, SvXMLDateElementAttributes eSecs, bool bSystem)
#define XML_ELEMENT(prefix, name)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_YELLOW
SvXMLStylesTokens GetType() const
static void lcl_EnquoteIfNecessary(OUStringBuffer &rContent, const SvXMLNumFormatContext &rParent)
SAL_DLLPRIVATE sal_Int32 PrivateGetKey()
void AddToCode(std::u16string_view rString)
const OUString & getNumThousandSep() const
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
SvXMLDateElementAttributes eDateMins
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTBLUE
static bool lcl_ValidChar(sal_Unicode cChar, const SvXMLNumFormatContext &rParent)
NF_DATETIME_SYSTEM_SHORT_HHMM
#define SAL_WARN(area, stream)
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
SvXMLDateElementAttributes eDateYear
SvNumberFormatter * GetNumberFormatter() const
if(!pCandidateA->getEnd().equal(pCandidateB->getStart()))
uno::Reference< uno::XComponentContext > m_xContext
virtual void CreateAndInsert(bool bOverwrite) override
const LocaleDataWrapper & GetLocaleData() const
Helper to gather the single language tag relevant attributes during reading ODF and form a resulting ...
virtual void SAL_CALL characters(const OUString &aChars) override
This method is called for all characters that are contained in the current element.
bool IsSystemLanguage() const
determine whether number format uses the system language
void AddNfKeyword(sal_uInt16 nIndex)
OUString toString(OptionInfo const *info)
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
static bool lcl_IsAtEnd(OUStringBuffer &rBuffer, const OUString &rToken)