diff --git a/.editorconfig b/.editorconfig index f3416ab7..a2008871 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,7 +5,6 @@ root = true [*] indent_style = space indent_size = 4 -end_of_line = crlf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true diff --git a/.gitignore b/.gitignore index 80d64f53..2100dfc1 100644 --- a/.gitignore +++ b/.gitignore @@ -290,4 +290,5 @@ __pycache__/ # Calculator specific Generated Files/ !/build/config/TRexDefs/** +!src/Calculator/TemporaryKey.pfx !src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx \ No newline at end of file diff --git a/build/pipelines/azure-pipelines.loc.yaml b/build/pipelines/azure-pipelines.loc.yaml index d2bef95e..d1ef8552 100644 --- a/build/pipelines/azure-pipelines.loc.yaml +++ b/build/pipelines/azure-pipelines.loc.yaml @@ -15,30 +15,33 @@ name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr) jobs: - job: Localize pool: - name: Package ES Custom Demands Lab A - demands: - - ClientAlias -equals PKGESUTILAPPS - workspace: - clean: outputs + vmImage: vs2017-win2016 + variables: + skipComponentGovernanceDetection: true steps: - - checkout: self - clean: true - - task: PkgESSetupBuild@10 - displayName: Initialize Package ES + - task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1 + displayName: Send resources to Touchdown Build inputs: - productName: Calculator - branchVersion: true + teamId: 86 + authId: d3dd8113-65b3-4526-bdca-a00a7d1c37ba + authKey: $(LocServiceKey) + isPreview: false + relativePathRoot: src/Calculator/Resources/en-US/ + resourceFilePath: '*.resw' + outputDirectoryRoot: src/Calculator/Resources/ - - task: PkgESTouchdownLocService@10 - displayName: Package ES Touchdown Loc Service + - script: | + cd $(Build.SourcesDirectory) + git add -A + git diff --cached --exit-code + echo '##vso[task.setvariable variable=hasChanges]%errorlevel%' + git diff --cached > $(Build.ArtifactStagingDirectory)\LocalizedStrings.patch + displayName: Check for changes and create patch file + + - task: PublishPipelineArtifact@0 + displayName: Publish patch file as artifact + condition: eq(variables['hasChanges'], '1') inputs: - IsCallToServiceStepSelected: true - IsCheckedInFileSelected: true - CheckinFilesAtOriginFilePath: true - GitLocPath: Loc/Resources - LocConfigFile: build/config/LocConfigPackageEs.xml - AuthenticationMode: OAuth - ClientApplicationID: d3dd8113-65b3-4526-bdca-a00a7d1c37ba - ApplicationKeyID: $(LocServiceKey) - SendToLoc: true + artifactName: Patch + targetPath: $(Build.ArtifactStagingDirectory) \ No newline at end of file diff --git a/build/pipelines/azure-pipelines.release.yaml b/build/pipelines/azure-pipelines.release.yaml index 78b4fd90..a4507e21 100644 --- a/build/pipelines/azure-pipelines.release.yaml +++ b/build/pipelines/azure-pipelines.release.yaml @@ -9,8 +9,8 @@ pr: none variables: versionMajor: 10 - versionMinor: 1902 - versionBuild: $[counter('10.1902.*', 0)] + versionMinor: 1903 + versionBuild: $[counter('10.1903.*', 0)] versionPatch: 0 name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)' diff --git a/build/pipelines/templates/build-app-internal.yaml b/build/pipelines/templates/build-app-internal.yaml index 8a75dcec..2de18a01 100644 --- a/build/pipelines/templates/build-app-internal.yaml +++ b/build/pipelines/templates/build-app-internal.yaml @@ -29,7 +29,7 @@ jobs: downloadDirectory: $(Build.SourcesDirectory) vstsFeed: WindowsApps vstsFeedPackage: calculator-internals - vstsPackageVersion: 0.0.7 + vstsPackageVersion: 0.0.10 - template: ./build-single-architecture.yaml parameters: diff --git a/build/pipelines/templates/package-appxbundle.yaml b/build/pipelines/templates/package-appxbundle.yaml index 2965c06e..c7735753 100644 --- a/build/pipelines/templates/package-appxbundle.yaml +++ b/build/pipelines/templates/package-appxbundle.yaml @@ -20,6 +20,8 @@ jobs: vmImage: vs2017-win2016 workspace: clean: outputs + variables: + skipComponentGovernanceDetection: true steps: - checkout: self clean: true diff --git a/build/pipelines/templates/prepare-release-internalonly.yaml b/build/pipelines/templates/prepare-release-internalonly.yaml index 6bb3b6cb..363ca049 100644 --- a/build/pipelines/templates/prepare-release-internalonly.yaml +++ b/build/pipelines/templates/prepare-release-internalonly.yaml @@ -17,6 +17,8 @@ jobs: name: Package ES Lab E workspace: clean: outputs + variables: + skipComponentGovernanceDetection: true steps: - checkout: self clean: true @@ -87,7 +89,7 @@ jobs: downloadDirectory: $(Build.SourcesDirectory) vstsFeed: WindowsApps vstsFeedPackage: calculator-internals - vstsPackageVersion: 0.0.7 + vstsPackageVersion: 0.0.10 - task: PkgESStoreBrokerPackage@10 displayName: Create StoreBroker Packages diff --git a/build/pipelines/templates/run-unit-tests.yaml b/build/pipelines/templates/run-unit-tests.yaml index 6123609e..2a000118 100644 --- a/build/pipelines/templates/run-unit-tests.yaml +++ b/build/pipelines/templates/run-unit-tests.yaml @@ -14,6 +14,8 @@ jobs: name: Essential Experiences Interactive workspace: clean: outputs + variables: + skipComponentGovernanceDetection: true steps: - checkout: none diff --git a/docs/Images/CalculatorScreenshot.png b/docs/Images/CalculatorScreenshot.png index 302e66b0..a5c32e96 100644 Binary files a/docs/Images/CalculatorScreenshot.png and b/docs/Images/CalculatorScreenshot.png differ diff --git a/docs/Images/VSInstallationScreenshot.png b/docs/Images/VSInstallationScreenshot.png index baa85c63..30152691 100644 Binary files a/docs/Images/VSInstallationScreenshot.png and b/docs/Images/VSInstallationScreenshot.png differ diff --git a/docs/Images/VisualStates/Converter1.gif b/docs/Images/VisualStates/Converter1.gif index 20923f8e..f8b93a3d 100644 Binary files a/docs/Images/VisualStates/Converter1.gif and b/docs/Images/VisualStates/Converter1.gif differ diff --git a/docs/Images/VisualStates/Scientific1.gif b/docs/Images/VisualStates/Scientific1.gif index a797e7cd..0dc53a51 100644 Binary files a/docs/Images/VisualStates/Scientific1.gif and b/docs/Images/VisualStates/Scientific1.gif differ diff --git a/docs/Images/VisualStates/Standard1.gif b/docs/Images/VisualStates/Standard1.gif index 2396e8df..d3ba3a7c 100644 Binary files a/docs/Images/VisualStates/Standard1.gif and b/docs/Images/VisualStates/Standard1.gif differ diff --git a/docs/Roadmap.md b/docs/Roadmap.md index 93b1428e..0b969c5c 100644 --- a/docs/Roadmap.md +++ b/docs/Roadmap.md @@ -9,6 +9,7 @@ In 2019, the Windows Calculator team is focused on: * Iterating upon the existing app design based on the latest [Fluent Design guidelines](https://developer.microsoft.com/en-us/windows/apps/design) * Improving testing and diagnostics within the project * Investigating new features with a focus on addressing top user feedback, including: + * Adding graphing mode * Adding the ability for users to pin Calculator on top of other windows * Providing additional customization options * [Your feature idea here] - please review our [new feature development process](https://github.com/Microsoft/calculator/blob/master/docs/NewFeatureProcess.md) to get started! diff --git a/src/.editorconfig b/src/.editorconfig deleted file mode 100644 index 602092c6..00000000 --- a/src/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*.{xaml,cpp,h}] -charset = utf-8-bom -indent_style = space -indent_size = 4 - -[*.{cpp,h}] -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/src/CalcManager/CEngine/CalcInput.cpp b/src/CalcManager/CEngine/CalcInput.cpp index 4994e025..45e553b9 100644 --- a/src/CalcManager/CEngine/CalcInput.cpp +++ b/src/CalcManager/CEngine/CalcInput.cpp @@ -56,7 +56,7 @@ bool CalcInput::TryToggleSign(bool isIntegerMode, wstring_view maxNumStr) return true; } -bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, long wordBitWidth, int maxDigits) +bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, int32_t wordBitWidth, int maxDigits) { // Convert from an integer into a character // This includes both normal digits and alpha 'digits' for radixes > 10 diff --git a/src/CalcManager/CEngine/CalcUtils.cpp b/src/CalcManager/CEngine/CalcUtils.cpp index 4aa8311d..7980e4e0 100644 --- a/src/CalcManager/CEngine/CalcUtils.cpp +++ b/src/CalcManager/CEngine/CalcUtils.cpp @@ -3,25 +3,26 @@ #include "pch.h" #include "Header Files/CalcEngine.h" +#include "Header Files/CalcUtils.h" -bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y) +bool IsOpInRange(OpCode op, uint32_t x, uint32_t y) { return ((op >= x) && (op <= y)); } -bool IsBinOpCode(WPARAM opCode) +bool IsBinOpCode(OpCode opCode) { return IsOpInRange(opCode, IDC_AND, IDC_PWR); } // WARNING: IDC_SIGN is a special unary op but still this doesn't catch this. Caller has to be aware // of it and catch it themselves or not needing this -bool IsUnaryOpCode(WPARAM opCode) +bool IsUnaryOpCode(OpCode opCode) { return IsOpInRange(opCode, IDC_UNARYFIRST, IDC_UNARYLAST); } -bool IsDigitOpCode(WPARAM opCode) +bool IsDigitOpCode(OpCode opCode) { return IsOpInRange(opCode, IDC_0, IDC_F); } @@ -31,7 +32,7 @@ bool IsDigitOpCode(WPARAM opCode) // so we abstract this as a separate routine. Note: There is another side to this. Some commands are not // gui mode setting to begin with, but once it is discovered it is invalid and we want to behave as though it // was never inout, we need to revert the state changes made as a result of this test -bool IsGuiSettingOpCode(WPARAM opCode) +bool IsGuiSettingOpCode(OpCode opCode) { if (IsOpInRange(opCode, IDM_HEX, IDM_BIN) || IsOpInRange(opCode, IDM_QWORD, IDM_BYTE) || diff --git a/src/CalcManager/CEngine/History.cpp b/src/CalcManager/CEngine/History.cpp index 860f1f60..ca276a41 100644 --- a/src/CalcManager/CEngine/History.cpp +++ b/src/CalcManager/CEngine/History.cpp @@ -2,18 +2,25 @@ // Licensed under the MIT License. #include "pch.h" -#pragma once #include "Header Files/CalcEngine.h" #include "Command.h" #include "CalculatorVector.h" #include "ExpressionCommand.h" -#include "CalcException.h" constexpr int ASCII_0 = 48; using namespace std; using namespace CalcEngine; +namespace { + void IFT(ResultCode hr) + { + if (FAILED(hr)) + { + throw hr; + } + } +} void CHistoryCollector::ReinitHistory() { m_lastOpStartIndex = -1; @@ -129,7 +136,7 @@ void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool fNoRepetition) } // This is expected to be called when a binary op in the last say 1+2+ is changing to another one say 1+2* (+ changed to *) -// It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new +// It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new // one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^) void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher) { @@ -196,7 +203,7 @@ bool CHistoryCollector::FOpndAddedToHistory() // AddUnaryOpToHistory // -// This is does the postfix to prefix translation of the input and adds the text to the history. Eg. doing 2 + 4 (sqrt), +// This is does the postfix to prefix translation of the input and adds the text to the history. Eg. doing 2 + 4 (sqrt), // this routine will ensure the last sqrt call unary operator, actually goes back in history and wraps 4 in sqrt(4) // void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE angletype) @@ -290,7 +297,7 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE a } // Called after = with the result of the equation -// Responsible for clearing the top line of current running history display, as well as adding yet another element to +// Responsible for clearing the top line of current running history display, as well as adding yet another element to // history of equations void CHistoryCollector::CompleteHistoryLine(wstring_view numStr) { @@ -406,37 +413,39 @@ int CHistoryCollector::AddCommand(_In_ const std::shared_ptr return nCommands - 1; } -//To Update the operands in the Expression according to the current Radix +// 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) { - unsigned int size; - IFT(m_spTokens->GetSize(&size)); + return; + } - for (unsigned int i = 0; i < size; ++i) + unsigned int size; + IFT(m_spTokens->GetSize(&size)); + + for (unsigned int i = 0; i < size; ++i) + { + std::pair token; + IFT(m_spTokens->GetAt(i, &token)); + int commandPosition = token.second; + if (commandPosition != -1) { - std::pair token; - IFT(m_spTokens->GetAt(i, &token)); - int commandPosition = token.second; - if (commandPosition != -1) + std::shared_ptr expCommand; + IFT(m_spCommands->GetAt(commandPosition, &expCommand)); + if (expCommand != nullptr && CalculationManager::CommandType::OperandCommand == expCommand->GetCommandType()) { - std::shared_ptr expCommand; - IFT(m_spCommands->GetAt(commandPosition, &expCommand)); - if (expCommand != nullptr && CalculationManager::CommandType::OperandCommand == expCommand->GetCommandType()) + std::shared_ptr opndCommand = std::static_pointer_cast(expCommand); + if (opndCommand != nullptr) { - std::shared_ptr opndCommand = std::static_pointer_cast(expCommand); - if (opndCommand != nullptr) - { - token.first = opndCommand->GetString(radix, precision); - IFT(m_spTokens->SetAt(i, token)); - opndCommand->SetCommands(GetOperandCommandsFromString(token.first)); - } + token.first = opndCommand->GetString(radix, precision); + IFT(m_spTokens->SetAt(i, token)); + opndCommand->SetCommands(GetOperandCommandsFromString(token.first)); } } } - SetExpressionDisplay(); } + SetExpressionDisplay(); } void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol) @@ -444,7 +453,7 @@ void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol) m_decimalSymbol = decimalSymbol; } -//Update the commands corresponding to the passed string Number +// Update the commands corresponding to the passed string Number std::shared_ptr> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr) { std::shared_ptr> commands = std::make_shared>(); diff --git a/src/CalcManager/CEngine/Number.cpp b/src/CalcManager/CEngine/Number.cpp index 0d809917..4bf83a33 100644 --- a/src/CalcManager/CEngine/Number.cpp +++ b/src/CalcManager/CEngine/Number.cpp @@ -28,10 +28,10 @@ namespace CalcEngine PNUMBER Number::ToPNUMBER() const { - PNUMBER ret = _createnum(static_cast(this->Mantissa().size()) + 1); + PNUMBER ret = _createnum(static_cast(this->Mantissa().size()) + 1); ret->sign = this->Sign(); ret->exp = this->Exp(); - ret->cdigit = static_cast(this->Mantissa().size()); + ret->cdigit = static_cast(this->Mantissa().size()); MANTTYPE *ptrRet = ret->mant; for (auto const& digit : this->Mantissa()) diff --git a/src/CalcManager/CEngine/Rational.cpp b/src/CalcManager/CEngine/Rational.cpp index 22a972a3..fd86b72a 100644 --- a/src/CalcManager/CEngine/Rational.cpp +++ b/src/CalcManager/CEngine/Rational.cpp @@ -31,7 +31,7 @@ namespace CalcEngine Rational::Rational(int32_t i) { - PRAT pr = longtorat(static_cast(i)); + PRAT pr = i32torat(static_cast(i)); m_p = Number{ pr->pp }; m_q = Number{ pr->pq }; @@ -41,7 +41,7 @@ namespace CalcEngine Rational::Rational(uint32_t ui) { - PRAT pr = Ulongtorat(static_cast(ui)); + PRAT pr = Ui32torat(static_cast(ui)); m_p = Number{ pr->pp }; m_q = Number{ pr->pq }; @@ -100,7 +100,7 @@ namespace CalcEngine addrat(&lhsRat, rhsRat, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -123,7 +123,7 @@ namespace CalcEngine subrat(&lhsRat, rhsRat, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -146,7 +146,7 @@ namespace CalcEngine mulrat(&lhsRat, rhsRat, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -169,7 +169,7 @@ namespace CalcEngine divrat(&lhsRat, rhsRat, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -192,7 +192,7 @@ namespace CalcEngine modrat(&lhsRat, rhsRat); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -215,7 +215,7 @@ namespace CalcEngine lshrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -238,7 +238,7 @@ namespace CalcEngine rshrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -261,7 +261,7 @@ namespace CalcEngine andrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -283,7 +283,7 @@ namespace CalcEngine orrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -305,7 +305,7 @@ namespace CalcEngine xorrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION); destroyrat(rhsRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -388,7 +388,7 @@ namespace CalcEngine { result = rat_equ(lhsRat, rhsRat, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -416,7 +416,7 @@ namespace CalcEngine { result = rat_lt(lhsRat, rhsRat, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(lhsRat); destroyrat(rhsRat); @@ -453,7 +453,7 @@ namespace CalcEngine { result = RatToString(rat, fmt, radix, precision); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(rat); throw(error); @@ -470,9 +470,9 @@ namespace CalcEngine uint64_t result; try { - result = rattoUlonglong(rat, RATIONAL_BASE, RATIONAL_PRECISION); + result = rattoUi64(rat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(rat); throw(error); diff --git a/src/CalcManager/CEngine/RationalMath.cpp b/src/CalcManager/CEngine/RationalMath.cpp index 46b5a086..37dc7926 100644 --- a/src/CalcManager/CEngine/RationalMath.cpp +++ b/src/CalcManager/CEngine/RationalMath.cpp @@ -14,7 +14,7 @@ Rational RationalMath::Frac(Rational const& rat) { fracrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -33,7 +33,7 @@ Rational RationalMath::Integer(Rational const& rat) { intrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -55,7 +55,7 @@ Rational RationalMath::Pow(Rational const& base, Rational const& pow) powrat(&baseRat, powRat, RATIONAL_BASE, RATIONAL_PRECISION); destroyrat(powRat); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(baseRat); destroyrat(powRat); @@ -81,7 +81,7 @@ Rational RationalMath::Fact(Rational const& rat) { factrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -101,7 +101,7 @@ Rational RationalMath::Exp(Rational const& rat) { exprat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -121,7 +121,7 @@ Rational RationalMath::Log(Rational const& rat) { lograt(&prat, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -156,7 +156,7 @@ Rational RationalMath::Sin(Rational const& rat, ANGLE_TYPE angletype) { sinanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -176,7 +176,7 @@ Rational RationalMath::Cos(Rational const& rat, ANGLE_TYPE angletype) { cosanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -196,7 +196,7 @@ Rational RationalMath::Tan(Rational const& rat, ANGLE_TYPE angletype) { tananglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -216,7 +216,7 @@ Rational RationalMath::ASin(Rational const& rat, ANGLE_TYPE angletype) { asinanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -236,7 +236,7 @@ Rational RationalMath::ACos(Rational const& rat, ANGLE_TYPE angletype) { acosanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -256,7 +256,7 @@ Rational RationalMath::ATan(Rational const& rat, ANGLE_TYPE angletype) { atananglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -276,7 +276,7 @@ Rational RationalMath::Sinh(Rational const& rat) { sinhrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -296,7 +296,7 @@ Rational RationalMath::Cosh(Rational const& rat) { coshrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -316,7 +316,7 @@ Rational RationalMath::Tanh(Rational const& rat) { tanhrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -336,7 +336,7 @@ Rational RationalMath::ASinh(Rational const& rat) { asinhrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -356,7 +356,7 @@ Rational RationalMath::ACosh(Rational const& rat) { acoshrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); @@ -376,7 +376,7 @@ Rational RationalMath::ATanh(Rational const& rat) { atanhrat(&prat, RATIONAL_PRECISION); } - catch (DWORD error) + catch (uint32_t error) { destroyrat(prat); throw(error); diff --git a/src/CalcManager/CEngine/calc.cpp b/src/CalcManager/CEngine/calc.cpp index 6f93a600..9d1ca9de 100644 --- a/src/CalcManager/CEngine/calc.cpp +++ b/src/CalcManager/CEngine/calc.cpp @@ -15,7 +15,7 @@ using namespace CalcEngine; static constexpr int DEFAULT_MAX_DIGITS = 32; static constexpr int DEFAULT_PRECISION = 32; -static constexpr long DEFAULT_RADIX = 10; +static constexpr int32_t DEFAULT_RADIX = 10; static constexpr wchar_t DEFAULT_DEC_SEPARATOR = L'.'; static constexpr wchar_t DEFAULT_GRP_SEPARATOR = L','; diff --git a/src/CalcManager/CEngine/scicomm.cpp b/src/CalcManager/CEngine/scicomm.cpp index f639c707..f17938bf 100644 --- a/src/CalcManager/CEngine/scicomm.cpp +++ b/src/CalcManager/CEngine/scicomm.cpp @@ -26,39 +26,41 @@ using namespace std; using namespace CalcEngine; -// NPrecedenceOfOp -// -// returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number -// 0 is returned. Higher the number, higher the precedence of the operator. -INT NPrecedenceOfOp(int nopCode) -{ - static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1, - IDC_ADD,2, IDC_SUB,2, IDC_RSHF,3, IDC_LSHF,3, - IDC_MOD,3, IDC_DIV,3, IDC_MUL,3, IDC_PWR,4, IDC_ROOT, 4 }; - int iPrec; +namespace { + // NPrecedenceOfOp + // + // returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number + // 0 is returned. Higher the number, higher the precedence of the operator. + int NPrecedenceOfOp(int nopCode) + { + static uint8_t rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1, + IDC_ADD,2, IDC_SUB,2, IDC_RSHF,3, IDC_LSHF,3, + IDC_MOD,3, IDC_DIV,3, IDC_MUL,3, IDC_PWR,4, IDC_ROOT, 4 }; + unsigned int iPrec; - iPrec = 0; - while ((iPrec < ARRAYSIZE(rgbPrec)) && (nopCode != rgbPrec[iPrec])) - { - iPrec += 2; - } - if (iPrec >= ARRAYSIZE(rgbPrec)) - { iPrec = 0; - } - return rgbPrec[iPrec + 1]; + while ((iPrec < size(rgbPrec)) && (nopCode != rgbPrec[iPrec])) + { + iPrec += 2; + } + if (iPrec >= size(rgbPrec)) + { + iPrec = 0; + } + return rgbPrec[iPrec + 1]; + } } // HandleErrorCommand // -// When it is discovered by the state machine that at this point the input is not valid (eg. "1+)"), we want to proceed as though this input never +// When it is discovered by the state machine that at this point the input is not valid (eg. "1+)"), we want to proceed as though this input never // occurred and may be some feedback to user like Beep. The rest of input can then continue by just ignoring this command. -void CCalcEngine::HandleErrorCommand(WPARAM idc) +void CCalcEngine::HandleErrorCommand(OpCode idc) { if (!IsGuiSettingOpCode(idc)) { - // we would have saved the prev command. Need to forget this state + // We would have saved the prev command. Need to forget this state m_nTempCom = m_nLastCom; } } @@ -81,7 +83,7 @@ void CCalcEngine::ClearTemporaryValues() m_bError = false; } -void CCalcEngine::ProcessCommand(WPARAM wParam) +void CCalcEngine::ProcessCommand(OpCode wParam) { if (wParam == IDC_SET_RESULT) { @@ -92,9 +94,9 @@ void CCalcEngine::ProcessCommand(WPARAM wParam) ProcessCommandWorker(wParam); } -void CCalcEngine::ProcessCommandWorker(WPARAM wParam) +void CCalcEngine::ProcessCommandWorker(OpCode wParam) { - INT nx, ni; + int nx, ni; // Save the last command. Some commands are not saved in this manor, these // commands are: @@ -105,7 +107,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) if (!IsGuiSettingOpCode(wParam)) { m_nLastCom = m_nTempCom; - m_nTempCom = (INT)wParam; + m_nTempCom = (int)wParam; } if (m_bError) @@ -126,7 +128,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) } } - // Toggle Record/Display mode if appropriate. + // Toggle Record/Display mode if appropriate. if (m_bRecord) { if (IsOpInRange(wParam, IDC_AND, IDC_MMINUS) || @@ -180,13 +182,13 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) // BINARY OPERATORS: if (IsBinOpCode(wParam)) { - /* Change the operation if last input was operation. */ + // Change the operation if last input was operation. if (IsBinOpCode(m_nLastCom)) { - INT nPrev; + int nPrev; bool fPrecInvToHigher = false; // Is Precedence Inversion from lower to higher precedence happening ?? - m_nOpCode = (INT)wParam; + m_nOpCode = (int)wParam; // Check to see if by changing this binop, a Precedence inversion is happening. // Eg. 1 * 2 + and + is getting changed to ^. The previous precedence rules would have already computed @@ -283,7 +285,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) DisplayAnnounceBinaryOperator(); m_lastVal = m_currentVal; - m_nOpCode = (INT)wParam; + m_nOpCode = (int)wParam; m_HistoryCollector.AddBinOpToHistory(m_nOpCode); m_bNoPrevEqu = m_bChangeOp = true; return; @@ -311,7 +313,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); } - m_HistoryCollector.AddUnaryOpToHistory((INT)wParam, m_bInv, m_angletype); + m_HistoryCollector.AddUnaryOpToHistory((int)wParam, m_bInv, m_angletype); } if ((wParam == IDC_SIN) || (wParam == IDC_COS) || (wParam == IDC_TAN) || (wParam == IDC_SINH) || (wParam == IDC_COSH) || (wParam == IDC_TANH)) @@ -324,7 +326,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) } } - m_currentVal = SciCalcFunctions(m_currentVal, (DWORD)wParam); + m_currentVal = SciCalcFunctions(m_currentVal, (uint32_t)wParam); if (m_bError) return; @@ -364,7 +366,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) CheckAndAddLastBinOpToHistory(); - if (TryToggleBit(m_currentVal, (DWORD)wParam - IDC_BINEDITSTART)) + if (TryToggleBit(m_currentVal, (uint32_t)wParam - IDC_BINEDITSTART)) { DisplayNum(); } @@ -440,7 +442,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) m_nTempCom = m_nLastCom; // Put back this last saved command to the prev state so ) can be handled properly ProcessCommand(IDC_CLOSEP); m_nLastCom = m_nTempCom; // Actually this is IDC_CLOSEP - m_nTempCom = (INT)wParam; // put back in the state where last op seen was IDC_CLOSEP, and current op is IDC_EQU + m_nTempCom = (int)wParam; // put back in the state where last op seen was IDC_CLOSEP, and current op is IDC_EQU } if (!m_bNoPrevEqu) @@ -544,6 +546,11 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx) || ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0))) { + if (!m_openParenCount && !nx) + { + m_pCalcDisplay->OnNoRightParenAdded(); + } + HandleErrorCommand(wParam); break; } @@ -567,7 +574,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) m_lastVal = 0; if (IsBinOpCode(m_nLastCom)) { - // We want 1 + ( to start as 1 + (0. Any number you type replaces 0. But if it is 1 + 3 (, it is + // We want 1 + ( to start as 1 + (0. Any number you type replaces 0. But if it is 1 + 3 (, it is // treated as 1 + (3 m_currentVal = 0; } @@ -796,7 +803,7 @@ void CCalcEngine::CheckAndAddLastBinOpToHistory(bool addToHistory) { if (m_HistoryCollector.FOpndAddedToHistory()) { - // if last time opnd was added but the last command was not a binary operator, then it must have come + // if last time opnd was added but the last command was not a binary operator, then it must have come // from commands which add the operand, like unary operator. So history at this is showing 1 + sqrt(4) // but in reality the sqrt(4) is getting replaced by new number (may be unary op, or MR or SUM etc.) // So erase the last operand @@ -848,7 +855,7 @@ void CCalcEngine::DisplayAnnounceBinaryOperator() } // Unary operator Function Name table Element -// since unary operators button names aren't exactly friendly for history purpose, +// since unary operators button names aren't exactly friendly for history purpose, // we have this separate table to get its localized name and for its Inv function if it exists. typedef struct { @@ -940,7 +947,7 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE // Try to lookup the ID in the UFNE table int ids = 0; int iufne = nOpCode - IDC_UNARYFIRST; - if (iufne >= 0 && iufne < ARRAYSIZE(rgUfne)) + if (iufne >= 0 && (size_t)iufne < size(rgUfne)) { if (fInv) { @@ -1020,7 +1027,7 @@ wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision) wstring numberString = GetStringForDisplay(rat, radix); if (!numberString.empty()) { - //revert the precision to previously stored precision + // Revert the precision to previously stored precision ChangeConstants(m_radix, m_precision); } @@ -1053,7 +1060,7 @@ wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix) result = tempRat.ToString(radix, m_nFE, m_precision); } - catch (DWORD) + catch (uint32_t) { } } diff --git a/src/CalcManager/CEngine/scidisp.cpp b/src/CalcManager/CEngine/scidisp.cpp index e01cc239..849fe863 100644 --- a/src/CalcManager/CEngine/scidisp.cpp +++ b/src/CalcManager/CEngine/scidisp.cpp @@ -39,7 +39,7 @@ typedef struct { Rational value; int32_t precision; uint32_t radix; - INT nFE; + int nFE; NUM_WIDTH numwidth; bool fIntMath; bool bRecord; diff --git a/src/CalcManager/CEngine/scifunc.cpp b/src/CalcManager/CEngine/scifunc.cpp index 75fbbfcf..a1007c1c 100644 --- a/src/CalcManager/CEngine/scifunc.cpp +++ b/src/CalcManager/CEngine/scifunc.cpp @@ -24,7 +24,7 @@ using namespace CalcEngine; using namespace CalcEngine::RationalMath; /* Routines for more complex mathematical functions/error checking. */ -CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& rat, DWORD op) +CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op) { Rational result{}; try @@ -70,7 +70,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r uint64_t w64Bits = result.ToUInt64_t(); uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0; - w64Bits >>= 1; //RShift by 1 + w64Bits >>= 1; // RShift by 1 w64Bits |= (lsb << (m_dwWordBitWidth - 1)); result = w64Bits; @@ -205,7 +205,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r } } // end switch( op ) } - catch (DWORD nErrCode) + catch (uint32_t nErrCode) { DisplayError(nErrCode); result = rat; @@ -215,9 +215,9 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r } /* Routine to display error messages and set m_bError flag. Errors are */ -/* called with DisplayError (n), where n is a DWORD between 0 and 5. */ +/* called with DisplayError (n), where n is a uint32_t between 0 and 5. */ -void CCalcEngine::DisplayError(DWORD nError) +void CCalcEngine::DisplayError(uint32_t nError) { wstring errorString{ GetString(IDS_ERRORS_FIRST + SCODE_CODE(nError)) }; diff --git a/src/CalcManager/CEngine/scioper.cpp b/src/CalcManager/CEngine/scioper.cpp index 06fe3450..b09083c4 100644 --- a/src/CalcManager/CEngine/scioper.cpp +++ b/src/CalcManager/CEngine/scioper.cpp @@ -133,7 +133,7 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa break; } } - catch (DWORD dwErrCode) + catch (uint32_t dwErrCode) { DisplayError(dwErrCode); diff --git a/src/CalcManager/CEngine/sciset.cpp b/src/CalcManager/CEngine/sciset.cpp index 01dd3d3b..5495748e 100644 --- a/src/CalcManager/CEngine/sciset.cpp +++ b/src/CalcManager/CEngine/sciset.cpp @@ -6,15 +6,16 @@ using namespace CalcEngine; using namespace CalcEngine::RationalMath; +using namespace std; // To be called when either the radix or num width changes. You can use -1 in either of these values to mean // dont change that. void CCalcEngine::SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth) { - // When in integer mode, the number is represented in 2's complement form. When a bit width is changing, we can - // change the number representation back to sign, abs num form in ratpak. Soon when display sees this, it will - // convert to 2's complement form, but this time all high bits will be propagated. Eg. -127, in byte mode is - // represented as 1000,0001. This puts it back as sign=-1, 01111111 . But DisplayNum will see this and convert it + // When in integer mode, the number is represented in 2's complement form. When a bit width is changing, we can + // change the number representation back to sign, abs num form in ratpak. Soon when display sees this, it will + // convert to 2's complement form, but this time all high bits will be propagated. Eg. -127, in byte mode is + // represented as 1000,0001. This puts it back as sign=-1, 01111111 . But DisplayNum will see this and convert it // back to 1111,1111,1000,0001 when in Word mode. if (m_fIntegerMode) { @@ -45,17 +46,17 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwid // inform ratpak that a change in base or precision has occurred BaseOrPrecisionChanged(); - // display the correct number for the new state (ie convert displayed + // display the correct number for the new state (ie convert displayed // number to correct base) DisplayNum(); } -LONG CCalcEngine::DwWordBitWidthFromeNumWidth(NUM_WIDTH /*numwidth*/) +int32_t CCalcEngine::DwWordBitWidthFromeNumWidth(NUM_WIDTH /*numwidth*/) { static constexpr int nBitMax[] = { 64, 32, 16, 8 }; - LONG wmax = nBitMax[0]; + int32_t wmax = nBitMax[0]; - if (m_numwidth >= 0 && m_numwidth < ARRAYSIZE(nBitMax)) + if (m_numwidth >= 0 && (size_t)m_numwidth < size(nBitMax)) { wmax = nBitMax[m_numwidth]; } @@ -68,7 +69,7 @@ uint32_t CCalcEngine::NRadixFromRadixType(RADIX_TYPE radixtype) uint32_t radix = 10; // convert special bases into symbolic values - if (radixtype >= 0 && radixtype < ARRAYSIZE(rgnRadish)) + if (radixtype >= 0 && (size_t)radixtype < size(rgnRadish)) { radix = rgnRadish[radixtype]; } @@ -76,9 +77,9 @@ uint32_t CCalcEngine::NRadixFromRadixType(RADIX_TYPE radixtype) } // Toggles a given bit into the number representation. returns true if it changed it actually. -bool CCalcEngine::TryToggleBit(CalcEngine::Rational& rat, DWORD wbitno) +bool CCalcEngine::TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno) { - DWORD wmax = DwWordBitWidthFromeNumWidth(m_numwidth); + uint32_t wmax = DwWordBitWidthFromeNumWidth(m_numwidth); if (wbitno >= wmax) { return false; // ignore error cant happen @@ -142,7 +143,7 @@ void CCalcEngine::UpdateMaxIntDigits() if (m_fIntegerMode) { m_cIntDigitsSav = static_cast(m_maxDecimalValueStrings[m_numwidth].length()) - 1; - // This is the max digits you can enter a decimal in fixed width mode aka integer mode -1. The last digit + // This is the max digits you can enter a decimal in fixed width mode aka integer mode -1. The last digit // has to be checked separately } else @@ -160,10 +161,10 @@ void CCalcEngine::ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t { if (10 == radix) { - ChangeConstants(radix, precision); // Base 10 precision for internal computing still needs to be 32, to + ChangeConstants(radix, precision); // Base 10 precision for internal computing still needs to be 32, to // take care of decimals precisely. For eg. to get the HI word of a qword, we do a rsh, which depends on getting - // 18446744073709551615 / 4294967296 = 4294967295.9999917... This is important it works this and doesn't reduce - // the precision to number of digits allowed to enter. In other words, precision and # of allowed digits to be + // 18446744073709551615 / 4294967296 = 4294967295.9999917... This is important it works this and doesn't reduce + // the precision to number of digits allowed to enter. In other words, precision and # of allowed digits to be // entered are different. } else diff --git a/src/CalcManager/CalcException.h b/src/CalcManager/CalcException.h deleted file mode 100644 index e63b1837..00000000 --- a/src/CalcManager/CalcException.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -class CalcException : public std::exception -{ -public: - CalcException(HRESULT hr) - { - m_hr = hr; - } - HRESULT GetException() - { - return m_hr; - } -private: - HRESULT m_hr; -}; - -void IFT(HRESULT hr) -{ - if (FAILED(hr)) - { - CalcException exception(hr); - throw(exception); - } -} diff --git a/src/CalcManager/CalcManager.vcxproj.filters b/src/CalcManager/CalcManager.vcxproj.filters index 9be2a455..2ca11666 100644 --- a/src/CalcManager/CalcManager.vcxproj.filters +++ b/src/CalcManager/CalcManager.vcxproj.filters @@ -119,7 +119,6 @@ RatPack - Header Files @@ -162,4 +161,4 @@ Header Files - \ No newline at end of file + diff --git a/src/CalcManager/CalculatorHistory.cpp b/src/CalcManager/CalculatorHistory.cpp index a34ca272..31a1dae2 100644 --- a/src/CalcManager/CalculatorHistory.cpp +++ b/src/CalcManager/CalculatorHistory.cpp @@ -7,8 +7,7 @@ using namespace std; using namespace CalculationManager; -CalculatorHistory::CalculatorHistory(CALCULATOR_MODE eMode, size_t maxSize) : - m_mode(eMode), +CalculatorHistory::CalculatorHistory(size_t maxSize) : m_maxHistorySize(maxSize) {} @@ -23,7 +22,7 @@ unsigned int CalculatorHistory::AddToHistory(_In_ shared_ptrGetString(&generatedExpression); - // Prefixing and suffixing the special Unicode markers to ensure that the expression + // Prefixing and suffixing the special Unicode markers to ensure that the expression // in the history doesn't get broken for RTL languages spHistoryItem->historyItemVector.expression = L'\u202d' + generatedExpression + L'\u202c'; spHistoryItem->historyItemVector.result = wstring(result); @@ -35,15 +34,13 @@ unsigned int CalculatorHistory::AddToHistory(_In_ shared_ptr const &spHistoryItem) { - int lastIndex; - if (m_historyItems.size() >= m_maxHistorySize) { m_historyItems.erase(m_historyItems.begin()); } m_historyItems.push_back(spHistoryItem); - lastIndex = static_cast(m_historyItems.size() - 1); + unsigned int lastIndex = static_cast(m_historyItems.size() - 1); return lastIndex; } diff --git a/src/CalcManager/CalculatorHistory.h b/src/CalcManager/CalculatorHistory.h index aececbda..8116e9e4 100644 --- a/src/CalcManager/CalculatorHistory.h +++ b/src/CalcManager/CalculatorHistory.h @@ -31,7 +31,7 @@ namespace CalculationManager { public: - CalculatorHistory(CALCULATOR_MODE eMode, const size_t maxSize); + CalculatorHistory(const size_t maxSize); unsigned int AddToHistory(_In_ std::shared_ptr>> const &spTokens, _In_ std::shared_ptr>> const &spCommands, std::wstring_view result); std::vector> const& GetHistory(); std::shared_ptr const& GetHistoryItem(unsigned int uIdx); @@ -43,7 +43,6 @@ namespace CalculationManager private: std::vector> m_historyItems; - CALCULATOR_MODE m_mode; const size_t m_maxHistorySize; }; } diff --git a/src/CalcManager/CalculatorManager.cpp b/src/CalcManager/CalculatorManager.cpp index 0e03afaf..b4b4dfaf 100644 --- a/src/CalcManager/CalculatorManager.cpp +++ b/src/CalcManager/CalculatorManager.cpp @@ -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" @@ -24,15 +24,15 @@ namespace CalculationManager { CalculatorManager::CalculatorManager(_In_ ICalcDisplay* displayCallback, _In_ IResourceProvider* resourceProvider) : m_displayCallback(displayCallback), + m_currentCalculatorEngine(nullptr), m_resourceProvider(resourceProvider), + m_inHistoryItemLoadMode(false), + m_persistedPrimaryValue(), + m_isExponentialFormat(false), m_currentDegreeMode(Command::CommandNULL), m_savedDegreeMode(Command::CommandDEG), - m_isExponentialFormat(false), - m_persistedPrimaryValue(), - m_currentCalculatorEngine(nullptr), - m_pStdHistory(new CalculatorHistory(CM_STD, MAX_HISTORY_ITEMS)), - m_pSciHistory(new CalculatorHistory(CM_SCI, MAX_HISTORY_ITEMS)), - m_inHistoryItemLoadMode(false) + m_pStdHistory(new CalculatorHistory(MAX_HISTORY_ITEMS)), + m_pSciHistory(new CalculatorHistory(MAX_HISTORY_ITEMS)) { CCalcEngine::InitialOneTimeOnlySetup(*m_resourceProvider); } @@ -109,7 +109,6 @@ namespace CalculationManager /// /// Callback from the engine - /// Used to set the current unmatched open parenthesis count /// /// string containing the parenthesis count void CalculatorManager::SetParenDisplayText(const wstring& parenthesisCount) @@ -117,6 +116,14 @@ namespace CalculationManager m_displayCallback->SetParenDisplayText(parenthesisCount); } + /// + /// Callback from the engine + /// + void CalculatorManager::OnNoRightParenAdded() + { + m_displayCallback->OnNoRightParenAdded(); + } + /// /// Reset CalculatorManager. /// Set the mode to the standard calculator @@ -205,7 +212,7 @@ namespace CalculationManager /// /// Send command to the Calc Engine - /// Cast Command Enum to WPARAM. + /// Cast Command Enum to OpCode. /// Handle special commands such as mode change and combination of two commands. /// /// Enum Command @@ -228,7 +235,7 @@ namespace CalculationManager this->SetProgrammerMode(); break; default: - m_currentCalculatorEngine->ProcessCommand(static_cast(command)); + m_currentCalculatorEngine->ProcessCommand(static_cast(command)); } m_savedCommands.clear(); // Clear the previous command history @@ -256,44 +263,44 @@ namespace CalculationManager switch (command) { case Command::CommandASIN: - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandSIN)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandSIN)); break; case Command::CommandACOS: - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandCOS)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandCOS)); break; case Command::CommandATAN: - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandTAN)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandTAN)); break; case Command::CommandPOWE: - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandLN)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandLN)); break; case Command::CommandASINH: - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandSINH)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandSINH)); break; case Command::CommandACOSH: - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandCOSH)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandCOSH)); break; case Command::CommandATANH: - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); - m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandTANH)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandINV)); + m_currentCalculatorEngine->ProcessCommand(static_cast(Command::CommandTANH)); break; case Command::CommandFE: m_isExponentialFormat = !m_isExponentialFormat; - // fall through + [[fallthrough]]; default: - m_currentCalculatorEngine->ProcessCommand(static_cast(command)); + m_currentCalculatorEngine->ProcessCommand(static_cast(command)); break; } } /// - /// Convert Command to unsigned char. + /// Convert Command to unsigned char. /// Since some Commands are higher than 255, they are saved after subtracting 255 /// The smallest Command is CommandSIGN = 80, thus, subtracted value does not overlap with other values. /// @@ -301,7 +308,10 @@ namespace CalculationManager unsigned char CalculatorManager::MapCommandForSerialize(Command command) { unsigned int commandToSave = static_cast(command); - commandToSave > UCHAR_MAX ? commandToSave -= UCHAR_MAX : commandToSave; + if (commandToSave > UCHAR_MAX) + { + commandToSave -= UCHAR_MAX; + } return static_cast(commandToSave); } @@ -353,7 +363,7 @@ namespace CalculationManager /// Serialized Rational of primary display void CalculatorManager::DeSerializePrimaryDisplay(const vector &serializedPrimaryDisplay) { - if (serializedPrimaryDisplay.size() == 0) + if (serializedPrimaryDisplay.empty()) { return; } @@ -428,9 +438,9 @@ namespace CalculationManager if (*commandItr >= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber) && *commandItr <= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizedNumberClearAll)) { - //MemoryCommands(which have values above 255) are pushed on m_savedCommands upon casting to unsigned char. - //SerializeCommands uses m_savedCommands, which is then used in DeSerializeCommands. - //Hence, a simple cast to MemoryCommand is not sufficient. + // MemoryCommands(which have values above 255) are pushed on m_savedCommands upon casting to unsigned char. + // SerializeCommands uses m_savedCommands, which is then used in DeSerializeCommands. + // Hence, a simple cast to MemoryCommand is not sufficient. MemoryCommand memoryCommand = static_cast(*commandItr + UCHAR_MAX + 1); unsigned int indexOfMemory = 0; switch (memoryCommand) @@ -483,22 +493,25 @@ namespace CalculationManager void CalculatorManager::MemorizeNumber() { m_savedCommands.push_back(MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber)); - if (!(m_currentCalculatorEngine->FInErrorState())) + + if (m_currentCalculatorEngine->FInErrorState()) { - m_currentCalculatorEngine->ProcessCommand(IDC_STORE); - - auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject(); - if (memoryObjectPtr != nullptr) - { - m_memorizedNumbers.insert(m_memorizedNumbers.begin(), *memoryObjectPtr); - } - - if (m_memorizedNumbers.size() > m_maximumMemorySize) - { - m_memorizedNumbers.resize(m_maximumMemorySize); - } - this->SetMemorizedNumbersString(); + return; } + + m_currentCalculatorEngine->ProcessCommand(IDC_STORE); + + auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject(); + if (memoryObjectPtr != nullptr) + { + m_memorizedNumbers.insert(m_memorizedNumbers.begin(), *memoryObjectPtr); + } + + if (m_memorizedNumbers.size() > m_maximumMemorySize) + { + m_memorizedNumbers.resize(m_maximumMemorySize); + } + this->SetMemorizedNumbersString(); } /// @@ -509,11 +522,14 @@ namespace CalculationManager void CalculatorManager::MemorizedNumberLoad(_In_ unsigned int indexOfMemory) { SaveMemoryCommand(MemoryCommand::MemorizedNumberLoad, indexOfMemory); - if (!(m_currentCalculatorEngine->FInErrorState())) + + if (m_currentCalculatorEngine->FInErrorState()) { - this->MemorizedNumberSelect(indexOfMemory); - m_currentCalculatorEngine->ProcessCommand(IDC_RECALL); + return; } + + this->MemorizedNumberSelect(indexOfMemory); + m_currentCalculatorEngine->ProcessCommand(IDC_RECALL); } /// @@ -525,24 +541,27 @@ namespace CalculationManager void CalculatorManager::MemorizedNumberAdd(_In_ unsigned int indexOfMemory) { SaveMemoryCommand(MemoryCommand::MemorizedNumberAdd, indexOfMemory); - if (!(m_currentCalculatorEngine->FInErrorState())) + + if (m_currentCalculatorEngine->FInErrorState()) { - if (m_memorizedNumbers.empty()) - { - this->MemorizeNumber(); - } - else - { - this->MemorizedNumberSelect(indexOfMemory); - m_currentCalculatorEngine->ProcessCommand(IDC_MPLUS); - - this->MemorizedNumberChanged(indexOfMemory); - - this->SetMemorizedNumbersString(); - } - - m_displayCallback->MemoryItemChanged(indexOfMemory); + return; } + + if (m_memorizedNumbers.empty()) + { + this->MemorizeNumber(); + } + else + { + this->MemorizedNumberSelect(indexOfMemory); + m_currentCalculatorEngine->ProcessCommand(IDC_MPLUS); + + this->MemorizedNumberChanged(indexOfMemory); + + this->SetMemorizedNumbersString(); + } + + m_displayCallback->MemoryItemChanged(indexOfMemory); } void CalculatorManager::MemorizedNumberClear(_In_ unsigned int indexOfMemory) @@ -563,27 +582,30 @@ namespace CalculationManager void CalculatorManager::MemorizedNumberSubtract(_In_ unsigned int indexOfMemory) { SaveMemoryCommand(MemoryCommand::MemorizedNumberSubtract, indexOfMemory); - if (!(m_currentCalculatorEngine->FInErrorState())) + + if (m_currentCalculatorEngine->FInErrorState()) { - // To add negative of the number on display to the memory -x = x - 2x - if (m_memorizedNumbers.empty()) - { - this->MemorizeNumber(); - this->MemorizedNumberSubtract(0); - this->MemorizedNumberSubtract(0); - } - else - { - this->MemorizedNumberSelect(indexOfMemory); - m_currentCalculatorEngine->ProcessCommand(IDC_MMINUS); - - this->MemorizedNumberChanged(indexOfMemory); - - this->SetMemorizedNumbersString(); - } - - m_displayCallback->MemoryItemChanged(indexOfMemory); + return; } + + // To add negative of the number on display to the memory -x = x - 2x + if (m_memorizedNumbers.empty()) + { + this->MemorizeNumber(); + this->MemorizedNumberSubtract(0); + this->MemorizedNumberSubtract(0); + } + else + { + this->MemorizedNumberSelect(indexOfMemory); + m_currentCalculatorEngine->ProcessCommand(IDC_MMINUS); + + this->MemorizedNumberChanged(indexOfMemory); + + this->SetMemorizedNumbersString(); + } + + m_displayCallback->MemoryItemChanged(indexOfMemory); } /// @@ -606,11 +628,13 @@ namespace CalculationManager /// Index of the target memory void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory) { - if (!(m_currentCalculatorEngine->FInErrorState())) + if (m_currentCalculatorEngine->FInErrorState()) { - auto memoryObject = m_memorizedNumbers.at(indexOfMemory); - m_currentCalculatorEngine->PersistedMemObject(memoryObject); + return; } + + auto memoryObject = m_memorizedNumbers.at(indexOfMemory); + m_currentCalculatorEngine->PersistedMemObject(memoryObject); } /// @@ -620,13 +644,15 @@ namespace CalculationManager /// Index of the target memory void CalculatorManager::MemorizedNumberChanged(_In_ unsigned int indexOfMemory) { - if (!(m_currentCalculatorEngine->FInErrorState())) + if (m_currentCalculatorEngine->FInErrorState()) { - auto memoryObject = m_currentCalculatorEngine->PersistedMemObject(); - if (memoryObject != nullptr) - { - m_memorizedNumbers.at(indexOfMemory) = *memoryObject; - } + return; + } + + auto memoryObject = m_currentCalculatorEngine->PersistedMemObject(); + if (memoryObject != nullptr) + { + m_memorizedNumbers.at(indexOfMemory) = *memoryObject; } } @@ -754,7 +780,7 @@ namespace CalculationManager } void CalculatorManager::UpdateMaxIntDigits() - { + { m_currentCalculatorEngine->UpdateMaxIntDigits(); } @@ -778,7 +804,7 @@ namespace CalculationManager /// How Rational is serialized : /// Serialized Rational.P(Number) + Serialized Rational.Q(Number) /// How Number is saved : - /// [0] = Rational.P.Sign + /// [0] = Rational.P.Sign /// [1] = Rational.P.Mantissa.size /// [2] = Rational.P.Exp /// [3] = Rational.P.Mantissa[0] @@ -816,7 +842,7 @@ namespace CalculationManager /// /// Serialize Number to vector of long /// How Number is saved : - /// [0] = Number.Sign + /// [0] = Number.Sign /// [1] = Number.Mantissa.size /// [2] = Number.Exp /// [3] = Number.Mantissa[0] @@ -843,7 +869,7 @@ namespace CalculationManager /// /// DeserializeNumber vector and construct a Number /// How Number is saved : - /// [0] = Number.Sign + /// [0] = Number.Sign /// [1] = Number.Mantissa.size /// [2] = Number.Exp /// [3] = Number.Mantissa[0] diff --git a/src/CalcManager/CalculatorManager.h b/src/CalcManager/CalculatorManager.h index 9f60c534..0b9986b0 100644 --- a/src/CalcManager/CalculatorManager.h +++ b/src/CalcManager/CalculatorManager.h @@ -27,9 +27,9 @@ namespace CalculationManager ProgrammerModePrecision = 64 }; - // Numbering continues from the Enum Command from Command.h + // Numbering continues from the Enum Command from Command.h // with some gap to ensure there is no overlap of these ids - // when static_cast is performed on these ids + // when static_cast is performed on these ids // they shouldn't fall in any number range greater than 80. So never // make the memory command ids go below 330 enum class MemoryCommand @@ -42,7 +42,7 @@ namespace CalculationManager MemorizedNumberClear = 335 }; - class CalculatorManager sealed : public virtual ICalcDisplay + class CalculatorManager final : public ICalcDisplay { private: ICalcDisplay* const m_displayCallback; @@ -94,7 +94,8 @@ namespace CalculationManager void SetExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands) override; void SetMemorizedNumbers(_In_ const std::vector& memorizedNumbers) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; - void SetParenDisplayText(const std::wstring& parenthesisCount); + void SetParenDisplayText(const std::wstring& parenthesisCount) override; + void OnNoRightParenAdded() override; void DisplayPasteError(); void MaxDigitsReached() override; void BinaryOperatorReceived() override; @@ -140,7 +141,7 @@ namespace CalculationManager std::shared_ptr const& GetHistoryItem(_In_ unsigned int uIdx); bool RemoveHistoryItem(_In_ unsigned int uIdx); void ClearHistory(); - const size_t MaxHistorySize() const { return m_pHistory->MaxHistorySize(); } + size_t MaxHistorySize() const { return m_pHistory->MaxHistorySize(); } CalculationManager::Command GetCurrentDegreeMode(); void SetHistory(_In_ CALCULATOR_MODE eMode, _In_ std::vector> const& history); void SetInHistoryItemLoadMode(_In_ bool isHistoryItemLoadMode); diff --git a/src/CalcManager/CalculatorResource.h b/src/CalcManager/CalculatorResource.h index 51bdd8b6..3493234a 100644 --- a/src/CalcManager/CalculatorResource.h +++ b/src/CalcManager/CalculatorResource.h @@ -10,7 +10,7 @@ namespace CalculationManager public: virtual ~IResourceProvider() { } - // Should return a string from the resource table for strings used + // Should return a string from the resource table for strings used // by the calculation engine. The strings that must be defined // and the ids to define them with can be seen in EngineStrings.h // with SIDS prefix. Additionally it must provide values for string diff --git a/src/CalcManager/CalculatorVector.h b/src/CalcManager/CalculatorVector.h index 9e8c1a72..a4de434d 100644 --- a/src/CalcManager/CalculatorVector.h +++ b/src/CalcManager/CalculatorVector.h @@ -3,13 +3,15 @@ #pragma once +#include "Ratpack/CalcErr.h" + template -class CalculatorVector +class CalculatorVector { public: - HRESULT GetAt(_In_opt_ unsigned int index, _Out_ TType *item) + ResultCode GetAt(_In_opt_ unsigned int index, _Out_ TType *item) { - HRESULT hr = S_OK; + ResultCode hr = S_OK; try { *item = m_vector.at(index); @@ -21,15 +23,15 @@ public: return hr; } - HRESULT GetSize(_Out_ unsigned int *size) + ResultCode GetSize(_Out_ unsigned int *size) { *size = static_cast(m_vector.size()); return S_OK; } - HRESULT SetAt(_In_ unsigned int index, _In_opt_ TType item) + ResultCode SetAt(_In_ unsigned int index, _In_opt_ TType item) { - HRESULT hr = S_OK; + ResultCode hr = S_OK; try { m_vector[index] = item; @@ -41,9 +43,9 @@ public: return hr; } - HRESULT RemoveAt(_In_ unsigned int index) + ResultCode RemoveAt(_In_ unsigned int index) { - HRESULT hr = S_OK; + ResultCode hr = S_OK; if (index < m_vector.size()) { m_vector.erase(m_vector.begin() + index); @@ -55,9 +57,9 @@ public: return hr; } - HRESULT InsertAt(_In_ unsigned int index, _In_ TType item) + ResultCode InsertAt(_In_ unsigned int index, _In_ TType item) { - HRESULT hr = S_OK; + ResultCode hr = S_OK; try { auto iter = m_vector.begin() + index; @@ -70,9 +72,9 @@ public: return hr; } - HRESULT Truncate(_In_ unsigned int index) + ResultCode Truncate(_In_ unsigned int index) { - HRESULT hr = S_OK; + ResultCode hr = S_OK; if (index < m_vector.size()) { auto startIter = m_vector.begin() + index; @@ -85,9 +87,9 @@ public: return hr; } - HRESULT Append(_In_opt_ TType item) + ResultCode Append(_In_opt_ TType item) { - HRESULT hr = S_OK; + ResultCode hr = S_OK; try { m_vector.push_back(item); @@ -99,21 +101,21 @@ public: return hr; } - HRESULT RemoveAtEnd() + ResultCode RemoveAtEnd() { m_vector.erase(--(m_vector.end())); return S_OK; } - HRESULT Clear() + ResultCode Clear() { m_vector.clear(); return S_OK; } - HRESULT GetString(_Out_ std::wstring* expression) + ResultCode GetString(_Out_ std::wstring* expression) { - HRESULT hr = S_OK; + ResultCode hr = S_OK; unsigned int nTokens = 0; std::pair currentPair; hr = this->GetSize(&nTokens); @@ -144,7 +146,7 @@ public: return hr; } - HRESULT GetExpressionSuffix(_Out_ std::wstring* suffix) + ResultCode GetExpressionSuffix(_Out_ std::wstring* suffix) { *suffix = L" ="; return S_OK; diff --git a/src/CalcManager/Command.h b/src/CalcManager/Command.h index 25ad7cf0..e6eeb8ac 100644 --- a/src/CalcManager/Command.h +++ b/src/CalcManager/Command.h @@ -94,7 +94,7 @@ namespace CalculationManager CommandFAC = 113, CommandREC = 114, CommandDMS = 115, - CommandCUBEROOT = 116, //x ^ 1/3 + CommandCUBEROOT = 116, // x ^ 1/3 CommandPOW10 = 117, // 10 ^ x CommandPERCENT = 118, diff --git a/src/CalcManager/ExpressionCommand.cpp b/src/CalcManager/ExpressionCommand.cpp index 906104a6..0b68a374 100644 --- a/src/CalcManager/ExpressionCommand.cpp +++ b/src/CalcManager/ExpressionCommand.cpp @@ -75,19 +75,19 @@ void CUnaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor) CBinaryCommand::CBinaryCommand(int command) :m_command(command) {} -void CBinaryCommand::SetCommand(int command) -{ - m_command = command; +void CBinaryCommand::SetCommand(int command) +{ + m_command = command; } int CBinaryCommand::GetCommand() const -{ - return m_command; +{ + return m_command; } CalculationManager::CommandType CBinaryCommand::GetCommandType() const -{ - return CalculationManager::CommandType::BinaryCommand; +{ + return CalculationManager::CommandType::BinaryCommand; } void CBinaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor) @@ -98,8 +98,8 @@ void CBinaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor) COpndCommand::COpndCommand(shared_ptr> const &commands, bool fNegative, bool fDecimal, bool fSciFmt) : m_commands(commands), m_fNegative(fNegative), - m_fDecimal(fDecimal), m_fSciFmt(fSciFmt), + m_fDecimal(fDecimal), m_fInitialized(false), m_value{} {} @@ -111,8 +111,8 @@ void COpndCommand::Initialize(Rational const& rat) } const shared_ptr> & COpndCommand::GetCommands() const -{ - return m_commands; +{ + return m_commands; } void COpndCommand::SetCommands(shared_ptr> const& commands) @@ -166,7 +166,7 @@ void COpndCommand::RemoveFromEnd() { unsigned int nCommands; m_commands->GetSize(&nCommands); - + if (nCommands == 1) { ClearAllAndAppendCommand(CalculationManager::Command::Command0); @@ -185,8 +185,8 @@ void COpndCommand::RemoveFromEnd() } bool COpndCommand::IsNegative() const -{ - return m_fNegative; +{ + return m_fNegative; } bool COpndCommand::IsSciFmt() const @@ -195,13 +195,13 @@ bool COpndCommand::IsSciFmt() const } bool COpndCommand::IsDecimalPresent() const -{ - return m_fDecimal; +{ + return m_fDecimal; } CalculationManager::CommandType COpndCommand::GetCommandType() const -{ - return CalculationManager::CommandType::OperandCommand; +{ + return CalculationManager::CommandType::OperandCommand; } void COpndCommand::ClearAllAndAppendCommand(CalculationManager::Command command) @@ -283,7 +283,7 @@ const wstring & COpndCommand::GetToken(wchar_t decimalSymbol) m_token.clear(); m_token.append(&chZero); } - + return m_token; } diff --git a/src/CalcManager/Header Files/CCommand.h b/src/CalcManager/Header Files/CCommand.h index 1944061b..2fc08b3c 100644 --- a/src/CalcManager/Header Files/CCommand.h +++ b/src/CalcManager/Header Files/CCommand.h @@ -45,7 +45,7 @@ // Key IDs: -// These id's must be consecutive from IDC_FIRSTCONTROL to IDC_LASTCONTROL. +// These id's must be consecutive from IDC_FIRSTCONTROL to IDC_LASTCONTROL. // The actual values don't matter but the order and sequence are very important. // Also, the order of the controls must match the order of the control names // in the string table. @@ -97,7 +97,7 @@ #define IDC_FAC 113 #define IDC_REC 114 #define IDC_DMS 115 -#define IDC_CUBEROOT 116 //x ^ 1/3 +#define IDC_CUBEROOT 116 // x ^ 1/3 #define IDC_POW10 117 // 10 ^ x #define IDC_PERCENT 118 #define IDC_UNARYLAST IDC_PERCENT diff --git a/src/CalcManager/Header Files/CalcEngine.h b/src/CalcManager/Header Files/CalcEngine.h index a0a44ffd..0ad8252f 100644 --- a/src/CalcManager/Header Files/CalcEngine.h +++ b/src/CalcManager/Header Files/CalcEngine.h @@ -22,6 +22,7 @@ #include "RadixType.h" #include "History.h" // for History Collector #include "CalcInput.h" +#include "CalcUtils.h" #include "ICalcDisplay.h" #include "Rational.h" #include "RationalMath.h" @@ -52,8 +53,8 @@ namespace CalculatorUnitTests class CCalcEngine { public: CCalcEngine(bool fPrecedence, bool fIntegerMode, CalculationManager::IResourceProvider* const pResourceProvider, __in_opt ICalcDisplay *pCalcDisplay, __in_opt std::shared_ptr pHistoryDisplay); - void ProcessCommand(WPARAM wID); - void DisplayError (DWORD nError); + void ProcessCommand(OpCode wID); + void DisplayError (uint32_t nError); std::unique_ptr PersistedMemObject(); void PersistedMemObject(CalcEngine::Rational const& memObject); bool FInErrorState() { return m_bError; } @@ -85,7 +86,7 @@ private: // if it hasn't yet been computed bool m_bChangeOp; /* Flag for changing operation. */ bool m_bRecord; // Global mode: recording or displaying - bool m_bSetCalcState; //Flag for setting the engine result state + bool m_bSetCalcState; // Flag for setting the engine result state CalcEngine::CalcInput m_input; // Global calc input object for decimal strings eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */ CalcEngine::Rational m_maxTrigonometricNum; @@ -116,7 +117,7 @@ private: int m_nLastCom; // Last command entered. ANGLE_TYPE m_angletype; // Current Angle type when in dec mode. one of deg, rad or grad NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode. - LONG m_dwWordBitWidth; // # of bits in currently selected word size + int32_t m_dwWordBitWidth; // # of bits in currently selected word size CHistoryCollector m_HistoryCollector; // Accumulator of each line of history as various commands are processed @@ -127,8 +128,8 @@ private: wchar_t m_groupSeparator; private: - void ProcessCommandWorker(WPARAM wParam); - void HandleErrorCommand(WPARAM idc); + void ProcessCommandWorker(OpCode wParam); + void HandleErrorCommand(OpCode idc); void HandleMaxDigitsReached(); void DisplayNum(void); int IsNumberInvalid(const std::wstring& numberString, int iMaxExp, int iMaxMantissa, uint32_t radix) const; @@ -136,13 +137,13 @@ private: void SetPrimaryDisplay(const std::wstring& szText, bool isError = false); void ClearTemporaryValues(); CalcEngine::Rational TruncateNumForIntMath(CalcEngine::Rational const& rat); - CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, DWORD op); + CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op); CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs); void SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth); - LONG DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth); + int32_t DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth); uint32_t NRadixFromRadixType( RADIX_TYPE radixtype); - bool TryToggleBit(CalcEngine::Rational& rat, DWORD wbitno); + bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno); void CheckAndAddLastBinOpToHistory(bool addToHistory = true); int IdcSetAngleTypeDecMode(int idc); diff --git a/src/CalcManager/Header Files/CalcInput.h b/src/CalcManager/Header Files/CalcInput.h index 4238e598..b39021e4 100644 --- a/src/CalcManager/Header Files/CalcInput.h +++ b/src/CalcManager/Header Files/CalcInput.h @@ -6,7 +6,7 @@ #include "Rational.h" // Space to hold enough digits for a quadword binary number (64) plus digit separator strings for that number (20) -constexpr int MAX_STRLEN = 84; +constexpr int MAX_STRLEN = 84; namespace CalcEngine { @@ -47,7 +47,7 @@ namespace CalcEngine void Clear(); bool TryToggleSign(bool isIntegerMode, std::wstring_view maxNumStr); - bool TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, std::wstring_view maxNumStr, long wordBitWidth, int maxDigits); + bool TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, std::wstring_view maxNumStr, int32_t wordBitWidth, int maxDigits); bool TryAddDecimalPt(); bool HasDecimalPt(); bool TryBeginExponent(); diff --git a/src/CalcManager/Header Files/CalcUtils.h b/src/CalcManager/Header Files/CalcUtils.h index 1e0dcae3..bd800783 100644 --- a/src/CalcManager/Header Files/CalcUtils.h +++ b/src/CalcManager/Header Files/CalcUtils.h @@ -3,11 +3,13 @@ #pragma once -bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y); -bool IsBinOpCode(WPARAM opCode); +using OpCode = uintptr_t; + +bool IsOpInRange(OpCode op, uint32_t x, uint32_t y); +bool IsBinOpCode(OpCode opCode); // WARNING: IDC_SIGN is a special unary op but still this doesn't catch this. Caller has to be aware // of it and catch it themselves or not needing this -bool IsUnaryOpCode(WPARAM opCode); -bool IsDigitOpCode(WPARAM opCode); -bool IsGuiSettingOpCode(WPARAM opCode); +bool IsUnaryOpCode(OpCode opCode); +bool IsDigitOpCode(OpCode opCode); +bool IsGuiSettingOpCode(OpCode opCode); diff --git a/src/CalcManager/Header Files/EngineStrings.h b/src/CalcManager/Header Files/EngineStrings.h index 7a420c8c..2ada6bba 100644 --- a/src/CalcManager/Header Files/EngineStrings.h +++ b/src/CalcManager/Header Files/EngineStrings.h @@ -128,7 +128,7 @@ #define SIDS_NFACTORIAL L"33" #define SIDS_RECIPROCAL L"34" #define SIDS_DMS L"35" -#define SIDS_CUBEROOT L"36" +#define SIDS_CUBEROOT L"36" #define SIDS_POWTEN L"37" #define SIDS_PERCENT L"38" #define SIDS_SCIENTIFIC_NOTATION L"39" @@ -200,7 +200,7 @@ #define SIDS_NOMEM L"105" #define SIDS_TOOMANY L"106" #define SIDS_OVERFLOW L"107" -#define SIDS_NORESULT L"108" +#define SIDS_NORESULT L"108" #define SIDS_INSUFFICIENT_DATA L"109" // 110 is skipped by CSTRINGSENGMAX #define SIDS_ERR_UNK_CH L"111" @@ -214,7 +214,7 @@ #define SIDS_ERR_INPUT_OVERFLOW L"119" #define SIDS_ERR_OUTPUT_OVERFLOW L"120" -__declspec(selectany) std::wstring g_sids[] = +__declspec(selectany) std::wstring g_sids[] = { std::wstring(SIDS_PLUS_MINUS), std::wstring(SIDS_C), @@ -252,7 +252,7 @@ __declspec(selectany) std::wstring g_sids[] = std::wstring(SIDS_NFACTORIAL), std::wstring(SIDS_RECIPROCAL), std::wstring(SIDS_DMS), - std::wstring(SIDS_CUBEROOT), + std::wstring(SIDS_CUBEROOT), std::wstring(SIDS_POWTEN), std::wstring(SIDS_PERCENT), std::wstring(SIDS_SCIENTIFIC_NOTATION), @@ -324,7 +324,7 @@ __declspec(selectany) std::wstring g_sids[] = std::wstring(SIDS_NOMEM), std::wstring(SIDS_TOOMANY), std::wstring(SIDS_OVERFLOW), - std::wstring(SIDS_NORESULT), + std::wstring(SIDS_NORESULT), std::wstring(SIDS_INSUFFICIENT_DATA), std::wstring(SIDS_ERR_UNK_CH), std::wstring(SIDS_ERR_UNK_FN), diff --git a/src/CalcManager/Header Files/History.h b/src/CalcManager/Header Files/History.h index c8f418cb..4f82088f 100644 --- a/src/CalcManager/Header Files/History.h +++ b/src/CalcManager/Header Files/History.h @@ -10,8 +10,8 @@ // maximum depth you can get by precedence. It is just an array's size limit. static constexpr size_t MAXPRECDEPTH = 25; -// Helper class really a internal class to CCalcEngine, to accumulate each history line of text by collecting the -// operands, operator, unary operator etc. Since it is a separate entity, it can be unit tested on its own but does +// Helper class really a internal class to CCalcEngine, to accumulate each history line of text by collecting the +// operands, operator, unary operator etc. Since it is a separate entity, it can be unit tested on its own but does // rely on CCalcEngine calling it in appropriate order. class CHistoryCollector { public: @@ -39,13 +39,13 @@ private: ICalcDisplay *m_pCalcDisplay; int m_iCurLineHistStart; // index of the beginning of the current equation - // a sort of state, set to the index before 2 after 2 in the expression 2 + 3 say. Useful for auto correct portion of history and for + // a sort of state, set to the index before 2 after 2 in the expression 2 + 3 say. Useful for auto correct portion of history and for // attaching the unary op around the last operand int m_lastOpStartIndex; // index of the beginning of the last operand added to the history int m_lastBinOpStartIndex; // index of the beginning of the last binary operator added to the history std::array m_operandIndices; // Stack of index of opnd's beginning for each '('. A parallel array to m_hnoParNum, but abstracted independently of that int m_curOperandIndex; // Stack index for the above stack - bool m_bLastOpndBrace; // iff the last opnd in history is already braced so we can avoid putting another one for unary operator + bool m_bLastOpndBrace; // iff the last opnd in history is already braced so we can avoid putting another one for unary operator wchar_t m_decimalSymbol; std::shared_ptr>> m_spTokens; std::shared_ptr>> m_spCommands; diff --git a/src/CalcManager/Header Files/ICalcDisplay.h b/src/CalcManager/Header Files/ICalcDisplay.h index abafbc3c..2ba57e65 100644 --- a/src/CalcManager/Header Files/ICalcDisplay.h +++ b/src/CalcManager/Header Files/ICalcDisplay.h @@ -13,6 +13,7 @@ public: virtual void SetIsInError(bool isInError) = 0; virtual void SetExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands) = 0; virtual void SetParenDisplayText(const std::wstring& pszText) = 0; + virtual void OnNoRightParenAdded() = 0; virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer. virtual void BinaryOperatorReceived() = 0; virtual void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) = 0; diff --git a/src/CalcManager/Ratpack/CalcErr.h b/src/CalcManager/Ratpack/CalcErr.h index b420a766..8c23e440 100644 --- a/src/CalcManager/Ratpack/CalcErr.h +++ b/src/CalcManager/Ratpack/CalcErr.h @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#pragma once + // CalcErr.h // // Defines the error codes thrown by ratpak and caught by Calculator @@ -24,7 +26,7 @@ // R - Reserved - not currently used for anything // // r - reserved portion of the facility code. Reserved for internal -// use. Used to indicate HRESULT values that are not status +// use. Used to indicate int32_t values that are not status // values, but are instead message ids for display strings. // // Facility - is the facility code @@ -34,49 +36,51 @@ // This format is based loosely on an OLE HRESULT and is compatible with the // SUCCEEDED and FAILED macros as well as the HRESULT_CODE macro +typedef int32_t ResultCode; + // CALC_E_DIVIDEBYZERO // // The current operation would require a divide by zero to complete -#define CALC_E_DIVIDEBYZERO ((DWORD)0x80000000) +#define CALC_E_DIVIDEBYZERO ((uint32_t)0x80000000) // CALC_E_DOMAIN // // The given input is not within the domain of this function -#define CALC_E_DOMAIN ((DWORD)0x80000001) +#define CALC_E_DOMAIN ((uint32_t)0x80000001) // CALC_E_INDEFINITE // // The result of this function is undefined -#define CALC_E_INDEFINITE ((DWORD)0x80000002) +#define CALC_E_INDEFINITE ((uint32_t)0x80000002) // CALC_E_POSINFINITY // // The result of this function is Positive Infinity. -#define CALC_E_POSINFINITY ((DWORD)0x80000003) +#define CALC_E_POSINFINITY ((uint32_t)0x80000003) // CALC_E_NEGINFINITY // // The result of this function is Negative Infinity -#define CALC_E_NEGINFINITY ((DWORD)0x80000004) +#define CALC_E_NEGINFINITY ((uint32_t)0x80000004) // CALC_E_INVALIDRANGE // // The given input is within the domain of the function but is beyond // the range for which calc can successfully compute the answer -#define CALC_E_INVALIDRANGE ((DWORD)0x80000006) +#define CALC_E_INVALIDRANGE ((uint32_t)0x80000006) // CALC_E_OUTOFMEMORY // // There is not enough free memory to complete the requested function -#define CALC_E_OUTOFMEMORY ((DWORD)0x80000007) +#define CALC_E_OUTOFMEMORY ((uint32_t)0x80000007) // CALC_E_OVERFLOW // // The result of this operation is an overflow -#define CALC_E_OVERFLOW ((DWORD)0x80000008) +#define CALC_E_OVERFLOW ((uint32_t)0x80000008) // CALC_E_NORESULT // // The result of this operation is undefined -#define CALC_E_NORESULT ((DWORD)0x80000009) +#define CALC_E_NORESULT ((uint32_t)0x80000009) diff --git a/src/CalcManager/Ratpack/basex.cpp b/src/CalcManager/Ratpack/basex.cpp index d36d7031..97a29dd4 100644 --- a/src/CalcManager/Ratpack/basex.cpp +++ b/src/CalcManager/Ratpack/basex.cpp @@ -2,17 +2,17 @@ // Licensed under the MIT License. //----------------------------------------------------------------------------- -// Package Title ratpak -// File basex.c -// Copyright (C) 1995-97 Microsoft -// Date 03-14-97 -// -// -// Description -// -// Contains number routines for internal base computations, these assume -// internal base is a power of 2. -// +// Package Title ratpak +// File basex.c +// Copyright (C) 1995-97 Microsoft +// Date 03-14-97 +// +// +// Description +// +// Contains number routines for internal base computations, these assume +// internal base is a power of 2. +// //----------------------------------------------------------------------------- #include "pch.h" #include "ratpak.h" @@ -41,14 +41,14 @@ void __inline mulnumx( PNUMBER *pa, PNUMBER b ) { // If b is not one we multiply if ( (*pa)->cdigit > 1 || (*pa)->mant[0] != 1 || (*pa)->exp != 0 ) - { + { // pa and b are both non-one. _mulnumx( pa, b ); } else { // if pa is one and b isn't just copy b. and adjust the sign. - long sign = (*pa)->sign; + int32_t sign = (*pa)->sign; DUPNUM(*pa,b); (*pa)->sign *= sign; } @@ -86,14 +86,14 @@ void _mulnumx( PNUMBER *pa, PNUMBER b ) MANTTYPE *ptrc; // ptrc is a pointer to the mantissa of c. MANTTYPE *ptrcoffset; // ptrcoffset, is the anchor location of the next // single digit multiply partial result. - long iadigit=0; // Index of digit being used in the first number. - long ibdigit=0; // Index of digit being used in the second number. + int32_t iadigit=0; // Index of digit being used in the first number. + int32_t ibdigit=0; // Index of digit being used in the second number. MANTTYPE da=0; // da is the digit from the fist number. TWO_MANTTYPE cy=0; // cy is the carry resulting from the addition of // a multiplied row into the result. - TWO_MANTTYPE mcy=0; // mcy is the resultant from a single + TWO_MANTTYPE mcy=0; // mcy is the resultant from a single // multiply, AND the carry of that multiply. - long icdigit=0; // Index of digit being calculated in final result. + int32_t icdigit=0; // Index of digit being calculated in final result. a=*pa; @@ -110,14 +110,14 @@ void _mulnumx( PNUMBER *pa, PNUMBER b ) { da = *ptra++; ptrb = b->mant; - - // Shift ptrc, and ptrcoffset, one for each digit + + // Shift ptrc, and ptrcoffset, one for each digit ptrc = ptrcoffset++; for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- ) { cy = 0; - mcy = (DWORDLONG)da * (*ptrb); + mcy = (uint64_t)da * (*ptrb); if ( mcy ) { icdigit = 0; @@ -126,28 +126,28 @@ void _mulnumx( PNUMBER *pa, PNUMBER b ) c->cdigit++; } } - + // If result is nonzero, or while result of carry is nonzero... while ( mcy || cy ) { - + // update carry from addition(s) and multiply. - cy += (TWO_MANTTYPE)ptrc[icdigit]+((DWORD)mcy&((DWORD)~BASEX)); - - // update result digit from - ptrc[icdigit++]=(MANTTYPE)((DWORD)cy&((DWORD)~BASEX)); - + cy += (TWO_MANTTYPE)ptrc[icdigit]+((uint32_t)mcy&((uint32_t)~BASEX)); + + // update result digit from + ptrc[icdigit++]=(MANTTYPE)((uint32_t)cy&((uint32_t)~BASEX)); + // update carries from mcy >>= BASEXPWR; cy >>= BASEXPWR; } - + ptrb++; ptrc++; - + } } - + // prevent different kinds of zeros, by stripping leading duplicate zeros. // digits are in order of increasing significance. while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) @@ -160,9 +160,9 @@ void _mulnumx( PNUMBER *pa, PNUMBER b ) } //----------------------------------------------------------------------------- // -// FUNCTION: numpowlongx +// FUNCTION: numpowi32x // -// ARGUMENTS: root as number power as long +// ARGUMENTS: root as number power as int32_t // number. // // RETURN: None root is changed. @@ -174,10 +174,10 @@ void _mulnumx( PNUMBER *pa, PNUMBER b ) // //----------------------------------------------------------------------------- -void numpowlongx( _Inout_ PNUMBER *proot, _In_ long power ) +void numpowi32x( _Inout_ PNUMBER *proot, _In_ int32_t power ) { - PNUMBER lret = longtonum( 1, BASEX ); + PNUMBER lret = i32tonum( 1, BASEX ); // Once the power remaining is zero we are done. while ( power > 0 ) @@ -198,7 +198,7 @@ void numpowlongx( _Inout_ PNUMBER *proot, _In_ long power ) } destroynum( *proot ); *proot=lret; - + } void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision); @@ -232,7 +232,7 @@ void __inline divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) else { // if pa is one and b is not one, just copy b, and adjust the sign. - long sign = (*pa)->sign; + int32_t sign = (*pa)->sign; DUPNUM(*pa,b); (*pa)->sign *= sign; } @@ -266,23 +266,23 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) // guesses one bit too far. PNUMBER tmp = nullptr; // current guess being worked on for divide. PNUMBER rem = nullptr; // remainder after applying guess. - long cdigits; // count of digits for answer. + int32_t cdigits; // count of digits for answer. MANTTYPE *ptrc; // ptrc is a pointer to the mantissa of c. - long thismax = precision + g_ratio; // set a maximum number of internal digits + int32_t thismax = precision + g_ratio; // set a maximum number of internal digits // to shoot for in the divide. a=*pa; if ( thismax < a->cdigit ) { - // a has more digits than precision specified, bump up digits to shoot + // a has more digits than precision specified, bump up digits to shoot // for. thismax = a->cdigit; } if ( thismax < b->cdigit ) { - // b has more digits than precision specified, bump up digits to shoot + // b has more digits than precision specified, bump up digits to shoot // for. thismax = b->cdigit; } @@ -301,14 +301,14 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) while ( cdigits++ < thismax && !zernum(rem) ) { - long digit = 0; + int32_t digit = 0; *ptrc = 0; while ( !lessnum( rem, b ) ) { digit = 1; DUPNUM( tmp, b ); destroynum( lasttmp ); - lasttmp=longtonum( 0, BASEX ); + lasttmp=i32tonum( 0, BASEX ); while ( lessnum( tmp, rem ) ) { destroynum( lasttmp ); @@ -317,7 +317,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) digit *= 2; } if ( lessnum( rem, tmp ) ) - { + { // too far, back up... destroynum( tmp ); digit /= 2; @@ -326,7 +326,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) } tmp->sign *= -1; - addnum( &rem, tmp, BASEX ); + addnum( &rem, tmp, BASEX ); destroynum( tmp ); destroynum( lasttmp ); *ptrc |= digit; @@ -341,7 +341,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) } if ( !cdigits ) - { + { // A zero, make sure no weird exponents creep in c->exp = 0; c->cdigit = 1; @@ -350,7 +350,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) { c->cdigit = cdigits; c->exp -= cdigits; - // prevent different kinds of zeros, by stripping leading duplicate + // prevent different kinds of zeros, by stripping leading duplicate // zeros. digits are in order of increasing significance. while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) { diff --git a/src/CalcManager/Ratpack/conv.cpp b/src/CalcManager/Ratpack/conv.cpp index f0e51906..c25d4481 100644 --- a/src/CalcManager/Ratpack/conv.cpp +++ b/src/CalcManager/Ratpack/conv.cpp @@ -11,7 +11,7 @@ // Description // // Contains conversion, input and output routines for numbers rationals -// and longs. +// and i32s. // // // @@ -29,12 +29,87 @@ static constexpr wstring_view DIGITS = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabc // ratio of internal 'digits' to output 'digits' // Calculated elsewhere as part of initialization and when base is changed -long g_ratio; // int(log(2L^BASEXPWR)/log(radix)) +int32_t g_ratio; // int(log(2L^BASEXPWR)/log(radix)) // Default decimal separator wchar_t g_decimalSeparator = L'.'; +// The following defines and Calc_ULong* functions were taken from +// https://github.com/dotnet/coreclr/blob/8b1595b74c943b33fa794e63e440e6f4c9679478/src/pal/inc/rt/intsafe.h +// under MIT License +// See also +// * https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +// * https://sourceforge.net/p/predef/wiki/Architectures/ +#if defined(MIDL_PASS) || defined(RC_INVOKED) || defined(_M_CEE_PURE) \ + || defined(_M_AMD64) || defined(__ARM_ARCH) || defined(__x86_64__) || defined(_M_ARM64) + +#ifndef Calc_UInt32x32To64 +#define Calc_UInt32x32To64(a, b) ((uint64_t)((uint32_t)(a)) * (uint64_t)((uint32_t)(b))) +#endif + +#elif defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) + +#ifndef Calc_UInt32x32To64 +#define Calc_UInt32x32To64(a, b) (uint64_t)((uint64_t)(uint32_t)(a) * (uint32_t)(b)) +#endif +#else + +#error Must define a target architecture. + +#endif + +#define CALC_INTSAFE_E_ARITHMETIC_OVERFLOW ((int32_t)0x80070216L) // 0x216 = 534 = ERROR_ARITHMETIC_OVERFLOW +#define CALC_ULONG_ERROR ((uint32_t)0xffffffffU) + +namespace { + int32_t + Calc_ULongAdd( + _In_ uint32_t ulAugend, + _In_ uint32_t ulAddend, + _Out_ uint32_t* pulResult) + { + int32_t hr = CALC_INTSAFE_E_ARITHMETIC_OVERFLOW; + *pulResult = CALC_ULONG_ERROR; + + if ((ulAugend + ulAddend) >= ulAugend) + { + *pulResult = (ulAugend + ulAddend); + hr = S_OK; + } + + return hr; + } + + int32_t + Calc_ULongLongToULong( + _In_ uint64_t ullOperand, + _Out_ uint32_t* pulResult) + { + int32_t hr = CALC_INTSAFE_E_ARITHMETIC_OVERFLOW; + *pulResult = CALC_ULONG_ERROR; + + if (ullOperand <= UINT32_MAX) + { + *pulResult = (uint32_t)ullOperand; + hr = S_OK; + } + + return hr; + } + + int32_t + Calc_ULongMult( + _In_ uint32_t ulMultiplicand, + _In_ uint32_t ulMultiplier, + _Out_ uint32_t* pulResult) + { + uint64_t ull64Result = Calc_UInt32x32To64(ulMultiplicand, ulMultiplier); + + return Calc_ULongLongToULong(ull64Result, pulResult); + } +} + // Used to strip trailing zeros, and prevent combinatorial explosions -bool stripzeroesnum(_Inout_ PNUMBER pnum, long starting); +bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting); void SetDecimalSeparator(wchar_t decimalSeparator) { @@ -61,7 +136,7 @@ void* zmalloc(size_t a) // //----------------------------------------------------------------------------- -void _dupnum(_In_ PNUMBER dest, _In_ PNUMBER src) +void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src) { memcpy(dest, src, (int)(sizeof(NUMBER) + ((src)->cdigit)*(sizeof(MANTTYPE)))); } @@ -125,16 +200,16 @@ void _destroyrat( _In_ PRAT prat ) // //----------------------------------------------------------------------------- -PNUMBER _createnum( _In_ ULONG size ) +PNUMBER _createnum( _In_ uint32_t size ) { PNUMBER pnumret= nullptr; - ULONG cbAlloc; + uint32_t cbAlloc; // sizeof( MANTTYPE ) is the size of a 'digit' - if (SUCCEEDED(ULongAdd(size, 1, &cbAlloc)) && - SUCCEEDED(ULongMult(cbAlloc, sizeof(MANTTYPE), &cbAlloc)) && - SUCCEEDED(ULongAdd(cbAlloc, sizeof(NUMBER), &cbAlloc))) + if (SUCCEEDED(Calc_ULongAdd(size, 1, &cbAlloc)) && + SUCCEEDED(Calc_ULongMult(cbAlloc, sizeof(MANTTYPE), &cbAlloc)) && + SUCCEEDED(Calc_ULongAdd(cbAlloc, sizeof(NUMBER), &cbAlloc))) { pnumret = (PNUMBER)zmalloc( cbAlloc ); if ( pnumret == nullptr) @@ -203,7 +278,7 @@ PRAT numtorat( _In_ PNUMBER pin, uint32_t radix) PNUMBER pnRadixn= nullptr; DUPNUM( pnRadixn, pin ); - PNUMBER qnRadixn=longtonum( 1, radix); + PNUMBER qnRadixn=i32tonum( 1, radix); // Ensure p and q start out as integers. if ( pnRadixn->exp < 0 ) @@ -245,24 +320,24 @@ PRAT numtorat( _In_ PNUMBER pin, uint32_t radix) PNUMBER nRadixxtonum( _In_ PNUMBER a, uint32_t radix, int32_t precision) { - unsigned long bitmask; - unsigned long cdigits; + uint32_t bitmask; + uint32_t cdigits; MANTTYPE *ptr; - PNUMBER sum = longtonum( 0, radix ); - PNUMBER powofnRadix = longtonum( BASEX, radix ); + PNUMBER sum = i32tonum( 0, radix ); + PNUMBER powofnRadix = i32tonum( BASEX, radix ); // A large penalty is paid for conversion of digits no one will see anyway. // limit the digits to the minimum of the existing precision or the // requested precision. cdigits = precision + 1; - if ( cdigits > (unsigned long)a->cdigit ) + if ( cdigits > (uint32_t)a->cdigit ) { - cdigits = (unsigned long)a->cdigit; + cdigits = (uint32_t)a->cdigit; } // scale by the internal base to the internal exponent offset of the LSD - numpowlong( &powofnRadix, a->exp + (a->cdigit - cdigits), radix, precision); + numpowi32( &powofnRadix, a->exp + (a->cdigit - cdigits), radix, precision); // Loop over all the relative digits from MSD to LSD for ( ptr = &(a->mant[a->cdigit-1]); cdigits > 0; @@ -303,8 +378,8 @@ PNUMBER nRadixxtonum( _In_ PNUMBER a, uint32_t radix, int32_t precision) PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix) { - PNUMBER pnumret = longtonum(0, BASEX); // pnumret is the number in internal form. - PNUMBER num_radix = longtonum(radix, BASEX); + PNUMBER pnumret = i32tonum(0, BASEX); // pnumret is the number in internal form. + PNUMBER num_radix = i32tonum(radix, BASEX); MANTTYPE *ptrdigit = a->mant; // pointer to digit being worked on. // Digits are in reverse order, back over them LSD first. @@ -312,20 +387,20 @@ PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix) PNUMBER thisdigit = nullptr; // thisdigit holds the current digit of a // being summed into result. - long idigit; // idigit is the iterate of digits in a. + int32_t idigit; // idigit is the iterate of digits in a. for ( idigit = 0; idigit < a->cdigit; idigit++ ) { mulnumx( &pnumret, num_radix); // WARNING: // This should just smack in each digit into a 'special' thisdigit. // and not do the overhead of recreating the number type each time. - thisdigit = longtonum( *ptrdigit--, BASEX ); + thisdigit = i32tonum( *ptrdigit--, BASEX ); addnum( &pnumret, thisdigit, BASEX ); destroynum( thisdigit ); } // Calculate the exponent of the external base for scaling. - numpowlongx( &num_radix, a->exp ); + numpowi32x( &num_radix, a->exp ); // ... and scale the result. mulnumx( &pnumret, num_radix); @@ -391,7 +466,7 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs } // Deal with exponent - long expt = 0; + int32_t expt = 0; if (!exponent.empty()) { // Exponent specified, convert to number form. @@ -404,18 +479,18 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs } // Convert exponent number form to native integral form, and cleanup. - expt = numtolong(numExp, radix); + expt = numtoi32(numExp, radix); destroynum(numExp); } // Convert native integral exponent form to rational multiplier form. - PNUMBER pnumexp = longtonum(radix, BASEX); - numpowlongx(&pnumexp, abs(expt)); + PNUMBER pnumexp = i32tonum(radix, BASEX); + numpowi32x(&pnumexp, abs(expt)); PRAT pratexp = nullptr; createrat(pratexp); DUPNUM(pratexp->pp, pnumexp); - pratexp->pq = longtonum(1, BASEX); + pratexp->pq = i32tonum(1, BASEX); destroynum(pnumexp); if (exponentIsNegative) @@ -574,11 +649,11 @@ wchar_t NormalizeCharDigit(wchar_t c, uint32_t radix) PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precision) { - long expSign = 1L; // expSign is exponent sign ( +/- 1 ) - long expValue = 0L; // expValue is exponent mantissa, should be unsigned + int32_t expSign = 1L; // expSign is exponent sign ( +/- 1 ) + int32_t expValue = 0L; // expValue is exponent mantissa, should be unsigned PNUMBER pnumret = nullptr; - createnum(pnumret, static_cast(numberString.length())); + createnum(pnumret, static_cast(numberString.length())); pnumret->sign = 1L; pnumret->cdigit = 0; pnumret->exp = 0; @@ -612,6 +687,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; @@ -636,7 +712,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis if (pos != wstring_view::npos) { expValue *= radix; - expValue += static_cast(pos); + expValue += static_cast(pos); } else { @@ -646,7 +722,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); @@ -682,7 +758,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis } else { - while (pnumret->cdigit < static_cast(numberString.length())) + while (pnumret->cdigit < static_cast(numberString.length())) { pnumret->cdigit++; pnumret->exp--; @@ -705,65 +781,65 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis //----------------------------------------------------------------------------- // -// FUNCTION: longtorat +// FUNCTION: i32torat // -// ARGUMENTS: long +// ARGUMENTS: int32_t // -// RETURN: Rational representation of long input. +// RETURN: Rational representation of int32_t input. // -// DESCRIPTION: Converts long input to rational (p over q) -// form, where q is 1 and p is the long. +// DESCRIPTION: Converts int32_t input to rational (p over q) +// form, where q is 1 and p is the int32_t. // //----------------------------------------------------------------------------- -PRAT longtorat( _In_ long inlong ) +PRAT i32torat( _In_ int32_t ini32 ) { PRAT pratret= nullptr; createrat( pratret ); - pratret->pp = longtonum(inlong, BASEX ); - pratret->pq = longtonum(1L, BASEX ); + pratret->pp = i32tonum(ini32, BASEX ); + pratret->pq = i32tonum(1L, BASEX ); return( pratret ); } //----------------------------------------------------------------------------- // -// FUNCTION: Ulongtorat +// FUNCTION: Ui32torat // -// ARGUMENTS: ulong +// ARGUMENTS: ui32 // -// RETURN: Rational representation of unsigned long input. +// RETURN: Rational representation of uint32_t input. // -// DESCRIPTION: Converts unsigned long input to rational (p over q) -// form, where q is 1 and p is the unsigned long. Being unsigned cant take negative +// DESCRIPTION: Converts uint32_t input to rational (p over q) +// form, where q is 1 and p is the uint32_t. Being unsigned cant take negative // numbers, but the full range of unsigned numbers // //----------------------------------------------------------------------------- -PRAT Ulongtorat( _In_ unsigned long inulong ) +PRAT Ui32torat( _In_ uint32_t inui32 ) { PRAT pratret= nullptr; createrat( pratret ); - pratret->pp = Ulongtonum(inulong, BASEX ); - pratret->pq = longtonum(1L, BASEX ); + pratret->pp = Ui32tonum(inui32, BASEX ); + pratret->pq = i32tonum(1L, BASEX ); return( pratret ); } //----------------------------------------------------------------------------- // -// FUNCTION: longtonum +// FUNCTION: i32tonum // -// ARGUMENTS: long input and radix requested. +// ARGUMENTS: int32_t input and radix requested. // // RETURN: number // // DESCRIPTION: Returns a number representation in the -// base requested of the long value passed in. +// base requested of the int32_t value passed in. // //----------------------------------------------------------------------------- -PNUMBER longtonum( long inlong, uint32_t radix) +PNUMBER i32tonum( int32_t ini32, uint32_t radix) { MANTTYPE *pmant; @@ -773,10 +849,10 @@ PNUMBER longtonum( long inlong, uint32_t radix) pmant = pnumret->mant; pnumret->cdigit = 0; pnumret->exp = 0; - if ( inlong < 0 ) + if ( ini32 < 0 ) { pnumret->sign = -1; - inlong *= -1; + ini32 *= -1; } else { @@ -784,30 +860,30 @@ PNUMBER longtonum( long inlong, uint32_t radix) } do { - *pmant++ = (MANTTYPE)(inlong % radix); - inlong /= radix; + *pmant++ = (MANTTYPE)(ini32 % radix); + ini32 /= radix; pnumret->cdigit++; - } while ( inlong ); + } while ( ini32 ); return( pnumret ); } //----------------------------------------------------------------------------- // -// FUNCTION: Ulongtonum +// FUNCTION: Ui32tonum // -// ARGUMENTS: ULONG input and radix requested. +// ARGUMENTS: uint32_t input and radix requested. // // RETURN: number // // DESCRIPTION: Returns a number representation in the -// base requested of the unsigned long value passed in. Being unsigned number it has no +// base requested of the uint32_t value passed in. Being unsigned number it has no // negative number and takes the full range of unsigned number // //----------------------------------------------------------------------------- -PNUMBER Ulongtonum(unsigned long inlong, uint32_t radix) +PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix) { MANTTYPE *pmant; PNUMBER pnumret= nullptr; @@ -817,12 +893,12 @@ PNUMBER Ulongtonum(unsigned long inlong, uint32_t radix) pnumret->cdigit = 0; pnumret->exp = 0; pnumret->sign = 1; - + do { - *pmant++ = (MANTTYPE)(inlong % radix); - inlong /= radix; + *pmant++ = (MANTTYPE)(ini32 % radix); + ini32 /= radix; pnumret->cdigit++; - } while ( inlong ); + } while ( ini32 ); return( pnumret ); } @@ -830,23 +906,23 @@ PNUMBER Ulongtonum(unsigned long inlong, uint32_t radix) //----------------------------------------------------------------------------- // -// FUNCTION: rattolong +// FUNCTION: rattoi32 // // ARGUMENTS: rational number in internal base, integer radix and int32_t precision. // -// RETURN: long +// RETURN: int32_t // -// DESCRIPTION: returns the long representation of the +// DESCRIPTION: returns the int32_t representation of the // number input. Assumes that the number is in the internal // base. // //----------------------------------------------------------------------------- -long rattolong( _In_ PRAT prat , uint32_t radix, int32_t precision) +int32_t rattoi32( _In_ PRAT prat , uint32_t radix, int32_t precision) { - if ( rat_gt( prat, rat_max_long, precision) || rat_lt( prat, rat_min_long, precision) ) + if ( rat_gt( prat, rat_max_i32, precision) || rat_lt( prat, rat_min_i32, precision) ) { - // Don't attempt rattolong of anything too big or small + // Don't attempt rattoi32 of anything too big or small throw( CALC_E_DOMAIN ); } @@ -857,7 +933,7 @@ long rattolong( _In_ PRAT prat , uint32_t radix, int32_t precision) divnumx( &(pint->pp), pint->pq, precision); DUPNUM( pint->pq, num_one ); - long lret = numtolong( pint->pp, BASEX ); + int32_t lret = numtoi32( pint->pp, BASEX ); destroyrat(pint); @@ -866,22 +942,22 @@ long rattolong( _In_ PRAT prat , uint32_t radix, int32_t precision) //----------------------------------------------------------------------------- // -// FUNCTION: rattoUlong +// FUNCTION: rattoUi32 // // ARGUMENTS: rational number in internal base, integer radix and int32_t precision. // -// RETURN: Ulong +// RETURN: Ui32 // -// DESCRIPTION: returns the Ulong representation of the +// DESCRIPTION: returns the Ui32 representation of the // number input. Assumes that the number is in the internal // base. // //----------------------------------------------------------------------------- -unsigned long rattoUlong( _In_ PRAT prat, uint32_t radix, int32_t precision) +uint32_t rattoUi32( _In_ PRAT prat, uint32_t radix, int32_t precision) { if ( rat_gt( prat, rat_dword, precision) || rat_lt( prat, rat_zero, precision) ) { - // Don't attempt rattoulong of anything too big or small + // Don't attempt rattoui32 of anything too big or small throw( CALC_E_DOMAIN ); } @@ -892,7 +968,7 @@ unsigned long rattoUlong( _In_ PRAT prat, uint32_t radix, int32_t precision) divnumx( &(pint->pp), pint->pq, precision); DUPNUM( pint->pq, num_one ); - unsigned long lret = numtolong( pint->pp, BASEX ); // This happens to work even if it is only signed + uint32_t lret = numtoi32( pint->pp, BASEX ); // This happens to work even if it is only signed destroyrat(pint); @@ -902,11 +978,11 @@ unsigned long rattoUlong( _In_ PRAT prat, uint32_t radix, int32_t precision) //----------------------------------------------------------------------------- // -// FUNCTION: rattoUlonglong +// FUNCTION: rattoUi64 // // ARGUMENTS: rational number in internal base, integer radix and int32_t precision // -// RETURN: Ulonglong +// RETURN: Ui64 // // DESCRIPTION: returns the 64 bit (irrespective of which processor this is running in) representation of the // number input. Assumes that the number is in the internal @@ -915,50 +991,50 @@ unsigned long rattoUlong( _In_ PRAT prat, uint32_t radix, int32_t precision) // internal base chosen happens to be 2^32, this is easier. //----------------------------------------------------------------------------- -ULONGLONG rattoUlonglong( _In_ PRAT prat, uint32_t radix, int32_t precision) +uint64_t rattoUi64( _In_ PRAT prat, uint32_t radix, int32_t precision) { PRAT pint = nullptr; // first get the LO 32 bit word DUPRAT(pint, prat); andrat(&pint, rat_dword, radix, precision); // & 0xFFFFFFFF (2 ^ 32 -1) - unsigned long lo = rattoUlong(pint, radix, precision); // wont throw exception because already hi-dword chopped off + uint32_t lo = rattoUi32(pint, radix, precision); // wont throw exception because already hi-dword chopped off DUPRAT(pint, prat); // previous pint will get freed by this as well - PRAT prat32 = longtorat(32); + PRAT prat32 = i32torat(32); rshrat(&pint, prat32, radix, precision); intrat( &pint, radix, precision); andrat(&pint, rat_dword, radix, precision); // & 0xFFFFFFFF (2 ^ 32 -1) - unsigned long hi = rattoUlong(pint, radix, precision); + uint32_t hi = rattoUi32(pint, radix, precision); destroyrat(prat32); destroyrat(pint); - return (((ULONGLONG)hi << 32) | lo); + return (((uint64_t)hi << 32) | lo); } //----------------------------------------------------------------------------- // -// FUNCTION: numtolong +// FUNCTION: numtoi32 // // ARGUMENTS: number input and base of that number. // -// RETURN: long +// RETURN: int32_t // -// DESCRIPTION: returns the long representation of the +// DESCRIPTION: returns the int32_t representation of the // number input. Assumes that the number is really in the // base claimed. // //----------------------------------------------------------------------------- -long numtolong( _In_ PNUMBER pnum, uint32_t radix ) +int32_t numtoi32( _In_ PNUMBER pnum, uint32_t radix ) { - long lret = 0; + int32_t lret = 0; MANTTYPE *pmant = pnum->mant; pmant += pnum->cdigit - 1; - long expt = pnum->exp; - for (long length = pnum->cdigit; length > 0 && length + expt > 0; length--) + int32_t expt = pnum->exp; + for (int32_t length = pnum->cdigit; length > 0 && length + expt > 0; length--) { lret *= radix; lret += *(pmant--); @@ -985,10 +1061,10 @@ long numtolong( _In_ PNUMBER pnum, uint32_t radix ) // //----------------------------------------------------------------------------- -bool stripzeroesnum(_Inout_ PNUMBER pnum, long starting) +bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting) { MANTTYPE *pmant; - long cdigits; + int32_t cdigits; bool fstrip = false; // point pmant to the LeastCalculatedDigit @@ -1041,10 +1117,10 @@ bool stripzeroesnum(_Inout_ PNUMBER pnum, long starting) wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_t precision) { stripzeroesnum(pnum, precision + 2); - long length = pnum->cdigit; - long exponent = pnum->exp + length; // Actual number of digits to the left of decimal + int32_t length = pnum->cdigit; + int32_t exponent = pnum->exp + length; // Actual number of digits to the left of decimal - long oldFormat = format; + int32_t oldFormat = format; if (exponent > precision && format == FMT_FLOAT) { // Force scientific mode to prevent user from assuming 33rd digit is exact. @@ -1064,7 +1140,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_ if (!zernum(pnum) && (pnum->cdigit >= precision || (length - exponent > precision && exponent >= -MAX_ZEROS_AFTER_DECIMAL))) { // Otherwise round. - round = longtonum(radix, radix); + round = i32tonum(radix, radix); divnum(&round, num_two, radix, precision); // Make round number exponent one below the LSD for the number. @@ -1109,7 +1185,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_ if (round != nullptr) { addnum(&pnum, round, radix); - long offset = (pnum->cdigit + pnum->exp) - (round->cdigit + round->exp); + int32_t offset = (pnum->cdigit + pnum->exp) - (round->cdigit + round->exp); destroynum(round); if (stripzeroesnum(pnum, offset)) { @@ -1125,7 +1201,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_ // Set up all the post rounding stuff. bool useSciForm = false; - long eout = exponent - 1; // Displayed exponent. + int32_t eout = exponent - 1; // Displayed exponent. MANTTYPE *pmant = pnum->mant + pnum->cdigit - 1; // Case where too many digits are to the left of the decimal or // FMT_SCIENTIFIC or FMT_ENGINEERING was specified. @@ -1239,7 +1315,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_ // // ARGUMENTS: // PRAT *representation of a number. -// long representation of base to dump to screen. +// i32 representation of base to dump to screen. // fmt, one of FMT_FLOAT FMT_SCIENTIFIC or FMT_ENGINEERING // precision uint32_t // @@ -1269,8 +1345,8 @@ PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision) DUPRAT(temprat, prat); // Convert p and q of rational form from internal base to requested base. // Scale by largest power of BASEX possible. - long scaleby = min(temprat->pp->exp, temprat->pq->exp); - scaleby = max(scaleby, 0); + int32_t scaleby = min(temprat->pp->exp, temprat->pq->exp); + scaleby = max(scaleby, 0); temprat->pp->exp -= scaleby; temprat->pq->exp -= scaleby; @@ -1358,12 +1434,12 @@ PNUMBER gcd( _In_ PNUMBER a, _In_ PNUMBER b) //----------------------------------------------------------------------------- // -// FUNCTION: longfactnum +// FUNCTION: i32factnum // // ARGUMENTS: -// long integer to factorialize. -// long integer representing base of answer. -// unsigned long integer for radix +// int32_t integer to factorialize. +// int32_t integer representing base of answer. +// uint32_t integer for radix // // RETURN: Factorial of input in radix PNUMBER form. // @@ -1371,17 +1447,17 @@ PNUMBER gcd( _In_ PNUMBER a, _In_ PNUMBER b) // //----------------------------------------------------------------------------- -PNUMBER longfactnum(long inlong, uint32_t radix) +PNUMBER i32factnum(int32_t ini32, uint32_t radix) { PNUMBER lret= nullptr; PNUMBER tmp= nullptr; - lret = longtonum( 1, radix); + lret = i32tonum( 1, radix); - while ( inlong > 0 ) + while ( ini32 > 0 ) { - tmp = longtonum( inlong--, radix); + tmp = i32tonum( ini32--, radix); mulnum( &lret, tmp, radix); destroynum( tmp ); } @@ -1390,30 +1466,30 @@ PNUMBER longfactnum(long inlong, uint32_t radix) //----------------------------------------------------------------------------- // -// FUNCTION: longprodnum +// FUNCTION: i32prodnum // // ARGUMENTS: -// long integer to factorialize. -// long integer representing base of answer. -// unsigned long integer for radix +// int32_t integer to factorialize. +// int32_t integer representing base of answer. +// uint32_t integer for radix // // RETURN: Factorial of input in base PNUMBER form. // //----------------------------------------------------------------------------- -PNUMBER longprodnum(long start, long stop, uint32_t radix) +PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix) { PNUMBER lret= nullptr; PNUMBER tmp= nullptr; - lret = longtonum( 1, radix); + lret = i32tonum( 1, radix); while ( start <= stop ) { if ( start ) { - tmp = longtonum( start, radix); + tmp = i32tonum( start, radix); mulnum( &lret, tmp, radix); destroynum( tmp ); } @@ -1424,10 +1500,10 @@ PNUMBER longprodnum(long start, long stop, uint32_t radix) //----------------------------------------------------------------------------- // -// FUNCTION: numpowlong +// FUNCTION: numpowi32 // -// ARGUMENTS: root as number power as long and radix of -// number along with the precision value in long. +// ARGUMENTS: root as number power as int32_t and radix of +// number along with the precision value in int32_t. // // RETURN: None root is changed. // @@ -1436,9 +1512,9 @@ PNUMBER longprodnum(long start, long stop, uint32_t radix) // //----------------------------------------------------------------------------- -void numpowlong( _Inout_ PNUMBER *proot, long power, uint32_t radix, int32_t precision) +void numpowi32( _Inout_ PNUMBER *proot, int32_t power, uint32_t radix, int32_t precision) { - PNUMBER lret = longtonum( 1, radix ); + PNUMBER lret = i32tonum( 1, radix ); while ( power > 0 ) { @@ -1457,9 +1533,9 @@ void numpowlong( _Inout_ PNUMBER *proot, long power, uint32_t radix, int32_t pre //----------------------------------------------------------------------------- // -// FUNCTION: ratpowlong +// FUNCTION: ratpowi32 // -// ARGUMENTS: root as rational, power as long and precision as uint32_t. +// ARGUMENTS: root as rational, power as int32_t and precision as int32_t. // // RETURN: None root is changed. // @@ -1468,14 +1544,14 @@ void numpowlong( _Inout_ PNUMBER *proot, long power, uint32_t radix, int32_t pre // //----------------------------------------------------------------------------- -void ratpowlong( _Inout_ PRAT *proot, long power, int32_t precision) +void ratpowi32( _Inout_ PRAT *proot, int32_t power, int32_t precision) { if ( power < 0 ) { // Take the positive power and invert answer. PNUMBER pnumtemp = nullptr; - ratpowlong( proot, -power, precision); + ratpowi32( proot, -power, precision); pnumtemp = (*proot)->pp; (*proot)->pp = (*proot)->pq; (*proot)->pq = pnumtemp; @@ -1484,7 +1560,7 @@ void ratpowlong( _Inout_ PRAT *proot, long power, int32_t precision) { PRAT lret= nullptr; - lret = longtorat( 1 ); + lret = i32torat( 1 ); while ( power > 0 ) { diff --git a/src/CalcManager/Ratpack/exp.cpp b/src/CalcManager/Ratpack/exp.cpp index 97d02c6b..c8691cfa 100644 --- a/src/CalcManager/Ratpack/exp.cpp +++ b/src/CalcManager/Ratpack/exp.cpp @@ -46,11 +46,11 @@ void _exprat( PRAT *px, int32_t precision) { CREATETAYLOR(); - addnum(&(pret->pp),num_one, BASEX); - addnum(&(pret->pq),num_one, BASEX); + addnum(&(pret->pp),num_one, BASEX); + addnum(&(pret->pq),num_one, BASEX); DUPRAT(thisterm,pret); - n2=longtonum(0L, BASEX); + n2=i32tonum(0L, BASEX); do { NEXTTERM(*px, INC(n2) DIVNUM(n2), precision); @@ -64,7 +64,7 @@ void exprat( PRAT *px, uint32_t radix, int32_t precision) { PRAT pwr= nullptr; PRAT pint= nullptr; - long intpwr; + int32_t intpwr; if ( rat_gt( *px, rat_max_exp, precision) || rat_lt( *px, rat_min_exp, precision) ) { @@ -77,11 +77,11 @@ void exprat( PRAT *px, uint32_t radix, int32_t precision) intrat(&pint, radix, precision); - intpwr = rattolong(pint, radix, precision); - ratpowlong( &pwr, intpwr, precision); + intpwr = rattoi32(pint, radix, precision); + ratpowi32( &pwr, intpwr, precision); subrat(px, pint, precision); - + // It just so happens to be an integral power of e. if ( rat_gt( *px, rat_negsmallest, precision) && rat_lt( *px, rat_smallest, precision) ) { @@ -131,7 +131,7 @@ void _lograt( PRAT *px, int32_t precision) CREATETAYLOR(); createrat(thisterm); - + // sub one from x (*px)->pq->sign *= -1; addnum(&((*px)->pp),(*px)->pq, BASEX); @@ -140,7 +140,7 @@ void _lograt( PRAT *px, int32_t precision) DUPRAT(pret,*px); DUPRAT(thisterm,*px); - n2=longtonum(1L, BASEX); + n2=i32tonum(1L, BASEX); (*px)->pp->sign *= -1; do { @@ -158,14 +158,14 @@ void lograt( PRAT *px, int32_t precision) bool fneglog; PRAT pwr = nullptr; // pwr is the large scaling factor. PRAT offset = nullptr; // offset is the incremental scaling factor. - - + + // Check for someone taking the log of zero or a negative number. if ( rat_le( *px, rat_zero, precision) ) { throw( CALC_E_DOMAIN ); } - + // Get number > 1, for scaling fneglog = rat_lt( *px, rat_one, precision); if ( fneglog ) @@ -176,17 +176,17 @@ void lograt( PRAT *px, int32_t precision) (*px)->pp = (*px)->pq; (*px)->pq = pnumtemp; } - + // Scale the number within BASEX factor of 1, for the large scale. // log(x*2^(BASEXPWR*k)) = BASEXPWR*k*log(2)+log(x) if ( LOGRAT2(*px) > 1 ) { - // Take advantage of px's base BASEX to scale quickly down to + // Take advantage of px's base BASEX to scale quickly down to // a reasonable range. - long intpwr; + int32_t intpwr; intpwr=LOGRAT2(*px)-1; (*px)->pq->exp += intpwr; - pwr=longtorat(intpwr*BASEXPWR); + pwr=i32torat(intpwr*BASEXPWR); mulrat(&pwr, ln_two, precision); // ln(x+e)-ln(x) looks close to e when x is close to one using some // expansions. This means we can trim past precision digits+1. @@ -206,17 +206,17 @@ void lograt( PRAT *px, int32_t precision) } _lograt(px, precision); - + // Add the large and small scaling factors, take into account // small scaling was done in e_to_one_half chunks. divrat(&offset, rat_two, precision); addrat(&pwr, offset, precision); - + // And add the resulting scaling factor to the answer. addrat(px, pwr, precision); trimit(px, precision); - + // If number started out < 1 rescale answer to negative. if ( fneglog ) { @@ -224,9 +224,9 @@ void lograt( PRAT *px, int32_t precision) } destroyrat(offset); - destroyrat(pwr); + destroyrat(pwr); } - + void log10rat( PRAT *px, int32_t precision) { @@ -235,7 +235,7 @@ void log10rat( PRAT *px, int32_t precision) } // -// return if the given x is even number. The assumption here is its denominator is 1 and we are testing the numerator is +// return if the given x is even number. The assumption here is its denominator is 1 and we are testing the numerator is // even or not bool IsEven(PRAT x, uint32_t radix, int32_t precision) { @@ -309,7 +309,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis // Calculate the following use the Powers of Powers rule: // px ^ (yNum/yDenom) == px ^ yNum ^ (1/yDenom) - // 1. For px ^ yNum, we call powratcomp directly which will call ratpowlong + // 1. For px ^ yNum, we call powratcomp directly which will call ratpowi32 // and store the result in pxPowNum // 2. For pxPowNum ^ (1/yDenom), we call powratcomp // 3. Validate the result of 2 by adding/subtracting 0.5, flooring and call powratcomp with yDenom @@ -318,7 +318,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis // 1. Initialize result. PRAT pxPow = nullptr; DUPRAT(pxPow, *px); - + // 2. Calculate pxPow = px ^ yNumerator // if yNumerator is not 1 if (!rat_equ(yNumerator, rat_one, precision)) @@ -341,7 +341,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis PRAT originalResult = nullptr; DUPRAT(originalResult, pxPow); powratcomp(&originalResult, oneoveryDenom, radix, precision); - + // ################################## // Round the originalResult to roundedResult // ################################## @@ -375,7 +375,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis else { DUPRAT(*px, originalResult); - } + } destroyrat(oneoveryDenom); destroyrat(originalResult); @@ -408,7 +408,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis //--------------------------------------------------------------------------- void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) { - long sign = ((*px)->pp->sign * (*px)->pq->sign); + int32_t sign = ((*px)->pp->sign * (*px)->pq->sign); // Take the absolute value (*px)->pp->sign = 1; @@ -429,7 +429,7 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) sign = 1; } } - else + else { PRAT pxint= nullptr; DUPRAT(pxint,*px); @@ -451,12 +451,12 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) fracrat(&podd, radix, precision); if ( rat_gt( podd, rat_negsmallest, precision) && rat_lt( podd, rat_smallest, precision) ) { - // If power is an integer let ratpowlong deal with it. + // If power is an integer let ratpowi32 deal with it. PRAT iy = nullptr; - long inty; + int32_t inty; DUPRAT(iy,y); subrat(&iy, podd, precision); - inty = rattolong(iy, radix, precision); + inty = rattoi32(iy, radix, precision); PRAT plnx = nullptr; DUPRAT(plnx,*px); @@ -472,7 +472,7 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) throw( CALC_E_DOMAIN ); } destroyrat(plnx); - ratpowlong(px, inty, precision); + ratpowi32(px, inty, precision); if ( ( inty & 1 ) == 0 ) { sign=1; @@ -491,7 +491,7 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) PRAT pNumerator = nullptr; PRAT pDenominator = nullptr; bool fBadExponent = false; - + // Get the numbers in arbitrary precision rational number format DUPRAT(pNumerator, rat_zero); // pNumerator->pq is 1 one DUPRAT(pDenominator, rat_zero); // pDenominator->pq is 1 one @@ -516,7 +516,7 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) } destroyrat(pNumerator); destroyrat(pDenominator); - + if (fBadExponent) { throw( CALC_E_DOMAIN ); diff --git a/src/CalcManager/Ratpack/fact.cpp b/src/CalcManager/Ratpack/fact.cpp index ab11451f..c974b005 100644 --- a/src/CalcManager/Ratpack/fact.cpp +++ b/src/CalcManager/Ratpack/fact.cpp @@ -72,18 +72,18 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision) PRAT mpy= nullptr; PRAT ratprec = nullptr; PRAT ratRadix = nullptr; - long oldprec; - + int32_t oldprec; + // Set up constants and initial conditions oldprec = precision; - ratprec = longtorat( oldprec ); - + ratprec = i32torat( oldprec ); + // Find the best 'A' for convergence to the required precision. - a=longtorat( radix ); + a=i32torat( radix ); lograt(&a, precision); mulrat(&a, ratprec, precision); - // Really is -ln(n)+1, but -ln(n) will be < 1 + // Really is -ln(n)+1, but -ln(n) will be < 1 // if we scale n between 0.5 and 1.5 addrat(&a, rat_two, precision); DUPRAT(tmp,a); @@ -91,12 +91,12 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision) mulrat(&tmp, *pn, precision); addrat(&a, tmp, precision); addrat(&a, rat_one, precision); - + // Calculate the necessary bump in precision and up the precision. - // The following code is equivalent to + // The following code is equivalent to // precision += ln(exp(a)*pow(a,n+1.5))-ln(radix)); DUPRAT(tmp,*pn); - one_pt_five=longtorat( 3L ); + one_pt_five=i32torat( 3L ); divrat( &one_pt_five, rat_two, precision); addrat( &tmp, one_pt_five, precision); DUPRAT(term,a); @@ -105,22 +105,22 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision) exprat( &tmp, radix, precision); mulrat( &term, tmp, precision); lograt( &term, precision); - ratRadix = longtorat(radix); + ratRadix = i32torat(radix); DUPRAT(tmp,ratRadix); lograt( &tmp, precision); subrat( &term, tmp, precision); - precision += rattolong( term, radix, precision); - + precision += rattoi32( term, radix, precision); + // Set up initial terms for series, refer to series in above comment block. DUPRAT(factorial,rat_one); // Start factorial out with one - count = longtonum( 0L, BASEX ); + count = i32tonum( 0L, BASEX ); DUPRAT(mpy,a); powratcomp(&mpy,*pn, radix, precision); // a2=a^2 DUPRAT(a2,a); mulrat(&a2, a, precision); - + // sum=(1/n)-(a/(n+1)) DUPRAT(sum,rat_one); divrat(&sum, *pn, precision); @@ -136,14 +136,14 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision) divrat(&err, ratRadix, precision); // Just get something not tiny in term - DUPRAT(term, rat_two ); + DUPRAT(term, rat_two ); // Loop until precision is reached, or asked to halt. while ( !zerrat( term ) && rat_gt( term, err, precision) ) { addrat(pn, rat_two, precision); - - // WARNING: mixing numbers and rationals here. + + // WARNING: mixing numbers and rationals here. // for speed and efficiency. INC(count); mulnumx(&(factorial->pp),count); @@ -166,15 +166,15 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision) DUPRAT(term,rat_one); divrat( &term, *pn, precision); subrat( &term, tmp, precision); - + divrat (&term, factorial, precision); addrat( &sum, term, precision); ABSRAT(term); } - + // Multiply by factor. mulrat( &sum, mpy, precision); - + // And cleanup precision = oldprec; destroyrat(ratprec); @@ -199,13 +199,13 @@ void factrat( PRAT *px, uint32_t radix, int32_t precision) PRAT fact = nullptr; PRAT frac = nullptr; PRAT neg_rat_one = nullptr; - + if ( rat_gt( *px, rat_max_fact, precision) || rat_lt( *px, rat_min_fact, precision) ) { // Don't attempt factorial of anything too large or small. throw CALC_E_OVERFLOW; } - + DUPRAT(fact,rat_one); DUPRAT(neg_rat_one,rat_one); @@ -226,7 +226,7 @@ void factrat( PRAT *px, uint32_t radix, int32_t precision) mulrat( &fact, *px, precision); subrat( px, rat_one, precision); } - + // Added to make numbers 'close enough' to integers use integer factorial. if ( LOGRATRADIX(*px) <= -precision) { diff --git a/src/CalcManager/Ratpack/itrans.cpp b/src/CalcManager/Ratpack/itrans.cpp index 66e6fc62..1ecbf4a1 100644 --- a/src/CalcManager/Ratpack/itrans.cpp +++ b/src/CalcManager/Ratpack/itrans.cpp @@ -69,13 +69,13 @@ void _asinrat( PRAT *px, int32_t precision) { CREATETAYLOR(); - DUPRAT(pret,*px); + DUPRAT(pret,*px); DUPRAT(thisterm,*px); DUPNUM(n2,num_one); do { - NEXTTERM(xx,MULNUM(n2) MULNUM(n2) + NEXTTERM(xx,MULNUM(n2) MULNUM(n2) INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); } while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); @@ -92,7 +92,7 @@ void asinanglerat( _Inout_ PRAT *pa, ANGLE_TYPE angletype, uint32_t radix, int32 void asinrat( PRAT *px, uint32_t radix, int32_t precision) { - long sgn; + int32_t sgn; PRAT pret= nullptr; PRAT phack= nullptr; @@ -100,7 +100,7 @@ void asinrat( PRAT *px, uint32_t radix, int32_t precision) (*px)->pp->sign = 1; (*px)->pq->sign = 1; - + // Avoid the really bad part of the asin curve near +/-1. DUPRAT(phack,*px); subrat(&phack, rat_one, precision); @@ -185,15 +185,15 @@ void _acosrat( PRAT *px, int32_t precision) { CREATETAYLOR(); - createrat(thisterm); - thisterm->pp=longtonum( 1L, BASEX ); - thisterm->pq=longtonum( 1L, BASEX ); + createrat(thisterm); + thisterm->pp=i32tonum( 1L, BASEX ); + thisterm->pq=i32tonum( 1L, BASEX ); DUPNUM(n2,num_one); do { - NEXTTERM(xx,MULNUM(n2) MULNUM(n2) + NEXTTERM(xx,MULNUM(n2) MULNUM(n2) INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); } while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); @@ -204,13 +204,13 @@ void _acosrat( PRAT *px, int32_t precision) void acosrat( PRAT *px, uint32_t radix, int32_t precision) { - long sgn; + int32_t sgn; sgn = (*px)->pp->sign*(*px)->pq->sign; (*px)->pp->sign = 1; (*px)->pq->sign = 1; - + if ( rat_equ( *px, rat_one, precision) ) { if ( sgn == -1 ) @@ -274,7 +274,7 @@ void _atanrat( PRAT *px, int32_t precision) { CREATETAYLOR(); - DUPRAT(pret,*px); + DUPRAT(pret,*px); DUPRAT(thisterm,*px); DUPNUM(n2,num_one); @@ -291,14 +291,14 @@ void _atanrat( PRAT *px, int32_t precision) void atanrat( PRAT *px, uint32_t radix, int32_t precision) { - long sgn; + int32_t sgn; PRAT tmpx= nullptr; sgn = (*px)->pp->sign * (*px)->pq->sign; (*px)->pp->sign = 1; (*px)->pq->sign = 1; - + if ( rat_gt( (*px), pt_eight_five, precision) ) { if ( rat_gt( (*px), rat_two, precision) ) @@ -314,7 +314,7 @@ void atanrat( PRAT *px, uint32_t radix, int32_t precision) subrat(px, tmpx, precision); destroyrat( tmpx ); } - else + else { (*px)->pp->sign = sgn; DUPRAT(tmpx,*px); diff --git a/src/CalcManager/Ratpack/itransh.cpp b/src/CalcManager/Ratpack/itransh.cpp index 7b75e703..d6734a1f 100644 --- a/src/CalcManager/Ratpack/itransh.cpp +++ b/src/CalcManager/Ratpack/itransh.cpp @@ -60,7 +60,7 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision) if ( rat_gt( *px, pt_eight_five, precision) || rat_lt( *px, neg_pt_eight_five, precision) ) { PRAT ptmp = nullptr; - DUPRAT(ptmp,(*px)); + DUPRAT(ptmp,(*px)); mulrat(&ptmp, *px, precision); addrat(&ptmp, rat_one, precision); rootrat(&ptmp, rat_two, radix, precision); @@ -73,14 +73,14 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision) CREATETAYLOR(); xx->pp->sign *= -1; - DUPRAT(pret,(*px)); + DUPRAT(pret,(*px)); DUPRAT(thisterm,(*px)); DUPNUM(n2,num_one); do { - NEXTTERM(xx,MULNUM(n2) MULNUM(n2) + NEXTTERM(xx,MULNUM(n2) MULNUM(n2) INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); } while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); @@ -99,7 +99,7 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision) // hyperbolic cose of // RETURN: acosh of x in PRAT form. // -// EXPLANATION: This uses +// EXPLANATION: This uses // // acosh(x)=ln(x+sqrt(x^2-1)) // @@ -117,7 +117,7 @@ void acoshrat( PRAT *px, uint32_t radix, int32_t precision) else { PRAT ptmp = nullptr; - DUPRAT(ptmp,(*px)); + DUPRAT(ptmp,(*px)); mulrat(&ptmp, *px, precision); subrat(&ptmp, rat_one, precision); rootrat(&ptmp,rat_two, radix, precision); @@ -148,7 +148,7 @@ void atanhrat( PRAT *px, int32_t precision) { PRAT ptmp = nullptr; - DUPRAT(ptmp,(*px)); + DUPRAT(ptmp,(*px)); subrat(&ptmp, rat_one, precision); addrat(px, rat_one, precision); divrat(px, ptmp, precision); diff --git a/src/CalcManager/Ratpack/logic.cpp b/src/CalcManager/Ratpack/logic.cpp index ed598eca..c7f8a3a3 100644 --- a/src/CalcManager/Ratpack/logic.cpp +++ b/src/CalcManager/Ratpack/logic.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. //--------------------------------------------------------------------------- @@ -16,13 +16,13 @@ #include "pch.h" #include "ratpak.h" - +using namespace std; void lshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) { PRAT pwr= nullptr; - long intb; + int32_t intb; intrat(pa, radix, precision); if ( !zernum( (*pa)->pp ) ) @@ -33,9 +33,9 @@ void lshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) // Don't attempt lsh of anything big throw( CALC_E_DOMAIN ); } - intb = rattolong(b, radix, precision); + intb = rattoi32(b, radix, precision); DUPRAT(pwr,rat_two); - ratpowlong(&pwr, intb, precision); + ratpowi32(&pwr, intb, precision); mulrat(pa, pwr, precision); destroyrat(pwr); } @@ -45,20 +45,20 @@ void rshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) { PRAT pwr= nullptr; - long intb; + int32_t intb; intrat(pa, radix, precision); if ( !zernum( (*pa)->pp ) ) - { + { // If input is zero we're done. if ( rat_lt( b, rat_min_exp, precision) ) { // Don't attempt rsh of anything big and negative. throw( CALC_E_DOMAIN ); } - intb = rattolong(b, radix, precision); + intb = rattoi32(b, radix, precision); DUPRAT(pwr,rat_two); - ratpowlong(&pwr, intb, precision); + ratpowi32(&pwr, intb, precision); divrat(pa, pwr, precision); destroyrat(pwr); } @@ -138,8 +138,8 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func ) MANTTYPE *pcha; MANTTYPE *pchb; MANTTYPE *pchc; - long cdigits; - long mexp; + int32_t cdigits; + int32_t mexp; MANTTYPE da; MANTTYPE db; @@ -155,11 +155,11 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func ) pchc = c->mant; for ( ;cdigits > 0; cdigits--, mexp++ ) { - da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > - (c->cdigit - a->cdigit) ) ) ? + da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > + (c->cdigit - a->cdigit) ) ) ? *pcha++ : 0 ); - db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > - (c->cdigit - b->cdigit) ) ) ? + db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > + (c->cdigit - b->cdigit) ) ) ? *pchb++ : 0 ); switch ( func ) { @@ -205,15 +205,14 @@ void modrat( PRAT *pa, PRAT b ) throw CALC_E_INDEFINITE; } DUPRAT(tmp,b); - + mulnumx( &((*pa)->pp), tmp->pq ); mulnumx( &(tmp->pp), (*pa)->pq ); remnum( &((*pa)->pp), tmp->pp, BASEX ); mulnumx( &((*pa)->pq), tmp->pq ); - - //Get *pa back in the integer over integer form. + + // Get *pa back in the integer over integer form. RENORMALIZE(*pa); destroyrat( tmp ); } - diff --git a/src/CalcManager/Ratpack/num.cpp b/src/CalcManager/Ratpack/num.cpp index 76fa91a1..2bfa6b89 100644 --- a/src/CalcManager/Ratpack/num.cpp +++ b/src/CalcManager/Ratpack/num.cpp @@ -2,20 +2,20 @@ // Licensed under the MIT License. //----------------------------------------------------------------------------- -// Package Title ratpak -// File num.c -// Copyright (C) 1995-97 Microsoft -// Date 01-16-95 -// -// -// Description -// -// Contains number routines for add, mul, div, rem and other support -// and longs. -// -// Special Information -// -// +// Package Title ratpak +// File num.c +// Copyright (C) 1995-97 Microsoft +// Date 01-16-95 +// +// +// Description +// +// Contains number routines for add, mul, div, rem and other support +// and longs. +// +// Special Information +// +// //----------------------------------------------------------------------------- #include "pch.h" #include "ratpak.h" @@ -66,18 +66,18 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) MANTTYPE *pcha; // pcha is a pointer to the mantissa of a. MANTTYPE *pchb; // pchb is a pointer to the mantissa of b. MANTTYPE *pchc; // pchc is a pointer to the mantissa of c. - long cdigits; // cdigits is the max count of the digits results + int32_t cdigits; // cdigits is the max count of the digits results // used as a counter. - long mexp; // mexp is the exponent of the result. + int32_t mexp; // mexp is the exponent of the result. MANTTYPE da; // da is a single 'digit' after possible padding. MANTTYPE db; // db is a single 'digit' after possible padding. MANTTYPE cy=0; // cy is the value of a carry after adding two 'digits' - long fcompla = 0; // fcompla is a flag to signal a is negative. - long fcomplb = 0; // fcomplb is a flag to signal b is negative. + int32_t fcompla = 0; // fcompla is a flag to signal a is negative. + int32_t fcomplb = 0; // fcomplb is a flag to signal b is negative. a=*pa; - - + + // Calculate the overlap of the numbers after alignment, this includes // necessary padding 0's cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) - @@ -90,7 +90,7 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) pcha = a->mant; pchb = b->mant; pchc = c->mant; - + // Figure out the sign of the numbers if ( a->sign != b->sign ) { @@ -98,21 +98,21 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) fcompla = ( a->sign == -1 ); fcomplb = ( b->sign == -1 ); } - + // Loop over all the digits, real and 0 padded. Here we know a and b are - // aligned + // aligned for ( ;cdigits > 0; cdigits--, mexp++ ) { - + // Get digit from a, taking padding into account. - da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > - (c->cdigit - a->cdigit) ) ) ? + da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > + (c->cdigit - a->cdigit) ) ) ? *pcha++ : 0 ); // Get digit from b, taking padding into account. - db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > - (c->cdigit - b->cdigit) ) ) ? + db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > + (c->cdigit - b->cdigit) ) ) ? *pchb++ : 0 ); - + // Handle complementing for a and b digit. Might be a better way, but // haven't found it yet. if ( fcompla ) @@ -123,20 +123,20 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) { db = (MANTTYPE)(radix) - 1 - db; } - + // Update carry as necessary cy = da + db + cy; *pchc++ = (MANTTYPE)(cy % (MANTTYPE)radix); cy /= (MANTTYPE)radix; } - + // Handle carry from last sum as extra digit if ( cy && !(fcompla || fcomplb) ) { *pchc++ = cy; c->cdigit++; } - + // Compute sign of result if ( !(fcompla || fcomplb) ) { @@ -150,14 +150,14 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) } else { - // In this particular case an overflow or underflow has occurred - // and all the digits need to be complemented, at one time an - // attempt to handle this above was made, it turned out to be much + // In this particular case an overflow or underflow has occurred + // and all the digits need to be complemented, at one time an + // attempt to handle this above was made, it turned out to be much // slower on average. c->sign = -1; cy = 1; for ( ( cdigits = c->cdigit ), (pchc = c->mant); - cdigits > 0; + cdigits > 0; cdigits-- ) { cy = (MANTTYPE)radix - (MANTTYPE)1 - *pchc + cy; @@ -166,7 +166,7 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) } } } - + // Remove leading zeros, remember digits are in order of // increasing significance. i.e. 100 would be 0,0,1 while ( c->cdigit > 1 && *(--pchc) == 0 ) @@ -205,7 +205,7 @@ void __inline mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix) } else { // if pa is one and b isn't just copy b, and adjust the sign. - long sign = (*pa)->sign; + int32_t sign = (*pa)->sign; DUPNUM(*pa,b); (*pa)->sign *= sign; } @@ -226,14 +226,14 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix) MANTTYPE *pchc; // pchc is a pointer to the mantissa of c. MANTTYPE *pchcoffset; // pchcoffset, is the anchor location of the next // single digit multiply partial result. - long iadigit = 0; // Index of digit being used in the first number. - long ibdigit = 0; // Index of digit being used in the second number. + int32_t iadigit = 0; // Index of digit being used in the first number. + int32_t ibdigit = 0; // Index of digit being used in the second number. MANTTYPE da = 0; // da is the digit from the fist number. TWO_MANTTYPE cy = 0; // cy is the carry resulting from the addition of // a multiplied row into the result. - TWO_MANTTYPE mcy = 0; // mcy is the resultant from a single + TWO_MANTTYPE mcy = 0; // mcy is the resultant from a single // multiply, AND the carry of that multiply. - long icdigit = 0; // Index of digit being calculated in final result. + int32_t icdigit = 0; // Index of digit being calculated in final result. a=*pa; ibdigit = a->cdigit + b->cdigit - 1; @@ -249,8 +249,8 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix) { da = *pcha++; pchb = b->mant; - - // Shift pchc, and pchcoffset, one for each digit + + // Shift pchc, and pchcoffset, one for each digit pchc = pchcoffset++; for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- ) @@ -268,23 +268,23 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix) // If result is nonzero, or while result of carry is nonzero... while ( mcy || cy ) { - + // update carry from addition(s) and multiply. cy += (TWO_MANTTYPE)pchc[icdigit]+(mcy%(TWO_MANTTYPE)radix); - - // update result digit from + + // update result digit from pchc[icdigit++]=(MANTTYPE)(cy%(TWO_MANTTYPE)radix); - + // update carries from mcy /= (TWO_MANTTYPE)radix; cy /= (TWO_MANTTYPE)radix; } - + pchb++; pchc++; } } - + // prevent different kinds of zeros, by stripping leading duplicate zeros. // digits are in order of increasing significance. while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) @@ -317,7 +317,7 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix) { PNUMBER tmp = nullptr; // tmp is the working remainder. PNUMBER lasttmp = nullptr; // lasttmp is the last remainder which worked. - + // Once *pa is less than b, *pa is the remainder. while ( !lessnum( *pa, b ) ) { @@ -334,22 +334,22 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix) } destroynum( lasttmp ); - lasttmp=longtonum( 0, radix); + lasttmp=i32tonum( 0, radix); - while ( lessnum( tmp, *pa ) ) + while ( lessnum( tmp, *pa ) ) { DUPNUM( lasttmp, tmp ); addnum( &tmp, tmp, radix); } if ( lessnum( *pa, tmp ) ) - { + { // too far, back up... destroynum( tmp ); tmp=lasttmp; lasttmp= nullptr; } - + // Subtract the working remainder from the remainder holder. tmp->sign = -1*(*pa)->sign; addnum( pa, tmp, radix); @@ -357,7 +357,7 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix) destroynum( tmp ); destroynum( lasttmp ); - } + } } @@ -381,7 +381,7 @@ void __inline divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) { if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 ) - { + { // b is not one _divnum( pa, b, radix, precision); } @@ -394,7 +394,7 @@ void __inline divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) { PNUMBER a = *pa; - long thismax = precision + 2; + int32_t thismax = precision + 2; if (thismax < a->cdigit) { thismax = a->cdigit; @@ -418,10 +418,10 @@ void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) tmp->sign = a->sign; rem->exp = b->cdigit + b->exp - rem->cdigit; - // Build a table of multiplications of the divisor, this is quicker for + // Build a table of multiplications of the divisor, this is quicker for // more than radix 'digits' - list numberList{ longtonum(0L, radix) }; - for (unsigned long i = 1; i < radix; i++) + list numberList{ i32tonum(0L, radix) }; + for (uint32_t i = 1; i < radix; i++) { PNUMBER newValue = nullptr; DUPNUM(newValue, numberList.front()); @@ -431,8 +431,8 @@ void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) } destroynum(tmp); - long digit; - long cdigits = 0; + int32_t digit; + int32_t cdigits = 0; while (cdigits++ < thismax && !zernum(rem)) { digit = radix - 1; @@ -505,11 +505,11 @@ void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) bool equnum( PNUMBER a, PNUMBER b ) { - long diff; + int32_t diff; MANTTYPE *pa; MANTTYPE *pb; - long cdigits; - long ccdigits; + int32_t cdigits; + int32_t ccdigits; MANTTYPE da; MANTTYPE db; @@ -535,21 +535,21 @@ bool equnum( PNUMBER a, PNUMBER b ) pb += b->cdigit - 1; cdigits = max( a->cdigit, b->cdigit ); ccdigits = cdigits; - + // Loop over all digits until we run out of digits or there is a // difference in the digits. for ( ;cdigits > 0; cdigits-- ) { - da = ( (cdigits > (ccdigits - a->cdigit) ) ? + da = ( (cdigits > (ccdigits - a->cdigit) ) ? *pa-- : 0 ); - db = ( (cdigits > (ccdigits - b->cdigit) ) ? + db = ( (cdigits > (ccdigits - b->cdigit) ) ? *pb-- : 0 ); if ( da != db ) { return false; } } - + // In this case, they are equal. return true; } @@ -573,11 +573,11 @@ bool equnum( PNUMBER a, PNUMBER b ) bool lessnum( PNUMBER a, PNUMBER b ) { - long diff; + int32_t diff; MANTTYPE *pa; MANTTYPE *pb; - long cdigits; - long ccdigits; + int32_t cdigits; + int32_t ccdigits; MANTTYPE da; MANTTYPE db; @@ -604,9 +604,9 @@ bool lessnum( PNUMBER a, PNUMBER b ) ccdigits = cdigits; for ( ;cdigits > 0; cdigits-- ) { - da = ( (cdigits > (ccdigits - a->cdigit) ) ? + da = ( (cdigits > (ccdigits - a->cdigit) ) ? *pa-- : 0 ); - db = ( (cdigits > (ccdigits - b->cdigit) ) ? + db = ( (cdigits > (ccdigits - b->cdigit) ) ? *pb-- : 0 ); diff = da-db; if ( diff ) @@ -635,12 +635,12 @@ bool lessnum( PNUMBER a, PNUMBER b ) bool zernum( PNUMBER a ) { - long length; + int32_t length; MANTTYPE *pcha; length = a->cdigit; pcha = a->mant; - - // loop over all the digits until you find a nonzero or until you run + + // loop over all the digits until you find a nonzero or until you run // out of digits while ( length-- > 0 ) { diff --git a/src/CalcManager/Ratpack/rat.cpp b/src/CalcManager/Ratpack/rat.cpp index 2d71dc24..e101458a 100644 --- a/src/CalcManager/Ratpack/rat.cpp +++ b/src/CalcManager/Ratpack/rat.cpp @@ -56,7 +56,7 @@ void gcdrat( PRAT *pa, int32_t precision) destroynum( pgcd ); *pa=a; - RENORMALIZE(*pa); + RENORMALIZE(*pa); } //----------------------------------------------------------------------------- @@ -82,7 +82,7 @@ void fracrat( PRAT *pa , uint32_t radix, int32_t precision) remnum( &((*pa)->pp), (*pa)->pq, BASEX ); - //Get *pa back in the integer over integer form. + // Get *pa back in the integer over integer form. RENORMALIZE(*pa); } @@ -100,7 +100,7 @@ void fracrat( PRAT *pa , uint32_t radix, int32_t precision) //----------------------------------------------------------------------------- void mulrat( PRAT *pa, PRAT b, int32_t precision) - + { // Only do the multiply if it isn't zero. if ( !zernum( (*pa)->pp ) ) @@ -170,7 +170,7 @@ void divrat( PRAT *pa, PRAT b, int32_t precision) #ifdef DIVGCD gcdrat( pa ); -#endif +#endif } @@ -215,13 +215,13 @@ void addrat( PRAT *pa, PRAT b, int32_t precision) if ( equnum( (*pa)->pq, b->pq ) ) { - // Very special case, q's match., + // Very special case, q's match., // make sure signs are involved in the calculation - // we have to do this since the optimization here is only + // we have to do this since the optimization here is only // working with the top half of the rationals. - (*pa)->pp->sign *= (*pa)->pq->sign; + (*pa)->pp->sign *= (*pa)->pq->sign; (*pa)->pq->sign = 1; - b->pp->sign *= b->pq->sign; + b->pp->sign *= b->pq->sign; b->pq->sign = 1; addnum( &((*pa)->pp), b->pp, BASEX ); } @@ -236,15 +236,15 @@ void addrat( PRAT *pa, PRAT b, int32_t precision) destroynum( (*pa)->pq ); (*pa)->pq = bot; trimit(pa, precision); - + // Get rid of negative zeros here. - (*pa)->pp->sign *= (*pa)->pq->sign; + (*pa)->pp->sign *= (*pa)->pq->sign; (*pa)->pq->sign = 1; } #ifdef ADDGCD gcdrat( pa ); -#endif +#endif } @@ -264,7 +264,7 @@ void addrat( PRAT *pa, PRAT b, int32_t precision) //----------------------------------------------------------------------------- void rootrat( PRAT *py, PRAT n, uint32_t radix, int32_t precision) -{ +{ // Initialize 1/n PRAT oneovern= nullptr; DUPRAT(oneovern,rat_one); diff --git a/src/CalcManager/Ratpack/ratconst.h b/src/CalcManager/Ratpack/ratconst.h index d208b33c..7367cd36 100644 --- a/src/CalcManager/Ratpack/ratconst.h +++ b/src/CalcManager/Ratpack/ratconst.h @@ -1,480 +1,482 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// Autogenerated by _dumprawrat in support.c -NUMBER init_num_one= { +#pragma once + +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_num_one= { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_num_two= { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_num_two= { 1, 1, 0, { 2,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_num_five= { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_num_five= { 1, 1, 0, { 5,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_num_six= { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_num_six= { 1, 1, 0, { 6,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_num_ten= { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_num_ten= { 1, 1, 0, { 10,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_smallest = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_smallest = { 1, 1, 0, { 1,} }; -NUMBER init_q_rat_smallest = { +inline const NUMBER init_q_rat_smallest = { 1, 4, 0, { 0, 190439170, 901055854, 10097,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_negsmallest = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_negsmallest = { -1, 1, 0, { 1,} }; -NUMBER init_q_rat_negsmallest = { +inline const NUMBER init_q_rat_negsmallest = { 1, 4, 0, { 0, 190439170, 901055854, 10097,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_pt_eight_five = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_pt_eight_five = { 1, 1, 0, { 85,} }; -NUMBER init_q_pt_eight_five = { +inline const NUMBER init_q_pt_eight_five = { 1, 1, 0, { 100,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_six = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_six = { 1, 1, 0, { 6,} }; -NUMBER init_q_rat_six = { +inline const NUMBER init_q_rat_six = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_two = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_two = { 1, 1, 0, { 2,} }; -NUMBER init_q_rat_two = { +inline const NUMBER init_q_rat_two = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_zero = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_zero = { 1, 1, 0, { 0,} }; -NUMBER init_q_rat_zero = { +inline const NUMBER init_q_rat_zero = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_one = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_one = { 1, 1, 0, { 1,} }; -NUMBER init_q_rat_one = { +inline const NUMBER init_q_rat_one = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_neg_one = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_neg_one = { -1, 1, 0, { 1,} }; -NUMBER init_q_rat_neg_one = { +inline const NUMBER init_q_rat_neg_one = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_half = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_half = { 1, 1, 0, { 1,} }; -NUMBER init_q_rat_half = { +inline const NUMBER init_q_rat_half = { 1, 1, 0, { 2,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_ten = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_ten = { 1, 1, 0, { 10,} }; -NUMBER init_q_rat_ten = { +inline const NUMBER init_q_rat_ten = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_pi = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_pi = { 1, 6, 0, { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} }; -NUMBER init_q_pi = { +inline const NUMBER init_q_pi = { 1, 6, 0, { 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_two_pi = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_two_pi = { 1, 6, 0, { 251055792, 567796700, 1773504224, 1198217877, 428852897, 17,} }; -NUMBER init_q_two_pi = { +inline const NUMBER init_q_two_pi = { 1, 6, 0, { 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_pi_over_two = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_pi_over_two = { 1, 6, 0, { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} }; -NUMBER init_q_pi_over_two = { +inline const NUMBER init_q_pi_over_two = { 1, 6, 0, { 429277156, 92748659, 1573365737, 1740753005, 1019699561, 5,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_one_pt_five_pi = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_one_pt_five_pi = { 1, 6, 0, { 1241201312, 270061909, 1051574664, 1924965045, 1340320627, 70,} }; -NUMBER init_q_one_pt_five_pi = { +inline const NUMBER init_q_one_pt_five_pi = { 1, 6, 0, { 1579671539, 1837970263, 1067644340, 523549916, 2119366659, 14,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_e_to_one_half = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_e_to_one_half = { 1, 6, 0, { 256945612, 216219427, 223516738, 477442596, 581063757, 23,} }; -NUMBER init_q_e_to_one_half = { +inline const NUMBER init_q_e_to_one_half = { 1, 6, 0, { 1536828363, 698484484, 1127331835, 224219346, 245499408, 14,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_exp = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_exp = { 1, 6, 0, { 943665199, 1606559160, 1094967530, 1759391384, 1671799163, 1123581,} }; -NUMBER init_q_rat_exp = { +inline const NUMBER init_q_rat_exp = { 1, 6, 0, { 879242208, 2022880100, 617392930, 1374929092, 1367479163, 413342,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_ln_ten = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_ln_ten = { 1, 6, 0, { 2086268922, 165794492, 1416063951, 1851428830, 1893239400, 65366841,} }; -NUMBER init_q_ln_ten = { +inline const NUMBER init_q_ln_ten = { 1, 6, 0, { 26790652, 564532679, 783998273, 216030448, 1564709968, 28388458,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_ln_two = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_ln_two = { 1, 6, 0, { 1789230241, 1057927868, 715399197, 908801241, 1411265331, 3,} }; -NUMBER init_q_ln_two = { +inline const NUMBER init_q_ln_two = { 1, 6, 0, { 1559869847, 1930657510, 1228561531, 219003871, 593099283, 5,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rad_to_deg = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rad_to_deg = { 1, 6, 0, { 2127722024, 1904928383, 2016479213, 2048947859, 1578647346, 492,} }; -NUMBER init_q_rad_to_deg = { +inline const NUMBER init_q_rad_to_deg = { 1, 6, 0, { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rad_to_grad = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rad_to_grad = { 1, 6, 0, { 2125526288, 684931327, 570267400, 129125085, 1038224725, 547,} }; -NUMBER init_q_rad_to_grad = { +inline const NUMBER init_q_rad_to_grad = { 1, 6, 0, { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_qword = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_qword = { 1, 3, 0, { 2147483647, 2147483647, 3,} }; -NUMBER init_q_rat_qword = { +inline const NUMBER init_q_rat_qword = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_dword = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_dword = { 1, 2, 0, { 2147483647, 1,} }; -NUMBER init_q_rat_dword = { +inline const NUMBER init_q_rat_dword = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_max_long = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_max_i32 = { 1, 1, 0, { 2147483647,} }; -NUMBER init_q_rat_max_long = { +inline const NUMBER init_q_rat_max_i32 = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_min_long = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_min_i32 = { -1, 2, 0, { 0, 1,} }; -NUMBER init_q_rat_min_long = { +inline const NUMBER init_q_rat_min_i32 = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_word = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_word = { 1, 1, 0, { 65535,} }; -NUMBER init_q_rat_word = { +inline const NUMBER init_q_rat_word = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_byte = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_byte = { 1, 1, 0, { 255,} }; -NUMBER init_q_rat_byte = { +inline const NUMBER init_q_rat_byte = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_400 = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_400 = { 1, 1, 0, { 400,} }; -NUMBER init_q_rat_400 = { +inline const NUMBER init_q_rat_400 = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_360 = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_360 = { 1, 1, 0, { 360,} }; -NUMBER init_q_rat_360 = { +inline const NUMBER init_q_rat_360 = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_200 = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_200 = { 1, 1, 0, { 200,} }; -NUMBER init_q_rat_200 = { +inline const NUMBER init_q_rat_200 = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_180 = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_180 = { 1, 1, 0, { 180,} }; -NUMBER init_q_rat_180 = { +inline const NUMBER init_q_rat_180 = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_max_exp = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_max_exp = { 1, 1, 0, { 100000,} }; -NUMBER init_q_rat_max_exp = { +inline const NUMBER init_q_rat_max_exp = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_min_exp = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_min_exp = { -1, 1, 0, { 100000,} }; -NUMBER init_q_rat_min_exp = { +inline const NUMBER init_q_rat_min_exp = { 1, 1, 0, { 1,} }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_max_fact = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_max_fact = { 1, 1, 0, { 3249, } }; -NUMBER init_q_rat_max_fact = { +inline const NUMBER init_q_rat_max_fact = { 1, 1, 0, { 1, } }; -// Autogenerated by _dumprawrat in support.c -NUMBER init_p_rat_min_fact = { +// Autogenerated by _dumprawrat in support.cpp +inline const NUMBER init_p_rat_min_fact = { -1, 1, 0, { 1000, } }; -NUMBER init_q_rat_min_fact = { +inline const NUMBER init_q_rat_min_fact = { 1, 1, 0, diff --git a/src/CalcManager/Ratpack/ratpak.h b/src/CalcManager/Ratpack/ratpak.h index 693380bc..75ac28de 100644 --- a/src/CalcManager/Ratpack/ratpak.h +++ b/src/CalcManager/Ratpack/ratpak.h @@ -24,8 +24,8 @@ static constexpr uint32_t BASEX = 0x80000000; // Internal radix used in calculat // this to 2^32 after solving scaling problems with // overflow detection esp. in mul -typedef unsigned long MANTTYPE; -typedef unsigned __int64 TWO_MANTTYPE; +typedef uint32_t MANTTYPE; +typedef uint64_t TWO_MANTTYPE; enum eNUMOBJ_FMT { FMT_FLOAT, // returns floating point, or exponential if number is too big @@ -54,10 +54,10 @@ typedef enum eANGLE_TYPE ANGLE_TYPE; #pragma warning(disable:4200) // nonstandard extension used : zero-sized array in struct/union typedef struct _number { - long sign; // The sign of the mantissa, +1, or -1 - long cdigit; // The number of digits, or what passes for digits in the + int32_t sign; // The sign of the mantissa, +1, or -1 + int32_t cdigit; // The number of digits, or what passes for digits in the // radix being used. - long exp; // The offset of digits from the radix point + int32_t exp; // The offset of digits from the radix point // (decimal point in radix 10) MANTTYPE mant[]; // This is actually allocated as a continuation of the @@ -127,8 +127,8 @@ extern PRAT rat_max_exp; extern PRAT rat_min_exp; extern PRAT rat_max_fact; extern PRAT rat_min_fact; -extern PRAT rat_max_long; -extern PRAT rat_min_long; +extern PRAT rat_max_i32; +extern PRAT rat_min_i32; // DUPNUM Duplicates a number taking care of allocation and internals #define DUPNUM(a,b) destroynum(a);createnum( a, (b)->cdigit );_dupnum(a, b); @@ -208,7 +208,7 @@ _destroynum(x),(x)=nullptr // TRIMNUM ASSUMES the number is in radix form NOT INTERNAL BASEX!!! #define TRIMNUM(x, precision) if ( !g_ftrueinfinite ) { \ - long trim = (x)->cdigit - precision-g_ratio;\ + int32_t trim = (x)->cdigit - precision-g_ratio;\ if ( trim > 1 ) \ { \ memmove( (x)->mant, &((x)->mant[trim]), sizeof(MANTTYPE)*((x)->cdigit-trim) ); \ @@ -218,14 +218,14 @@ memmove( (x)->mant, &((x)->mant[trim]), sizeof(MANTTYPE)*((x)->cdigit-trim) ); \ } // TRIMTOP ASSUMES the number is in INTERNAL BASEX!!! #define TRIMTOP(x, precision) if ( !g_ftrueinfinite ) { \ - long trim = (x)->pp->cdigit - (precision/g_ratio) - 2;\ + int32_t trim = (x)->pp->cdigit - (precision/g_ratio) - 2;\ if ( trim > 1 ) \ { \ memmove( (x)->pp->mant, &((x)->pp->mant[trim]), sizeof(MANTTYPE)*((x)->pp->cdigit-trim) ); \ (x)->pp->cdigit -= trim; \ (x)->pp->exp += trim; \ } \ - trim = min((x)->pp->exp,(x)->pq->exp);\ + trim = std::min((x)->pp->exp,(x)->pq->exp);\ (x)->pp->exp -= trim;\ (x)->pq->exp -= trim;\ } @@ -246,8 +246,8 @@ memmove( (x)->pp->mant, &((x)->pp->mant[trim]), sizeof(MANTTYPE)*((x)->pp->cdigi DUPRAT(xx,*px); \ mulrat(&xx,*px, precision); \ createrat(pret); \ - pret->pp=longtonum( 0L, BASEX ); \ - pret->pq=longtonum( 0L, BASEX ); + pret->pp=i32tonum( 0L, BASEX ); \ + pret->pq=i32tonum( 0L, BASEX ); #define DESTROYTAYLOR() destroynum( n2 ); \ destroyrat( xx );\ @@ -294,7 +294,7 @@ extern bool g_ftrueinfinite; // set to true to allow infinite precision // don't use unless you know what you are doing // used to help decide when to stop calculating. -extern long g_ratio; // Internally calculated ratio of internal radix +extern int32_t g_ratio; // Internally calculated ratio of internal radix //----------------------------------------------------------------------------- // @@ -321,10 +321,10 @@ extern PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision); // flattens a PRAT by converting it to a PNUMBER and back to a PRAT extern void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision); -extern long numtolong(_In_ PNUMBER pnum, uint32_t radix ); -extern long rattolong(_In_ PRAT prat, uint32_t radix, int32_t precision); -ULONGLONG rattoUlonglong(_In_ PRAT prat, uint32_t radix, int32_t precision); -extern PNUMBER _createnum(_In_ ULONG size ); // returns an empty number structure with size digits +extern int32_t numtoi32(_In_ PNUMBER pnum, uint32_t radix ); +extern int32_t rattoi32(_In_ PRAT prat, uint32_t radix, int32_t precision); +uint64_t rattoUi64(_In_ PRAT prat, uint32_t radix, int32_t precision); +extern PNUMBER _createnum(_In_ uint32_t size ); // returns an empty number structure with size digits extern PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision); extern PNUMBER gcd(_In_ PNUMBER a, _In_ PNUMBER b ); extern PNUMBER StringToNumber(std::wstring_view numberString, uint32_t radix, int32_t precision); // takes a text representation of a number and returns a number. @@ -332,10 +332,10 @@ extern PNUMBER StringToNumber(std::wstring_view numberString, uint32_t radix, in // takes a text representation of a number as a mantissa with sign and an exponent with sign. extern PRAT StringToRat(bool mantissaIsNegative, std::wstring_view mantissa, bool exponentIsNegative, std::wstring_view exponent, uint32_t radix, int32_t precision); -extern PNUMBER longfactnum(long inlong, uint32_t radix); -extern PNUMBER longprodnum(long start, long stop, uint32_t radix); -extern PNUMBER longtonum(long inlong, uint32_t radix); -extern PNUMBER Ulongtonum(unsigned long inlong, uint32_t radix); +extern PNUMBER i32factnum(int32_t ini32, uint32_t radix); +extern PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix); +extern PNUMBER i32tonum(int32_t ini32, uint32_t radix); +extern PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix); extern PNUMBER numtonRadixx(PNUMBER a, uint32_t radix); // creates a empty/undefined rational representation (p/q) @@ -393,8 +393,8 @@ extern void log10rat( _Inout_ PRAT *px, int32_t precision); // returns a new rat structure with the natural log of x->p/x->q extern void lograt( _Inout_ PRAT *px, int32_t precision); -extern PRAT longtorat( long inlong ); -extern PRAT Ulongtorat( unsigned long inulong ); +extern PRAT i32torat( int32_t ini32 ); +extern PRAT Ui32torat( uint32_t inui32 ); extern PRAT numtorat( _In_ PNUMBER pin, uint32_t radix); extern void sinhrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); @@ -411,7 +411,7 @@ extern void tanrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); // angle type extern void tananglerat( _Inout_ PRAT *px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision); -extern void _dupnum(_In_ PNUMBER dest, _In_ PNUMBER src); +extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src); extern void _destroynum( _In_ PNUMBER pnum ); extern void _destroyrat( _In_ PRAT prat ); @@ -429,13 +429,13 @@ extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void mulnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b ); extern void mulrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision); -extern void numpowlong( _Inout_ PNUMBER *proot, long power, uint32_t radix, int32_t precision); -extern void numpowlongx( _Inout_ PNUMBER *proot, long power ); +extern void numpowi32( _Inout_ PNUMBER *proot, int32_t power, uint32_t radix, int32_t precision); +extern void numpowi32x( _Inout_ PNUMBER *proot, int32_t power ); extern void orrat( _Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void powrat( _Inout_ PRAT *pa, _In_ PRAT b , uint32_t radix, int32_t precision); extern void powratNumeratorDenominator(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void powratcomp(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); -extern void ratpowlong( _Inout_ PRAT *proot, long power, int32_t precision); +extern void ratpowi32( _Inout_ PRAT *proot, int32_t power, int32_t precision); extern void remnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void rootrat( _Inout_ PRAT *pa, _In_ PRAT b , uint32_t radix, int32_t precision); extern void scale2pi( _Inout_ PRAT *px, uint32_t radix, int32_t precision); diff --git a/src/CalcManager/Ratpack/support.cpp b/src/CalcManager/Ratpack/support.cpp index d747b4d1..ebee00c6 100644 --- a/src/CalcManager/Ratpack/support.cpp +++ b/src/CalcManager/Ratpack/support.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. //---------------------------------------------------------------------------- @@ -31,8 +31,8 @@ static int cbitsofprecision = 0; #define READRAWNUM(v) #define DUMPRAWRAT(v) _dumprawrat(#v,v, wcout) #define DUMPRAWNUM(v) fprintf( stderr, \ -"// Autogenerated by _dumprawrat in support.c\n" ); \ - fprintf( stderr, "NUMBER init_" #v "= {\n" ); \ +"// Autogenerated by _dumprawrat in support.cpp\n" ); \ + fprintf( stderr, "inline const NUMBER init_" #v "= {\n" ); \ _dumprawnum(v, wcout); \ fprintf( stderr, "};\n" ) @@ -45,8 +45,8 @@ static int cbitsofprecision = 0; DUPNUM((v)->pq,(&(init_q_##v))); #define READRAWNUM(v) DUPNUM(v,(&(init_##v))) -#define INIT_AND_DUMP_RAW_NUM_IF_NULL(r, v) if (r == nullptr) { r = longtonum(v, BASEX); DUMPRAWNUM(v); } -#define INIT_AND_DUMP_RAW_RAT_IF_NULL(r, v) if (r == nullptr) { r = longtorat(v); DUMPRAWRAT(v); } +#define INIT_AND_DUMP_RAW_NUM_IF_NULL(r, v) if (r == nullptr) { r = i32tonum(v, BASEX); DUMPRAWNUM(v); } +#define INIT_AND_DUMP_RAW_RAT_IF_NULL(r, v) if (r == nullptr) { r = i32torat(v); DUMPRAWRAT(v); } static constexpr int RATIO_FOR_DECIMAL = 9; static constexpr int DECIMAL = 10; @@ -58,7 +58,7 @@ static int cbitsofprecision = RATIO_FOR_DECIMAL * DECIMAL * CALC_DECIMAL_DIGITS_ #endif -bool g_ftrueinfinite = false; // Set to true if you don't want +bool g_ftrueinfinite = false; // Set to true if you don't want // chopping internally // precision used internally @@ -87,7 +87,7 @@ PRAT rat_exp= nullptr; PRAT rad_to_deg= nullptr; PRAT rad_to_grad= nullptr; PRAT rat_qword= nullptr; -PRAT rat_dword= nullptr; // unsigned max ulong +PRAT rat_dword= nullptr; // unsigned max ui32 PRAT rat_word= nullptr; PRAT rat_byte= nullptr; PRAT rat_360= nullptr; @@ -101,8 +101,8 @@ PRAT rat_max_exp= nullptr; PRAT rat_min_exp= nullptr; PRAT rat_max_fact = nullptr; PRAT rat_min_fact = nullptr; -PRAT rat_min_long= nullptr; // min signed long -PRAT rat_max_long= nullptr; // max signed long +PRAT rat_min_i32= nullptr; // min signed i32 +PRAT rat_max_i32= nullptr; // max signed i32 //---------------------------------------------------------------------------- // @@ -119,8 +119,8 @@ PRAT rat_max_long= nullptr; // max signed long void ChangeConstants(uint32_t radix, int32_t precision) { - // ratio is set to the number of digits in the current radix, you can get - // in the internal BASEX radix, this is important for length calculations + // ratio is set to the number of digits in the current radix, you can get + // in the internal BASEX radix, this is important for length calculations // in translating from radix to BASEX and back. uint64_t limit = static_cast(BASEX) / static_cast(radix); @@ -132,7 +132,7 @@ void ChangeConstants(uint32_t radix, int32_t precision) g_ratio += !g_ratio; destroyrat(rat_nRadix); - rat_nRadix=longtorat( radix ); + rat_nRadix=i32torat( radix ); // Check to see what we have to recalculate and what we don't if (cbitsofprecision < (g_ratio * static_cast(radix) * precision)) @@ -166,7 +166,7 @@ void ChangeConstants(uint32_t radix, int32_t precision) INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_min_fact, -1000); DUPRAT(rat_smallest, rat_nRadix); - ratpowlong(&rat_smallest, -precision, precision); + ratpowi32(&rat_smallest, -precision, precision); DUPRAT(rat_negsmallest, rat_smallest); rat_negsmallest->pp->sign = -1; DUMPRAWRAT(rat_smallest); @@ -183,29 +183,29 @@ void ChangeConstants(uint32_t radix, int32_t precision) if (pt_eight_five == nullptr) { createrat(pt_eight_five); - pt_eight_five->pp = longtonum(85L, BASEX); - pt_eight_five->pq = longtonum(100L, BASEX); + pt_eight_five->pp = i32tonum(85L, BASEX); + pt_eight_five->pq = i32tonum(100L, BASEX); DUMPRAWRAT(pt_eight_five); } DUPRAT(rat_qword, rat_two); - numpowlong(&(rat_qword->pp), 64, BASEX, precision); + numpowi32(&(rat_qword->pp), 64, BASEX, precision); subrat(&rat_qword, rat_one, precision); DUMPRAWRAT(rat_qword); DUPRAT(rat_dword, rat_two); - numpowlong(&(rat_dword->pp), 32, BASEX, precision); + numpowi32(&(rat_dword->pp), 32, BASEX, precision); subrat(&rat_dword, rat_one, precision); DUMPRAWRAT(rat_dword); - DUPRAT(rat_max_long, rat_two); - numpowlong(&(rat_max_long->pp), 31, BASEX, precision); - DUPRAT(rat_min_long, rat_max_long); - subrat(&rat_max_long, rat_one, precision); // rat_max_long = 2^31 -1 - DUMPRAWRAT(rat_max_long); + DUPRAT(rat_max_i32, rat_two); + numpowi32(&(rat_max_i32->pp), 31, BASEX, precision); + DUPRAT(rat_min_i32, rat_max_i32); + subrat(&rat_max_i32, rat_one, precision); // rat_max_i32 = 2^31 -1 + DUMPRAWRAT(rat_max_i32); - rat_min_long->pp->sign *= -1; // rat_min_long = -2^31 - DUMPRAWRAT(rat_min_long); + rat_min_i32->pp->sign *= -1; // rat_min_i32 = -2^31 + DUMPRAWRAT(rat_min_i32); DUPRAT(rat_min_exp, rat_max_exp); rat_min_exp->pp->sign *= -1; @@ -213,9 +213,9 @@ void ChangeConstants(uint32_t radix, int32_t precision) cbitsofprecision = g_ratio * radix * precision; - // Apparently when dividing 180 by pi, another (internal) digit of + // Apparently when dividing 180 by pi, another (internal) digit of // precision is needed. - long extraPrecision = precision + g_ratio; + int32_t extraPrecision = precision + g_ratio; DUPRAT(pi, rat_half); asinrat(&pi, radix, extraPrecision); mulrat(&pi, rat_six, extraPrecision); @@ -253,12 +253,12 @@ void ChangeConstants(uint32_t radix, int32_t precision) destroyrat(rad_to_deg); - rad_to_deg = longtorat(180L); + rad_to_deg = i32torat(180L); divrat(&rad_to_deg, pi, extraPrecision); DUMPRAWRAT(rad_to_deg); destroyrat(rad_to_grad); - rad_to_grad = longtorat(200L); + rad_to_grad = i32torat(200L); divrat(&rad_to_grad, pi, extraPrecision); DUMPRAWRAT(rad_to_grad); } @@ -267,7 +267,7 @@ void ChangeConstants(uint32_t radix, int32_t precision) _readconstants(); DUPRAT(rat_smallest, rat_nRadix); - ratpowlong(&rat_smallest, -precision, precision); + ratpowi32(&rat_smallest, -precision, precision); DUPRAT(rat_negsmallest, rat_smallest); rat_negsmallest->pp->sign = -1; } @@ -333,7 +333,7 @@ bool rat_equ( PRAT a, PRAT b, int32_t precision) // // FUNCTION: rat_ge // -// ARGUMENTS: PRAT a, PRAT b and long precision +// ARGUMENTS: PRAT a, PRAT b and int32_t precision // // RETURN: true if a is greater than or equal to b // @@ -348,7 +348,7 @@ bool rat_ge( PRAT a, PRAT b, int32_t precision) b->pp->sign *= -1; addrat( &rattmp, b, precision); b->pp->sign *= -1; - bool bret = ( zernum( rattmp->pp ) || + bool bret = ( zernum( rattmp->pp ) || rattmp->pp->sign * rattmp->pq->sign == 1 ); destroyrat( rattmp ); return( bret ); @@ -384,7 +384,7 @@ bool rat_gt( PRAT a, PRAT b, int32_t precision) // // FUNCTION: rat_le // -// ARGUMENTS: PRAT a, PRAT b and long precision +// ARGUMENTS: PRAT a, PRAT b and int32_t precision // // RETURN: true if a is less than or equal to b // @@ -411,7 +411,7 @@ bool rat_le( PRAT a, PRAT b, int32_t precision) // // FUNCTION: rat_lt // -// ARGUMENTS: PRAT a, PRAT b and long precision +// ARGUMENTS: PRAT a, PRAT b and int32_t precision // // RETURN: true if a is less than b // @@ -472,10 +472,10 @@ void scale( PRAT *px, PRAT scalefact, uint32_t radix, int32_t precision ) { PRAT pret = nullptr; DUPRAT(pret,*px); - - // Logscale is a quick way to tell how much extra precision is needed for + + // Logscale is a quick way to tell how much extra precision is needed for // scaling by scalefact. - long logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - + int32_t logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - (pret->pq->cdigit+pret->pq->exp) ); if ( logscale > 0 ) { @@ -508,9 +508,9 @@ void scale2pi( PRAT *px, uint32_t radix, int32_t precision ) PRAT my_two_pi = nullptr; DUPRAT(pret,*px); - // Logscale is a quick way to tell how much extra precision is needed for + // Logscale is a quick way to tell how much extra precision is needed for // scaling by 2 pi. - long logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - + int32_t logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - (pret->pq->cdigit+pret->pq->exp) ); if ( logscale > 0 ) { @@ -652,27 +652,27 @@ void _readconstants( void ) READRAWRAT(rat_min_exp); READRAWRAT(rat_max_fact); READRAWRAT(rat_min_fact); - READRAWRAT(rat_min_long); - READRAWRAT(rat_max_long); + READRAWRAT(rat_min_i32); + READRAWRAT(rat_max_i32); } //--------------------------------------------------------------------------- // // FUNCTION: trimit // -// ARGUMENTS: PRAT *px, long precision +// ARGUMENTS: PRAT *px, int32_t precision // // -// DESCRIPTION: Chops off digits from rational numbers to avoid time -// explosions in calculations of functions using series. -// It can be shown that it is enough to only keep the first n digits -// of the largest of p or q in the rational p over q form, and of course -// scale the smaller by the same number of digits. This will give you -// n-1 digits of accuracy. This dramatically speeds up calculations +// DESCRIPTION: Chops off digits from rational numbers to avoid time +// explosions in calculations of functions using series. +// It can be shown that it is enough to only keep the first n digits +// of the largest of p or q in the rational p over q form, and of course +// scale the smaller by the same number of digits. This will give you +// n-1 digits of accuracy. This dramatically speeds up calculations // involving hundreds of digits or more. // The last part of this trim dealing with exponents never affects accuracy // -// RETURN: none, modifies the pointed to PRAT +// RETURN: none, modifies the pointed to PRAT // //--------------------------------------------------------------------------- @@ -680,8 +680,8 @@ void trimit( PRAT *px, int32_t precision) { if ( !g_ftrueinfinite ) - { - long trim; + { + int32_t trim; PNUMBER pp=(*px)->pp; PNUMBER pq=(*px)->pq; trim = g_ratio * (min((pp->cdigit+pp->exp),(pq->cdigit+pq->exp))-1) - precision; diff --git a/src/CalcManager/Ratpack/trans.cpp b/src/CalcManager/Ratpack/trans.cpp index ad82a94d..82897564 100644 --- a/src/CalcManager/Ratpack/trans.cpp +++ b/src/CalcManager/Ratpack/trans.cpp @@ -47,8 +47,8 @@ void scalerat( _Inout_ PRAT *pa, ANGLE_TYPE angletype, uint32_t radix, int32_t p // EXPLANATION: This uses Taylor series // // n -// ___ 2j+1 -// \ ] j X +// ___ 2j+1 +// \ ] j X // \ -1 * --------- // / (2j+1)! // /__] @@ -73,7 +73,7 @@ void _sinrat( PRAT *px, int32_t precision) { CREATETAYLOR(); - DUPRAT(pret,*px); + DUPRAT(pret,*px); DUPRAT(thisterm,*px); DUPNUM(n2,num_one); @@ -84,11 +84,11 @@ void _sinrat( PRAT *px, int32_t precision) } while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); DESTROYTAYLOR(); - - // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need + + // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need // this trick here. inbetween(px, rat_one, precision); - + // Since *px might be epsilon near zero we must set it to zero. if ( rat_le(*px, rat_smallest, precision) && rat_ge(*px, rat_negsmallest, precision) ) { @@ -166,14 +166,14 @@ void _cosrat( PRAT *px, uint32_t radix, int32_t precision) CREATETAYLOR(); destroynum(pret->pp); - destroynum(pret->pq); + destroynum(pret->pq); - pret->pp=longtonum( 1L, radix); - pret->pq=longtonum( 1L, radix); + pret->pp=i32tonum( 1L, radix); + pret->pq=i32tonum( 1L, radix); DUPRAT(thisterm,pret) - - n2=longtonum(0L, radix); + + n2=i32tonum(0L, radix); xx->pp->sign *= -1; do { @@ -181,7 +181,7 @@ void _cosrat( PRAT *px, uint32_t radix, int32_t precision) } while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); DESTROYTAYLOR(); - // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need + // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need // this trick here. inbetween(px, rat_one, precision); // Since *px might be epsilon near zero we must set it to zero. diff --git a/src/CalcManager/Ratpack/transh.cpp b/src/CalcManager/Ratpack/transh.cpp index fb756516..92a12583 100644 --- a/src/CalcManager/Ratpack/transh.cpp +++ b/src/CalcManager/Ratpack/transh.cpp @@ -80,7 +80,7 @@ void _sinhrat( PRAT *px, int32_t precision) CREATETAYLOR(); - DUPRAT(pret,*px); + DUPRAT(pret,*px); DUPRAT(thisterm,pret); DUPNUM(n2,num_one); @@ -159,12 +159,12 @@ void _coshrat( PRAT *px, uint32_t radix, int32_t precision) CREATETAYLOR(); - pret->pp=longtonum( 1L, radix); - pret->pq=longtonum( 1L, radix); + pret->pp=i32tonum( 1L, radix); + pret->pq=i32tonum( 1L, radix); DUPRAT(thisterm,pret) - n2=longtonum(0L, radix); + n2=i32tonum(0L, radix); do { NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); @@ -194,7 +194,7 @@ void coshrat( PRAT *px, uint32_t radix, int32_t precision) { _coshrat( px, radix, precision); } - // Since *px might be epsilon below 1 due to TRIMIT + // Since *px might be epsilon below 1 due to TRIMIT // we need this trick here. if ( rat_lt(*px, rat_one, precision) ) { diff --git a/src/CalcManager/UnitConverter.cpp b/src/CalcManager/UnitConverter.cpp index e30934f4..0548719a 100644 --- a/src/CalcManager/UnitConverter.cpp +++ b/src/CalcManager/UnitConverter.cpp @@ -46,7 +46,7 @@ UnitConverter::UnitConverter(_In_ const shared_ptr& dataLo { m_dataLoader = dataLoader; m_currencyDataLoader = currencyDataLoader; - //declaring the delimiter character conversion map + // declaring the delimiter character conversion map quoteConversions[L'|'] = L"{p}"; quoteConversions[L'['] = L"{lc}"; quoteConversions[L']'] = L"{rc}"; @@ -90,7 +90,7 @@ vector UnitConverter::GetCategories() } /// -/// Sets the current category in use by this converter, +/// Sets the current category in use by this converter, /// and returns a list of unit types that exist under the given category. /// /// Category struct which we are setting @@ -109,22 +109,8 @@ CategorySelectionInitializer UnitConverter::SetCurrentCategory(const Category& i vector& 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,21 +142,23 @@ Category UnitConverter::GetCurrentCategory() /// Unit struct we are converting to void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType) { - if (CheckLoad()) + if (!CheckLoad()) { - m_fromType = fromType; - m_toType = toType; - Calculate(); - - UpdateCurrencySymbols(); - UpdateViewModel(); + return; } + + m_fromType = fromType; + m_toType = toType; + Calculate(); + + UpdateCurrencySymbols(); + UpdateViewModel(); } /// /// Switches the active field, indicating that we are now entering data into /// what was originally the return field, and storing results into what was -/// originally the current field. We swap appropriate values, +/// originally the current field. We swap appropriate values, /// but do not callback, as values have not changed. /// /// @@ -181,22 +169,24 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType /// void UnitConverter::SwitchActive(const wstring& newValue) { - if (CheckLoad()) + if (!CheckLoad()) { - swap(m_fromType, m_toType); - swap(m_currentHasDecimal, m_returnHasDecimal); - m_returnDisplay = m_currentDisplay; - m_currentDisplay = newValue; - m_currentHasDecimal = (m_currentDisplay.find(L'.') != m_currentDisplay.npos); - m_switchedActive = true; + return; + } - if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr) - { - shared_ptr currencyDataLoader = GetCurrencyConverterDataLoader(); - const pair currencyRatios = currencyDataLoader->GetCurrencyRatioEquality(m_fromType, m_toType); + swap(m_fromType, m_toType); + swap(m_currentHasDecimal, m_returnHasDecimal); + m_returnDisplay = m_currentDisplay; + m_currentDisplay = newValue; + m_currentHasDecimal = (m_currentDisplay.find(L'.') != m_currentDisplay.npos); + m_switchedActive = true; - m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second); - } + if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr) + { + shared_ptr currencyDataLoader = GetCurrencyConverterDataLoader(); + const pair currencyRatios = currencyDataLoader->GetCurrencyRatioEquality(m_fromType, m_toType); + + m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second); } } @@ -291,55 +281,53 @@ wstring UnitConverter::ConversionDataToString(ConversionData d, const wchar_t * /// wstring UnitConverter::Serialize() { - if (CheckLoad()) - { - wstringstream out(wstringstream::out); - const wchar_t * delimiter = L";"; - - out << UnitToString(m_fromType, delimiter) << "|"; - out << UnitToString(m_toType, delimiter) << "|"; - out << CategoryToString(m_currentCategory, delimiter) << "|"; - out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter; - out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|"; - wstringstream categoryString(wstringstream::out); - wstringstream categoryToUnitString(wstringstream::out); - wstringstream unitToUnitToDoubleString(wstringstream::out); - for (const Category& c : m_categories) - { - categoryString << CategoryToString(c, delimiter) << ","; - } - - for (const auto& cur : m_categoryToUnits) - { - categoryToUnitString << CategoryToString(cur.first, delimiter) << "["; - for (const Unit& u : cur.second) - { - categoryToUnitString << UnitToString(u, delimiter) << ","; - } - categoryToUnitString << "[" << "]"; - } - - for (const auto& cur : m_ratioMap) - { - unitToUnitToDoubleString << UnitToString(cur.first, delimiter) << "["; - for (const auto& curConversion : cur.second) - { - unitToUnitToDoubleString << UnitToString(curConversion.first, delimiter) << ":"; - unitToUnitToDoubleString << ConversionDataToString(curConversion.second, delimiter) << ":,"; - } - unitToUnitToDoubleString << "[" << "]"; - } - - out << categoryString.str() << "|"; - out << categoryToUnitString.str() << "|"; - out << unitToUnitToDoubleString.str() << "|"; - wstring test = out.str(); - return test; - } - else + if (!CheckLoad()) { return wstring(); } + + wstringstream out(wstringstream::out); + const wchar_t * delimiter = L";"; + + out << UnitToString(m_fromType, delimiter) << "|"; + out << UnitToString(m_toType, delimiter) << "|"; + out << CategoryToString(m_currentCategory, delimiter) << "|"; + out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter; + out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|"; + wstringstream categoryString(wstringstream::out); + wstringstream categoryToUnitString(wstringstream::out); + wstringstream unitToUnitToDoubleString(wstringstream::out); + for (const Category& c : m_categories) + { + categoryString << CategoryToString(c, delimiter) << ","; + } + + for (const auto& cur : m_categoryToUnits) + { + categoryToUnitString << CategoryToString(cur.first, delimiter) << "["; + for (const Unit& u : cur.second) + { + categoryToUnitString << UnitToString(u, delimiter) << ","; + } + categoryToUnitString << "[" << "]"; + } + + for (const auto& cur : m_ratioMap) + { + unitToUnitToDoubleString << UnitToString(cur.first, delimiter) << "["; + for (const auto& curConversion : cur.second) + { + unitToUnitToDoubleString << UnitToString(curConversion.first, delimiter) << ":"; + unitToUnitToDoubleString << ConversionDataToString(curConversion.second, delimiter) << ":,"; + } + unitToUnitToDoubleString << "[" << "]"; + } + + out << categoryString.str() << "|"; + out << categoryToUnitString.str() << "|"; + out << unitToUnitToDoubleString.str() << "|"; + wstring test = out.str(); + return test; } /// @@ -349,55 +337,58 @@ wstring UnitConverter::Serialize() void UnitConverter::DeSerialize(const wstring& serializedData) { Reset(); - if (!serializedData.empty()) + + if (serializedData.empty()) { - vector outerTokens = StringToVector(serializedData, L"|"); - assert(outerTokens.size() == EXPECTEDSERIALIZEDTOKENCOUNT); - m_fromType = StringToUnit(outerTokens[0]); - m_toType = StringToUnit(outerTokens[1]); - m_currentCategory = StringToCategory(outerTokens[2]); - vector stateDataTokens = StringToVector(outerTokens[3], L";"); - assert(stateDataTokens.size() == EXPECTEDSTATEDATATOKENCOUNT); - m_currentHasDecimal = (stateDataTokens[0].compare(L"1") == 0); - m_returnHasDecimal = (stateDataTokens[1].compare(L"1") == 0); - m_switchedActive = (stateDataTokens[2].compare(L"1") == 0); - m_currentDisplay = stateDataTokens[3]; - m_returnDisplay = stateDataTokens[4]; - vector categoryListTokens = StringToVector(outerTokens[4], L","); - for (wstring token : categoryListTokens) - { - m_categories.push_back(StringToCategory(token)); - } - vector unitVectorTokens = StringToVector(outerTokens[5], L"]"); - for (wstring unitVector : unitVectorTokens) - { - vector mapcomponents = StringToVector(unitVector, L"["); - assert(mapcomponents.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT); - Category key = StringToCategory(mapcomponents[0]); - vector units = StringToVector(mapcomponents[1], L","); - for (wstring unit : units) - { - m_categoryToUnits[key].push_back(StringToUnit(unit)); - } - } - vector ratioMapTokens = StringToVector(outerTokens[6], L"]"); - for (wstring token : ratioMapTokens) - { - vector ratioMapComponentTokens = StringToVector(token, L"["); - assert(ratioMapComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT); - Unit key = StringToUnit(ratioMapComponentTokens[0]); - vector ratioMapList = StringToVector(ratioMapComponentTokens[1], L","); - for (wstring subtoken : ratioMapList) - { - vector ratioMapSubComponentTokens = StringToVector(subtoken, L":"); - assert(ratioMapSubComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT); - Unit subkey = StringToUnit(ratioMapSubComponentTokens[0]); - ConversionData conversion = StringToConversionData(ratioMapSubComponentTokens[1]); - m_ratioMap[key][subkey] = conversion; - } - } - UpdateViewModel(); + return; } + + vector outerTokens = StringToVector(serializedData, L"|"); + assert(outerTokens.size() == EXPECTEDSERIALIZEDTOKENCOUNT); + m_fromType = StringToUnit(outerTokens[0]); + m_toType = StringToUnit(outerTokens[1]); + m_currentCategory = StringToCategory(outerTokens[2]); + vector stateDataTokens = StringToVector(outerTokens[3], L";"); + assert(stateDataTokens.size() == EXPECTEDSTATEDATATOKENCOUNT); + m_currentHasDecimal = (stateDataTokens[0].compare(L"1") == 0); + m_returnHasDecimal = (stateDataTokens[1].compare(L"1") == 0); + m_switchedActive = (stateDataTokens[2].compare(L"1") == 0); + m_currentDisplay = stateDataTokens[3]; + m_returnDisplay = stateDataTokens[4]; + vector categoryListTokens = StringToVector(outerTokens[4], L","); + for (wstring token : categoryListTokens) + { + m_categories.push_back(StringToCategory(token)); + } + vector unitVectorTokens = StringToVector(outerTokens[5], L"]"); + for (wstring unitVector : unitVectorTokens) + { + vector mapcomponents = StringToVector(unitVector, L"["); + assert(mapcomponents.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT); + Category key = StringToCategory(mapcomponents[0]); + vector units = StringToVector(mapcomponents[1], L","); + for (wstring unit : units) + { + m_categoryToUnits[key].push_back(StringToUnit(unit)); + } + } + vector ratioMapTokens = StringToVector(outerTokens[6], L"]"); + for (wstring token : ratioMapTokens) + { + vector ratioMapComponentTokens = StringToVector(token, L"["); + assert(ratioMapComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT); + Unit key = StringToUnit(ratioMapComponentTokens[0]); + vector ratioMapList = StringToVector(ratioMapComponentTokens[1], L","); + for (wstring subtoken : ratioMapList) + { + vector ratioMapSubComponentTokens = StringToVector(subtoken, L":"); + assert(ratioMapSubComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT); + Unit subkey = StringToUnit(ratioMapSubComponentTokens[0]); + ConversionData conversion = StringToConversionData(ratioMapSubComponentTokens[1]); + m_ratioMap[key][subkey] = conversion; + } + } + UpdateViewModel(); } /// @@ -406,21 +397,23 @@ void UnitConverter::DeSerialize(const wstring& serializedData) /// wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it void UnitConverter::RestoreUserPreferences(const wstring& userPreferences) { - if (!userPreferences.empty()) + if (userPreferences.empty()) { - vector outerTokens = StringToVector(userPreferences, L"|"); - if (outerTokens.size() == 3) - { - m_fromType = StringToUnit(outerTokens[0]); - m_toType = StringToUnit(outerTokens[1]); - m_currentCategory = StringToCategory(outerTokens[2]); - } + return; + } + + vector outerTokens = StringToVector(userPreferences, L"|"); + if (outerTokens.size() == 3) + { + m_fromType = StringToUnit(outerTokens[0]); + m_toType = StringToUnit(outerTokens[1]); + m_currentCategory = StringToCategory(outerTokens[2]); } } /// /// Serializes the Category and Associated Units in the converter and returns it as a string -/// +/// wstring UnitConverter::SaveUserPreferences() { wstringstream out(wstringstream::out); @@ -441,7 +434,7 @@ wstring UnitConverter::Quote(const wstring& s) { wstringstream quotedString(wstringstream::out); - //Iterate over the delimiter characters we need to quote + // Iterate over the delimiter characters we need to quote wstring::const_iterator cursor = s.begin(); while(cursor != s.end()) { @@ -479,7 +472,7 @@ wstring UnitConverter::Unquote(const wstring& s) } if (cursor == s.end()) { - //badly formatted + // Badly formatted break; } else @@ -503,144 +496,146 @@ wstring UnitConverter::Unquote(const wstring& s) /// Command enum representing the command that was entered void UnitConverter::SendCommand(Command command) { - if (CheckLoad()) + if (!CheckLoad()) { - //TODO: Localization of characters - bool clearFront = false; - if (m_currentDisplay == L"0") + return; + } + + // TODO: Localization of characters + bool clearFront = false; + if (m_currentDisplay == L"0") + { + clearFront = true; + } + bool clearBack = false; + if ((m_currentHasDecimal && m_currentDisplay.size() - 1 >= MAXIMUMDIGITSALLOWED) || (!m_currentHasDecimal && m_currentDisplay.size() >= MAXIMUMDIGITSALLOWED)) + { + clearBack = true; + } + if (command != Command::Negate && m_switchedActive) + { + ClearValues(); + m_switchedActive = false; + clearFront = true; + clearBack = false; + } + switch (command) + { + case Command::Zero: + m_currentDisplay += L"0"; + break; + + case Command::One: + m_currentDisplay += L"1"; + break; + + case Command::Two: + m_currentDisplay += L"2"; + break; + + case Command::Three: + m_currentDisplay += L"3"; + break; + + case Command::Four: + m_currentDisplay += L"4"; + break; + + case Command::Five: + m_currentDisplay += L"5"; + break; + + case Command::Six: + m_currentDisplay += L"6"; + break; + + case Command::Seven: + m_currentDisplay += L"7"; + break; + + case Command::Eight: + m_currentDisplay += L"8"; + break; + + case Command::Nine: + m_currentDisplay += L"9"; + break; + + case Command::Decimal: + clearFront = false; + clearBack = false; + if (!m_currentHasDecimal) { - clearFront = true; + m_currentDisplay += L"."; + m_currentHasDecimal = true; } - bool clearBack = false; - if ((m_currentHasDecimal && m_currentDisplay.size() - 1 >= MAXIMUMDIGITSALLOWED) || (!m_currentHasDecimal && m_currentDisplay.size() >= MAXIMUMDIGITSALLOWED)) + break; + + case Command::Backspace: + clearFront = false; + clearBack = false; + if ((m_currentDisplay.front() != '-' && m_currentDisplay.size() > 1) || m_currentDisplay.size() > 2) { - clearBack = true; - } - if (command != Command::Negate && m_switchedActive) - { - ClearValues(); - m_switchedActive = false; - clearFront = true; - clearBack = false; - } - switch (command) - { - case Command::Zero: - m_currentDisplay += L"0"; - break; - - case Command::One: - m_currentDisplay += L"1"; - break; - - case Command::Two: - m_currentDisplay += L"2"; - break; - - case Command::Three: - m_currentDisplay += L"3"; - break; - - case Command::Four: - m_currentDisplay += L"4"; - break; - - case Command::Five: - m_currentDisplay += L"5"; - break; - - case Command::Six: - m_currentDisplay += L"6"; - break; - - case Command::Seven: - m_currentDisplay += L"7"; - break; - - case Command::Eight: - m_currentDisplay += L"8"; - break; - - case Command::Nine: - m_currentDisplay += L"9"; - break; - - case Command::Decimal: - clearFront = false; - clearBack = false; - if (!m_currentHasDecimal) + if (m_currentDisplay.back() == '.') { - m_currentDisplay += L"."; - m_currentHasDecimal = true; + m_currentHasDecimal = false; } - break; + m_currentDisplay.pop_back(); + } + else + { + m_currentDisplay = L"0"; + m_currentHasDecimal = false; + } + break; - case Command::Backspace: - clearFront = false; - clearBack = false; - if ((m_currentDisplay.front() != '-' && m_currentDisplay.size() > 1) || m_currentDisplay.size() > 2) + case Command::Negate: + clearFront = false; + clearBack = false; + if (m_currentCategory.supportsNegative) + { + if (m_currentDisplay.front() == '-') { - if (m_currentDisplay.back() == '.') - { - m_currentHasDecimal = false; - } - m_currentDisplay.pop_back(); + m_currentDisplay.erase(0, 1); } else { - m_currentDisplay = L"0"; - m_currentHasDecimal = false; + m_currentDisplay.insert(0, 1, '-'); } - break; - - case Command::Negate: - clearFront = false; - clearBack = false; - if (m_currentCategory.supportsNegative) - { - if (m_currentDisplay.front() == '-') - { - m_currentDisplay.erase(0, 1); - } - else - { - m_currentDisplay.insert(0, 1, '-'); - } - } - break; - - case Command::Clear: - clearFront = false; - clearBack = false; - ClearValues(); - break; - - case Command::Reset: - clearFront = false; - clearBack = false; - ClearValues(); - Reset(); - break; - - default: - break; } - + break; - if (clearFront) - { - m_currentDisplay.erase(0, 1); - } - if (clearBack) - { - m_currentDisplay.erase(m_currentDisplay.size() - 1, 1); - m_vmCallback->MaxDigitsReached(); - } + case Command::Clear: + clearFront = false; + clearBack = false; + ClearValues(); + break; - Calculate(); + case Command::Reset: + clearFront = false; + clearBack = false; + ClearValues(); + Reset(); + break; - UpdateViewModel(); + default: + break; } + + + if (clearFront) + { + m_currentDisplay.erase(0, 1); + } + if (clearBack) + { + m_currentDisplay.erase(m_currentDisplay.size() - 1, 1); + m_vmCallback->MaxDigitsReached(); + } + + Calculate(); + + UpdateViewModel(); } /// @@ -728,7 +723,7 @@ vector> UnitConverter::CalculateSuggested() vector intermediateVector; vector intermediateWhimsicalVector; unordered_map ratios = m_ratioMap[m_fromType]; - //Calculate converted values for every other unit type in this category, along with their magnitude + // Calculate converted values for every other unit type in this category, along with their magnitude for (const auto& cur : ratios) { if (cur.first != m_fromType && cur.first != m_toType) @@ -745,21 +740,21 @@ vector> UnitConverter::CalculateSuggested() } } - //Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value + // Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value sort(intermediateVector.begin(), intermediateVector.end(), [] (SuggestedValueIntermediate first, SuggestedValueIntermediate second) - { - if (abs(first.magnitude) == abs(second.magnitude)) - { - return first.magnitude > second.magnitude; - } - else - { + { + if (abs(first.magnitude) == abs(second.magnitude)) + { + return first.magnitude > second.magnitude; + } + else + { return abs(first.magnitude) < abs(second.magnitude); } }); - //Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings + // Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings for (const auto& entry : intermediateVector) { wstring roundedString; @@ -783,7 +778,7 @@ vector> UnitConverter::CalculateSuggested() } // The Whimsicals are determined differently - //Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value + // Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value sort(intermediateWhimsicalVector.begin(), intermediateWhimsicalVector.end(), [] (SuggestedValueIntermediate first, SuggestedValueIntermediate second) { @@ -797,7 +792,7 @@ vector> UnitConverter::CalculateSuggested() } }); - //Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings + // Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings vector> whimsicalReturnVector; for (const auto& entry : intermediateWhimsicalVector) @@ -844,47 +839,49 @@ void UnitConverter::Reset() ClearValues(); m_switchedActive = false; - if (!m_categories.empty()) + if (m_categories.empty()) { - m_currentCategory = m_categories[0]; + return; + } - m_categoryToUnits.clear(); - m_ratioMap.clear(); - bool readyCategoryFound = false; - for (const Category& category : m_categories) + m_currentCategory = m_categories[0]; + + m_categoryToUnits.clear(); + m_ratioMap.clear(); + bool readyCategoryFound = false; + for (const Category& category : m_categories) + { + shared_ptr activeDataLoader = GetDataLoaderForCategory(category); + if (activeDataLoader == nullptr) { - shared_ptr activeDataLoader = GetDataLoaderForCategory(category); - if (activeDataLoader == nullptr) - { - // The data loader is different depending on the category, e.g. currency data loader - // is different from the static data loader. - // If there is no data loader for this category, continue. - continue; - } - - vector units = activeDataLoader->LoadOrderedUnits(category); - m_categoryToUnits[category] = units; - - // Just because the units are empty, doesn't mean the user can't select this category, - // we just want to make sure we don't let an unready category be the default. - if (!units.empty()) - { - for (Unit u : units) - { - m_ratioMap[u] = activeDataLoader->LoadOrderedRatios(u); - } - - if (!readyCategoryFound) - { - m_currentCategory = category; - readyCategoryFound = true; - } - } + // The data loader is different depending on the category, e.g. currency data loader + // is different from the static data loader. + // If there is no data loader for this category, continue. + continue; } - InitializeSelectedUnits(); - Calculate(); + vector units = activeDataLoader->LoadOrderedUnits(category); + m_categoryToUnits[category] = units; + + // Just because the units are empty, doesn't mean the user can't select this category, + // we just want to make sure we don't let an unready category be the default. + if (!units.empty()) + { + for (Unit u : units) + { + m_ratioMap[u] = activeDataLoader->LoadOrderedRatios(u); + } + + if (!readyCategoryFound) + { + m_currentCategory = category; + readyCategoryFound = true; + } + } } + + InitializeSelectedUnits(); + Calculate(); } /// @@ -1029,22 +1026,24 @@ void UnitConverter::Calculate() /// wstring to trim void UnitConverter::TrimString(wstring& returnString) { - if (returnString.find(L'.') != m_returnDisplay.npos) + if (returnString.find(L'.') == m_returnDisplay.npos) { - wstring::iterator iter; - for (iter = returnString.end() - 1; ;iter--) + return; + } + + wstring::iterator iter; + for (iter = returnString.end() - 1; ;iter--) + { + if (*iter != L'0') { - if (*iter != L'0') - { - returnString.erase(iter + 1, returnString.end()); - break; - } - } - if (*(returnString.end()-1) == L'.') - { - returnString.erase(returnString.end()-1, returnString.end()); + returnString.erase(iter + 1, returnString.end()); + break; } } + if (*(returnString.end()-1) == L'.') + { + returnString.erase(returnString.end()-1, returnString.end()); + } } /// diff --git a/src/CalcManager/UnitConverter.h b/src/CalcManager/UnitConverter.h index 3f323c35..4e130d12 100644 --- a/src/CalcManager/UnitConverter.h +++ b/src/CalcManager/UnitConverter.h @@ -51,7 +51,7 @@ namespace UnitConversionManager // null checks. // // unitId, name, abbreviation, isConversionSource, isConversionTarget, isWhimsical - const Unit EMPTY_UNIT = Unit{ -1, L"", L"", true, true, false }; + inline const Unit EMPTY_UNIT = Unit{ -1, L"", L"", true, true, false }; struct Category { diff --git a/src/CalcManager/pch.h b/src/CalcManager/pch.h index 27e01ff3..c5f39b6d 100644 --- a/src/CalcManager/pch.h +++ b/src/CalcManager/pch.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once @@ -7,15 +7,21 @@ #define WIN32_LEAN_AND_MEAN #endif +// Windows headers define min/max macros. +// Disable it for project code. +#define NOMINMAX + #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/src/CalcViewModel/ApplicationViewModel.cpp b/src/CalcViewModel/ApplicationViewModel.cpp index 4df5bac3..f99ce036 100644 --- a/src/CalcViewModel/ApplicationViewModel.cpp +++ b/src/CalcViewModel/ApplicationViewModel.cpp @@ -32,14 +32,11 @@ using namespace Windows::UI::Xaml::Data; using namespace Windows::UI::Xaml::Input; using namespace Windows::UI::Xaml::Media; -namespace CalculatorApp::ViewModel::ApplicationViewModelProperties +namespace { - StringReference Mode(L"Mode"); - StringReference PreviousMode(L"PreviousMode"); - StringReference ClearMemoryVisibility(L"ClearMemoryVisibility"); - StringReference AppBarVisibility(L"AppBarVisibility"); - StringReference CategoryName(L"CategoryName"); - StringReference Categories(L"Categories"); + StringReference CategoriesPropertyName(L"Categories"); + StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility"); + StringReference AppBarVisibilityPropertyName(L"AppBarVisibility"); } ApplicationViewModel::ApplicationViewModel() : @@ -60,7 +57,7 @@ void ApplicationViewModel::Mode::set(ViewMode value) PreviousMode = m_mode; m_mode = value; OnModeChanged(); - RaisePropertyChanged(ApplicationViewModelProperties::Mode); + RaisePropertyChanged(ModePropertyName); } } @@ -69,7 +66,7 @@ void ApplicationViewModel::Categories::set(IObservableVector^ if (m_categories != value) { m_categories = value; - RaisePropertyChanged(ApplicationViewModelProperties::Categories); + RaisePropertyChanged(CategoriesPropertyName); } } @@ -163,11 +160,11 @@ void ApplicationViewModel::OnModeChanged() // // Save the changed mode, so that the new window launches in this mode. // Don't save until after we have adjusted to the new mode, so we don't save a mode that fails to load. - ApplicationData::Current->LocalSettings->Values->Insert(ApplicationViewModelProperties::Mode, NavCategory::Serialize(m_mode)); + ApplicationData::Current->LocalSettings->Values->Insert(ModePropertyName, NavCategory::Serialize(m_mode)); TraceLogger::GetInstance().LogModeChangeEnd(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread())); - RaisePropertyChanged(ApplicationViewModelProperties::ClearMemoryVisibility); - RaisePropertyChanged(ApplicationViewModelProperties::AppBarVisibility); + RaisePropertyChanged(ClearMemoryVisibilityPropertyName); + RaisePropertyChanged(AppBarVisibilityPropertyName); } void ApplicationViewModel::OnCopyCommand(Object^ parameter) diff --git a/src/CalcViewModel/ApplicationViewModel.h b/src/CalcViewModel/ApplicationViewModel.h index a8d459f7..f13e00ad 100644 --- a/src/CalcViewModel/ApplicationViewModel.h +++ b/src/CalcViewModel/ApplicationViewModel.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once @@ -11,16 +11,6 @@ namespace CalculatorApp { namespace ViewModel { - namespace ApplicationViewModelProperties - { - extern Platform::StringReference Mode; - extern Platform::StringReference PreviousMode; - extern Platform::StringReference ClearMemoryVisibility; - extern Platform::StringReference AppBarVisibility; - extern Platform::StringReference CategoryName; - extern Platform::StringReference Categories; - } - [Windows::UI::Xaml::Data::Bindable] public ref class ApplicationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged { @@ -32,9 +22,9 @@ namespace CalculatorApp OBSERVABLE_OBJECT(); OBSERVABLE_PROPERTY_RW(StandardCalculatorViewModel^, CalculatorViewModel); OBSERVABLE_PROPERTY_RW(DateCalculatorViewModel^, DateCalcViewModel); - OBSERVABLE_PROPERTY_RW(CalculatorApp::ViewModel::UnitConverterViewModel^, ConverterViewModel); + OBSERVABLE_PROPERTY_RW(UnitConverterViewModel^, ConverterViewModel); OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::ViewMode, PreviousMode); - OBSERVABLE_PROPERTY_RW(Platform::String^, CategoryName); + OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, CategoryName); COMMAND_FOR_METHOD(CopyCommand, ApplicationViewModel::OnCopyCommand); COMMAND_FOR_METHOD(PasteCommand, ApplicationViewModel::OnPasteCommand); @@ -48,6 +38,13 @@ namespace CalculatorApp void set(CalculatorApp::Common::ViewMode value); } + static property Platform::String^ ModePropertyName + { + Platform::String^ get() + { + return Platform::StringReference(L"Mode"); + } + } property Windows::Foundation::Collections::IObservableVector^ Categories { diff --git a/src/CalcViewModel/Common/AlwaysSelectedCollectionView.h b/src/CalcViewModel/Common/AlwaysSelectedCollectionView.h index 40dd5cf3..54c3b67c 100644 --- a/src/CalcViewModel/Common/AlwaysSelectedCollectionView.h +++ b/src/CalcViewModel/Common/AlwaysSelectedCollectionView.h @@ -3,9 +3,9 @@ #pragma once -namespace CalculatorApp { namespace Common +namespace CalculatorApp { namespace Common { - ref class AlwaysSelectedCollectionView sealed: + ref class AlwaysSelectedCollectionView sealed: public Windows::UI::Xaml::DependencyObject, public Windows::UI::Xaml::Data::ICollectionView { @@ -14,11 +14,11 @@ namespace CalculatorApp { namespace Common m_currentPosition(-1) { m_source = source; - + Windows::UI::Xaml::Interop::IBindableObservableVector^ observable = dynamic_cast(source); if (observable) { - observable->VectorChanged += + observable->VectorChanged += ref new Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler(this, &AlwaysSelectedCollectionView::OnSourceBindableVectorChanged); } } @@ -53,7 +53,7 @@ namespace CalculatorApp { namespace Common return ref new Platform::Collections::Vector(); } } - property bool HasMoreItems + property bool HasMoreItems { virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::HasMoreItems::get { @@ -77,7 +77,7 @@ namespace CalculatorApp { namespace Common } // The item is not in the collection - // We're going to schedule a call back later so we + // We're going to schedule a call back later so we // restore the selection to the way we wanted it to begin with if (m_currentPosition >= 0 && m_currentPosition < static_cast(m_source->Size)) { @@ -161,7 +161,7 @@ namespace CalculatorApp { namespace Common m_currentChanging -= token; } } - + // IVector // Not implemented methods virtual void Append(Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector::Append @@ -219,7 +219,7 @@ namespace CalculatorApp { namespace Common return m_source->Size; } } - + // IObservableVector event Windows::Foundation::Collections::VectorChangedEventHandler^ VectorChanged { @@ -262,9 +262,9 @@ namespace CalculatorApp { namespace Common private: virtual Platform::Object^ Convert( - Platform::Object^ value, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ value, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert { auto result = dynamic_cast(value); @@ -276,9 +276,9 @@ namespace CalculatorApp { namespace Common } virtual Platform::Object^ ConvertBack( - Platform::Object^ /*value*/, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ /*value*/, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack { return Windows::UI::Xaml::DependencyProperty::UnsetValue; diff --git a/src/CalcViewModel/Common/AppResourceProvider.cpp b/src/CalcViewModel/Common/AppResourceProvider.cpp index d7982827..45d3a31c 100644 --- a/src/CalcViewModel/Common/AppResourceProvider.cpp +++ b/src/CalcViewModel/Common/AppResourceProvider.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#pragma once - #include "pch.h" #include "AppResourceProvider.h" diff --git a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp index 72b4a712..823572f3 100644 --- a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp +++ b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp @@ -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" @@ -20,6 +20,8 @@ namespace CalculatorApp::Common::Automation StringReference CategoryNameChanged(L"CategoryNameChanged"); StringReference UpdateCurrencyRates(L"UpdateCurrencyRates"); StringReference DisplayCopied(L"DisplayCopied"); + StringReference OpenParenthesisCountChanged(L"OpenParenthesisCountChanged"); + StringReference NoParenthesisAdded(L"NoParenthesisAdded"); } } @@ -142,3 +144,21 @@ NarratorAnnouncement^ CalculatorAnnouncement::GetDisplayCopiedAnnouncement(Strin AutomationNotificationKind::ActionCompleted, AutomationNotificationProcessing::ImportantMostRecent); } + +NarratorAnnouncement^ CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(String^ announcement) +{ + return ref new NarratorAnnouncement( + announcement, + CalculatorActivityIds::OpenParenthesisCountChanged, + AutomationNotificationKind::ActionCompleted, + AutomationNotificationProcessing::ImportantMostRecent); +} + +NarratorAnnouncement^ CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(String^ announcement) +{ + return ref new NarratorAnnouncement( + announcement, + CalculatorActivityIds::NoParenthesisAdded, + AutomationNotificationKind::ActionCompleted, + AutomationNotificationProcessing::ImportantMostRecent); +} diff --git a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h index 16635b4a..3ec6a5e3 100644 --- a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h +++ b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once @@ -88,7 +88,10 @@ namespace CalculatorApp::Common::Automation static NarratorAnnouncement^ GetCategoryNameChangedAnnouncement(Platform::String^ announcement); static NarratorAnnouncement^ GetUpdateCurrencyRatesAnnouncement(Platform::String^ announcement); - + static NarratorAnnouncement^ GetDisplayCopiedAnnouncement(Platform::String^ announcement); + + static NarratorAnnouncement^ GetOpenParenthesisCountChangedAnnouncement(Platform::String^ announcement); + static NarratorAnnouncement^ GetNoRightParenthesisAddedAnnouncement(Platform::String ^ announcement); }; } diff --git a/src/CalcViewModel/Common/BindableBase.cpp b/src/CalcViewModel/Common/BindableBase.cpp index 270e68ac..b1fdcc78 100644 --- a/src/CalcViewModel/Common/BindableBase.cpp +++ b/src/CalcViewModel/Common/BindableBase.cpp @@ -18,17 +18,17 @@ void BindableBase::OnPropertyChanged(String^ propertyName) PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName)); } -Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetCustomProperty(Platform::String^ name) +Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetCustomProperty(Platform::String^ name) { return nullptr; } -Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type) +Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type) { return nullptr; } -Platform::String^ BindableBase::GetStringRepresentation() +Platform::String^ BindableBase::GetStringRepresentation() { - return this->ToString(); + return this->ToString(); } diff --git a/src/CalcViewModel/Common/CalculatorButtonUser.h b/src/CalcViewModel/Common/CalculatorButtonUser.h index cd602c69..cc6647d9 100644 --- a/src/CalcViewModel/Common/CalculatorButtonUser.h +++ b/src/CalcViewModel/Common/CalculatorButtonUser.h @@ -80,7 +80,7 @@ namespace CalculatorApp D = (int) CM::Command::CommandD, E = (int) CM::Command::CommandE, F = (int) CM::Command::CommandF, - Memory, // This is the memory button. Doesn't have a direct mapping to the CalcEngine. + Memory, // This is the memory button. Doesn't have a direct mapping to the CalcEngine. Sinh = (int) CM::Command::CommandSINH, Cosh = (int) CM::Command::CommandCOSH, Tanh = (int) CM::Command::CommandTANH, diff --git a/src/CalcViewModel/Common/CalculatorDisplay.cpp b/src/CalcViewModel/Common/CalculatorDisplay.cpp index 705da22c..cd531e01 100644 --- a/src/CalcViewModel/Common/CalculatorDisplay.cpp +++ b/src/CalcViewModel/Common/CalculatorDisplay.cpp @@ -2,7 +2,7 @@ // Licensed under the MIT License. // This class provides the concrete implementation for the ICalcDisplay interface -// that is declared in the Calculation Manager Library. +// that is declared in the Calculation Manager Library. #include "pch.h" #include "CalculatorDisplay.h" #include "StandardCalculatorViewModel.h" @@ -29,8 +29,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue { if (m_callbackReference) { - auto calcVM = m_callbackReference.Resolve(); - if (calcVM) + if (auto calcVM = m_callbackReference.Resolve()) { calcVM->SetPrimaryDisplay(displayStringValue, isError); } @@ -41,20 +40,29 @@ void CalculatorDisplay::SetParenDisplayText(_In_ const std::wstring& parenthesis { if (m_callbackReference != nullptr) { - auto calcVM = m_callbackReference.Resolve(); - if (calcVM) + if (auto calcVM = m_callbackReference.Resolve()) { calcVM->SetParenthesisCount(parenthesisCount); } } } +void CalculatorDisplay::OnNoRightParenAdded() +{ + if (m_callbackReference != nullptr) + { + if (auto calcVM = m_callbackReference.Resolve()) + { + calcVM->OnNoRightParenAdded(); + } + } +} + void CalculatorDisplay::SetIsInError(bool isError) { if (m_callbackReference != nullptr) { - auto calcVM = m_callbackReference.Resolve(); - if (calcVM) + if (auto calcVM = m_callbackReference.Resolve()) { calcVM->IsInError = isError; } @@ -65,8 +73,7 @@ void CalculatorDisplay::SetExpressionDisplay(_Inout_ std::shared_ptr(); - if (calcVM) + if(auto calcVM = m_callbackReference.Resolve()) { calcVM->SetExpressionDisplay(tokens, commands); } @@ -77,8 +84,7 @@ void CalculatorDisplay::SetMemorizedNumbers(_In_ const vector& new { if (m_callbackReference != nullptr) { - auto calcVM = m_callbackReference.Resolve(); - if (calcVM) + if (auto calcVM = m_callbackReference.Resolve()) { calcVM->SetMemorizedNumbers(newMemorizedNumbers); } @@ -89,8 +95,7 @@ void CalculatorDisplay::OnHistoryItemAdded(_In_ unsigned int addedItemIndex) { if (m_historyCallbackReference != nullptr) { - auto historyVM = m_historyCallbackReference.Resolve(); - if (historyVM) + if (auto historyVM = m_historyCallbackReference.Resolve()) { historyVM->OnHistoryItemAdded(addedItemIndex); } @@ -101,8 +106,7 @@ void CalculatorDisplay::MaxDigitsReached() { if (m_callbackReference != nullptr) { - auto calcVM = m_callbackReference.Resolve(); - if (calcVM) + if (auto calcVM = m_callbackReference.Resolve()) { calcVM->OnMaxDigitsReached(); } @@ -113,8 +117,7 @@ void CalculatorDisplay::BinaryOperatorReceived() { if (m_callbackReference != nullptr) { - auto calcVM = m_callbackReference.Resolve(); - if (calcVM) + if (auto calcVM = m_callbackReference.Resolve()) { calcVM->OnBinaryOperatorReceived(); } @@ -125,8 +128,7 @@ void CalculatorDisplay::MemoryItemChanged(unsigned int indexOfMemory) { if (m_callbackReference != nullptr) { - auto calcVM = m_callbackReference.Resolve(); - if (calcVM) + if (auto calcVM = m_callbackReference.Resolve()) { calcVM->OnMemoryItemChanged(indexOfMemory); } diff --git a/src/CalcViewModel/Common/CalculatorDisplay.h b/src/CalcViewModel/Common/CalculatorDisplay.h index 692af37e..9ff06a6e 100644 --- a/src/CalcViewModel/Common/CalculatorDisplay.h +++ b/src/CalcViewModel/Common/CalculatorDisplay.h @@ -22,6 +22,7 @@ namespace CalculatorApp void SetMemorizedNumbers(_In_ const std::vector& memorizedNumbers) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override; + void OnNoRightParenAdded() override; void MaxDigitsReached() override; void BinaryOperatorReceived() override; void MemoryItemChanged(unsigned int indexOfMemory) override; diff --git a/src/CalcViewModel/Common/ConversionResultTaskHelper.h b/src/CalcViewModel/Common/ConversionResultTaskHelper.h index a89f3f14..2fe543c3 100644 --- a/src/CalcViewModel/Common/ConversionResultTaskHelper.h +++ b/src/CalcViewModel/Common/ConversionResultTaskHelper.h @@ -12,7 +12,7 @@ namespace CalculatorApp public: ConversionResultTaskHelper(unsigned int delay, const std::function functionToRun); ~ConversionResultTaskHelper(); - + private: concurrency::task CompleteAfter(unsigned int timeout); diff --git a/src/CalcViewModel/Common/CopyPasteManager.cpp b/src/CalcViewModel/Common/CopyPasteManager.cpp index 68ddd2e8..d10c4c57 100644 --- a/src/CalcViewModel/Common/CopyPasteManager.cpp +++ b/src/CalcViewModel/Common/CopyPasteManager.cpp @@ -26,6 +26,7 @@ constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" }; // [\s\x85] means white-space characters static const wstring c_wspc = L"[\\s\\x85]*"; static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc; +static const wstring c_wspcLParenSigned = c_wspc + L"([-+]?[(])*" + c_wspc; static const wstring c_wspcRParens = c_wspc + L"[)]*" + c_wspc; static const wstring c_signedDecFloat = L"[-+]?\\d*(\\d|[.])\\d*"; @@ -44,8 +45,8 @@ static const array standardModePatterns = }; static const array scientificModePatterns = { - wregex(c_wspcLParens + c_signedDecFloat + c_wspcRParens), - wregex(c_wspcLParens + c_signedDecFloat + L"[e]([+]|[-])+\\d+" + c_wspcRParens) + wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_wspcRParens), + wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + L"[e]([+]|[-])+\\d+" + c_wspcRParens) }; static const array, 4> programmerModePatterns = { { @@ -129,17 +130,17 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m if (pastedText->Length() > MaxPasteableLength) { // return NoOp to indicate don't paste anything. - TraceLogger::GetInstance().LogInvalidInputPasted(L"PastedExpressionSizeGreaterThanMaxAllowed", L"MoreThanMaxInput", mode, programmerNumberBase, bitLengthType); + TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"PastedExpressionSizeGreaterThanMaxAllowed", mode, programmerNumberBase, bitLengthType); return StringReference(PasteErrorString); } wstring pasteExpression = pastedText->Data(); - // Get english translated expression + // Get english translated expression String^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression); // Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333 - pasteExpression = Utils::RemoveUnwantedCharsFromWstring(englishString->Data()); + pasteExpression = RemoveUnwantedCharsFromWstring(englishString->Data()); // If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste. if (!pasteExpression.empty() && pasteExpression.back() == L'=') @@ -164,7 +165,7 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m // validate each operand with patterns for different modes if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType)) { - TraceLogger::GetInstance().LogInvalidInputPasted(L"InvalidExpressionForPresentMode", pastedText->Data(), mode, programmerNumberBase, bitLengthType); + TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"InvalidExpressionForPresentMode", mode, programmerNumberBase, bitLengthType); return StringReference(PasteErrorString); } @@ -193,7 +194,7 @@ vector CopyPasteManager::ExtractOperands(const wstring& pasteExpression if (operands.size() >= MaxOperandCount) { - TraceLogger::GetInstance().LogInvalidInputPasted(L"OperandCountGreaterThanMaxCount", pasteExpression.c_str(), mode, programmerNumberBase, bitLengthType); + TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"OperandCountGreaterThanMaxCount", mode, programmerNumberBase, bitLengthType); operands.clear(); return operands; } @@ -207,7 +208,7 @@ vector CopyPasteManager::ExtractOperands(const wstring& pasteExpression // to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999. if (expLength > MaxExponentLength) { - TraceLogger::GetInstance().LogInvalidInputPasted(L"ExponentLengthGreaterThanMaxLength", pasteExpression.c_str(), mode, programmerNumberBase, bitLengthType); + TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"ExponentLengthGreaterThanMaxLength", mode, programmerNumberBase, bitLengthType); operands.clear(); return operands; } @@ -402,9 +403,9 @@ pair CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo wstring CopyPasteManager::SanitizeOperand(const wstring& operand) { - wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-' }; + wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-', L'+' }; - return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, ARRAYSIZE(unWantedChars)); + return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, static_cast(size(unWantedChars))); } bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, unsigned long long int& result) @@ -567,3 +568,21 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num return len; } + +// return wstring after removing characters like space, comma, double quotes, and monetary prefix currency symbols supported by the Windows keyboard: +// yen or yuan(¥) - 165 +// unspecified currency sign(¤) - 164 +// Ghanaian cedi(₵) - 8373 +// dollar or peso($) - 36 +// colón(₡) - 8353 +// won(₩) - 8361 +// shekel(₪) - 8362 +// naira(₦) - 8358 +// Indian rupee(₹) - 8377 +// pound(£) - 163 +// euro(€) - 8364 +wstring CopyPasteManager::RemoveUnwantedCharsFromWstring(const wstring& input) +{ + wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 }; + return Utils::RemoveUnwantedCharsFromWstring(input, unWantedChars, 18); +} diff --git a/src/CalcViewModel/Common/CopyPasteManager.h b/src/CalcViewModel/Common/CopyPasteManager.h index 1da4af4e..9a886154 100644 --- a/src/CalcViewModel/Common/CopyPasteManager.h +++ b/src/CalcViewModel/Common/CopyPasteManager.h @@ -58,6 +58,7 @@ namespace CalculatorApp static size_t OperandLength(std::wstring operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1); static size_t StandardScientificOperandLength(std::wstring operand); static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase); + static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input); static constexpr size_t MaxStandardOperandLength = 16; static constexpr size_t MaxScientificOperandLength = 32; diff --git a/src/CalcViewModel/Common/DateCalculator.cpp b/src/CalcViewModel/Common/DateCalculator.cpp index 79092216..63efcdd0 100644 --- a/src/CalcViewModel/Common/DateCalculator.cpp +++ b/src/CalcViewModel/Common/DateCalculator.cpp @@ -12,10 +12,11 @@ using namespace CalculatorApp::Common::DateCalculation; DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier) { m_calendar = ref new Calendar(); + m_calendar->ChangeTimeZone("UTC"); m_calendar->ChangeCalendarSystem(calendarIdentifier); } -// Adding Duration to a Date +// Adding Duration to a Date // Returns: True if function succeeds to calculate the date else returns False bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate) { @@ -52,7 +53,7 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate) { // For Subtract the Algorithm is different than Add. Here the smaller units are subtracted first - // and then the larger units. + // and then the larger units. try { m_calendar->SetDateTime(startDate); diff --git a/src/CalcViewModel/Common/DateCalculator.h b/src/CalcViewModel/Common/DateCalculator.h index b755e2ee..3e8a78a5 100644 --- a/src/CalcViewModel/Common/DateCalculator.h +++ b/src/CalcViewModel/Common/DateCalculator.h @@ -3,11 +3,11 @@ #pragma once -const ULONGLONG c_millisecond = 10000; -const ULONGLONG c_second = 1000 * c_millisecond; -const ULONGLONG c_minute = 60 * c_second; -const ULONGLONG c_hour = 60 * c_minute; -const ULONGLONG c_day = 24 * c_hour; +const uint64_t c_millisecond = 10000; +const uint64_t c_second = 1000 * c_millisecond; +const uint64_t c_minute = 60 * c_second; +const uint64_t c_hour = 60 * c_minute; +const uint64_t 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 diff --git a/src/CalcViewModel/Common/DelegateCommand.h b/src/CalcViewModel/Common/DelegateCommand.h index 0cd4fd79..ba29bb7c 100644 --- a/src/CalcViewModel/Common/DelegateCommand.h +++ b/src/CalcViewModel/Common/DelegateCommand.h @@ -21,10 +21,10 @@ namespace CalculatorApp private: - // Explicit, and private, implementation of ICommand, this way of programming makes it so + // Explicit, and private, implementation of ICommand, this way of programming makes it so // the ICommand methods will only be available if the ICommand interface is requested via a dynamic_cast // The ICommand interface is meant to be consumed by Xaml and not by the app, this is a defensive measure against - // code in the app calling Execute. + // code in the app calling Execute. virtual void ExecuteImpl(Platform::Object^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::Execute { TTarget^ target = m_weakTarget.Resolve(); diff --git a/src/CalcViewModel/Common/KeyboardShortcutManager.cpp b/src/CalcViewModel/Common/KeyboardShortcutManager.cpp index 977ca13d..d7b87c96 100644 --- a/src/CalcViewModel/Common/KeyboardShortcutManager.cpp +++ b/src/CalcViewModel/Common/KeyboardShortcutManager.cpp @@ -56,7 +56,7 @@ namespace CalculatorApp { // Lights up all of the buttons in the given range // The range is defined by a pair of iterators - template + template void LightUpButtons(const T& buttons) { auto iterator = buttons.first; @@ -72,14 +72,14 @@ namespace CalculatorApp void LightUpButton(ButtonBase^ button) { - // If the button is a toggle button then we don't need + // If the button is a toggle button then we don't need // to change the UI of the button if (dynamic_cast(button)) { return; } - // The button will go into the visual Pressed state with this call + // The button will go into the visual Pressed state with this call VisualStateManager::GoToState(button, "Pressed", true); // This timer will fire after lightUpTime and make the button @@ -89,7 +89,7 @@ namespace CalculatorApp TimeSpan lightUpTime{}; lightUpTime.Duration = 500000L; // Half second (in 100-ns units) timer->Interval = lightUpTime; - + WeakReference timerWeakReference(timer); WeakReference buttonWeakReference(button); timer->Tick += ref new EventHandler( @@ -206,7 +206,7 @@ void KeyboardShortcutManager::HonorEscape() } void KeyboardShortcutManager::OnCharacterPropertyChanged( - DependencyObject^ target, + DependencyObject^ target, String^ oldValue, String^ newValue) { @@ -263,10 +263,10 @@ void KeyboardShortcutManager::OnVirtualKeyPropertyChanged( reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); auto button = static_cast(target); - + int viewId = Utils::GetWindowId(); auto iterViewMap = s_VirtualKeysForButtons.find(viewId); - + // Check if the View Id has already been registered if (iterViewMap != s_VirtualKeysForButtons.end()) { @@ -281,7 +281,7 @@ void KeyboardShortcutManager::OnVirtualKeyPropertyChanged( } void KeyboardShortcutManager::OnVirtualKeyControlChordPropertyChanged( - DependencyObject^ target, + DependencyObject^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue) { @@ -537,7 +537,7 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^ // Handle Ctrl + E for DateCalculator if ((key == VirtualKey::E) && - isControlKeyPressed && + isControlKeyPressed && !isShiftKeyPressed) { const auto& lookupMap = GetCurrentKeyDictionary(static_cast(key)); @@ -710,7 +710,7 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher^, Acceler { int viewId = Utils::GetWindowId(); auto iterViewMap = s_AboutFlyout.find(viewId); - + if ((iterViewMap != s_AboutFlyout.end()) && (iterViewMap->second != nullptr)) { iterViewMap->second->Hide(); @@ -721,9 +721,9 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher^, Acceler void KeyboardShortcutManager::Initialize() { auto coreWindow = Window::Current->CoreWindow; - coreWindow->CharacterReceived += + coreWindow->CharacterReceived += ref new TypedEventHandler(&KeyboardShortcutManager::OnCharacterReceivedHandler); - coreWindow->KeyDown += + coreWindow->KeyDown += ref new TypedEventHandler(&KeyboardShortcutManager::OnKeyDownHandler); coreWindow->KeyUp += ref new TypedEventHandler(&KeyboardShortcutManager::OnKeyUpHandler); @@ -758,7 +758,7 @@ void KeyboardShortcutManager::UpdateDropDownState(bool isOpen) void KeyboardShortcutManager::UpdateDropDownState(Flyout^ aboutPageFlyout) { int viewId = Utils::GetWindowId(); - + if (s_AboutFlyout.find(viewId) != s_AboutFlyout.end()) { s_AboutFlyout.erase(viewId); @@ -803,7 +803,7 @@ void KeyboardShortcutManager::RegisterNewAppViewId() { s_CharacterForButtons.insert(std::make_pair(appViewId, std::multimap())); } - + if (s_VirtualKeysForButtons.find(appViewId) == s_VirtualKeysForButtons.end()) { s_VirtualKeysForButtons.insert(std::make_pair(appViewId, std::multimap())); @@ -823,17 +823,17 @@ void KeyboardShortcutManager::RegisterNewAppViewId() { s_VirtualKeyAltChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); } - + if (s_VirtualKeyControlShiftChordsForButtons.find(appViewId) == s_VirtualKeyControlShiftChordsForButtons.end()) { s_VirtualKeyControlShiftChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); } - + if (s_VirtualKeyInverseChordsForButtons.find(appViewId) == s_VirtualKeyInverseChordsForButtons.end()) { s_VirtualKeyInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); } - + if (s_VirtualKeyControlInverseChordsForButtons.find(appViewId) == s_VirtualKeyControlInverseChordsForButtons.end()) { s_VirtualKeyControlInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); diff --git a/src/CalcViewModel/Common/LocalizationService.cpp b/src/CalcViewModel/Common/LocalizationService.cpp index df1d85b3..25c2f8a6 100644 --- a/src/CalcViewModel/Common/LocalizationService.cpp +++ b/src/CalcViewModel/Common/LocalizationService.cpp @@ -206,7 +206,7 @@ FontWeight LocalizationService::GetFontWeightOverride() double LocalizationService::GetFontScaleFactorOverride(LanguageFontType fontType) { assert(m_overrideFontApiValues); - + switch (fontType) { case LanguageFontType::UIText: @@ -271,12 +271,12 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target) { control->FontSize = sizeToUse; } - else + else { control->ClearValue(Control::FontSizeProperty); } } - else + else { auto textBlock = dynamic_cast(target); if (textBlock) @@ -290,7 +290,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target) { textBlock->FontSize = sizeToUse; } - else + else { textBlock->ClearValue(TextBlock::FontSizeProperty); } @@ -309,7 +309,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target) { richTextBlock->FontSize = sizeToUse; } - else + else { richTextBlock->ClearValue(RichTextBlock::FontSizeProperty); } @@ -328,7 +328,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target) { textElement->FontSize = sizeToUse; } - else + else { textElement->ClearValue(TextElement::FontSizeProperty); } @@ -416,7 +416,7 @@ IIterable^ LocalizationService::GetLanguageIdentifiers() 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, + // 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. diff --git a/src/CalcViewModel/Common/LocalizationSettings.h b/src/CalcViewModel/Common/LocalizationSettings.h index c1d4dfe2..d37e9647 100644 --- a/src/CalcViewModel/Common/LocalizationSettings.h +++ b/src/CalcViewModel/Common/LocalizationSettings.h @@ -4,6 +4,8 @@ #pragma once #include "LocalizationService.h" +#include + namespace CalculatorApp { namespace Common @@ -41,7 +43,7 @@ namespace CalculatorApp result = GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_SDECIMAL, decimalString, - ARRAYSIZE(decimalString)); + static_cast(std::size(decimalString))); if (result == 0) { throw std::runtime_error("Unexpected error while getting locale info"); @@ -51,7 +53,7 @@ namespace CalculatorApp result = GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_STHOUSAND, groupingSymbolString, - ARRAYSIZE(groupingSymbolString)); + static_cast(std::size(groupingSymbolString))); if (result == 0) { throw std::runtime_error("Unexpected error while getting locale info"); @@ -61,7 +63,7 @@ namespace CalculatorApp result = GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_SGROUPING, numberGroupingString, - ARRAYSIZE(numberGroupingString)); + static_cast(std::size(numberGroupingString))); if (result == 0) { throw std::runtime_error("Unexpected error while getting locale info"); @@ -72,7 +74,7 @@ namespace CalculatorApp result = ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SLIST, listSeparatorString, - ARRAYSIZE(listSeparatorString)); // Max length of the expected return value is 4 + static_cast(std::size(listSeparatorString))); // Max length of the expected return value is 4 if (result == 0) { throw std::runtime_error("Unexpected error while getting locale info"); @@ -122,7 +124,7 @@ namespace CalculatorApp ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK, // The first day in a week reinterpret_cast(day), // Argument is of type PWSTR - ARRAYSIZE(day)); // Max return size are 80 characters + static_cast(std::size(day))); // Max return size are 80 characters // The LOCALE_IFIRSTDAYOFWEEK integer value varies from 0, 1, .. 6 for Monday, Tuesday, ... Sunday // DayOfWeek enum value varies from 0, 1, .. 6 for Sunday, Monday, ... Saturday diff --git a/src/CalcViewModel/Common/LocalizationStringUtil.h b/src/CalcViewModel/Common/LocalizationStringUtil.h index f3b69413..0516ae5a 100644 --- a/src/CalcViewModel/Common/LocalizationStringUtil.h +++ b/src/CalcViewModel/Common/LocalizationStringUtil.h @@ -20,11 +20,11 @@ namespace CalculatorApp va_list args = NULL; va_start(args, pMessage); DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, - pMessage, + pMessage, 0, 0, - spBuffer.get(), - length, + spBuffer.get(), + length, &args); va_end(args); diff --git a/src/CalcViewModel/Common/NavCategory.h b/src/CalcViewModel/Common/NavCategory.h index 61a8dbfc..33e6915a 100644 --- a/src/CalcViewModel/Common/NavCategory.h +++ b/src/CalcViewModel/Common/NavCategory.h @@ -141,7 +141,7 @@ namespace CalculatorApp property Platform::String^ AccessKey { - Platform::String^ get() + Platform::String^ get() { return m_accessKey; } @@ -220,11 +220,11 @@ namespace CalculatorApp static Windows::Foundation::Collections::IObservableVector^ CreateMenuOptions(); static Platform::String^ GetHeaderResourceKey(CategoryGroupType type); - + internal: static NavCategoryGroup^ CreateCalculatorCategory(); static NavCategoryGroup^ CreateConverterCategory(); - + private: NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer); diff --git a/src/CalcViewModel/Common/TraceLogger.cpp b/src/CalcViewModel/Common/TraceLogger.cpp index 17f719a0..bbf6e605 100644 --- a/src/CalcViewModel/Common/TraceLogger.cpp +++ b/src/CalcViewModel/Common/TraceLogger.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#pragma once - #include "pch.h" #include "TraceLogger.h" #include "NetworkManager.h" @@ -59,7 +57,7 @@ namespace CalculatorApp constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_BEGIN = L"MemoryFlyoutOpenBegin"; constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_END = L"MemoryFlyoutOpenEnd"; constexpr auto EVENT_NAME_MEMORY_CLEAR_ALL = L"MemoryClearAll"; - constexpr auto EVENT_NAME_INVALID_INPUT_PASTED = L"InvalidInputPasted"; + constexpr auto EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED = L"InvalidPastedInputOccurred"; constexpr auto EVENT_NAME_VALID_INPUT_PASTED = L"ValidInputPasted"; constexpr auto EVENT_NAME_BITFLIP_PANE_CLICKED = L"BitFlipPaneClicked"; constexpr auto EVENT_NAME_BITFLIP_BUTTONS_USED = L"BitFlipToggleButtonUsed"; @@ -81,6 +79,9 @@ namespace CalculatorApp constexpr auto EVENT_NAME_EXCEPTION = L"Exception"; + constexpr auto PDT_PRIVACY_DATA_TAG = L"PartA_PrivTags"; + constexpr auto PDT_PRODUCT_AND_SERVICE_USAGE = 0x0000'0000'0200'0000u; + #ifdef SEND_TELEMETRY // c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords // c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords @@ -102,7 +103,7 @@ namespace CalculatorApp g_calculatorProvider( L"MicrosoftCalculator", LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), // Microsoft Telemetry group - GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }), //Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0} + GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }), // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0} m_appLaunchActivity{ nullptr } { // initialize the function array @@ -247,7 +248,7 @@ namespace CalculatorApp { windowIdLog.insert(pair(windowId, false)); } - // if the event is not logged already for the present mode + // if the event is not logged already for the present mode if (currentMode != mode) { currentMode = mode; @@ -270,7 +271,7 @@ namespace CalculatorApp { windowIdLog.insert(pair(windowId, false)); } - // if the event is not logged already for the present mode + // if the event is not logged already for the present mode if (currentMode != mode) { currentMode = mode; @@ -292,7 +293,7 @@ namespace CalculatorApp { windowIdLog.insert(pair(windowId, false)); } - // if the event is not logged already for the present mode + // if the event is not logged already for the present mode if (currentMode != mode) { currentMode = mode; @@ -481,9 +482,9 @@ namespace CalculatorApp LogTelemetryEvent(EVENT_NAME_MEMORY_BODY_OPENED, fields); } - //If calculator is launched in any mode other than standard then this call will come which is not intended. But there is no way to avoid it. - //So don't use this function to analyze the count of mode change in session instead use CalculatorViewedInSession and ConverterViewedInSession to do that. - //Use of this function is to analyze perf of mode change. + // If calculator is launched in any mode other than standard then this call will come which is not intended. But there is no way to avoid it. + // So don't use this function to analyze the count of mode change in session instead use CalculatorViewedInSession and ConverterViewedInSession to do that. + // Use of this function is to analyze perf of mode change. void TraceLogger::LogModeChangeBegin(ViewMode fromMode, ViewMode toMode, int windowId) { if (!GetTraceLoggingProviderEnabled()) return; @@ -498,7 +499,7 @@ namespace CalculatorApp } } - //comment: same as LogModeChangeBegin + // comment: same as LogModeChangeBegin void TraceLogger::LogModeChangeEnd(ViewMode toMode, int windowId) const { if (!GetTraceLoggingProviderEnabled()) return; @@ -577,7 +578,7 @@ namespace CalculatorApp // Writer lock for the static resources reader_writer_lock::scoped_lock lock(s_traceLoggerLock); auto iterMap = s_memoryMap.find(windowId); - + LoggingFields fields{}; LogTelemetryEvent(EVENT_NAME_MEMORY_CLEAR_ALL, fields); @@ -641,17 +642,17 @@ namespace CalculatorApp LogTelemetryEvent(EVENT_NAME_SINGLE_MEMORY_USED, fields); } - void TraceLogger::LogInvalidInputPasted(wstring_view reason, wstring_view pastedExpression, ViewMode mode, int programmerNumberBase, int bitLengthType) + void TraceLogger::LogInvalidPastedInputOccurred(wstring_view reason, ViewMode mode, int programmerNumberBase, int bitLengthType) { if (!GetTraceLoggingProviderEnabled()) return; LoggingFields fields{}; fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data()); fields.AddString(L"Reason", reason); - fields.AddString(L"PastedExpression", pastedExpression); fields.AddString(L"ProgrammerNumberBase", GetProgrammerType(programmerNumberBase).c_str()); fields.AddString(L"BitLengthType", GetProgrammerType(bitLengthType).c_str()); - LogTelemetryEvent(EVENT_NAME_INVALID_INPUT_PASTED, fields); + fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE); + LogTelemetryEvent(EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED, fields); } void TraceLogger::LogValidInputPasted(ViewMode mode) const diff --git a/src/CalcViewModel/Common/TraceLogger.h b/src/CalcViewModel/Common/TraceLogger.h index b0213b2c..2b659047 100644 --- a/src/CalcViewModel/Common/TraceLogger.h +++ b/src/CalcViewModel/Common/TraceLogger.h @@ -9,8 +9,8 @@ static const int maxFunctionSize = (int)CalculationManager::Command::CommandBINEDITEND; -// A trace logging provider can only be instantiated and registered once per module. -// This class implements a singleton model ensure that only one instance is created. +// A trace logging provider can only be instantiated and registered once per module. +// This class implements a singleton model ensure that only one instance is created. namespace CalculatorApp { struct FuncLog @@ -64,7 +64,7 @@ namespace CalculatorApp void LogMemoryFlyoutOpenBegin(unsigned int) const; void LogDebug(std::wstring_view debugData); void LogMemoryFlyoutOpenEnd(unsigned int) const; - void LogInvalidInputPasted(std::wstring_view reason, std::wstring_view pastedExpression, CalculatorApp::Common::ViewMode mode, int ProgrammerNumberBase, int bitLengthType); + void LogInvalidPastedInputOccurred(std::wstring_view reason, CalculatorApp::Common::ViewMode mode, int ProgrammerNumberBase, int bitLengthType); void LogValidInputPasted(CalculatorApp::Common::ViewMode mode) const; void UpdateFunctionUsage(int func); void LogFunctionUsage(int); @@ -105,7 +105,7 @@ namespace CalculatorApp // Any new Log method should // a) decide the level of logging. This will help us in limiting recording of events only up to a certain level. See this link for guidance https://msdn.microsoft.com/en-us/library/windows/desktop/aa363742(v=vs.85).aspx - // We're using Verbose level for events that are called frequently and needed only for debugging or capturing perf for specific scenarios + // We're using Verbose level for events that are called frequently and needed only for debugging or capturing perf for specific scenarios // b) should decide whether or not to log to telemetry and pass TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY) accordingly // c) Should accept a variable number of additional data arguments if needed void LogTelemetryEvent(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const; diff --git a/src/CalcViewModel/Common/Utils.cpp b/src/CalcViewModel/Common/Utils.cpp index 55e78e6c..6aad5f52 100644 --- a/src/CalcViewModel/Common/Utils.cpp +++ b/src/CalcViewModel/Common/Utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // @@ -54,7 +54,7 @@ double Utils::GetDoubleFromWstring(wstring input) return ::atof(inputString.c_str()); } -//returns windowId for the current view +// Returns windowId for the current view int Utils::GetWindowId() { int windowId = -1; @@ -80,20 +80,13 @@ void Utils::RunOnUIThreadNonblocking(std::function&& function, _In_ Core } } -// returns if the last character of a wstring is the target wchar_t +// Returns if the last character of a wstring is the target wchar_t bool Utils::IsLastCharacterTarget(_In_ wstring const &input, _In_ wchar_t target) { return !input.empty() && input.back() == target; } -//return wstring after removing characters like space, comma, and double quotes -wstring Utils::RemoveUnwantedCharsFromWstring(wstring input) -{ - wchar_t unWantedChars[] = { L' ', L',', L'"', 8234, 8235, 8236, 8237 }; - return RemoveUnwantedCharsFromWstring(input, unWantedChars, 6); -} - -//return wstring after removing characters specified by unwantedChars array +// Return wstring after removing characters specified by unwantedChars array wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedChars, unsigned int size) { for (unsigned int i = 0; i < size; ++i) @@ -110,7 +103,7 @@ void Utils::SerializeCommandsAndTokens(_In_ shared_ptrGetSize(&commandsSize)); - // save the size of the commands vector + // Save the size of the commands vector writer->WriteUInt32(commandsSize); SerializeCommandVisitor cmdVisitor(writer); diff --git a/src/CalcViewModel/Common/Utils.h b/src/CalcViewModel/Common/Utils.h index d682a76a..a6b773af 100644 --- a/src/CalcViewModel/Common/Utils.h +++ b/src/CalcViewModel/Common/Utils.h @@ -42,10 +42,16 @@ }\ } private: t m_##n; public: -#define NAMED_OBSERVABLE_PROPERTY_RW(t, n)\ +#define OBSERVABLE_NAMED_PROPERTY_R(t, n)\ + OBSERVABLE_PROPERTY_R(t, n)\ + internal: static property Platform::String^ n##PropertyName {\ + Platform::String^ get() { return Platform::StringReference(L#n); }\ + } public: + +#define OBSERVABLE_NAMED_PROPERTY_RW(t, n)\ OBSERVABLE_PROPERTY_RW(t, n)\ - private: property Platform::StringReference n##_PropertyName {\ - Platform::StringReference get() { return Platform::StringReference(L#n); }\ + internal: static property Platform::String^ n##PropertyName {\ + Platform::String^ get() { return Platform::StringReference(L#n); }\ } public: #define OBSERVABLE_PROPERTY_FIELD(n) m_##n @@ -54,11 +60,11 @@ #ifndef UNIT_TESTS #define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\ internal: void RaisePropertyChanged(Platform::String^ p) {\ - PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p)); } public: + PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p)); } public: #else #define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\ internal: void RaisePropertyChanged(Platform::String^ p) {\ - } public: + } public: #endif // The callback specified in the macro is a method in the class that will be called every time the object changes @@ -68,21 +74,21 @@ internal: void RaisePropertyChanged(Platform::String^ p) {\ PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p));\ c(p);\ - } public: + } public: #else #define OBSERVABLE_OBJECT_CALLBACK(c) virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\ internal: void RaisePropertyChanged(Platform::String^ p) {\ c(p);\ - } public: + } public: #endif -// The variable member generated by this macro should not be used in the class code, use the -// property getter instead. +// The variable member generated by this macro should not be used in the class code, use the +// property getter instead. #define COMMAND_FOR_METHOD(p, m) property Windows::UI::Xaml::Input::ICommand^ p {\ Windows::UI::Xaml::Input::ICommand^ get() {\ if (!donotuse_##p) {\ donotuse_##p = CalculatorApp::Common::MakeDelegate(this, &m);\ - } return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; public: + } return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; public: #define DEPENDENCY_PROPERTY_DECLARATION(t, n)\ property t n {\ @@ -141,7 +147,7 @@ namespace Utils const wchar_t PDF = 0x202c; // Pop Directional Formatting const wchar_t LRO = 0x202d; // Left-to-Right Override - // Regular DependencyProperty + // Regular DependencyProperty template Windows::UI::Xaml::DependencyProperty^ RegisterDependencyProperty( _In_ const wchar_t* const name, @@ -205,7 +211,7 @@ namespace Utils ref new Windows::UI::Xaml::PropertyChangedCallback(callback))); } - // Attached DependencyProperty + // Attached DependencyProperty template Windows::UI::Xaml::DependencyProperty^ RegisterDependencyPropertyAttached( _In_ const wchar_t* const name, @@ -280,7 +286,6 @@ namespace Utils Platform::String^ GetStringValue(Platform::String^ input); bool IsLastCharacterTarget(std::wstring const &input, wchar_t target); std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size); - std::wstring RemoveUnwantedCharsFromWstring(std::wstring input); double GetDoubleFromWstring(std::wstring input); int GetWindowId(); void RunOnUIThreadNonblocking(std::function&& function, _In_ Windows::UI::Core::CoreDispatcher^ currentDispatcher); diff --git a/src/CalcViewModel/Common/ValidatingConverters.h b/src/CalcViewModel/Common/ValidatingConverters.h index 9b99cbcd..b33c148f 100644 --- a/src/CalcViewModel/Common/ValidatingConverters.h +++ b/src/CalcViewModel/Common/ValidatingConverters.h @@ -14,9 +14,9 @@ namespace CalculatorApp { namespace Common private: virtual Platform::Object^ Convert( - Platform::Object^ value, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ value, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert { // Pass through as we don't want to change the value from the source @@ -24,9 +24,9 @@ namespace CalculatorApp { namespace Common } virtual Platform::Object^ ConvertBack( - Platform::Object^ value, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ value, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack { if (value) @@ -47,9 +47,9 @@ namespace CalculatorApp { namespace Common private: virtual Platform::Object^ Convert( - Platform::Object^ value, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ value, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert { // Pass through as we don't want to change the value from the source @@ -57,9 +57,9 @@ namespace CalculatorApp { namespace Common } virtual Platform::Object^ ConvertBack( - Platform::Object^ value, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ value, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack { // The value to be valid has to be a boxed int32 value diff --git a/src/CalcViewModel/DataLoaders/CurrencyDataLoader.cpp b/src/CalcViewModel/DataLoaders/CurrencyDataLoader.cpp index 4bb4f727..48c64d42 100644 --- a/src/CalcViewModel/DataLoaders/CurrencyDataLoader.cpp +++ b/src/CalcViewModel/DataLoaders/CurrencyDataLoader.cpp @@ -203,7 +203,7 @@ void CurrencyDataLoader::LoadData() } } - co_return didLoad; + co_return didLoad; }).then([this](bool didLoad) { UpdateDisplayedTimestamp(); @@ -329,7 +329,7 @@ task CurrencyDataLoader::TryLoadDataFromCacheAsync() { loadComplete = co_await TryLoadDataFromWebAsync(); } - + if (!loadComplete) { loadComplete = co_await TryFinishLoadFromCacheAsync(); diff --git a/src/CalcViewModel/DataLoaders/CurrencyDataLoader.h b/src/CalcViewModel/DataLoaders/CurrencyDataLoader.h index cdb006bb..eba76641 100644 --- a/src/CalcViewModel/DataLoaders/CurrencyDataLoader.h +++ b/src/CalcViewModel/DataLoaders/CurrencyDataLoader.h @@ -87,7 +87,7 @@ namespace CalculatorApp bool TryParseWebResponses( _In_ Platform::String^ staticDataJson, - _In_ Platform::String^ allRatiosJson, + _In_ Platform::String^ allRatiosJson, _Inout_ std::vector& staticData, _Inout_ CurrencyRatioMap& allRatiosData); bool TryParseStaticData(_In_ Platform::String^ rawJson, _Inout_ std::vector& staticData); diff --git a/src/CalcViewModel/DataLoaders/UnitConverterDataLoader.cpp b/src/CalcViewModel/DataLoaders/UnitConverterDataLoader.cpp index dea93bbb..45411c1d 100644 --- a/src/CalcViewModel/DataLoaders/UnitConverterDataLoader.cpp +++ b/src/CalcViewModel/DataLoaders/UnitConverterDataLoader.cpp @@ -200,7 +200,7 @@ void UnitConverterDataLoader::GetUnits(_In_ unordered_map(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. ", " // This will be used for date difference formatting: Y years, M months, W weeks, D days - m_listSeparator = ref new String((localizationSettings.GetListSeparator() + L" ").c_str()); + m_listSeparator = localizationSettings.GetListSeparator() + L" "; // Initialize the output results UpdateDisplayResult(); @@ -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); @@ -110,18 +97,18 @@ DateCalculatorViewModel::DateCalculatorViewModel() : void DateCalculatorViewModel::OnPropertyChanged(_In_ String^ prop) { - if (prop == DateCalculatorViewModelProperties::StrDateDiffResult) + if (prop == StrDateDiffResultPropertyName) { UpdateStrDateDiffResultAutomationName(); } - else if (prop == DateCalculatorViewModelProperties::StrDateResult) + else if (prop == StrDateResultPropertyName) { UpdateStrDateResultAutomationName(); } - else if (prop != DateCalculatorViewModelProperties::StrDateDiffResultAutomationName - && prop != DateCalculatorViewModelProperties::StrDateDiffResultInDays - && prop != DateCalculatorViewModelProperties::StrDateResultAutomationName - && prop != DateCalculatorViewModelProperties::IsDiffInDays) + else if (prop != StrDateDiffResultAutomationNamePropertyName + && prop != StrDateDiffResultInDaysPropertyName + && prop != StrDateResultAutomationNamePropertyName + && prop != IsDiffInDaysPropertyName) { OnInputsChanged(); } @@ -180,9 +167,9 @@ void DateCalculatorViewModel::UpdateDisplayResult() StrDateDiffResultInDays = L""; StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates"); } - else if ((m_dateDiffResult.year == 0) && - (m_dateDiffResult.month == 0) && - (m_dateDiffResult.week == 0)) + else if ((m_dateDiffResult.year == 0) && + (m_dateDiffResult.month == 0) && + (m_dateDiffResult.week == 0)) { IsDiffInDays = true; StrDateDiffResultInDays = L""; @@ -245,22 +232,23 @@ void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String^ calendarI String^ DateCalculatorViewModel::GetDateDiffString() const { - String^ result = L""; + wstring result; bool addDelimiter = false; AppResourceProvider resourceLoader = AppResourceProvider::GetInstance(); auto yearCount = m_dateDiffResult.year; if (yearCount > 0) { - result = String::Concat(GetLocalizedNumberString(yearCount), L" "); + result += GetLocalizedNumberString(yearCount)->Data(); + result += L" "; if (yearCount > 1) { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Years")); + result += resourceLoader.GetResourceString(L"Date_Years")->Data(); } else { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Year")); + result += resourceLoader.GetResourceString(L"Date_Year")->Data(); } // set the flags to add a delimiter whenever the next unit is added @@ -272,22 +260,23 @@ String^ DateCalculatorViewModel::GetDateDiffString() const { if (addDelimiter) { - result = String::Concat(result, m_listSeparator); + result += m_listSeparator; } else { addDelimiter = true; } - result = String::Concat(result, String::Concat(GetLocalizedNumberString(monthCount), L" ")); + result += GetLocalizedNumberString(monthCount)->Data(); + result += L" "; if (monthCount > 1) { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Months")); + result += resourceLoader.GetResourceString(L"Date_Months")->Data(); } else { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Month")); + result += resourceLoader.GetResourceString(L"Date_Month")->Data(); } } @@ -296,22 +285,23 @@ String^ DateCalculatorViewModel::GetDateDiffString() const { if (addDelimiter) { - result = String::Concat(result, m_listSeparator); + result += m_listSeparator; } else { addDelimiter = true; } - result = String::Concat(result, String::Concat(GetLocalizedNumberString(weekCount), L" ")); + result += GetLocalizedNumberString(weekCount)->Data(); + result += L" "; if (weekCount > 1) { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Weeks")); + result += resourceLoader.GetResourceString(L"Date_Weeks")->Data(); } else { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Week")); + result += resourceLoader.GetResourceString(L"Date_Week")->Data(); } } @@ -320,43 +310,45 @@ String^ DateCalculatorViewModel::GetDateDiffString() const { if (addDelimiter) { - result = String::Concat(result, m_listSeparator); + result += m_listSeparator; } else { addDelimiter = true; } - result = String::Concat(result, String::Concat(GetLocalizedNumberString(dayCount), L" ")); + result += GetLocalizedNumberString(dayCount)->Data(); + result += L" "; if (dayCount > 1) { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Days")); + result += resourceLoader.GetResourceString(L"Date_Days")->Data(); } else { - result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Day")); + result += resourceLoader.GetResourceString(L"Date_Day")->Data(); } } - return result; + return ref new String(result.data()); } String^ DateCalculatorViewModel::GetDateDiffStringInDays() const { - String^ strDateUnit; + wstring result = GetLocalizedNumberString(m_dateDiffResultInDays.day)->Data(); + result += L" "; // Display the result as '1 day' or 'N days' if (m_dateDiffResultInDays.day > 1) { - strDateUnit = AppResourceProvider::GetInstance().GetResourceString(L"Date_Days"); + result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Days")->Data(); } else { - strDateUnit = AppResourceProvider::GetInstance().GetResourceString(L"Date_Day"); + result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Day")->Data(); } - return String::Concat(GetLocalizedNumberString(m_dateDiffResultInDays.day), String::Concat(L" ", strDateUnit)); + return ref new String(result.data()); } void DateCalculatorViewModel::OnCopyCommand(Platform::Object^ parameter) @@ -378,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; diff --git a/src/CalcViewModel/DateCalculatorViewModel.h b/src/CalcViewModel/DateCalculatorViewModel.h index f2fe7ebf..2fffa1cc 100644 --- a/src/CalcViewModel/DateCalculatorViewModel.h +++ b/src/CalcViewModel/DateCalculatorViewModel.h @@ -23,8 +23,8 @@ 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, - // then show only one result and avoid redundancy + 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); OBSERVABLE_PROPERTY_RW(int, MonthsOffset); @@ -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; } @@ -146,7 +144,7 @@ namespace CalculatorApp CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat; Windows::Globalization::DateTimeFormatting::DateTimeFormatter^ m_dateTimeFormatter; - Platform::String^ m_listSeparator; + std::wstring m_listSeparator; }; } } diff --git a/src/CalcViewModel/HistoryItemViewModel.h b/src/CalcViewModel/HistoryItemViewModel.h index ab22f5da..25822488 100644 --- a/src/CalcViewModel/HistoryItemViewModel.h +++ b/src/CalcViewModel/HistoryItemViewModel.h @@ -17,18 +17,18 @@ namespace CalculatorApp internal: HistoryItemViewModel(Platform::String^ expression, - Platform::String^ result, + Platform::String^ result, _In_ std::shared_ptr>> const &spTokens, _In_ std::shared_ptr>> const &spCommands); std::shared_ptr>> const& GetTokens() { - return m_spTokens; + return m_spTokens; } std::shared_ptr>> const& GetCommands() - { - return m_spCommands; + { + return m_spCommands; } public: diff --git a/src/CalcViewModel/HistoryViewModel.cpp b/src/CalcViewModel/HistoryViewModel.cpp index 4e9fb839..e3cda23e 100644 --- a/src/CalcViewModel/HistoryViewModel.cpp +++ b/src/CalcViewModel/HistoryViewModel.cpp @@ -64,7 +64,7 @@ void HistoryViewModel::ReloadHistory(_In_ ViewMode currentMode) if (historyListModel.size() > 0) { for (auto ritr = historyListModel.rbegin(); ritr != historyListModel.rend(); ++ritr) - { + { wstring expression = (*ritr)->historyItemVector.expression; wstring result = (*ritr)->historyItemVector.result; localizer.LocalizeDisplayValue(&expression); diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index a25aeb18..c01c4789 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -30,37 +30,34 @@ constexpr int StandardModePrecision = 16; constexpr int ScientificModePrecision = 32; constexpr int ProgrammerModePrecision = 64; -namespace CalculatorApp::ViewModel +namespace { - namespace CalculatorViewModelProperties - { - StringReference IsMemoryEmpty(L"IsMemoryEmpty"); - StringReference IsScientific(L"IsScientific"); - StringReference IsStandard(L"IsStandard"); - StringReference IsProgrammer(L"IsProgrammer"); - StringReference DisplayValue(L"DisplayValue"); - StringReference IsInError(L"IsInError"); - StringReference BinaryDisplayValue(L"BinaryDisplayValue"); - } - - namespace CalculatorResourceKeys - { - StringReference CalculatorExpression(L"Format_CalculatorExpression"); - StringReference CalculatorResults(L"Format_CalculatorResults"); - StringReference CalculatorResults_DecimalSeparator_Announced(L"Format_CalculatorResults_Decimal"); - StringReference HexButton(L"Format_HexButtonValue"); - StringReference DecButton(L"Format_DecButtonValue"); - StringReference OctButton(L"Format_OctButtonValue"); - StringReference BinButton(L"Format_BinButtonValue"); - StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix"); - StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); - StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback"); - StringReference MemorySave(L"Format_MemorySave"); - StringReference MemoryItemChanged(L"Format_MemorySlotChanged"); - StringReference MemoryItemCleared(L"Format_MemorySlotCleared"); - StringReference MemoryCleared(L"Memory_Cleared"); - StringReference DisplayCopied(L"Display_Copied"); - } + StringReference IsStandardPropertyName(L"IsStandard"); + StringReference IsScientificPropertyName(L"IsScientific"); + StringReference IsProgrammerPropertyName(L"IsProgrammer"); + StringReference DisplayValuePropertyName(L"DisplayValue"); + StringReference CalculationResultAutomationNamePropertyName(L"CalculationResultAutomationName"); +} + +namespace CalculatorResourceKeys +{ + StringReference CalculatorExpression(L"Format_CalculatorExpression"); + StringReference CalculatorResults(L"Format_CalculatorResults"); + StringReference CalculatorResults_DecimalSeparator_Announced(L"Format_CalculatorResults_Decimal"); + StringReference HexButton(L"Format_HexButtonValue"); + StringReference DecButton(L"Format_DecButtonValue"); + StringReference OctButton(L"Format_OctButtonValue"); + StringReference BinButton(L"Format_BinButtonValue"); + StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix"); + StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix"); + StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement"); + StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); + StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback"); + StringReference MemorySave(L"Format_MemorySave"); + StringReference MemoryItemChanged(L"Format_MemorySlotChanged"); + StringReference MemoryItemCleared(L"Format_MemorySlotCleared"); + StringReference MemoryCleared(L"Memory_Cleared"); + StringReference DisplayCopied(L"Display_Copied"); } StandardCalculatorViewModel::StandardCalculatorViewModel() : @@ -92,7 +89,9 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() : m_localizedMemorySavedAutomationFormat(nullptr), m_localizedMemoryItemChangedAutomationFormat(nullptr), m_localizedMemoryItemClearedAutomationFormat(nullptr), - m_localizedMemoryCleared(nullptr) + m_localizedMemoryCleared(nullptr), + m_localizedOpenParenthesisCountChangedAutomationFormat(nullptr), + m_localizedNoRightParenthesisAddedFormat(nullptr) { WeakReference calculatorViewModel(this); m_calculatorDisplay.SetCallback(calculatorViewModel); @@ -226,6 +225,34 @@ void StandardCalculatorViewModel::SetParenthesisCount(_In_ const wstring& parent } } +void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement() +{ + String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount); + wstring localizedParenthesisCount = parenthesisCount->Data(); + LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount); + + String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement( + CalculatorResourceKeys::OpenParenthesisCountAutomationFormat, + m_localizedOpenParenthesisCountChangedAutomationFormat, + localizedParenthesisCount.c_str()); + + Announcement = CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(announcement); +} + +void StandardCalculatorViewModel::OnNoRightParenAdded() +{ + SetNoParenAddedNarratorAnnouncement(); +} + +void StandardCalculatorViewModel::SetNoParenAddedNarratorAnnouncement() +{ + String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement( + CalculatorResourceKeys::NoParenthesisAdded, + m_localizedNoRightParenthesisAddedFormat); + + Announcement = CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(announcement); +} + void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType) { if (selectedExpressionCommandType == CommandType::OperandCommand) @@ -483,7 +510,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum) if (IsOperandTextCompletelySelected) { - //Clear older text; + // Clear older text; m_selectedExpressionLastData = L""; if (ch == L'x') { @@ -525,6 +552,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum) length = m_selectedExpressionLastData->Length() + 1; if (length > 50) { + delete [] temp; return; } for (; i < length; ++i) @@ -550,8 +578,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum) bool StandardCalculatorViewModel::IsOperator(Command cmdenum) { - if ((cmdenum == Command::Command0) || (cmdenum == Command::Command1) || (cmdenum == Command::Command2) || (cmdenum == Command::Command3) || (cmdenum == Command::Command4) || (cmdenum == Command::Command5) - || (cmdenum == Command::Command6) || (cmdenum == Command::Command7) || (cmdenum == Command::Command8) || (cmdenum == Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK) + if ((cmdenum >= Command::Command0 && cmdenum <= Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK) || (cmdenum == Command::CommandEXP) || (cmdenum == Command::CommandFE) || (cmdenum == Command::ModeBasic) || (cmdenum == Command::ModeProgrammer) || (cmdenum == Command::ModeScientific) || (cmdenum == Command::CommandINV) || (cmdenum == Command::CommandCENTR) || (cmdenum == Command::CommandDEG) || (cmdenum == Command::CommandRAD) || (cmdenum == Command::CommandGRAD) || ((cmdenum >= Command::CommandBINEDITSTART) && (cmdenum <= Command::CommandBINEDITEND))) @@ -572,7 +599,7 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter) if (IsInError) { m_standardCalculatorManager.SendCommand(Command::CommandCLEAR); - + if (!IsRecoverableCommand((int)numOpEnum)) { return; @@ -624,8 +651,7 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter) { m_CurrentAngleType = numOpEnum; } - if ((cmdenum == Command::Command0) || (cmdenum == Command::Command1) || (cmdenum == Command::Command2) || (cmdenum == Command::Command3) || (cmdenum == Command::Command4) || (cmdenum == Command::Command5) - || (cmdenum == Command::Command6) || (cmdenum == Command::Command7) || (cmdenum == Command::Command8) || (cmdenum == Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK) || (cmdenum == Command::CommandEXP)) + if ((cmdenum >= Command::Command0 && cmdenum <= Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK) || (cmdenum == Command::CommandEXP)) { IsOperatorCommand = false; } @@ -835,8 +861,8 @@ void StandardCalculatorViewModel::OnPaste(String^ pastedString, ViewMode mode) Command cmdenum = ConvertToOperatorsEnum(mappedNumOp); m_standardCalculatorManager.SendCommand(cmdenum); - // The CalcEngine state machine won't allow the negate command to be sent before any - // other digits, so instead a flag is set and the command is sent after the first appropriate + // The CalcEngine state machine won't allow the negate command to be sent before any + // other digits, so instead a flag is set and the command is sent after the first appropriate // command. if (sendNegate) { @@ -1162,10 +1188,10 @@ Array^ StandardCalculatorViewModel::Serialize() writer->WriteInt32(data); } - //For ProgrammerMode + // For ProgrammerMode writer->WriteUInt32(static_cast(CurrentRadixType)); - //Serialize commands of calculator manager + // Serialize commands of calculator manager vector serializedCommand = m_standardCalculatorManager.SerializeCommands(); writer->WriteUInt32(static_cast(serializedCommand.size())); writer->WriteBytes(ref new Array(serializedCommand.data(), static_cast(serializedCommand.size()))); @@ -1175,7 +1201,7 @@ Array^ StandardCalculatorViewModel::Serialize() Utils::SerializeCommandsAndTokens(m_tokens, m_commands, writer); } - //Convert viewmodel data in writer to bytes + // Convert viewmodel data in writer to bytes IBuffer^ buffer = writer->DetachBuffer(); DataReader^ reader = DataReader::FromBuffer(buffer); Platform::Array^ viewModelDataAsBytes = ref new Array(buffer->Length); @@ -1223,7 +1249,7 @@ void StandardCalculatorViewModel::Deserialize(Array^ state) m_standardCalculatorManager.DeSerializePrimaryDisplay(serializedPrimaryDisplay); CurrentRadixType = reader->ReadUInt32(); - //Read command data and Deserialize + // Read command data and Deserialize UINT32 modeldatalength = reader->ReadUInt32(); Array^ modelDataAsBytes = ref new Array(modeldatalength); reader->ReadBytes(modelDataAsBytes); @@ -1242,30 +1268,30 @@ void StandardCalculatorViewModel::Deserialize(Array^ state) void StandardCalculatorViewModel::OnPropertyChanged(String^ propertyname) { - if (propertyname == CalculatorViewModelProperties::IsScientific) + if (propertyname == IsScientificPropertyName) { if (IsScientific) { OnButtonPressed(NumbersAndOperatorsEnum::IsScientificMode); } } - else if (propertyname == CalculatorViewModelProperties::IsProgrammer) + else if (propertyname == IsProgrammerPropertyName) { if (IsProgrammer) { OnButtonPressed(NumbersAndOperatorsEnum::IsProgrammerMode); } } - else if (propertyname == CalculatorViewModelProperties::IsStandard) + else if (propertyname == IsStandardPropertyName) { if (IsStandard) { OnButtonPressed(NumbersAndOperatorsEnum::IsStandardMode); } } - else if (propertyname == CalculatorViewModelProperties::DisplayValue) + else if (propertyname == DisplayValuePropertyName) { - RaisePropertyChanged(CalculationResultAutomationName_PropertyName); + RaisePropertyChanged(CalculationResultAutomationNamePropertyName); Announcement = GetDisplayUpdatedNarratorAnnouncement(); } } @@ -1570,7 +1596,7 @@ void StandardCalculatorViewModel::Recalculate(bool fromHistory) m_standardCalculatorManager.SendCommand(static_cast(currentCommands[i])); } - if (fromHistory) // This is for the cases where the expression is loaded from history + if (fromHistory) // This is for the cases where the expression is loaded from history { // To maintain F-E state of the engine, as the last operand hasn't reached engine by now m_standardCalculatorManager.SendCommand(Command::CommandFE); @@ -1614,7 +1640,7 @@ bool StandardCalculatorViewModel::IsOpnd(int nOpCode) Command::CommandPNT }; - for (int i = 0; i < ARRAYSIZE(opnd); i++) + for (unsigned int i = 0; i < size(opnd); i++) { if (nOpCode == static_cast(opnd[i])) { @@ -1645,7 +1671,7 @@ bool StandardCalculatorViewModel::IsUnaryOp(int nOpCode) Command::CommandCUB }; - for (int i = 0; i < ARRAYSIZE(unaryOp); i++) + for (unsigned int i = 0; i < size(unaryOp); i++) { if (nOpCode == static_cast(unaryOp[i])) { @@ -1672,7 +1698,7 @@ bool StandardCalculatorViewModel::IsTrigOp(int nOpCode) Command::CommandATAN }; - for (int i = 0; i < ARRAYSIZE(trigOp); i++) + for (unsigned int i = 0; i < size(trigOp); i++) { if (nOpCode == static_cast(trigOp[i])) { @@ -1695,7 +1721,7 @@ bool StandardCalculatorViewModel::IsBinOp(int nOpCode) Command::CommandPWR }; - for (int i = 0; i < ARRAYSIZE(binOp); i++) + for (unsigned int i = 0; i < size(binOp); i++) { if (nOpCode == static_cast(binOp[i])) { @@ -1729,7 +1755,7 @@ bool StandardCalculatorViewModel::IsRecoverableCommand(int nOpCode) Command::CommandF }; - for (int i = 0; i < ARRAYSIZE(recoverableCommands); i++) + for (unsigned int i = 0; i < size(recoverableCommands); i++) { if (nOpCode == static_cast(recoverableCommands[i])) { @@ -1947,7 +1973,7 @@ void StandardCalculatorViewModel::UpdatecommandsInRecordingMode() } else { - //reset all vars + // Reset all vars isDecimal = false; isNegative = false; isExpMode = false; diff --git a/src/CalcViewModel/StandardCalculatorViewModel.h b/src/CalcViewModel/StandardCalculatorViewModel.h index 91ff9da0..ba6dc82b 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.h +++ b/src/CalcViewModel/StandardCalculatorViewModel.h @@ -31,12 +31,6 @@ namespace CalculatorApp #define ASCII_0 48 public delegate void HideMemoryClickedHandler(); public delegate void ProgModeRadixChangeHandler(); - namespace CalculatorViewModelProperties - { - extern Platform::StringReference IsMemoryEmpty; - extern Platform::StringReference IsInError; - extern Platform::StringReference BinaryDisplayValue; - } [Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged @@ -51,14 +45,14 @@ namespace CalculatorApp OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged); OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayValue); OBSERVABLE_PROPERTY_RW(HistoryViewModel^, HistoryVM); - OBSERVABLE_PROPERTY_RW(bool, IsInError); + OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError); OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand); OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayStringExpression); OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector^, ExpressionTokens); OBSERVABLE_PROPERTY_RW(Platform::String^, DecimalDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, OctalDisplayValue); - OBSERVABLE_PROPERTY_RW(Platform::String^, BinaryDisplayValue); + OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, BinaryDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue_AutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, DecDisplayValue_AutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, OctDisplayValue_AutomationName); @@ -69,19 +63,19 @@ namespace CalculatorApp OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled); OBSERVABLE_PROPERTY_RW(bool, IsCurrentViewPinned); OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector^, MemorizedNumbers); - OBSERVABLE_PROPERTY_RW(bool, IsMemoryEmpty); + OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty); OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked); OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled); OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked); OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled); - NAMED_OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationResultAutomationName); - NAMED_OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationExpressionAutomationName); + OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationResultAutomationName); + OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationExpressionAutomationName); OBSERVABLE_PROPERTY_RW(bool, IsShiftProgrammerChecked); OBSERVABLE_PROPERTY_RW(bool, IsQwordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDwordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsWordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled); - OBSERVABLE_PROPERTY_RW(Platform::String^, OpenParenthesisCount); + OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, OpenParenthesisCount); OBSERVABLE_PROPERTY_RW(int, CurrentRadixType); OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated); OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled); @@ -263,7 +257,7 @@ namespace CalculatorApp property Platform::String^ LeftParenthesisAutomationName { - Platform::String^ get() + Platform::String^ get() { return GetLeftParenthesisAutomationName(); } @@ -276,7 +270,7 @@ namespace CalculatorApp NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate); - //Memory feature related methods. They are internal because they need to called from the MainPage code-behind + // Memory feature related methods. They are internal because they need to called from the MainPage code-behind void OnMemoryButtonPressed(); void OnMemoryItemPressed(Platform::Object^ memoryItemPosition); void OnMemoryAdd(Platform::Object^ memoryItemPosition); @@ -290,6 +284,9 @@ namespace CalculatorApp void SetExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands); void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands); void SetParenthesisCount(_In_ const std::wstring& parenthesisCount); + void SetOpenParenthesisCountNarratorAnnouncement(); + void OnNoRightParenAdded(); + void SetNoParenAddedNarratorAnnouncement(); void OnMaxDigitsReached(); void OnBinaryOperatorReceived(); void OnMemoryItemChanged(unsigned int indexOfMemory); @@ -337,6 +334,8 @@ namespace CalculatorApp Platform::String^ m_localizedMemoryItemChangedAutomationFormat; Platform::String^ m_localizedMemoryItemClearedAutomationFormat; Platform::String^ m_localizedMemoryCleared; + Platform::String^ m_localizedOpenParenthesisCountChangedAutomationFormat; + Platform::String^ m_localizedNoRightParenthesisAddedFormat; bool m_pinned; bool m_isOperandEnabled; diff --git a/src/CalcViewModel/UnitConverterViewModel.cpp b/src/CalcViewModel/UnitConverterViewModel.cpp index 393165eb..a04b584e 100644 --- a/src/CalcViewModel/UnitConverterViewModel.cpp +++ b/src/CalcViewModel/UnitConverterViewModel.cpp @@ -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,48 +53,40 @@ 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 +namespace { - namespace UnitConverterViewModelProperties - { - StringReference CurrentCategory(L"CurrentCategory"); - StringReference Unit1(L"Unit1"); - StringReference Unit2(L"Unit2"); - StringReference Value1Active(L"Value1Active"); - StringReference Value2Active(L"Value2Active"); - StringReference Value1(L"Value1"); - StringReference Value2(L"Value2"); - StringReference Value1AutomationName(L"Value1AutomationName"); - StringReference Value2AutomationName(L"Value2AutomationName"); - StringReference SupplementaryVisibility(L"SupplementaryVisibility"); - StringReference SupplementaryResults(L"SupplementaryResults"); - StringReference Unit1AutomationName(L"Unit1AutomationName"); - StringReference Unit2AutomationName(L"Unit2AutomationName"); - StringReference CurrencySymbol1(L"CurrencySymbol1"); - StringReference CurrencySymbol2(L"CurrencySymbol2"); - StringReference CurrencySymbolVisibility(L"CurrencySymbolVisibility"); - StringReference CurrencyRatioEquality(L"CurrencyRatioEquality"); - StringReference CurrencyRatioEqualityAutomationName(L"CurrencyRatioEqualityAutomationName"); - StringReference NetworkBehavior(L"NetworkBehavior"); - StringReference CurrencyDataLoadFailed(L"CurrencyDataLoadFailed"); - StringReference CurrencyDataIsWeekOld(L"CurrencyDataIsWeekOld"); - StringReference IsCurrencyLoadingVisible(L"IsCurrencyLoadingVisible"); - } + StringReference CurrentCategoryPropertyName(L"CurrentCategory"); + StringReference Unit1AutomationNamePropertyName(L"Unit1AutomationName"); + StringReference Unit2AutomationNamePropertyName(L"Unit2AutomationName"); + StringReference Unit1PropertyName(L"Unit1"); + StringReference Unit2PropertyName(L"Unit2"); + StringReference Value1PropertyName(L"Value1"); + StringReference Value2PropertyName(L"Value2"); + StringReference Value1ActivePropertyName(L"Value1Active"); + StringReference Value2ActivePropertyName(L"Value2Active"); + StringReference Value1AutomationNamePropertyName(L"Value1AutomationName"); + StringReference Value2AutomationNamePropertyName(L"Value2AutomationName"); + StringReference CurrencySymbol1PropertyName(L"CurrencySymbol1"); + StringReference CurrencySymbol2PropertyName(L"CurrencySymbol2"); + StringReference CurrencySymbolVisibilityPropertyName(L"CurrencySymbolVisibility"); + StringReference SupplementaryVisibilityPropertyName(L"SupplementaryVisibility"); +} - namespace UnitConverterResourceKeys - { - StringReference ValueFromFormat(L"Format_ValueFrom"); - StringReference ValueFromDecimalFormat(L"Format_ValueFrom_Decimal"); - StringReference ValueToFormat(L"Format_ValueTo"); - StringReference ConversionResultFormat(L"Format_ConversionResult"); - StringReference InputUnit_Name(L"InputUnit_Name"); - StringReference OutputUnit_Name(L"OutputUnit_Name"); - StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); - StringReference UpdatingCurrencyRates(L"UpdatingCurrencyRates"); - StringReference CurrencyRatesUpdated(L"CurrencyRatesUpdated"); - StringReference CurrencyRatesUpdateFailed(L"CurrencyRatesUpdateFailed"); - } +namespace CalculatorApp::ViewModel::UnitConverterResourceKeys +{ + StringReference ValueFromFormat(L"Format_ValueFrom"); + StringReference ValueFromDecimalFormat(L"Format_ValueFrom_Decimal"); + StringReference ValueToFormat(L"Format_ValueTo"); + StringReference ConversionResultFormat(L"Format_ConversionResult"); + StringReference InputUnit_Name(L"InputUnit_Name"); + StringReference OutputUnit_Name(L"OutputUnit_Name"); + StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); + StringReference UpdatingCurrencyRates(L"UpdatingCurrencyRates"); + StringReference CurrencyRatesUpdated(L"CurrencyRatesUpdated"); + StringReference CurrencyRatesUpdateFailed(L"CurrencyRatesUpdateFailed"); } UnitConverterViewModel::UnitConverterViewModel(const shared_ptr& model) : @@ -142,7 +134,7 @@ UnitConverterViewModel::UnitConverterViewModel(const shared_ptrMode = CurrencyFormatterMode::UseCurrencyCode; m_currencyFormatter->ApplyRoundingForCurrency(RoundingAlgorithm::RoundHalfDown); m_currencyMaxFractionDigits = m_currencyFormatter->FractionDigits; - + auto resourceLoader = AppResourceProvider::GetInstance(); m_localizedValueFromFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromFormat); m_localizedValueToFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueToFormat); @@ -202,12 +194,10 @@ void UnitConverterViewModel::BuildUnitList(const vector& modelUnitLis m_Units->Clear(); for (const UCM::Unit& modelUnit : modelUnitList) { - if (modelUnit.isWhimsical) + if (!modelUnit.isWhimsical) { - continue; + m_Units->Append(ref new Unit(modelUnit)); } - - m_Units->Append(ref new Unit(modelUnit)); } if (m_Units->Size == 0) @@ -257,7 +247,7 @@ void UnitConverterViewModel::OnUnitChanged(Object^ parameter) void UnitConverterViewModel::OnSwitchActive(Platform::Object^ unused) { - // this can be false if this switch occurs without the user having explicitly updated any strings + // this can be false if this switch occurs without the user having explicitly updated any strings // (for example, during deserialization). We only want to try this cleanup if there's actually // something to clean up. if (m_relocalizeStringOnSwitch) @@ -279,10 +269,10 @@ void UnitConverterViewModel::OnSwitchActive(Platform::Object^ unused) m_valueFromUnlocalized.swap(m_valueToUnlocalized); Utils::Swap(&m_localizedValueFromFormat, &m_localizedValueToFormat); - + Utils::Swap(&m_Unit1AutomationName, &m_Unit2AutomationName); - RaisePropertyChanged(UnitConverterViewModelProperties::Unit1AutomationName); - RaisePropertyChanged(UnitConverterViewModelProperties::Unit2AutomationName); + RaisePropertyChanged(Unit1AutomationNamePropertyName); + RaisePropertyChanged(Unit2AutomationNamePropertyName); m_isInputBlocked = false; m_model->SwitchActive(m_valueFromUnlocalized); @@ -324,7 +314,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str if (allowPartialStrings) { // 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" + // a final number. Without this, when typing the three characters in "3.2" // you don't see the decimal point when typing it, you only see it once you've finally // typed a post-decimal digit. @@ -341,17 +331,22 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str { wstring currencyResult = m_currencyFormatter->Format(stod(stringToLocalize))->Data(); wstring currencyCode = m_currencyFormatter->Currency->Data(); - + // CurrencyFormatter always includes LangCode or Symbol. Make it include LangCode // because this includes a non-breaking space. Remove the LangCode. auto pos = currencyResult.find(currencyCode); 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()); } } @@ -367,7 +362,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str if (hasDecimal) { // Since the output from GetLocaleInfoEx() and DecimalFormatter are differing for decimal string - // we are adding the below work-around of editing the string returned by DecimalFormatter + // we are adding the below work-around of editing the string returned by DecimalFormatter // and replacing the decimal separator with the one returned by GetLocaleInfoEx() String^ formattedSampleString = m_decimalFormatter->Format(stod("1.1")); wstring formattedSampleWString = wstring(formattedSampleString->Data()); @@ -378,7 +373,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str { resultWithDecimal.replace(pos, 1, &m_decimalSeparator); } - + // Copy back the edited string to the result result = ref new String(resultWithDecimal.c_str()); } @@ -479,7 +474,7 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object^ parameter) NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter); UCM::Command command = CommandFromButtonId(numOpEnum); - //Don't clear the display if combo box is open and escape is pressed + // Don't clear the display if combo box is open and escape is pressed if (command == UCM::Command::Clear && IsDropDownOpen) { return; @@ -556,13 +551,13 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop) { static bool isCategoryChanging = false; - if (prop->Equals(UnitConverterViewModelProperties::CurrentCategory)) + if (prop == CurrentCategoryPropertyName) { isCategoryChanging = true; CategoryChanged->Execute(nullptr); isCategoryChanging = false; } - else if (prop->Equals(UnitConverterViewModelProperties::Unit1) || prop->Equals(UnitConverterViewModelProperties::Unit2)) + else if (prop == Unit1PropertyName || prop == Unit2PropertyName) { // Category changes will handle updating units after they've both been updated. // This event should only be used to update units from explicit user interaction. @@ -571,7 +566,7 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop) UnitChanged->Execute(nullptr); } // Get the localized automation name for each CalculationResults field - if (prop->Equals(UnitConverterViewModelProperties::Unit1)) + if (prop == Unit1PropertyName) { UpdateValue1AutomationName(); } @@ -580,15 +575,15 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop) UpdateValue2AutomationName(); } } - else if (prop->Equals(UnitConverterViewModelProperties::Value1)) + else if (prop == Value1PropertyName) { UpdateValue1AutomationName(); } - else if (prop->Equals(UnitConverterViewModelProperties::Value2)) + else if (prop == Value2PropertyName) { UpdateValue2AutomationName(); } - else if (prop->Equals(UnitConverterViewModelProperties::Value1Active) || prop->Equals(UnitConverterViewModelProperties::Value2Active)) + else if (prop == Value1ActivePropertyName || prop == Value2ActivePropertyName) { // if one of the values is activated, and as a result both are true, it means // that we're trying to switch. @@ -600,11 +595,11 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop) UpdateValue1AutomationName(); UpdateValue2AutomationName(); } - else if (prop->Equals(UnitConverterViewModelProperties::SupplementaryResults)) + else if (prop == SupplementaryResultsPropertyName) { - RaisePropertyChanged(UnitConverterViewModelProperties::SupplementaryVisibility); + RaisePropertyChanged(SupplementaryVisibilityPropertyName); } - else if (prop->Equals(UnitConverterViewModelProperties::Value1AutomationName)) + else if (prop == Value1AutomationNamePropertyName) { m_isValue1Updating = false; if (!m_isValue2Updating) @@ -612,7 +607,7 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop) AnnounceConversionResult(); } } - else if (prop->Equals(UnitConverterViewModelProperties::Value2AutomationName)) + else if (prop == Value2AutomationNamePropertyName) { m_isValue2Updating = false; if (!m_isValue1Updating) @@ -620,9 +615,9 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop) AnnounceConversionResult(); } } - else if (prop->Equals(UnitConverterViewModelProperties::CurrencySymbol1) || prop->Equals(UnitConverterViewModelProperties::CurrencySymbol2)) + else if (prop == CurrencySymbol1PropertyName || prop == CurrencySymbol2PropertyName) { - RaisePropertyChanged(UnitConverterViewModelProperties::CurrencySymbolVisibility); + RaisePropertyChanged(CurrencySymbolVisibilityPropertyName); } } @@ -643,10 +638,8 @@ String^ UnitConverterViewModel::Serialize() String^ serializedData = ref new String(wstring(out.str()).c_str()); return serializedData; } - else - { - return nullptr; - } + + return nullptr; } void UnitConverterViewModel::Deserialize(Platform::String^ state) @@ -674,7 +667,7 @@ void UnitConverterViewModel::Deserialize(Platform::String^ state) RaisePropertyChanged(nullptr); // Update since all props have been updated. } -//Saving User Preferences of Category and Associated-Units across Sessions. +// Saving User Preferences of Category and Associated-Units across Sessions. void UnitConverterViewModel::SaveUserPreferences() { if (UnitsAreValid()) @@ -695,7 +688,7 @@ void UnitConverterViewModel::SaveUserPreferences() } } -//Restoring User Preferences of Category and Associated-Units. +// Restoring User Preferences of Category and Associated-Units. void UnitConverterViewModel::RestoreUserPreferences() { if (!IsCurrencyCurrentCategory) @@ -849,7 +842,7 @@ void UnitConverterViewModel::RefreshSupplementaryResults() } m_cacheMutex.unlock(); - RaisePropertyChanged(UnitConverterViewModelProperties::SupplementaryResults); + RaisePropertyChanged(SupplementaryResultsPropertyName); //EventWriteConverterSupplementaryResultsUpdated(); } @@ -879,14 +872,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(m_currencyMaxFractionDigits) + 1 == currencyInput.length()); } - else - { - m_isInputBlocked = false; - } } NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId( @@ -973,7 +963,7 @@ void UnitConverterViewModel::OnPaste(String^ stringToPaste, ViewMode mode) { if (isFirstLegalChar) { - // Send Clear before sending something that will actually apply + // Send Clear before sending something that will actually apply // to the field. m_model->SendCommand(UCM::Command::Clear); isFirstLegalChar = false; @@ -988,7 +978,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); diff --git a/src/CalcViewModel/UnitConverterViewModel.h b/src/CalcViewModel/UnitConverterViewModel.h index baabd860..5a982384 100644 --- a/src/CalcViewModel/UnitConverterViewModel.h +++ b/src/CalcViewModel/UnitConverterViewModel.h @@ -19,7 +19,7 @@ namespace CalculatorApp public ref class Category sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged { internal: - Category(const UnitConversionManager::Category& category) : + Category(const UnitConversionManager::Category& category) : m_original(category) { } @@ -52,7 +52,7 @@ namespace CalculatorApp public ref class Unit sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged { internal: - Unit(const UnitConversionManager::Unit& unit) : + Unit(const UnitConversionManager::Unit& unit) : m_original(unit) { } @@ -138,32 +138,13 @@ namespace CalculatorApp return ref new Activatable(activatable); } - namespace UnitConverterViewModelProperties - { - extern Platform::StringReference CurrentCategory; - extern Platform::StringReference Unit1; - extern Platform::StringReference Unit2; - extern Platform::StringReference Value1Active; - extern Platform::StringReference Value2Active; - extern Platform::StringReference SupplementaryVisibility; - extern Platform::StringReference SupplementaryResults; - extern Platform::StringReference CurrencySymbol1; - extern Platform::StringReference CurrencySymbol2; - extern Platform::StringReference CurrencySymbolVisibility; - extern Platform::StringReference CurrencyRatioEquality; - extern Platform::StringReference NetworkBehavior; - extern Platform::StringReference CurrencyDataLoadFailed; - extern Platform::StringReference CurrencyDataIsWeekOld; - extern Platform::StringReference IsCurrencyLoadingVisible; - } - [Windows::UI::Xaml::Data::Bindable] public ref class UnitConverterViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged { internal: UnitConverterViewModel(const std::shared_ptr& model); - public: + public: OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged); OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector^, Categories); @@ -176,7 +157,7 @@ namespace CalculatorApp OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencySymbol2); OBSERVABLE_PROPERTY_RW(Unit^, Unit2); OBSERVABLE_PROPERTY_RW(Platform::String^, Value2); - OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector^, SupplementaryResults); + OBSERVABLE_NAMED_PROPERTY_R(Windows::Foundation::Collections::IObservableVector^, SupplementaryResults); OBSERVABLE_PROPERTY_RW(bool, Value1Active); OBSERVABLE_PROPERTY_RW(bool, Value2Active); OBSERVABLE_PROPERTY_RW(Platform::String^, Value1AutomationName); @@ -187,14 +168,14 @@ namespace CalculatorApp OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDropDownOpen); OBSERVABLE_PROPERTY_RW(bool, IsDropDownEnabled); - OBSERVABLE_PROPERTY_RW(bool, IsCurrencyLoadingVisible); + OBSERVABLE_NAMED_PROPERTY_RW(bool, IsCurrencyLoadingVisible); OBSERVABLE_PROPERTY_RW(bool, IsCurrencyCurrentCategory); OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyRatioEquality); OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyRatioEqualityAutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyTimestamp); - OBSERVABLE_PROPERTY_RW(CalculatorApp::NetworkAccessBehavior, NetworkBehavior); - OBSERVABLE_PROPERTY_RW(bool, CurrencyDataLoadFailed); - OBSERVABLE_PROPERTY_RW(bool, CurrencyDataIsWeekOld); + OBSERVABLE_NAMED_PROPERTY_RW(CalculatorApp::NetworkAccessBehavior, NetworkBehavior); + OBSERVABLE_NAMED_PROPERTY_RW(bool, CurrencyDataLoadFailed); + OBSERVABLE_NAMED_PROPERTY_RW(bool, CurrencyDataIsWeekOld); property Windows::UI::Xaml::Visibility SupplementaryVisibility { @@ -224,7 +205,7 @@ namespace CalculatorApp COMMAND_FOR_METHOD(PasteCommand, UnitConverterViewModel::OnPasteCommand); void AnnounceConversionResult(); - + internal: void ResetView(); void PopulateData(); @@ -242,8 +223,8 @@ namespace CalculatorApp void UpdateValue2AutomationName(); Platform::String^ Serialize(); void Deserialize(Platform::String^ state); - - //Saving And Restoring User Preferences of Category and Associated-Units across Sessions. + + // Saving And Restoring User Preferences of Category and Associated-Units across Sessions. void SaveUserPreferences(); void RestoreUserPreferences(); @@ -360,9 +341,9 @@ namespace CalculatorApp UnitConverterVMCallback(UnitConverterViewModel^ viewModel) : m_viewModel(viewModel) {} - void DisplayCallback(const std::wstring& from, const std::wstring& to) override - { - m_viewModel->UpdateDisplay(from, to); + void DisplayCallback(const std::wstring& from, const std::wstring& to) override + { + m_viewModel->UpdateDisplay(from, to); } void SuggestedValueCallback( diff --git a/src/CalcViewModel/pch.h b/src/CalcViewModel/pch.h index b2717d17..17128bc6 100644 --- a/src/CalcViewModel/pch.h +++ b/src/CalcViewModel/pch.h @@ -10,6 +10,10 @@ #define WIN32_LEAN_AND_MEAN #endif +// Windows headers define min/max macros. +// Disable it for project code. +#define NOMINMAX + #include #include @@ -26,7 +30,7 @@ #include #include #include - +#include // C++\WinRT Headers #include "winrt/base.h" #include "winrt/Windows.Foundation.Diagnostics.h" diff --git a/src/Calculator.sln b/src/Calculator.sln index 2a6989f1..2d36a93f 100644 --- a/src/Calculator.sln +++ b/src/Calculator.sln @@ -9,7 +9,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalcManager", "CalcManager\ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3A5DF651-B8A1-45CA-9135-964A6FC7F5D1}" ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig nuget.config = nuget.config EndProjectSection EndProject diff --git a/src/Calculator/AboutFlyout.xaml b/src/Calculator/AboutFlyout.xaml index cfce6fbc..c2d82f47 100644 --- a/src/Calculator/AboutFlyout.xaml +++ b/src/Calculator/AboutFlyout.xaml @@ -38,7 +38,7 @@ - + SetVersionString(); Header->Text = resourceLoader.GetResourceString("AboutButton/Content"); + + auto copyrightText = LocalizationStringUtil::GetLocalizedString(resourceLoader.GetResourceString("AboutControlCopyright")->Data(), to_wstring(BUILD_YEAR).c_str()); + AboutControlCopyrightRun->Text = ref new String(copyrightText.c_str()); + } void AboutFlyout::FeedbackButton_Click(_In_ Object^ sender, _In_ RoutedEventArgs^ e) diff --git a/src/Calculator/App.xaml b/src/Calculator/App.xaml index b06b7336..60103662 100644 --- a/src/Calculator/App.xaml +++ b/src/Calculator/App.xaml @@ -371,12 +371,13 @@ - - + - + + + - - + - + + + - - + - + + + false 10.0 black + Always + TemporaryKey.pfx + true + False @@ -126,16 +130,6 @@ - - TemporaryKey.pfx - true - True - False - - - false - Never - /bigobj /await /std:c++17 @@ -257,6 +251,7 @@ + App.xaml @@ -360,7 +355,7 @@ Designer - + @@ -390,6 +385,7 @@ + Create Create @@ -459,142 +455,138 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Calculator/Calculator.vcxproj.filters b/src/Calculator/Calculator.vcxproj.filters index f17fe368..cc25a224 100644 --- a/src/Calculator/Calculator.vcxproj.filters +++ b/src/Calculator/Calculator.vcxproj.filters @@ -308,6 +308,9 @@ Common + + Controls + @@ -407,12 +410,16 @@ Common + + Controls + + diff --git a/src/Calculator/Common/AlwaysSelectedCollectionView.h b/src/Calculator/Common/AlwaysSelectedCollectionView.h index 2cc85101..6e702c79 100644 --- a/src/Calculator/Common/AlwaysSelectedCollectionView.h +++ b/src/Calculator/Common/AlwaysSelectedCollectionView.h @@ -3,9 +3,9 @@ #pragma once -namespace CalculatorApp { namespace Common +namespace CalculatorApp { namespace Common { - ref class AlwaysSelectedCollectionView sealed: + ref class AlwaysSelectedCollectionView sealed: public Windows::UI::Xaml::DependencyObject, public Windows::UI::Xaml::Data::ICollectionView { @@ -14,11 +14,11 @@ namespace CalculatorApp { namespace Common m_currentPosition(-1) { m_source = source; - + Windows::UI::Xaml::Interop::IBindableObservableVector^ observable = dynamic_cast(source); if (observable) { - observable->VectorChanged += + observable->VectorChanged += ref new Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler(this, &AlwaysSelectedCollectionView::OnSourceBindableVectorChanged); } } @@ -53,7 +53,7 @@ namespace CalculatorApp { namespace Common return ref new Platform::Collections::Vector(); } } - property bool HasMoreItems + property bool HasMoreItems { virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::HasMoreItems::get { @@ -77,11 +77,11 @@ namespace CalculatorApp { namespace Common } // The item is not in the collection - // We're going to schedule a call back later so we + // We're going to schedule a call back later so we // restore the selection to the way we wanted it to begin with if (m_currentPosition >= 0 && m_currentPosition < static_cast(m_source->Size)) { - this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, + this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler( [this]() { @@ -161,7 +161,7 @@ namespace CalculatorApp { namespace Common m_currentChanging -= token; } } - + // IVector // Not implemented methods virtual void Append(Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector::Append @@ -219,7 +219,7 @@ namespace CalculatorApp { namespace Common return m_source->Size; } } - + // IObservableVector event Windows::Foundation::Collections::VectorChangedEventHandler^ VectorChanged { @@ -262,9 +262,9 @@ namespace CalculatorApp { namespace Common private: virtual Platform::Object^ Convert( - Platform::Object^ value, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ value, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert { auto result = dynamic_cast(value); @@ -276,9 +276,9 @@ namespace CalculatorApp { namespace Common } virtual Platform::Object^ ConvertBack( - Platform::Object^ /*value*/, - Windows::UI::Xaml::Interop::TypeName /*targetType*/, - Platform::Object^ /*parameter*/, + Platform::Object^ /*value*/, + Windows::UI::Xaml::Interop::TypeName /*targetType*/, + Platform::Object^ /*parameter*/, Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack { return Windows::UI::Xaml::DependencyProperty::UnsetValue; diff --git a/src/Calculator/Common/AppLifecycleLogger.cpp b/src/Calculator/Common/AppLifecycleLogger.cpp index 983deac6..5bfb6141 100644 --- a/src/Calculator/Common/AppLifecycleLogger.cpp +++ b/src/Calculator/Common/AppLifecycleLogger.cpp @@ -37,7 +37,7 @@ namespace CalculatorApp m_appLifecycleProvider( L"Microsoft.Windows.AppLifeCycle", LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), // Microsoft Telemetry group - GUID{ 0xef00584a, 0x2655, 0x462c, 0xbc, 0x24, 0xe7, 0xde, 0x63, 0xe, 0x7f, 0xbf }) //Unique provider ID {EF00584A-2655-462C-BC24-E7DE630E7FBF} + GUID{ 0xef00584a, 0x2655, 0x462c, 0xbc, 0x24, 0xe7, 0xde, 0x63, 0xe, 0x7f, 0xbf }) // Unique provider ID {EF00584A-2655-462C-BC24-E7DE630E7FBF} { } diff --git a/src/Calculator/Common/AppLifecycleLogger.h b/src/Calculator/Common/AppLifecycleLogger.h index d1d88bad..ca7ac65c 100644 --- a/src/Calculator/Common/AppLifecycleLogger.h +++ b/src/Calculator/Common/AppLifecycleLogger.h @@ -29,9 +29,9 @@ namespace CalculatorApp AppLifecycleLogger(); // Any new Log method should - // a) decide the level of logging. This will help us in limiting recording of events only up to a certain level. See this link for guidance https://msdn.microsoft.com/en-us/library/windows/desktop/aa363742(v=vs.85).aspx - // We're using Verbose level for events that are called frequently and needed only for debugging or capturing perf for specific scenarios - // b) should decide whether or not to log to telemetry and pass TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY) accordingly + // a) Decide the level of logging. This will help us in limiting recording of events only up to a certain level. See this link for guidance https://msdn.microsoft.com/en-us/library/windows/desktop/aa363742(v=vs.85).aspx + // We're using Verbose level for events that are called frequently and needed only for debugging or capturing perf for specific scenarios + // b) Should decide whether or not to log to telemetry and pass TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY) accordingly // c) Should accept a variable number of additional data arguments if needed void LogAppLifecycleEvent(winrt::hstring const& eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields const& fields) const; void PopulateAppInfo(winrt::Windows::Foundation::Diagnostics::LoggingFields& fields) const; diff --git a/src/Calculator/Common/BindableBase.cpp b/src/Calculator/Common/BindableBase.cpp index 270e68ac..b1fdcc78 100644 --- a/src/Calculator/Common/BindableBase.cpp +++ b/src/Calculator/Common/BindableBase.cpp @@ -18,17 +18,17 @@ void BindableBase::OnPropertyChanged(String^ propertyName) PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName)); } -Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetCustomProperty(Platform::String^ name) +Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetCustomProperty(Platform::String^ name) { return nullptr; } -Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type) +Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type) { return nullptr; } -Platform::String^ BindableBase::GetStringRepresentation() +Platform::String^ BindableBase::GetStringRepresentation() { - return this->ToString(); + return this->ToString(); } diff --git a/src/Calculator/Controls/CalculationResult.cpp b/src/Calculator/Controls/CalculationResult.cpp index 90563752..f12daff5 100644 --- a/src/Calculator/Controls/CalculationResult.cpp +++ b/src/Calculator/Controls/CalculationResult.cpp @@ -76,7 +76,7 @@ void CalculationResult::OnApplyTemplate() if (m_textContainer) { m_textContainer->SizeChanged += ref new SizeChangedEventHandler(this, &CalculationResult::TextContainerSizeChanged); - // We want to know when the size of the container changes so + // We want to know when the size of the container changes so // we can rescale the textbox m_textContainerLayoutChangedToken = m_textContainer->LayoutUpdated += ref new EventHandler(this, &CalculationResult::OnTextContainerLayoutUpdated); @@ -154,15 +154,15 @@ void CalculationResult::OnIsInErrorPropertyChanged(bool /*oldValue*/, bool newVa if (newValue) { // If there's an error message we need to override the normal display font - // with the font appropriate for this language. This is because the error + // with the font appropriate for this language. This is because the error // message is localized and therefore can contain characters that are not - // available in the normal font. + // available in the normal font. // We use UIText as the font type because this is the most common font type to use m_textBlock->FontFamily = LocalizationService::GetInstance()->GetLanguageFontFamilyForType(LanguageFontType::UIText); } else { - // The error result is no longer an error so we will restore the + // The error result is no longer an error so we will restore the // value to FontFamily property to the value provided in the style // for the TextBlock in the template. m_textBlock->ClearValue(TextBlock::FontFamilyProperty); @@ -175,7 +175,7 @@ void CalculationResult::UpdateVisualState() { VisualStateManager::GoToState(this, "Active", true); } - else + else { VisualStateManager::GoToState(this, "Normal", true); } @@ -192,8 +192,8 @@ void CalculationResult::UpdateTextState() String^ oldText = m_textBlock->Text; String^ newText = Utils::LRO + DisplayValue + Utils::PDF; - //Initiate the scaling operation - //UpdateLayout will keep calling us until we make it through the below 2 if-statements + // Initiate the scaling operation + // UpdateLayout will keep calling us until we make it through the below 2 if-statements if (!m_isScalingText || oldText != newText) { m_textBlock->Text = newText; @@ -210,7 +210,7 @@ void CalculationResult::UpdateTextState() if (widthDiff > WIDTHCUTOFF) { - fontSizeChange = min(max(floor(WIDTHTOFONTSCALAR * widthDiff) - WIDTHTOFONTOFFSET, INCREMENTOFFSET), MAXFONTINCREMENT); + fontSizeChange = min(max(floor(WIDTHTOFONTSCALAR * widthDiff) - WIDTHTOFONTOFFSET, INCREMENTOFFSET), MAXFONTINCREMENT); } if (m_textBlock->ActualWidth < containerSize && abs(m_textBlock->FontSize - m_startingFontSize) > FONTTOLERANCE && !m_haveCalculatedMax) { @@ -329,17 +329,17 @@ void CalculationResult::ShowHideScrollButtons(::Visibility vLeft, ::Visibility v void CalculationResult::UpdateScrollButtons() { // When the width is smaller than the container, don't show any - if (m_textBlock->ActualWidth < m_textContainer->ActualWidth) + if (m_textBlock->ActualWidth < m_textContainer->ActualWidth) { ShowHideScrollButtons(::Visibility::Collapsed, ::Visibility::Collapsed); } // We have more number on both side. Show both arrows - else if (m_textContainer->HorizontalOffset > 0 && m_textContainer->HorizontalOffset < (m_textContainer->ExtentWidth - m_textContainer->ViewportWidth)) + else if (m_textContainer->HorizontalOffset > 0 && m_textContainer->HorizontalOffset < (m_textContainer->ExtentWidth - m_textContainer->ViewportWidth)) { ShowHideScrollButtons(::Visibility::Visible, ::Visibility::Visible); } // Width is larger than the container and left most part of the number is shown. Should be able to scroll left. - else if (m_textContainer->HorizontalOffset == 0) + else if (m_textContainer->HorizontalOffset == 0) { ShowHideScrollButtons(::Visibility::Collapsed, ::Visibility::Visible); } diff --git a/src/Calculator/Controls/CalculatorButton.cpp b/src/Calculator/Controls/CalculatorButton.cpp index 68efc005..abd00b92 100644 --- a/src/Calculator/Controls/CalculatorButton.cpp +++ b/src/Calculator/Controls/CalculatorButton.cpp @@ -54,7 +54,7 @@ void CalculatorButton::OnKeyUp(KeyRoutedEventArgs^ e) } void CalculatorButton::OnButtonIdPropertyChanged( - NumbersAndOperatorsEnum /*oldValue*/, + NumbersAndOperatorsEnum /*oldValue*/, NumbersAndOperatorsEnum newValue) { this->CommandParameter = ref new CalculatorButtonPressedEventArgs(AuditoryFeedback, newValue); diff --git a/src/Calculator/Controls/CalculatorButton.h b/src/Calculator/Controls/CalculatorButton.h index 71c29a9b..daad7382 100644 --- a/src/Calculator/Controls/CalculatorButton.h +++ b/src/Calculator/Controls/CalculatorButton.h @@ -13,7 +13,7 @@ namespace CalculatorApp public ref class CalculatorButton sealed: Windows::UI::Xaml::Controls::Button { public: - + CalculatorButton(); DEPENDENCY_PROPERTY_OWNER(CalculatorButton); diff --git a/src/Calculator/Controls/FlipButtons.cpp b/src/Calculator/Controls/FlipButtons.cpp index cb1d6b34..1ab2b4b9 100644 --- a/src/Calculator/Controls/FlipButtons.cpp +++ b/src/Calculator/Controls/FlipButtons.cpp @@ -43,7 +43,7 @@ void FlipButtons::OnKeyUp(KeyRoutedEventArgs^ e) } void FlipButtons::OnButtonIdPropertyChanged( - NumbersAndOperatorsEnum /*oldValue*/, + NumbersAndOperatorsEnum /*oldValue*/, NumbersAndOperatorsEnum newValue) { this->CommandParameter = newValue; diff --git a/src/Calculator/Controls/FlipButtons.h b/src/Calculator/Controls/FlipButtons.h index ab3ef8e7..67df4057 100644 --- a/src/Calculator/Controls/FlipButtons.h +++ b/src/Calculator/Controls/FlipButtons.h @@ -29,7 +29,7 @@ namespace CalculatorApp private: void OnButtonIdPropertyChanged( - NumbersAndOperatorsEnum oldValue, + NumbersAndOperatorsEnum oldValue, NumbersAndOperatorsEnum newValue); }; } diff --git a/src/Calculator/Controls/HorizontalNoOverflowStackPanel.cpp b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.cpp new file mode 100644 index 00000000..b009bc28 --- /dev/null +++ b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.cpp @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// +// HorizontalNoOverflowStackPanel.xaml.cpp +// Implementation of the HorizontalNoOverflowStackPanel class +// + +#include "pch.h" +#include "HorizontalNoOverflowStackPanel.h" + +using namespace std; +using namespace CalculatorApp::Controls; +using namespace Windows::Foundation; + +Size HorizontalNoOverflowStackPanel::MeasureOverride(Size availableSize) +{ + float maxHeight = 0; + float width = 0; + for (auto child : Children) + { + child->Measure(Size(numeric_limits::infinity(), numeric_limits::infinity())); + maxHeight = max(maxHeight, child->DesiredSize.Height); + width += child->DesiredSize.Width; + } + return Size(min(width, availableSize.Width), min(availableSize.Height, maxHeight)); +} + +bool HorizontalNoOverflowStackPanel::ShouldPrioritizeLastItem() +{ + return false; +} + +Size HorizontalNoOverflowStackPanel::ArrangeOverride(Size finalSize) +{ + if (Children->Size == 0) + { + return finalSize; + } + + float posX = 0; + auto lastChild = Children->GetAt(Children->Size - 1); + float lastChildWidth = 0; + if (Children->Size > 2 && ShouldPrioritizeLastItem()) + { + lastChildWidth = lastChild->DesiredSize.Width; + } + for (auto item : Children) + { + auto widthAvailable = finalSize.Width - posX; + if (item != lastChild) + { + widthAvailable -= lastChildWidth; + } + float itemWidth = item->DesiredSize.Width; + if (widthAvailable > 0 && itemWidth <= widthAvailable) + { + //stack the items horizontally (left to right) + item->Arrange(Rect(posX, 0, itemWidth, finalSize.Height)); + posX += item->RenderSize.Width; + } + else + { + //Not display the item + item->Arrange(Rect(0, 0, 0, 0)); + } + } + return finalSize; +} + diff --git a/src/Calculator/Controls/HorizontalNoOverflowStackPanel.h b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.h new file mode 100644 index 00000000..7619faf4 --- /dev/null +++ b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// +// HorizontalNoOverflowStackPanel.h +// Declaration of the HorizontalNoOverflowStackPanel class +// + +#pragma once +#include "CalcViewModel/Common/Utils.h" + +namespace CalculatorApp +{ + namespace Controls + { + public ref class HorizontalNoOverflowStackPanel : public Windows::UI::Xaml::Controls::Panel + { + DEPENDENCY_PROPERTY_OWNER(HorizontalNoOverflowStackPanel); + //Prioritize the last item over all other items (except the first one) + internal: + HorizontalNoOverflowStackPanel() {} + protected: + virtual Windows::Foundation::Size MeasureOverride(Windows::Foundation::Size availableSize) override; + virtual Windows::Foundation::Size ArrangeOverride(Windows::Foundation::Size finalSize) override; + virtual bool ShouldPrioritizeLastItem(); + }; + } +} diff --git a/src/Calculator/Controls/OperandTextBox.cpp b/src/Calculator/Controls/OperandTextBox.cpp index 3a5224aa..31e814c2 100644 --- a/src/Calculator/Controls/OperandTextBox.cpp +++ b/src/Calculator/Controls/OperandTextBox.cpp @@ -23,7 +23,7 @@ using namespace Windows::UI::Xaml::Media; using namespace Windows::UI::Xaml::Navigation; void OperandTextBox::OnApplyTemplate() -{ +{ this->IsEnabled = false; this->IsHitTestVisible = false; this->IsTapEnabled = false; diff --git a/src/Calculator/Controls/OverflowTextBlock.cpp b/src/Calculator/Controls/OverflowTextBlock.cpp index b5633eaa..85baebc4 100644 --- a/src/Calculator/Controls/OverflowTextBlock.cpp +++ b/src/Calculator/Controls/OverflowTextBlock.cpp @@ -34,22 +34,22 @@ void OverflowTextBlock::OnApplyTemplate() m_expressionContainer = safe_cast(GetTemplateChild("expressionContainer")); m_expressionContainer->ChangeView(m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth, nullptr, nullptr); - + m_scrollLeft = safe_cast(GetTemplateChild("scrollLeft")); m_scrollRight = safe_cast(GetTemplateChild("scrollRight")); - + m_scrollLeftClickEventToken = m_scrollLeft->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick); m_scrollRightClickEventToken = m_scrollRight->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick); m_scrollingLeft = false; m_scrollingRight = false; - + auto borderContainer = safe_cast(GetTemplateChild("expressionborder")); m_pointerEnteredEventToken = borderContainer->PointerEntered += ref new PointerEventHandler(this, &OverflowTextBlock::OnPointerEntered); m_pointerExitedEventToken = borderContainer->PointerExited += ref new PointerEventHandler(this, &OverflowTextBlock::OnPointerExited); m_listView = safe_cast(GetTemplateChild("TokenList")); - + UpdateAllState(); } diff --git a/src/Calculator/Controls/OverflowTextBlock.h b/src/Calculator/Controls/OverflowTextBlock.h index 1fe3dd95..13b2e828 100644 --- a/src/Calculator/Controls/OverflowTextBlock.h +++ b/src/Calculator/Controls/OverflowTextBlock.h @@ -12,7 +12,7 @@ namespace CalculatorApp public ref class OverflowTextBlock sealed : public Windows::UI::Xaml::Controls::Control { public: - OverflowTextBlock() + OverflowTextBlock() { } diff --git a/src/Calculator/Controls/SupplementaryItemsControl.cpp b/src/Calculator/Controls/SupplementaryItemsControl.cpp index d5bc00a4..665c1d16 100644 --- a/src/Calculator/Controls/SupplementaryItemsControl.cpp +++ b/src/Calculator/Controls/SupplementaryItemsControl.cpp @@ -38,5 +38,3 @@ void SupplementaryItemsControl::PrepareContainerForItemOverride(DependencyObject { return ref new SupplementaryContentPresenterAP(this); } - - diff --git a/src/Calculator/Converters/BooleanToVisibilityConverter.h b/src/Calculator/Converters/BooleanToVisibilityConverter.h index 4ee40701..3c31e61c 100644 --- a/src/Calculator/Converters/BooleanToVisibilityConverter.h +++ b/src/Calculator/Converters/BooleanToVisibilityConverter.h @@ -16,7 +16,7 @@ namespace CalculatorApp public: static constexpr Windows::UI::Xaml::Visibility Convert(bool visibility) { - return visibility + return visibility ? Windows::UI::Xaml::Visibility::Visible : Windows::UI::Xaml::Visibility::Collapsed; } diff --git a/src/Calculator/Resources/af-ZA/Resources.resw b/src/Calculator/Resources/af-ZA/Resources.resw index 1e563e89..03914db2 100644 --- a/src/Calculator/Resources/af-ZA/Resources.resw +++ b/src/Calculator/Resources/af-ZA/Resources.resw @@ -119,15 +119,27 @@ Sakrekenaar - {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store. + + + Sakrekenaar [Dev] + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the name of the application when built by a user via GitHub. We use a different name to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Windows-Sakrekenaar {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. + + Windows-Sakrekenaar [Dev] + {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. This is the the version of the name used when the app is built by a user via GitHub. + Sakrekenaar - {@Appx_Description@} + {@Appx_Description@} This description is used for the official application when published through Windows Store. + + + Sakrekenaar [Dev] + {@Appx_Description@} This is the description of the application when built by a user via GitHub. We use a different description to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Kopieer @@ -2265,9 +2277,9 @@ Microsoft-Privaatheidstelling Displayed on a link to the Microsoft Privacy Statement on the About panel - - © 2018 Microsoft. Alle regte voorbehou. - Copyright statement, displayed on the About panel + + © %1 Microsoft. Alle regte voorbehou. + {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) Inligting oor @@ -2601,7 +2613,7 @@ x of - Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronounciation. + Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronunciation. en diff --git a/src/Calculator/Resources/am-ET/Resources.resw b/src/Calculator/Resources/am-ET/Resources.resw index 476e41bd..bf5de965 100644 --- a/src/Calculator/Resources/am-ET/Resources.resw +++ b/src/Calculator/Resources/am-ET/Resources.resw @@ -119,15 +119,27 @@ ማስሊያ - {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store. + + + ማስሊያ [Dev] + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the name of the application when built by a user via GitHub. We use a different name to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Windows ማስሊያ {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. + + Windows ማስሊያ [Dev] + {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. This is the the version of the name used when the app is built by a user via GitHub. + ማስሊያ - {@Appx_Description@} + {@Appx_Description@} This description is used for the official application when published through Windows Store. + + + ማስሊያ [Dev] + {@Appx_Description@} This is the description of the application when built by a user via GitHub. We use a different description to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. ቅዳ @@ -918,7 +930,7 @@ Screen reader prompt for the Calculator cos button on the scientific operator keypad - ሰያፍ + ሰዓት Screen reader prompt for the Calculator tan button on the scientific operator keypad @@ -1082,7 +1094,7 @@ Unit conversion category name called Power (eg. the power of an engine or a light bulb) - ቶሎታ + ፍጥነት Unit conversion category name called Speed @@ -1090,7 +1102,7 @@ Unit conversion category name called Time - ድምጽ መጠን + የድምጽ መጠን Unit conversion category name called Volume (eg. cups, teaspoons, milliliters) @@ -2265,9 +2277,9 @@ የ Microsoft ግላዊነት መግለጫ Displayed on a link to the Microsoft Privacy Statement on the About panel - - © 2018 Microsoft. ሁሉም መብቱ የተጠበቀ። - Copyright statement, displayed on the About panel + + © %1 Microsoft. ሁሉም መብቱ የተጠበቀ። + {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) ስለ @@ -2601,7 +2613,7 @@ x ወይም - Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronounciation. + Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronunciation. እና @@ -2616,7 +2628,7 @@ The timestamp of currency conversion ratios fetched from an online service. %1 is the date. %2 is the time. Example: "Updated Sep 28, 2016 5:42 PM" - የዝማኔ ክፍያዎች + የዝማኔ ፍጥነቶች The text displayed for a hyperlink button that refreshes currency converter ratios. @@ -2688,11 +2700,11 @@ AccessKey for the currency converter navbar item. {StringCategory="Accelerator"} - + D AccessKey for the data converter navbar item. {StringCategory="Accelerator"} - + E AccessKey for the energy converter navbar item. {StringCategory="Accelerator"} @@ -2708,7 +2720,7 @@ AccessKey for the pressure converter navbar item. {StringCategory="Accelerator"} - + S AccessKey for the speed converter navbar item. {StringCategory="Accelerator"} @@ -2716,7 +2728,7 @@ AccessKey for the time converter navbar item. {StringCategory="Accelerator"} - ድመ + AccessKey for the volume converter navbar item. {StringCategory="Accelerator"} @@ -2728,7 +2740,7 @@ AccessKey for the temperature converter navbar item. {StringCategory="Accelerator"} - አጽ + C Access key for the Clear history button.{StringCategory="Accelerator"} diff --git a/src/Calculator/Resources/ar-SA/Resources.resw b/src/Calculator/Resources/ar-SA/Resources.resw index aab109b7..296f7952 100644 --- a/src/Calculator/Resources/ar-SA/Resources.resw +++ b/src/Calculator/Resources/ar-SA/Resources.resw @@ -119,15 +119,27 @@ الحاسبة - {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store. + + + الحاسبة [Dev] + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the name of the application when built by a user via GitHub. We use a different name to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. الحاسبة في Windows {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. + + الحاسبة في Windows [Dev] + {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. This is the the version of the name used when the app is built by a user via GitHub. + الحاسبة - {@Appx_Description@} + {@Appx_Description@} This description is used for the official application when published through Windows Store. + + + الحاسبة [Dev] + {@Appx_Description@} This is the description of the application when built by a user via GitHub. We use a different description to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. نسخ @@ -2266,9 +2278,9 @@ بيان الخصوصية الخاص بشركة Microsoft Displayed on a link to the Microsoft Privacy Statement on the About panel - - © 2018 Microsoft. جميع الحقوق محفوظة. - Copyright statement, displayed on the About panel + + © %1 Microsoft. جميع الحقوق محفوظة. + {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) حول @@ -2602,7 +2614,7 @@ x or - Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronounciation. + Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronunciation. و diff --git a/src/Calculator/Resources/az-Latn-AZ/CEngineStrings.resw b/src/Calculator/Resources/az-Latn-AZ/CEngineStrings.resw index 9c66f216..6fefcd56 100644 --- a/src/Calculator/Resources/az-Latn-AZ/CEngineStrings.resw +++ b/src/Calculator/Resources/az-Latn-AZ/CEngineStrings.resw @@ -150,7 +150,7 @@ Same 107 - Sıfırla bölmək mümkün deyil + Sıfra bölmək mümkün deyil Error string shown when a divide by zero condition happens during the calculation \ No newline at end of file diff --git a/src/Calculator/Resources/az-Latn-AZ/Resources.resw b/src/Calculator/Resources/az-Latn-AZ/Resources.resw index 32a24559..8cdfe566 100644 --- a/src/Calculator/Resources/az-Latn-AZ/Resources.resw +++ b/src/Calculator/Resources/az-Latn-AZ/Resources.resw @@ -119,15 +119,27 @@ Kalkulyator - {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store. + + + Kalkulyator [Dev] + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the name of the application when built by a user via GitHub. We use a different name to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Windows Kalkulyator {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. + + Windows Kalkulyator [Dev] + {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. This is the the version of the name used when the app is built by a user via GitHub. + Kalkulyator - {@Appx_Description@} + {@Appx_Description@} This description is used for the official application when published through Windows Store. + + + Kalkulyator [Dev] + {@Appx_Description@} This is the description of the application when built by a user via GitHub. We use a different description to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Köçür @@ -2265,9 +2277,9 @@ Microsoft Məxfilik Bildirişi Displayed on a link to the Microsoft Privacy Statement on the About panel - - © 2018 Microsoft. Bütün hüquqlar qorunur. - Copyright statement, displayed on the About panel + + © %1 Microsoft. Bütün hüquqlar qorunur. + {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) Haqqında @@ -2601,7 +2613,7 @@ x, yaxud - Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronounciation. + Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronunciation. diff --git a/src/Calculator/Resources/be-BY/Resources.resw b/src/Calculator/Resources/be-BY/Resources.resw index d5f0cd53..bb36bc97 100644 --- a/src/Calculator/Resources/be-BY/Resources.resw +++ b/src/Calculator/Resources/be-BY/Resources.resw @@ -119,15 +119,27 @@ Калькулятар - {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store. + + + Калькулятар [Dev] + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the name of the application when built by a user via GitHub. We use a different name to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Калькулятар Windows {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. + + Калькулятар Windows [Dev] + {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. This is the the version of the name used when the app is built by a user via GitHub. + Калькулятар - {@Appx_Description@} + {@Appx_Description@} This description is used for the official application when published through Windows Store. + + + Калькулятар [Dev] + {@Appx_Description@} This is the description of the application when built by a user via GitHub. We use a different description to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Капіяваць @@ -2265,9 +2277,9 @@ Заява аб канфідэнцыйнасці Microsoft Displayed on a link to the Microsoft Privacy Statement on the About panel - - © Microsoft, 2018. Усе правы абароненыя. - Copyright statement, displayed on the About panel + + © Microsoft, %1. Усе правы абароненыя. + {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) Інфармацыя @@ -2601,7 +2613,7 @@ выключальнае або - Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronounciation. + Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronunciation. пабітавае і @@ -2616,7 +2628,7 @@ The timestamp of currency conversion ratios fetched from an online service. %1 is the date. %2 is the time. Example: "Updated Sep 28, 2016 5:42 PM" - Абнавіць курсы + Абнавіць тарыфы The text displayed for a hyperlink button that refreshes currency converter ratios. @@ -2887,4 +2899,4 @@ Пагадненне аб выкарыстанні сэрвісаў Microsoft Displayed on a link to the Microsoft Services Agreement in the about this app information - \ No newline at end of file + diff --git a/src/Calculator/Resources/bg-BG/Resources.resw b/src/Calculator/Resources/bg-BG/Resources.resw index 3ef8f7fe..676ee4d4 100644 --- a/src/Calculator/Resources/bg-BG/Resources.resw +++ b/src/Calculator/Resources/bg-BG/Resources.resw @@ -119,15 +119,27 @@ Калкулатор - {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store. + + + Калкулатор [Dev] + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the name of the application when built by a user via GitHub. We use a different name to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Калкулатор на Windows {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. + + Калкулатор на Windows [Dev] + {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. This is the the version of the name used when the app is built by a user via GitHub. + Калкулатор - {@Appx_Description@} + {@Appx_Description@} This description is used for the official application when published through Windows Store. + + + Калкулатор [Dev] + {@Appx_Description@} This is the description of the application when built by a user via GitHub. We use a different description to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Копиране @@ -2265,9 +2277,9 @@ Декларация за поверителност на Microsoft Displayed on a link to the Microsoft Privacy Statement on the About panel - - © 2018 Microsoft. Всички права запазени. - Copyright statement, displayed on the About panel + + © %1 Microsoft. Всички права запазени. + {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) Относно @@ -2601,7 +2613,7 @@ x или - Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronounciation. + Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronunciation. и diff --git a/src/Calculator/Resources/bn-BD/Resources.resw b/src/Calculator/Resources/bn-BD/Resources.resw index 3dec2e26..2836bc7a 100644 --- a/src/Calculator/Resources/bn-BD/Resources.resw +++ b/src/Calculator/Resources/bn-BD/Resources.resw @@ -119,15 +119,27 @@ ক্যালকুলেটর - {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store. + + + ক্যালকুলেটর [Dev] + {@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the name of the application when built by a user via GitHub. We use a different name to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. Windows ক্যালকুলেটর {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. + + Windows ক্যালকুলেটর [Dev] + {@Appx_DisplayName@}{StringCategory="Feature Title"} Name that shows up in the app store. It contains "Windows" to distinguish it from 3rd party calculator apps. This is the the version of the name used when the app is built by a user via GitHub. + ক্যালকুলেটর - {@Appx_Description@} + {@Appx_Description@} This description is used for the official application when published through Windows Store. + + + ক্যালকুলেটর [Dev] + {@Appx_Description@} This is the description of the application when built by a user via GitHub. We use a different description to make it easier for users to distinguish the apps when both this version and the Store version are installed on the same device. প্রতিলিপি @@ -2265,9 +2277,9 @@ Microsoft গোপনীয়তার বিবৃতি Displayed on a link to the Microsoft Privacy Statement on the About panel - - © 2018 Microsoft. সর্বস্বত্ব সংরক্ষিত। - Copyright statement, displayed on the About panel + + © %1 Microsoft. সর্বস্বত্ব সংরক্ষিত। + {Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits) বিষয়ক @@ -2601,7 +2613,7 @@ x বা - Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronounciation. + Auditory feedback for Screen Reader users. Users will hear "Display is 7 x or" when the button is pressed. XOR is a mathematical operation on two binary values. Here the feedback is "x or" in order to get the correct pronunciation. এবং @@ -2616,7 +2628,7 @@ The timestamp of currency conversion ratios fetched from an online service. %1 is the date. %2 is the time. Example: "Updated Sep 28, 2016 5:42 PM" - হালনাগাদ হার + হালনাগাদের হার The text displayed for a hyperlink button that refreshes currency converter ratios. diff --git a/src/Calculator/Resources/ca-ES/Resources.resw b/src/Calculator/Resources/ca-ES/Resources.resw index 6e9fd54f..63e2b9a5 100644 --- a/src/Calculator/Resources/ca-ES/Resources.resw +++ b/src/Calculator/Resources/ca-ES/Resources.resw @@ -1,4 +1,4 @@ - + - + @@ -102,6 +102,6 @@ Style="{ThemeResource SupplementaryValuesStyle}" IsTextScaleFactorEnabled="False" ItemTemplateSelector="{StaticResource ResultTemplateSelector}" - LayoutUpdated="OnSupplementaryValuesLayoutUpdated"/> + ItemsSource="{x:Bind Results, Mode=OneWay}"/> diff --git a/src/Calculator/Views/SupplementaryResults.xaml.cpp b/src/Calculator/Views/SupplementaryResults.xaml.cpp index d598ae93..06c83600 100644 --- a/src/Calculator/Views/SupplementaryResults.xaml.cpp +++ b/src/Calculator/Views/SupplementaryResults.xaml.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // @@ -27,6 +27,8 @@ using namespace Windows::UI::Xaml::Navigation; // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 +DEPENDENCY_PROPERTY_INITIALIZATION(SupplementaryResults, Results); + Object^ DelighterUnitToStyleConverter::Convert(Object^ value, TypeName /*targetType*/, Object^ /*parameter*/, String^ /*language*/) { Unit^ unit = safe_cast(value); @@ -62,74 +64,22 @@ Windows::UI::Xaml::DataTemplate^ SupplementaryResultDataTemplateSelector::Select } } -SupplementaryResults::SupplementaryResults() : - m_data(ref new Vector) +SupplementaryResults::SupplementaryResults() { InitializeComponent(); - - this->Loaded += ref new RoutedEventHandler(this, &SupplementaryResults::OnLoaded); } -void SupplementaryResults::RefreshData() +bool SupplementaryResultNoOverflowStackPanel::ShouldPrioritizeLastItem() { - // Copy the list so that when we chop stuff off, we don't modify the original - // complete list. - m_data->Clear(); - for(SupplementaryResult^ sr : safe_cast(this->DataContext)->SupplementaryResults) + if (Children->Size == 0) { - m_data->Append(sr); + return false; } - - // Set as source - SupplementaryValues->ItemsSource = m_data; -} - -void SupplementaryResults::OnLoaded(Object^ sender, RoutedEventArgs^ e) -{ - UnitConverterViewModel^ vm = safe_cast(this->DataContext); - vm->PropertyChanged += ref new PropertyChangedEventHandler(this, &SupplementaryResults::OnConverterPropertyChanged); - Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &SupplementaryResults::OnWindowSizeChanged); - // We may be loaded into a state where we need to render (like rehydrate), so prepare data - RefreshData(); -} - -void SupplementaryResults::OnConverterPropertyChanged(Object^ /*sender*/, PropertyChangedEventArgs^ e) -{ - if (e->PropertyName == UnitConverterViewModelProperties::SupplementaryResults) + auto lastChild = dynamic_cast(Children->GetAt(Children->Size - 1)); + if (lastChild == nullptr) { - RefreshData(); - } -} - -void SupplementaryResults::OnWindowSizeChanged(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e) -{ - // to reload supplementary results every time the window is resized - RefreshData(); -} - -void SupplementaryResults::OnSupplementaryValuesLayoutUpdated(Platform::Object^ sender, Platform::Object^ e) -{ - // This means we overflowed and are cutting off, or in a very rare case we fit exactly. Unfortunately - // the fitting exactly case will still have an item removed, as there is no other way for us to - // detect that we need to trim. - Grid^ parentGrid = dynamic_cast(VisualTreeHelper::GetParent(this)); - if (parentGrid != nullptr) - { - double parentWidth = parentGrid->ActualWidth; - if (SupplementaryValues && SupplementaryValues->ActualWidth >= parentWidth) - { - if (m_data->Size > 0) - { - SupplementaryResult^ last = m_data->GetAt(m_data->Size - 1); - if (!last->IsWhimsical() || m_data->Size <= 2) - { - m_data->RemoveAtEnd(); - } - else - { - m_data->RemoveAt(m_data->Size - 2); - } - } - } + return false; } + auto suppResult = dynamic_cast(lastChild->DataContext); + return suppResult == nullptr? false: suppResult->IsWhimsical(); } diff --git a/src/Calculator/Views/SupplementaryResults.xaml.h b/src/Calculator/Views/SupplementaryResults.xaml.h index 1d94b0ab..a0be9e03 100644 --- a/src/Calculator/Views/SupplementaryResults.xaml.h +++ b/src/Calculator/Views/SupplementaryResults.xaml.h @@ -12,6 +12,7 @@ #include "Controls/SupplementaryItemsControl.h" #include "Controls/OperandTextBox.h" #include "Controls/OperatorTextBox.h" +#include "Controls/HorizontalNoOverflowStackPanel.h" #include "CalcViewModel/UnitConverterViewModel.h" namespace CalculatorApp @@ -58,18 +59,18 @@ namespace CalculatorApp Windows::UI::Xaml::DataTemplate^ m_delighterTemplate; }; + public ref class SupplementaryResultNoOverflowStackPanel sealed: public CalculatorApp::Controls::HorizontalNoOverflowStackPanel + { + protected: + virtual bool ShouldPrioritizeLastItem() override; + }; + [Windows::Foundation::Metadata::WebHostHidden] public ref class SupplementaryResults sealed { public: SupplementaryResults(); - - private: - void RefreshData(); - void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void OnConverterPropertyChanged(Platform::Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e); - void OnSupplementaryValuesLayoutUpdated(Platform::Object^ sender, Platform::Object^ e); - void OnWindowSizeChanged(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e); - Windows::Foundation::Collections::IObservableVector^ m_data; + DEPENDENCY_PROPERTY_OWNER(SupplementaryResults); + DEPENDENCY_PROPERTY_WITH_DEFAULT(Windows::Foundation::Collections::IIterable^, Results, nullptr); }; } diff --git a/src/Calculator/Views/UnitConverter.xaml b/src/Calculator/Views/UnitConverter.xaml index 7afc660d..e21dd503 100644 --- a/src/Calculator/Views/UnitConverter.xaml +++ b/src/Calculator/Views/UnitConverter.xaml @@ -1,4 +1,4 @@ - - +