From a07a5e1977f827981c86df65ca70c016a9363579 Mon Sep 17 00:00:00 2001 From: Iman Namvar Date: Mon, 12 Apr 2021 16:22:41 +0430 Subject: [PATCH 1/2] feat: Jalaali (Persian) Date input support --- Terminal.Gui/Views/DateField.cs | 79 ++++++++++++++++++++++++++++----- UICatalog/Scenarios/Text.cs | 6 ++- 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 14178e5729..6baf86d959 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -5,10 +5,10 @@ // // Licensed under the MIT license // +using NStack; using System; using System.Globalization; using System.Linq; -using NStack; namespace Terminal.Gui { /// @@ -25,6 +25,7 @@ public class DateField : TextField { string sepChar; string longFormat; string shortFormat; + bool isJalaali; int FieldLen { get { return isShort ? shortFieldLen : longFieldLen; } } string Format { get { return isShort ? shortFormat : longFormat; } } @@ -47,9 +48,11 @@ public class DateField : TextField { /// The y coordinate. /// Initial date contents. /// If true, shows only two digits for the year. - public DateField (int x, int y, DateTime date, bool isShort = false) : base (x, y, isShort ? 10 : 12, "") + /// If true, parse will convert jalaali input fo georgian date + public DateField (int x, int y, DateTime date, bool isShort = false, bool isJalaali = false) : base (x, y, isShort ? 10 : 12, "") { this.isShort = isShort; + this.isJalaali = isJalaali; Initialize (date); } @@ -62,9 +65,13 @@ public DateField () : this (DateTime.MinValue) { } /// Initializes a new instance of using layout. /// /// - public DateField (DateTime date) : base ("") + /// + public DateField (DateTime date, bool isJalaali = false) : base ("") { - this.isShort = true; + + this.isJalaali = isJalaali; + if (!isJalaali) + this.isShort = true; Width = FieldLen + 2; Initialize (date); } @@ -73,8 +80,8 @@ void Initialize (DateTime date) { CultureInfo cultureInfo = CultureInfo.CurrentCulture; sepChar = cultureInfo.DateTimeFormat.DateSeparator; - longFormat = GetLongFormat (cultureInfo.DateTimeFormat.ShortDatePattern); - shortFormat = GetShortFormat (longFormat); + longFormat = isJalaali ? $" yyyy{sepChar}MM{sepChar}dd" : GetLongFormat (cultureInfo.DateTimeFormat.ShortDatePattern); + shortFormat = isJalaali ? $" yy{sepChar}MM{sepChar}dd" : GetShortFormat (longFormat); CursorPosition = 1; Date = date; TextChanged += DateField_Changed; @@ -83,8 +90,10 @@ void Initialize (DateTime date) void DateField_Changed (ustring e) { try { + if (!DateTime.TryParseExact (GetDate (Text).ToString (), GetInvarianteFormat (), CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result)) Text = e; + } catch (Exception) { Text = e; } @@ -129,7 +138,12 @@ public DateTime Date { var oldData = date; date = value; - this.Text = value.ToString (Format); + if (isJalaali) { + + this.Text = ToJalaaliString (Format, date); + } else { + this.Text = value.ToString (Format); + } var args = new DateTimeEventArgs (oldData, value, Format); if (oldData != value) { OnDateChanged (args); @@ -137,6 +151,8 @@ public DateTime Date { } } + + /// /// Get or set the date format for the widget. /// @@ -202,11 +218,28 @@ bool SetText (ustring text) vals [idx] = day.ToString (); } else day = Int32.Parse (vals [idx].ToString ()); - string d = GetDate (month, day, year, frm); + DateTime result; + if (isJalaali) { + try { + PersianCalendar pc = new PersianCalendar (); + if (year < 10) { + year += 1400; + } + result = pc.ToDateTime (year, month, day, 12, 0, 0, 0); + year = result.Year; + month = result.Month; + day = result.Day; + } catch { + return false; + } + } else { + string d = GetDate (month, day, year, frm); + + if (!DateTime.TryParseExact (d, Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out result) || + !isValidDate) + return false; + } - if (!DateTime.TryParseExact (d, Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result) || - !isValidDate) - return false; Date = result; return true; } @@ -377,6 +410,28 @@ public virtual void OnDateChanged (DateTimeEventArgs args) { DateChanged?.Invoke (args); } + + string ToJalaaliString (string format, DateTime date) + { + if (string.IsNullOrEmpty (format)) format = " yyyy/MM/dd"; + PersianCalendar pc = new PersianCalendar (); + + + var year = pc.GetYear (date); + var month = pc.GetMonth (date); + var day = pc.GetDayOfMonth (date); + + + format = format.Replace ("yyyy", year.ToString (CultureInfo.InvariantCulture)); + format = format.Replace ("yy", (year % 100).ToString ("00", CultureInfo.InvariantCulture)); + format = format.Replace ("MM", month.ToString ("00", CultureInfo.InvariantCulture)); + format = format.Replace ("M", month.ToString (CultureInfo.InvariantCulture)); + format = format.Replace ("dd", day.ToString ("00", CultureInfo.InvariantCulture)); + format = format.Replace ("d", day.ToString (CultureInfo.InvariantCulture)); + + return format; + } + } /// @@ -386,7 +441,7 @@ public class DateTimeEventArgs : EventArgs { /// /// The old or value. /// - public T OldValue {get;} + public T OldValue { get; } /// /// The new or value. diff --git a/UICatalog/Scenarios/Text.cs b/UICatalog/Scenarios/Text.cs index 86f505a142..d43790f04b 100644 --- a/UICatalog/Scenarios/Text.cs +++ b/UICatalog/Scenarios/Text.cs @@ -61,12 +61,13 @@ public override void Setup () }; Win.Add (hexView); - var dateField = new DateField (System.DateTime.Now) { + var dateField = new DateField (System.DateTime.Now, isJalaali: true) { X = 1, Y = Pos.Bottom (hexView) + 1, Width = 20, //ColorScheme = Colors.Dialog, - IsShortFormat = false + IsShortFormat = false, + }; Win.Add (dateField); @@ -81,6 +82,7 @@ public override void Setup () dateField.TextChanged += (prev) => { labelMirroringDateField.Text = dateField.Text; }; + _timeField = new TimeField (DateTime.Now.TimeOfDay) { X = Pos.Right (labelMirroringDateField) + 5, From 12f636873022f0d5023817188342c532032d9775 Mon Sep 17 00:00:00 2001 From: Iman Namvar Date: Mon, 12 Apr 2021 16:23:22 +0430 Subject: [PATCH 2/2] fix: clean scenario Text input sample --- UICatalog/Scenarios/Text.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UICatalog/Scenarios/Text.cs b/UICatalog/Scenarios/Text.cs index d43790f04b..2b8923caf9 100644 --- a/UICatalog/Scenarios/Text.cs +++ b/UICatalog/Scenarios/Text.cs @@ -61,7 +61,7 @@ public override void Setup () }; Win.Add (hexView); - var dateField = new DateField (System.DateTime.Now, isJalaali: true) { + var dateField = new DateField (System.DateTime.Now) { X = 1, Y = Pos.Bottom (hexView) + 1, Width = 20,