mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-20 21:33:10 -07:00
Use different formatter for different currency
This commit is contained in:
parent
483dacbeff
commit
24f3fb2ad6
2 changed files with 116 additions and 27 deletions
|
@ -134,7 +134,6 @@ UnitConverterViewModel::UnitConverterViewModel(const shared_ptr<UCM::IUnitConver
|
|||
m_currencyFormatter->IsGrouped = true;
|
||||
m_currencyFormatter->Mode = CurrencyFormatterMode::UseCurrencyCode;
|
||||
m_currencyFormatter->ApplyRoundingForCurrency(RoundingAlgorithm::RoundHalfDown);
|
||||
m_currencyMaxFractionDigits = m_currencyFormatter->FractionDigits;
|
||||
|
||||
auto resourceLoader = AppResourceProvider::GetInstance();
|
||||
m_localizedValueFromFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueFromFormat);
|
||||
|
@ -228,6 +227,8 @@ void UnitConverterViewModel::OnUnitChanged(Object ^ parameter)
|
|||
return;
|
||||
}
|
||||
|
||||
UpdateCurrencyFormatter();
|
||||
|
||||
m_model->SetCurrentUnitTypes(UnitFrom->GetModelUnit(), UnitTo->GetModelUnit());
|
||||
if (m_supplementaryResultsTimer != nullptr)
|
||||
{
|
||||
|
@ -246,7 +247,7 @@ void UnitConverterViewModel::OnSwitchActive(Platform::Object ^ unused)
|
|||
if (m_relocalizeStringOnSwitch)
|
||||
{
|
||||
// clean up any ill-formed strings that were in progress before the switch
|
||||
ValueFrom = ConvertToLocalizedString(m_valueFromUnlocalized, false);
|
||||
ValueFrom = ConvertToLocalizedString(m_valueFromUnlocalized, false, CurrencyFormatterParameterFrom);
|
||||
}
|
||||
|
||||
SwitchConversionParameters();
|
||||
|
@ -271,7 +272,7 @@ void UnitConverterViewModel::OnSwitchActive(Platform::Object ^ unused)
|
|||
m_model->SwitchActive(m_valueFromUnlocalized);
|
||||
}
|
||||
|
||||
String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings)
|
||||
String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings, CurrencyFormatterParameter cfp)
|
||||
{
|
||||
Platform::String ^ result;
|
||||
|
||||
|
@ -280,10 +281,33 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st
|
|||
return result;
|
||||
}
|
||||
|
||||
CurrencyFormatter ^ currencyFormatter;
|
||||
|
||||
switch (cfp)
|
||||
{
|
||||
case CurrencyFormatterParameter::Default:
|
||||
currencyFormatter = m_currencyFormatter;
|
||||
break;
|
||||
case CurrencyFormatterParameter::ForValue1:
|
||||
currencyFormatter = m_currencyFormatter1;
|
||||
break;
|
||||
case CurrencyFormatterParameter::ForValue2:
|
||||
currencyFormatter = m_currencyFormatter2;
|
||||
break;
|
||||
}
|
||||
|
||||
// If unit hasn't been set, currencyFormatter1/2 is nullptr. Fallback to default.
|
||||
if (currencyFormatter == nullptr)
|
||||
{
|
||||
currencyFormatter = m_currencyFormatter;
|
||||
}
|
||||
|
||||
int lastCurrencyFractionDigits = currencyFormatter->FractionDigits;
|
||||
|
||||
m_decimalFormatter->IsDecimalPointAlwaysDisplayed = false;
|
||||
m_decimalFormatter->FractionDigits = 0;
|
||||
m_currencyFormatter->IsDecimalPointAlwaysDisplayed = false;
|
||||
m_currencyFormatter->FractionDigits = 0;
|
||||
currencyFormatter->IsDecimalPointAlwaysDisplayed = false;
|
||||
currencyFormatter->FractionDigits = 0;
|
||||
|
||||
wstring::size_type posOfE = stringToLocalize.find(L'e');
|
||||
if (posOfE != wstring::npos)
|
||||
|
@ -293,7 +317,8 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st
|
|||
std::wstring significandStr(stringToLocalize.substr(0, posOfE));
|
||||
std::wstring exponentStr(stringToLocalize.substr(posOfSign + 1, stringToLocalize.length() - posOfSign));
|
||||
|
||||
result += ConvertToLocalizedString(significandStr, allowPartialStrings) + "e" + signOfE + ConvertToLocalizedString(exponentStr, allowPartialStrings);
|
||||
result += ConvertToLocalizedString(significandStr, allowPartialStrings, cfp) + "e" + signOfE
|
||||
+ ConvertToLocalizedString(exponentStr, allowPartialStrings, cfp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -312,18 +337,18 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st
|
|||
// typed a post-decimal digit.
|
||||
|
||||
m_decimalFormatter->IsDecimalPointAlwaysDisplayed = true;
|
||||
m_currencyFormatter->IsDecimalPointAlwaysDisplayed = true;
|
||||
currencyFormatter->IsDecimalPointAlwaysDisplayed = true;
|
||||
}
|
||||
|
||||
// force post-decimal digits so that trailing zeroes entered by the user aren't suddenly cut off.
|
||||
m_decimalFormatter->FractionDigits = static_cast<int>(stringToLocalize.length() - (posOfDecimal + 1));
|
||||
m_currencyFormatter->FractionDigits = m_currencyMaxFractionDigits;
|
||||
currencyFormatter->FractionDigits = lastCurrencyFractionDigits;
|
||||
}
|
||||
|
||||
if (IsCurrencyCurrentCategory)
|
||||
{
|
||||
wstring currencyResult = m_currencyFormatter->Format(stod(stringToLocalize))->Data();
|
||||
wstring currencyCode = m_currencyFormatter->Currency->Data();
|
||||
wstring currencyResult = currencyFormatter->Format(stod(stringToLocalize))->Data();
|
||||
wstring currencyCode = currencyFormatter->Currency->Data();
|
||||
|
||||
// CurrencyFormatter always includes LangCode or Symbol. Make it include LangCode
|
||||
// because this includes a non-breaking space. Remove the LangCode.
|
||||
|
@ -370,6 +395,8 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st
|
|||
// Copy back the edited string to the result
|
||||
result = ref new String(resultWithDecimal.c_str());
|
||||
}
|
||||
|
||||
currencyFormatter->FractionDigits = lastCurrencyFractionDigits;
|
||||
}
|
||||
|
||||
wstring resultHolder = wstring(result->Data());
|
||||
|
@ -394,9 +421,9 @@ void UnitConverterViewModel::DisplayPasteError()
|
|||
|
||||
void UnitConverterViewModel::UpdateDisplay(const wstring& from, const wstring& to)
|
||||
{
|
||||
String ^ fromStr = this->ConvertToLocalizedString(from, true);
|
||||
String ^ fromStr = this->ConvertToLocalizedString(from, true, CurrencyFormatterParameterFrom);
|
||||
UpdateInputBlocked(from);
|
||||
String ^ toStr = this->ConvertToLocalizedString(to, true);
|
||||
String ^ toStr = this->ConvertToLocalizedString(to, true, CurrencyFormatterParameterTo);
|
||||
|
||||
bool updatedValueFrom = ValueFrom != fromStr;
|
||||
bool updatedValueTo = ValueTo != toStr;
|
||||
|
@ -473,14 +500,14 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter)
|
|||
}
|
||||
|
||||
static constexpr UCM::Command OPERANDS[] = { UCM::Command::Zero, UCM::Command::One, UCM::Command::Two, UCM::Command::Three, UCM::Command::Four,
|
||||
UCM::Command::Five, UCM::Command::Six, UCM::Command::Seven, UCM::Command::Eight, UCM::Command::Nine };
|
||||
UCM::Command::Five, UCM::Command::Six, UCM::Command::Seven, UCM::Command::Eight, UCM::Command::Nine };
|
||||
if (m_isInputBlocked &&
|
||||
command != UCM::Command::Clear &&
|
||||
command != UCM::Command::Backspace)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_model->SendCommand(command);
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_model->SendCommand(command);
|
||||
|
||||
TraceLogger::GetInstance()->LogConverterInputReceived(Mode);
|
||||
}
|
||||
|
@ -755,8 +782,8 @@ void UnitConverterViewModel::RefreshSupplementaryResults()
|
|||
|
||||
for (tuple<wstring, UCM::Unit> suggestedValue : m_cachedSuggestedValues)
|
||||
{
|
||||
SupplementaryResult ^ result =
|
||||
ref new SupplementaryResult(this->ConvertToLocalizedString(get<0>(suggestedValue), false), ref new Unit(get<1>(suggestedValue)));
|
||||
SupplementaryResult ^ result = ref new SupplementaryResult(
|
||||
this->ConvertToLocalizedString(get<0>(suggestedValue), false, CurrencyFormatterParameter::Default), ref new Unit(get<1>(suggestedValue)));
|
||||
if (result->IsWhimsical())
|
||||
{
|
||||
whimsicals.push_back(result);
|
||||
|
@ -803,10 +830,26 @@ void UnitConverterViewModel::UpdateInputBlocked(_In_ const wstring& currencyInpu
|
|||
m_isInputBlocked = false;
|
||||
if (posOfDecimal != wstring::npos && IsCurrencyCurrentCategory)
|
||||
{
|
||||
m_isInputBlocked = (posOfDecimal + static_cast<size_t>(m_currencyMaxFractionDigits) + 1 == currencyInput.length());
|
||||
m_isInputBlocked = (posOfDecimal + static_cast<size_t>(CurrencyFormatterFrom->FractionDigits) + 1 == currencyInput.length());
|
||||
}
|
||||
}
|
||||
|
||||
void UnitConverterViewModel::UpdateCurrencyFormatter()
|
||||
{
|
||||
if (!IsCurrencyCurrentCategory || m_Unit1->Abbreviation->IsEmpty() || m_Unit2->Abbreviation->IsEmpty())
|
||||
return;
|
||||
|
||||
m_currencyFormatter1 = ref new CurrencyFormatter(m_Unit1->Abbreviation);
|
||||
m_currencyFormatter1->IsGrouped = true;
|
||||
m_currencyFormatter1->Mode = CurrencyFormatterMode::UseCurrencyCode;
|
||||
m_currencyFormatter1->ApplyRoundingForCurrency(RoundingAlgorithm::RoundHalfDown);
|
||||
|
||||
m_currencyFormatter2 = ref new CurrencyFormatter(m_Unit2->Abbreviation);
|
||||
m_currencyFormatter2->IsGrouped = true;
|
||||
m_currencyFormatter2->Mode = CurrencyFormatterMode::UseCurrencyCode;
|
||||
m_currencyFormatter2->ApplyRoundingForCurrency(RoundingAlgorithm::RoundHalfDown);
|
||||
}
|
||||
|
||||
NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate)
|
||||
{
|
||||
static_assert(NumbersAndOperatorsEnum::Zero < NumbersAndOperatorsEnum::One, "NumbersAndOperatorsEnum order is invalid");
|
||||
|
@ -934,14 +977,19 @@ void UnitConverterViewModel::OnPaste(String ^ stringToPaste)
|
|||
}
|
||||
}
|
||||
|
||||
String ^ UnitConverterViewModel::GetLocalizedAutomationName(_In_ String ^ displayvalue, _In_ String ^ unitname, _In_ String ^ format)
|
||||
String
|
||||
^ UnitConverterViewModel::GetLocalizedAutomationName(
|
||||
_In_ String ^ displayvalue,
|
||||
_In_ String ^ unitname,
|
||||
_In_ String ^ format,
|
||||
_In_ CurrencyFormatterParameter cfp)
|
||||
{
|
||||
String ^ valueToLocalize = displayvalue;
|
||||
if (displayvalue == ValueFrom && Utils::IsLastCharacterTarget(m_valueFromUnlocalized, m_decimalSeparator))
|
||||
{
|
||||
// Need to compute a second localized value for the automation
|
||||
// name that does not include the decimal separator.
|
||||
displayvalue = ConvertToLocalizedString(m_valueFromUnlocalized, false /*allowTrailingDecimal*/);
|
||||
displayvalue = ConvertToLocalizedString(m_valueFromUnlocalized, false /*allowTrailingDecimal*/, cfp);
|
||||
format = m_localizedValueFromDecimalFormat;
|
||||
}
|
||||
|
||||
|
@ -962,7 +1010,7 @@ void UnitConverterViewModel::UpdateValue1AutomationName()
|
|||
{
|
||||
if (Unit1)
|
||||
{
|
||||
Value1AutomationName = GetLocalizedAutomationName(Value1, Unit1->AccessibleName, m_localizedValueFromFormat);
|
||||
Value1AutomationName = GetLocalizedAutomationName(Value1, Unit1->AccessibleName, m_localizedValueFromFormat, CurrencyFormatterParameter::ForValue1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -970,7 +1018,7 @@ void UnitConverterViewModel::UpdateValue2AutomationName()
|
|||
{
|
||||
if (Unit2)
|
||||
{
|
||||
Value2AutomationName = GetLocalizedAutomationName(Value2, Unit2->AccessibleName, m_localizedValueToFormat);
|
||||
Value2AutomationName = GetLocalizedAutomationName(Value2, Unit2->AccessibleName, m_localizedValueToFormat, CurrencyFormatterParameter::ForValue1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -227,8 +227,19 @@ namespace CalculatorApp
|
|||
void OnCopyCommand(Platform::Object ^ parameter);
|
||||
void OnPasteCommand(Platform::Object ^ parameter);
|
||||
|
||||
enum class CurrencyFormatterParameter
|
||||
{
|
||||
Default,
|
||||
ForValue1,
|
||||
ForValue2,
|
||||
};
|
||||
|
||||
Platform::String
|
||||
^ GetLocalizedAutomationName(_In_ Platform::String ^ displayvalue, _In_ Platform::String ^ unitname, _In_ Platform::String ^ format);
|
||||
^ GetLocalizedAutomationName(
|
||||
_In_ Platform::String ^ displayvalue,
|
||||
_In_ Platform::String ^ unitname,
|
||||
_In_ Platform::String ^ format,
|
||||
_In_ CurrencyFormatterParameter cfp);
|
||||
Platform::String
|
||||
^ GetLocalizedConversionResultStringFormat(
|
||||
_In_ Platform::String ^ fromValue,
|
||||
|
@ -276,11 +287,12 @@ namespace CalculatorApp
|
|||
void SupplementaryResultsTimerCancel(Windows::System::Threading::ThreadPoolTimer ^ timer);
|
||||
void RefreshSupplementaryResults();
|
||||
void UpdateInputBlocked(_In_ const std::wstring& currencyInput);
|
||||
void UpdateCurrencyFormatter();
|
||||
bool UnitsAreValid();
|
||||
void ResetCategory();
|
||||
|
||||
void OnButtonPressed(Platform::Object ^ parameter);
|
||||
Platform::String ^ ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings);
|
||||
Platform::String ^ ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings, CurrencyFormatterParameter cfp);
|
||||
|
||||
std::shared_ptr<UnitConversionManager::IUnitConverter> m_model;
|
||||
wchar_t m_decimalSeparator;
|
||||
|
@ -290,6 +302,34 @@ namespace CalculatorApp
|
|||
Source,
|
||||
Target
|
||||
} m_value1cp;
|
||||
property CurrencyFormatterParameter CurrencyFormatterParameterFrom
|
||||
{
|
||||
CurrencyFormatterParameter get()
|
||||
{
|
||||
return m_value1cp == ConversionParameter::Source ? CurrencyFormatterParameter::ForValue1 : CurrencyFormatterParameter::ForValue2;
|
||||
}
|
||||
}
|
||||
property CurrencyFormatterParameter CurrencyFormatterParameterTo
|
||||
{
|
||||
CurrencyFormatterParameter get()
|
||||
{
|
||||
return m_value1cp == ConversionParameter::Target ? CurrencyFormatterParameter::ForValue1 : CurrencyFormatterParameter::ForValue2;
|
||||
}
|
||||
}
|
||||
property Windows::Globalization::NumberFormatting::CurrencyFormatter^ CurrencyFormatterFrom
|
||||
{
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter^ get()
|
||||
{
|
||||
return m_value1cp == ConversionParameter::Source ? m_currencyFormatter1 : m_currencyFormatter2;
|
||||
}
|
||||
}
|
||||
property Windows::Globalization::NumberFormatting::CurrencyFormatter^ CurrencyFormatterTo
|
||||
{
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter^ get()
|
||||
{
|
||||
return m_value1cp == ConversionParameter::Target ? m_currencyFormatter1 : m_currencyFormatter2;
|
||||
}
|
||||
}
|
||||
property Platform::String^ ValueFrom
|
||||
{
|
||||
Platform::String^ get() { return m_value1cp == ConversionParameter::Source ? Value1 : Value2; }
|
||||
|
@ -323,7 +363,8 @@ namespace CalculatorApp
|
|||
std::mutex m_cacheMutex;
|
||||
Windows::Globalization::NumberFormatting::DecimalFormatter ^ m_decimalFormatter;
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ m_currencyFormatter;
|
||||
int m_currencyMaxFractionDigits;
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ m_currencyFormatter1;
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ m_currencyFormatter2;
|
||||
std::wstring m_valueFromUnlocalized;
|
||||
std::wstring m_valueToUnlocalized;
|
||||
bool m_relocalizeStringOnSwitch;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue