tdf#79049 speed up OOXML workbook load (4)
Optimise LocaleDataWrapper for reads by initialising the
data we in the constructor, so we don't need any kind of
locking
Reduces load time from 34s to 28s.
Change-Id: I4bd3bddb30b70ba015fe5b1372534f9507762b74
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114960
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/chart2/source/controller/main/ConfigurationAccess.cxx b/chart2/source/controller/main/ConfigurationAccess.cxx
index 2d1dcfc..4040c8d 100644
--- a/chart2/source/controller/main/ConfigurationAccess.cxx
+++ b/chart2/source/controller/main/ConfigurationAccess.cxx
@@ -33,8 +33,7 @@ namespace
bool lcl_IsMetric()
{
SvtSysLocale aSysLocale;
const LocaleDataWrapper* pLocWrapper = aSysLocale.GetLocaleDataPtr();
MeasurementSystem eSys = pLocWrapper->getMeasurementSystemEnum();
MeasurementSystem eSys = aSysLocale.GetLocaleData().getMeasurementSystemEnum();
return ( eSys == MeasurementSystem::Metric );
}
diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 2845c22..4507cd5 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -221,12 +221,11 @@ static LanguageType GetDocLanguage( const SvxAutoCorrDoc& rDoc, sal_Int32 nPos )
static LocaleDataWrapper& GetLocaleDataWrapper( LanguageType nLang )
{
static LocaleDataWrapper aLclDtWrp( GetAppLang() );
static std::unique_ptr<LocaleDataWrapper> xLclDtWrp;
LanguageTag aLcl( nLang );
const LanguageTag& rLcl = aLclDtWrp.getLoadedLanguageTag();
if( aLcl != rLcl )
aLclDtWrp.setLanguageTag( aLcl );
return aLclDtWrp;
if (!xLclDtWrp || xLclDtWrp->getLoadedLanguageTag() != aLcl)
xLclDtWrp.reset(new LocaleDataWrapper(aLcl));
return *xLclDtWrp;
}
static TransliterationWrapper& GetIgnoreTranslWrapper()
{
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index c4e037f..3907c1a 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -2464,7 +2464,7 @@ void FormulaCompiler::AppendDouble( OUStringBuffer& rBuffer, double fVal ) const
::rtl::math::doubleToUStringBuffer( rBuffer, fVal,
rtl_math_StringFormat_Automatic,
rtl_math_DecimalPlaces_Max,
aSysLocale.GetLocaleDataPtr()->getNumDecimalSep()[0],
aSysLocale.GetLocaleData().getNumDecimalSep()[0],
true );
}
}
diff --git a/include/svl/ondemand.hxx b/include/svl/ondemand.hxx
index 5ce944a..097a34f 100644
--- a/include/svl/ondemand.hxx
+++ b/include/svl/ondemand.hxx
@@ -55,18 +55,17 @@ class OnDemandLocaleDataWrapper
SvtSysLocale aSysLocale;
LanguageType eCurrentLanguage;
LanguageType eLastAnyLanguage;
const LocaleDataWrapper* pSystem;
std::unique_ptr<const LocaleDataWrapper> pEnglish;
std::unique_ptr< LocaleDataWrapper> pAny;
const LocaleDataWrapper* pCurrent;
int nCurrent; // 0 == system, 1 == english, 2 == any
bool bInitialized;
public:
OnDemandLocaleDataWrapper()
: eLastAnyLanguage( LANGUAGE_DONTKNOW )
, nCurrent(0)
, bInitialized(false)
{
pCurrent = pSystem = aSysLocale.GetLocaleDataPtr();
eCurrentLanguage = LANGUAGE_SYSTEM;
}
@@ -86,12 +85,12 @@ public:
{
LanguageType eLang = rLanguageTag.getLanguageType( false);
if ( eLang == LANGUAGE_SYSTEM )
pCurrent = pSystem;
nCurrent = 0;
else if ( eLang == LANGUAGE_ENGLISH_US )
{
if ( !pEnglish )
pEnglish.reset( new LocaleDataWrapper( m_xContext, rLanguageTag ) );
pCurrent = pEnglish.get();
if ( !pEnglish )
pEnglish.reset( new LocaleDataWrapper( m_xContext, rLanguageTag ) );
nCurrent = 1;
}
else
{
@@ -102,10 +101,10 @@ public:
}
else if ( eLastAnyLanguage != eLang )
{
pAny->setLanguageTag( rLanguageTag );
pAny.reset( new LocaleDataWrapper( m_xContext, rLanguageTag ) );
eLastAnyLanguage = eLang;
}
pCurrent = pAny.get();
nCurrent = 2;
}
eCurrentLanguage = eLang;
}
@@ -113,9 +112,18 @@ public:
LanguageType getCurrentLanguage() const
{ return eCurrentLanguage; }
const LocaleDataWrapper* get() const { return pCurrent; }
const LocaleDataWrapper* get() const
{
switch (nCurrent)
{
case 0: return &aSysLocale.GetLocaleData();
case 1: return pEnglish.get();
case 2: return pAny.get();
default: assert(false); return nullptr;
}
}
const LocaleDataWrapper* operator->() const { return get(); }
const LocaleDataWrapper& operator*() const { return *pCurrent; }
const LocaleDataWrapper& operator*() const { return *get(); }
};
/** Load a calendar only if it's needed. Keep calendar for "en-US" locale
diff --git a/include/svx/svdetc.hxx b/include/svx/svdetc.hxx
index 14af856..a6e26bb 100644
--- a/include/svx/svdetc.hxx
+++ b/include/svx/svdetc.hxx
@@ -182,7 +182,6 @@ public:
class SVXCORE_DLLPUBLIC SdrGlobalData
{
const SvtSysLocale* pSysLocale; // follows always locale settings
const LocaleDataWrapper* pLocaleData; // follows always SysLocale
public:
std::vector<Link<SdrObjCreatorParams, SdrObject*>>
aUserMakeObjHdl;
diff --git a/include/unotools/localedatawrapper.hxx b/include/unotools/localedatawrapper.hxx
index 70c62ad..29e9815 100644
--- a/include/unotools/localedatawrapper.hxx
+++ b/include/unotools/localedatawrapper.hxx
@@ -30,7 +30,6 @@
#include <rtl/ustring.hxx>
#include <rtl/math.h>
#include <i18nlangtag/languagetag.hxx>
#include <unotools/readwritemutexguard.hxx>
#include <unotools/unotoolsdllapi.h>
#include <memory>
#include <map>
@@ -58,6 +57,10 @@ enum class MeasurementSystem {
US
};
/**
* This class can be accessed without locking because we load
* all of the data in the constructor.
*/
class UNOTOOLS_DLLPUBLIC LocaleDataWrapper
{
static sal_uInt8 nLocaleDataChecking; // 0:=dontknow, 1:=yes, 2:=no
@@ -81,54 +84,44 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper
sal_uInt16 nCurrPositiveFormat;
sal_uInt16 nCurrNegativeFormat;
sal_uInt16 nCurrDigits;
bool bLocaleDataItemValid;
bool bReservedWordValid;
bool bSecondaryCalendarValid;
mutable ::utl::ReadWriteMutex aMutex;
struct SAL_DLLPRIVATE Locale_Compare
{
bool operator()(const css::lang::Locale& rLocale1, const css::lang::Locale& rLocale2) const;
};
mutable std::map<css::lang::Locale, css::i18n::LocaleDataItem2, Locale_Compare> maDataItemCache;
// whenever Locale changes
void invalidateData();
void loadData();
void loadDateAcceptancePatterns(const std::vector<OUString> & rOverrideDateAcceptancePatterns);
void getOneLocaleItemImpl( sal_Int16 nItem );
const OUString& getOneLocaleItem( sal_Int16 nItem ) const;
void getOneReservedWordImpl( sal_Int16 nWord );
const OUString& getOneReservedWord( sal_Int16 nWord ) const;
void getCurrSymbolsImpl();
void getCurrFormatsImpl();
void loadCurrencyFormats();
void scanCurrFormatImpl( const OUString& rCode,
sal_Int32 nStart, sal_Int32& nSign,
sal_Int32& nPar, sal_Int32& nNum,
sal_Int32& nBlank, sal_Int32& nSym ) const;
void getDateOrdersImpl();
void loadDateOrders();
DateOrder scanDateOrderImpl( const OUString& rCode ) const;
void getDefaultCalendarImpl();
void getSecondaryCalendarImpl();
void ImplAddFormatNum( rtl::OUStringBuffer& rBuf,
sal_Int64 nNumber, sal_uInt16 nDecimals,
bool bUseThousandSep, bool bTrailingZeros ) const;
void getDigitGroupingImpl();
void loadDigitGrouping();
public:
LocaleDataWrapper(
const css::uno::Reference< css::uno::XComponentContext > & rxContext,
const LanguageTag& rLanguageTag
);
LocaleDataWrapper(
const LanguageTag& rLanguageTag
);
~LocaleDataWrapper();
LocaleDataWrapper(
const css::uno::Reference< css::uno::XComponentContext > & rxContext,
const LanguageTag& rLanguageTag
);
/**
@param rOverrideDateAcceptancePatterns Override locale's date acceptance patterns.
An empty sequence resets the patterns to the locale's pattern sequence.
*/
LocaleDataWrapper(
const LanguageTag& rLanguageTag,
const std::vector<OUString> & rOverrideDateAcceptancePatterns = {}
);
~LocaleDataWrapper();
/** Get the service factory, meant to be able to create a CalendarWrapper
from a LocaleDataWrapper. Note that the service factory may be
@@ -139,9 +132,6 @@ public:
css::uno::XComponentContext > & getComponentContext()
const { return m_xContext; }
/// set a new Locale to request
void setLanguageTag( const LanguageTag& rLanguageTag );
/// get current requested Locale
const LanguageTag& getLanguageTag() const;
@@ -163,10 +153,6 @@ public:
css::uno::Sequence< css::lang::Locale > getAllInstalledLocaleNames() const;
css::uno::Sequence< OUString > getDateAcceptancePatterns() const;
/** Override locale's date acceptance patterns.
An empty sequence resets the patterns to the locale's pattern sequence.
*/
void setDateAcceptancePatterns( const css::uno::Sequence< OUString > & rPatterns );
/// same as the wrapper implementation but static
static css::uno::Sequence< css::lang::Locale > getInstalledLocaleNames();
diff --git a/include/unotools/syslocale.hxx b/include/unotools/syslocale.hxx
index 31ca652..5bb2d52 100644
--- a/include/unotools/syslocale.hxx
+++ b/include/unotools/syslocale.hxx
@@ -61,7 +61,6 @@ public:
INSTANCE OF SvtSysLocale LIVES!
It is a faster access but be sure what you do!
*/
const LocaleDataWrapper* GetLocaleDataPtr() const;
const CharClass* GetCharClassPtr() const;
SvtSysLocaleOptions& GetOptions() const;
const LanguageTag& GetLanguageTag() const;
diff --git a/include/vcl/toolkit/field.hxx b/include/vcl/toolkit/field.hxx
index 714ff87..e30d16e 100644
--- a/include/vcl/toolkit/field.hxx
+++ b/include/vcl/toolkit/field.hxx
@@ -40,7 +40,7 @@ class VCL_DLLPUBLIC FormatterBase
{
private:
VclPtr<Edit> mpField;
std::unique_ptr<LocaleDataWrapper>
mutable std::unique_ptr<LocaleDataWrapper>
mpLocaleDataWrapper;
bool mbReformat;
bool mbStrictFormat;
@@ -54,6 +54,8 @@ protected:
void SetEmptyFieldValueData( bool bValue ) { mbEmptyFieldValue = bValue; }
SAL_DLLPRIVATE LocaleDataWrapper& ImplGetLocaleDataWrapper() const;
/** reset the LocaleDataWrapper when the language tag changes */
SAL_DLLPRIVATE void ImplResetLocaleDataWrapper() const;
Edit* GetField() const { return mpField; }
void ClearField() { mpField.clear(); }
diff --git a/linguistic/source/misc.cxx b/linguistic/source/misc.cxx
index 3e0bedd..59214be 100644
--- a/linguistic/source/misc.cxx
+++ b/linguistic/source/misc.cxx
@@ -74,11 +74,10 @@ osl::Mutex & GetLinguMutex()
const LocaleDataWrapper & GetLocaleDataWrapper( LanguageType nLang )
{
static LocaleDataWrapper aLclDtaWrp( SvtSysLocale().GetLanguageTag() );
if (nLang != aLclDtaWrp.getLoadedLanguageTag().getLanguageType())
aLclDtaWrp.setLanguageTag( LanguageTag( nLang ) );
return aLclDtaWrp;
static std::unique_ptr<LocaleDataWrapper> xLclDtaWrp;
if (!xLclDtaWrp || xLclDtaWrp->getLoadedLanguageTag().getLanguageType() != nLang)
xLclDtaWrp.reset(new LocaleDataWrapper(LanguageTag( nLang )));
return *xLclDtaWrp;
}
LanguageType LinguLocaleToLanguage( const css::lang::Locale& rLocale )
diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx
index e47303b..55415f1f 100644
--- a/sc/source/core/data/global.cxx
+++ b/sc/source/core/data/global.cxx
@@ -1003,7 +1003,7 @@ const LocaleDataWrapper* ScGlobal::getLocaleDataPtr()
xSysLocale,
"ScGlobal::getLocaleDataPtr() called before ScGlobal::Init()");
return xSysLocale->GetLocaleDataPtr();
return &xSysLocale->GetLocaleData();
}
const CharClass* ScGlobal::getCharClassPtr()
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 29427be..86b6406 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -4804,7 +4804,7 @@ void appendDouble( const sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, dou
rtl::math::doubleToUStringBuffer(
rBuf, fVal,
rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
aSysLocale.GetLocaleDataPtr()->getNumDecimalSep()[0], true);
aSysLocale.GetLocaleData().getNumDecimalSep()[0], true);
}
}
diff --git a/sd/source/ui/app/optsitem.cxx b/sd/source/ui/app/optsitem.cxx
index a5eb94e..9b628aa 100644
--- a/sd/source/ui/app/optsitem.cxx
+++ b/sd/source/ui/app/optsitem.cxx
@@ -171,7 +171,7 @@ void SdOptionsGeneric::Store()
bool SdOptionsGeneric::isMetricSystem()
{
SvtSysLocale aSysLocale;
MeasurementSystem eSys = aSysLocale.GetLocaleDataPtr()->getMeasurementSystemEnum();
MeasurementSystem eSys = aSysLocale.GetLocaleData().getMeasurementSystemEnum();
return ( eSys == MeasurementSystem::Metric );
}
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index a3207d2..42fa566 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -4035,7 +4035,9 @@ void SvNumberFormatter::ImpInitCurrencyTable()
{
LanguageType eLang = LanguageTag::convertToLanguageType( rLocale, false);
rInstalledLocales.insert( eLang);
pLocaleData->setLanguageTag( LanguageTag( rLocale) );
pLocaleData.reset(new LocaleDataWrapper(
::comphelper::getProcessComponentContext(),
LanguageTag(rLocale) ));
Sequence< Currency2 > aCurrSeq = pLocaleData->getAllCurrencies();
sal_Int32 nCurrencyCount = aCurrSeq.getLength();
Currency2 const * const pCurrencies = aCurrSeq.getConstArray();
diff --git a/svtools/source/filter/SvFilterOptionsDialog.cxx b/svtools/source/filter/SvFilterOptionsDialog.cxx
index 7203cfd..cfd88ab 100644
--- a/svtools/source/filter/SvFilterOptionsDialog.cxx
+++ b/svtools/source/filter/SvFilterOptionsDialog.cxx
@@ -267,7 +267,7 @@ void SvFilterOptionsDialog::setSourceDocument( const uno::Reference< lang::XComp
FilterConfigItem aConfigItem( aConfigPath );
OUString aPropertyName;
SvtSysLocale aSysLocale;
if ( aSysLocale.GetLocaleDataPtr()->getMeasurementSystemEnum() == MeasurementSystem::Metric )
if ( aSysLocale.GetLocaleData().getMeasurementSystemEnum() == MeasurementSystem::Metric )
aPropertyName = "Metric";
else
aPropertyName = "NonMetric";
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
index 4964c2f..69d0306 100644
--- a/svx/source/svdraw/svdetc.cxx
+++ b/svx/source/svdraw/svdetc.cxx
@@ -60,7 +60,6 @@ using namespace ::com::sun::star;
// Global data of the DrawingEngine
SdrGlobalData::SdrGlobalData()
: pSysLocale(nullptr)
, pLocaleData(nullptr)
{
if (!utl::ConfigManager::IsFuzzing())
{
@@ -77,9 +76,7 @@ const SvtSysLocale* SdrGlobalData::GetSysLocale()
}
const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
{
if ( !pLocaleData )
pLocaleData = GetSysLocale()->GetLocaleDataPtr();
return pLocaleData;
return &GetSysLocale()->GetLocaleData();
}
namespace {
diff --git a/sw/inc/calc.hxx b/sw/inc/calc.hxx
index dee45a3c..3b585da 100644
--- a/sw/inc/calc.hxx
+++ b/sw/inc/calc.hxx
@@ -202,7 +202,7 @@ class SwCalc
SwDoc& m_rDoc;
SvtSysLocale m_aSysLocale;
const LocaleDataWrapper* m_pLocaleDataWrapper;
std::unique_ptr<LocaleDataWrapper> m_xLocaleDataWrapper;
CharClass* m_pCharClass;
sal_uInt16 m_nListPor;
diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx
index 652e269..19d3d92 100644
--- a/sw/source/core/bastyp/calc.cxx
+++ b/sw/source/core/bastyp/calc.cxx
@@ -218,7 +218,6 @@ SwCalc::SwCalc( SwDoc& rD )
, m_aErrExpr( OUString(), SwSbxValue(), nullptr )
, m_nCommandPos(0)
, m_rDoc( rD )
, m_pLocaleDataWrapper( m_aSysLocale.GetLocaleDataPtr() )
, m_pCharClass( &GetAppCharClass() )
, m_nListPor( 0 )
, m_bHasNumber( false )
@@ -228,16 +227,15 @@ SwCalc::SwCalc( SwDoc& rD )
{
m_aErrExpr.aStr = "~C_ERR~";
LanguageType eLang = GetDocAppScriptLang( m_rDoc );
LanguageTag aLanguageTag( eLang );
if( eLang != m_pLocaleDataWrapper->getLanguageTag().getLanguageType() ||
eLang != m_pCharClass->getLanguageTag().getLanguageType() )
if( eLang != m_pCharClass->getLanguageTag().getLanguageType() )
{
LanguageTag aLanguageTag( eLang );
m_pCharClass = new CharClass( ::comphelper::getProcessComponentContext(), aLanguageTag );
m_pLocaleDataWrapper = new LocaleDataWrapper( aLanguageTag );
}
m_xLocaleDataWrapper.reset(new LocaleDataWrapper( aLanguageTag ));
m_sCurrSym = comphelper::string::strip(m_pLocaleDataWrapper->getCurrSymbol(), ' ');
m_sCurrSym = comphelper::string::strip(m_xLocaleDataWrapper->getCurrSymbol(), ' ');
m_sCurrSym = m_pCharClass->lowercase( m_sCurrSym );
static char const
@@ -349,8 +347,6 @@ SwCalc::SwCalc( SwDoc& rD )
SwCalc::~SwCalc() COVERITY_NOEXCEPT_FALSE
{
if( m_pLocaleDataWrapper != m_aSysLocale.GetLocaleDataPtr() )
delete m_pLocaleDataWrapper;
if( m_pCharClass != &GetAppCharClass() )
delete m_pCharClass;
}
@@ -410,7 +406,7 @@ OUString SwCalc::GetStrResult( double nValue )
nValue,
rtl_math_StringFormat_Automatic,
nDecPlaces,
m_pLocaleDataWrapper->getNumDecimalSep()[0],
m_xLocaleDataWrapper->getNumDecimalSep()[0],
true ));
return aRetStr;
}
@@ -532,7 +528,7 @@ SwCalcExp* SwCalc::VarLook( const OUString& rStr, bool bIns )
OUString sResult;
double nNumber = DBL_MAX;
LanguageType nLang = m_pLocaleDataWrapper->getLanguageTag().getLanguageType();
LanguageType nLang = m_xLocaleDataWrapper->getLanguageTag().getLanguageType();
if(pMgr->GetColumnCnt( sSourceName, sTableName, sColumnName,
nTmpRec, nLang, sResult, &nNumber ))
{
@@ -1376,7 +1372,7 @@ bool SwCalc::Str2Double( const OUString& rCommand, sal_Int32& rCommandPos,
double& rVal )
{
const SvtSysLocale aSysLocale;
return lcl_Str2Double( rCommand, rCommandPos, rVal, aSysLocale.GetLocaleDataPtr() );
return lcl_Str2Double( rCommand, rCommandPos, rVal, &aSysLocale.GetLocaleData() );
}
bool SwCalc::Str2Double( const OUString& rCommand, sal_Int32& rCommandPos,
@@ -1394,7 +1390,7 @@ bool SwCalc::Str2Double( const OUString& rCommand, sal_Int32& rCommandPos,
}
bool const bRet = lcl_Str2Double(rCommand, rCommandPos, rVal,
pLclD ? pLclD.get() : aSysLocale.GetLocaleDataPtr());
pLclD ? pLclD.get() : &aSysLocale.GetLocaleData());
return bRet;
}
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx
index 4ef9322..b187e70 100644
--- a/sw/source/core/doc/DocumentFieldsManager.cxx
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -973,7 +973,7 @@ void DocumentFieldsManager::UpdateExpFieldsImpl(
pMgr->CloseAll( false );
SvtSysLocale aSysLocale;
const LocaleDataWrapper* pLclData = aSysLocale.GetLocaleDataPtr();
const LocaleDataWrapper* pLclData = &aSysLocale.GetLocaleData();
const LanguageType nLang = pLclData->getLanguageTag().getLanguageType();
bool bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, aCalc );
#endif
diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx
index 8c59d0a..e0e91bb 100644
--- a/unotools/source/i18n/localedatawrapper.cxx
+++ b/unotools/source/i18n/localedatawrapper.cxx
@@ -37,11 +37,11 @@
#include <com/sun/star/i18n/NumberFormatMapper.hpp>
#include <comphelper/processfactory.hxx>
#include <comphelper/sequence.hxx>
#include <rtl/instance.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/math.hxx>
const sal_uInt16 nCurrFormatInvalid = 0xffff;
const sal_uInt16 nCurrFormatDefault = 0;
using namespace ::com::sun::star;
@@ -61,21 +61,6 @@ namespace
{};
}
bool LocaleDataWrapper::Locale_Compare::operator()(const css::lang::Locale& rLocale1, const css::lang::Locale& rLocale2) const
{
if (rLocale1.Language < rLocale2.Language)
return true;
else if (rLocale1.Language > rLocale2.Language)
return false;
if (rLocale1.Country < rLocale2.Country)
return true;
else if (rLocale1.Country > rLocale2.Country)
return false;
return rLocale1.Variant < rLocale2.Variant;
}
sal_uInt8 LocaleDataWrapper::nLocaleDataChecking = 0;
LocaleDataWrapper::LocaleDataWrapper(
@@ -85,76 +70,152 @@ LocaleDataWrapper::LocaleDataWrapper(
:
m_xContext( rxContext ),
xLD( LocaleData2::create(rxContext) ),
maLanguageTag( rLanguageTag ),
bLocaleDataItemValid( false ),
bReservedWordValid( false ),
bSecondaryCalendarValid( false )
maLanguageTag( rLanguageTag )
{
invalidateData();
loadData();
loadDateAcceptancePatterns({});
}
LocaleDataWrapper::LocaleDataWrapper(
const LanguageTag& rLanguageTag
const LanguageTag& rLanguageTag,
const std::vector<OUString> & rOverrideDateAcceptancePatterns
)
:
m_xContext( comphelper::getProcessComponentContext() ),
xLD( LocaleData2::create(m_xContext) ),
maLanguageTag( rLanguageTag ),
bLocaleDataItemValid( false ),
bReservedWordValid( false ),
bSecondaryCalendarValid( false )
maLanguageTag( rLanguageTag )
{
invalidateData();
loadData();
loadDateAcceptancePatterns(rOverrideDateAcceptancePatterns);
}
LocaleDataWrapper::~LocaleDataWrapper()
{
}
void LocaleDataWrapper::setLanguageTag( const LanguageTag& rLanguageTag )
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::CriticalChange );
maLanguageTag = rLanguageTag;
invalidateData();
}
const LanguageTag& LocaleDataWrapper::getLanguageTag() const
{
::utl::ReadWriteGuard aGuard( aMutex );
return maLanguageTag;
}
const css::lang::Locale& LocaleDataWrapper::getMyLocale() const
{
::utl::ReadWriteGuard aGuard( aMutex );
return maLanguageTag.getLocale();
}
void LocaleDataWrapper::invalidateData()
void LocaleDataWrapper::loadData()
{
aCurrSymbol.clear();
aCurrBankSymbol.clear();
nDateOrder = nLongDateOrder = DateOrder::Invalid;
nCurrPositiveFormat = nCurrNegativeFormat = nCurrDigits = nCurrFormatInvalid;
if ( bLocaleDataItemValid )
const css::lang::Locale& rMyLocale = maLanguageTag.getLocale();
{
for (OUString & j : aLocaleItem)
j.clear();
bLocaleDataItemValid = false;
Sequence< Currency2 > aCurrSeq = getAllCurrencies();
if ( !aCurrSeq.hasElements() )
{
if (areChecksEnabled())
outputCheckMessage("LocaleDataWrapper::getCurrSymbolsImpl: no currency at all, using ShellsAndPebbles");
aCurrSymbol = "ShellsAndPebbles";
aCurrBankSymbol = aCurrSymbol;
nCurrPositiveFormat = nCurrNegativeFormat = nCurrFormatDefault;
nCurrDigits = 2;
}
else
{
auto pCurr = std::find_if(aCurrSeq.begin(), aCurrSeq.end(),
[](const Currency2& rCurr) { return rCurr.Default; });
if ( pCurr == aCurrSeq.end() )
{
if (areChecksEnabled())
{
outputCheckMessage( appendLocaleInfo( "LocaleDataWrapper::getCurrSymbolsImpl: no default currency" ) );
}
pCurr = aCurrSeq.begin();
}
aCurrSymbol = pCurr->Symbol;
aCurrBankSymbol = pCurr->BankSymbol;
nCurrDigits = pCurr->DecimalPlaces;
}
}
if ( bReservedWordValid )
loadCurrencyFormats();
{
for (OUString & j : aReservedWord)
j.clear();
bReservedWordValid = false;
xDefaultCalendar.reset();
xSecondaryCalendar.reset();
Sequence< Calendar2 > xCals = getAllCalendars();
if (xCals.getLength() > 1)
{
auto pCal = std::find_if(xCals.begin(), xCals.end(),
[](const Calendar2& rCal) { return !rCal.Default; });
if (pCal != xCals.end())
xSecondaryCalendar = std::make_shared<Calendar2>( *pCal);
}
auto pCal = xCals.begin();
if (xCals.getLength() > 1)
{
pCal = std::find_if(xCals.begin(), xCals.end(),
[](const Calendar2& rCal) { return rCal.Default; });
if (pCal == xCals.end())
pCal = xCals.begin();
}
xDefaultCalendar = std::make_shared<Calendar2>( *pCal);
}
xDefaultCalendar.reset();
xSecondaryCalendar.reset();
bSecondaryCalendarValid = false;
if (aGrouping.hasElements())
aGrouping[0] = 0;
if (aDateAcceptancePatterns.hasElements())
aDateAcceptancePatterns = Sequence<OUString>();
loadDateOrders();
try
{
aDateAcceptancePatterns = xLD->getDateAcceptancePatterns( rMyLocale );
}
catch (const Exception&)
{
TOOLS_WARN_EXCEPTION( "unotools.i18n", "getDateAcceptancePatterns" );
aDateAcceptancePatterns = css::uno::Sequence< OUString >(0);
}
loadDigitGrouping();
try
{
aReservedWordSeq = xLD->getReservedWord( rMyLocale );
}
catch ( const Exception& )
{
TOOLS_WARN_EXCEPTION( "unotools.i18n", "getReservedWord" );
aReservedWordSeq = css::uno::Sequence< OUString >(0);
}
for (int i=0; i < css::i18n::reservedWords::COUNT; ++i)
aReservedWord[i] = aReservedWordSeq[i];
try
{
aLocaleDataItem = xLD->getLocaleItem2( rMyLocale );
}
catch (const Exception&)
{
TOOLS_WARN_EXCEPTION( "unotools.i18n", "getLocaleItem" );
static const css::i18n::LocaleDataItem2 aEmptyItem;
aLocaleDataItem = aEmptyItem;
}
aLocaleItem[LocaleItem::DATE_SEPARATOR] = aLocaleDataItem.dateSeparator;
aLocaleItem[LocaleItem::THOUSAND_SEPARATOR] = aLocaleDataItem.thousandSeparator;
aLocaleItem[LocaleItem::DECIMAL_SEPARATOR] = aLocaleDataItem.decimalSeparator;
aLocaleItem[LocaleItem::TIME_SEPARATOR] = aLocaleDataItem.timeSeparator;
aLocaleItem[LocaleItem::TIME_100SEC_SEPARATOR] = aLocaleDataItem.time100SecSeparator;
aLocaleItem[LocaleItem::LIST_SEPARATOR] = aLocaleDataItem.listSeparator;
aLocaleItem[LocaleItem::SINGLE_QUOTATION_START] = aLocaleDataItem.quotationStart;
aLocaleItem[LocaleItem::SINGLE_QUOTATION_END] = aLocaleDataItem.quotationEnd;
aLocaleItem[LocaleItem::DOUBLE_QUOTATION_START] = aLocaleDataItem.doubleQuotationStart;
aLocaleItem[LocaleItem::DOUBLE_QUOTATION_END] = aLocaleDataItem.doubleQuotationEnd;
aLocaleItem[LocaleItem::MEASUREMENT_SYSTEM] = aLocaleDataItem.measurementSystem;
aLocaleItem[LocaleItem::TIME_AM] = aLocaleDataItem.timeAM;
aLocaleItem[LocaleItem::TIME_PM] = aLocaleDataItem.timePM;
aLocaleItem[LocaleItem::LONG_DATE_DAY_OF_WEEK_SEPARATOR] = aLocaleDataItem.LongDateDayOfWeekSeparator;
aLocaleItem[LocaleItem::LONG_DATE_DAY_SEPARATOR] = aLocaleDataItem.LongDateDaySeparator;
aLocaleItem[LocaleItem::LONG_DATE_MONTH_SEPARATOR] = aLocaleDataItem.LongDateMonthSeparator;
aLocaleItem[LocaleItem::LONG_DATE_YEAR_SEPARATOR] = aLocaleDataItem.LongDateYearSeparator;
aLocaleItem[LocaleItem::DECIMAL_SEPARATOR_ALTERNATIVE] = aLocaleDataItem.decimalSeparatorAlternative;
}
/* FIXME-BCP47: locale data should provide a language tag instead that could be
@@ -174,30 +235,7 @@ css::i18n::LanguageCountryInfo LocaleDataWrapper::getLanguageCountryInfo() const
const css::i18n::LocaleDataItem2& LocaleDataWrapper::getLocaleItem() const
{
{
::utl::ReadWriteGuard aGuard( aMutex );
const css::lang::Locale& rLocal = getMyLocale();
auto itr = maDataItemCache.find(rLocal);
if (itr != maDataItemCache.end())
return itr->second;
}
try
{
::utl::ReadWriteGuard aGuard( aMutex );
const css::lang::Locale& rLocal = getMyLocale();
css::i18n::LocaleDataItem2 aItem = xLD->getLocaleItem2( rLocal );
auto aRet = maDataItemCache.insert(std::make_pair(rLocal, aItem));
assert(aRet.second);
return aRet.first->second;
}
catch (const Exception&)
{
TOOLS_WARN_EXCEPTION( "unotools.i18n", "getLocaleItem" );
}
static css::i18n::LocaleDataItem2 aEmptyItem;
return aEmptyItem;
return aLocaleDataItem;
}
css::uno::Sequence< css::i18n::Currency2 > LocaleDataWrapper::getAllCurrencies() const
@@ -353,113 +391,21 @@ std::vector< LanguageType > LocaleDataWrapper::getInstalledLanguageTypes()
const OUString& LocaleDataWrapper::getOneLocaleItem( sal_Int16 nItem ) const
{
::utl::ReadWriteGuard aGuard( aMutex );
if ( nItem >= LocaleItem::COUNT2 )
{
SAL_WARN( "unotools.i18n", "getOneLocaleItem: bounds" );
return aLocaleItem[0];
}
if (aLocaleItem[nItem].isEmpty())
{ // no cached content
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getOneLocaleItemImpl( nItem );
}
return aLocaleItem[nItem];
}
void LocaleDataWrapper::getOneLocaleItemImpl( sal_Int16 nItem )
{
if ( !bLocaleDataItemValid )
{
aLocaleDataItem = getLocaleItem();
bLocaleDataItemValid = true;
}
switch ( nItem )
{
case LocaleItem::DATE_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.dateSeparator;
break;
case LocaleItem::THOUSAND_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.thousandSeparator;
break;
case LocaleItem::DECIMAL_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.decimalSeparator;
break;
case LocaleItem::TIME_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.timeSeparator;
break;
case LocaleItem::TIME_100SEC_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.time100SecSeparator;
break;
case LocaleItem::LIST_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.listSeparator;
break;
case LocaleItem::SINGLE_QUOTATION_START :
aLocaleItem[nItem] = aLocaleDataItem.quotationStart;
break;
case LocaleItem::SINGLE_QUOTATION_END :
aLocaleItem[nItem] = aLocaleDataItem.quotationEnd;
break;
case LocaleItem::DOUBLE_QUOTATION_START :
aLocaleItem[nItem] = aLocaleDataItem.doubleQuotationStart;
break;
case LocaleItem::DOUBLE_QUOTATION_END :
aLocaleItem[nItem] = aLocaleDataItem.doubleQuotationEnd;
break;
case LocaleItem::MEASUREMENT_SYSTEM :
aLocaleItem[nItem] = aLocaleDataItem.measurementSystem;
break;
case LocaleItem::TIME_AM :
aLocaleItem[nItem] = aLocaleDataItem.timeAM;
break;
case LocaleItem::TIME_PM :
aLocaleItem[nItem] = aLocaleDataItem.timePM;
break;
case LocaleItem::LONG_DATE_DAY_OF_WEEK_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.LongDateDayOfWeekSeparator;
break;
case LocaleItem::LONG_DATE_DAY_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.LongDateDaySeparator;
break;
case LocaleItem::LONG_DATE_MONTH_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.LongDateMonthSeparator;
break;
case LocaleItem::LONG_DATE_YEAR_SEPARATOR :
aLocaleItem[nItem] = aLocaleDataItem.LongDateYearSeparator;
break;
case LocaleItem::DECIMAL_SEPARATOR_ALTERNATIVE :
aLocaleItem[nItem] = aLocaleDataItem.decimalSeparatorAlternative;
break;
default:
SAL_WARN( "unotools.i18n", "getOneLocaleItemImpl: which one?" );
}
}
void LocaleDataWrapper::getOneReservedWordImpl( sal_Int16 nWord )
{
if ( !bReservedWordValid )
{
aReservedWordSeq = getReservedWord();
bReservedWordValid = true;
}
DBG_ASSERT( nWord < aReservedWordSeq.getLength(), "getOneReservedWordImpl: which one?" );
if ( nWord < aReservedWordSeq.getLength() )
aReservedWord[nWord] = aReservedWordSeq[nWord];
}
const OUString& LocaleDataWrapper::getOneReservedWord( sal_Int16 nWord ) const
{
::utl::ReadWriteGuard aGuard( aMutex );
if ( nWord < 0 || nWord >= reservedWords::COUNT )
{
SAL_WARN( "unotools.i18n", "getOneReservedWord: bounds" );
nWord = reservedWords::FALSE_WORD;
}
if (aReservedWord[nWord].isEmpty())
{ // no cached content
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getOneReservedWordImpl( nWord );
}
return aReservedWord[nWord];
}
@@ -472,22 +418,6 @@ MeasurementSystem LocaleDataWrapper::mapMeasurementStringToEnum( const OUString&
return MeasurementSystem::US;
}
void LocaleDataWrapper::getSecondaryCalendarImpl()
{
if (!xSecondaryCalendar && !bSecondaryCalendarValid)
{
Sequence< Calendar2 > xCals = getAllCalendars();
if (xCals.getLength() > 1)
{
auto pCal = std::find_if(xCals.begin(), xCals.end(),
[](const Calendar2& rCal) { return !rCal.Default; });
if (pCal != xCals.end())
xSecondaryCalendar = std::make_shared<Calendar2>( *pCal);
}
bSecondaryCalendarValid = true;
}
}
bool LocaleDataWrapper::doesSecondaryCalendarUseEC( std::u16string_view rName ) const
{
if (rName.empty())
@@ -503,13 +433,6 @@ bool LocaleDataWrapper::doesSecondaryCalendarUseEC( std::u16string_view rName )
aBcp47 != "zh-TW")
return false;
::utl::ReadWriteGuard aGuard( aMutex );
if (!bSecondaryCalendarValid)
{ // no cached content
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getSecondaryCalendarImpl();
}
if (!xSecondaryCalendar)
return false;
if (!xSecondaryCalendar->Name.equalsIgnoreAsciiCase( rName))
@@ -518,31 +441,8 @@ bool LocaleDataWrapper::doesSecondaryCalendarUseEC( std::u16string_view rName )
return true;
}
void LocaleDataWrapper::getDefaultCalendarImpl()
{
if (xDefaultCalendar)
return;
Sequence< Calendar2 > xCals = getAllCalendars();
auto pCal = xCals.begin();
if (xCals.getLength() > 1)
{
pCal = std::find_if(xCals.begin(), xCals.end(),
[](const Calendar2& rCal) { return rCal.Default; });
if (pCal == xCals.end())
pCal = xCals.begin();
}
xDefaultCalendar = std::make_shared<Calendar2>( *pCal);
}
const std::shared_ptr< css::i18n::Calendar2 >& LocaleDataWrapper::getDefaultCalendar() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if (!xDefaultCalendar)
{ // no cached content
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getDefaultCalendarImpl();
}
return xDefaultCalendar;
}
@@ -560,87 +460,29 @@ css::uno::Sequence< css::i18n::CalendarItem2 > const & LocaleDataWrapper::getDef
const OUString& LocaleDataWrapper::getCurrSymbol() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if (aCurrSymbol.isEmpty())
{
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getCurrSymbolsImpl();
}
return aCurrSymbol;
}
const OUString& LocaleDataWrapper::getCurrBankSymbol() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if (aCurrBankSymbol.isEmpty())
{
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getCurrSymbolsImpl();
}
return aCurrBankSymbol;
}
sal_uInt16 LocaleDataWrapper::getCurrPositiveFormat() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if ( nCurrPositiveFormat == nCurrFormatInvalid )
{
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getCurrFormatsImpl();
}
return nCurrPositiveFormat;
}
sal_uInt16 LocaleDataWrapper::getCurrNegativeFormat() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if ( nCurrNegativeFormat == nCurrFormatInvalid )
{
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getCurrFormatsImpl();
}
return nCurrNegativeFormat;
}
sal_uInt16 LocaleDataWrapper::getCurrDigits() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if ( nCurrDigits == nCurrFormatInvalid )
{
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getCurrSymbolsImpl();
}
return nCurrDigits;
}
void LocaleDataWrapper::getCurrSymbolsImpl()
{
Sequence< Currency2 > aCurrSeq = getAllCurrencies();
if ( !aCurrSeq.hasElements() )
{
if (areChecksEnabled())
outputCheckMessage("LocaleDataWrapper::getCurrSymbolsImpl: no currency at all, using ShellsAndPebbles");
aCurrSymbol = "ShellsAndPebbles";
aCurrBankSymbol = aCurrSymbol;
nCurrPositiveFormat = nCurrNegativeFormat = nCurrFormatDefault;
nCurrDigits = 2;
return;
}
auto pCurr = std::find_if(aCurrSeq.begin(), aCurrSeq.end(),
[](const Currency2& rCurr) { return rCurr.Default; });
if ( pCurr == aCurrSeq.end() )
{
if (areChecksEnabled())
{
outputCheckMessage( appendLocaleInfo( "LocaleDataWrapper::getCurrSymbolsImpl: no default currency" ) );
}
pCurr = aCurrSeq.begin();
}
aCurrSymbol = pCurr->Symbol;
aCurrBankSymbol = pCurr->BankSymbol;
nCurrDigits = pCurr->DecimalPlaces;
}
void LocaleDataWrapper::scanCurrFormatImpl( const OUString& rCode,
sal_Int32 nStart, sal_Int32& nSign, sal_Int32& nPar,
sal_Int32& nNum, sal_Int32& nBlank, sal_Int32& nSym ) const
@@ -719,10 +561,10 @@ void LocaleDataWrapper::scanCurrFormatImpl( const OUString& rCode,
}
}
void LocaleDataWrapper::getCurrFormatsImpl()
void LocaleDataWrapper::loadCurrencyFormats()
{
css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( m_xContext );
uno::Sequence< NumberFormatCode > aFormatSeq = xNFC->getAllFormatCode( KNumberFormatUsage::CURRENCY, getMyLocale() );
uno::Sequence< NumberFormatCode > aFormatSeq = xNFC->getAllFormatCode( KNumberFormatUsage::CURRENCY, maLanguageTag.getLocale() );
sal_Int32 nCnt = aFormatSeq.getLength();
if ( !nCnt )
{ // bad luck
@@ -765,9 +607,6 @@ void LocaleDataWrapper::getCurrFormatsImpl()
}
}
// make sure it's loaded
getCurrSymbol();
sal_Int32 nSign, nPar, nNum, nBlank, nSym;
// positive format
@@ -862,23 +701,11 @@ void LocaleDataWrapper::getCurrFormatsImpl()
DateOrder LocaleDataWrapper::getDateOrder() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if ( nDateOrder == DateOrder::Invalid )
{
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getDateOrdersImpl();
}
return nDateOrder;
}
DateOrder LocaleDataWrapper::getLongDateOrder() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if ( nLongDateOrder == DateOrder::Invalid )
{
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getDateOrdersImpl();
}
return nLongDateOrder;
}
@@ -961,10 +788,10 @@ DateOrder LocaleDataWrapper::scanDateOrderImpl( const OUString& rCode ) const
}
}
void LocaleDataWrapper::getDateOrdersImpl()
void LocaleDataWrapper::loadDateOrders()
{
css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( m_xContext );
uno::Sequence< NumberFormatCode > aFormatSeq = xNFC->getAllFormatCode( KNumberFormatUsage::DATE, getMyLocale() );
uno::Sequence< NumberFormatCode > aFormatSeq = xNFC->getAllFormatCode( KNumberFormatUsage::DATE, maLanguageTag.getLocale() );
sal_Int32 nCnt = aFormatSeq.getLength();
if ( !nCnt )
{ // bad luck
@@ -1047,7 +874,7 @@ void LocaleDataWrapper::getDateOrdersImpl()
// --- digit grouping -------------------------------------------------
void LocaleDataWrapper::getDigitGroupingImpl()
void LocaleDataWrapper::loadDigitGrouping()
{
/* TODO: This is a very simplified grouping setup that only serves its
* current purpose for Indian locales. A free-form flexible one would
@@ -1081,12 +908,6 @@ void LocaleDataWrapper::getDigitGroupingImpl()
css::uno::Sequence< sal_Int32 > LocaleDataWrapper::getDigitGrouping() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if (!aGrouping.hasElements() || aGrouping[0] == 0)
{ // no cached content
aGuard.changeReadToWrite();
const_cast<LocaleDataWrapper*>(this)->getDigitGroupingImpl();
}
return aGrouping;
}
@@ -1224,7 +1045,7 @@ void LocaleDataWrapper::ImplAddFormatNum( OUStringBuffer& rBuf,
}
// append decimal separator
rBuf.append( getNumDecimalSep() );
rBuf.append( aLocaleDataItem.decimalSeparator );
// fill with zeros
sal_uInt16 i = 0;
@@ -1240,7 +1061,7 @@ void LocaleDataWrapper::ImplAddFormatNum( OUStringBuffer& rBuf,
}
else
{
const OUString& rThoSep = getNumThousandSep();
const OUString& rThoSep = aLocaleDataItem.thousandSeparator;
// copy number to buffer (excluding decimals)
sal_uInt16 nNumLen2 = nNumLen-nDecimals;
@@ -1261,7 +1082,7 @@ void LocaleDataWrapper::ImplAddFormatNum( OUStringBuffer& rBuf,
// append decimals
if ( nDecimals )
{
rBuf.append( getNumDecimalSep() );
rBuf.append( aLocaleDataItem.decimalSeparator );
bool bNullEnd = true;
while ( i < nNumLen )
@@ -1284,7 +1105,6 @@ void LocaleDataWrapper::ImplAddFormatNum( OUStringBuffer& rBuf,
OUString LocaleDataWrapper::getDate( const Date& rDate ) const
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
//!TODO: leading zeros et al
OUStringBuffer aBuf(128);
sal_uInt16 nDay = rDate.GetDay();
@@ -1304,23 +1124,23 @@ OUString LocaleDataWrapper::getDate( const Date& rDate ) const
{
case DateOrder::DMY :
ImplAdd2UNum( aBuf, nDay, true /* IsDateDayLeadingZero() */ );
aBuf.append( getDateSep() );
aBuf.append( aLocaleDataItem.dateSeparator );
ImplAdd2UNum( aBuf, nMonth, true /* IsDateMonthLeadingZero() */ );
aBuf.append( getDateSep() );
aBuf.append( aLocaleDataItem.dateSeparator );
ImplAddNum( aBuf, nYear, nYearLen );
break;
case DateOrder::MDY :
ImplAdd2UNum( aBuf, nMonth, true /* IsDateMonthLeadingZero() */ );
aBuf.append( getDateSep() );
aBuf.append( aLocaleDataItem.dateSeparator );
ImplAdd2UNum( aBuf, nDay, true /* IsDateDayLeadingZero() */ );
aBuf.append( getDateSep() );
aBuf.append( aLocaleDataItem.dateSeparator );
ImplAddNum( aBuf, nYear, nYearLen );
break;
default:
ImplAddNum( aBuf, nYear, nYearLen );
aBuf.append( getDateSep() );
aBuf.append( aLocaleDataItem.dateSeparator );
ImplAdd2UNum( aBuf, nMonth, true /* IsDateMonthLeadingZero() */ );
aBuf.append( getDateSep() );
aBuf.append( aLocaleDataItem.dateSeparator );
ImplAdd2UNum( aBuf, nDay, true /* IsDateDayLeadingZero() */ );
}
@@ -1329,7 +1149,6 @@ OUString LocaleDataWrapper::getDate( const Date& rDate ) const
OUString LocaleDataWrapper::getTime( const tools::Time& rTime, bool bSec, bool b100Sec ) const
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
//!TODO: leading zeros et al
OUStringBuffer aBuf(128);
sal_uInt16 nHour = rTime.GetHour();
@@ -1337,16 +1156,16 @@ OUString LocaleDataWrapper::getTime( const tools::Time& rTime, bool bSec, bool b
nHour %= 24;
ImplAdd2UNum( aBuf, nHour, true /* IsTimeLeadingZero() */ );
aBuf.append( getTimeSep() );
aBuf.append( aLocaleDataItem.timeSeparator );
ImplAdd2UNum( aBuf, rTime.GetMin(), true );
if ( bSec )
{
aBuf.append( getTimeSep() );
aBuf.append( aLocaleDataItem.timeSeparator );
ImplAdd2UNum( aBuf, rTime.GetSec(), true );
if ( b100Sec )
{
aBuf.append( getTime100SecSep() );
aBuf.append( aLocaleDataItem.time100SecSeparator );
ImplAdd9UNum( aBuf, rTime.GetNanoSec() );
}
}
@@ -1357,7 +1176,6 @@ OUString LocaleDataWrapper::getTime( const tools::Time& rTime, bool bSec, bool b
OUString LocaleDataWrapper::getLongDate( const Date& rDate, CalendarWrapper& rCal,
bool bTwoDigitYear ) const
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
OUStringBuffer aBuf(20);
OUStringBuffer aStr(120); // complete guess
sal_Int16 nVal;
@@ -1365,7 +1183,7 @@ OUString LocaleDataWrapper::getLongDate( const Date& rDate, CalendarWrapper& rCa
// day of week
nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_WEEK );
aStr.append(rCal.getDisplayName( CalendarDisplayIndex::DAY, nVal, 1 ));
aStr.append(getLongDateDayOfWeekSep());
aStr.append(aLocaleDataItem.LongDateDayOfWeekSeparator);
// day of month
nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_MONTH );
ImplAdd2UNum( aBuf, nVal, false/*bDayOfMonthWithLeadingZero*/ );
@@ -1384,20 +1202,19 @@ OUString LocaleDataWrapper::getLongDate( const Date& rDate, CalendarWrapper& rCa
switch ( getLongDateOrder() )
{
case DateOrder::DMY :
aStr.append(aDay + getLongDateDaySep() + aMonth + getLongDateMonthSep() + aYear);
aStr.append(aDay + aLocaleDataItem.LongDateDaySeparator + aMonth + aLocaleDataItem.LongDateMonthSeparator + aYear);
break;
case DateOrder::MDY :
aStr.append(aMonth + getLongDateMonthSep() + aDay + getLongDateDaySep() + aYear);
aStr.append(aMonth + aLocaleDataItem.LongDateMonthSeparator + aDay + aLocaleDataItem.LongDateDaySeparator + aYear);
break;
default: // YMD
aStr.append(aYear + getLongDateYearSep() + aMonth + getLongDateMonthSep() + aDay);
aStr.append(aYear + aLocaleDataItem.LongDateYearSeparator + aMonth + aLocaleDataItem.LongDateMonthSeparator + aDay);
}
return aStr.makeStringAndClear();
}
OUString LocaleDataWrapper::getDuration( const tools::Time& rTime, bool bSec, bool b100Sec ) const
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
OUStringBuffer aBuf(128);
if ( rTime < tools::Time( 0 ) )
@@ -1407,16 +1224,16 @@ OUString LocaleDataWrapper::getDuration( const tools::Time& rTime, bool bSec, bo
ImplAddUNum( aBuf, rTime.GetHour(), 2 );
else
ImplAddUNum( aBuf, rTime.GetHour() );
aBuf.append( getTimeSep() );
aBuf.append( aLocaleDataItem.timeSeparator );
ImplAdd2UNum( aBuf, rTime.GetMin(), true );
if ( bSec )
{
aBuf.append( getTimeSep() );
aBuf.append( aLocaleDataItem.timeSeparator );
ImplAdd2UNum( aBuf, rTime.GetSec(), true );
if ( b100Sec )
{
aBuf.append( getTime100SecSep() );
aBuf.append( aLocaleDataItem.time100SecSeparator );
ImplAdd9UNum( aBuf, rTime.GetNanoSec() );
}
}
@@ -1426,23 +1243,22 @@ OUString LocaleDataWrapper::getDuration( const tools::Time& rTime, bool bSec, bo
// --- simple number formatting ---------------------------------------
static size_t ImplGetNumberStringLengthGuess( const LocaleDataWrapper& rLoc, sal_uInt16 nDecimals )
static size_t ImplGetNumberStringLengthGuess( const css::i18n::LocaleDataItem2& rLocaleDataItem, sal_uInt16 nDecimals )
{
// approximately 3.2 bits per digit
const size_t nDig = ((sizeof(sal_Int64) * 8) / 3) + 1;
// digits, separators (pessimized for insane "every digit may be grouped"), leading zero, sign
size_t nGuess = ((nDecimals < nDig) ?
(((nDig - nDecimals) * rLoc.getNumThousandSep().getLength()) + nDig) :
nDecimals) + rLoc.getNumDecimalSep().getLength() + 3;
(((nDig - nDecimals) * rLocaleDataItem.thousandSeparator.getLength()) + nDig) :
nDecimals) + rLocaleDataItem.decimalSeparator.getLength() + 3;
return nGuess;
}
OUString LocaleDataWrapper::getNum( sal_Int64 nNumber, sal_uInt16 nDecimals,
bool bUseThousandSep, bool bTrailingZeros ) const
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
// check if digits and separators will fit into fixed buffer or allocate
size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals );
size_t nGuess = ImplGetNumberStringLengthGuess( aLocaleDataItem, nDecimals );
OUStringBuffer aBuf(int(nGuess + 16));
ImplAddFormatNum( aBuf, nNumber, nDecimals,
@@ -1454,11 +1270,10 @@ OUString LocaleDataWrapper::getNum( sal_Int64 nNumber, sal_uInt16 nDecimals,
OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
const OUString& rCurrencySymbol, bool bUseThousandSep ) const
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
sal_Unicode cZeroChar = getCurrZeroChar();
// check if digits and separators will fit into fixed buffer or allocate
size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals );
size_t nGuess = ImplGetNumberStringLengthGuess( aLocaleDataItem, nDecimals );
OUStringBuffer aNumBuf(int(nGuess + 16));
OUStringBuffer aBuf(int(rCurrencySymbol.getLength() + nGuess + 20 ));
@@ -1642,15 +1457,15 @@ OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
double LocaleDataWrapper::stringToDouble( const OUString& rString, bool bUseGroupSep,
rtl_math_ConversionStatus* pStatus, sal_Int32* pParseEnd ) const
{
const sal_Unicode cGroupSep = (bUseGroupSep ? getNumThousandSep()[0] : 0);
const sal_Unicode cGroupSep = (bUseGroupSep ? aLocaleDataItem.thousandSeparator[0] : 0);
rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
sal_Int32 nParseEnd = 0;
double fValue = rtl::math::stringToDouble( rString, getNumDecimalSep()[0], cGroupSep, &eStatus, &nParseEnd);
bool bTryAlt = (nParseEnd < rString.getLength() && !getNumDecimalSepAlt().isEmpty() &&
rString[nParseEnd] == getNumDecimalSepAlt().toChar());
double fValue = rtl::math::stringToDouble( rString, aLocaleDataItem.decimalSeparator[0], cGroupSep, &eStatus, &nParseEnd);
bool bTryAlt = (nParseEnd < rString.getLength() && !aLocaleDataItem.decimalSeparatorAlternative.isEmpty() &&
rString[nParseEnd] == aLocaleDataItem.decimalSeparatorAlternative.toChar());
// Try re-parsing with alternative if that was the reason to stop.
if (bTryAlt)
fValue = rtl::math::stringToDouble( rString, getNumDecimalSepAlt().toChar(), cGroupSep, &eStatus, &nParseEnd);
fValue = rtl::math::stringToDouble( rString, aLocaleDataItem.decimalSeparatorAlternative.toChar(), cGroupSep, &eStatus, &nParseEnd);
if (pStatus)
*pStatus = eStatus;
if (pParseEnd)
@@ -1661,15 +1476,15 @@ double LocaleDataWrapper::stringToDouble( const OUString& rString, bool bUseGrou
double LocaleDataWrapper::stringToDouble( const sal_Unicode* pBegin, const sal_Unicode* pEnd, bool bUseGroupSep,
rtl_math_ConversionStatus* pStatus, const sal_Unicode** ppParseEnd ) const
{
const sal_Unicode cGroupSep = (bUseGroupSep ? getNumThousandSep()[0] : 0);
const sal_Unicode cGroupSep = (bUseGroupSep ? aLocaleDataItem.thousandSeparator[0] : 0);
rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
const sal_Unicode* pParseEnd = nullptr;
double fValue = rtl_math_uStringToDouble( pBegin, pEnd, getNumDecimalSep()[0], cGroupSep, &eStatus, &pParseEnd);
bool bTryAlt = (pParseEnd < pEnd && !getNumDecimalSepAlt().isEmpty() &&
*pParseEnd == getNumDecimalSepAlt().toChar());
double fValue = rtl_math_uStringToDouble( pBegin, pEnd, aLocaleDataItem.decimalSeparator[0], cGroupSep, &eStatus, &pParseEnd);
bool bTryAlt = (pParseEnd < pEnd && !aLocaleDataItem.decimalSeparatorAlternative.isEmpty() &&
*pParseEnd == aLocaleDataItem.decimalSeparatorAlternative.toChar());
// Try re-parsing with alternative if that was the reason to stop.
if (bTryAlt)
fValue = rtl_math_uStringToDouble( pBegin, pEnd, getNumDecimalSepAlt().toChar(), cGroupSep, &eStatus, &pParseEnd);
fValue = rtl_math_uStringToDouble( pBegin, pEnd, aLocaleDataItem.decimalSeparatorAlternative.toChar(), cGroupSep, &eStatus, &pParseEnd);
if (pStatus)
*pStatus = eStatus;
if (ppParseEnd)
@@ -1687,7 +1502,6 @@ LanguageTag LocaleDataWrapper::getLoadedLanguageTag() const
OUString LocaleDataWrapper::appendLocaleInfo(const OUString& rDebugMsg) const
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::BlockCritical );
OUStringBuffer aDebugMsg(rDebugMsg);
aDebugMsg.append('\n');
aDebugMsg.append(maLanguageTag.getBcp47());
@@ -1763,60 +1577,41 @@ css::uno::Sequence< css::i18n::Calendar2 > LocaleDataWrapper::getAllCalendars()
css::uno::Sequence< OUString > LocaleDataWrapper::getDateAcceptancePatterns() const
{
::utl::ReadWriteGuard aGuard( aMutex );
if (aDateAcceptancePatterns.hasElements())
return aDateAcceptancePatterns;
aGuard.changeReadToWrite();
try
{
const_cast<LocaleDataWrapper*>(this)->aDateAcceptancePatterns =
xLD->getDateAcceptancePatterns( getMyLocale() );
return aDateAcceptancePatterns;
}
catch (const Exception&)
{
TOOLS_WARN_EXCEPTION( "unotools.i18n", "getDateAcceptancePatterns" );
}
return css::uno::Sequence< OUString >(0);
return aDateAcceptancePatterns;
}
// --- Override layer --------------------------------------------------------
void LocaleDataWrapper::setDateAcceptancePatterns(
const css::uno::Sequence< OUString > & rPatterns )
void LocaleDataWrapper::loadDateAcceptancePatterns(
const std::vector<OUString> & rPatterns )
{
::utl::ReadWriteGuard aGuard( aMutex, ReadWriteGuardMode::Write );
if (!aDateAcceptancePatterns.hasElements() || !rPatterns.hasElements())
if (!aDateAcceptancePatterns.hasElements() || rPatterns.empty())
{
try
{
aDateAcceptancePatterns = xLD->getDateAcceptancePatterns( getMyLocale() );
aDateAcceptancePatterns = xLD->getDateAcceptancePatterns( maLanguageTag.getLocale() );
}
catch (const Exception&)
{
TOOLS_WARN_EXCEPTION( "unotools.i18n", "setDateAcceptancePatterns" );
}
if (!rPatterns.hasElements())
if (rPatterns.empty())
return; // just a reset
if (!aDateAcceptancePatterns.hasElements())
{
aDateAcceptancePatterns = rPatterns;
aDateAcceptancePatterns = comphelper::containerToSequence(rPatterns);
return;
}
}
// Never overwrite the locale's full date pattern! The first.
if (aDateAcceptancePatterns[0] == rPatterns[0])
aDateAcceptancePatterns = rPatterns; // sane
aDateAcceptancePatterns = comphelper::containerToSequence(rPatterns); // sane
else
{
// Copy existing full date pattern and append the sequence passed.
/* TODO: could check for duplicates and shrink target sequence */
Sequence< OUString > aTmp( rPatterns.getLength() + 1 );
Sequence< OUString > aTmp( rPatterns.size() + 1 );
aTmp[0] = aDateAcceptancePatterns[0];
std::copy(rPatterns.begin(), rPatterns.end(), std::next(aTmp.begin()));
aDateAcceptancePatterns = aTmp;
diff --git a/unotools/source/misc/syslocale.cxx b/unotools/source/misc/syslocale.cxx
index 7f89d34..d685227 100644
--- a/unotools/source/misc/syslocale.cxx
+++ b/unotools/source/misc/syslocale.cxx
@@ -57,13 +57,14 @@ public:
virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override;
private:
void setDateAcceptancePatternsConfig();
std::vector<OUString> getDateAcceptancePatternsConfig();
};
SvtSysLocale_Impl::SvtSysLocale_Impl()
{
pLocaleData.reset(new LocaleDataWrapper( aSysLocaleOptions.GetRealLanguageTag() ));
setDateAcceptancePatternsConfig();
pLocaleData.reset(new LocaleDataWrapper(
aSysLocaleOptions.GetRealLanguageTag(),
getDateAcceptancePatternsConfig() ));
// listen for further changes
aSysLocaleOptions.AddListener( this );
@@ -83,36 +84,33 @@ CharClass* SvtSysLocale_Impl::GetCharClass()
void SvtSysLocale_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints nHint )
{
if ( !(nHint & ConfigurationHints::Locale) &&
!(nHint & ConfigurationHints::DatePatterns) )
return;
MutexGuard aGuard( SvtSysLocale::GetMutex() );
const LanguageTag& rLanguageTag = aSysLocaleOptions.GetRealLanguageTag();
if ( nHint & ConfigurationHints::Locale )
{
const LanguageTag& rLanguageTag = aSysLocaleOptions.GetRealLanguageTag();
pLocaleData->setLanguageTag( rLanguageTag );
GetCharClass()->setLanguageTag( rLanguageTag );
}
if ( nHint & ConfigurationHints::DatePatterns )
{
setDateAcceptancePatternsConfig();
}
pLocaleData.reset(new LocaleDataWrapper(rLanguageTag, getDateAcceptancePatternsConfig()));
}
void SvtSysLocale_Impl::setDateAcceptancePatternsConfig()
std::vector<OUString> SvtSysLocale_Impl::getDateAcceptancePatternsConfig()
{
OUString aStr( aSysLocaleOptions.GetDatePatternsConfigString());
if (aStr.isEmpty())
pLocaleData->setDateAcceptancePatterns( uno::Sequence<OUString>()); // reset
else
return {}; // reset
::std::vector< OUString > aVec;
for (sal_Int32 nIndex = 0; nIndex >= 0; /*nop*/)
{
::std::vector< OUString > aVec;
for (sal_Int32 nIndex = 0; nIndex >= 0; /*nop*/)
{
OUString aTok( aStr.getToken( 0, ';', nIndex));
if (!aTok.isEmpty())
aVec.push_back( aTok);
}
pLocaleData->setDateAcceptancePatterns( comphelper::containerToSequence(aVec) );
OUString aTok( aStr.getToken( 0, ';', nIndex));
if (!aTok.isEmpty())
aVec.push_back( aTok);
}
return aVec;
}
SvtSysLocale::SvtSysLocale()
@@ -148,11 +146,6 @@ const LocaleDataWrapper& SvtSysLocale::GetLocaleData() const
return *(pImpl->pLocaleData);
}
const LocaleDataWrapper* SvtSysLocale::GetLocaleDataPtr() const
{
return pImpl->pLocaleData.get();
}
const CharClass& SvtSysLocale::GetCharClass() const
{
return *(pImpl->GetCharClass());
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx
index 9a42dcb..cc5a633 100644
--- a/vcl/source/control/field.cxx
+++ b/vcl/source/control/field.cxx
@@ -456,11 +456,19 @@ LocaleDataWrapper& FormatterBase::ImplGetLocaleDataWrapper() const
{
if ( !mpLocaleDataWrapper )
{
const_cast<FormatterBase*>(this)->mpLocaleDataWrapper.reset( new LocaleDataWrapper( GetLanguageTag() ) );
mpLocaleDataWrapper.reset( new LocaleDataWrapper( GetLanguageTag() ) );
}
return *mpLocaleDataWrapper;
}
/** reset the LocaleDataWrapper when the language tag changes */
void FormatterBase::ImplResetLocaleDataWrapper() const
{
// just get rid of, the next time it is requested, it will get loaded with the right
// language tag
mpLocaleDataWrapper.reset();
}
const LocaleDataWrapper& FormatterBase::GetLocaleDataWrapper() const
{
return ImplGetLocaleDataWrapper();
@@ -873,7 +881,7 @@ void NumericBox::DataChanged( const DataChangedEvent& rDCEvt )
{
OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
@@ -1492,7 +1500,7 @@ void MetricField::DataChanged( const DataChangedEvent& rDCEvt )
{
OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
@@ -1605,7 +1613,7 @@ void MetricBox::DataChanged( const DataChangedEvent& rDCEvt )
{
OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
@@ -1760,7 +1768,7 @@ void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt )
{
OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
@@ -1843,7 +1851,7 @@ void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt )
{
OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
index e303c18..b66e226 100644
--- a/vcl/source/control/field2.cxx
+++ b/vcl/source/control/field2.cxx
@@ -2036,7 +2036,7 @@ void DateField::DataChanged( const DataChangedEvent& rDCEvt )
if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & (AllSettingsFlags::LOCALE|AllSettingsFlags::MISC)) )
{
if (rDCEvt.GetFlags() & AllSettingsFlags::LOCALE)
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
ReformatAll();
}
}
@@ -2104,7 +2104,7 @@ void DateBox::DataChanged( const DataChangedEvent& rDCEvt )
if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::LOCALE) )
{
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
ReformatAll();
}
}
@@ -2893,7 +2893,7 @@ void TimeField::DataChanged( const DataChangedEvent& rDCEvt )
if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::LOCALE) )
{
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
ReformatAll();
}
}
@@ -3024,7 +3024,7 @@ void TimeBox::DataChanged( const DataChangedEvent& rDCEvt )
if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::LOCALE) )
{
ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
ImplResetLocaleDataWrapper();
ReformatAll();
}
}
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index 1392c4e..38c4d42 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -1623,7 +1623,8 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if ( nElemType == NF_KEY_NNNN )
{
// write additional text element for separator
pLocaleData->setLanguageTag( LanguageTag( nLang ) );
pLocaleData.reset( new LocaleDataWrapper( pFormatter->GetComponentContext(),
LanguageTag( nLang ) ) );
AddToTextElement_Impl( pLocaleData->getLongDateDayOfWeekSep() );
}
}
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index a62133c..f7cabc5 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -365,12 +365,10 @@ void SvXMLNumImpData::RemoveVolatileFormats()
const LocaleDataWrapper& SvXMLNumImpData::GetLocaleData( LanguageType nLang )
{
if ( !pLocaleData )
if ( !pLocaleData || pLocaleData->getLanguageTag() != LanguageTag(nLang) )
pLocaleData = std::make_unique<LocaleDataWrapper>(
pFormatter ? pFormatter->GetComponentContext() : m_xContext,
LanguageTag( nLang ) );
else
pLocaleData->setLanguageTag( LanguageTag( nLang ) );
return *pLocaleData;
}