diff --git a/src/CalcManager/UnitConverter.cpp b/src/CalcManager/UnitConverter.cpp index d760b611..3d4b1865 100644 --- a/src/CalcManager/UnitConverter.cpp +++ b/src/CalcManager/UnitConverter.cpp @@ -24,7 +24,7 @@ static constexpr uint32_t OPTIMALDIGITSALLOWED = 7U; static constexpr wchar_t LEFTESCAPECHAR = L'{'; static constexpr wchar_t RIGHTESCAPECHAR = L'}'; -static const double OPTIMALDECIMALALLOWED = 1e-6; // pow(10, -1 * (OPTIMALDIGITSALLOWED - 1)); +static const double OPTIMALDECIMALALLOWED = 1e-6; // pow(10, -1 * (OPTIMALDIGITSALLOWED - 1)); static const double MINIMUMDECIMALALLOWED = 1e-14; // pow(10, -1 * (MAXIMUMDIGITSALLOWED - 1)); unordered_map quoteConversions; @@ -149,6 +149,11 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType return; } + if (m_fromType != fromType) + { + m_switchedActive = true; + } + m_fromType = fromType; m_toType = toType; Calculate(); @@ -191,6 +196,11 @@ void UnitConverter::SwitchActive(const wstring& newValue) } } +bool UnitConversionManager::UnitConverter::IsSwitchedActive() const +{ + return m_switchedActive; +} + wstring UnitConverter::CategoryToString(const Category& c, wstring_view delimiter) { return Quote(std::to_wstring(c.id)) diff --git a/src/CalcManager/UnitConverter.h b/src/CalcManager/UnitConverter.h index 81a2629f..fe085dcb 100644 --- a/src/CalcManager/UnitConverter.h +++ b/src/CalcManager/UnitConverter.h @@ -223,6 +223,7 @@ namespace UnitConversionManager virtual Category GetCurrentCategory() = 0; virtual void SetCurrentUnitTypes(const Unit& fromType, const Unit& toType) = 0; virtual void SwitchActive(const std::wstring& newValue) = 0; + virtual bool IsSwitchedActive() const = 0; virtual std::wstring SaveUserPreferences() = 0; virtual void RestoreUserPreferences(_In_ std::wstring_view userPreferences) = 0; virtual void SendCommand(Command command) = 0; @@ -246,6 +247,7 @@ namespace UnitConversionManager Category GetCurrentCategory() override; void SetCurrentUnitTypes(const Unit& fromType, const Unit& toType) override; void SwitchActive(const std::wstring& newValue) override; + bool IsSwitchedActive() const override; std::wstring SaveUserPreferences() override; void RestoreUserPreferences(std::wstring_view userPreference) override; void SendCommand(Command command) override; diff --git a/src/CalcViewModel/Common/CopyPasteManager.cpp b/src/CalcViewModel/Common/CopyPasteManager.cpp index ae24aad1..8f84eead 100644 --- a/src/CalcViewModel/Common/CopyPasteManager.cpp +++ b/src/CalcViewModel/Common/CopyPasteManager.cpp @@ -502,23 +502,32 @@ ULONG32 CopyPasteManager::StandardScientificOperandLength(Platform::String ^ ope { auto operandWstring = wstring(operand->Data()); const bool hasDecimal = operandWstring.find('.') != wstring::npos; + auto length = operandWstring.length(); if (hasDecimal) { - if (operandWstring.length() >= 2) + if (length >= 2) { if ((operandWstring[0] == L'0') && (operandWstring[1] == L'.')) { - return static_cast(operandWstring.length() - 2); + length -= 2; } else { - return static_cast(operandWstring.length() - 1); + length -= 1; } } } - return static_cast(operandWstring.length()); + auto exponentPos = operandWstring.find('e'); + const bool hasExponent = exponentPos != wstring::npos; + if (hasExponent) + { + auto expLength = operandWstring.substr(exponentPos).length(); + length -= expLength; + } + + return static_cast(length); } ULONG32 CopyPasteManager::ProgrammerOperandLength(Platform::String ^ operand, NumberBase numberBase) diff --git a/src/CalcViewModel/UnitConverterViewModel.cpp b/src/CalcViewModel/UnitConverterViewModel.cpp index a159cf7f..90960eb8 100644 --- a/src/CalcViewModel/UnitConverterViewModel.cpp +++ b/src/CalcViewModel/UnitConverterViewModel.cpp @@ -134,7 +134,6 @@ UnitConverterViewModel::UnitConverterViewModel(const shared_ptrIsGrouped = 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,7 +227,9 @@ void UnitConverterViewModel::OnUnitChanged(Object ^ parameter) return; } + UpdateCurrencyFormatter(); m_model->SetCurrentUnitTypes(UnitFrom->GetModelUnit(), UnitTo->GetModelUnit()); + if (m_supplementaryResultsTimer != nullptr) { // End timer to show results immediately @@ -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(); @@ -269,9 +270,11 @@ void UnitConverterViewModel::OnSwitchActive(Platform::Object ^ unused) m_isInputBlocked = false; m_model->SwitchActive(m_valueFromUnlocalized); + + UpdateIsDecimalEnabled(); } -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 +283,33 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st return result; } + CurrencyFormatter ^ currencyFormatter; + + switch (cfp) + { + case CurrencyFormatterParameter::ForValue1: + currencyFormatter = m_currencyFormatter1; + break; + case CurrencyFormatterParameter::ForValue2: + currencyFormatter = m_currencyFormatter2; + break; + default: + currencyFormatter = m_currencyFormatter; + 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 +319,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 { @@ -304,7 +331,7 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st if (hasDecimal) { - if (allowPartialStrings) + if (allowPartialStrings && lastCurrencyFractionDigits > 0) { // allow "in progress" strings, like "3." that occur during the composition of // a final number. Without this, when typing the three characters in "3.2" @@ -312,18 +339,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(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. @@ -381,6 +408,10 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st } result = L"-" + result; } + + // restore the original fraction digits + currencyFormatter->FractionDigits = lastCurrencyFractionDigits; + return result; } @@ -394,9 +425,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 +504,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 }; - if (m_isInputBlocked && - command != UCM::Command::Clear && - command != UCM::Command::Backspace) - { - return; - } - m_model->SendCommand(command); + UCM::Command::Five, UCM::Command::Six, UCM::Command::Seven, UCM::Command::Eight, UCM::Command::Nine }; + + // input should be allowed if user just switches active, because we will clear values in such cases + if (m_isInputBlocked && !m_model->IsSwitchedActive() && command != UCM::Command::Clear && command != UCM::Command::Backspace) + { + return; + } + m_model->SendCommand(command); TraceLogger::GetInstance()->LogConverterInputReceived(Mode); } @@ -755,8 +786,8 @@ void UnitConverterViewModel::RefreshSupplementaryResults() for (tuple 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 +834,46 @@ void UnitConverterViewModel::UpdateInputBlocked(_In_ const wstring& currencyInpu m_isInputBlocked = false; if (posOfDecimal != wstring::npos && IsCurrencyCurrentCategory) { - m_isInputBlocked = (posOfDecimal + static_cast(m_currencyMaxFractionDigits) + 1 == currencyInput.length()); + m_isInputBlocked = (posOfDecimal + static_cast(CurrencyFormatterFrom->FractionDigits) + 1 == currencyInput.length()); } } +std::wstring TruncateFractionDigits(const std::wstring& n, int digitCount) +{ + auto i = n.find('.'); + if (i == std::wstring::npos) + return n; + size_t actualDigitCount = n.size() - i - 1; + return n.substr(0, n.size() - (actualDigitCount - digitCount)); +} + +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); + + UpdateIsDecimalEnabled(); + + OnPaste(ref new String(TruncateFractionDigits(m_valueFromUnlocalized, CurrencyFormatterFrom->FractionDigits).data())); +} + +void UnitConverterViewModel::UpdateIsDecimalEnabled() +{ + if (!IsCurrencyCurrentCategory || CurrencyFormatterFrom == nullptr) + return; + IsDecimalEnabled = CurrencyFormatterFrom->FractionDigits > 0; +} + NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate) { static_assert(NumbersAndOperatorsEnum::Zero < NumbersAndOperatorsEnum::One, "NumbersAndOperatorsEnum order is invalid"); @@ -934,14 +1001,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 +1034,7 @@ void UnitConverterViewModel::UpdateValue1AutomationName() { if (Unit1) { - Value1AutomationName = GetLocalizedAutomationName(Value1, Unit1->AccessibleName, m_localizedValueFromFormat); + Value1AutomationName = GetLocalizedAutomationName(Value1, Unit1->AccessibleName, m_localizedValueFromFormat, CurrencyFormatterParameter::ForValue1); } } @@ -970,7 +1042,7 @@ void UnitConverterViewModel::UpdateValue2AutomationName() { if (Unit2) { - Value2AutomationName = GetLocalizedAutomationName(Value2, Unit2->AccessibleName, m_localizedValueToFormat); + Value2AutomationName = GetLocalizedAutomationName(Value2, Unit2->AccessibleName, m_localizedValueToFormat, CurrencyFormatterParameter::ForValue1); } } diff --git a/src/CalcViewModel/UnitConverterViewModel.h b/src/CalcViewModel/UnitConverterViewModel.h index a5287e45..b48c1c3b 100644 --- a/src/CalcViewModel/UnitConverterViewModel.h +++ b/src/CalcViewModel/UnitConverterViewModel.h @@ -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,13 @@ namespace CalculatorApp void SupplementaryResultsTimerCancel(Windows::System::Threading::ThreadPoolTimer ^ timer); void RefreshSupplementaryResults(); void UpdateInputBlocked(_In_ const std::wstring& currencyInput); + void UpdateCurrencyFormatter(); + void UpdateIsDecimalEnabled(); 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 m_model; wchar_t m_decimalSeparator; @@ -290,6 +303,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 +364,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; diff --git a/src/Calculator/AboutFlyout.xaml b/src/Calculator/AboutFlyout.xaml index 50f6f4e1..b83dfd83 100644 --- a/src/Calculator/AboutFlyout.xaml +++ b/src/Calculator/AboutFlyout.xaml @@ -14,6 +14,7 @@ + @@ -72,5 +73,21 @@ Click="FeedbackButton_Click"/> + + + + + + + diff --git a/src/Calculator/AboutFlyout.xaml.cpp b/src/Calculator/AboutFlyout.xaml.cpp index 5f295c59..9a84a752 100644 --- a/src/Calculator/AboutFlyout.xaml.cpp +++ b/src/Calculator/AboutFlyout.xaml.cpp @@ -40,6 +40,8 @@ AboutFlyout::AboutFlyout() auto copyrightText = LocalizationStringUtil::GetLocalizedString(resourceLoader->GetResourceString("AboutControlCopyright"), StringReference(to_wstring(BUILD_YEAR).c_str())); AboutControlCopyrightRun->Text = copyrightText; + + InitializeContributeTextBlock(); } void AboutFlyout::FeedbackButton_Click(_In_ Object ^ sender, _In_ RoutedEventArgs ^ e) @@ -61,3 +63,30 @@ void AboutFlyout::SetDefaultFocus() { AboutFlyoutEULA->Focus(::FocusState::Programmatic); } + +void AboutFlyout::InitializeContributeTextBlock() +{ + auto resProvider = AppResourceProvider::GetInstance(); + std::wstring contributeHyperlinkText = resProvider->GetResourceString(L"AboutFlyoutContribute")->Data(); + + // The resource string has the 'GitHub' hyperlink wrapped with '%HL%'. + // Break the string and assign pieces appropriately. + static const std::wstring delimiter{ L"%HL%" }; + static const size_t delimiterLength{ delimiter.length() }; + + // Find the delimiters. + size_t firstSplitPosition = contributeHyperlinkText.find(delimiter, 0); + assert(firstSplitPosition != std::wstring::npos); + size_t secondSplitPosition = contributeHyperlinkText.find(delimiter, firstSplitPosition + 1); + assert(secondSplitPosition != std::wstring::npos); + size_t hyperlinkTextLength = secondSplitPosition - (firstSplitPosition + delimiterLength); + + // Assign pieces. + auto contributeTextBeforeHyperlink = ref new String(contributeHyperlinkText.substr(0, firstSplitPosition).c_str()); + auto contributeTextLink = ref new String(contributeHyperlinkText.substr(firstSplitPosition + delimiterLength, hyperlinkTextLength).c_str()); + auto contributeTextAfterHyperlink = ref new String(contributeHyperlinkText.substr(secondSplitPosition + delimiterLength).c_str()); + + ContributeRunBeforeLink->Text = contributeTextBeforeHyperlink; + ContributeRunLink->Text = contributeTextLink; + ContributeRunAfterLink->Text = contributeTextAfterHyperlink; +} diff --git a/src/Calculator/AboutFlyout.xaml.h b/src/Calculator/AboutFlyout.xaml.h index ab0e481e..f4e47a36 100644 --- a/src/Calculator/AboutFlyout.xaml.h +++ b/src/Calculator/AboutFlyout.xaml.h @@ -18,5 +18,6 @@ public private: void FeedbackButton_Click(_In_ Platform::Object ^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs ^ e); void SetVersionString(); + void InitializeContributeTextBlock(); }; } /* namespace CalculatorApp */ diff --git a/src/Calculator/Resources/en-US/Resources.resw b/src/Calculator/Resources/en-US/Resources.resw index c4c99678..c491f732 100644 --- a/src/Calculator/Resources/en-US/Resources.resw +++ b/src/Calculator/Resources/en-US/Resources.resw @@ -2717,6 +2717,10 @@ © %1 Microsoft. All rights reserved. {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) + + To learn how you can contribute to Windows Calculator, check out the project on %HL%GitHub%HL%. + {Locked="%HL%GitHub%HL%"}. GitHub link, Displayed on the About panel + About The text that shows in the dropdown navigation control to open About panel diff --git a/src/Calculator/Resources/zh-CN/Resources.resw b/src/Calculator/Resources/zh-CN/Resources.resw index dce7e04c..0f22d1a6 100644 --- a/src/Calculator/Resources/zh-CN/Resources.resw +++ b/src/Calculator/Resources/zh-CN/Resources.resw @@ -3392,15 +3392,15 @@ Error displayed when parity is cannot be determined - 此函数为偶数。 + 此函数为偶函数。 Message displayed with the function parity is even - 此函数既不是偶数也不是奇数。 + 此函数既不是偶函数也不是奇函数。 Message displayed with the function parity is neither even nor odd - 函数为奇数。 + 此函数为奇函数。 Message displayed with the function parity is odd diff --git a/src/Calculator/Views/MainPage.xaml b/src/Calculator/Views/MainPage.xaml index dae7b25f..8d0af906 100644 --- a/src/Calculator/Views/MainPage.xaml +++ b/src/Calculator/Views/MainPage.xaml @@ -28,6 +28,7 @@