diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 3a7470dc1..154e43cc5 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -239,6 +239,7 @@ public override void Initialize() var pref = ViewModels.Preferences.Instance; SetLocale(pref.Locale); + Models.DateTimeFormat.UseCulture(pref.Locale); SetTheme(pref.Theme, pref.ThemeOverrides); SetFonts(pref.DefaultFontFamily, pref.MonospaceFontFamily); } diff --git a/src/Models/DateTimeFormat.cs b/src/Models/DateTimeFormat.cs index d313d56ae..43253e234 100644 --- a/src/Models/DateTimeFormat.cs +++ b/src/Models/DateTimeFormat.cs @@ -33,6 +33,18 @@ public static bool Use24Hours set; } = true; + public static int DayOfWeekStyle + { + get; + set; + } = 0; + + public static bool UseLocalizedCulture + { + get; + set; + } = true; + public string DateFormat { get; @@ -40,14 +52,37 @@ public string DateFormat public string Example { - get => DateTime.Now.ToString(DateFormat, _culture); + get => DateTime.Now.ToString(DateFormat, ActiveCulture); } - private static readonly CultureInfo _culture = CreateCulture(); + private static CultureInfo ActiveCulture => UseLocalizedCulture ? _localizedCulture : _invariantCulture; + + private static CultureInfo _localizedCulture = CreateCulture(CultureInfo.CurrentCulture); + private static readonly CultureInfo _invariantCulture = CreateCulture(CultureInfo.InvariantCulture); + + // Ties the localized day/month names to the application's selected language + // (e.g. locale key "el_GR"), instead of the operating-system culture. + public static void UseCulture(string localeKey) + { + var baseCulture = CultureInfo.CurrentCulture; + if (!string.IsNullOrEmpty(localeKey)) + { + try + { + baseCulture = CultureInfo.GetCultureInfo(localeKey.Replace('_', '-')); + } + catch (CultureNotFoundException) + { + // fall back to the operating-system culture + } + } + + _localizedCulture = CreateCulture(baseCulture); + } - private static CultureInfo CreateCulture() + private static CultureInfo CreateCulture(CultureInfo baseCulture) { - var culture = (CultureInfo)CultureInfo.CurrentCulture.Clone(); + var culture = (CultureInfo)baseCulture.Clone(); culture.DateTimeFormat.DateSeparator = "/"; culture.DateTimeFormat.TimeSeparator = ":"; return culture; @@ -67,11 +102,18 @@ public static string Format(ulong timestamp, bool dateOnly = false) public static string Format(DateTime localTime, bool dateOnly = false) { var actived = Supported[ActiveIndex]; + var dateFormat = DayOfWeekStyle switch + { + 1 => $"ddd {actived.DateFormat}", + 2 => $"dddd {actived.DateFormat}", + _ => actived.DateFormat, + }; + if (dateOnly) - return localTime.ToString(actived.DateFormat, _culture); + return localTime.ToString(dateFormat, ActiveCulture); - var format = Use24Hours ? $"{actived.DateFormat} HH:mm:ss" : $"{actived.DateFormat} hh:mm:ss tt"; - return localTime.ToString(format, _culture); + var format = Use24Hours ? $"{dateFormat} HH:mm:ss" : $"{dateFormat} hh:mm:ss tt"; + return localTime.ToString(format, ActiveCulture); } } } diff --git a/src/Resources/Locales/el_GR.axaml b/src/Resources/Locales/el_GR.axaml index 7f1da3c39..2e4b1b2e7 100644 --- a/src/Resources/Locales/el_GR.axaml +++ b/src/Resources/Locales/el_GR.axaml @@ -660,8 +660,12 @@ ΓΕΝΙΚΑ Έλεγχος για ενημερώσεις κατά την εκκίνηση Μορφή ημερομηνίας + Χωρίς ημέρα + Σύντομη ημέρα + Πλήρης ημέρα Ενεργοποίηση συμπαγών φακέλων στο δέντρο αλλαγών Γλώσσα + Τοπικές ημερομηνίες Commits ιστορικού Εμφάνιση της σελίδας `ΤΟΠΙΚΕΣ ΑΛΛΑΓΕΣ` από προεπιλογή Εμφάνιση της καρτέλας `ΑΛΛΑΓΕΣ` στις λεπτομέρειες commit από προεπιλογή diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 33456d92a..1364a8ff1 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -682,8 +682,12 @@ GENERAL Check for updates on startup Date Format + No day of week + Short day + Full day Enable compact folders in changes tree Language + Localized dates History Commits Show `LOCAL CHANGES` page by default Show `CHANGES` tab in commit detail by default diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index ce0942d4c..5e0d8da6c 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -36,8 +36,12 @@ public string Locale get => _locale; set { - if (SetProperty(ref _locale, value) && !_isLoading) - App.SetLocale(value); + if (SetProperty(ref _locale, value)) + { + Models.DateTimeFormat.UseCulture(value); + if (!_isLoading) + App.SetLocale(value); + } } } @@ -169,6 +173,34 @@ public bool Use24Hours } } + public int DayOfWeekStyle + { + get => Models.DateTimeFormat.DayOfWeekStyle; + set + { + if (value != Models.DateTimeFormat.DayOfWeekStyle && + value >= 0 && + value <= 2) + { + Models.DateTimeFormat.DayOfWeekStyle = value; + OnPropertyChanged(); + } + } + } + + public bool DateTimeUseLocalizedCulture + { + get => Models.DateTimeFormat.UseLocalizedCulture; + set + { + if (value != Models.DateTimeFormat.UseLocalizedCulture) + { + Models.DateTimeFormat.UseLocalizedCulture = value; + OnPropertyChanged(); + } + } + } + public bool UseFixedTabWidth { get => _useFixedTabWidth; diff --git a/src/Views/CommitTimeTextBlock.cs b/src/Views/CommitTimeTextBlock.cs index 66c4090ab..e19e49c4b 100644 --- a/src/Views/CommitTimeTextBlock.cs +++ b/src/Views/CommitTimeTextBlock.cs @@ -46,6 +46,30 @@ public int DateTimeFormat set => SetAndRaise(DateTimeFormatProperty, ref _dateTimeFormat, value); } + public static readonly DirectProperty DayOfWeekStyleProperty = + AvaloniaProperty.RegisterDirect( + nameof(DayOfWeekStyle), + static o => o.DayOfWeekStyle, + static (o, v) => o.DayOfWeekStyle = v); + + public int DayOfWeekStyle + { + get => _dayOfWeekStyle; + set => SetAndRaise(DayOfWeekStyleProperty, ref _dayOfWeekStyle, value); + } + + public static readonly DirectProperty UseLocalizedCultureProperty = + AvaloniaProperty.RegisterDirect( + nameof(UseLocalizedCulture), + static o => o.UseLocalizedCulture, + static (o, v) => o.UseLocalizedCulture = v); + + public bool UseLocalizedCulture + { + get => _useLocalizedCulture; + set => SetAndRaise(UseLocalizedCultureProperty, ref _useLocalizedCulture, value); + } + public static readonly DirectProperty TimestampProperty = AvaloniaProperty.RegisterDirect( nameof(Timestamp), @@ -83,7 +107,10 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang HorizontalAlignment = HorizontalAlignment.Center; } } - else if (change.Property == DateTimeFormatProperty || change.Property == Use24HoursProperty) + else if (change.Property == DateTimeFormatProperty || + change.Property == Use24HoursProperty || + change.Property == DayOfWeekStyleProperty || + change.Property == UseLocalizedCultureProperty) { if (ShowAsDateTime) SetCurrentValue(TextProperty, GetDisplayText()); @@ -174,6 +201,8 @@ private string GetDisplayText() private bool _showAsDateTime = true; private bool _use24Hours = true; private int _dateTimeFormat = 0; + private int _dayOfWeekStyle = 0; + private bool _useLocalizedCulture = true; private ulong _timestamp = 0; private DispatcherTimer _refreshTimer = null; } diff --git a/src/Views/DateTimePresenter.cs b/src/Views/DateTimePresenter.cs index eddfec96e..f741801a0 100644 --- a/src/Views/DateTimePresenter.cs +++ b/src/Views/DateTimePresenter.cs @@ -44,6 +44,30 @@ public int DateTimeFormat set => SetAndRaise(DateTimeFormatProperty, ref _dateTimeFormat, value); } + public static readonly DirectProperty DayOfWeekStyleProperty = + AvaloniaProperty.RegisterDirect( + nameof(DayOfWeekStyle), + static o => o.DayOfWeekStyle, + static (o, v) => o.DayOfWeekStyle = v); + + public int DayOfWeekStyle + { + get => _dayOfWeekStyle; + set => SetAndRaise(DayOfWeekStyleProperty, ref _dayOfWeekStyle, value); + } + + public static readonly DirectProperty UseLocalizedCultureProperty = + AvaloniaProperty.RegisterDirect( + nameof(UseLocalizedCulture), + static o => o.UseLocalizedCulture, + static (o, v) => o.UseLocalizedCulture = v); + + public bool UseLocalizedCulture + { + get => _useLocalizedCulture; + set => SetAndRaise(UseLocalizedCultureProperty, ref _useLocalizedCulture, value); + } + public static readonly DirectProperty TimestampProperty = AvaloniaProperty.RegisterDirect( nameof(Timestamp), @@ -73,6 +97,20 @@ public DateTimePresenter() Source = ViewModels.Preferences.Instance, Path = "DateTimeFormat" }); + + Bind(DayOfWeekStyleProperty, new Binding() + { + Mode = BindingMode.OneWay, + Source = ViewModels.Preferences.Instance, + Path = "DayOfWeekStyle" + }); + + Bind(UseLocalizedCultureProperty, new Binding() + { + Mode = BindingMode.OneWay, + Source = ViewModels.Preferences.Instance, + Path = "DateTimeUseLocalizedCulture" + }); } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) @@ -82,6 +120,8 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang if (change.Property == ShowDateOnlyProperty || change.Property == Use24HoursProperty || change.Property == DateTimeFormatProperty || + change.Property == DayOfWeekStyleProperty || + change.Property == UseLocalizedCultureProperty || change.Property == TimestampProperty) { var text = Models.DateTimeFormat.Format(Timestamp, ShowDateOnly); @@ -92,6 +132,8 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang private bool _showDateOnly = false; private bool _use24Hours = true; private int _dateTimeFormat = 0; + private int _dayOfWeekStyle = 0; + private bool _useLocalizedCulture = true; private ulong _timestamp = 0; } } diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 6aeb8c75c..c01139c43 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -206,6 +206,8 @@ Timestamp="{Binding AuthorTime, Mode=OneWay}" ShowAsDateTime="{Binding Source={x:Static vm:Preferences.Instance}, Path=!DisplayTimeAsPeriodInHistories, Mode=OneWay}" DateTimeFormat="{Binding Source={x:Static vm:Preferences.Instance}, Path=DateTimeFormat, Mode=OneWay}" + DayOfWeekStyle="{Binding Source={x:Static vm:Preferences.Instance}, Path=DayOfWeekStyle, Mode=OneWay}" + UseLocalizedCulture="{Binding Source={x:Static vm:Preferences.Instance}, Path=DateTimeUseLocalizedCulture, Mode=OneWay}" Use24Hours="{Binding Source={x:Static vm:Preferences.Instance}, Path=Use24Hours, Mode=OneWay}"/> @@ -226,6 +228,8 @@ Timestamp="{Binding CommitterTime, Mode=OneWay}" ShowAsDateTime="{Binding Source={x:Static vm:Preferences.Instance}, Path=!DisplayTimeAsPeriodInHistories, Mode=OneWay}" DateTimeFormat="{Binding Source={x:Static vm:Preferences.Instance}, Path=DateTimeFormat, Mode=OneWay}" + DayOfWeekStyle="{Binding Source={x:Static vm:Preferences.Instance}, Path=DayOfWeekStyle, Mode=OneWay}" + UseLocalizedCulture="{Binding Source={x:Static vm:Preferences.Instance}, Path=DateTimeUseLocalizedCulture, Mode=OneWay}" Use24Hours="{Binding Source={x:Static vm:Preferences.Instance}, Path=Use24Hours, Mode=OneWay}"/> diff --git a/src/Views/Preferences.axaml b/src/Views/Preferences.axaml index 6e6aee4f1..ba54a7ecd 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -52,19 +52,27 @@ Text="{DynamicResource Text.Preferences.General.Locale}" HorizontalAlignment="Right" Margin="0,0,16,0"/> - + + + + + - + - + + + + + +