mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-22 14:13:30 -07:00
Merge remote-tracking branch 'upstream/master' into Fix245
This commit is contained in:
commit
55c860361a
11 changed files with 504 additions and 441 deletions
|
@ -416,8 +416,11 @@ int CHistoryCollector::AddCommand(_In_ const std::shared_ptr<IExpressionCommand>
|
|||
// To Update the operands in the Expression according to the current Radix
|
||||
void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precision)
|
||||
{
|
||||
if (m_spTokens != nullptr)
|
||||
if (m_spTokens == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int size;
|
||||
IFT(m_spTokens->GetSize(&size));
|
||||
|
||||
|
@ -444,7 +447,6 @@ void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precisio
|
|||
}
|
||||
SetExpressionDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
|
||||
{
|
||||
|
|
|
@ -490,8 +490,12 @@ namespace CalculationManager
|
|||
void CalculatorManager::MemorizeNumber()
|
||||
{
|
||||
m_savedCommands.push_back(MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber));
|
||||
if (!(m_currentCalculatorEngine->FInErrorState()))
|
||||
|
||||
if (m_currentCalculatorEngine->FInErrorState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentCalculatorEngine->ProcessCommand(IDC_STORE);
|
||||
|
||||
auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject();
|
||||
|
@ -506,7 +510,6 @@ namespace CalculationManager
|
|||
}
|
||||
this->SetMemorizedNumbersString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recall the memorized number.
|
||||
|
@ -516,12 +519,15 @@ namespace CalculationManager
|
|||
void CalculatorManager::MemorizedNumberLoad(_In_ unsigned int indexOfMemory)
|
||||
{
|
||||
SaveMemoryCommand(MemoryCommand::MemorizedNumberLoad, indexOfMemory);
|
||||
if (!(m_currentCalculatorEngine->FInErrorState()))
|
||||
|
||||
if (m_currentCalculatorEngine->FInErrorState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->MemorizedNumberSelect(indexOfMemory);
|
||||
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do the addition to the selected memory
|
||||
|
@ -532,8 +538,12 @@ namespace CalculationManager
|
|||
void CalculatorManager::MemorizedNumberAdd(_In_ unsigned int indexOfMemory)
|
||||
{
|
||||
SaveMemoryCommand(MemoryCommand::MemorizedNumberAdd, indexOfMemory);
|
||||
if (!(m_currentCalculatorEngine->FInErrorState()))
|
||||
|
||||
if (m_currentCalculatorEngine->FInErrorState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_memorizedNumbers.empty())
|
||||
{
|
||||
this->MemorizeNumber();
|
||||
|
@ -550,7 +560,6 @@ namespace CalculationManager
|
|||
|
||||
m_displayCallback->MemoryItemChanged(indexOfMemory);
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorManager::MemorizedNumberClear(_In_ unsigned int indexOfMemory)
|
||||
{
|
||||
|
@ -570,8 +579,12 @@ namespace CalculationManager
|
|||
void CalculatorManager::MemorizedNumberSubtract(_In_ unsigned int indexOfMemory)
|
||||
{
|
||||
SaveMemoryCommand(MemoryCommand::MemorizedNumberSubtract, indexOfMemory);
|
||||
if (!(m_currentCalculatorEngine->FInErrorState()))
|
||||
|
||||
if (m_currentCalculatorEngine->FInErrorState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// To add negative of the number on display to the memory -x = x - 2x
|
||||
if (m_memorizedNumbers.empty())
|
||||
{
|
||||
|
@ -591,7 +604,6 @@ namespace CalculationManager
|
|||
|
||||
m_displayCallback->MemoryItemChanged(indexOfMemory);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear all the memorized values
|
||||
|
@ -613,12 +625,14 @@ namespace CalculationManager
|
|||
/// <param name="indexOfMemory">Index of the target memory</param>
|
||||
void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory)
|
||||
{
|
||||
if (!(m_currentCalculatorEngine->FInErrorState()))
|
||||
if (m_currentCalculatorEngine->FInErrorState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto memoryObject = m_memorizedNumbers.at(indexOfMemory);
|
||||
m_currentCalculatorEngine->PersistedMemObject(memoryObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function that needs to be executed when memory is modified
|
||||
|
@ -627,15 +641,17 @@ namespace CalculationManager
|
|||
/// <param name="indexOfMemory">Index of the target memory</param>
|
||||
void CalculatorManager::MemorizedNumberChanged(_In_ unsigned int indexOfMemory)
|
||||
{
|
||||
if (!(m_currentCalculatorEngine->FInErrorState()))
|
||||
if (m_currentCalculatorEngine->FInErrorState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto memoryObject = m_currentCalculatorEngine->PersistedMemObject();
|
||||
if (memoryObject != nullptr)
|
||||
{
|
||||
m_memorizedNumbers.at(indexOfMemory) = *memoryObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorManager::SaveMemoryCommand(_In_ MemoryCommand command, _In_ unsigned int indexOfMemory)
|
||||
{
|
||||
|
|
|
@ -612,6 +612,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
|||
break;
|
||||
}
|
||||
// Drop through in the 'e'-as-a-digit case
|
||||
[[fallthrough]];
|
||||
default:
|
||||
state = machine[state][NZ];
|
||||
break;
|
||||
|
@ -646,7 +647,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
|||
break;
|
||||
case LD:
|
||||
pnumret->exp++;
|
||||
// Fall through
|
||||
[[fallthrough]];
|
||||
case DD:
|
||||
{
|
||||
curChar = NormalizeCharDigit(curChar, radix);
|
||||
|
|
|
@ -109,22 +109,8 @@ CategorySelectionInitializer UnitConverter::SetCurrentCategory(const Category& i
|
|||
vector<Unit>& unitVector = m_categoryToUnits[m_currentCategory];
|
||||
for (unsigned int i = 0; i < unitVector.size(); i++)
|
||||
{
|
||||
if (unitVector[i].id == m_fromType.id)
|
||||
{
|
||||
unitVector[i].isConversionSource = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
unitVector[i].isConversionSource = false;
|
||||
}
|
||||
if (unitVector[i].id == m_toType.id)
|
||||
{
|
||||
unitVector[i].isConversionTarget = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
unitVector[i].isConversionTarget = false;
|
||||
}
|
||||
unitVector[i].isConversionSource = (unitVector[i].id == m_fromType.id);
|
||||
unitVector[i].isConversionTarget = (unitVector[i].id == m_toType.id);
|
||||
}
|
||||
m_currentCategory = input;
|
||||
if (!m_currentCategory.supportsNegative && m_currentDisplay.front() == L'-')
|
||||
|
@ -156,8 +142,11 @@ Category UnitConverter::GetCurrentCategory()
|
|||
/// <param name="toType">Unit struct we are converting to</param>
|
||||
void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType)
|
||||
{
|
||||
if (CheckLoad())
|
||||
if (!CheckLoad())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_fromType = fromType;
|
||||
m_toType = toType;
|
||||
Calculate();
|
||||
|
@ -165,7 +154,6 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType
|
|||
UpdateCurrencySymbols();
|
||||
UpdateViewModel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches the active field, indicating that we are now entering data into
|
||||
|
@ -181,8 +169,11 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType
|
|||
/// </param>
|
||||
void UnitConverter::SwitchActive(const wstring& newValue)
|
||||
{
|
||||
if (CheckLoad())
|
||||
if (!CheckLoad())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
swap(m_fromType, m_toType);
|
||||
swap(m_currentHasDecimal, m_returnHasDecimal);
|
||||
m_returnDisplay = m_currentDisplay;
|
||||
|
@ -198,7 +189,6 @@ void UnitConverter::SwitchActive(const wstring& newValue)
|
|||
m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wstring UnitConverter::CategoryToString(const Category& c, const wchar_t * delimiter)
|
||||
{
|
||||
|
@ -291,8 +281,11 @@ wstring UnitConverter::ConversionDataToString(ConversionData d, const wchar_t *
|
|||
/// </summary>
|
||||
wstring UnitConverter::Serialize()
|
||||
{
|
||||
if (CheckLoad())
|
||||
if (!CheckLoad())
|
||||
{
|
||||
return wstring();
|
||||
}
|
||||
|
||||
wstringstream out(wstringstream::out);
|
||||
const wchar_t * delimiter = L";";
|
||||
|
||||
|
@ -336,11 +329,6 @@ wstring UnitConverter::Serialize()
|
|||
wstring test = out.str();
|
||||
return test;
|
||||
}
|
||||
else
|
||||
{
|
||||
return wstring();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// De-Serializes the data in the converter from a string
|
||||
|
@ -349,8 +337,12 @@ wstring UnitConverter::Serialize()
|
|||
void UnitConverter::DeSerialize(const wstring& serializedData)
|
||||
{
|
||||
Reset();
|
||||
if (!serializedData.empty())
|
||||
|
||||
if (serializedData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vector<wstring> outerTokens = StringToVector(serializedData, L"|");
|
||||
assert(outerTokens.size() == EXPECTEDSERIALIZEDTOKENCOUNT);
|
||||
m_fromType = StringToUnit(outerTokens[0]);
|
||||
|
@ -398,7 +390,6 @@ void UnitConverter::DeSerialize(const wstring& serializedData)
|
|||
}
|
||||
UpdateViewModel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// De-Serializes the data in the converter from a string
|
||||
|
@ -406,8 +397,11 @@ void UnitConverter::DeSerialize(const wstring& serializedData)
|
|||
/// <param name="userPreferences">wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it</param>
|
||||
void UnitConverter::RestoreUserPreferences(const wstring& userPreferences)
|
||||
{
|
||||
if (!userPreferences.empty())
|
||||
if (userPreferences.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
|
||||
if (outerTokens.size() == 3)
|
||||
{
|
||||
|
@ -416,7 +410,6 @@ void UnitConverter::RestoreUserPreferences(const wstring& userPreferences)
|
|||
m_currentCategory = StringToCategory(outerTokens[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the Category and Associated Units in the converter and returns it as a string
|
||||
|
@ -503,8 +496,11 @@ wstring UnitConverter::Unquote(const wstring& s)
|
|||
/// <param name="command">Command enum representing the command that was entered</param>
|
||||
void UnitConverter::SendCommand(Command command)
|
||||
{
|
||||
if (CheckLoad())
|
||||
if (!CheckLoad())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Localization of characters
|
||||
bool clearFront = false;
|
||||
if (m_currentDisplay == L"0")
|
||||
|
@ -641,7 +637,6 @@ void UnitConverter::SendCommand(Command command)
|
|||
|
||||
UpdateViewModel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback interface to send display update calls to
|
||||
|
@ -844,8 +839,11 @@ void UnitConverter::Reset()
|
|||
ClearValues();
|
||||
m_switchedActive = false;
|
||||
|
||||
if (!m_categories.empty())
|
||||
if (m_categories.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentCategory = m_categories[0];
|
||||
|
||||
m_categoryToUnits.clear();
|
||||
|
@ -885,7 +883,6 @@ void UnitConverter::Reset()
|
|||
InitializeSelectedUnits();
|
||||
Calculate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the active data loader based on the input category.
|
||||
|
@ -1029,8 +1026,11 @@ void UnitConverter::Calculate()
|
|||
/// <param name="input">wstring to trim</param>
|
||||
void UnitConverter::TrimString(wstring& returnString)
|
||||
{
|
||||
if (returnString.find(L'.') != m_returnDisplay.npos)
|
||||
if (returnString.find(L'.') == m_returnDisplay.npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wstring::iterator iter;
|
||||
for (iter = returnString.end() - 1; ;iter--)
|
||||
{
|
||||
|
@ -1045,7 +1045,6 @@ void UnitConverter::TrimString(wstring& returnString)
|
|||
returnString.erase(returnString.end()-1, returnString.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the given double to the given number of significant digits
|
||||
|
|
|
@ -12,6 +12,7 @@ using namespace CalculatorApp::Common::DateCalculation;
|
|||
DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier)
|
||||
{
|
||||
m_calendar = ref new Calendar();
|
||||
m_calendar->ChangeTimeZone("UTC");
|
||||
m_calendar->ChangeCalendarSystem(calendarIdentifier);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,7 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
|
|||
m_StrDateDiffResultAutomationName(L""),
|
||||
m_StrDateDiffResultInDays(L""),
|
||||
m_StrDateResult(L""),
|
||||
m_StrDateResultAutomationName(L""),
|
||||
m_fromDate({ 0 }),
|
||||
m_toDate({ 0 }),
|
||||
m_startDate({ 0 }),
|
||||
m_dateResult({ 0 })
|
||||
m_StrDateResultAutomationName(L"")
|
||||
{
|
||||
const auto& localizationSettings = LocalizationSettings::GetInstance();
|
||||
|
||||
|
@ -56,19 +52,19 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
|
|||
|
||||
// Initialize Date Calc engine
|
||||
m_dateCalcEngine = make_shared<DateCalculationEngine>(localizationSettings.GetCalendarIdentifier());
|
||||
|
||||
// Initialize dates of DatePicker controls to today's date
|
||||
auto calendar = ref new Calendar();
|
||||
// We force the timezone to UTC, in order to avoid being affected by Daylight Saving Time
|
||||
// when we calculate the difference between 2 dates.
|
||||
calendar->ChangeTimeZone("UTC");
|
||||
auto 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);
|
||||
m_fromDate = ClipTime(today);
|
||||
m_toDate = ClipTime(today);
|
||||
|
||||
// StartDate should not be clipped
|
||||
StartDate = today;
|
||||
m_startDate = today;
|
||||
m_dateResult = today;
|
||||
|
||||
// Initialize the list separator delimiter appended with a space at the end, e.g. ", "
|
||||
|
@ -86,15 +82,6 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
|
|||
m_offsetValues->Append(ref new String(numberStr.c_str()));
|
||||
}
|
||||
|
||||
/* In the ClipTime function, we used to change timezone to UTC before clipping the time.
|
||||
The comment from the previous developers 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);
|
||||
|
@ -383,13 +370,14 @@ String^ DateCalculatorViewModel::GetLocalizedNumberString(int value) const
|
|||
return ref new String(numberStr.c_str());
|
||||
}
|
||||
|
||||
// Adjusts the given DateTime to 12AM of the same day
|
||||
// Adjusts the given DateTime to 12AM (UTC) of the same day
|
||||
DateTime DateCalculatorViewModel::ClipTime(DateTime dateTime)
|
||||
{
|
||||
auto calendar = ref new Calendar();
|
||||
calendar->ChangeTimeZone("UTC");
|
||||
calendar->SetDateTime(dateTime);
|
||||
calendar->Period = 1;
|
||||
calendar->Hour = 12;
|
||||
calendar->Period = calendar->FirstPeriodInThisDay;
|
||||
calendar->Hour = calendar->FirstHourInThisPeriod;
|
||||
calendar->Minute = 0;
|
||||
calendar->Second = 0;
|
||||
calendar->Nanosecond = 0;
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace CalculatorApp
|
|||
// Input Properties
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsDateDiffMode);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsAddMode);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsDiffInDays); // If diff is only in days or the dates are the same,
|
||||
OBSERVABLE_PROPERTY_R(bool, IsDiffInDays); // If diff is only in days or the dates are the same,
|
||||
// then show only one result and avoid redundancy
|
||||
|
||||
OBSERVABLE_PROPERTY_RW(int, DaysOffset);
|
||||
|
@ -82,11 +82,11 @@ namespace CalculatorApp
|
|||
}
|
||||
|
||||
// Output Properties
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResult);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResultAutomationName);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResultInDays);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateResult);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateResultAutomationName);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResult);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResultAutomationName);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResultInDays);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String^, StrDateResult);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String^, StrDateResultAutomationName);
|
||||
|
||||
COMMAND_FOR_METHOD(CopyCommand, DateCalculatorViewModel::OnCopyCommand);
|
||||
|
||||
|
@ -104,8 +104,6 @@ namespace CalculatorApp
|
|||
Platform::String^ GetLocalizedNumberString(int value) const;
|
||||
static Windows::Foundation::DateTime ClipTime(Windows::Foundation::DateTime dateTime);
|
||||
|
||||
static void CheckClipTimeSameDay(Windows::Globalization::Calendar^ reference);
|
||||
|
||||
property bool IsOutOfBound
|
||||
{
|
||||
bool get() { return m_isOutOfBound; }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pch.h"
|
||||
|
@ -53,6 +53,8 @@ constexpr size_t SELECTED_TARGET_UNIT = 2;
|
|||
|
||||
// x millisecond delay before we consider conversion to be final
|
||||
constexpr unsigned int CONVERSION_FINALIZED_DELAY_IN_MS = 1000;
|
||||
const wregex regexTrimSpacesStart = wregex(L"^\\s+");
|
||||
const wregex regexTrimSpacesEnd = wregex(L"\\s+$");
|
||||
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
|
@ -202,13 +204,11 @@ void UnitConverterViewModel::BuildUnitList(const vector<UCM::Unit>& modelUnitLis
|
|||
m_Units->Clear();
|
||||
for (const UCM::Unit& modelUnit : modelUnitList)
|
||||
{
|
||||
if (modelUnit.isWhimsical)
|
||||
if (!modelUnit.isWhimsical)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_Units->Append(ref new Unit(modelUnit));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Units->Size == 0)
|
||||
{
|
||||
|
@ -348,10 +348,15 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
|
|||
if (pos != wstring::npos)
|
||||
{
|
||||
currencyResult.erase(pos, currencyCode.length());
|
||||
pos = currencyResult.find(L'\u00a0'); // non-breaking space
|
||||
if (pos != wstring::npos)
|
||||
std::wsmatch sm;
|
||||
if (regex_search(currencyResult, sm, regexTrimSpacesStart))
|
||||
{
|
||||
currencyResult.erase(pos, 1);
|
||||
currencyResult.erase(sm.prefix().length(), sm.length());
|
||||
}
|
||||
|
||||
if (regex_search(currencyResult, sm, regexTrimSpacesEnd))
|
||||
{
|
||||
currencyResult.erase(sm.prefix().length(), sm.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,11 +648,9 @@ String^ UnitConverterViewModel::Serialize()
|
|||
String^ serializedData = ref new String(wstring(out.str()).c_str());
|
||||
return serializedData;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void UnitConverterViewModel::Deserialize(Platform::String^ state)
|
||||
{
|
||||
|
@ -879,14 +882,11 @@ void UnitConverterViewModel::UpdateInputBlocked(_In_ const wstring& currencyInpu
|
|||
{
|
||||
// currencyInput is in en-US and has the default decimal separator, so this is safe to do.
|
||||
auto posOfDecimal = currencyInput.find(L'.');
|
||||
m_isInputBlocked = false;
|
||||
if (posOfDecimal != wstring::npos && IsCurrencyCurrentCategory)
|
||||
{
|
||||
m_isInputBlocked = (posOfDecimal + static_cast<size_t>(m_currencyMaxFractionDigits) + 1 == currencyInput.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isInputBlocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId(
|
||||
|
@ -988,7 +988,7 @@ void UnitConverterViewModel::OnPaste(String^ stringToPaste, ViewMode mode)
|
|||
}
|
||||
|
||||
// Negate is only allowed if it's the first legal character, which is handled above.
|
||||
if (NumbersAndOperatorsEnum::None != op && NumbersAndOperatorsEnum::Negate != op)
|
||||
if (NumbersAndOperatorsEnum::Negate != op)
|
||||
{
|
||||
UCM::Command cmd = CommandFromButtonId(op);
|
||||
m_model->SendCommand(cmd);
|
||||
|
|
|
@ -515,6 +515,7 @@
|
|||
<Setter Target="M5.MaxWidth" Value="80"/>
|
||||
<Setter Target="memButton.(Grid.Column)" Value="5"/>
|
||||
<Setter Target="MemoryButton.(Grid.Column)" Value="6"/>
|
||||
<Setter Target="HistoryButton.Visibility" Value="Collapsed"/>
|
||||
</VisualState.Setters>
|
||||
<Storyboard Completed="OnStoryboardCompleted"/>
|
||||
</VisualState>
|
||||
|
|
|
@ -415,7 +415,7 @@ void Calculator::UpdateHistoryState()
|
|||
SetChildAsHistory();
|
||||
HistoryButton->Visibility = ::Visibility::Collapsed;
|
||||
|
||||
if (m_IsLastFlyoutHistory)
|
||||
if (!IsProgrammer && m_IsLastFlyoutHistory)
|
||||
{
|
||||
DockPivot->SelectedIndex = 0;
|
||||
}
|
||||
|
@ -522,7 +522,7 @@ void Calculator::HistoryFlyout_Closed(_In_ Object ^sender, _In_ Object ^args)
|
|||
AutomationProperties::SetName(HistoryButton, m_openHistoryFlyoutAutomationName);
|
||||
m_fIsHistoryFlyoutOpen = false;
|
||||
EnableControls(true);
|
||||
if (HistoryButton->IsEnabled)
|
||||
if (HistoryButton->IsEnabled && HistoryButton->Visibility == ::Visibility::Visible)
|
||||
{
|
||||
HistoryButton->Focus(::FocusState::Programmatic);
|
||||
}
|
||||
|
|
|
@ -387,6 +387,63 @@ namespace DateCalculationUnitTests
|
|||
VERIFY_IS_TRUE(StringReference(L"") != viewModel->StrDateResult);
|
||||
}
|
||||
|
||||
TEST_METHOD(DateCalcViewModelDateDiffDaylightSavingTimeTest)
|
||||
{
|
||||
auto viewModel = ref new DateCalculatorViewModel();
|
||||
|
||||
viewModel->IsDateDiffMode = true;
|
||||
VERIFY_IS_TRUE(viewModel->IsDateDiffMode);
|
||||
|
||||
// 29.02.2008
|
||||
viewModel->FromDate = DateUtils::SystemTimeToDateTime(datetimeDifftest[5].startDate);
|
||||
// 31.03.2008
|
||||
viewModel->ToDate = DateUtils::SystemTimeToDateTime(datetimeDifftest[5].endDate);
|
||||
|
||||
//// Assert for the result
|
||||
VERIFY_IS_FALSE(viewModel->IsDiffInDays);
|
||||
VERIFY_ARE_EQUAL(StringReference(L"31 days"), viewModel->StrDateDiffResultInDays);
|
||||
VERIFY_ARE_EQUAL(StringReference(L"1 month, 2 days"), viewModel->StrDateDiffResult);
|
||||
|
||||
// Daylight Saving Time - Clock Forward
|
||||
// 10.03.2019
|
||||
SYSTEMTIME startDate;
|
||||
startDate.wYear = 2019;
|
||||
startDate.wMonth = 03;
|
||||
startDate.wDay = 10;
|
||||
startDate.wDayOfWeek = 0;
|
||||
startDate.wHour = startDate.wMinute = 0;
|
||||
startDate.wSecond = startDate.wMilliseconds = 0;
|
||||
viewModel->FromDate = DateUtils::SystemTimeToDateTime(startDate);
|
||||
// 11.03.2019
|
||||
SYSTEMTIME endDate;
|
||||
endDate.wYear = 2019;
|
||||
endDate.wMonth = 03;
|
||||
endDate.wDay = 11;
|
||||
endDate.wDayOfWeek = 0;
|
||||
endDate.wHour = endDate.wMinute = 0;
|
||||
endDate.wSecond = endDate.wMilliseconds = 0;
|
||||
viewModel->ToDate = DateUtils::SystemTimeToDateTime(endDate);
|
||||
VERIFY_IS_TRUE(viewModel->IsDiffInDays);
|
||||
VERIFY_ARE_EQUAL(StringReference(L"1 day"), viewModel->StrDateDiffResult);
|
||||
|
||||
endDate.wDay += 6;
|
||||
viewModel->ToDate = DateUtils::SystemTimeToDateTime(endDate);
|
||||
VERIFY_IS_FALSE(viewModel->IsDiffInDays);
|
||||
VERIFY_ARE_EQUAL(StringReference(L"1 week"), viewModel->StrDateDiffResult);
|
||||
|
||||
// Daylight Saving Time - Clock Backward
|
||||
// 03.11.2019
|
||||
startDate.wMonth = 11;
|
||||
startDate.wDay = 03;
|
||||
viewModel->FromDate = DateUtils::SystemTimeToDateTime(startDate);
|
||||
// 04.11.2019
|
||||
endDate.wMonth = 11;
|
||||
endDate.wDay = 04;
|
||||
viewModel->ToDate = DateUtils::SystemTimeToDateTime(endDate);
|
||||
VERIFY_IS_TRUE(viewModel->IsDiffInDays);
|
||||
VERIFY_ARE_EQUAL(StringReference(L"1 day"), viewModel->StrDateDiffResult);
|
||||
}
|
||||
|
||||
TEST_METHOD(DateCalcViewModelAddTest)
|
||||
{
|
||||
// TODO - MSFT 10331900, fix this test
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue