[Libreoffice-commits] core.git: include/svl svl/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Fri Sep 17 19:27:00 UTC 2021


 include/svl/numformat.hxx       |    2 -
 include/svl/ondemand.hxx        |   76 +++++++++++++++++++++++++++++++++++++---
 svl/source/numbers/zforlist.cxx |    8 ++--
 3 files changed, 77 insertions(+), 9 deletions(-)

New commits:
commit 82689553221e1f8ceab62d72a27b31902d45f436
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Fri Sep 17 16:03:11 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Fri Sep 17 21:26:26 2021 +0200

    create OnDemandCharClass cache
    
    and use it in SvNumberFormatter for situations where we are rapidly
    switching locales (e.g. spreadsheet with alternating locales on adjacent
    rows)
    
    Change-Id: Ic35fdbbfbdc960673e91a37efed1d0e12c1a0751
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122264
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/include/svl/numformat.hxx b/include/svl/numformat.hxx
index a851032ef47c..4026ff71e4a4 100644
--- a/include/svl/numformat.hxx
+++ b/include/svl/numformat.hxx
@@ -563,7 +563,7 @@ private:
     std::unique_ptr<SvNumberFormatTable> pFormatTable; // For the UI dialog
     std::unique_ptr<SvNumberFormatterIndexTable>
         pMergeTable; // List of indices for merging two formatters
-    std::optional<CharClass> oCharClass; // CharacterClassification
+    OnDemandCharClass xCharClass; // CharacterClassification
     OnDemandLocaleDataWrapper xLocaleData; // LocaleData switched between SYSTEM, ENGLISH and other
     OnDemandTransliterationWrapper xTransliteration; // Transliteration loaded on demand
     OnDemandCalendarWrapper xCalendar; // Calendar loaded on demand
diff --git a/include/svl/ondemand.hxx b/include/svl/ondemand.hxx
index 71bec2207a24..4a0a91b18264 100644
--- a/include/svl/ondemand.hxx
+++ b/include/svl/ondemand.hxx
@@ -19,15 +19,16 @@
 
 #pragma once
 
-#include <optional>
-#include <unotools/syslocale.hxx>
+#include <com/sun/star/uno/Reference.hxx>
 #include <i18nlangtag/lang.h>
+#include <i18nutil/transliteration.hxx>
+#include <unotools/syslocale.hxx>
 #include <unotools/localedatawrapper.hxx>
 #include <unotools/calendarwrapper.hxx>
 #include <unotools/transliterationwrapper.hxx>
 #include <unotools/nativenumberwrapper.hxx>
-#include <com/sun/star/uno/Reference.hxx>
-#include <i18nutil/transliteration.hxx>
+#include <unotools/charclass.hxx>
+#include <optional>
 
 /*
     On demand instantiation and initialization of several i18n wrappers,
@@ -278,4 +279,71 @@ public:
     }
 };
 
+/** @short
+    SvNumberformatter uses it upon switching locales.
+
+    @descr
+    Avoids reloading and analysing of locale data again and again.
+
+    @ATTENTION
+    If the default ctor is used the init() method MUST be called before
+    accessing any locale data.
+ */
+
+class OnDemandCharClass
+{
+    std::optional<CharClass> moCharClass1;
+    std::optional<CharClass> moCharClass2;
+    int nCurrent; // -1 == uninitialised, 0 == class1, 1 == class2
+
+public:
+    OnDemandCharClass()
+        : nCurrent(-1)
+    {
+    }
+
+    void changeLocale(const css::uno::Reference<css::uno::XComponentContext>& xContext,
+                      const LanguageTag& rLanguageTag)
+    {
+        // check for existing match
+        if (moCharClass1 && moCharClass1->getLanguageTag() == rLanguageTag)
+        {
+            nCurrent = 0;
+            return;
+        }
+        if (moCharClass2 && moCharClass2->getLanguageTag() == rLanguageTag)
+        {
+            nCurrent = 1;
+            return;
+        }
+        // no match - update one the current entries
+        if (nCurrent == -1 || nCurrent == 1)
+        {
+            moCharClass1.emplace(xContext, rLanguageTag);
+            nCurrent = 0;
+        }
+        else
+        {
+            moCharClass2.emplace(xContext, rLanguageTag);
+            nCurrent = 1;
+        }
+    }
+
+    const CharClass* get() const
+    {
+        switch (nCurrent)
+        {
+            case 0:
+                return &*moCharClass1;
+            case 1:
+                return &*moCharClass2;
+            default:
+                assert(false);
+                return nullptr;
+        }
+    }
+    const CharClass* operator->() const { return get(); }
+    const CharClass& operator*() const { return *get(); }
+};
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index 9c35f99547fc..e623a0239743 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -303,7 +303,7 @@ void SvNumberFormatter::ImpConstruct( LanguageType eLang )
     nDefaultSystemCurrencyFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
 
     maLanguageTag.reset( eLang );
-    oCharClass.emplace( m_xContext, maLanguageTag );
+    xCharClass.changeLocale( m_xContext, maLanguageTag );
     xLocaleData.init( m_xContext, maLanguageTag );
     xCalendar.init( m_xContext, maLanguageTag.getLocale() );
     xTransliteration.init( m_xContext, eLang );
@@ -338,7 +338,7 @@ void SvNumberFormatter::ChangeIntl(LanguageType eLnge)
     ActLnge = eLnge;
 
     maLanguageTag.reset( eLnge );
-    oCharClass.emplace( m_xContext, maLanguageTag );
+    xCharClass.changeLocale( m_xContext, maLanguageTag );
     xLocaleData.changeLocale( maLanguageTag );
     xCalendar.changeLocale( maLanguageTag.getLocale() );
     xTransliteration.changeLocale( eLnge );
@@ -532,7 +532,7 @@ const ::utl::TransliterationWrapper* SvNumberFormatter::GetTransliteration() con
     return xTransliteration.get();
 }
 
-const CharClass* SvNumberFormatter::GetCharClass() const { return oCharClass ? &*oCharClass : nullptr; }
+const CharClass* SvNumberFormatter::GetCharClass() const { return xCharClass.get(); }
 
 const LocaleDataWrapper* SvNumberFormatter::GetLocaleData() const { return xLocaleData.get(); }
 
@@ -1846,7 +1846,7 @@ bool SvNumberFormatter::GetPreviewStringGuess( const OUString& sFormatString,
     eLnge = ActLnge;
     bool bEnglish = (eLnge == LANGUAGE_ENGLISH_US);
 
-    OUString aFormatStringUpper( oCharClass->uppercase( sFormatString ) );
+    OUString aFormatStringUpper( xCharClass->uppercase( sFormatString ) );
     sal_uInt32 nCLOffset = ImpGenerateCL( eLnge );
     sal_uInt32 nKey = ImpIsEntry( aFormatStringUpper, nCLOffset, eLnge );
     if ( nKey != NUMBERFORMAT_ENTRY_NOT_FOUND )


More information about the Libreoffice-commits mailing list