[Libreoffice-commits] core.git: chart2/source editeng/source formula/source include/svl include/svx include/unotools include/vcl linguistic/source sc/source sd/source svl/source svtools/source svx/source sw/inc sw/source unotools/source vcl/source xmloff/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Sun May 2 08:01:27 UTC 2021


 chart2/source/controller/main/ConfigurationAccess.cxx |    3 
 editeng/source/misc/svxacorr.cxx                      |    9 
 formula/source/core/api/FormulaCompiler.cxx           |    2 
 include/svl/ondemand.hxx                              |   30 -
 include/svx/svdetc.hxx                                |    1 
 include/unotools/localedatawrapper.hxx                |   62 --
 include/unotools/syslocale.hxx                        |    1 
 include/vcl/toolkit/field.hxx                         |    4 
 linguistic/source/misc.cxx                            |    9 
 sc/source/core/data/global.cxx                        |    2 
 sc/source/core/tool/token.cxx                         |    2 
 sd/source/ui/app/optsitem.cxx                         |    2 
 svl/source/numbers/zforlist.cxx                       |    4 
 svtools/source/filter/SvFilterOptionsDialog.cxx       |    2 
 svx/source/svdraw/svdetc.cxx                          |    5 
 sw/inc/calc.hxx                                       |    2 
 sw/source/core/bastyp/calc.cxx                        |   20 
 sw/source/core/doc/DocumentFieldsManager.cxx          |    2 
 unotools/source/i18n/localedatawrapper.cxx            |  539 +++++-------------
 unotools/source/misc/syslocale.cxx                    |   43 -
 vcl/source/control/field.cxx                          |   20 
 vcl/source/control/field2.cxx                         |    8 
 xmloff/source/style/xmlnumfe.cxx                      |    3 
 xmloff/source/style/xmlnumfi.cxx                      |    4 
 24 files changed, 280 insertions(+), 499 deletions(-)

New commits:
commit 86b345a963a64fd9b9a3cab522b3ac2e909977fd
Author:     Noel Grandin <noel at peralex.com>
AuthorDate: Sat May 1 08:30:46 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Sun May 2 10:00:43 2021 +0200

    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 at collabora.co.uk>

diff --git a/chart2/source/controller/main/ConfigurationAccess.cxx b/chart2/source/controller/main/ConfigurationAccess.cxx
index 2d1dcfcf9b6e..4040c8db1b8d 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 2845c2279b68..4507cd5523b5 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 c4e037f624cd..3907c1ac8314 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 5ce944a96986..097a34f6726c 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 14af8569f0e5..a6e26bbbdaf4 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 70c62ad3073b..29e9815935c2 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                getOneLocaleItemImpl( sal_Int16 nItem );
+
+    void                loadData();
+    void                loadDateAcceptancePatterns(const std::vector<OUString> & rOverrideDateAcceptancePatterns);
+
     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 31ca65281dd6..5bb2d5222720 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 714ff87de2c9..e30d16e55edc 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 3e0beddada2d..59214bed4500 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 e47303bf7cab..55415f1fdbd7 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 29427bed8506..86b6406c8098 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 a5eb94e7d739..9b628aa0d6c5 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 a3207d20831b..42fa5660ab18 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 7203cfd5e41b..cfd88abb27f2 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 4964c2fc7ed7..69d0306c77b7 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 dee45a3cbc1d..3b585da69fcb 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 652e269c32d9..19d3d92bcb40 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 4ef9322d7c91..b187e709e9b0 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 8c59d0a6267c..e0e91bbbac79 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();
+
+    {
+        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);
+    }
+
+    loadDateOrders();
+
+    try
+    {
+        aDateAcceptancePatterns = xLD->getDateAcceptancePatterns( rMyLocale );
+    }
+    catch (const Exception&)
     {
-        for (OUString & j : aReservedWord)
-            j.clear();
-        bReservedWordValid = false;
-    }
-    xDefaultCalendar.reset();
-    xSecondaryCalendar.reset();
-    bSecondaryCalendarValid = false;
-    if (aGrouping.hasElements())
-        aGrouping[0] = 0;
-    if (aDateAcceptancePatterns.hasElements())
-        aDateAcceptancePatterns = Sequence<OUString>();
+        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 7f89d34f3946..d68522720834 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 9a42dcb2d8a5..cc5a6330d1a9 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 e303c18e74af..b66e226262ff 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 1392c4e0f2f7..38c4d42d2986 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 a62133cfff99..f7cabc5fa29f 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;
 }
 


More information about the Libreoffice-commits mailing list