summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2021-09-17 16:03:11 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-09-17 21:26:26 +0200
commit82689553221e1f8ceab62d72a27b31902d45f436 (patch)
tree17078ac4de66192ca44a66214ea081c094e421e6
parent54906a9b925dee3fd0076e9d258a82c223d62520 (diff)
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@collabora.co.uk>
-rw-r--r--include/svl/numformat.hxx2
-rw-r--r--include/svl/ondemand.hxx76
-rw-r--r--svl/source/numbers/zforlist.cxx8
3 files changed, 77 insertions, 9 deletions
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 )