using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Duplicati.Library.Main { /// /// Changes the current locale for all threads and for log messages in the current context. /// When disposed the changes are reset. /// public class LocaleChange : IDisposable { private static readonly string LOGTAG = Logging.Log.LogTagFromType(); private bool m_doResetLocale = false; private System.Globalization.CultureInfo m_resetLocale = null; private System.Globalization.CultureInfo m_resetLocaleUI = null; private IDisposable m_localizationContext = null; /// /// Change locale if newLocale is not null /// public LocaleChange(System.Globalization.CultureInfo newLocale) { if (newLocale == null) { return; } try { DoGetLocale(out m_resetLocale, out m_resetLocaleUI); m_doResetLocale = true; // Wrap the call to avoid loading issues for the setLocale method DoSetLocale(newLocale, newLocale); m_localizationContext = Localization.LocalizationService.TemporaryContext(newLocale); } catch (MissingMethodException ex) { m_doResetLocale = false; m_resetLocale = m_resetLocaleUI = null; Library.Logging.Log.WriteWarningMessage(LOGTAG, "LocaleChangeError", ex, Strings.Controller.FailedForceLocaleError(ex.Message)); } } /// /// Change locale if ForcedLocale is specified in options /// /// Command line options /// /// Thrown if specified locale was not found. /// public LocaleChange(Options options) : this(options.HasForcedLocale ? options.ForcedLocale : null) { } /// /// Change locale if 'force-locale' is specified in options dictionary /// /// Command line options /// /// Thrown if specified locale was not found. /// public LocaleChange(Dictionary options) : this(new Options(options)) { } public void Dispose() { if (m_doResetLocale) { // Wrap the call to avoid loading issues for the setLocale method DoSetLocale(m_resetLocale, m_resetLocaleUI); m_doResetLocale = false; m_resetLocale = null; m_resetLocaleUI = null; } if(m_localizationContext != null) { m_localizationContext.Dispose(); m_localizationContext = null; } } /// /// Attempts to get the locale, but delays linking to the calls as they are missing in some environments /// [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] private static void DoGetLocale(out System.Globalization.CultureInfo locale, out System.Globalization.CultureInfo uiLocale) { locale = System.Globalization.CultureInfo.DefaultThreadCurrentCulture; uiLocale = System.Globalization.CultureInfo.DefaultThreadCurrentUICulture; } /// /// Attempts to set the locale, but delays linking to the calls as they are missing in some environments /// [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] private static void DoSetLocale(System.Globalization.CultureInfo locale, System.Globalization.CultureInfo uiLocale) { System.Globalization.CultureInfo.DefaultThreadCurrentCulture = locale; System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = uiLocale; } } }