mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-23 06:25:19 -07:00
commit
f93281dc78
11 changed files with 1423 additions and 681 deletions
|
@ -39,6 +39,7 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\CalculatorButtonUser.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\CalculatorButtonUser.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\CalculatorDisplay.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\CalculatorDisplay.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\CopyPasteManager.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\CopyPasteManager.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\DateCalculator.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\DelegateCommand.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\DelegateCommand.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\DisplayExpressionToken.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\DisplayExpressionToken.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\EngineResourceProvider.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\EngineResourceProvider.cs" />
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\MyVirtualKey.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\MyVirtualKey.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\NavCategory.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\NavCategory.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\TitleBarHelper.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\TitleBarHelper.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\TraceLogger.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\Utils.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\Utils.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\CalculationResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Controls\CalculationResult.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\CalculationResultAutomationPeer.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Controls\CalculationResultAutomationPeer.cs" />
|
||||||
|
|
377
src/Calculator.Shared/Common/DateCalculator.cs
Normal file
377
src/Calculator.Shared/Common/DateCalculator.cs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -379,7 +379,7 @@ namespace CalculatorApp.Common
|
||||||
// as configured by running intl.cpl.
|
// as configured by running intl.cpl.
|
||||||
//
|
//
|
||||||
// This helper function creates a DateTimeFormatter with a TwentyFour hour clock
|
// This helper function creates a DateTimeFormatter with a TwentyFour hour clock
|
||||||
DateTimeFormatter GetRegionalSettingsAwareDateTimeFormatter( string format)
|
public static DateTimeFormatter GetRegionalSettingsAwareDateTimeFormatter( string format)
|
||||||
{
|
{
|
||||||
IEnumerable<String> languageIdentifiers = GetLanguageIdentifiers();
|
IEnumerable<String> languageIdentifiers = GetLanguageIdentifiers();
|
||||||
if (languageIdentifiers == null)
|
if (languageIdentifiers == null)
|
||||||
|
@ -392,75 +392,39 @@ namespace CalculatorApp.Common
|
||||||
|
|
||||||
// If successful, returns a formatter that respects the user's regional format settings,
|
// If successful, returns a formatter that respects the user's regional format settings,
|
||||||
// as configured by running intl.cpl.
|
// 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
|
IEnumerable<string> languageIdentifiers = GetLanguageIdentifiers();
|
||||||
//IIterable<String> languageIdentifiers = GetLanguageIdentifiers();
|
if (languageIdentifiers == null)
|
||||||
//if (languageIdentifiers == null)
|
{
|
||||||
//{
|
languageIdentifiers = ApplicationLanguages.Languages;
|
||||||
// languageIdentifiers = ApplicationLanguages.Languages;
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
//return new DateTimeFormatter(format, languageIdentifiers, GlobalizationPerences.HomeGeographicRegion, calendarIdentifier, clockIdentifier);
|
return new DateTimeFormatter(format, languageIdentifiers, GlobalizationPreferences.HomeGeographicRegion, calendarIdentifier, clockIdentifier);
|
||||||
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CurrencyFormatter GetRegionalSettingsAwareCurrencyFormatter()
|
public static CurrencyFormatter GetRegionalSettingsAwareCurrencyFormatter()
|
||||||
{
|
{
|
||||||
// UNO TODO
|
string userCurrency =
|
||||||
//string userCurrency =
|
(GlobalizationPreferences.Currencies.Count > 0) ? GlobalizationPreferences.Currencies[0] : DefaultCurrencyCode;
|
||||||
// (GlobalizationPreferences.Currencies.Size > 0) ? GlobalizationPreferences.Currencies.GetAt(0) : string(DefaultCurrencyCode.data());
|
|
||||||
|
|
||||||
//IIterable<String> languageIdentifiers = GetLanguageIdentifiers();
|
IEnumerable<string> languageIdentifiers = GetLanguageIdentifiers();
|
||||||
//if (languageIdentifiers == null)
|
if (languageIdentifiers == null)
|
||||||
//{
|
{
|
||||||
// languageIdentifiers = ApplicationLanguages.Languages;
|
languageIdentifiers = ApplicationLanguages.Languages;
|
||||||
//}
|
}
|
||||||
|
|
||||||
//var currencyFormatter = new CurrencyFormatter(userCurrency, languageIdentifiers, GlobalizationPerences.HomeGeographicRegion);
|
var currencyFormatter = new CurrencyFormatter(userCurrency, languageIdentifiers, GlobalizationPreferences.HomeGeographicRegion);
|
||||||
|
|
||||||
//int fractionDigits = LocalizationSettings.GetInstance().GetCurrencyTrailingDigits();
|
int fractionDigits = LocalizationSettings.GetInstance().GetCurrencyTrailingDigits();
|
||||||
//currencyFormatter.FractionDigits = fractionDigits;
|
currencyFormatter.FractionDigits = fractionDigits;
|
||||||
|
|
||||||
//return currencyFormatter;
|
return currencyFormatter;
|
||||||
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static IEnumerable<String> GetLanguageIdentifiers()
|
static IEnumerable<String> GetLanguageIdentifiers()
|
||||||
{
|
{
|
||||||
#if !HAS_UNO
|
return GlobalizationPreferences.Languages;
|
||||||
//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<String>();
|
|
||||||
// languageList.Append(localeString);
|
|
||||||
// return languageList;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//return null;
|
|
||||||
yield break;
|
|
||||||
#else
|
|
||||||
yield break;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resources for the engine use numbers as keys. It's inconvenient, but also difficult to
|
// Resources for the engine use numbers as keys. It's inconvenient, but also difficult to
|
||||||
|
|
|
@ -128,17 +128,16 @@ namespace CalculatorApp
|
||||||
m_digitSymbols[i] = i.ToString(NumberFormatInfo.CurrentInfo)[0];
|
m_digitSymbols[i] = i.ToString(NumberFormatInfo.CurrentInfo)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// As CalcEngine only supports the first character of the decimal separator,
|
// As CalcEngine only supports the first character of the decimal separator,
|
||||||
// Only first character of the decimal separator string is supported.
|
// Only first character of the decimal separator string is supported.
|
||||||
m_decimalSeparator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator[0];
|
m_decimalSeparator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator[0];
|
||||||
m_numberGroupSeparator = NumberFormatInfo.CurrentInfo.NumberGroupSeparator[0];
|
m_numberGroupSeparator = NumberFormatInfo.CurrentInfo.NumberGroupSeparator[0];
|
||||||
m_numberGrouping = ""; // UNO TODO https://docs.microsoft.com/en-us/windows/desktop/Intl/locale-sgrouping
|
m_numberGrouping = ""; // UNO TODO https://docs.microsoft.com/en-us/windows/desktop/Intl/locale-sgrouping
|
||||||
m_listSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
|
m_listSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
|
||||||
m_currencyTrailingDigits = NumberFormatInfo.CurrentInfo.CurrencyDecimalDigits;
|
m_currencyTrailingDigits = NumberFormatInfo.CurrentInfo.CurrencyDecimalDigits;
|
||||||
m_currencySymbolPrecedence = ~(NumberFormatInfo.CurrentInfo.CurrencyPositivePattern) & 1;
|
m_currencySymbolPrecedence = ~(NumberFormatInfo.CurrentInfo.CurrencyPositivePattern) & 1;
|
||||||
|
m_resolvedName = CultureInfo.CurrentCulture.Name;
|
||||||
m_calendarIdentifier = "";//CultureInfo.CurrentCulture.DateTimeFormat.Calendar.ToString();
|
m_calendarIdentifier = new Windows.Globalization.Calendar().GetCalendarSystem();
|
||||||
|
|
||||||
m_firstDayOfWeek = (Windows.Globalization.DayOfWeek)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
|
m_firstDayOfWeek = (Windows.Globalization.DayOfWeek)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -155,7 +154,7 @@ namespace CalculatorApp
|
||||||
return m_localizationSettings;
|
return m_localizationSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetLocaleName()
|
public string GetLocaleName()
|
||||||
{
|
{
|
||||||
return m_resolvedName;
|
return m_resolvedName;
|
||||||
}
|
}
|
||||||
|
@ -326,7 +325,7 @@ namespace CalculatorApp
|
||||||
return m_listSeparator;
|
return m_listSeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
Windows.Globalization.DayOfWeek GetFirstDayOfWeek()
|
public Windows.Globalization.DayOfWeek GetFirstDayOfWeek()
|
||||||
{
|
{
|
||||||
return m_firstDayOfWeek;
|
return m_firstDayOfWeek;
|
||||||
}
|
}
|
||||||
|
|
81
src/Calculator.Shared/Common/TraceLogger.cs
Normal file
81
src/Calculator.Shared/Common/TraceLogger.cs
Normal file
|
@ -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) {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,9 +35,8 @@ namespace CalculatorApp.ViewModel
|
||||||
private StandardCalculatorViewModel m_CalculatorViewModel;
|
private StandardCalculatorViewModel m_CalculatorViewModel;
|
||||||
public StandardCalculatorViewModel CalculatorViewModel { get => m_CalculatorViewModel; set { m_CalculatorViewModel = value; RaisePropertyChanged("CalculatorViewModel"); } }
|
public StandardCalculatorViewModel CalculatorViewModel { get => m_CalculatorViewModel; set { m_CalculatorViewModel = value; RaisePropertyChanged("CalculatorViewModel"); } }
|
||||||
|
|
||||||
// UNO TODO
|
private DateCalculatorViewModel m_DateCalcViewModel;
|
||||||
//private DateCalculatorViewModel m_DateCalcViewModel;
|
public DateCalculatorViewModel DateCalcViewModel { get => m_DateCalcViewModel; set { m_DateCalcViewModel = value; RaisePropertyChanged("DateCalcViewModel"); } }
|
||||||
//public DateCalculatorViewModel DateCalcViewModel { get => m_DateCalcViewModel; set { m_DateCalcViewModel = value; RaisePropertyChanged("DateCalcViewModel"); } }
|
|
||||||
|
|
||||||
|
|
||||||
// UNO TODO
|
// UNO TODO
|
||||||
|
@ -160,12 +159,11 @@ namespace CalculatorApp.ViewModel
|
||||||
else if (NavCategory.IsDateCalculatorViewMode(m_mode))
|
else if (NavCategory.IsDateCalculatorViewMode(m_mode))
|
||||||
{
|
{
|
||||||
// TraceLogger.GetInstance().LogDateCalculatorModeViewed(m_mode, ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()));
|
// TraceLogger.GetInstance().LogDateCalculatorModeViewed(m_mode, ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()));
|
||||||
// UNO TODO
|
if (m_DateCalcViewModel == null)
|
||||||
//if (m_DateCalcViewModel == null)
|
{
|
||||||
//{
|
m_DateCalcViewModel = new DateCalculatorViewModel();
|
||||||
// m_DateCalcViewModel = new DateCalculatorViewModel();
|
}
|
||||||
//}
|
}
|
||||||
}
|
|
||||||
else if (NavCategory.IsConverterViewMode(m_mode))
|
else if (NavCategory.IsConverterViewMode(m_mode))
|
||||||
{
|
{
|
||||||
// UNO TODO
|
// UNO TODO
|
||||||
|
@ -200,12 +198,13 @@ namespace CalculatorApp.ViewModel
|
||||||
//{
|
//{
|
||||||
// ConverterViewModel.OnCopyCommand(parameter);
|
// ConverterViewModel.OnCopyCommand(parameter);
|
||||||
//}
|
//}
|
||||||
//else if (NavCategory.IsDateCalculatorViewMode(m_mode))
|
|
||||||
//{
|
|
||||||
// DateCalcViewModel.OnCopyCommand(parameter);
|
|
||||||
//}
|
|
||||||
//else
|
//else
|
||||||
{
|
if (NavCategory.IsDateCalculatorViewMode(m_mode))
|
||||||
|
{
|
||||||
|
DateCalcViewModel.OnCopyCommand(parameter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
CalculatorViewModel.OnCopyCommand(parameter);
|
CalculatorViewModel.OnCopyCommand(parameter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -553,7 +553,7 @@ namespace CalculatorApp
|
||||||
FullscreenFlyoutClosed();
|
FullscreenFlyoutClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseHistoryFlyout()
|
public void CloseHistoryFlyout()
|
||||||
{
|
{
|
||||||
if (m_fIsHistoryFlyoutOpen)
|
if (m_fIsHistoryFlyoutOpen)
|
||||||
{
|
{
|
||||||
|
@ -561,7 +561,7 @@ namespace CalculatorApp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseMemoryFlyout()
|
public void CloseMemoryFlyout()
|
||||||
{
|
{
|
||||||
if (m_fIsMemoryFlyoutOpen)
|
if (m_fIsMemoryFlyoutOpen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,11 +5,10 @@
|
||||||
xmlns:converters="using:CalculatorApp.Converters"
|
xmlns:converters="using:CalculatorApp.Converters"
|
||||||
xmlns:local="using:CalculatorApp.Views"
|
xmlns:local="using:CalculatorApp.Views"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
Loaded="OnLoaded"
|
||||||
mc:Ignorable="">
|
mc:Ignorable="">
|
||||||
|
|
||||||
<!-- UNO TODO Loaded="OnLoaded"-->
|
<UserControl.Resources>
|
||||||
|
|
||||||
<!-- UNO TODO <UserControl.Resources>
|
|
||||||
<converters:BooleanNegationConverter x:Key="BooleanNegationConverter" />
|
<converters:BooleanNegationConverter x:Key="BooleanNegationConverter" />
|
||||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||||
<converters:BooleanToVisibilityNegationConverter x:Key="BooleanToVisibilityNegationConverter" />
|
<converters:BooleanToVisibilityNegationConverter x:Key="BooleanToVisibilityNegationConverter" />
|
||||||
|
@ -441,13 +440,13 @@
|
||||||
Value="False" />
|
Value="False" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<MenuFlyout x:Key="ResultsContextMenu"
|
<!--TODO UNO <MenuFlyout x:Key="ResultsContextMenu"
|
||||||
x:Name="ResultsContextMenu">
|
x:Name="ResultsContextMenu">
|
||||||
<MenuFlyoutItem x:Name="CopyMenuItem"
|
<MenuFlyoutItem x:Name="CopyMenuItem"
|
||||||
x:Uid="CopyMenuItem"
|
x:Uid="CopyMenuItem"
|
||||||
Click="OnCopyMenuItemClicked"
|
Click="OnCopyMenuItemClicked"
|
||||||
Icon="Copy" />
|
Icon="Copy" />
|
||||||
</MenuFlyout>
|
</MenuFlyout>-->
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Grid x:Name="DateCalculatorGrid"
|
<Grid x:Name="DateCalculatorGrid"
|
||||||
|
@ -500,7 +499,7 @@
|
||||||
</VisualStateGroup>
|
</VisualStateGroup>
|
||||||
</VisualStateManager.VisualStateGroups>
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
|
||||||
--><!-- ComboBox for Date Calculation options --><!--
|
<!-- ComboBox for Date Calculation options -->
|
||||||
<ComboBox x:Name="DateCalculationOption"
|
<ComboBox x:Name="DateCalculationOption"
|
||||||
x:Uid="DateCalculationOption"
|
x:Uid="DateCalculationOption"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
@ -518,7 +517,7 @@
|
||||||
IsSelected="{Binding IsDateDiffMode, Converter={StaticResource BooleanNegationConverter}, Mode=TwoWay}" />
|
IsSelected="{Binding IsDateDiffMode, Converter={StaticResource BooleanNegationConverter}, Mode=TwoWay}" />
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|
||||||
--><!-- Grid to Calculate Difference between Two Dates --><!--
|
<!-- Grid to Calculate Difference between Two Dates -->
|
||||||
<Grid x:Name="DateDiffGrid"
|
<Grid x:Name="DateDiffGrid"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Visibility="{Binding IsDateDiffMode, Converter={StaticResource BooleanToVisibilityConverter}}">
|
Visibility="{Binding IsDateDiffMode, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
@ -543,7 +542,7 @@
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
--><!-- From Date --><!--
|
<!-- From Date -->
|
||||||
<TextBlock x:Name="Date_FromLabel"
|
<TextBlock x:Name="Date_FromLabel"
|
||||||
x:Uid="Date_FromLabel"
|
x:Uid="Date_FromLabel"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
@ -559,7 +558,7 @@
|
||||||
Closed="CalendarFlyoutClosed"
|
Closed="CalendarFlyoutClosed"
|
||||||
DateChanged="FromDate_DateChanged" />
|
DateChanged="FromDate_DateChanged" />
|
||||||
|
|
||||||
--><!-- To Date --><!--
|
<!-- To Date -->
|
||||||
<TextBlock x:Name="Date_ToLabel"
|
<TextBlock x:Name="Date_ToLabel"
|
||||||
x:Uid="Date_ToLabel"
|
x:Uid="Date_ToLabel"
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
|
@ -576,7 +575,7 @@
|
||||||
Closed="CalendarFlyoutClosed"
|
Closed="CalendarFlyoutClosed"
|
||||||
DateChanged="ToDate_DateChanged" />
|
DateChanged="ToDate_DateChanged" />
|
||||||
|
|
||||||
--><!-- Difference Result --><!--
|
<!-- Difference Result -->
|
||||||
<TextBlock x:Uid="Date_DifferenceLabel"
|
<TextBlock x:Uid="Date_DifferenceLabel"
|
||||||
Grid.Row="7"
|
Grid.Row="7"
|
||||||
Margin="0,0,0,0"
|
Margin="0,0,0,0"
|
||||||
|
@ -599,7 +598,7 @@
|
||||||
Visibility="{Binding IsDiffInDays, Converter={StaticResource BooleanToVisibilityNegationConverter}}" />
|
Visibility="{Binding IsDiffInDays, Converter={StaticResource BooleanToVisibilityNegationConverter}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
--><!-- Grid for Add/Subtract Date --><!--
|
<!-- Grid for Add/Subtract Date -->
|
||||||
<Grid x:Name="AddSubtractDateGrid"
|
<Grid x:Name="AddSubtractDateGrid"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
x:DeferLoadStrategy="Lazy"
|
x:DeferLoadStrategy="Lazy"
|
||||||
|
@ -624,7 +623,8 @@
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
--><!-- From Date --><!--
|
<!-- From Date -->
|
||||||
|
|
||||||
<TextBlock x:Name="AddSubtract_Date_FromLabel"
|
<TextBlock x:Name="AddSubtract_Date_FromLabel"
|
||||||
x:Uid="Date_FromLabel"
|
x:Uid="Date_FromLabel"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
@ -668,7 +668,8 @@
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
--><!-- Date Offset to be Added/Subtracted --><!--
|
<!-- Date Offset to be Added/Subtracted -->
|
||||||
|
|
||||||
<Grid x:Name="DateOffsetGrid"
|
<Grid x:Name="DateOffsetGrid"
|
||||||
Grid.Row="6">
|
Grid.Row="6">
|
||||||
|
|
||||||
|
@ -734,7 +735,8 @@
|
||||||
SelectionChanged="OffsetValue_Changed" />
|
SelectionChanged="OffsetValue_Changed" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
--><!-- Resulting Date --><!--
|
<!-- Resulting Date -->
|
||||||
|
|
||||||
<TextBlock x:Uid="DateLabel"
|
<TextBlock x:Uid="DateLabel"
|
||||||
Grid.Row="8"
|
Grid.Row="8"
|
||||||
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
|
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
|
||||||
|
@ -748,5 +750,5 @@
|
||||||
ContextFlyout="{StaticResource ResultsContextMenu}"
|
ContextFlyout="{StaticResource ResultsContextMenu}"
|
||||||
Text="{Binding StrDateResult}" />
|
Text="{Binding StrDateResult}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>-->
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
using System;
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
using System.Collections.Generic;
|
// Licensed under the MIT License.
|
||||||
using System.IO;
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
using Windows.Foundation;
|
using Windows.Globalization;
|
||||||
using Windows.Foundation.Collections;
|
using Windows.Globalization.DateTimeFormatting;
|
||||||
|
using Windows.UI.Core;
|
||||||
|
using Windows.UI.ViewManagement;
|
||||||
using Windows.UI.Xaml;
|
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;
|
||||||
using Windows.UI.Xaml.Controls.Primitives;
|
using CalculatorApp.Common;
|
||||||
using Windows.UI.Xaml.Data;
|
using CalculatorApp.ViewModel;
|
||||||
using Windows.UI.Xaml.Input;
|
|
||||||
using Windows.UI.Xaml.Media;
|
|
||||||
using Windows.UI.Xaml.Navigation;
|
|
||||||
|
|
||||||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
// 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
|
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()
|
public DateCalculator()
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,19 +284,18 @@ namespace CalculatorApp
|
||||||
{
|
{
|
||||||
m_calculator.SetDefaultFocus();
|
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
|
void EnsureCalculator()
|
||||||
//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()
|
|
||||||
{
|
{
|
||||||
if (m_calculator == null)
|
if (m_calculator == null)
|
||||||
{
|
{
|
||||||
|
@ -336,23 +335,22 @@ namespace CalculatorApp
|
||||||
|
|
||||||
void EnsureDateCalculator()
|
void EnsureDateCalculator()
|
||||||
{
|
{
|
||||||
// UNO TODO
|
if (m_dateCalculator == null)
|
||||||
//if (m_dateCalculator == null)
|
{
|
||||||
//{
|
// delay loading converter
|
||||||
// // delay loading converter
|
m_dateCalculator = new DateCalculator();
|
||||||
// m_dateCalculator = new DateCalculator();
|
m_dateCalculator.Name = "dateCalculator";
|
||||||
// m_dateCalculator.Name = "dateCalculator";
|
m_dateCalculator.DataContext = m_model.DateCalcViewModel;
|
||||||
// m_dateCalculator.DataContext = m_model.DateCalcViewModel;
|
|
||||||
|
|
||||||
// DateCalcHolder.Child = m_dateCalculator;
|
DateCalcHolder.Child = m_dateCalculator;
|
||||||
//}
|
}
|
||||||
|
|
||||||
//if (m_calculator != null)
|
if (m_calculator != null)
|
||||||
//{
|
{
|
||||||
// m_calculator.CloseHistoryFlyout();
|
m_calculator.CloseHistoryFlyout();
|
||||||
// m_calculator.CloseMemoryFlyout();
|
m_calculator.CloseMemoryFlyout();
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureConverter()
|
void EnsureConverter()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue