diff --git a/src/Calculator.Shared/Calculator.Shared.projitems b/src/Calculator.Shared/Calculator.Shared.projitems
index 24599449..6004fdf4 100644
--- a/src/Calculator.Shared/Calculator.Shared.projitems
+++ b/src/Calculator.Shared/Calculator.Shared.projitems
@@ -39,6 +39,7 @@
+
@@ -48,6 +49,7 @@
+
diff --git a/src/Calculator.Shared/Common/DateCalculator.cs b/src/Calculator.Shared/Common/DateCalculator.cs
new file mode 100644
index 00000000..ab4433a5
--- /dev/null
+++ b/src/Calculator.Shared/Common/DateCalculator.cs
@@ -0,0 +1,377 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Windows.Globalization;
+
+namespace CalculatorApp.Common.DateCalculation
+{
+ [Flags]
+ public enum DateUnit
+ {
+ Year = 0x01,
+ Month = 0x02,
+ Week = 0x04,
+ Day = 0x08
+ };
+
+ // Struct to store the difference between two Dates in the form of Years, Months , Weeks
+ public struct DateDifference
+ {
+ public int year;
+ public int month;
+ public int week;
+ public int day;
+ };
+
+ public class DateCalculationEngine
+ {
+ const ulong c_millisecond = 10000;
+ const ulong c_second = 1000 * c_millisecond;
+ const ulong c_minute = 60 * c_second;
+ const ulong c_hour = 60 * c_minute;
+ const ulong c_day = 24 * c_hour;
+
+ const int c_unitsOfDate = 4; // Units Year,Month,Week,Day
+ const int c_unitsGreaterThanDays = 3; // Units Greater than Days (Year/Month/Week) 3
+ const int c_daysInWeek = 7;
+
+ private Calendar m_calendar;
+
+ public DateCalculationEngine(string calendarIdentifier)
+ {
+ m_calendar = new Calendar();
+ m_calendar.ChangeTimeZone("UTC");
+ m_calendar.ChangeCalendarSystem(calendarIdentifier);
+ }
+
+ // Adding Duration to a Date
+ // Returns: True if function succeeds to calculate the date else returns False
+ public bool AddDuration( DateTime startDate, DateDifference duration, out DateTime endDate)
+ {
+ var currentCalendarSystem = m_calendar.GetCalendarSystem();
+
+ try
+ {
+ m_calendar.SetDateTime(startDate);
+
+ // The Japanese Era system can have multiple year partitions within the same year.
+ // For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
+ // The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results
+ // in a date in Heisei 31. To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date
+ // math, and then convert back to the Japanese era system. This works because the Japanese era system maintains the same year/month boundaries and
+ // durations as the Gregorian system and is only different in display value.
+ if (currentCalendarSystem == CalendarIdentifiers.Japanese)
+ {
+ m_calendar.ChangeCalendarSystem(CalendarIdentifiers.Gregorian);
+ }
+
+ if (duration.year != 0)
+ {
+ m_calendar.AddYears(duration.year);
+ }
+ if (duration.month != 0)
+ {
+ m_calendar.AddMonths(duration.month);
+ }
+ if (duration.day != 0)
+ {
+ m_calendar.AddDays(duration.day);
+ }
+
+ endDate = m_calendar.GetDateTime().DateTime;
+ }
+ catch (ArgumentException ex)
+ {
+ // ensure that we revert to the correct calendar system
+ m_calendar.ChangeCalendarSystem(currentCalendarSystem);
+
+ // Do nothing
+ endDate = default(DateTime);
+ return false;
+ }
+
+ m_calendar.ChangeCalendarSystem(currentCalendarSystem);
+
+ return true;
+ }
+
+ // Subtracting Duration from a Date
+ // Returns: True if function succeeds to calculate the date else returns False
+ public bool SubtractDuration( DateTime startDate, DateDifference duration, out DateTime endDate)
+ {
+ var currentCalendarSystem = m_calendar.GetCalendarSystem();
+
+ // For Subtract the Algorithm is different than Add. Here the smaller units are subtracted first
+ // and then the larger units.
+ try
+ {
+ m_calendar.SetDateTime(startDate);
+
+ // The Japanese Era system can have multiple year partitions within the same year.
+ // For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
+ // The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results
+ // in a date in Heisei 31. To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date
+ // math, and then convert back to the Japanese era system. This works because the Japanese era system maintains the same year/month boundaries and
+ // durations as the Gregorian system and is only different in display value.
+ if (currentCalendarSystem == CalendarIdentifiers.Japanese)
+ {
+ m_calendar.ChangeCalendarSystem(CalendarIdentifiers.Gregorian);
+ }
+
+ if (duration.day != 0)
+ {
+ m_calendar.AddDays(-duration.day);
+ }
+ if (duration.month != 0)
+ {
+ m_calendar.AddMonths(-duration.month);
+ }
+ if (duration.year != 0)
+ {
+ m_calendar.AddYears(-duration.year);
+ }
+ endDate = m_calendar.GetDateTime().DateTime;
+ }
+ catch (ArgumentException ex)
+ {
+ // ensure that we revert to the correct calendar system
+ m_calendar.ChangeCalendarSystem(currentCalendarSystem);
+
+ // Do nothing
+ endDate = default(DateTime);
+ return false;
+ }
+
+ m_calendar.ChangeCalendarSystem(currentCalendarSystem);
+
+ // Check that the UniversalTime value is not negative
+ return (endDate.ToUniversalTime().Ticks >= 0);
+ }
+
+ // Calculate the difference between two dates
+ public void GetDateDifference( DateTime date1, DateTime date2, DateUnit outputFormat, out DateDifference difference)
+ {
+ DateTime startDate;
+ DateTime endDate;
+ DateTime pivotDate;
+ DateTime tempPivotDate;
+ uint daysDiff = 0;
+ uint[] differenceInDates = new uint[c_unitsOfDate];
+
+ if (date1.ToUniversalTime() < date2.ToUniversalTime())
+ {
+ startDate = date1;
+ endDate = date2;
+ }
+ else
+ {
+ startDate = date2;
+ endDate = date1;
+ }
+
+ pivotDate = startDate;
+
+ daysDiff = (uint)GetDifferenceInDays(startDate, endDate);
+
+ // If output has units other than days
+ // 0th bit: Year, 1st bit: Month, 2nd bit: Week, 3rd bit: Day
+ if (((int)(outputFormat) & 7) != 0)
+ {
+ uint daysInMonth;
+ uint approximateDaysInYear;
+
+ // If we're unable to calculate the days-in-month or days-in-year, we'll leave the values at 0.
+ if (TryGetCalendarDaysInMonth(startDate, out daysInMonth) && TryGetCalendarDaysInYear(endDate, out approximateDaysInYear))
+ {
+ uint[] daysIn = new uint[c_unitsOfDate] { approximateDaysInYear, daysInMonth, c_daysInWeek, 1 };
+
+ for (int unitIndex = 0; unitIndex < c_unitsGreaterThanDays; unitIndex++)
+ {
+ tempPivotDate = pivotDate;
+
+ // Check if the bit flag is set for the date unit
+ DateUnit dateUnit = (DateUnit)(1 << unitIndex);
+
+ if ((int)(outputFormat & dateUnit) != 0)
+ {
+ bool isEndDateHit = false;
+ differenceInDates[unitIndex] = (daysDiff / daysIn[unitIndex]);
+
+ if (differenceInDates[unitIndex] != 0)
+ {
+ try
+ {
+ pivotDate = AdjustCalendarDate(pivotDate, dateUnit, (int)(differenceInDates[unitIndex]));
+ }
+ catch (ArgumentException)
+ {
+ // Operation failed due to out of bound result
+ // Do nothing
+ differenceInDates[unitIndex] = 0;
+ }
+ }
+
+ int tempDaysDiff;
+
+ do
+ {
+ tempDaysDiff = GetDifferenceInDays(pivotDate, endDate);
+
+ if (tempDaysDiff < 0)
+ {
+ // pivotDate has gone over the end date; start from the beginning of this unit
+ differenceInDates[unitIndex] -= 1;
+ pivotDate = tempPivotDate;
+ pivotDate = AdjustCalendarDate(pivotDate, dateUnit, (int)(differenceInDates[unitIndex]));
+ isEndDateHit = true;
+ }
+ else if (tempDaysDiff > 0)
+ {
+ if (isEndDateHit)
+ {
+ // This is the closest the pivot can get to the end date for this unit
+ break;
+ }
+
+ // pivotDate is still below the end date
+ try
+ {
+ pivotDate = AdjustCalendarDate(pivotDate, dateUnit, 1);
+ differenceInDates[unitIndex] += 1;
+ }
+ catch (ArgumentException)
+ {
+ // handling for 31st Dec, 9999 last valid date
+ // Do nothing - break out
+ break;
+ }
+ }
+ } while (tempDaysDiff != 0); // dates are the same - exit the loop
+
+ tempPivotDate = AdjustCalendarDate(tempPivotDate, dateUnit, (int)(differenceInDates[unitIndex]));
+ pivotDate = tempPivotDate;
+ daysDiff = (uint)GetDifferenceInDays(pivotDate, endDate);
+ }
+ }
+ }
+ }
+
+ differenceInDates[3] = daysDiff;
+
+ difference.year = (int)differenceInDates[0];
+ difference.month = (int)differenceInDates[1];
+ difference.week = (int)differenceInDates[2];
+ difference.day = (int)differenceInDates[3];
+ }
+
+ // Private Methods
+
+ // Gets number of days between the two date time values
+ int GetDifferenceInDays(DateTime date1, DateTime date2)
+ {
+ // A tick is defined as the number of 100 nanoseconds
+ long ticksDifference = date2.ToUniversalTime().Ticks - date1.ToUniversalTime().Ticks;
+ return (int)(ticksDifference / (long)(c_day));
+ }
+
+ // Gets number of Calendar days in the month in which this date falls.
+ // Returns true if successful, false otherwise.
+ bool TryGetCalendarDaysInMonth( DateTime date, out uint daysInMonth)
+ {
+ daysInMonth = 0;
+ bool result = false;
+ m_calendar.SetDateTime(date);
+
+ // NumberOfDaysInThisMonth returns -1 if unknown.
+ int daysInThisMonth = m_calendar.NumberOfDaysInThisMonth;
+ if (daysInThisMonth != -1)
+ {
+ daysInMonth = (uint)(daysInThisMonth);
+ result = true;
+ }
+
+ return result;
+ }
+
+ // Gets number of Calendar days in the year in which this date falls.
+ // Returns true if successful, false otherwise.
+ bool TryGetCalendarDaysInYear( DateTime date, out uint daysInYear)
+ {
+ daysInYear = 0;
+ bool result = false;
+ uint days = 0;
+
+ m_calendar.SetDateTime(date);
+
+ // NumberOfMonthsInThisYear returns -1 if unknown.
+ int monthsInYear = m_calendar.NumberOfMonthsInThisYear;
+ if (monthsInYear != -1)
+ {
+ bool monthResult = true;
+
+ // Not all years begin with Month 1.
+ int firstMonthThisYear = m_calendar.FirstMonthInThisYear;
+ for (int month = 0; month < monthsInYear; month++)
+ {
+ m_calendar.Month = firstMonthThisYear + month;
+
+ // NumberOfDaysInThisMonth returns -1 if unknown.
+ int daysInMonth = m_calendar.NumberOfDaysInThisMonth;
+ if (daysInMonth == -1)
+ {
+ monthResult = false;
+ break;
+ }
+
+ days += (uint)daysInMonth;
+ }
+
+ if (monthResult)
+ {
+ daysInYear = days;
+ result = true;
+ }
+ }
+
+ return result;
+ }
+
+ // Adds/Subtracts certain value for a particular date unit
+ DateTime AdjustCalendarDate(DateTime date, DateUnit dateUnit, int difference)
+ {
+ m_calendar.SetDateTime(date);
+
+ // The Japanese Era system can have multiple year partitions within the same year.
+ // For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
+ // The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results in
+ // a date in Heisei 31. To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date math,
+ // and then convert back to the Japanese era system. This works because the Japanese era system maintains the same year/month boundaries and durations as
+ // the Gregorian system and is only different in display value.
+ var currentCalendarSystem = m_calendar.GetCalendarSystem();
+ if (currentCalendarSystem == CalendarIdentifiers.Japanese)
+ {
+ m_calendar.ChangeCalendarSystem(CalendarIdentifiers.Gregorian);
+ }
+
+ switch (dateUnit)
+ {
+ case DateUnit.Year:
+ m_calendar.AddYears(difference);
+ break;
+ case DateUnit.Month:
+ m_calendar.AddMonths(difference);
+ break;
+ case DateUnit.Week:
+ m_calendar.AddWeeks(difference);
+ break;
+ }
+
+ m_calendar.ChangeCalendarSystem(currentCalendarSystem);
+
+ return m_calendar.GetDateTime().DateTime;
+ }
+ }
+}
diff --git a/src/Calculator.Shared/Common/LocalizationService.cs b/src/Calculator.Shared/Common/LocalizationService.cs
index 49ebcd44..e715fd9d 100644
--- a/src/Calculator.Shared/Common/LocalizationService.cs
+++ b/src/Calculator.Shared/Common/LocalizationService.cs
@@ -379,7 +379,7 @@ namespace CalculatorApp.Common
// as configured by running intl.cpl.
//
// This helper function creates a DateTimeFormatter with a TwentyFour hour clock
- DateTimeFormatter GetRegionalSettingsAwareDateTimeFormatter( string format)
+ public static DateTimeFormatter GetRegionalSettingsAwareDateTimeFormatter( string format)
{
IEnumerable languageIdentifiers = GetLanguageIdentifiers();
if (languageIdentifiers == null)
@@ -392,75 +392,39 @@ namespace CalculatorApp.Common
// If successful, returns a formatter that respects the user's regional format settings,
// as configured by running intl.cpl.
- DateTimeFormatter GetRegionalSettingsAwareDateTimeFormatter( string format, string calendarIdentifier, string clockIdentifier)
+ public static DateTimeFormatter GetRegionalSettingsAwareDateTimeFormatter( string format, string calendarIdentifier, string clockIdentifier)
{
- // UNO TODO
- //IIterable languageIdentifiers = GetLanguageIdentifiers();
- //if (languageIdentifiers == null)
- //{
- // languageIdentifiers = ApplicationLanguages.Languages;
- //}
+ IEnumerable languageIdentifiers = GetLanguageIdentifiers();
+ if (languageIdentifiers == null)
+ {
+ languageIdentifiers = ApplicationLanguages.Languages;
+ }
- //return new DateTimeFormatter(format, languageIdentifiers, GlobalizationPerences.HomeGeographicRegion, calendarIdentifier, clockIdentifier);
-
- throw new NotImplementedException();
+ return new DateTimeFormatter(format, languageIdentifiers, GlobalizationPreferences.HomeGeographicRegion, calendarIdentifier, clockIdentifier);
}
- public CurrencyFormatter GetRegionalSettingsAwareCurrencyFormatter()
+ public static CurrencyFormatter GetRegionalSettingsAwareCurrencyFormatter()
{
- // UNO TODO
- //string userCurrency =
- // (GlobalizationPreferences.Currencies.Size > 0) ? GlobalizationPreferences.Currencies.GetAt(0) : string(DefaultCurrencyCode.data());
+ string userCurrency =
+ (GlobalizationPreferences.Currencies.Count > 0) ? GlobalizationPreferences.Currencies[0] : DefaultCurrencyCode;
- //IIterable languageIdentifiers = GetLanguageIdentifiers();
- //if (languageIdentifiers == null)
- //{
- // languageIdentifiers = ApplicationLanguages.Languages;
- //}
+ IEnumerable languageIdentifiers = GetLanguageIdentifiers();
+ if (languageIdentifiers == null)
+ {
+ languageIdentifiers = ApplicationLanguages.Languages;
+ }
- //var currencyFormatter = new CurrencyFormatter(userCurrency, languageIdentifiers, GlobalizationPerences.HomeGeographicRegion);
+ var currencyFormatter = new CurrencyFormatter(userCurrency, languageIdentifiers, GlobalizationPreferences.HomeGeographicRegion);
- //int fractionDigits = LocalizationSettings.GetInstance().GetCurrencyTrailingDigits();
- //currencyFormatter.FractionDigits = fractionDigits;
+ int fractionDigits = LocalizationSettings.GetInstance().GetCurrencyTrailingDigits();
+ currencyFormatter.FractionDigits = fractionDigits;
- //return currencyFormatter;
-
- throw new NotImplementedException();
+ return currencyFormatter;
}
static IEnumerable GetLanguageIdentifiers()
- {
-#if !HAS_UNO
- //char currentLocale[LOCALE_NAME_MAX_LENGTH] = {};
- //int result = GetUserDefaultLocaleName(currentLocale, LOCALE_NAME_MAX_LENGTH);
- //if (result != 0)
- //{
- // // GetUserDefaultLocaleName may return an invalid bcp47 language tag with trailing non-BCP47 friendly characters,
- // // which if present would start with an underscore, for example sort order
- // // (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd373814(v=vs.85).aspx).
- // // Therefore, if there is an underscore in the locale name, trim all characters from the underscore onwards.
- // WCHAR* underscore = wcschr(currentLocale, '_');
- // if (underscore != null)
- // {
- // *underscore = '\0';
- // }
-
- // string localestring = new String(currentLocale);
- // // validate if the locale we have is valid
- // // otherwise we fallback to the default.
- // if (Language.IsWellFormed(localeString))
- // {
- // var languageList = new Vector();
- // languageList.Append(localeString);
- // return languageList;
- // }
- //}
-
- //return null;
- yield break;
-#else
- yield break;
-#endif
+ {
+ return GlobalizationPreferences.Languages;
}
// Resources for the engine use numbers as keys. It's inconvenient, but also difficult to
diff --git a/src/Calculator.Shared/Common/LocalizationSettings.cs b/src/Calculator.Shared/Common/LocalizationSettings.cs
index 5fe8f6b4..902d00e8 100644
--- a/src/Calculator.Shared/Common/LocalizationSettings.cs
+++ b/src/Calculator.Shared/Common/LocalizationSettings.cs
@@ -128,17 +128,16 @@ namespace CalculatorApp
m_digitSymbols[i] = i.ToString(NumberFormatInfo.CurrentInfo)[0];
}
- // As CalcEngine only supports the first character of the decimal separator,
- // Only first character of the decimal separator string is supported.
- m_decimalSeparator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator[0];
+ // As CalcEngine only supports the first character of the decimal separator,
+ // Only first character of the decimal separator string is supported.
+ m_decimalSeparator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator[0];
m_numberGroupSeparator = NumberFormatInfo.CurrentInfo.NumberGroupSeparator[0];
m_numberGrouping = ""; // UNO TODO https://docs.microsoft.com/en-us/windows/desktop/Intl/locale-sgrouping
m_listSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
m_currencyTrailingDigits = NumberFormatInfo.CurrentInfo.CurrencyDecimalDigits;
m_currencySymbolPrecedence = ~(NumberFormatInfo.CurrentInfo.CurrencyPositivePattern) & 1;
-
- m_calendarIdentifier = "";//CultureInfo.CurrentCulture.DateTimeFormat.Calendar.ToString();
-
+ m_resolvedName = CultureInfo.CurrentCulture.Name;
+ m_calendarIdentifier = new Windows.Globalization.Calendar().GetCalendarSystem();
m_firstDayOfWeek = (Windows.Globalization.DayOfWeek)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
#endif
}
@@ -155,7 +154,7 @@ namespace CalculatorApp
return m_localizationSettings;
}
- string GetLocaleName()
+ public string GetLocaleName()
{
return m_resolvedName;
}
@@ -326,7 +325,7 @@ namespace CalculatorApp
return m_listSeparator;
}
- Windows.Globalization.DayOfWeek GetFirstDayOfWeek()
+ public Windows.Globalization.DayOfWeek GetFirstDayOfWeek()
{
return m_firstDayOfWeek;
}
diff --git a/src/Calculator.Shared/Common/TraceLogger.cs b/src/Calculator.Shared/Common/TraceLogger.cs
new file mode 100644
index 00000000..8b769748
--- /dev/null
+++ b/src/Calculator.Shared/Common/TraceLogger.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Windows.Globalization;
+using CalculatorApp.Common;
+
+namespace CalculatorApp
+{
+ public class TraceLogger
+ {
+ private static TraceLogger _instance = new TraceLogger();
+ public static TraceLogger GetInstance() => _instance;
+
+
+ public bool GetTraceLoggingProviderEnabled() => false;
+
+ public void LogAppLaunchStart() {}
+ public void LogAppLaunchComplete() {}
+ public void LogAppResumeComplete() {}
+ //public void LogOnAppLaunch(std::wstring_view previousExecutionState) {}
+ public void LogMemoryClearAll(int i) {}
+ public void LogBitFlipPaneClicked() {}
+ public void LogBitFlipUsed() {}
+ public void LogHistoryBodyOpened() {}
+ public void LogHistoryItemLoadBegin() {}
+ public void LogHistoryItemLoadEnd(uint i) {}
+ public void LogHistoryFlyoutOpenBegin(uint i) {}
+ public void LogHistoryFlyoutOpenEnd(int i) {}
+ public void LogCalculatorModeViewed(ViewMode mode, int i) {}
+ public void LogDateCalculatorModeViewed(ViewMode mode, int i) {}
+ public void LogConverterModeViewed(ViewMode mode, int i) {}
+ public void LogModeChangeBegin(ViewMode oldMode, ViewMode newMode, int i) {}
+ public void LogModeChangeEnd(ViewMode mode, int i) {}
+ public void LogClearHistory() {}
+ public void InsertintoMemoryMap(int i, bool b1, bool b2, bool b3) {}
+ public void UpdateMemoryMap(int i1, int i2, bool b1, bool b2, bool b3) {}
+ public void DeleteFromMemoryMap(int i1, int i2) {}
+ public void LogMemoryUsed(int i1, uint i2, bool b1, bool b2, bool b3, uint i4) {}
+ public void LogMultipleMemoryUsed(uint i1, uint i2) {}
+ public void LogSingleMemoryUsed(uint i) {}
+ //public void LogSharedMemoryUsed(std::wstring_view, std::wstring_view, uint i) {}
+ public void LogMemoryBodyOpened() {}
+ public void LogMemoryFlyoutOpenBegin(uint i) {}
+ //public void LogDebug(std::wstring_view debugData) {}
+ public void LogMemoryFlyoutOpenEnd(uint i) {}
+ //public void LogInvalidPastedInputOccurred(std::wstring_view reason, ViewMode mode, int ProgrammerNumberBase, int bitLengthType) {}
+ public void LogValidInputPasted(ViewMode mode) {}
+ public void UpdateFunctionUsage(int func) {}
+ public void LogFunctionUsage(int i) {}
+ public void InitFunctionLogArray() {}
+ public void LogBitLengthButtonUsed(int windowId) {}
+ public void LogRadixButtonUsed(int windowId) {}
+ public void LogAngleButtonUsed(int windowId) {}
+ public void LogHypButtonUsed(int windowId) {}
+ public void LogNewWindowCreationBegin(int windowId) {}
+ public void LogNewWindowCreationEnd(int windowId) {}
+ //public void LogError(std::wstring_view errorString) {}
+ public void LogPrelaunchedAppActivatedByUser() {}
+ public void LogAppPrelaunchedBySystem() {}
+ //public void UpdateWindowCount(size_t windowCount) {}
+ public bool UpdateWindowIdLog(int windowId) => true;
+ public void LogMaxWindowCount() {}
+ public void LogWindowActivated() {}
+ public void LogWindowLaunched() {}
+ public void LogUserRequestedRefreshFailed() {}
+ //public void LogConversionResult(std::wstring_view fromValue, std::wstring_view fromUnit, std::wstring_view toValue, std::wstring_view toUnit) {}
+ public void LogAboutFlyoutOpened() {}
+ public void LogNavBarOpened() {}
+ public void LogViewClosingTelemetry(int i) {}
+ public void LogCoreWindowWasNull() {}
+
+ // Trace methods for Date Calculator usage
+ public void LogDateDifferenceModeUsed(int windowId) {}
+ public void LogDateAddSubtractModeUsed(int windowId, bool isAddMode) {}
+ public void LogDateClippedTimeDifferenceFound(Calendar today, DateTime clippedTime) {}
+
+ //public void LogStandardException(std::wstring_view functionName, _In_ const std::exception& e) {}
+ //public void LogWinRTException(std::wstring_view functionName, _In_ winrt::hresult_error const& e) {}
+ //public void LogPlatformException(std::wstring_view functionName, _In_ Platform::Exception ^ e) {}
+ }
+}
diff --git a/src/Calculator.Shared/ViewModels/ApplicationViewModel.cs b/src/Calculator.Shared/ViewModels/ApplicationViewModel.cs
index 2069defe..b2b609d4 100644
--- a/src/Calculator.Shared/ViewModels/ApplicationViewModel.cs
+++ b/src/Calculator.Shared/ViewModels/ApplicationViewModel.cs
@@ -35,9 +35,8 @@ namespace CalculatorApp.ViewModel
private StandardCalculatorViewModel m_CalculatorViewModel;
public StandardCalculatorViewModel CalculatorViewModel { get => m_CalculatorViewModel; set { m_CalculatorViewModel = value; RaisePropertyChanged("CalculatorViewModel"); } }
- // UNO TODO
- //private DateCalculatorViewModel m_DateCalcViewModel;
- //public DateCalculatorViewModel DateCalcViewModel { get => m_DateCalcViewModel; set { m_DateCalcViewModel = value; RaisePropertyChanged("DateCalcViewModel"); } }
+ private DateCalculatorViewModel m_DateCalcViewModel;
+ public DateCalculatorViewModel DateCalcViewModel { get => m_DateCalcViewModel; set { m_DateCalcViewModel = value; RaisePropertyChanged("DateCalcViewModel"); } }
// UNO TODO
@@ -160,12 +159,11 @@ namespace CalculatorApp.ViewModel
else if (NavCategory.IsDateCalculatorViewMode(m_mode))
{
// TraceLogger.GetInstance().LogDateCalculatorModeViewed(m_mode, ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()));
- // UNO TODO
- //if (m_DateCalcViewModel == null)
- //{
- // m_DateCalcViewModel = new DateCalculatorViewModel();
- //}
- }
+ if (m_DateCalcViewModel == null)
+ {
+ m_DateCalcViewModel = new DateCalculatorViewModel();
+ }
+ }
else if (NavCategory.IsConverterViewMode(m_mode))
{
// UNO TODO
@@ -200,12 +198,13 @@ namespace CalculatorApp.ViewModel
//{
// ConverterViewModel.OnCopyCommand(parameter);
//}
- //else if (NavCategory.IsDateCalculatorViewMode(m_mode))
- //{
- // DateCalcViewModel.OnCopyCommand(parameter);
- //}
//else
- {
+ if (NavCategory.IsDateCalculatorViewMode(m_mode))
+ {
+ DateCalcViewModel.OnCopyCommand(parameter);
+ }
+ else
+ {
CalculatorViewModel.OnCopyCommand(parameter);
}
}
diff --git a/src/Calculator.Shared/ViewModels/DateCalculatorViewModel.cs b/src/Calculator.Shared/ViewModels/DateCalculatorViewModel.cs
index c7778222..11c385a2 100644
--- a/src/Calculator.Shared/ViewModels/DateCalculatorViewModel.cs
+++ b/src/Calculator.Shared/ViewModels/DateCalculatorViewModel.cs
@@ -1,531 +1,651 @@
-//using System;
-//using System.Collections.Generic;
-//using System.ComponentModel;
-//using System.Text;
-//using Windows.UI.Xaml.Data;
-//using Windows.Globalization;
-//using CalculatorApp.Common;
-//using Windows.Globalization.DateTimeFormatting;
-//using CalculatorApp.Common.DateCalculation;
-//using Windows.Foundation;
-//using Platform.Collections;
-//using System.Numerics;
-
-//namespace WindowsCalculator.Shared.ViewModels
-//{
-// /* MAX?
-// {
-// StringReference StrDateDiffResult(L"StrDateDiffResult");
-// StringReference StrDateDiffResultAutomationName(L"StrDateDiffResultAutomationName");
-// StringReference StrDateDiffResultInDays(L"StrDateDiffResultInDays");
-// StringReference StrDateResult(L"StrDateResult");
-// StringReference StrDateResultAutomationName(L"StrDateResultAutomationName");
-// StringReference IsDiffInDays(L"IsDiffInDays");
-// }
-// */
-
-// [Bindable]
-// public sealed class DateCalculatorViewModel : INotifyPropertyChanged
-// {
-// // Private members
-// private DateCalculationEngine m_dateCalcEngine;
-// private DateUnit m_daysOutputFormat;
-// private DateUnit m_allDateUnitsOutputFormat;
-// private DateTimeFormatter m_dateTimeFormatter;
-// private string m_listSeparator;
-
-// private bool m_isOutOfBound;
-// private Vector m_offsetValues;
-// private DateTime m_fromDate;
-// private DateTime m_toDate;
-// private DateTime m_startDate;
-// private DateTime m_dateResult;
-// private DateDifference m_dateDiffResult;
-// private DateDifference m_dateDiffResultInDays;
-
-// public DateCalculatorViewModel()
-// {
-// m_IsDateDiffMode = true;
-// m_IsAddMode = true;
-// m_isOutOfBound = false;
-// m_DaysOffset = 0;
-// m_MonthsOffset = 0;
-// m_YearsOffset = 0;
-// m_StrDateDiffResult = "";
-// m_StrDateDiffResultAutomationName = "";
-// m_StrDateDiffResultInDays = "";
-// m_StrDateResult = "";
-// m_StrDateResultAutomationName = "";
-// m_fromDate = 0;
-// m_toDate = 0;
-// m_startDate = 0;
-// m_dateResult = 0;
-
-// var localizationSettings = LocalizationSettings.GetInstance();
-
-// // Initialize Date Output format instances
-// InitializeDateOutputFormats(localizationSettings.GetCalendarIdentifier());
-
-// // Initialize Date Calc engine
-// m_dateCalcEngine = make_shared(localizationSettings.GetCalendarIdentifier());
-
-// // Initialize dates of DatePicker controls to today's date
-// var calendar = new Calendar();
-// var today = calendar.GetDateTime();
-
-// // FromDate and ToDate should be clipped (adjusted to a consistent hour in UTC)
-// m_fromDate = today;
-// m_toDate = today;
-// FromDate = ClipTime(today);
-// ToDate = ClipTime(today);
-
-// // StartDate should not be clipped
-// StartDate = today;
-// m_dateResult = today;
-
-// // Initialize the list separator delimiter appended with a space at the end, e.g. ", "
-// // This will be used for date difference formatting: Y years, M months, W weeks, D days
-// m_listSeparator = new String((localizationSettings.GetListSeparator() + " ").ToString());
-
-// // Initialize the output results
-// UpdateDisplayResult();
-
-// m_offsetValues = new Vector ();
-
-// for (int i = 0; i <= c_maxOffsetValue; i++)
-// {
-// // MAX?
-// string numberStr = i.ToString();
-// localizationSettings.LocalizeDisplayValue(numberStr);
-// m_offsetValues.Append(numberStr.ToString());
-// }
-
-// /* In the ClipTime function, we used to change timezone to UTC before clipping the time.
-// The comment from the previous delopers said this was done to eliminate the effects of
-// Daylight Savings Time. We can't think of a good reason why this change in timezone is
-// necessary and did find bugs related to the change, therefore, we have removed the
-// change. Just in case, we will see if the clipped time is ever a different day from the
-// original day, which would hopefully indicate the change in timezone was actually
-// necessary. We will collect telemetry if we find this case. If we don't see any
-// telemetry events after the application has been used for some time, we will feel safe
-// and can remove this function. */
-// DayOfWeek trueDayOfWeek = calendar->DayOfWeek;
-
-// DateTime clippedTime = ClipTime(today);
-// calendar.SetDateTime(clippedTime);
-
-// if (calendar->DayOfWeek != trueDayOfWeek)
-// {
-// // MAX?
-// calendar.SetDateTime(today);
-// TraceLogger.GetInstance().LogDateClippedTimeDifferenceFound(
-// from_cx(calendar),
-// DateTime{ TimeSpan{ clippedTime.UniversalTime } });
-// }
-// }
-
-// static void CheckClipTimeSameDay(Calendar reference)
-// {
-
-// }
-
-// private bool IsOutOfBound
-// {
-// get { return m_isOutOfBound; }
-// set
-// {
-// m_isOutOfBound = value;
-// UpdateDisplayResult();
-// }
-// }
-
-// private DateDifference DateDiffResult
-// {
-// get { return m_dateDiffResult; }
-// set {
-// m_dateDiffResult = value;
-// UpdateDisplayResult();
-// }
-// }
-
-// private DateDifference DateDiffResultInDays
-// {
-// get { return m_dateDiffResultInDays; }
-// set
-// {
-// m_dateDiffResultInDays = value;
-// UpdateDisplayResult();
-// }
-// }
-
-// private DateTime DateResult
-// {
-// get { return m_dateResult; }
-// set {
-// m_dateResult = value;
-// UpdateDisplayResult();
-// }
-// }
-
-// // PUBLIC
-
-// // Input Properties
-// public string IsDateDiffMode { get; set; }
-// public string IsAddMode { get; set; }
-// public string IsDiffInDays { get; set; } // If diff is only in days or the dates are the same,
-// // then show only one result and avoid redundancy
-
-// public string DaysOffset { get; set; }
-// public string MonthsOffset { get; set; }
-// public string YearsOffset { get; set; }
-
-// // Read only property for offset values
-// public IVector OffsetValues
-// {
-// get { return m_offsetValues; }
-// }
-
-// // From date for Date Diff
-// public DateTime FromDate
-// {
-// DateTime get() { return m_fromDate; }
-// set
-// {
-// if (m_fromDate.UniversalTime != value.UniversalTime)
-// {
-// m_fromDate = value;
-// RaisePropertyChanged("FromDate");
-// }
-// }
-// }
-
-// // To date for Date Diff
-// public DateTime ToDate
-// {
-// get { return m_toDate; }
-// set
-// {
-// if (m_toDate.UniversalTime != value.UniversalTime)
-// {
-// m_toDate = value;
-// RaisePropertyChanged("ToDate");
-// }
-// }
-// }
-
-// // Start date for Add/Subtract date
-// public DateTime StartDate
-// {
-// get { return m_startDate; }
-// set
-// {
-// if (m_startDate.UniversalTime != value.UniversalTime)
-// {
-// m_startDate = value;
-// RaisePropertyChanged("StartDate");
-// }
-// }
-// }
-
-// // Output Properties
-// public string StrDateDiffResult { get; set; }
-
-// public string StrDateDiffResultAutomationName { get; set; }
-
-// public string StrDateDiffResultInDays { get; set; }
-
-// public string StrDateResult { get; set; }
-
-// public string StrDateResultAutomationName { get; set; }
-
-// public void OnCopyCommand(Object parameter)
-// {
-
-// }
-
-// // PRIVATE
-// private void OnPropertyChanged(string prop)
-// {
-// if (prop == DateCalculatorViewModelProperties.StrDateDiffResult)
-// {
-// UpdateStrDateDiffResultAutomationName();
-// }
-// else if (prop == DateCalculatorViewModelProperties.StrDateResult)
-// {
-// UpdateStrDateResultAutomationName();
-// }
-// else if (prop != DateCalculatorViewModelProperties.StrDateDiffResultAutomationName
-// && prop != DateCalculatorViewModelProperties.StrDateDiffResultInDays
-// && prop != DateCalculatorViewModelProperties.StrDateResultAutomationName
-// && prop != DateCalculatorViewModelProperties.IsDiffInDays)
-// {
-// OnInputsChanged();
-// }
-// }
-
-// private void OnInputsChanged()
-// {
-// DateDifference dateDiff;
-
-// if (m_IsDateDiffMode)
-// {
-// DateTime clippedFromDate = ClipTime(FromDate);
-// DateTime clippedToDate = ClipTime(ToDate);
-
-// // Calculate difference between two dates
-// m_dateCalcEngine->GetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat, &dateDiff);
-// DateDiffResult = dateDiff;
-
-// m_dateCalcEngine->GetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat, &dateDiff);
-// DateDiffResultInDays = dateDiff;
-// }
-// else
-// {
-// dateDiff.day = DaysOffset;
-// dateDiff.month = MonthsOffset;
-// dateDiff.year = YearsOffset;
-
-// DateTime dateTimeResult;
-
-// if (m_IsAddMode)
-// {
-// // Add number of Days, Months and Years to a Date
-// IsOutOfBound = !m_dateCalcEngine->AddDuration(StartDate, dateDiff, &dateTimeResult);
-// }
-// else
-// {
-// // Subtract number of Days, Months and Years from a Date
-// IsOutOfBound = !m_dateCalcEngine->SubtractDuration(StartDate, dateDiff, &dateTimeResult);
-// }
-
-// if (!m_isOutOfBound)
-// {
-// DateResult = dateTimeResult;
-// }
-// }
-// }
-
-// private void UpdateDisplayResult()
-// {
-// if (m_IsDateDiffMode)
-// {
-// // Are to and from dates the same
-// if (m_dateDiffResultInDays.day == 0)
-// {
-// IsDiffInDays = true;
-// StrDateDiffResultInDays = "";
-// StrDateDiffResult = AppResourceProvider.GetInstance().GetResourceString("Date_SameDates");
-// }
-// else if ((m_dateDiffResult.year == 0) &&
-// (m_dateDiffResult.month == 0) &&
-// (m_dateDiffResult.week == 0))
-// {
-// IsDiffInDays = true;
-// StrDateDiffResultInDays = "";
-
-// // Display result in number of days
-// StrDateDiffResult = GetDateDiffStringInDays();
-// }
-// else
-// {
-// IsDiffInDays = false;
-
-// // Display result in days, weeks, months and years
-// StrDateDiffResult = GetDateDiffString();
-
-// // Display result in number of days
-// StrDateDiffResultInDays = GetDateDiffStringInDays();
-// }
-// }
-// else
-// {
-// if (m_isOutOfBound)
-// {
-// // Display Date out of bound message
-// StrDateResult = AppResourceProvider.GetInstance().GetResourceString("Date_OutOfBoundMessage");
-// }
-// else
-// {
-// // Display the resulting date in long format
-// StrDateResult = m_dateTimeFormatter.Format(DateResult);
-// }
-// }
-// }
-
-// private void UpdateStrDateDiffResultAutomationName()
-// {
-// String automationFormat = AppResourceProvider.GetInstance().GetResourceString("Date_DifferenceResultAutomationName");
-// String localizedAutomationName = LocalizationStringUtil.GetLocalizedString(automationFormat->Data(), StrDateDiffResult.Data());
-
-// StrDateDiffResultAutomationName = new String(localizedAutomationName.ToString());
-// }
-
-// private void UpdateStrDateResultAutomationName()
-// {
-// String automationFormat = AppResourceProvider.GetInstance().GetResourceString("Date_ResultingDateAutomationName");
-// String localizedAutomationName = LocalizationStringUtil.GetLocalizedString(automationFormat.Data(), StrDateResult.Data());
-
-// StrDateResultAutomationName = new String(localizedAutomationName.ToString());
-// }
-
-// private void InitializeDateOutputFormats(string calendarIdentifer)
-// {
-// // Format for Add/Subtract days
-// m_dateTimeFormatter = LocalizationService.GetRegionalSettingsAwareDateTimeFormatter(
-// "longdate",
-// calendarIdentifier,
-// ClockIdentifiers.TwentyFourHour); // Clock Identifier is not used
-
-// // Format for Date Difference
-// m_allDateUnitsOutputFormat = DateUnit.Year | DateUnit.Month | DateUnit.Week | DateUnit.Day;
-// m_daysOutputFormat = DateUnit.Day;
-// }
-
-// private string GetDateDiffString()
-// {
-// String result = "";
-// bool addDelimiter = false;
-// AppResourceProvider resourceLoader = AppResourceProvider.GetInstance();
-
-// var yearCount = m_dateDiffResult.year;
-
-// if (yearCount > 0)
-// {
-// result = String.Concat(GetLocalizedNumberString(yearCount), " ");
-
-// if (yearCount > 1)
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Years"));
-// }
-// else
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Year"));
-// }
-
-// // set the flags to add a delimiter whenever the next unit is added
-// addDelimiter = true;
-// }
-
-// var monthCount = m_dateDiffResult.month;
-
-// if (monthCount > 0)
-// {
-// if (addDelimiter)
-// {
-// result = String.Concat(result, m_listSeparator);
-// }
-// else
-// {
-// addDelimiter = true;
-// }
-
-// result = String.Concat(result, String.Concat(GetLocalizedNumberString(monthCount), " "));
-
-// if (monthCount > 1)
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Months"));
-// }
-// else
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Month"));
-// }
-// }
-
-// var weekCount = m_dateDiffResult.week;
-
-// if (weekCount > 0)
-// {
-// if (addDelimiter)
-// {
-// result = String.Concat(result, m_listSeparator);
-// }
-// else
-// {
-// addDelimiter = true;
-// }
-
-// result = String.Concat(result, String.Concat(GetLocalizedNumberString(weekCount), " "));
-
-// if (weekCount > 1)
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Weeks"));
-// }
-// else
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Week"));
-// }
-// }
-
-// var dayCount = m_dateDiffResult.day;
-
-// if (dayCount > 0)
-// {
-// if (addDelimiter)
-// {
-// result = String.Concat(result, m_listSeparator);
-// }
-// else
-// {
-// addDelimiter = true;
-// }
-
-// result = String.Concat(result, String.Concat(GetLocalizedNumberString(dayCount), " "));
-
-// if (dayCount > 1)
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Days"));
-// }
-// else
-// {
-// result = String.Concat(result, resourceLoader.GetResourceString("Date_Day"));
-// }
-// }
-
-// return result;
-// }
-
-// private string GetDateDiffStringInDays()
-// {
-// String strDateUnit;
-
-// // Display the result as '1 day' or 'N days'
-// if (m_dateDiffResultInDays.day > 1)
-// {
-// strDateUnit = AppResourceProvider.GetInstance().GetResourceString("Date_Days");
-// }
-// else
-// {
-// strDateUnit = AppResourceProvider.GetInstance().GetResourceString("Date_Day");
-// }
-
-// return String.Concat(GetLocalizedNumberString(m_dateDiffResultInDays.day), String.Concat(" ", strDateUnit));
-// }
-
-// private string GetLocalizedNumberString(int value)
-// {
-// string numberStr = value.ToString();
-// LocalizationSettings.GetInstance().LocalizeDisplayValue(numberStr);
-
-// return numberStr.ToString();
-// }
-
-// private static DateTime ClipTime(DateTime dateTime)
-// {
-// var calendar = new Calendar();
-// calendar.SetDateTime(dateTime);
-// calendar.Period = 1;
-// calendar.Hour = 12;
-// calendar.Minute = 0;
-// calendar.Second = 0;
-// calendar.Nanosecond = 0;
-
-// return calendar.GetDateTime();
-// }
-
-// // MAX?
-// private static void CheckClipTimeSameDay(Calendar reference)
-// {
-
-// }
-// }
-//}
\ No newline at end of file
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+using Windows.UI.Xaml.Data;
+using Windows.Globalization;
+using CalculatorApp.Common;
+using Windows.Globalization.DateTimeFormatting;
+using CalculatorApp.Common.DateCalculation;
+using Windows.Foundation;
+using System.Numerics;
+using CalculatorApp;
+
+namespace CalculatorApp.ViewModel
+{
+ [Windows.UI.Xaml.Data.Bindable]
+ public sealed class DateCalculatorViewModel : INotifyPropertyChanged
+ {
+ const int c_maxOffsetValue = 999;
+
+ const string StrDateDiffResultPropertyName="StrDateDiffResult";
+ const string StrDateDiffResultAutomationNamePropertyName="StrDateDiffResultAutomationName";
+ const string StrDateDiffResultInDaysPropertyName="StrDateDiffResultInDays";
+ const string StrDateResultPropertyName="StrDateResult";
+ const string StrDateResultAutomationNamePropertyName="StrDateResultAutomationName";
+ const string IsDiffInDaysPropertyName="IsDiffInDays";
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string p = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p));
+
+ // Private members
+ private DateCalculationEngine m_dateCalcEngine;
+ private DateUnit m_daysOutputFormat;
+ private DateUnit m_allDateUnitsOutputFormat;
+ private DateTimeFormatter m_dateTimeFormatter;
+ private string m_listSeparator;
+
+ private CalculatorList m_offsetValues;
+ private DateTime m_fromDate;
+ private DateTime m_toDate;
+ private DateTime m_startDate;
+ private DateTime m_dateResult;
+ private DateDifference m_dateDiffResult;
+ private DateDifference m_dateDiffResultInDays;
+
+ private bool m_IsDateDiffMode = true;
+ private bool m_IsAddMode = true;
+ private bool m_IsDiffInDays = true;
+ private bool m_isOutOfBound = false;
+ private int m_DaysOffset = 0;
+ private int m_MonthsOffset = 0;
+ private int m_YearsOffset = 0;
+ private string m_StrDateDiffResult = "";
+ private string m_StrDateDiffResultAutomationName = "";
+ private string m_StrDateDiffResultInDays = "";
+ private string m_StrDateResult = "";
+ private string m_StrDateResultAutomationName = "";
+
+ public DateCalculatorViewModel()
+ {
+ var localizationSettings = LocalizationSettings.GetInstance();
+
+ // Initialize Date Output format instances
+ InitializeDateOutputFormats(localizationSettings.GetCalendarIdentifier());
+
+ // Initialize Date Calc engine
+ m_dateCalcEngine = new DateCalculationEngine(localizationSettings.GetCalendarIdentifier());
+
+ // Initialize dates of DatePicker controls to today's date
+ var calendar = new Calendar();
+ var today = calendar.GetDateTime().DateTime;
+
+ // FromDate and ToDate should be clipped (adjusted to a consistent hour in UTC)
+ m_fromDate = today;
+ m_toDate = today;
+ FromDate = ClipTime(today);
+ ToDate = ClipTime(today);
+
+ // StartDate should not be clipped
+ StartDate = today;
+ m_dateResult = today;
+
+ // Initialize the list separator delimiter appended with a space at the end, e.g. ", "
+ // This will be used for date difference formatting: Y years, M months, W weeks, D days
+ m_listSeparator = localizationSettings.GetListSeparator() + " ";
+
+ // Initialize the output results
+ UpdateDisplayResult();
+
+ m_offsetValues = new CalculatorList();
+
+ for (int i = 0; i <= c_maxOffsetValue; i++)
+ {
+ // MAX?
+ string numberStr = i.ToString();
+ localizationSettings.LocalizeDisplayValue(ref numberStr);
+ m_offsetValues.Append(numberStr.ToString());
+ }
+
+ /* In the ClipTime function, we used to change timezone to UTC before clipping the time.
+ The comment from the previous delopers said this was done to eliminate the effects of
+ Daylight Savings Time. We can't think of a good reason why this change in timezone is
+ necessary and did find bugs related to the change, therefore, we have removed the
+ change. Just in case, we will see if the clipped time is ever a different day from the
+ original day, which would hopefully indicate the change in timezone was actually
+ necessary. We will collect telemetry if we find this case. If we don't see any
+ telemetry events after the application has been used for some time, we will feel safe
+ and can remove this function. */
+ Windows.Globalization.DayOfWeek trueDayOfWeek = calendar.DayOfWeek;
+
+ DateTime clippedTime = ClipTime(today);
+ calendar.SetDateTime(clippedTime);
+
+ if (calendar.DayOfWeek != trueDayOfWeek)
+ {
+ // MAX?
+ calendar.SetDateTime(today);
+ TraceLogger.GetInstance().LogDateClippedTimeDifferenceFound(
+ calendar,
+ clippedTime.ToUniversalTime());
+ }
+
+ PropertyChanged += (snd, e) => ((DateCalculatorViewModel)snd).OnPropertyChanged(e.PropertyName);
+ }
+
+ static void CheckClipTimeSameDay(Calendar reference)
+ {
+
+ }
+
+ private bool IsOutOfBound
+ {
+ get { return m_isOutOfBound; }
+ set
+ {
+ m_isOutOfBound = value;
+ UpdateDisplayResult();
+ }
+ }
+
+ private DateDifference DateDiffResult
+ {
+ get { return m_dateDiffResult; }
+ set {
+ m_dateDiffResult = value;
+ UpdateDisplayResult();
+ }
+ }
+
+ private DateDifference DateDiffResultInDays
+ {
+ get { return m_dateDiffResultInDays; }
+ set
+ {
+ m_dateDiffResultInDays = value;
+ UpdateDisplayResult();
+ }
+ }
+
+ private DateTime DateResult
+ {
+ get { return m_dateResult; }
+ set {
+ m_dateResult = value;
+ UpdateDisplayResult();
+ }
+ }
+
+ // PUBLIC
+
+ // Input Properties
+ public bool IsDateDiffMode
+ {
+ get => m_IsDateDiffMode;
+ set
+ {
+ if (m_IsDateDiffMode != value)
+ {
+ m_IsDateDiffMode = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+ public bool IsAddMode
+ {
+ get => m_IsAddMode;
+ set
+ {
+ if (m_IsAddMode != value)
+ {
+ m_IsAddMode = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+ public bool IsDiffInDays
+ {
+ get => m_IsDiffInDays;
+ private set
+ {
+ if (m_IsDiffInDays != value)
+ {
+ m_IsDiffInDays = value;
+ RaisePropertyChanged();
+ }
+ }
+ } // If diff is only in days or the dates are the same,
+ // then show only one result and avoid redundancy
+
+ public int DaysOffset
+ {
+ get => m_DaysOffset;
+ set
+ {
+ if (m_DaysOffset != value)
+ {
+ m_DaysOffset = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public int MonthsOffset
+ {
+ get => m_MonthsOffset;
+ set
+ {
+ if (m_MonthsOffset != value)
+ {
+ m_MonthsOffset = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public int YearsOffset
+ {
+ get => m_YearsOffset;
+ set
+ {
+ if (m_YearsOffset != value)
+ {
+ m_YearsOffset = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ // Read only property for offset values
+ public CalculatorList OffsetValues
+ {
+ get { return m_offsetValues; }
+ }
+
+ // From date for Date Diff
+ public DateTime FromDate
+ {
+ get { return m_fromDate; }
+ set
+ {
+ if (m_fromDate.ToUniversalTime() != value.ToUniversalTime())
+ {
+ m_fromDate = value;
+ RaisePropertyChanged("FromDate");
+ }
+ }
+ }
+
+ // To date for Date Diff
+ public DateTime ToDate
+ {
+ get { return m_toDate; }
+ set
+ {
+ if (m_toDate.ToUniversalTime() != value.ToUniversalTime())
+ {
+ m_toDate = value;
+ RaisePropertyChanged("ToDate");
+ }
+ }
+ }
+
+ // Start date for Add/Subtract date
+ public DateTime StartDate
+ {
+ get { return m_startDate; }
+ set
+ {
+ if (m_startDate.ToUniversalTime() != value.ToUniversalTime())
+ {
+ m_startDate = value;
+ RaisePropertyChanged("StartDate");
+ }
+ }
+ }
+
+ // Output Properties
+ public string StrDateDiffResult
+ {
+ get => m_StrDateDiffResult;
+ private set
+ {
+ if (m_StrDateDiffResult != value)
+ {
+ m_StrDateDiffResult = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public string StrDateDiffResultAutomationName
+ {
+ get => m_StrDateDiffResultAutomationName;
+ private set
+ {
+ if (m_StrDateDiffResultAutomationName != value)
+ {
+ m_StrDateDiffResultAutomationName = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public string StrDateDiffResultInDays
+ {
+ get => m_StrDateDiffResultInDays;
+ private set
+ {
+ if (m_StrDateDiffResultInDays != value)
+ {
+ m_StrDateDiffResultInDays = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public string StrDateResult
+ {
+ get => m_StrDateResult;
+ private set
+ {
+ if (m_StrDateResult != value)
+ {
+ m_StrDateResult = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public string StrDateResultAutomationName
+ {
+ get => m_StrDateResultAutomationName;
+ private set
+ {
+ if (m_StrDateResultAutomationName != value)
+ {
+ m_StrDateResultAutomationName = value;
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public void OnCopyCommand(Object parameter)
+ {
+
+ }
+
+ // PRIVATE
+ private void OnPropertyChanged(string prop)
+ {
+ if (prop == StrDateDiffResultPropertyName)
+ {
+ UpdateStrDateDiffResultAutomationName();
+ }
+ else if (prop == StrDateResultPropertyName)
+ {
+ UpdateStrDateResultAutomationName();
+ }
+ else if (
+ prop != StrDateDiffResultAutomationNamePropertyName
+ && prop != StrDateDiffResultInDaysPropertyName
+ && prop != StrDateResultAutomationNamePropertyName
+ && prop != IsDiffInDaysPropertyName)
+ {
+ OnInputsChanged();
+ }
+ }
+
+ private void OnInputsChanged()
+ {
+ DateDifference dateDiff = new DateDifference();
+
+ if (m_IsDateDiffMode)
+ {
+ DateTime clippedFromDate = ClipTime(FromDate);
+ DateTime clippedToDate = ClipTime(ToDate);
+
+ // Calculate difference between two dates
+ m_dateCalcEngine.GetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat, out dateDiff);
+ DateDiffResult = dateDiff;
+
+ m_dateCalcEngine.GetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat, out dateDiff);
+ DateDiffResultInDays = dateDiff;
+ }
+ else
+ {
+ dateDiff.day = DaysOffset;
+ dateDiff.month = MonthsOffset;
+ dateDiff.year = YearsOffset;
+
+ DateTime dateTimeResult;
+
+ if (m_IsAddMode)
+ {
+ // Add number of Days, Months and Years to a Date
+ IsOutOfBound = !m_dateCalcEngine.AddDuration(StartDate, dateDiff, out dateTimeResult);
+ }
+ else
+ {
+ // Subtract number of Days, Months and Years from a Date
+ IsOutOfBound = !m_dateCalcEngine.SubtractDuration(StartDate, dateDiff, out dateTimeResult);
+ }
+
+ if (!m_isOutOfBound)
+ {
+ DateResult = dateTimeResult;
+ }
+ }
+ }
+
+ private void UpdateDisplayResult()
+ {
+ if (m_IsDateDiffMode)
+ {
+ // Are to and from dates the same
+ if (m_dateDiffResultInDays.day == 0)
+ {
+ IsDiffInDays = true;
+ StrDateDiffResultInDays = "";
+ StrDateDiffResult = AppResourceProvider.GetInstance().GetResourceString("Date_SameDates");
+ }
+ else if ((m_dateDiffResult.year == 0) &&
+ (m_dateDiffResult.month == 0) &&
+ (m_dateDiffResult.week == 0))
+ {
+ IsDiffInDays = true;
+ StrDateDiffResultInDays = "";
+
+ // Display result in number of days
+ StrDateDiffResult = GetDateDiffStringInDays();
+ }
+ else
+ {
+ IsDiffInDays = false;
+
+ // Display result in days, weeks, months and years
+ StrDateDiffResult = GetDateDiffString();
+
+ // Display result in number of days
+ StrDateDiffResultInDays = GetDateDiffStringInDays();
+ }
+ }
+ else
+ {
+ if (m_isOutOfBound)
+ {
+ // Display Date out of bound message
+ StrDateResult = AppResourceProvider.GetInstance().GetResourceString("Date_OutOfBoundMessage");
+ }
+ else
+ {
+ // Display the resulting date in long format
+ StrDateResult = m_dateTimeFormatter.Format(DateResult);
+ }
+ }
+ }
+
+ private void UpdateStrDateDiffResultAutomationName()
+ {
+ String automationFormat = AppResourceProvider.GetInstance().GetResourceString("Date_DifferenceResultAutomationName");
+ String localizedAutomationName = LocalizationStringUtil.GetLocalizedString(automationFormat, StrDateDiffResult);
+
+ StrDateDiffResultAutomationName = localizedAutomationName.ToString();
+ }
+
+ private void UpdateStrDateResultAutomationName()
+ {
+ String automationFormat = AppResourceProvider.GetInstance().GetResourceString("Date_ResultingDateAutomationName");
+ String localizedAutomationName = LocalizationStringUtil.GetLocalizedString(automationFormat, StrDateResult);
+
+ StrDateResultAutomationName = localizedAutomationName.ToString();
+ }
+
+ private void InitializeDateOutputFormats(string calendarIdentifier)
+ {
+ // Format for Add/Subtract days
+ m_dateTimeFormatter = LocalizationService.GetRegionalSettingsAwareDateTimeFormatter(
+ "longdate",
+ calendarIdentifier,
+ ClockIdentifiers.TwentyFourHour); // Clock Identifier is not used
+
+ // Format for Date Difference
+ m_allDateUnitsOutputFormat = DateUnit.Year | DateUnit.Month | DateUnit.Week | DateUnit.Day;
+ m_daysOutputFormat = DateUnit.Day;
+ }
+
+ private string GetDateDiffString()
+ {
+ String result = "";
+ bool addDelimiter = false;
+ AppResourceProvider resourceLoader = AppResourceProvider.GetInstance();
+
+ var yearCount = m_dateDiffResult.year;
+
+ if (yearCount > 0)
+ {
+ result = String.Concat(GetLocalizedNumberString(yearCount), " ");
+
+ if (yearCount > 1)
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Years"));
+ }
+ else
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Year"));
+ }
+
+ // set the flags to add a delimiter whenever the next unit is added
+ addDelimiter = true;
+ }
+
+ var monthCount = m_dateDiffResult.month;
+
+ if (monthCount > 0)
+ {
+ if (addDelimiter)
+ {
+ result = String.Concat(result, m_listSeparator);
+ }
+ else
+ {
+ addDelimiter = true;
+ }
+
+ result = String.Concat(result, String.Concat(GetLocalizedNumberString(monthCount), " "));
+
+ if (monthCount > 1)
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Months"));
+ }
+ else
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Month"));
+ }
+ }
+
+ var weekCount = m_dateDiffResult.week;
+
+ if (weekCount > 0)
+ {
+ if (addDelimiter)
+ {
+ result = String.Concat(result, m_listSeparator);
+ }
+ else
+ {
+ addDelimiter = true;
+ }
+
+ result = String.Concat(result, String.Concat(GetLocalizedNumberString(weekCount), " "));
+
+ if (weekCount > 1)
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Weeks"));
+ }
+ else
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Week"));
+ }
+ }
+
+ var dayCount = m_dateDiffResult.day;
+
+ if (dayCount > 0)
+ {
+ if (addDelimiter)
+ {
+ result = String.Concat(result, m_listSeparator);
+ }
+ else
+ {
+ addDelimiter = true;
+ }
+
+ result = String.Concat(result, String.Concat(GetLocalizedNumberString(dayCount), " "));
+
+ if (dayCount > 1)
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Days"));
+ }
+ else
+ {
+ result = String.Concat(result, resourceLoader.GetResourceString("Date_Day"));
+ }
+ }
+
+ return result;
+ }
+
+ private string GetDateDiffStringInDays()
+ {
+ String strDateUnit;
+
+ // Display the result as '1 day' or 'N days'
+ if (m_dateDiffResultInDays.day > 1)
+ {
+ strDateUnit = AppResourceProvider.GetInstance().GetResourceString("Date_Days");
+ }
+ else
+ {
+ strDateUnit = AppResourceProvider.GetInstance().GetResourceString("Date_Day");
+ }
+
+ return String.Concat(GetLocalizedNumberString(m_dateDiffResultInDays.day), String.Concat(" ", strDateUnit));
+ }
+
+ private string GetLocalizedNumberString(int value)
+ {
+ string numberStr = value.ToString();
+ LocalizationSettings.GetInstance().LocalizeDisplayValue(ref numberStr);
+
+ return numberStr.ToString();
+ }
+
+ private static DateTime ClipTime(DateTime dateTime)
+ {
+ var calendar = new Calendar();
+ calendar.SetDateTime(dateTime);
+ calendar.Period = 1;
+ calendar.Hour = 12;
+ calendar.Minute = 0;
+ calendar.Second = 0;
+ calendar.Nanosecond = 0;
+
+ return calendar.GetDateTime().DateTime;
+ }
+ }
+}
diff --git a/src/Calculator.Shared/Views/Calculator.xaml.cs b/src/Calculator.Shared/Views/Calculator.xaml.cs
index 422c3775..d774e013 100644
--- a/src/Calculator.Shared/Views/Calculator.xaml.cs
+++ b/src/Calculator.Shared/Views/Calculator.xaml.cs
@@ -553,7 +553,7 @@ namespace CalculatorApp
FullscreenFlyoutClosed();
}
- void CloseHistoryFlyout()
+ public void CloseHistoryFlyout()
{
if (m_fIsHistoryFlyoutOpen)
{
@@ -561,7 +561,7 @@ namespace CalculatorApp
}
}
- void CloseMemoryFlyout()
+ public void CloseMemoryFlyout()
{
if (m_fIsMemoryFlyoutOpen)
{
diff --git a/src/Calculator.Shared/Views/DateCalculator.xaml b/src/Calculator.Shared/Views/DateCalculator.xaml
index 31d9b822..4f513fde 100644
--- a/src/Calculator.Shared/Views/DateCalculator.xaml
+++ b/src/Calculator.Shared/Views/DateCalculator.xaml
@@ -5,11 +5,10 @@
xmlns:converters="using:CalculatorApp.Converters"
xmlns:local="using:CalculatorApp.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ Loaded="OnLoaded"
mc:Ignorable="">
-
-
-
-
+
-
+
- -->
-
+
-
+
- -->
-
+
@@ -543,14 +542,14 @@
- -->
-
+
- -->
-
+
- -->
-
+
-
+
- -->
- -->
+
-
+
-
+
- -->
+
@@ -688,7 +689,7 @@
Margin="0,0,0,6"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
TextWrapping="Wrap" />
-
+
-
+
-
+
-
+
-
+
- -->
+
@@ -748,5 +750,5 @@
ContextFlyout="{StaticResource ResultsContextMenu}"
Text="{Binding StrDateResult}" />
- -->
+
diff --git a/src/Calculator.Shared/Views/DateCalculator.xaml.cs b/src/Calculator.Shared/Views/DateCalculator.xaml.cs
index c8fa6365..272ced89 100644
--- a/src/Calculator.Shared/Views/DateCalculator.xaml.cs
+++ b/src/Calculator.Shared/Views/DateCalculator.xaml.cs
@@ -1,17 +1,19 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
+using Windows.Globalization;
+using Windows.Globalization.DateTimeFormatting;
+using Windows.UI.Core;
+using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
+using Windows.UI.Xaml.Automation;
+using Windows.UI.Xaml.Automation.Peers;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
-using Windows.UI.Xaml.Navigation;
+using CalculatorApp.Common;
+using CalculatorApp.ViewModel;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
@@ -19,9 +21,207 @@ namespace CalculatorApp
{
public sealed partial class DateCalculator : UserControl
{
+ // We choose 2550 as the max year because CalendarDatePicker experiences clipping
+ // issues just after 2558. We would like 9999 but will need to wait for a platform
+ // fix before we use a higher max year. This platform issue is tracked by
+ // TODO: MSFT-9273247
+ const int c_maxYear = 2550;
+ const int c_minYear = 1601;
+
public DateCalculator()
{
this.InitializeComponent();
+
+ var localizationSettings = LocalizationSettings.GetInstance();
+
+ // Set Calendar Identifier
+ DateDiff_FromDate.CalendarIdentifier = localizationSettings.GetCalendarIdentifier();
+ DateDiff_ToDate.CalendarIdentifier = localizationSettings.GetCalendarIdentifier();
+
+ // Setting the FirstDayofWeek
+ DateDiff_FromDate.FirstDayOfWeek = localizationSettings.GetFirstDayOfWeek();
+ DateDiff_ToDate.FirstDayOfWeek = localizationSettings.GetFirstDayOfWeek();
+
+ // Setting the Language explicitly is not required,
+ // this is a workaround for the bug in the control due to which
+ // the displayed date is incorrect for non Gregorian Calendar Systems
+ // The displayed date doesn't honor the shortdate format, on setting the Language the format is refreshed
+ DateDiff_FromDate.Language = localizationSettings.GetLocaleName();
+ DateDiff_ToDate.Language = localizationSettings.GetLocaleName();
+
+ // Set Min and Max Dates according to the Gregorian Calendar(1601 & 9999)
+ var calendar = new Calendar();
+ var today = calendar.GetDateTime();
+
+ calendar.ChangeCalendarSystem(CalendarIdentifiers.Gregorian);
+ calendar.Day = 1;
+ calendar.Month = 1;
+ calendar.Year = c_minYear;
+ var minYear = calendar.GetDateTime(); // 1st January, 1601
+ DateDiff_FromDate.MinDate = minYear;
+ DateDiff_ToDate.MinDate = minYear;
+
+ calendar.Day = 31;
+ calendar.Month = 12;
+ calendar.Year = c_maxYear;
+ var maxYear = calendar.GetDateTime(); // 31st December, 9878
+ DateDiff_FromDate.MaxDate = maxYear;
+ DateDiff_ToDate.MaxDate = maxYear;
+
+ // Set the PlaceHolderText for CalendarDatePicker
+ DateTimeFormatter dateTimeFormatter = LocalizationService.GetRegionalSettingsAwareDateTimeFormatter(
+ "day month year",
+ localizationSettings.GetCalendarIdentifier(),
+ ClockIdentifiers.TwentyFourHour); // Clock Identifier is not used
+
+ DateDiff_FromDate.DateFormat = "day month year";
+ DateDiff_ToDate.DateFormat = "day month year";
+
+ var placeholderText = dateTimeFormatter.Format(today);
+
+ DateDiff_FromDate.PlaceholderText = placeholderText;
+ DateDiff_ToDate.PlaceholderText = placeholderText;
+
+ // TODO UNO
+ // CopyMenuItem.Text = AppResourceProvider.GetInstance().GetResourceString("copyMenuItem");
+ DateCalculationOption.SelectionChanged += new SelectionChangedEventHandler(DateCalcOption_Changed);
+ }
+
+ void FromDate_DateChanged( CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs e)
+ {
+ if (e.NewDate != null)
+ {
+ var dateCalcViewModel = (DateCalculatorViewModel)this.DataContext;
+ dateCalcViewModel.FromDate = e.NewDate.Value.DateTime;
+ TraceLogger.GetInstance().LogDateDifferenceModeUsed(ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()));
+ }
+ else
+ {
+ ReselectCalendarDate(sender, e.OldDate.Value.DateTime);
+ }
+ }
+
+ void ToDate_DateChanged( CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs e)
+ {
+ if (e.NewDate != null)
+ {
+ var dateCalcViewModel = (DateCalculatorViewModel)this.DataContext;
+ dateCalcViewModel.ToDate = e.NewDate.Value.DateTime;
+ TraceLogger.GetInstance().LogDateDifferenceModeUsed(ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()));
+ }
+ else
+ {
+ ReselectCalendarDate(sender, e.OldDate.Value.DateTime);
+ }
+ }
+
+ void AddSubtract_DateChanged( CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs e)
+ {
+ if (e.NewDate != null)
+ {
+ var dateCalcViewModel = (DateCalculatorViewModel)this.DataContext;
+ dateCalcViewModel.StartDate = e.NewDate.Value.DateTime;
+ TraceLogger.GetInstance().LogDateAddSubtractModeUsed(
+ ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()), dateCalcViewModel.IsAddMode);
+ }
+ else
+ {
+ ReselectCalendarDate(sender, e.OldDate.Value.DateTime);
+ }
+ }
+
+ void OffsetValue_Changed( object sender, SelectionChangedEventArgs e)
+ {
+ var dateCalcViewModel = (DateCalculatorViewModel)this.DataContext;
+ TraceLogger.GetInstance().LogDateAddSubtractModeUsed(
+ ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()), dateCalcViewModel.IsAddMode);
+ }
+
+ void OnCopyMenuItemClicked( object sender, RoutedEventArgs e)
+ {
+ // TODO UNO
+ //var calcResult = (TextBlock)ResultsContextMenu.Target;
+
+ //CopyPasteManager.CopyToClipboard(calcResult.Text);
+ }
+
+ void OnLoaded( object sender, Windows.UI.Xaml.RoutedEventArgs e)
+ {
+ }
+
+ public void CloseCalendarFlyout()
+ {
+ if (DateDiff_FromDate.IsCalendarOpen)
+ {
+ DateDiff_FromDate.IsCalendarOpen = false;
+ }
+
+ if (DateDiff_ToDate.IsCalendarOpen)
+ {
+ DateDiff_ToDate.IsCalendarOpen = false;
+ }
+
+ if ((AddSubtract_FromDate != null) && (AddSubtract_FromDate.IsCalendarOpen))
+ {
+ AddSubtract_FromDate.IsCalendarOpen = false;
+ }
+ }
+
+ public void SetDefaultFocus()
+ {
+ DateCalculationOption.Focus(FocusState.Programmatic);
+ }
+
+ void DateCalcOption_Changed( object sender, Windows.UI.Xaml.Controls.SelectionChangedEventArgs e)
+ {
+ FindName("AddSubtractDateGrid");
+ DateCalculationOption.SelectionChanged -= DateCalcOption_Changed;
+ }
+
+ void AddSubtractDateGrid_Loaded( object sender, Windows.UI.Xaml.RoutedEventArgs e)
+ {
+ var localizationSettings = LocalizationSettings.GetInstance();
+
+ AddSubtract_FromDate.PlaceholderText = DateDiff_FromDate.PlaceholderText;
+ AddSubtract_FromDate.CalendarIdentifier = localizationSettings.GetCalendarIdentifier();
+ AddSubtract_FromDate.FirstDayOfWeek = localizationSettings.GetFirstDayOfWeek();
+ AddSubtract_FromDate.Language = localizationSettings.GetLocaleName();
+
+ AddSubtract_FromDate.MinDate = DateDiff_FromDate.MinDate;
+ AddSubtract_FromDate.MaxDate = DateDiff_FromDate.MaxDate;
+ AddSubtract_FromDate.DateFormat = "day month year";
+ }
+
+ void ReselectCalendarDate( Windows.UI.Xaml.Controls.CalendarDatePicker calendarDatePicker, DateTime dateTime)
+ {
+ // Reselect the unselected Date
+ calendarDatePicker.Date = dateTime;
+
+ // Dismiss the Calendar flyout
+ calendarDatePicker.IsCalendarOpen = false;
+ }
+
+ void OffsetDropDownClosed( object sender, object e)
+ {
+ RaiseLiveRegionChangedAutomationEvent(/* DateDiff mode */ false);
+ }
+
+ void CalendarFlyoutClosed( object sender, object e)
+ {
+ var dateCalcViewModel = (DateCalculatorViewModel)this.DataContext;
+ RaiseLiveRegionChangedAutomationEvent(dateCalcViewModel.IsDateDiffMode);
+ }
+
+ void RaiseLiveRegionChangedAutomationEvent( bool isDateDiffMode)
+ {
+ TextBlock resultTextBlock = (isDateDiffMode ? DateDiffAllUnitsResultLabel : DateResultLabel);
+ String automationName = AutomationProperties.GetName(resultTextBlock);
+ TextBlockAutomationPeer.FromElement(resultTextBlock).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
+ }
+
+ void AddSubtractOption_Checked( object sender, RoutedEventArgs e)
+ {
+ RaiseLiveRegionChangedAutomationEvent(/* DateDiff mode */ false);
}
}
}
diff --git a/src/Calculator.Shared/Views/MainPage.xaml.cs b/src/Calculator.Shared/Views/MainPage.xaml.cs
index c40dbd8d..f10658e0 100644
--- a/src/Calculator.Shared/Views/MainPage.xaml.cs
+++ b/src/Calculator.Shared/Views/MainPage.xaml.cs
@@ -284,19 +284,18 @@ namespace CalculatorApp
{
m_calculator.SetDefaultFocus();
}
+ if (m_dateCalculator != null && m_dateCalculator.Visibility == Visibility.Visible)
+ {
+ m_dateCalculator.SetDefaultFocus();
+ }
+ // UNO TODO
+ //if (m_converter != null && m_converter.Visibility == Visibility.Visible)
+ //{
+ // m_converter.SetDefaultFocus();
+ //}
+ }
- // UNO TODO
- //if (m_dateCalculator != null && m_dateCalculator.Visibility == Visibility.Visible)
- //{
- // m_dateCalculator.SetDefaultFocus();
- //}
- //if (m_converter != null && m_converter.Visibility == Visibility.Visible)
- //{
- // m_converter.SetDefaultFocus();
- //}
- }
-
- void EnsureCalculator()
+ void EnsureCalculator()
{
if (m_calculator == null)
{
@@ -336,23 +335,22 @@ namespace CalculatorApp
void EnsureDateCalculator()
{
- // UNO TODO
- //if (m_dateCalculator == null)
- //{
- // // delay loading converter
- // m_dateCalculator = new DateCalculator();
- // m_dateCalculator.Name = "dateCalculator";
- // m_dateCalculator.DataContext = m_model.DateCalcViewModel;
+ if (m_dateCalculator == null)
+ {
+ // delay loading converter
+ m_dateCalculator = new DateCalculator();
+ m_dateCalculator.Name = "dateCalculator";
+ m_dateCalculator.DataContext = m_model.DateCalcViewModel;
- // DateCalcHolder.Child = m_dateCalculator;
- //}
+ DateCalcHolder.Child = m_dateCalculator;
+ }
- //if (m_calculator != null)
- //{
- // m_calculator.CloseHistoryFlyout();
- // m_calculator.CloseMemoryFlyout();
- //}
- }
+ if (m_calculator != null)
+ {
+ m_calculator.CloseHistoryFlyout();
+ m_calculator.CloseMemoryFlyout();
+ }
+ }
void EnsureConverter()
{