summaryrefslogtreecommitdiffstats
path: root/include/svl/ondemand.hxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/svl/ondemand.hxx288
1 files changed, 288 insertions, 0 deletions
diff --git a/include/svl/ondemand.hxx b/include/svl/ondemand.hxx
new file mode 100644
index 000000000..5ce944a96
--- /dev/null
+++ b/include/svl/ondemand.hxx
@@ -0,0 +1,288 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SVL_ONDEMAND_HXX
+#define INCLUDED_SVL_ONDEMAND_HXX
+
+#include <memory>
+#include <unotools/syslocale.hxx>
+#include <i18nlangtag/lang.h>
+#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>
+
+/*
+ On demand instantiation and initialization of several i18n wrappers,
+ helping the number formatter to not perform worse than it already does.
+ */
+
+/** @short
+ Switch between LANGUAGE_SYSTEM and LANGUAGE_ENGLISH_US and any other
+ LocaleDataWrapper.
+ 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. The passed parameters Locale and LanguageType
+ must match each other.
+ */
+
+class OnDemandLocaleDataWrapper
+{
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ SvtSysLocale aSysLocale;
+ LanguageType eCurrentLanguage;
+ LanguageType eLastAnyLanguage;
+ const LocaleDataWrapper* pSystem;
+ std::unique_ptr<const LocaleDataWrapper> pEnglish;
+ std::unique_ptr< LocaleDataWrapper> pAny;
+ const LocaleDataWrapper* pCurrent;
+ bool bInitialized;
+
+public:
+ OnDemandLocaleDataWrapper()
+ : eLastAnyLanguage( LANGUAGE_DONTKNOW )
+ , bInitialized(false)
+ {
+ pCurrent = pSystem = aSysLocale.GetLocaleDataPtr();
+ eCurrentLanguage = LANGUAGE_SYSTEM;
+ }
+
+ bool isInitialized() const { return bInitialized; }
+
+ void init(
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const LanguageTag& rLanguageTag
+ )
+ {
+ m_xContext = rxContext;
+ changeLocale( rLanguageTag );
+ bInitialized = true;
+ }
+
+ void changeLocale( const LanguageTag& rLanguageTag )
+ {
+ LanguageType eLang = rLanguageTag.getLanguageType( false);
+ if ( eLang == LANGUAGE_SYSTEM )
+ pCurrent = pSystem;
+ else if ( eLang == LANGUAGE_ENGLISH_US )
+ {
+ if ( !pEnglish )
+ pEnglish.reset( new LocaleDataWrapper( m_xContext, rLanguageTag ) );
+ pCurrent = pEnglish.get();
+ }
+ else
+ {
+ if ( !pAny )
+ {
+ pAny.reset( new LocaleDataWrapper( m_xContext, rLanguageTag ) );
+ eLastAnyLanguage = eLang;
+ }
+ else if ( eLastAnyLanguage != eLang )
+ {
+ pAny->setLanguageTag( rLanguageTag );
+ eLastAnyLanguage = eLang;
+ }
+ pCurrent = pAny.get();
+ }
+ eCurrentLanguage = eLang;
+ }
+
+ LanguageType getCurrentLanguage() const
+ { return eCurrentLanguage; }
+
+ const LocaleDataWrapper* get() const { return pCurrent; }
+ const LocaleDataWrapper* operator->() const { return get(); }
+ const LocaleDataWrapper& operator*() const { return *pCurrent; }
+};
+
+/** Load a calendar only if it's needed. Keep calendar for "en-US" locale
+ separately, as there can be alternation between locale dependent and
+ locale independent formats.
+ SvNumberformatter uses it upon switching locales.
+
+ @ATTENTION If the default ctor is used the init() method MUST be called
+ before accessing the calendar.
+ */
+class OnDemandCalendarWrapper
+{
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::lang::Locale aEnglishLocale;
+ css::lang::Locale aLocale;
+ mutable css::lang::Locale aLastAnyLocale;
+ mutable std::unique_ptr<CalendarWrapper> pEnglishPtr;
+ mutable std::unique_ptr<CalendarWrapper> pAnyPtr;
+
+public:
+ OnDemandCalendarWrapper()
+ {
+ LanguageTag aEnglishLanguageTag(LANGUAGE_ENGLISH_US);
+ aEnglishLocale = aEnglishLanguageTag.getLocale();
+ aLastAnyLocale = aEnglishLocale;
+ }
+
+ void init(
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::lang::Locale& rLocale
+ )
+ {
+ m_xContext = rxContext;
+ changeLocale( rLocale );
+ pEnglishPtr.reset();
+ pAnyPtr.reset();
+ }
+
+ void changeLocale( const css::lang::Locale& rLocale )
+ {
+ aLocale = rLocale;
+ }
+
+ CalendarWrapper* get() const
+ {
+ CalendarWrapper* pPtr;
+ if ( aLocale == aEnglishLocale )
+ {
+ if (!pEnglishPtr)
+ {
+ pEnglishPtr.reset( new CalendarWrapper( m_xContext ));
+ pEnglishPtr->loadDefaultCalendar( aEnglishLocale );
+ }
+ pPtr = pEnglishPtr.get();
+ }
+ else
+ {
+ if ( !pAnyPtr )
+ {
+ pAnyPtr.reset(new CalendarWrapper( m_xContext ));
+ pAnyPtr->loadDefaultCalendar(aLocale);
+ aLastAnyLocale = aLocale;
+ }
+ else if ( aLocale != aLastAnyLocale )
+ {
+ pAnyPtr->loadDefaultCalendar( aLocale );
+ aLastAnyLocale = aLocale;
+ }
+ pPtr = pAnyPtr.get();
+ }
+ return pPtr;
+ }
+
+};
+
+/** Load a transliteration only if it's needed.
+ SvNumberformatter uses it upon switching locales.
+ @ATTENTION If the default ctor is used the init() method MUST be called
+ before accessing the transliteration.
+ */
+class OnDemandTransliterationWrapper
+{
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ LanguageType eLanguage;
+ TransliterationFlags nType;
+ mutable std::unique_ptr<::utl::TransliterationWrapper>
+ pPtr;
+ mutable bool bValid;
+ bool bInitialized;
+
+public:
+ OnDemandTransliterationWrapper()
+ : eLanguage( LANGUAGE_SYSTEM )
+ , nType(TransliterationFlags::NONE)
+ , bValid(false)
+ , bInitialized(false)
+ {}
+
+ bool isInitialized() const { return bInitialized; }
+
+ void init(
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ LanguageType eLang
+ )
+ {
+ m_xContext = rxContext;
+ nType = TransliterationFlags::IGNORE_CASE;
+ changeLocale( eLang );
+ pPtr.reset();
+ bInitialized = true;
+ }
+
+ void changeLocale( LanguageType eLang )
+ {
+ bValid = false;
+ eLanguage = eLang;
+ }
+
+ const ::utl::TransliterationWrapper* get() const
+ {
+ if ( !bValid )
+ {
+ if ( !pPtr )
+ pPtr.reset( new ::utl::TransliterationWrapper( m_xContext, nType ) );
+ pPtr->loadModuleIfNeeded( eLanguage );
+ bValid = true;
+ }
+ return pPtr.get();
+ }
+
+ const ::utl::TransliterationWrapper* operator->() const { return get(); }
+};
+
+/** Load a native number service wrapper only if it's needed.
+ SvNumberformatter uses it.
+
+ @ATTENTION
+ If the default ctor is used the init() method MUST be called
+ before accessing the native number supplier.
+ */
+class OnDemandNativeNumberWrapper
+{
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ mutable std::unique_ptr<NativeNumberWrapper>
+ pPtr;
+
+public:
+ OnDemandNativeNumberWrapper()
+ {}
+
+ void init(
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext
+ )
+ {
+ m_xContext = rxContext;
+ pPtr.reset();
+ }
+
+ NativeNumberWrapper* get() const
+ {
+ if ( !pPtr )
+ pPtr.reset(new NativeNumberWrapper( m_xContext ));
+ return pPtr.get();
+ }
+
+};
+
+#endif // INCLUDED_SVL_ONDEMAND_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */