/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include /* 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 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 *get(); } }; /** 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 pEnglishPtr; mutable std::unique_ptr 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) , pPtr(nullptr) , 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 pPtr; public: OnDemandNativeNumberWrapper() : pPtr(nullptr) {} 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: */