Merge pull request #4 from Microsoft/master

Merge with master
This commit is contained in:
Pepe Rivera 2019-04-26 15:52:58 -07:00 committed by GitHub
commit 869cfface1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
196 changed files with 2074 additions and 2308 deletions

23
.gitattributes vendored
View file

@ -12,29 +12,6 @@
############################################################################### ###############################################################################
*.cs diff=csharp *.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
*.sln merge=binary
*.csproj merge=binary
*.vbproj merge=binary
*.vcxproj merge=binary
*.vcproj merge=binary
*.dbproj merge=binary
*.fsproj merge=binary
*.lsproj merge=binary
*.wixproj merge=binary
*.modelproj merge=binary
*.sqlproj merge=binary
*.wwaproj merge=binary
############################################################################### ###############################################################################
# behavior for image files # behavior for image files
# #

1
.gitignore vendored
View file

@ -289,6 +289,7 @@ __pycache__/
# Calculator specific # Calculator specific
Generated Files/ Generated Files/
src/GraphControl/GraphingImplOverrides.props
!/build/config/TRexDefs/** !/build/config/TRexDefs/**
!src/Calculator/TemporaryKey.pfx !src/Calculator/TemporaryKey.pfx
!src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx !src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx

View file

@ -16,6 +16,9 @@ Calculator ships regularly with new features and bug fixes. You can get the late
- Calculation history and memory capabilities. - Calculation history and memory capabilities.
- Conversion between many units of measurement. - Conversion between many units of measurement.
- Currency conversion based on data retrieved from [Bing](https://www.bing.com). - Currency conversion based on data retrieved from [Bing](https://www.bing.com).
- [Infinite precision](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic) for basic
arithmetic operations (addition, subtraction, multiplication, division) so that calculations
never lose precision.
## Getting started ## Getting started
Prerequisites: Prerequisites:

View file

@ -1,5 +1,5 @@
<SignConfigXML> <SignConfigXML>
<job platform="" configuration="" certSubject="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" jobname="EngFunSimpleSign" approvers="gstolt;vigarg"> <job platform="" configuration="" certSubject="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" jobname="EngFunSimpleSign" approvers="">
<file src="__INPATHROOT__\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle" signType="136020001" dest="__OUTPATHROOT__\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle" /> <file src="__INPATHROOT__\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle" signType="136020001" dest="__OUTPATHROOT__\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle" />
</job> </job>
</SignConfigXML> </SignConfigXML>

View file

@ -33,6 +33,10 @@ jobs:
platform: ARM64 platform: ARM64
condition: not(eq(variables['Build.Reason'], 'PullRequest')) condition: not(eq(variables['Build.Reason'], 'PullRequest'))
- template: ./templates/run-ui-tests.yaml
parameters:
platform: x64
- template: ./templates/run-unit-tests.yaml - template: ./templates/run-unit-tests.yaml
parameters: parameters:
platform: x64 platform: x64

View file

@ -30,7 +30,7 @@ steps:
inputs: inputs:
solution: src/Calculator.sln solution: src/Calculator.sln
vsVersion: 15.0 vsVersion: 15.0
msbuildArgs: /bl:$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator.binlog /p:OutDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\ /p:GenerateProjectSpecificOutputFolder=true /p:AppVersion=$(Build.BuildNumber) ${{ parameters.extraMsBuildArgs }} msbuildArgs: /bl:$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator.binlog /p:OutDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\ /p:GenerateProjectSpecificOutputFolder=true /p:AppVersion=$(Build.BuildNumber) /t:Publish /p:PublishDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\publish\ ${{ parameters.extraMsBuildArgs }}
platform: $(BuildPlatform) platform: $(BuildPlatform)
configuration: $(BuildConfiguration) configuration: $(BuildConfiguration)
clean: true clean: true

View file

@ -1,5 +1,5 @@
# This template contains a job which builds artifacts needed to release the app to the store and to # This template contains a job which builds artifacts needed to release the app to the store and to
# Windows using Microsoft-internal systems. It relies Microsoft-internal resources and will not # Windows using Microsoft-internal systems. It relies on Microsoft-internal resources and will not
# work outside of Microsoft. # work outside of Microsoft.
# Specifically, this job: # Specifically, this job:
# - Signs the bundle using a secure system. If you want to build your own, use SignTool following # - Signs the bundle using a secure system. If you want to build your own, use SignTool following
@ -28,8 +28,8 @@ jobs:
- task: PkgESSetupBuild@10 - task: PkgESSetupBuild@10
displayName: Initialize Package ES displayName: Initialize Package ES
inputs: inputs:
productName: Calculator productName: Calculator
disableWorkspace: true disableWorkspace: true
env: env:
XES_DISABLEPROV: true XES_DISABLEPROV: true
@ -46,6 +46,8 @@ jobs:
- task: PkgESCodeSign@10 - task: PkgESCodeSign@10
displayName: Send bundle to Package ES code signing service displayName: Send bundle to Package ES code signing service
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs: inputs:
signConfigXml: build\config\SignConfig.xml signConfigXml: build\config\SignConfig.xml
inPathRoot: $(Build.ArtifactStagingDirectory)\appxBundle inPathRoot: $(Build.ArtifactStagingDirectory)\appxBundle
@ -60,25 +62,25 @@ jobs:
- task: CopyFiles@2 - task: CopyFiles@2
displayName: Copy signed AppxBundle to vpack staging folder displayName: Copy signed AppxBundle to vpack staging folder
inputs: inputs:
sourceFolder: $(Build.ArtifactStagingDirectory)\appxBundleSigned sourceFolder: $(Build.ArtifactStagingDirectory)\appxBundleSigned
targetFolder: $(Build.ArtifactStagingDirectory)\vpack\appxBundle targetFolder: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
- task: PkgESVPack@10 - task: PkgESVPack@10
displayName: Create and push vpack for app displayName: Create and push vpack for app
env: env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken) SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs: inputs:
sourceDirectory: $(Build.ArtifactStagingDirectory)\vpack\appxBundle sourceDirectory: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
description: VPack for the Calculator Application description: VPack for the Calculator Application
pushPkgName: calculator.app pushPkgName: calculator.app
version: $(versionMajor).$(versionMinor).$(versionBuild) version: $(versionMajor).$(versionMinor).$(versionBuild)
owner: paxeeapps owner: paxeeapps
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1
displayName: Publish vpack\app artifact with vpack manifest displayName: Publish vpack\app artifact with vpack manifest
inputs: inputs:
pathtoPublish: $(XES_VPACKMANIFESTDIRECTORY)\$(XES_VPACKMANIFESTNAME) pathtoPublish: $(XES_VPACKMANIFESTDIRECTORY)\$(XES_VPACKMANIFESTNAME)
artifactName: vpack\app artifactName: vpack\app
# TODO (macool): create and push internal test packages and test config # TODO (macool): create and push internal test packages and test config

View file

@ -0,0 +1,52 @@
# This template contains jobs to run UI tests using WinAppDriver.
parameters:
platform: ''
jobs:
- job: UITests${{ parameters.platform }}
displayName: UITests ${{ parameters.platform }}
dependsOn: Build${{ parameters.platform }}
condition: succeeded()
pool:
vmImage: windows-2019
variables:
skipComponentGovernanceDetection: true
steps:
- checkout: none
- powershell: Set-DisplayResolution -Width 1920 -Height 1080 -Force
displayName: Set resolution to 1920x1080
continueOnError: true
- task: DownloadBuildArtifacts@0
displayName: Download AppxBundle and CalculatorUITests
inputs:
artifactName: drop
itemPattern: |
drop/Release/${{ parameters.platform }}/Calculator/AppPackages/**
drop/Release/${{ parameters.platform }}/publish/**
- task: PowerShell@2
displayName: Install certificate
inputs:
filePath: $(Build.ArtifactStagingDirectory)/drop/Release/${{ parameters.platform }}/Calculator/AppPackages/Calculator_$(Build.BuildNumber)_Test/Add-AppDevPackage.ps1
arguments: -CertificatePath $(Build.ArtifactStagingDirectory)/drop/Release/${{ parameters.platform }}/Calculator/AppPackages/Calculator_$(Build.BuildNumber)_Test/Calculator_$(Build.BuildNumber)_${{ parameters.platform }}.cer -Force
- task: PowerShell@2
displayName: Install app
inputs:
filePath: $(Build.ArtifactStagingDirectory)/drop/Release/${{ parameters.platform }}/Calculator/AppPackages/Calculator_$(Build.BuildNumber)_Test/Add-AppDevPackage.ps1
arguments: -Force
- powershell: Start-Process -FilePath "C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe" -Verb RunAs
displayName: Start WinAppDriver
- task: VSTest@2
displayName: Run CalculatorUITests
inputs:
testAssemblyVer2: $(Build.ArtifactStagingDirectory)/drop/Release/${{ parameters.platform }}/publish/CalculatorUITests.dll
vsTestVersion: 16.0
runSettingsFile: $(Build.ArtifactStagingDirectory)/drop/Release/${{ parameters.platform }}/publish/CalculatorUITests.runsettings
platform: ${{ parameters.platform }}
configuration: Release

View file

@ -153,7 +153,9 @@ The CalcEngine contains the logic for interpreting and performing operations acc
### RatPack ### RatPack
The RatPack (short for Rational Pack) is the core of the Calculator model and contains the logic for performing its mathematical operations. The interface to this layer is defined in [ratpak.h][ratpak.h]. The RatPack (short for Rational Pack) is the core of the Calculator model and contains the logic for
performing its mathematical operations (using [infinite precision][Infinite Precision] arithmetic
instead of regular floating point arithmetic). The interface to this layer is defined in [ratpak.h][ratpak.h].
[References]:#################################################################################################### [References]:####################################################################################################

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <sstream>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace std; using namespace std;

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h" #include "Header Files/CalcUtils.h"

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Command.h" #include "Command.h"
#include "CalculatorVector.h" #include "CalculatorVector.h"

View file

@ -1,6 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
#include "pch.h" #include <algorithm>
#include "Header Files/Number.h" #include "Header Files/Number.h"
using namespace std; using namespace std;

View file

@ -1,6 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
#include "pch.h" #include <intsafe.h>
#include "Header Files/Rational.h" #include "Header Files/Rational.h"
using namespace std; using namespace std;
@ -182,6 +182,13 @@ namespace CalcEngine
return *this; return *this;
} }
/// <summary>
/// Calculate the remainder after division, the sign of a result will match the sign of the current object.
/// </summary>
/// <remarks>
/// This function has the same behavior as the standard C/C++ operator '%'
/// to calculate the modulus after division instead, use <see cref="RationalMath::Mod"/> instead.
/// </remarks>
Rational& Rational::operator%=(Rational const& rhs) Rational& Rational::operator%=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
@ -189,7 +196,7 @@ namespace CalcEngine
try try
{ {
modrat(&lhsRat, rhsRat); remrat(&lhsRat, rhsRat);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (uint32_t error) catch (uint32_t error)
@ -342,6 +349,12 @@ namespace CalcEngine
return lhs; return lhs;
} }
/// <summary>
/// Calculate the remainder after division, the sign of a result will match the sign of lhs.
/// </summary>
/// <remarks>
/// This function has the same behavior as the standard C/C++ operator '%', to calculate the modulus after division instead, use <see cref="Rational::operator%"/> instead.
/// </remarks>
Rational operator%(Rational lhs, Rational const& rhs) Rational operator%(Rational lhs, Rational const& rhs)
{ {
lhs %= rhs; lhs %= rhs;

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/RationalMath.h" #include "Header Files/RationalMath.h"
using namespace std; using namespace std;
@ -387,3 +386,33 @@ Rational RationalMath::ATanh(Rational const& rat)
return result; return result;
} }
/// <summary>
/// Calculate the modulus after division, the sign of the result will match the sign of b.
/// </summary>
/// <remarks>
/// When one of the operand is negative
/// the result will differ from the C/C++ operator '%'
/// use <see cref="Rational::operator%"/> instead to calculate the remainder after division.
/// </remarks>
Rational RationalMath::Mod(Rational const& a, Rational const& b)
{
PRAT prat = a.ToPRAT();
PRAT pn = b.ToPRAT();
try
{
modrat(&prat, pn);
destroyrat(pn);
}
catch (uint32_t error)
{
destroyrat(prat);
destroyrat(pn);
throw(error);
}
auto res = Rational{ prat };
destroyrat(prat);
return res;
}

View file

@ -1,9 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <cassert>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "CalculatorResource.h" #include "CalculatorResource.h"
using namespace std; using namespace std;

View file

@ -12,7 +12,8 @@
* *
* Author: * Author:
\****************************************************************************/ \****************************************************************************/
#include "pch.h"
#include <string>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h" #include "Header Files/CalcUtils.h"
@ -390,7 +391,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
cleared for CENTR */ cleared for CENTR */
if (nullptr != m_pCalcDisplay) if (nullptr != m_pCalcDisplay)
{ {
m_pCalcDisplay->SetParenDisplayText(L""); m_pCalcDisplay->SetParenthesisNumber(0);
m_pCalcDisplay->SetExpressionDisplay(make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>()); m_pCalcDisplay->SetExpressionDisplay(make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>());
} }
@ -594,7 +595,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
// Set the "(=xx" indicator. // Set the "(=xx" indicator.
if (nullptr != m_pCalcDisplay) if (nullptr != m_pCalcDisplay)
{ {
m_pCalcDisplay->SetParenDisplayText(m_openParenCount ? to_wstring(m_openParenCount) : L""); m_pCalcDisplay->SetParenthesisNumber(m_openParenCount >= 0 ? static_cast<unsigned int>(m_openParenCount) : 0);
} }
if (!m_bError) if (!m_bError)

View file

@ -12,7 +12,9 @@
* *
* Author: * Author:
\****************************************************************************/ \****************************************************************************/
#include "pch.h"
#include <sstream>
#include <regex>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace std; using namespace std;

View file

@ -16,7 +16,6 @@
/*** ***/ /*** ***/
/*** ***/ /*** ***/
/**************************************************************************/ /**************************************************************************/
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace std; using namespace std;

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace CalcEngine; using namespace CalcEngine;
@ -78,7 +77,7 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
case IDC_DIV: case IDC_DIV:
case IDC_MOD: case IDC_MOD:
{ {
int iNumeratorSign = 1, iDenominatorSign = 1, iFinalSign = 1; int iNumeratorSign = 1, iDenominatorSign = 1;
auto temp = result; auto temp = result;
result = rhs; result = rhs;
@ -107,20 +106,30 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
if (operation == IDC_DIV) if (operation == IDC_DIV)
{ {
iFinalSign = iNumeratorSign * iDenominatorSign;
result /= temp; result /= temp;
if (m_fIntegerMode && (iNumeratorSign * iDenominatorSign) == -1)
{
result = -(Integer(result));
}
} }
else else
{ {
iFinalSign = iNumeratorSign; if (m_fIntegerMode)
result %= temp; {
} // Programmer mode, use remrat (remainder after division)
result %= temp;
if (m_fIntegerMode && iFinalSign == -1) if (iNumeratorSign == -1)
{ {
result = -(Integer(result)); result = -(Integer(result));
}
}
else
{
//other modes, use modrat (modulus after division)
result = Mod(result, temp);
}
} }
break; break;
} }

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace CalcEngine; using namespace CalcEngine;

View file

@ -157,6 +157,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -173,6 +174,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -189,6 +191,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -205,6 +208,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -222,6 +226,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -238,6 +243,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -254,6 +260,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -270,6 +277,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -278,7 +286,6 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="CalcException.h" />
<ClInclude Include="CalculatorHistory.h" /> <ClInclude Include="CalculatorHistory.h" />
<ClInclude Include="CalculatorManager.h" /> <ClInclude Include="CalculatorManager.h" />
<ClInclude Include="CalculatorResource.h" /> <ClInclude Include="CalculatorResource.h" />

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <cassert>
#include "CalculatorHistory.h" #include "CalculatorHistory.h"
using namespace std; using namespace std;

View file

@ -38,7 +38,7 @@ namespace CalculationManager
void ClearHistory(); void ClearHistory();
unsigned int AddItem(_In_ std::shared_ptr<HISTORYITEM> const &spHistoryItem); unsigned int AddItem(_In_ std::shared_ptr<HISTORYITEM> const &spHistoryItem);
bool RemoveItem(unsigned int uIdx); bool RemoveItem(unsigned int uIdx);
const size_t MaxHistorySize() const { return m_maxHistorySize; } size_t MaxHistorySize() const { return m_maxHistorySize; }
~CalculatorHistory(void); ~CalculatorHistory(void);
private: private:

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <climits> // for UCHAR_MAX
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "CalculatorManager.h" #include "CalculatorManager.h"
#include "CalculatorResource.h" #include "CalculatorResource.h"
@ -111,9 +111,9 @@ namespace CalculationManager
/// Callback from the engine /// Callback from the engine
/// </summary> /// </summary>
/// <param name="parenthesisCount">string containing the parenthesis count</param> /// <param name="parenthesisCount">string containing the parenthesis count</param>
void CalculatorManager::SetParenDisplayText(const wstring& parenthesisCount) void CalculatorManager::SetParenthesisNumber(_In_ unsigned int parenthesisCount)
{ {
m_displayCallback->SetParenDisplayText(parenthesisCount); m_displayCallback->SetParenthesisNumber(parenthesisCount);
} }
/// <summary> /// <summary>

View file

@ -94,7 +94,7 @@ namespace CalculationManager
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override; void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(const std::wstring& parenthesisCount) override; void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
void OnNoRightParenAdded() override; void OnNoRightParenAdded() override;
void DisplayPasteError(); void DisplayPasteError();
void MaxDigitsReached() override; void MaxDigitsReached() override;

View file

@ -1,9 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
#include <string>
#include <vector>
#include <winerror.h>
#include "Ratpack/CalcErr.h" #include "Ratpack/CalcErr.h"
#include <stdexcept> // for std::out_of_range
#include <sal.h> // for SAL
template <typename TType> template <typename TType>
class CalculatorVector class CalculatorVector

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <string>
#include "Header Files/CCommand.h" #include "Header Files/CCommand.h"
#include "CalculatorVector.h" #include "CalculatorVector.h"
#include "ExpressionCommand.h" #include "ExpressionCommand.h"

View file

@ -1,7 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
#include <memory> // for std::shared_ptr
#include "CalculatorVector.h" #include "CalculatorVector.h"
#include "Command.h" #include "Command.h"

View file

@ -13,6 +13,8 @@
* *
\****************************************************************************/ \****************************************************************************/
#pragma once
// The following are the valid id's which can be passed to CCalcEngine::ProcessCommand // The following are the valid id's which can be passed to CCalcEngine::ProcessCommand
#define IDM_HEX 313 #define IDM_HEX 313

View file

@ -45,7 +45,7 @@ namespace CalculationManager
class IResourceProvider; class IResourceProvider;
} }
namespace CalculatorUnitTests namespace CalculatorEngineTests
{ {
class CalcEngineTests; class CalcEngineTests;
} }
@ -160,5 +160,5 @@ private:
static void ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision); static void ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision);
void BaseOrPrecisionChanged(); void BaseOrPrecisionChanged();
friend class CalculatorUnitTests::CalcEngineTests; friend class CalculatorEngineTests::CalcEngineTests;
}; };

View file

@ -13,6 +13,11 @@
* Created: 13-Feb-2008 * Created: 13-Feb-2008
* *
\****************************************************************************/ \****************************************************************************/
#pragma once
#include <string>
inline constexpr auto IDS_ERRORS_FIRST = 99; inline constexpr auto IDS_ERRORS_FIRST = 99;
// This is the list of error strings corresponding to SCERR_DIVIDEZERO.. // This is the list of error strings corresponding to SCERR_DIVIDEZERO..

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <array>
#include "ICalcDisplay.h" #include "ICalcDisplay.h"
#include "IHistoryDisplay.h" #include "IHistoryDisplay.h"
#include "Rational.h" #include "Rational.h"

View file

@ -12,7 +12,7 @@ public:
virtual void SetPrimaryDisplay(const std::wstring& pszText, bool isError) = 0; virtual void SetPrimaryDisplay(const std::wstring& pszText, bool isError) = 0;
virtual void SetIsInError(bool isInError) = 0; virtual void SetIsInError(bool isInError) = 0;
virtual void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) = 0; virtual void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) = 0;
virtual void SetParenDisplayText(const std::wstring& pszText) = 0; virtual void SetParenthesisNumber(_In_ unsigned int count) = 0;
virtual void OnNoRightParenAdded() = 0; virtual void OnNoRightParenAdded() = 0;
virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer. virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer.
virtual void BinaryOperatorReceived() = 0; virtual void BinaryOperatorReceived() = 0;

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <vector>
#include "Ratpack/ratpak.h" #include "Ratpack/ratpak.h"
namespace CalcEngine namespace CalcEngine

View file

@ -13,6 +13,7 @@ namespace CalcEngine::RationalMath
Rational Pow(Rational const& base, Rational const& pow); Rational Pow(Rational const& base, Rational const& pow);
Rational Root(Rational const& base, Rational const& root); Rational Root(Rational const& base, Rational const& root);
Rational Fact(Rational const& rat); Rational Fact(Rational const& rat);
Rational Mod(Rational const& a, Rational const& b);
Rational Exp(Rational const& rat); Rational Exp(Rational const& rat);
Rational Log(Rational const& rat); Rational Log(Rational const& rat);

View file

@ -14,8 +14,8 @@
// internal base is a power of 2. // internal base is a power of 2.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
#include <cstring> // for memmove
void _mulnumx( PNUMBER *pa, PNUMBER b ); void _mulnumx( PNUMBER *pa, PNUMBER b );

View file

@ -17,7 +17,10 @@
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "pch.h" #include <algorithm>
#include <winerror.h>
#include <sstream>
#include <cstring> // for memmove, memcpy
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;

View file

@ -14,7 +14,6 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -408,7 +407,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) void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
{ {
int32_t sign = ((*px)->pp->sign * (*px)->pq->sign); int32_t sign = SIGN(*px);
// Take the absolute value // Take the absolute value
(*px)->pp->sign = 1; (*px)->pp->sign = 1;

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -13,7 +13,6 @@
// Contains fact(orial) and supporting _gamma functions. // Contains fact(orial) and supporting _gamma functions.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -216,7 +215,7 @@ void factrat( PRAT *px, uint32_t radix, int32_t precision)
// Check for negative integers and throw an error. // Check for negative integers and throw an error.
if ( ( zerrat(frac) || ( LOGRATRADIX(frac) <= -precision) ) && if ( ( zerrat(frac) || ( LOGRATRADIX(frac) <= -precision) ) &&
( (*px)->pp->sign * (*px)->pq->sign == -1 ) ) ( SIGN(*px) == -1 ) )
{ {
throw CALC_E_DOMAIN; throw CALC_E_DOMAIN;
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -15,7 +15,6 @@
// Special Information // Special Information
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -92,11 +91,9 @@ void asinanglerat( _Inout_ PRAT *pa, ANGLE_TYPE angletype, uint32_t radix, int32
void asinrat( PRAT *px, uint32_t radix, int32_t precision) void asinrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
int32_t sgn;
PRAT pret= nullptr; PRAT pret= nullptr;
PRAT phack= nullptr; PRAT phack= nullptr;
int32_t sgn = SIGN(*px);
sgn = (*px)->pp->sign* (*px)->pq->sign;
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;
@ -204,9 +201,7 @@ void _acosrat( PRAT *px, int32_t precision)
void acosrat( PRAT *px, uint32_t radix, int32_t precision) void acosrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
int32_t sgn; int32_t sgn = SIGN(*px);
sgn = (*px)->pp->sign*(*px)->pq->sign;
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;
@ -291,10 +286,8 @@ void _atanrat( PRAT *px, int32_t precision)
void atanrat( PRAT *px, uint32_t radix, int32_t precision) void atanrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
int32_t sgn;
PRAT tmpx= nullptr; PRAT tmpx= nullptr;
int32_t sgn = SIGN(*px);
sgn = (*px)->pp->sign * (*px)->pq->sign;
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;

View file

@ -16,7 +16,6 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"

View file

@ -13,59 +13,58 @@
// Contains routines for and, or, xor, not and other support // Contains routines for and, or, xor, not and other support
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;
void lshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void lshrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
PRAT pwr= nullptr; PRAT pwr = nullptr;
int32_t intb; int32_t intb;
intrat(pa, radix, precision); intrat(pa, radix, precision);
if ( !zernum( (*pa)->pp ) ) if (!zernum((*pa)->pp))
{ {
// If input is zero we're done. // If input is zero we're done.
if ( rat_gt( b, rat_max_exp, precision) ) if (rat_gt(b, rat_max_exp, precision))
{ {
// Don't attempt lsh of anything big // Don't attempt lsh of anything big
throw( CALC_E_DOMAIN ); throw(CALC_E_DOMAIN);
} }
intb = rattoi32(b, radix, precision); intb = rattoi32(b, radix, precision);
DUPRAT(pwr,rat_two); DUPRAT(pwr, rat_two);
ratpowi32(&pwr, intb, precision); ratpowi32(&pwr, intb, precision);
mulrat(pa, pwr, precision); mulrat(pa, pwr, precision);
destroyrat(pwr); destroyrat(pwr);
} }
} }
void rshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void rshrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
PRAT pwr= nullptr; PRAT pwr = nullptr;
int32_t intb; int32_t intb;
intrat(pa, radix, precision); intrat(pa, radix, precision);
if ( !zernum( (*pa)->pp ) ) if (!zernum((*pa)->pp))
{ {
// If input is zero we're done. // If input is zero we're done.
if ( rat_lt( b, rat_min_exp, precision) ) if (rat_lt(b, rat_min_exp, precision))
{ {
// Don't attempt rsh of anything big and negative. // Don't attempt rsh of anything big and negative.
throw( CALC_E_DOMAIN ); throw(CALC_E_DOMAIN);
} }
intb = rattoi32(b, radix, precision); intb = rattoi32(b, radix, precision);
DUPRAT(pwr,rat_two); DUPRAT(pwr, rat_two);
ratpowi32(&pwr, intb, precision); ratpowi32(&pwr, intb, precision);
divrat(pa, pwr, precision); divrat(pa, pwr, precision);
destroyrat(pwr); destroyrat(pwr);
} }
} }
void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision); void boolrat(PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision);
void boolnum( PNUMBER *pa, PNUMBER b, int func ); void boolnum(PNUMBER *pa, PNUMBER b, int func);
enum { enum {
@ -74,22 +73,22 @@ enum {
FUNC_XOR FUNC_XOR
} BOOL_FUNCS; } BOOL_FUNCS;
void andrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void andrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
boolrat( pa, b, FUNC_AND, radix, precision); boolrat(pa, b, FUNC_AND, radix, precision);
} }
void orrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void orrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
boolrat( pa, b, FUNC_OR, radix, precision); boolrat(pa, b, FUNC_OR, radix, precision);
} }
void xorrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void xorrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
boolrat( pa, b, FUNC_XOR, radix, precision); boolrat(pa, b, FUNC_XOR, radix, precision);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -104,15 +103,15 @@ void xorrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision) void boolrat(PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision)
{ {
PRAT tmp= nullptr; PRAT tmp = nullptr;
intrat( pa, radix, precision); intrat(pa, radix, precision);
DUPRAT(tmp,b); DUPRAT(tmp, b);
intrat( &tmp, radix, precision); intrat(&tmp, radix, precision);
boolnum( &((*pa)->pp), tmp->pp, func ); boolnum(&((*pa)->pp), tmp->pp, func);
destroyrat(tmp); destroyrat(tmp);
} }
@ -130,11 +129,11 @@ void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void boolnum( PNUMBER *pa, PNUMBER b, int func ) void boolnum(PNUMBER *pa, PNUMBER b, int func)
{ {
PNUMBER c= nullptr; PNUMBER c = nullptr;
PNUMBER a= nullptr; PNUMBER a = nullptr;
MANTTYPE *pcha; MANTTYPE *pcha;
MANTTYPE *pchb; MANTTYPE *pchb;
MANTTYPE *pchc; MANTTYPE *pchc;
@ -143,26 +142,26 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
MANTTYPE da; MANTTYPE da;
MANTTYPE db; MANTTYPE db;
a=*pa; a = *pa;
cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) - cdigits = max(a->cdigit + a->exp, b->cdigit + b->exp) -
min( a->exp, b->exp ); min(a->exp, b->exp);
createnum( c, cdigits ); createnum(c, cdigits);
c->exp = min( a->exp, b->exp ); c->exp = min(a->exp, b->exp);
mexp = c->exp; mexp = c->exp;
c->cdigit = cdigits; c->cdigit = cdigits;
pcha = a->mant; pcha = a->mant;
pchb = b->mant; pchb = b->mant;
pchc = c->mant; pchc = c->mant;
for ( ;cdigits > 0; cdigits--, mexp++ ) for (; cdigits > 0; cdigits--, mexp++)
{
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))) ?
*pchb++ : 0);
switch (func)
{ {
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) ) ) ?
*pchb++ : 0 );
switch ( func )
{
case FUNC_AND: case FUNC_AND:
*pchc++ = da & db; *pchc++ = da & db;
break; break;
@ -172,15 +171,51 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
case FUNC_XOR: case FUNC_XOR:
*pchc++ = da ^ db; *pchc++ = da ^ db;
break; break;
}
} }
}
c->sign = a->sign; c->sign = a->sign;
while ( c->cdigit > 1 && *(--pchc) == 0 ) while (c->cdigit > 1 && *(--pchc) == 0)
{ {
c->cdigit--; c->cdigit--;
} }
destroynum( *pa ); destroynum(*pa);
*pa=c; *pa = c;
}
//-----------------------------------------------------------------------------
//
// FUNCTION: remrat
//
// ARGUMENTS: pointer to a rational a second rational.
//
// RETURN: None, changes pointer.
//
// DESCRIPTION: Calculate the remainder of *pa / b,
// equivalent of 'pa % b' in C/C++ and produces a result
// that is either zero or has the same sign as the dividend.
//
//-----------------------------------------------------------------------------
void remrat(PRAT *pa, PRAT b)
{
if (zerrat(b))
{
throw CALC_E_INDEFINITE;
}
PRAT tmp = nullptr;
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.
RENORMALIZE(*pa);
destroyrat(tmp);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -191,28 +226,38 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
// //
// RETURN: None, changes pointer. // RETURN: None, changes pointer.
// //
// DESCRIPTION: Does the rational equivalent of frac(*pa); // DESCRIPTION: Calculate the remainder of *pa / b, with the sign of the result
// either zero or has the same sign as the divisor.
// NOTE: When *pa or b are negative, the result won't be the same as
// the C/C++ operator %, use remrat if it's the behavior you expect.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void modrat( PRAT *pa, PRAT b ) void modrat(PRAT *pa, PRAT b)
{ {
//contrary to remrat(X, 0) returning 0, modrat(X, 0) must return X
if (zerrat(b))
{
return;
}
PRAT tmp = nullptr; PRAT tmp = nullptr;
DUPRAT(tmp, b);
if ( zerrat( b ) ) auto needAdjust = (SIGN(*pa) == -1 ? (SIGN(b) == 1) : (SIGN(b) == -1));
{
throw CALC_E_INDEFINITE;
}
DUPRAT(tmp,b);
mulnumx( &((*pa)->pp), tmp->pq ); mulnumx(&((*pa)->pp), tmp->pq);
mulnumx( &(tmp->pp), (*pa)->pq ); mulnumx(&(tmp->pp), (*pa)->pq);
remnum( &((*pa)->pp), tmp->pp, BASEX ); remnum(&((*pa)->pp), tmp->pp, BASEX);
mulnumx( &((*pa)->pq), tmp->pq ); mulnumx(&((*pa)->pq), tmp->pq);
if (needAdjust && !zerrat(*pa))
{
addrat(pa, b, BASEX);
}
// Get *pa back in the integer over integer form. // Get *pa back in the integer over integer form.
RENORMALIZE(*pa); RENORMALIZE(*pa);
destroyrat( tmp ); destroyrat(tmp);
} }

View file

@ -17,7 +17,8 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h" #include <list>
#include <cstring> // for memmove
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;

View file

@ -16,7 +16,6 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;

View file

@ -17,7 +17,11 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include <algorithm>
#include <string>
#include "CalcErr.h" #include "CalcErr.h"
#include <cstring> // for memmove
#include <sal.h> // for SAL
static constexpr uint32_t BASEXPWR = 31L;// Internal log2(BASEX) static constexpr uint32_t BASEXPWR = 31L;// Internal log2(BASEX)
static constexpr uint32_t BASEX = 0x80000000; // Internal radix used in calculations, hope to raise static constexpr uint32_t BASEX = 0x80000000; // Internal radix used in calculations, hope to raise
@ -148,6 +152,9 @@ extern PRAT rat_min_i32;
#define LOGNUM2(pnum) ((pnum)->cdigit+(pnum)->exp) #define LOGNUM2(pnum) ((pnum)->cdigit+(pnum)->exp)
#define LOGRAT2(prat) (LOGNUM2((prat)->pp)-LOGNUM2((prat)->pq)) #define LOGRAT2(prat) (LOGNUM2((prat)->pp)-LOGNUM2((prat)->pq))
// SIGN returns the sign of the rational
#define SIGN(prat) ((prat)->pp->sign*(prat)->pq->sign)
#if defined( DEBUG_RATPAK ) #if defined( DEBUG_RATPAK )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
@ -423,7 +430,8 @@ extern void divnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b, int32_t precision);
extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision); extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision);
extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision); extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision);
extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision); extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision);
extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b ); extern void remrat(_Inout_ PRAT *pa, _In_ PRAT b);
extern void modrat(_Inout_ PRAT *pa, _In_ PRAT b);
extern void gcdrat( _Inout_ PRAT *pa, int32_t precision); extern void gcdrat( _Inout_ PRAT *pa, int32_t precision);
extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); 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 mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix);

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -18,7 +18,9 @@
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include "pch.h" #include <string>
#include <cstring> // for memmove
#include <iostream> // for wostream
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;
@ -296,7 +298,7 @@ void intrat( PRAT *px, uint32_t radix, int32_t precision)
// Subtract the fractional part of the rational // Subtract the fractional part of the rational
PRAT pret = nullptr; PRAT pret = nullptr;
DUPRAT(pret,*px); DUPRAT(pret,*px);
modrat( &pret, rat_one ); remrat( &pret, rat_one );
subrat( px, pret, precision); subrat( px, pret, precision);
destroyrat( pret ); destroyrat( pret );
@ -348,8 +350,7 @@ bool rat_ge( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( zernum( rattmp->pp ) || bool bret = ( zernum( rattmp->pp ) || SIGN(rattmp) == 1 );
rattmp->pp->sign * rattmp->pq->sign == 1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -374,8 +375,7 @@ bool rat_gt( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( !zernum( rattmp->pp ) && bool bret = ( !zernum( rattmp->pp ) && SIGN(rattmp) == 1 );
rattmp->pp->sign * rattmp->pq->sign == 1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -400,8 +400,7 @@ bool rat_le( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( zernum( rattmp->pp ) || bool bret = ( zernum( rattmp->pp ) || SIGN(rattmp) == -1 );
rattmp->pp->sign * rattmp->pq->sign == -1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -426,8 +425,7 @@ bool rat_lt( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( !zernum( rattmp->pp ) && bool bret = ( !zernum( rattmp->pp ) && SIGN(rattmp) == -1 );
rattmp->pp->sign * rattmp->pq->sign == -1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }

View file

@ -14,7 +14,6 @@
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"

View file

@ -14,7 +14,6 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"

View file

@ -1,7 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <cassert>
#include <sstream>
#include <algorithm> // for std::sort
#include "Command.h" #include "Command.h"
#include "UnitConverter.h" #include "UnitConverter.h"
@ -63,7 +65,8 @@ UnitConverter::UnitConverter(_In_ const shared_ptr<IConverterDataLoader>& dataLo
unquoteConversions[L"{sc}"] = L';'; unquoteConversions[L"{sc}"] = L';';
unquoteConversions[L"{lb}"] = LEFTESCAPECHAR; unquoteConversions[L"{lb}"] = LEFTESCAPECHAR;
unquoteConversions[L"{rb}"] = RIGHTESCAPECHAR; unquoteConversions[L"{rb}"] = RIGHTESCAPECHAR;
Reset(); ClearValues();
ResetCategoriesAndRatios();
} }
void UnitConverter::Initialize() void UnitConverter::Initialize()
@ -75,7 +78,7 @@ bool UnitConverter::CheckLoad()
{ {
if (m_categories.empty()) if (m_categories.empty())
{ {
Reset(); ResetCategoriesAndRatios();
} }
return !m_categories.empty(); return !m_categories.empty();
} }
@ -152,7 +155,6 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType
Calculate(); Calculate();
UpdateCurrencySymbols(); UpdateCurrencySymbols();
UpdateViewModel();
} }
/// <summary> /// <summary>
@ -336,7 +338,8 @@ wstring UnitConverter::Serialize()
/// <param name="serializedData">wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it</param> /// <param name="serializedData">wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it</param>
void UnitConverter::DeSerialize(const wstring& serializedData) void UnitConverter::DeSerialize(const wstring& serializedData)
{ {
Reset(); ClearValues();
ResetCategoriesAndRatios();
if (serializedData.empty()) if (serializedData.empty())
{ {
@ -403,12 +406,30 @@ void UnitConverter::RestoreUserPreferences(const wstring& userPreferences)
} }
vector<wstring> outerTokens = StringToVector(userPreferences, L"|"); vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
if (outerTokens.size() == 3) if (outerTokens.size() != 3)
{ {
m_fromType = StringToUnit(outerTokens[0]); return;
m_toType = StringToUnit(outerTokens[1]);
m_currentCategory = StringToCategory(outerTokens[2]);
} }
auto fromType = StringToUnit(outerTokens[0]);
auto toType = StringToUnit(outerTokens[1]);
m_currentCategory = StringToCategory(outerTokens[2]);
// Only restore from the saved units if they are valid in the current available units.
auto itr = m_categoryToUnits.find(m_currentCategory);
if (itr != m_categoryToUnits.end())
{
const auto& curUnits = itr->second;
if (find(curUnits.begin(), curUnits.end(), fromType) != curUnits.end())
{
m_fromType = fromType;
}
if (find(curUnits.begin(), curUnits.end(), toType) != curUnits.end())
{
m_toType = toType;
}
}
} }
/// <summary> /// <summary>
@ -615,7 +636,7 @@ void UnitConverter::SendCommand(Command command)
clearFront = false; clearFront = false;
clearBack = false; clearBack = false;
ClearValues(); ClearValues();
Reset(); ResetCategoriesAndRatios();
break; break;
default: default:
@ -634,8 +655,6 @@ void UnitConverter::SendCommand(Command command)
} }
Calculate(); Calculate();
UpdateViewModel();
} }
/// <summary> /// <summary>
@ -824,19 +843,16 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
returnVector.push_back(whimsicalReturnVector.at(0)); returnVector.push_back(whimsicalReturnVector.at(0));
} }
//
return returnVector; return returnVector;
} }
/// <summary> /// <summary>
/// Resets the converter to its initial state /// Resets categories and ratios
/// </summary> /// </summary>
void UnitConverter::Reset() void UnitConverter::ResetCategoriesAndRatios()
{ {
m_categories = m_dataLoader->LoadOrderedCategories(); m_categories = m_dataLoader->LoadOrderedCategories();
ClearValues();
m_switchedActive = false; m_switchedActive = false;
if (m_categories.empty()) if (m_categories.empty())
@ -881,7 +897,6 @@ void UnitConverter::Reset()
} }
InitializeSelectedUnits(); InitializeSelectedUnits();
Calculate();
} }
/// <summary> /// <summary>
@ -972,11 +987,21 @@ bool UnitConverter::AnyUnitIsEmpty()
/// </summary> /// </summary>
void UnitConverter::Calculate() void UnitConverter::Calculate()
{ {
unordered_map<Unit, ConversionData, UnitHash> conversionTable = m_ratioMap[m_fromType]; if (AnyUnitIsEmpty())
double returnValue = stod(m_currentDisplay);
if (AnyUnitIsEmpty() || (conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0))
{ {
m_returnDisplay = m_currentDisplay; m_returnDisplay = m_currentDisplay;
m_returnHasDecimal = m_currentHasDecimal;
TrimString(m_returnDisplay);
UpdateViewModel();
return;
}
unordered_map<Unit, ConversionData, UnitHash> conversionTable = m_ratioMap[m_fromType];
double returnValue = stod(m_currentDisplay);
if (conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0)
{
m_returnDisplay = m_currentDisplay;
m_returnHasDecimal = m_currentHasDecimal;
TrimString(m_returnDisplay); TrimString(m_returnDisplay);
} }
else else
@ -1015,9 +1040,9 @@ void UnitConverter::Calculate()
m_returnDisplay = returnString; m_returnDisplay = returnString;
TrimString(m_returnDisplay); TrimString(m_returnDisplay);
} }
m_returnHasDecimal = (m_returnDisplay.find(L'.') != m_returnDisplay.npos);
} }
UpdateViewModel();
m_returnHasDecimal = (m_returnDisplay.find(L'.') != m_returnDisplay.npos);
} }
/// <summary> /// <summary>

View file

@ -1,8 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
#include <vector>
#include <unordered_map>
#include <ppltasks.h>
#include <sal.h> // for SAL
#include <memory> // for std::shared_ptr
namespace UnitConversionManager namespace UnitConversionManager
{ {
enum class Command; enum class Command;
@ -195,6 +201,8 @@ namespace UnitConversionManager
virtual void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) = 0; virtual void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) = 0;
virtual void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) = 0; virtual void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) = 0;
virtual concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() = 0; virtual concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() = 0;
virtual void Calculate() = 0;
virtual void ResetCategoriesAndRatios() = 0;
}; };
class UnitConverter : public IUnitConverter, public std::enable_shared_from_this<UnitConverter> class UnitConverter : public IUnitConverter, public std::enable_shared_from_this<UnitConverter>
@ -218,6 +226,8 @@ namespace UnitConversionManager
void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) override; void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) override;
void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) override; void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) override;
concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() override; concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() override;
void Calculate() override;
void ResetCategoriesAndRatios() override;
// IUnitConverter // IUnitConverter
static std::vector<std::wstring> StringToVector(const std::wstring& w, const wchar_t * delimiter, bool addRemainder = false); static std::vector<std::wstring> StringToVector(const std::wstring& w, const wchar_t * delimiter, bool addRemainder = false);
@ -228,9 +238,7 @@ namespace UnitConversionManager
bool CheckLoad(); bool CheckLoad();
double Convert(double value, ConversionData conversionData); double Convert(double value, ConversionData conversionData);
std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested(); std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested();
void Reset();
void ClearValues(); void ClearValues();
void Calculate();
void TrimString(std::wstring& input); void TrimString(std::wstring& input);
void InitializeSelectedUnits(); void InitializeSelectedUnits();
std::wstring RoundSignificant(double num, int numSignificant); std::wstring RoundSignificant(double num, int numSignificant);

View file

@ -1,4 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" // Intentionally do not include the pch.h here. For projects that don't
// use precompiled headers, including the header here would force unnecessary compilation.
// The pch will be included through forced include.

View file

@ -3,27 +3,20 @@
#pragma once #pragma once
#ifndef WIN32_LEAN_AND_MEAN // The CalcManager project should be able to be compiled with or without a precompiled header
#define WIN32_LEAN_AND_MEAN // in - order to support other toolchains besides MSVC. When adding new system headers, make sure
#endif // that the relevant source file includes all headers it needs, but then also add the system headers
// here so that MSVC users see the performance benefit.
// Windows headers define min/max macros. #include <algorithm>
// Disable it for project code.
#define NOMINMAX
#include <assert.h>
#include <windows.h>
#include <winerror.h>
#include <sstream>
#include <iostream>
#include <iterator>
#include <string>
#include <memory>
#include <vector>
#include <limits>
#include <list>
#include <regex>
#include <unordered_map>
#include <intsafe.h>
#include <array> #include <array>
#include <cassert>
#include <intsafe.h>
#include <list>
#include <ppltasks.h> #include <ppltasks.h>
#include <regex>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <winerror.h>

View file

@ -1,11 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View file

@ -36,7 +36,6 @@ namespace
{ {
StringReference CategoriesPropertyName(L"Categories"); StringReference CategoriesPropertyName(L"Categories");
StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility"); StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility");
StringReference AppBarVisibilityPropertyName(L"AppBarVisibility");
} }
ApplicationViewModel::ApplicationViewModel() : ApplicationViewModel::ApplicationViewModel() :
@ -164,7 +163,6 @@ void ApplicationViewModel::OnModeChanged()
TraceLogger::GetInstance().LogModeChangeEnd(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread())); TraceLogger::GetInstance().LogModeChangeEnd(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
RaisePropertyChanged(ClearMemoryVisibilityPropertyName); RaisePropertyChanged(ClearMemoryVisibilityPropertyName);
RaisePropertyChanged(AppBarVisibilityPropertyName);
} }
void ApplicationViewModel::OnCopyCommand(Object^ parameter) void ApplicationViewModel::OnCopyCommand(Object^ parameter)
@ -189,7 +187,7 @@ void ApplicationViewModel::OnPasteCommand(Object^ parameter)
{ {
ConverterViewModel->OnPasteCommand(parameter); ConverterViewModel->OnPasteCommand(parameter);
} }
else else if (NavCategory::IsCalculatorViewMode(m_mode))
{ {
CalculatorViewModel->OnPasteCommand(parameter); CalculatorViewModel->OnPasteCommand(parameter);
} }

View file

@ -66,16 +66,6 @@ namespace CalculatorApp
} }
} }
property Windows::UI::Xaml::Visibility AppBarVisibility
{
Windows::UI::Xaml::Visibility get()
{
return CalculatorApp::Common::NavCategory::IsCalculatorViewMode(Mode)
? Windows::UI::Xaml::Visibility::Visible
: Windows::UI::Xaml::Visibility::Collapsed;
}
}
private: private:
bool TryRecoverFromNavigationModeFailure(); bool TryRecoverFromNavigationModeFailure();

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// Implementation of the NarratorNotifier class. // Implementation of the NarratorNotifier class.

View file

@ -36,7 +36,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue
} }
} }
void CalculatorDisplay::SetParenDisplayText(_In_ const std::wstring& parenthesisCount) void CalculatorDisplay::SetParenthesisNumber(_In_ unsigned int parenthesisCount)
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {

View file

@ -21,7 +21,7 @@ namespace CalculatorApp
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override; void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override; void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
void OnNoRightParenAdded() override; void OnNoRightParenAdded() override;
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;

View file

@ -15,14 +15,15 @@ using namespace Windows::Foundation;
using namespace Windows::System; using namespace Windows::System;
using namespace Windows::ApplicationModel::DataTransfer; using namespace Windows::ApplicationModel::DataTransfer;
unsigned long long maxOperandNumber;
String^ CopyPasteManager::supportedFormats[] = String^ CopyPasteManager::supportedFormats[] =
{ {
StandardDataFormats::Text StandardDataFormats::Text
}; };
constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" }; static constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" };
// The below values can not be "constexpr"-ed,
// as both wstring_view and wchar[] can not be concatenated
// [\s\x85] means white-space characters // [\s\x85] means white-space characters
static const wstring c_wspc = L"[\\s\\x85]*"; static const wstring c_wspc = L"[\\s\\x85]*";
static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc; static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc;
@ -103,19 +104,16 @@ task<String^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupTyp
int CopyPasteManager::ClipboardTextFormat() int CopyPasteManager::ClipboardTextFormat()
{ {
int result = -1; const auto dataPackageView = Clipboard::GetContent();
auto dataPackageView = Clipboard::GetContent();
for (int i = 0; i < RTL_NUMBER_OF(supportedFormats); i++) for (int i = 0; i < RTL_NUMBER_OF(supportedFormats); i++)
{ {
if (dataPackageView->Contains(supportedFormats[i])) if (dataPackageView->Contains(supportedFormats[i]))
{ {
result = i; return i;
break;
} }
} }
return result; return -1;
} }
String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode mode, int programmerNumberBase, int bitLengthType) String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode mode, int programmerNumberBase, int bitLengthType)
@ -268,13 +266,8 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
return false; return false;
} }
bool expMatched = true;
vector<wregex> patterns{}; vector<wregex> patterns{};
pair<size_t, uint64_t> operandLimits = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType);
size_t maxOperandLength = operandLimits.first;
uint64_t maxOperandValue = operandLimits.second;
if (mode == ViewMode::Standard) if (mode == ViewMode::Standard)
{ {
patterns.assign(standardModePatterns.begin(), standardModePatterns.end()); patterns.assign(standardModePatterns.begin(), standardModePatterns.end());
@ -292,11 +285,14 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
patterns.assign(unitConverterPatterns.begin(), unitConverterPatterns.end()); patterns.assign(unitConverterPatterns.begin(), unitConverterPatterns.end());
} }
for (const wstring& operand : operands) const auto [maxOperandLength, maxOperandValue] = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType);
bool expMatched = true;
for (const auto& operand : operands)
{ {
// Each operand only needs to match one of the available patterns. // Each operand only needs to match one of the available patterns.
bool operandMatched = false; bool operandMatched = false;
for (const wregex& pattern : patterns) for (const auto& pattern : patterns)
{ {
operandMatched = operandMatched || regex_match(operand, pattern); operandMatched = operandMatched || regex_match(operand, pattern);
} }
@ -305,7 +301,7 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
{ {
// Remove characters that are valid in the expression but we do not want to include in length calculations // Remove characters that are valid in the expression but we do not want to include in length calculations
// or which will break conversion from string-to-ULL. // or which will break conversion from string-to-ULL.
wstring operandValue = SanitizeOperand(operand); const wstring operandValue = SanitizeOperand(operand);
// If an operand exceeds the maximum length allowed, break and return. // If an operand exceeds the maximum length allowed, break and return.
if (OperandLength(operandValue, mode, modeType, programmerNumberBase) > maxOperandLength) if (OperandLength(operandValue, mode, modeType, programmerNumberBase) > maxOperandLength)
@ -341,16 +337,16 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType) pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType)
{ {
size_t maxLength = 0; constexpr size_t defaultMaxOperandLength = 0;
uint64_t maxValue = 0; constexpr uint64_t defaultMaxValue = 0;
if (mode == ViewMode::Standard) if (mode == ViewMode::Standard)
{ {
maxLength = MaxStandardOperandLength; return make_pair(MaxStandardOperandLength, defaultMaxValue);
} }
else if (mode == ViewMode::Scientific) else if (mode == ViewMode::Scientific)
{ {
maxLength = MaxScientificOperandLength; return make_pair(MaxScientificOperandLength, defaultMaxValue);
} }
else if (mode == ViewMode::Programmer) else if (mode == ViewMode::Programmer)
{ {
@ -390,15 +386,17 @@ pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo
unsigned int signBit = (programmerNumberBase == DecBase) ? 1 : 0; unsigned int signBit = (programmerNumberBase == DecBase) ? 1 : 0;
maxLength = (size_t)ceil((bitLength - signBit) / bitsPerDigit); const auto maxLength = static_cast<size_t>(ceil((bitLength - signBit) / bitsPerDigit));
maxValue = UINT64_MAX >> (MaxProgrammerBitLength - (bitLength - signBit)); const uint64_t maxValue = UINT64_MAX >> (MaxProgrammerBitLength - (bitLength - signBit));
return make_pair(maxLength, maxValue);
} }
else if (modeType == CategoryGroupType::Converter) else if (modeType == CategoryGroupType::Converter)
{ {
maxLength = MaxConverterInputLength; return make_pair(MaxConverterInputLength, defaultMaxValue);
} }
return make_pair(maxLength, maxValue); return make_pair(defaultMaxOperandLength, defaultMaxValue);
} }
wstring CopyPasteManager::SanitizeOperand(const wstring& operand) wstring CopyPasteManager::SanitizeOperand(const wstring& operand)
@ -417,8 +415,7 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
return false; return false;
} }
// Default to base10 int intBase;
int intBase = 10;
switch (numberBase) switch (numberBase)
{ {
case HexBase: case HexBase:
@ -430,6 +427,7 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
case BinBase: case BinBase:
intBase = 2; intBase = 2;
break; break;
default:
case DecBase: case DecBase:
intBase = 10; intBase = 10;
break; break;
@ -441,11 +439,11 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
result = stoull(operand, &size, intBase); result = stoull(operand, &size, intBase);
return true; return true;
} }
catch (invalid_argument) catch (const invalid_argument&)
{ {
// Do nothing // Do nothing
} }
catch (out_of_range) catch (const out_of_range&)
{ {
// Do nothing // Do nothing
} }
@ -453,35 +451,28 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
return false; return false;
} }
size_t CopyPasteManager::OperandLength(wstring operand, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase) size_t CopyPasteManager::OperandLength(const wstring& operand, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase)
{ {
size_t len = 0; if (modeType == CategoryGroupType::Converter) {
if (mode == ViewMode::Standard || mode == ViewMode::Scientific) return operand.length();
{
len = StandardScientificOperandLength(operand);
}
else if (mode == ViewMode::Programmer)
{
len = ProgrammerOperandLength(operand, programmerNumberBase);
}
else if (modeType == CategoryGroupType::Converter)
{
len = operand.length();
} }
return len; switch(mode) {
case ViewMode::Standard:
case ViewMode::Scientific:
return StandardScientificOperandLength(operand);
case ViewMode::Programmer:
return ProgrammerOperandLength(operand, programmerNumberBase);
default:
return 0;
}
} }
size_t CopyPasteManager::StandardScientificOperandLength(wstring operand) size_t CopyPasteManager::StandardScientificOperandLength(const wstring& operand)
{ {
bool hasDecimal = false; const bool hasDecimal = operand.find('.') != wstring::npos;
for (size_t i = 0; i < operand.length(); i++)
{
if (operand[i] == L'.')
{
hasDecimal = true;
}
}
if (hasDecimal) if (hasDecimal)
{ {
@ -503,7 +494,6 @@ size_t CopyPasteManager::StandardScientificOperandLength(wstring operand)
size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int numberBase) size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int numberBase)
{ {
size_t len = operand.length();
vector<wstring> prefixes{}; vector<wstring> prefixes{};
vector<wstring> suffixes{}; vector<wstring> suffixes{};
@ -525,7 +515,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
break; break;
default: default:
// No defined prefixes/suffixes // No defined prefixes/suffixes
break; return 0;
} }
// UInt suffixes are common across all modes // UInt suffixes are common across all modes
@ -535,9 +525,11 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
wstring operandUpper = operand; wstring operandUpper = operand;
transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper); transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper);
size_t len = operand.length();
// Detect if there is a suffix and subtract its length // Detect if there is a suffix and subtract its length
// Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value). // Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value).
for (const wstring& suffix : suffixes) for (const auto& suffix : suffixes)
{ {
if (len < suffix.length()) if (len < suffix.length())
{ {
@ -552,7 +544,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
} }
// Detect if there is a prefix and subtract its length // Detect if there is a prefix and subtract its length
for (const wstring& prefix : prefixes) for (const auto& prefix : prefixes)
{ {
if (len < prefix.length()) if (len < prefix.length())
{ {

View file

@ -13,15 +13,14 @@ namespace CalculatorUnitTests
namespace CalculatorApp namespace CalculatorApp
{ {
inline constexpr auto QwordType = 1;
#define QwordType 1 inline constexpr auto DwordType = 2;
#define DwordType 2 inline constexpr auto WordType = 3;
#define WordType 3 inline constexpr auto ByteType = 4;
#define ByteType 4 inline constexpr auto HexBase = 5;
#define HexBase 5 inline constexpr auto DecBase = 6;
#define DecBase 6 inline constexpr auto OctBase = 7;
#define OctBase 7 inline constexpr auto BinBase = 8;
#define BinBase 8
class CopyPasteManager class CopyPasteManager
{ {
@ -55,8 +54,8 @@ namespace CalculatorApp
static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1); static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1);
static std::wstring SanitizeOperand(const std::wstring& operand); static std::wstring SanitizeOperand(const std::wstring& operand);
static bool TryOperandToULL(const std::wstring& operand, int numberBase, unsigned long long int& result); static bool TryOperandToULL(const std::wstring& operand, int numberBase, unsigned long long int& result);
static size_t OperandLength(std::wstring operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1); static size_t OperandLength(const std::wstring& operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1);
static size_t StandardScientificOperandLength(std::wstring operand); static size_t StandardScientificOperandLength(const std::wstring& operand);
static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase); static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase);
static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input); static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input);

View file

@ -20,13 +20,27 @@ DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier)
// Returns: True if function succeeds to calculate the date else returns False // 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) bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate)
{ {
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
try try
{ {
m_calendar->SetDateTime(startDate); m_calendar->SetDateTime(startDate);
if (duration.year != 0) if (duration.year != 0)
{ {
// The Japanese Era system can have multiple year partitions within the same year.
// For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results in a date in Heisei 31.
// To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date math, and then convert back to the Japanese era system.
// This works because the Japanese era system maintains the same year/month boundaries and durations as the Gregorian system and is only different in display value.
if (currentCalendarSystem == CalendarIdentifiers::Japanese)
{
m_calendar->ChangeCalendarSystem(CalendarIdentifiers::Gregorian);
}
m_calendar->AddYears(duration.year); m_calendar->AddYears(duration.year);
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
} }
if (duration.month != 0) if (duration.month != 0)
{ {
@ -41,6 +55,9 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
} }
catch (Platform::InvalidArgumentException^ ex) catch (Platform::InvalidArgumentException^ ex)
{ {
// ensure that we revert to the correct calendar system
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
// Do nothing // Do nothing
return false; return false;
} }
@ -52,6 +69,8 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
// Returns: True if function succeeds to calculate the date else returns False // Returns: True if function succeeds to calculate the date else returns False
bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate) bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate)
{ {
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
// For Subtract the Algorithm is different than Add. Here the smaller units are subtracted first // 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 try
@ -68,13 +87,28 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
} }
if (duration.year != 0) if (duration.year != 0)
{ {
// The Japanese Era system can have multiple year partitions within the same year.
// For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results in a date in Heisei 31.
// To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date math, and then convert back to the Japanese era system.
// This works because the Japanese era system maintains the same year/month boundaries and durations as the Gregorian system and is only different in display value.
if (currentCalendarSystem == CalendarIdentifiers::Japanese)
{
m_calendar->ChangeCalendarSystem(CalendarIdentifiers::Gregorian);
}
m_calendar->AddYears(-duration.year); m_calendar->AddYears(-duration.year);
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
} }
*endDate = m_calendar->GetDateTime(); *endDate = m_calendar->GetDateTime();
} }
catch (Platform::InvalidArgumentException^ ex) catch (Platform::InvalidArgumentException^ ex)
{ {
// ensure that we revert to the correct calendar system
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
// Do nothing // Do nothing
return false; return false;
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
namespace CalculatorApp namespace CalculatorApp
@ -162,7 +162,8 @@ namespace CalculatorApp
Data_Zebibytes = UnitStart + 162, Data_Zebibytes = UnitStart + 162,
Data_Zetabits = UnitStart + 163, Data_Zetabits = UnitStart + 163,
Data_Zetabytes = UnitStart + 164, Data_Zetabytes = UnitStart + 164,
UnitEnd = Data_Zetabytes Area_Pyeong = UnitStart + 165,
UnitEnd = Area_Pyeong
}; };
} }
} }

View file

@ -118,12 +118,19 @@ void UnitConverterDataLoader::LoadData()
unordered_map<int, double> unitConversions = categoryToUnitConversionDataMap.at(categoryViewMode); unordered_map<int, double> unitConversions = categoryToUnitConversionDataMap.at(categoryViewMode);
double unitFactor = unitConversions[unit.id]; double unitFactor = unitConversions[unit.id];
for (auto itr = unitConversions.begin(); itr != unitConversions.end(); ++itr) for (const auto&[id, conversionFactor] : unitConversions)
{ {
if (idToUnit.find(id) == idToUnit.end())
{
// Optional units will not be in idToUnit but can be in unitConversions.
// For optional units that did not make it to the current set of units, just continue.
continue;
}
UCM::ConversionData parsedData = { 1.0, 0.0, false }; UCM::ConversionData parsedData = { 1.0, 0.0, false };
assert(itr->second > 0); // divide by zero assert assert(conversionFactor > 0); // divide by zero assert
parsedData.ratio = unitFactor / itr->second; parsedData.ratio = unitFactor / conversionFactor;
conversions.insert(pair<UCM::Unit, UCM::ConversionData>(idToUnit.at(itr->first), parsedData)); conversions.insert(pair<UCM::Unit, UCM::ConversionData>(idToUnit.at(id), parsedData));
} }
} }
else else
@ -175,6 +182,10 @@ void UnitConverterDataLoader::GetUnits(_In_ unordered_map<ViewMode, vector<Order
bool useWattInsteadOfKilowatt = m_currentRegionCode == "GB"; bool useWattInsteadOfKilowatt = m_currentRegionCode == "GB";
// Use Pyeong, a Korean floorspace unit.
// https://en.wikipedia.org/wiki/Korean_units_of_measurement#Area
bool usePyeong = m_currentRegionCode == L"KP" || m_currentRegionCode == L"KR";
vector<OrderedUnit> areaUnits; vector<OrderedUnit> areaUnits;
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Acre, GetLocalizedStringName(L"UnitName_Acre"), GetLocalizedStringName(L"UnitAbbreviation_Acre"), 9 }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Acre, GetLocalizedStringName(L"UnitName_Acre"), GetLocalizedStringName(L"UnitAbbreviation_Acre"), 9 });
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Hectare, GetLocalizedStringName(L"UnitName_Hectare"), GetLocalizedStringName(L"UnitAbbreviation_Hectare"), 4 }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Hectare, GetLocalizedStringName(L"UnitName_Hectare"), GetLocalizedStringName(L"UnitAbbreviation_Hectare"), 4 });
@ -190,6 +201,10 @@ void UnitConverterDataLoader::GetUnits(_In_ unordered_map<ViewMode, vector<Order
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Paper, GetLocalizedStringName(L"UnitName_Paper"), GetLocalizedStringName(L"UnitAbbreviation_Paper"), 12, false, false, true }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Paper, GetLocalizedStringName(L"UnitName_Paper"), GetLocalizedStringName(L"UnitAbbreviation_Paper"), 12, false, false, true });
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_SoccerField, GetLocalizedStringName(L"UnitName_SoccerField"), GetLocalizedStringName(L"UnitAbbreviation_SoccerField"),13, false, false, true }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_SoccerField, GetLocalizedStringName(L"UnitName_SoccerField"), GetLocalizedStringName(L"UnitAbbreviation_SoccerField"),13, false, false, true });
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Castle, GetLocalizedStringName(L"UnitName_Castle"), GetLocalizedStringName(L"UnitAbbreviation_Castle"), 14, false, false, true }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Castle, GetLocalizedStringName(L"UnitName_Castle"), GetLocalizedStringName(L"UnitAbbreviation_Castle"), 14, false, false, true });
if (usePyeong)
{
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Pyeong, GetLocalizedStringName(L"UnitName_Pyeong"), GetLocalizedStringName(L"UnitAbbreviation_Pyeong"), 15, false, false, false });
}
unitMap.emplace(ViewMode::Area, areaUnits); unitMap.emplace(ViewMode::Area, areaUnits);
vector<OrderedUnit> dataUnits; vector<OrderedUnit> dataUnits;
@ -384,6 +399,7 @@ void UnitConverterDataLoader::GetConversionData(_In_ unordered_map<ViewMode, uno
{ ViewMode::Area, UnitConverterUnits::Area_Paper, 0.06032246 }, { ViewMode::Area, UnitConverterUnits::Area_Paper, 0.06032246 },
{ ViewMode::Area, UnitConverterUnits::Area_SoccerField, 10869.66 }, { ViewMode::Area, UnitConverterUnits::Area_SoccerField, 10869.66 },
{ ViewMode::Area, UnitConverterUnits::Area_Castle, 100000 }, { ViewMode::Area, UnitConverterUnits::Area_Castle, 100000 },
{ ViewMode::Area, UnitConverterUnits::Area_Pyeong, 400.0 / 121.0 },
{ ViewMode::Data, UnitConverterUnits::Data_Bit, 0.000000125 }, { ViewMode::Data, UnitConverterUnits::Data_Bit, 0.000000125 },
{ ViewMode::Data, UnitConverterUnits::Data_Byte, 0.000001 }, { ViewMode::Data, UnitConverterUnits::Data_Byte, 0.000001 },

View file

@ -48,7 +48,6 @@ namespace CalculatorResourceKeys
StringReference DecButton(L"Format_DecButtonValue"); StringReference DecButton(L"Format_DecButtonValue");
StringReference OctButton(L"Format_OctButtonValue"); StringReference OctButton(L"Format_OctButtonValue");
StringReference BinButton(L"Format_BinButtonValue"); StringReference BinButton(L"Format_BinButtonValue");
StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix");
StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix"); StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix");
StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement"); StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement");
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
@ -67,6 +66,7 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_BinaryDisplayValue(L"0"), m_BinaryDisplayValue(L"0"),
m_OctalDisplayValue(L"0"), m_OctalDisplayValue(L"0"),
m_standardCalculatorManager(&m_calculatorDisplay, &m_resourceProvider), m_standardCalculatorManager(&m_calculatorDisplay, &m_resourceProvider),
m_ExpressionTokens(ref new Vector<DisplayExpressionToken^>()),
m_MemorizedNumbers(ref new Vector<MemoryItemViewModel^>()), m_MemorizedNumbers(ref new Vector<MemoryItemViewModel^>()),
m_IsMemoryEmpty(true), m_IsMemoryEmpty(true),
m_IsFToEChecked(false), m_IsFToEChecked(false),
@ -80,8 +80,8 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_isBinaryBitFlippingEnabled(false), m_isBinaryBitFlippingEnabled(false),
m_CurrentRadixType(RADIX_TYPE::DEC_RADIX), m_CurrentRadixType(RADIX_TYPE::DEC_RADIX),
m_CurrentAngleType(NumbersAndOperatorsEnum::Degree), m_CurrentAngleType(NumbersAndOperatorsEnum::Degree),
m_OpenParenthesisCount(L""),
m_Announcement(nullptr), m_Announcement(nullptr),
m_OpenParenthesisCount(0),
m_feedbackForButtonPress(nullptr), m_feedbackForButtonPress(nullptr),
m_isRtlLanguage(false), m_isRtlLanguage(false),
m_localizedMaxDigitsReachedAutomationFormat(nullptr), m_localizedMaxDigitsReachedAutomationFormat(nullptr),
@ -102,7 +102,6 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_localizedDecimalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::DecButton); m_localizedDecimalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::DecButton);
m_localizedOctalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::OctButton); m_localizedOctalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::OctButton);
m_localizedBinaryAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::BinButton); m_localizedBinaryAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::BinButton);
m_leftParenthesisAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::LeftParenthesisAutomationFormat);
// Initialize the Automation Name // Initialize the Automation Name
CalculationResultAutomationName = GetLocalizedStringFormat(m_localizedCalculationResultAutomationFormat, m_DisplayValue); CalculationResultAutomationName = GetLocalizedStringFormat(m_localizedCalculationResultAutomationFormat, m_DisplayValue);
@ -216,19 +215,23 @@ void StandardCalculatorViewModel::DisplayPasteError()
m_standardCalculatorManager.DisplayPasteError(); m_standardCalculatorManager.DisplayPasteError();
} }
void StandardCalculatorViewModel::SetParenthesisCount(_In_ const wstring& parenthesisCount) void StandardCalculatorViewModel::SetParenthesisCount(_In_ unsigned int parenthesisCount)
{ {
if (m_OpenParenthesisCount == parenthesisCount)
{
return;
}
OpenParenthesisCount = parenthesisCount;
if (IsProgrammer || IsScientific) if (IsProgrammer || IsScientific)
{ {
OpenParenthesisCount = ref new String(parenthesisCount.c_str()); SetOpenParenthesisCountNarratorAnnouncement();
RaisePropertyChanged("LeftParenthesisAutomationName");
} }
} }
void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement() void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement()
{ {
String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount); wstring localizedParenthesisCount = to_wstring(m_OpenParenthesisCount).c_str();
wstring localizedParenthesisCount = parenthesisCount->Data();
LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount); LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement( String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
@ -281,15 +284,6 @@ void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionC
} }
} }
String ^ StandardCalculatorViewModel::GetLeftParenthesisAutomationName()
{
String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount);
wstring localizedParenthesisCount = std::wstring(parenthesisCount->Data());
LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
return GetLocalizedStringFormat(m_leftParenthesisAutomationFormat, ref new String(localizedParenthesisCount.c_str()));
}
void StandardCalculatorViewModel::SetExpressionDisplay(_Inout_ shared_ptr<CalculatorVector<pair<wstring, int>>> const &tokens, _Inout_ shared_ptr<CalculatorVector <shared_ptr<IExpressionCommand>>> const &commands) void StandardCalculatorViewModel::SetExpressionDisplay(_Inout_ shared_ptr<CalculatorVector<pair<wstring, int>>> const &tokens, _Inout_ shared_ptr<CalculatorVector <shared_ptr<IExpressionCommand>>> const &commands)
{ {
m_tokens = tokens; m_tokens = tokens;
@ -321,59 +315,67 @@ void StandardCalculatorViewModel::SetTokens(_Inout_ shared_ptr<CalculatorVector<
{ {
AreTokensUpdated = false; AreTokensUpdated = false;
if (m_ExpressionTokens == nullptr)
{
m_ExpressionTokens = ref new Vector<DisplayExpressionToken^>();
}
else
{
m_ExpressionTokens->Clear();
}
unsigned int nTokens = 0; unsigned int nTokens = 0;
tokens->GetSize(&nTokens); tokens->GetSize(&nTokens);
if (nTokens == 0)
{
m_ExpressionTokens->Clear();
return;
}
pair <wstring, int> currentToken; pair <wstring, int> currentToken;
const auto& localizer = LocalizationSettings::GetInstance(); const auto& localizer = LocalizationSettings::GetInstance();
const wstring separator = L" ";
for (unsigned int i = 0; i < nTokens; ++i) for (unsigned int i = 0; i < nTokens; ++i)
{ {
if (SUCCEEDED(tokens->GetAt(i, &currentToken))) if (SUCCEEDED(tokens->GetAt(i, &currentToken)))
{ {
Common::TokenType type; Common::TokenType type;
const wstring separator = L" ";
bool isEditable = (currentToken.second == -1) ? false : true; bool isEditable = (currentToken.second == -1) ? false : true;
localizer.LocalizeDisplayValue(&(currentToken.first)); localizer.LocalizeDisplayValue(&(currentToken.first));
if (!isEditable) if (!isEditable)
{ {
if (currentToken.first == separator) type = currentToken.first == separator ? TokenType::Separator : TokenType::Operator;
{
type = TokenType::Separator;
}
else
{
type = TokenType::Operator;
}
} }
else else
{ {
shared_ptr<IExpressionCommand> command; shared_ptr<IExpressionCommand> command;
IFTPlatformException(m_commands->GetAt(static_cast<unsigned int>(currentToken.second), &command)); IFTPlatformException(m_commands->GetAt(static_cast<unsigned int>(currentToken.second), &command));
type = command->GetCommandType() == CommandType::OperandCommand ? TokenType::Operand : TokenType::Operator;
}
if (command->GetCommandType() == CommandType::OperandCommand) auto currentTokenString = ref new String(currentToken.first.c_str());
if (i < m_ExpressionTokens->Size)
{
auto existingItem = m_ExpressionTokens->GetAt(i);
if (type == existingItem->Type && existingItem->Token->Equals(currentTokenString))
{ {
type = TokenType::Operand; existingItem->TokenPosition = i;
existingItem->IsTokenEditable = isEditable;
existingItem->CommandIndex = 0;
} }
else else
{ {
type = TokenType::Operator; auto expressionToken = ref new DisplayExpressionToken(currentTokenString, i, isEditable, type);
m_ExpressionTokens->InsertAt(i, expressionToken);
} }
}
else
{
auto expressionToken = ref new DisplayExpressionToken(currentTokenString, i, isEditable, type);
m_ExpressionTokens->Append(expressionToken);
} }
DisplayExpressionToken^ expressionToken = ref new DisplayExpressionToken(ref new String(currentToken.first.c_str()), i, isEditable, type);
m_ExpressionTokens->Append(expressionToken);
} }
} }
while (m_ExpressionTokens->Size != nTokens)
{
m_ExpressionTokens->RemoveAtEnd();
}
} }
String^ StandardCalculatorViewModel::GetCalculatorExpressionAutomationName() String^ StandardCalculatorViewModel::GetCalculatorExpressionAutomationName()
@ -531,7 +533,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
{ {
if (commandIndex == 0) if (commandIndex == 0)
{ {
delete [] temp; delete[] temp;
return; return;
} }
@ -552,7 +554,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
length = m_selectedExpressionLastData->Length() + 1; length = m_selectedExpressionLastData->Length() + 1;
if (length > 50) if (length > 50)
{ {
delete [] temp; delete[] temp;
return; return;
} }
for (; i < length; ++i) for (; i < length; ++i)
@ -1422,29 +1424,29 @@ void StandardCalculatorViewModel::SaveEditedCommand(_In_ unsigned int tokenPosit
switch (nOpCode) switch (nOpCode)
{ {
case static_cast<int>(Command::CommandASIN) : case static_cast<int>(Command::CommandASIN) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSIN), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSIN), true, angleType);
break; break;
case static_cast<int>(Command::CommandACOS) : case static_cast<int>(Command::CommandACOS) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOS), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOS), true, angleType);
break; break;
case static_cast<int>(Command::CommandATAN) : case static_cast<int>(Command::CommandATAN) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTAN), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTAN), true, angleType);
break; break;
case static_cast<int>(Command::CommandASINH) : case static_cast<int>(Command::CommandASINH) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSINH), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSINH), true, angleType);
break; break;
case static_cast<int>(Command::CommandACOSH) : case static_cast<int>(Command::CommandACOSH) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOSH), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOSH), true, angleType);
break; break;
case static_cast<int>(Command::CommandATANH) : case static_cast<int>(Command::CommandATANH) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTANH), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTANH), true, angleType);
break; break;
case static_cast<int>(Command::CommandPOWE) : case static_cast<int>(Command::CommandPOWE) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandLN), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandLN), true, angleType);
break; break;
default: default:
updatedToken = CCalcEngine::OpCodeToUnaryString(nOpCode, false, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(nOpCode, false, angleType);
} }
if ((token.first.length() > 0) && (token.first[token.first.length() - 1] == L'(')) if ((token.first.length() > 0) && (token.first[token.first.length() - 1] == L'('))
{ {

View file

@ -48,7 +48,7 @@ namespace CalculatorApp
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError); OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError);
OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand); OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand);
OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayStringExpression); OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayStringExpression);
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<Common::DisplayExpressionToken^>^, ExpressionTokens); OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Common::DisplayExpressionToken^>^, ExpressionTokens);
OBSERVABLE_PROPERTY_RW(Platform::String^, DecimalDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, DecimalDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, OctalDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, OctalDisplayValue);
@ -75,18 +75,17 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_RW(bool, IsDwordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDwordEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsWordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsWordEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled); OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled);
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, OpenParenthesisCount);
OBSERVABLE_PROPERTY_RW(int, CurrentRadixType); OBSERVABLE_PROPERTY_RW(int, CurrentRadixType);
OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated); OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled); OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled);
OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled); OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement^, Announcement); OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement^, Announcement);
OBSERVABLE_PROPERTY_R(unsigned int, OpenParenthesisCount);
COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand); COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand);
COMMAND_FOR_METHOD(PasteCommand, StandardCalculatorViewModel::OnPasteCommand); COMMAND_FOR_METHOD(PasteCommand, StandardCalculatorViewModel::OnPasteCommand);
COMMAND_FOR_METHOD(ButtonPressed, StandardCalculatorViewModel::OnButtonPressed); COMMAND_FOR_METHOD(ButtonPressed, StandardCalculatorViewModel::OnButtonPressed);
COMMAND_FOR_METHOD(ClearMemoryCommand, StandardCalculatorViewModel::OnClearMemoryCommand); COMMAND_FOR_METHOD(ClearMemoryCommand, StandardCalculatorViewModel::OnClearMemoryCommand);
COMMAND_FOR_METHOD(PinUnpinAppBarButtonOnClicked, StandardCalculatorViewModel::OnPinUnpinCommand);
COMMAND_FOR_METHOD(MemoryItemPressed, StandardCalculatorViewModel::OnMemoryItemPressed); COMMAND_FOR_METHOD(MemoryItemPressed, StandardCalculatorViewModel::OnMemoryItemPressed);
COMMAND_FOR_METHOD(MemoryAdd, StandardCalculatorViewModel::OnMemoryAdd); COMMAND_FOR_METHOD(MemoryAdd, StandardCalculatorViewModel::OnMemoryAdd);
COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract); COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract);
@ -255,14 +254,6 @@ namespace CalculatorApp
void set(bool value) { m_completeTextSelection = value; } void set(bool value) { m_completeTextSelection = value; }
} }
property Platform::String^ LeftParenthesisAutomationName
{
Platform::String^ get()
{
return GetLeftParenthesisAutomationName();
}
}
internal: internal:
void OnPaste(Platform::String^ pastedString, CalculatorApp::Common::ViewMode mode); void OnPaste(Platform::String^ pastedString, CalculatorApp::Common::ViewMode mode);
void OnCopyCommand(Platform::Object^ parameter); void OnCopyCommand(Platform::Object^ parameter);
@ -283,7 +274,7 @@ namespace CalculatorApp
void SetTokens(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens); void SetTokens(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens);
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands); void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands);
void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands); void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands);
void SetParenthesisCount(_In_ const std::wstring& parenthesisCount); void SetParenthesisCount(_In_ unsigned int parenthesisCount);
void SetOpenParenthesisCountNarratorAnnouncement(); void SetOpenParenthesisCountNarratorAnnouncement();
void OnNoRightParenAdded(); void OnNoRightParenAdded();
void SetNoParenAddedNarratorAnnouncement(); void SetNoParenAddedNarratorAnnouncement();
@ -354,7 +345,6 @@ namespace CalculatorApp
bool m_isLastOperationHistoryLoad; bool m_isLastOperationHistoryLoad;
Platform::String^ m_selectedExpressionLastData; Platform::String^ m_selectedExpressionLastData;
Common::DisplayExpressionToken^ m_selectedExpressionToken; Common::DisplayExpressionToken^ m_selectedExpressionToken;
Platform::String^ m_leftParenthesisAutomationFormat;
Platform::String^ LocalizeDisplayValue(_In_ std::wstring const &displayValue, _In_ bool isError); Platform::String^ LocalizeDisplayValue(_In_ std::wstring const &displayValue, _In_ bool isError);
Platform::String^ CalculateNarratorDisplayValue(_In_ std::wstring const &displayValue, _In_ Platform::String^ localizedDisplayValue, _In_ bool isError); Platform::String^ CalculateNarratorDisplayValue(_In_ std::wstring const &displayValue, _In_ Platform::String^ localizedDisplayValue, _In_ bool isError);
@ -364,7 +354,6 @@ namespace CalculatorApp
CalculationManager::Command ConvertToOperatorsEnum(NumbersAndOperatorsEnum operation); CalculationManager::Command ConvertToOperatorsEnum(NumbersAndOperatorsEnum operation);
void DisableButtons(CalculationManager::CommandType selectedExpressionCommandType); void DisableButtons(CalculationManager::CommandType selectedExpressionCommandType);
Platform::String^ GetLeftParenthesisAutomationName();
Platform::String^ m_feedbackForButtonPress; Platform::String^ m_feedbackForButtonPress;
void OnButtonPressed(Platform::Object^ parameter); void OnButtonPressed(Platform::Object^ parameter);

View file

@ -165,12 +165,16 @@ void UnitConverterViewModel::PopulateData()
} }
void UnitConverterViewModel::OnCategoryChanged(Object^ parameter) void UnitConverterViewModel::OnCategoryChanged(Object^ parameter)
{
m_model->SendCommand(UCM::Command::Clear);
ResetCategory();
}
void UnitConverterViewModel::ResetCategory()
{ {
UCM::Category currentCategory = CurrentCategory->GetModelCategory(); UCM::Category currentCategory = CurrentCategory->GetModelCategory();
IsCurrencyCurrentCategory = currentCategory.id == NavCategory::Serialize(ViewMode::Currency); IsCurrencyCurrentCategory = currentCategory.id == NavCategory::Serialize(ViewMode::Currency);
m_model->SendCommand(UCM::Command::Clear);
m_isInputBlocked = false; m_isInputBlocked = false;
SetSelectedUnits(); SetSelectedUnits();
@ -706,7 +710,9 @@ void UnitConverterViewModel::OnCurrencyDataLoadFinished(bool didLoad)
{ {
m_isCurrencyDataLoaded = true; m_isCurrencyDataLoaded = true;
CurrencyDataLoadFailed = !didLoad; CurrencyDataLoadFailed = !didLoad;
ResetView(); m_model->ResetCategoriesAndRatios();
m_model->Calculate();
ResetCategory();
StringReference key = didLoad ? UnitConverterResourceKeys::CurrencyRatesUpdated : UnitConverterResourceKeys::CurrencyRatesUpdateFailed; StringReference key = didLoad ? UnitConverterResourceKeys::CurrencyRatesUpdated : UnitConverterResourceKeys::CurrencyRatesUpdateFailed;
String^ announcement = AppResourceProvider::GetInstance().GetResourceString(key); String^ announcement = AppResourceProvider::GetInstance().GetResourceString(key);

View file

@ -223,6 +223,7 @@ namespace CalculatorApp
void UpdateValue2AutomationName(); void UpdateValue2AutomationName();
Platform::String^ Serialize(); Platform::String^ Serialize();
void Deserialize(Platform::String^ state); void Deserialize(Platform::String^ state);
void ResetCategoriesAndRatio();
// 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 SaveUserPreferences();
@ -263,6 +264,7 @@ namespace CalculatorApp
void RefreshSupplementaryResults(); void RefreshSupplementaryResults();
void UpdateInputBlocked(_In_ const std::wstring& currencyInput); void UpdateInputBlocked(_In_ const std::wstring& currencyInput);
bool UnitsAreValid(); bool UnitsAreValid();
void ResetCategory();
void OnButtonPressed(Platform::Object^ parameter); void OnButtonPressed(Platform::Object^ parameter);
Platform::String^ ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings); Platform::String^ ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings);

View file

@ -16,6 +16,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalcViewModel", "CalcViewMo
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorUnitTests", "CalculatorUnitTests\CalculatorUnitTests.vcxproj", "{D3BAED2C-4B07-4E1D-8807-9D6499450349}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorUnitTests", "CalculatorUnitTests\CalculatorUnitTests.vcxproj", "{D3BAED2C-4B07-4E1D-8807-9D6499450349}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorUITests", "CalculatorUITests\CalculatorUITests.csproj", "{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM Debug|ARM = Debug|ARM
@ -28,22 +30,6 @@ Global
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.ActiveCfg = Debug|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.Build.0 = Debug|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM64.ActiveCfg = Debug|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM64.Build.0 = Debug|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x64.ActiveCfg = Debug|x64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x64.Build.0 = Debug|x64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.ActiveCfg = Debug|Win32
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.Build.0 = Debug|Win32
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.ActiveCfg = Release|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.Build.0 = Release|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM64.ActiveCfg = Release|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM64.Build.0 = Release|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Release|x64.ActiveCfg = Release|x64
{311E866D-8B93-4609-A691-265941FEE101}.Release|x64.Build.0 = Release|x64
{311E866D-8B93-4609-A691-265941FEE101}.Release|x86.ActiveCfg = Release|Win32
{311E866D-8B93-4609-A691-265941FEE101}.Release|x86.Build.0 = Release|Win32
{9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.ActiveCfg = Debug|ARM {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.ActiveCfg = Debug|ARM
{9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Build.0 = Debug|ARM {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Build.0 = Debug|ARM
{9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Deploy.0 = Debug|ARM {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Deploy.0 = Debug|ARM
@ -68,6 +54,22 @@ Global
{9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.ActiveCfg = Release|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.ActiveCfg = Release|Win32
{9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Build.0 = Release|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Build.0 = Release|Win32
{9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Deploy.0 = Release|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Deploy.0 = Release|Win32
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.ActiveCfg = Debug|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.Build.0 = Debug|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM64.ActiveCfg = Debug|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM64.Build.0 = Debug|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x64.ActiveCfg = Debug|x64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x64.Build.0 = Debug|x64
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.ActiveCfg = Debug|Win32
{311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.Build.0 = Debug|Win32
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.ActiveCfg = Release|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.Build.0 = Release|ARM
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM64.ActiveCfg = Release|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Release|ARM64.Build.0 = Release|ARM64
{311E866D-8B93-4609-A691-265941FEE101}.Release|x64.ActiveCfg = Release|x64
{311E866D-8B93-4609-A691-265941FEE101}.Release|x64.Build.0 = Release|x64
{311E866D-8B93-4609-A691-265941FEE101}.Release|x86.ActiveCfg = Release|Win32
{311E866D-8B93-4609-A691-265941FEE101}.Release|x86.Build.0 = Release|Win32
{90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.ActiveCfg = Debug|ARM {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.ActiveCfg = Debug|ARM
{90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.Build.0 = Debug|ARM {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.Build.0 = Debug|ARM
{90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM64.ActiveCfg = Debug|ARM64 {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM64.ActiveCfg = Debug|ARM64
@ -100,6 +102,22 @@ Global
{D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.ActiveCfg = Release|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.ActiveCfg = Release|Win32
{D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.Build.0 = Release|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.Build.0 = Release|Win32
{D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.Deploy.0 = Release|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.Deploy.0 = Release|Win32
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM.Build.0 = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM64.Build.0 = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x64.ActiveCfg = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x64.Build.0 = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x86.ActiveCfg = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x86.Build.0 = Debug|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM.ActiveCfg = Release|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM.Build.0 = Release|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM64.ActiveCfg = Release|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM64.Build.0 = Release|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x64.ActiveCfg = Release|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x64.Build.0 = Release|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x86.ActiveCfg = Release|Any CPU
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -19,7 +19,6 @@
<Color x:Key="ChromeMediumLowColor">#FF2B2B2B</Color> <Color x:Key="ChromeMediumLowColor">#FF2B2B2B</Color>
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource AltHighColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource AltHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/>
<SolidColorBrush x:Key="TitleBarBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/>
@ -55,7 +54,6 @@
<Color x:Key="ChromeMediumLowColor">#FFE0E0E0</Color> <Color x:Key="ChromeMediumLowColor">#FFE0E0E0</Color>
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource SystemAltHighColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource SystemAltHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/>
<SolidColorBrush x:Key="TitleBarBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/>
@ -89,7 +87,6 @@
<x:Double x:Key="HighContrastStrokeThickness">2</x:Double> <x:Double x:Key="HighContrastStrokeThickness">2</x:Double>
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="TitleBarBackgroundTransparentBrush" Color="{ThemeResource SystemColorActiveCaptionColor}"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{ThemeResource SystemColorCaptionTextColor}"/> <SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{ThemeResource SystemColorCaptionTextColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="{ThemeResource SystemColorHighlightColor}"/> <SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
@ -356,7 +353,8 @@
<Setter Property="ZoomMode" Value="Disabled"/> <Setter Property="ZoomMode" Value="Disabled"/>
</Style> </Style>
<Style x:Key="CalculationResultStyle" TargetType="Controls:CalculationResult"> <Style x:Key="CalculationResultStyle"
TargetType="Controls:CalculationResult">
<Setter Property="Background" Value="Transparent"/> <Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/> <Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/> <Setter Property="HorizontalAlignment" Value="Stretch"/>
@ -368,7 +366,7 @@
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Controls:CalculationResult"> <ControlTemplate TargetType="Controls:CalculationResult">
<Grid x:Name="border" Background="{TemplateBinding Background}"> <Grid x:Name="Border" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="12"/> <ColumnDefinition Width="12"/>
<ColumnDefinition/> <ColumnDefinition/>
@ -378,19 +376,19 @@
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"> <VisualState x:Name="Active">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="SemiBold"/> <Setter Target="NormalOutput.FontWeight" Value="SemiBold"/>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/> <Setter Target="NormalOutput.IsTextSelectionEnabled" Value="True"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/> <VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="TextContainer"
Grid.Column="1" Grid.Column="1"
Padding="0,0,0,0" Padding="0,0,0,0"
Style="{ThemeResource ResultsScrollerSnapped}" Style="{ThemeResource ResultsScrollerSnapped}"
AutomationProperties.AccessibilityView="Raw"> AutomationProperties.AccessibilityView="Raw">
<TextBlock x:Name="normalOutput" <TextBlock x:Name="NormalOutput"
Margin="{TemplateBinding DisplayMargin}" Margin="{TemplateBinding DisplayMargin}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
@ -402,7 +400,7 @@
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"
TextWrapping="NoWrap"/> TextWrapping="NoWrap"/>
</ScrollViewer> </ScrollViewer>
<HyperlinkButton x:Name="scrollLeft" <HyperlinkButton x:Name="ScrollLeft"
Grid.Column="0" Grid.Column="0"
Width="20" Width="20"
MinWidth="20" MinWidth="20"
@ -415,12 +413,12 @@
Foreground="{ThemeResource SystemControlForegroundAccentBrush}" Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0" BorderThickness="0"
Visibility="Collapsed"> Visibility="Collapsed">
<FontIcon x:Name="scrollLeftText" <FontIcon x:Name="ScrollLeftText"
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12" FontSize="12"
Glyph="&#xE26C;"/> Glyph="&#xE26C;"/>
</HyperlinkButton> </HyperlinkButton>
<HyperlinkButton x:Name="scrollRight" <HyperlinkButton x:Name="ScrollRight"
Grid.Column="2" Grid.Column="2"
Width="20" Width="20"
MinWidth="20" MinWidth="20"
@ -433,7 +431,7 @@
Foreground="{ThemeResource SystemControlForegroundAccentBrush}" Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0" BorderThickness="0"
Visibility="Collapsed"> Visibility="Collapsed">
<FontIcon x:Name="scrollRightText" <FontIcon x:Name="ScrollRightText"
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12" FontSize="12"
Glyph="&#xE26B;"/> Glyph="&#xE26B;"/>

View file

@ -233,12 +233,14 @@ void App::OnAppLaunch(IActivatedEventArgs^ args, String^ argument)
TraceLogger::GetInstance().LogOnAppLaunch(previousExecutionState.ToString()->Data()); TraceLogger::GetInstance().LogOnAppLaunch(previousExecutionState.ToString()->Data());
#if _DEBUG // Uncomment the following lines to display frame-rate and per-frame CPU usage info.
if (IsDebuggerPresent()) //#if _DEBUG
{ // if (IsDebuggerPresent())
DebugSettings->EnableFrameRateCounter = true; // {
} // DebugSettings->EnableFrameRateCounter = true;
#endif // }
//#endif
auto userSettings = ref new Windows::UI::ViewManagement::UISettings(); auto userSettings = ref new Windows::UI::ViewManagement::UISettings();
m_isAnimationEnabled = userSettings->AnimationsEnabled; m_isAnimationEnabled = userSettings->AnimationsEnabled;

View file

@ -234,19 +234,15 @@
<ClInclude Include="Controls\OverflowTextBlockAutomationPeer.h" /> <ClInclude Include="Controls\OverflowTextBlockAutomationPeer.h" />
<ClInclude Include="Common\AlwaysSelectedCollectionView.h" /> <ClInclude Include="Common\AlwaysSelectedCollectionView.h" />
<ClInclude Include="Common\BindableBase.h" /> <ClInclude Include="Common\BindableBase.h" />
<ClInclude Include="Controls\AppBar.h" />
<ClInclude Include="Controls\CalculationResult.h" /> <ClInclude Include="Controls\CalculationResult.h" />
<ClInclude Include="Controls\CalculatorButton.h" /> <ClInclude Include="Controls\CalculatorButton.h" />
<ClInclude Include="Controls\FlipButtons.h" /> <ClInclude Include="Controls\FlipButtons.h" />
<ClInclude Include="Controls\OperandTextBox.h" />
<ClInclude Include="Controls\OperatorTextBox.h" />
<ClInclude Include="Controls\OverflowTextBlock.h" /> <ClInclude Include="Controls\OverflowTextBlock.h" />
<ClInclude Include="Controls\RadixButton.h" /> <ClInclude Include="Controls\RadixButton.h" />
<ClInclude Include="Controls\SupplementaryItemsControl.h" /> <ClInclude Include="Controls\SupplementaryItemsControl.h" />
<ClInclude Include="Converters\BitFlipAutomationNameConverter.h" /> <ClInclude Include="Converters\BitFlipAutomationNameConverter.h" />
<ClInclude Include="Converters\BooleanNegationConverter.h" /> <ClInclude Include="Converters\BooleanNegationConverter.h" />
<ClInclude Include="Converters\BooleanToVisibilityConverter.h" /> <ClInclude Include="Converters\BooleanToVisibilityConverter.h" />
<ClInclude Include="Converters\ExpressionItemContainerStyle.h" />
<ClInclude Include="Converters\ExpressionItemTemplateSelector.h" /> <ClInclude Include="Converters\ExpressionItemTemplateSelector.h" />
<ClInclude Include="Converters\ItemSizeToVisibilityConverter.h" /> <ClInclude Include="Converters\ItemSizeToVisibilityConverter.h" />
<ClInclude Include="Converters\RadixToStringConverter.h" /> <ClInclude Include="Converters\RadixToStringConverter.h" />
@ -256,7 +252,6 @@
<ClInclude Include="App.xaml.h"> <ClInclude Include="App.xaml.h">
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
</ClInclude> </ClInclude>
<ClInclude Include="Common\TitleBarHelper.h" />
<ClInclude Include="Views\Calculator.xaml.h"> <ClInclude Include="Views\Calculator.xaml.h">
<DependentUpon>Views\Calculator.xaml</DependentUpon> <DependentUpon>Views\Calculator.xaml</DependentUpon>
</ClInclude> </ClInclude>
@ -372,15 +367,12 @@
<ClCompile Include="Controls\CalculationResult.cpp" /> <ClCompile Include="Controls\CalculationResult.cpp" />
<ClCompile Include="Controls\CalculatorButton.cpp" /> <ClCompile Include="Controls\CalculatorButton.cpp" />
<ClCompile Include="Controls\FlipButtons.cpp" /> <ClCompile Include="Controls\FlipButtons.cpp" />
<ClCompile Include="Controls\OperandTextBox.cpp" />
<ClCompile Include="Controls\OperatorTextBox.cpp" />
<ClCompile Include="Controls\OverflowTextBlock.cpp" /> <ClCompile Include="Controls\OverflowTextBlock.cpp" />
<ClCompile Include="Controls\RadixButton.cpp" /> <ClCompile Include="Controls\RadixButton.cpp" />
<ClCompile Include="Controls\SupplementaryItemsControl.cpp" /> <ClCompile Include="Controls\SupplementaryItemsControl.cpp" />
<ClCompile Include="Converters\BitFlipAutomationNameConverter.cpp" /> <ClCompile Include="Converters\BitFlipAutomationNameConverter.cpp" />
<ClCompile Include="Converters\BooleanNegationConverter.cpp" /> <ClCompile Include="Converters\BooleanNegationConverter.cpp" />
<ClCompile Include="Converters\BooleanToVisibilityConverter.cpp" /> <ClCompile Include="Converters\BooleanToVisibilityConverter.cpp" />
<ClCompile Include="Converters\ExpressionItemContainerStyle.cpp" />
<ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp" /> <ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp" />
<ClCompile Include="Converters\ItemSizeToVisibilityConverter.cpp" /> <ClCompile Include="Converters\ItemSizeToVisibilityConverter.cpp" />
<ClCompile Include="Converters\RadixToStringConverter.cpp" /> <ClCompile Include="Converters\RadixToStringConverter.cpp" />
@ -396,7 +388,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="Common\TitleBarHelper.cpp" />
<ClCompile Include="Views\Calculator.xaml.cpp"> <ClCompile Include="Views\Calculator.xaml.cpp">
<DependentUpon>Views\Calculator.xaml</DependentUpon> <DependentUpon>Views\Calculator.xaml</DependentUpon>
</ClCompile> </ClCompile>

View file

@ -243,9 +243,6 @@
<ClCompile Include="Converters\BooleanToVisibilityConverter.cpp"> <ClCompile Include="Converters\BooleanToVisibilityConverter.cpp">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Converters\ExpressionItemContainerStyle.cpp">
<Filter>Converters</Filter>
</ClCompile>
<ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp"> <ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClCompile> </ClCompile>
@ -271,12 +268,6 @@
<ClCompile Include="Views\NumberPad.xaml.cpp" /> <ClCompile Include="Views\NumberPad.xaml.cpp" />
<ClCompile Include="Views\SupplementaryResults.xaml.cpp" /> <ClCompile Include="Views\SupplementaryResults.xaml.cpp" />
<ClCompile Include="Views\UnitConverter.xaml.cpp" /> <ClCompile Include="Views\UnitConverter.xaml.cpp" />
<ClCompile Include="Controls\OperandTextBox.cpp">
<Filter>Controls</Filter>
</ClCompile>
<ClCompile Include="Controls\OperatorTextBox.cpp">
<Filter>Controls</Filter>
</ClCompile>
<ClCompile Include="Controls\FlipButtons.cpp"> <ClCompile Include="Controls\FlipButtons.cpp">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClCompile> </ClCompile>
@ -287,9 +278,6 @@
</ClCompile> </ClCompile>
<ClCompile Include="WindowFrameService.cpp" /> <ClCompile Include="WindowFrameService.cpp" />
<ClCompile Include="Views\DateCalculator.xaml.cpp" /> <ClCompile Include="Views\DateCalculator.xaml.cpp" />
<ClCompile Include="Common\TitleBarHelper.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Controls\CalculationResultAutomationPeer.cpp"> <ClCompile Include="Controls\CalculationResultAutomationPeer.cpp">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClCompile> </ClCompile>
@ -299,7 +287,6 @@
<ClCompile Include="Views\StateTriggers\AspectRatioTrigger.cpp"> <ClCompile Include="Views\StateTriggers\AspectRatioTrigger.cpp">
<Filter>Views\StateTriggers</Filter> <Filter>Views\StateTriggers</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Views\TitleBar.xaml.cpp" />
<ClCompile Include="Views\MemoryListItem.xaml.cpp" /> <ClCompile Include="Views\MemoryListItem.xaml.cpp" />
<ClCompile Include="Views\OperatorsPanel.xaml.cpp" /> <ClCompile Include="Views\OperatorsPanel.xaml.cpp" />
<ClCompile Include="Controls\SupplementaryItemsControl.cpp"> <ClCompile Include="Controls\SupplementaryItemsControl.cpp">
@ -311,6 +298,7 @@
<ClCompile Include="Controls\HorizontalNoOverflowStackPanel.cpp"> <ClCompile Include="Controls\HorizontalNoOverflowStackPanel.cpp">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Views\TitleBar.xaml.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
@ -321,9 +309,6 @@
<ClInclude Include="Common\BindableBase.h"> <ClInclude Include="Common\BindableBase.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Controls\AppBar.h">
<Filter>Controls</Filter>
</ClInclude>
<ClInclude Include="Controls\CalculationResult.h"> <ClInclude Include="Controls\CalculationResult.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
@ -342,9 +327,6 @@
<ClInclude Include="Converters\BooleanToVisibilityConverter.h"> <ClInclude Include="Converters\BooleanToVisibilityConverter.h">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Converters\ExpressionItemContainerStyle.h">
<Filter>Converters</Filter>
</ClInclude>
<ClInclude Include="Converters\ExpressionItemTemplateSelector.h"> <ClInclude Include="Converters\ExpressionItemTemplateSelector.h">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClInclude> </ClInclude>
@ -370,12 +352,6 @@
<ClInclude Include="Views\NumberPad.xaml.h" /> <ClInclude Include="Views\NumberPad.xaml.h" />
<ClInclude Include="Views\SupplementaryResults.xaml.h" /> <ClInclude Include="Views\SupplementaryResults.xaml.h" />
<ClInclude Include="Views\UnitConverter.xaml.h" /> <ClInclude Include="Views\UnitConverter.xaml.h" />
<ClInclude Include="Controls\OperandTextBox.h">
<Filter>Controls</Filter>
</ClInclude>
<ClInclude Include="Controls\OperatorTextBox.h">
<Filter>Controls</Filter>
</ClInclude>
<ClInclude Include="Controls\FlipButtons.h"> <ClInclude Include="Controls\FlipButtons.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
@ -389,9 +365,6 @@
<ClInclude Include="Converters\BitFlipAutomationNameConverter.h"> <ClInclude Include="Converters\BitFlipAutomationNameConverter.h">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\TitleBarHelper.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Controls\CalculationResultAutomationPeer.h"> <ClInclude Include="Controls\CalculationResultAutomationPeer.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
@ -401,7 +374,6 @@
<ClInclude Include="Views\StateTriggers\AspectRatioTrigger.h"> <ClInclude Include="Views\StateTriggers\AspectRatioTrigger.h">
<Filter>Views\StateTriggers</Filter> <Filter>Views\StateTriggers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Views\TitleBar.xaml.h" />
<ClInclude Include="Views\MemoryListItem.xaml.h" /> <ClInclude Include="Views\MemoryListItem.xaml.h" />
<ClInclude Include="Views\OperatorsPanel.xaml.h" /> <ClInclude Include="Views\OperatorsPanel.xaml.h" />
<ClInclude Include="Controls\SupplementaryItemsControl.h"> <ClInclude Include="Controls\SupplementaryItemsControl.h">
@ -413,6 +385,7 @@
<ClInclude Include="Controls\HorizontalNoOverflowStackPanel.h"> <ClInclude Include="Controls\HorizontalNoOverflowStackPanel.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Views\TitleBar.xaml.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AppxManifest Include="Package.appxmanifest" /> <AppxManifest Include="Package.appxmanifest" />
@ -471,15 +444,15 @@
<Page Include="Views\DateCalculator.xaml"> <Page Include="Views\DateCalculator.xaml">
<Filter>Views</Filter> <Filter>Views</Filter>
</Page> </Page>
<Page Include="Views\TitleBar.xaml">
<Filter>Views</Filter>
</Page>
<Page Include="Views\MemoryListItem.xaml"> <Page Include="Views\MemoryListItem.xaml">
<Filter>Views</Filter> <Filter>Views</Filter>
</Page> </Page>
<Page Include="Views\OperatorsPanel.xaml"> <Page Include="Views\OperatorsPanel.xaml">
<Filter>Views</Filter> <Filter>Views</Filter>
</Page> </Page>
<Page Include="Views\TitleBar.xaml">
<Filter>Views</Filter>
</Page>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PRIResource Include="Resources\en-US\CEngineStrings.resw"> <PRIResource Include="Resources\en-US\CEngineStrings.resw">

View file

@ -1,94 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "TitleBarHelper.h"
#include "Converters/BooleanToVisibilityConverter.h"
#include "CalcViewModel/ViewState.h"
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Converters;
using namespace Platform;
using namespace std;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
unique_ptr<TitleBarHelper> TitleBarHelper::CreateTitleBarHelperIfNotDocked(FrameworkElement^ customTitleBar)
{
return (App::GetAppViewState() == ViewState::DockedView)
? nullptr
: CalculatorApp::Common::TitleBarHelper::CreateTitleBarHelper(customTitleBar);
}
unique_ptr<TitleBarHelper> TitleBarHelper::CreateTitleBarHelper(_In_ FrameworkElement^ customTitleBar)
{
assert(customTitleBar != nullptr);
if (customTitleBar != nullptr)
{
CoreApplicationViewTitleBar^ coreTitleBar = CoreApplication::GetCurrentView()->TitleBar;
assert(coreTitleBar != nullptr);
if (coreTitleBar != nullptr)
{
return make_unique<TitleBarHelper>(coreTitleBar, customTitleBar);
}
}
return nullptr;
}
TitleBarHelper::TitleBarHelper(_In_ CoreApplicationViewTitleBar^ coreTitleBar, _In_ FrameworkElement^ customTitleBar) :
m_coreTitleBar(coreTitleBar),
m_customTitleBar(customTitleBar)
{
RegisterForLayoutChanged();
RegisterForVisibilityChanged();
SetCustomTitleBar();
}
TitleBarHelper::~TitleBarHelper()
{
m_coreTitleBar->LayoutMetricsChanged -= m_layoutChangedToken;
m_coreTitleBar->IsVisibleChanged -= m_visibilityChangedToken;
}
void TitleBarHelper::SetTitleBarHeight(double height)
{
m_customTitleBar->Height = height;
}
void TitleBarHelper::SetTitleBarVisibility(bool isVisible)
{
m_customTitleBar->Visibility = BooleanToVisibilityConverter::Convert(isVisible);
}
void TitleBarHelper::RegisterForLayoutChanged()
{
m_layoutChangedToken =
m_coreTitleBar->LayoutMetricsChanged += ref new TypedEventHandler<CoreApplicationViewTitleBar^, Object^>(
[this](CoreApplicationViewTitleBar^ cTitleBar, Object^)
{
// Update title bar control size as needed to account for system size changes
SetTitleBarHeight(cTitleBar->Height);
});
}
void TitleBarHelper::RegisterForVisibilityChanged()
{
m_visibilityChangedToken =
m_coreTitleBar->IsVisibleChanged += ref new TypedEventHandler<CoreApplicationViewTitleBar^, Object^>(
[this](CoreApplicationViewTitleBar^ cTitleBar, Object^)
{
// Update title bar visibility
SetTitleBarVisibility(cTitleBar->IsVisible);
});
}
void TitleBarHelper::SetCustomTitleBar()
{
// Set custom XAML Title Bar
m_coreTitleBar->ExtendViewIntoTitleBar = true;
SetTitleBarHeight(m_coreTitleBar->Height);
SetTitleBarVisibility(m_coreTitleBar->IsVisible);
Window::Current->SetTitleBar(m_customTitleBar);
}

View file

@ -1,40 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Common
{
class TitleBarHelper
{
public:
static std::unique_ptr<TitleBarHelper> CreateTitleBarHelperIfNotDocked(
_In_ Windows::UI::Xaml::FrameworkElement^ customTitleBar);
// Prefer CreateTitleBarHelper over constructing your own instance,
// because Create* will nullcheck the parameters.
static std::unique_ptr<TitleBarHelper> CreateTitleBarHelper(
_In_ Windows::UI::Xaml::FrameworkElement^ customTitleBar);
TitleBarHelper(
_In_ Windows::ApplicationModel::Core::CoreApplicationViewTitleBar^ coreTitleBar,
_In_ Windows::UI::Xaml::FrameworkElement^ customTitleBar);
~TitleBarHelper();
void SetTitleBarHeight(double height);
void SetTitleBarVisibility(bool isVisible);
private:
void RegisterForLayoutChanged();
void RegisterForVisibilityChanged();
void SetCustomTitleBar();
Platform::Agile<Windows::ApplicationModel::Core::CoreApplicationViewTitleBar^> m_coreTitleBar;
Windows::UI::Xaml::FrameworkElement^ m_customTitleBar;
Windows::Foundation::EventRegistrationToken m_layoutChangedToken;
Windows::Foundation::EventRegistrationToken m_visibilityChangedToken;
};
}
}

View file

@ -1,29 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Common/KeyboardShortcutManager.h"
namespace CalculatorApp
{
namespace Controls
{
public ref class AppBar sealed : public Windows::UI::Xaml::Controls::AppBar
{
public:
AppBar()
{}
protected:
virtual void OnKeyDown(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) override
{
Windows::UI::Xaml::Controls::AppBar::OnKeyDown(e);
if (e->Key == Windows::System::VirtualKey::Escape)
{
Common::KeyboardShortcutManager::IgnoreEscape(true);
}
}
};
}
}

View file

@ -72,7 +72,7 @@ void CalculationResult::OnApplyTemplate()
{ {
m_textContainer->LayoutUpdated -= m_textContainerLayoutChangedToken; m_textContainer->LayoutUpdated -= m_textContainerLayoutChangedToken;
} }
m_textContainer = dynamic_cast<ScrollViewer^>(GetTemplateChild("textContainer")); m_textContainer = dynamic_cast<ScrollViewer^>(GetTemplateChild("TextContainer"));
if (m_textContainer) if (m_textContainer)
{ {
m_textContainer->SizeChanged += ref new SizeChangedEventHandler(this, &CalculationResult::TextContainerSizeChanged); m_textContainer->SizeChanged += ref new SizeChangedEventHandler(this, &CalculationResult::TextContainerSizeChanged);
@ -81,9 +81,9 @@ void CalculationResult::OnApplyTemplate()
m_textContainerLayoutChangedToken = m_textContainer->LayoutUpdated += ref new EventHandler<Object^>(this, &CalculationResult::OnTextContainerLayoutUpdated); m_textContainerLayoutChangedToken = m_textContainer->LayoutUpdated += ref new EventHandler<Object^>(this, &CalculationResult::OnTextContainerLayoutUpdated);
m_textContainer->ChangeView(m_textContainer->ExtentWidth - m_textContainer->ViewportWidth,nullptr,nullptr); m_textContainer->ChangeView(m_textContainer->ExtentWidth - m_textContainer->ViewportWidth,nullptr,nullptr);
m_scrollLeft = dynamic_cast<HyperlinkButton^>(GetTemplateChild("scrollLeft")); m_scrollLeft = dynamic_cast<HyperlinkButton^>(GetTemplateChild("ScrollLeft"));
m_scrollRight = dynamic_cast<HyperlinkButton^>(GetTemplateChild("scrollRight")); m_scrollRight = dynamic_cast<HyperlinkButton^>(GetTemplateChild("ScrollRight"));
auto borderContainer = dynamic_cast<UIElement^>(GetTemplateChild("border")); auto borderContainer = dynamic_cast<UIElement^>(GetTemplateChild("Border"));
if (m_scrollLeft && m_scrollRight) if (m_scrollLeft && m_scrollRight)
{ {
m_scrollLeft->Click += ref new RoutedEventHandler(this, &CalculationResult::OnScrollClick); m_scrollLeft->Click += ref new RoutedEventHandler(this, &CalculationResult::OnScrollClick);
@ -91,7 +91,7 @@ void CalculationResult::OnApplyTemplate()
borderContainer->PointerEntered += ref new PointerEventHandler(this, &CalculationResult::OnPointerEntered); borderContainer->PointerEntered += ref new PointerEventHandler(this, &CalculationResult::OnPointerEntered);
borderContainer->PointerExited += ref new PointerEventHandler(this, &CalculationResult::OnPointerExited); borderContainer->PointerExited += ref new PointerEventHandler(this, &CalculationResult::OnPointerExited);
} }
m_textBlock = dynamic_cast<TextBlock^>(m_textContainer->FindName("normalOutput")); m_textBlock = dynamic_cast<TextBlock^>(m_textContainer->FindName("NormalOutput"));
if (m_textBlock) if (m_textBlock)
{ {
m_textBlock->Visibility = ::Visibility::Visible; m_textBlock->Visibility = ::Visibility::Visible;

View file

@ -1,58 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "OperandTextBox.h"
#include "regex"
using namespace CalculatorApp;
using namespace CalculatorApp::Controls;
using namespace Platform;
using namespace std;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Input;
using namespace Windows::System;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
void OperandTextBox::OnApplyTemplate()
{
this->IsEnabled = false;
this->IsHitTestVisible = false;
this->IsTapEnabled = false;
this->MaxLength = 50;
this->IsRightTapEnabled = false;
this->IsTabStop = false;
auto parent = VisualTreeHelper::GetParent(this);
ListViewItem^ listViewItem;
ListView^ listView;
while (parent != nullptr)
{
if (listViewItem == nullptr)
{
listViewItem = dynamic_cast<ListViewItem^>(parent);
}
listView = dynamic_cast<ListView^>(parent);
if (listView != nullptr)
{
break;
}
parent = VisualTreeHelper::GetParent(parent);
}
if (listView != nullptr)
{
listViewItem->IsEnabled = false;
listViewItem->IsHitTestVisible = false;
listViewItem->IsTapEnabled = false;
}
TextBox::OnApplyTemplate();
}

View file

@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Controls
{
public ref class OperandTextBox sealed : public Windows::UI::Xaml::Controls::TextBox
{
public:
OperandTextBox() { }
protected:
virtual void OnApplyTemplate() override;
};
}
}

View file

@ -1,59 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "OperatorTextBox.h"
#include "regex"
using namespace CalculatorApp;
using namespace CalculatorApp::Controls;
using namespace Platform;
using namespace std;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Input;
using namespace Windows::System;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
void OperatorTextBox::OnApplyTemplate()
{
this->IsEnabled = false;
this->IsHitTestVisible = false;
this->IsTapEnabled = false;
this->MaxLength = 50;
this->IsReadOnly = true;
this->IsRightTapEnabled = false;
this->IsTabStop = false;
auto parent = VisualTreeHelper::GetParent(this);
ListViewItem^ listViewItem;
ListView^ listView;
while (parent != nullptr)
{
if (listViewItem == nullptr)
{
listViewItem = dynamic_cast<ListViewItem^>(parent);
}
listView = dynamic_cast<ListView^>(parent);
if (listView != nullptr)
{
break;
}
parent = VisualTreeHelper::GetParent(parent);
}
if (listView != nullptr)
{
listViewItem->IsEnabled = false;
listViewItem->IsHitTestVisible = false;
listViewItem->IsTapEnabled = false;
}
TextBox::OnApplyTemplate();
}

View file

@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Controls
{
public ref class OperatorTextBox sealed : public Windows::UI::Xaml::Controls::TextBox
{
public:
OperatorTextBox() { }
protected:
virtual void OnApplyTemplate() override;
};
}
}

View file

@ -30,25 +30,38 @@ DEPENDENCY_PROPERTY_INITIALIZATION(OverflowTextBlock, TokensUpdated);
void OverflowTextBlock::OnApplyTemplate() void OverflowTextBlock::OnApplyTemplate()
{ {
assert(((m_scrollLeft == nullptr) && (m_scrollRight == nullptr)) || ((m_scrollLeft != nullptr) && (m_scrollRight != nullptr))); UnregisterEventHandlers();
m_expressionContainer = safe_cast<ScrollViewer^>(GetTemplateChild("expressionContainer")); auto uiElement = GetTemplateChild("ExpressionContainer");
m_expressionContainer->ChangeView(m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth, nullptr, nullptr); if (uiElement != nullptr)
{
m_expressionContainer = safe_cast<ScrollViewer^>(uiElement);
m_expressionContainer->ChangeView(m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth, nullptr, nullptr);
m_containerViewChangedToken = m_expressionContainer->ViewChanged += ref new EventHandler<ScrollViewerViewChangedEventArgs ^>(this, &OverflowTextBlock::OnViewChanged);
}
m_scrollLeft = safe_cast<Button^>(GetTemplateChild("scrollLeft")); uiElement = GetTemplateChild("ScrollLeft");
m_scrollRight = safe_cast<Button^>(GetTemplateChild("scrollRight")); if (uiElement != nullptr)
{
m_scrollLeft = safe_cast<Button^>(uiElement);
m_scrollLeftClickEventToken = m_scrollLeft->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick);
}
m_scrollLeftClickEventToken = m_scrollLeft->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick); uiElement = GetTemplateChild("ScrollRight");
m_scrollRightClickEventToken = m_scrollRight->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick); if (uiElement != nullptr)
{
m_scrollRight = safe_cast<Button^>(uiElement);
m_scrollRightClickEventToken = m_scrollRight->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick);
}
m_scrollingLeft = false; m_scrollingLeft = false;
m_scrollingRight = false; m_scrollingRight = false;
auto borderContainer = safe_cast<Border^>(GetTemplateChild("expressionborder")); uiElement = GetTemplateChild("TokenList");
m_pointerEnteredEventToken = borderContainer->PointerEntered += ref new PointerEventHandler(this, &OverflowTextBlock::OnPointerEntered); if (uiElement != nullptr)
m_pointerExitedEventToken = borderContainer->PointerExited += ref new PointerEventHandler(this, &OverflowTextBlock::OnPointerExited); {
m_itemsControl = safe_cast<ItemsControl^>(uiElement);
m_listView = safe_cast<ListView^>(GetTemplateChild("TokenList")); }
UpdateAllState(); UpdateAllState();
} }
@ -60,18 +73,19 @@ AutomationPeer^ OverflowTextBlock::OnCreateAutomationPeer()
void OverflowTextBlock::OnTokensUpdatedPropertyChanged(bool /*oldValue*/, bool newValue) void OverflowTextBlock::OnTokensUpdatedPropertyChanged(bool /*oldValue*/, bool newValue)
{ {
if ((m_listView != nullptr) && (newValue)) if (m_expressionContainer != nullptr && newValue)
{ {
unsigned int tokenCount = m_listView->Items->Size; m_expressionContainer->UpdateLayout();
if (tokenCount > 0) m_expressionContainer->ChangeView(m_expressionContainer->ScrollableWidth, nullptr, nullptr, true);
{
m_listView->UpdateLayout();
m_listView->ScrollIntoView(m_listView->Items->GetAt(tokenCount - 1));
m_expressionContainer->ChangeView(m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth, nullptr, nullptr);
}
} }
AutomationProperties::SetAccessibilityView(this, auto newIsAccessibilityViewControl = m_itemsControl != nullptr && m_itemsControl->Items->Size > 0;
m_listView != nullptr && m_listView->Items->Size > 0 ? AccessibilityView::Control : AccessibilityView::Raw); if (m_isAccessibilityViewControl != newIsAccessibilityViewControl)
{
m_isAccessibilityViewControl = newIsAccessibilityViewControl;
AutomationProperties::SetAccessibilityView(this,
newIsAccessibilityViewControl ? AccessibilityView::Control : AccessibilityView::Raw);
}
UpdateScrollButtons();
} }
void OverflowTextBlock::UpdateAllState() void OverflowTextBlock::UpdateAllState()
@ -93,7 +107,7 @@ void OverflowTextBlock::UpdateVisualState()
void OverflowTextBlock::ScrollLeft() void OverflowTextBlock::ScrollLeft()
{ {
if (m_expressionContainer->HorizontalOffset > 0) if (m_expressionContainer != nullptr && m_expressionContainer->HorizontalOffset > 0)
{ {
m_scrollingLeft = true; m_scrollingLeft = true;
double offset = m_expressionContainer->HorizontalOffset - (scrollRatio * m_expressionContainer->ViewportWidth); double offset = m_expressionContainer->HorizontalOffset - (scrollRatio * m_expressionContainer->ViewportWidth);
@ -105,7 +119,7 @@ void OverflowTextBlock::ScrollLeft()
void OverflowTextBlock::ScrollRight() void OverflowTextBlock::ScrollRight()
{ {
if (m_expressionContainer->HorizontalOffset < m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth) if (m_expressionContainer != nullptr && m_expressionContainer->HorizontalOffset < m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth)
{ {
m_scrollingRight = true; m_scrollingRight = true;
double offset = m_expressionContainer->HorizontalOffset + (scrollRatio * m_expressionContainer->ViewportWidth); double offset = m_expressionContainer->HorizontalOffset + (scrollRatio * m_expressionContainer->ViewportWidth);
@ -128,26 +142,15 @@ void OverflowTextBlock::OnScrollClick(_In_ Object^ sender, _In_ RoutedEventArgs^
} }
} }
void OverflowTextBlock::OnPointerEntered(_In_ Object^, _In_ PointerRoutedEventArgs^ e)
{
if (e->Pointer->PointerDeviceType == PointerDeviceType::Mouse)
{
UpdateScrollButtons();
}
}
void OverflowTextBlock::OnPointerExited(_In_ Object^, _In_ PointerRoutedEventArgs^ e)
{
if (e->Pointer->PointerDeviceType == PointerDeviceType::Mouse)
{
UpdateScrollButtons();
}
}
void OverflowTextBlock::UpdateScrollButtons() void OverflowTextBlock::UpdateScrollButtons()
{ {
if (m_itemsControl == nullptr || m_expressionContainer == nullptr)
{
return;
}
// When the width is smaller than the container, don't show any // When the width is smaller than the container, don't show any
if (m_listView->ActualWidth <= m_expressionContainer->ActualWidth) if (m_itemsControl->ActualWidth <= m_expressionContainer->ActualWidth)
{ {
ShowHideScrollButtons(::Visibility::Collapsed, ::Visibility::Collapsed); ShowHideScrollButtons(::Visibility::Collapsed, ::Visibility::Collapsed);
} }
@ -163,7 +166,10 @@ void OverflowTextBlock::UpdateScrollButtons()
if (m_scrollingLeft) if (m_scrollingLeft)
{ {
m_scrollingLeft = false; m_scrollingLeft = false;
m_scrollRight->Focus(::FocusState::Programmatic); if (m_scrollRight != nullptr)
{
m_scrollRight->Focus(::FocusState::Programmatic);
}
} }
} }
else // Width is larger than the container and right most part of the number is shown. Should be able to scroll left. else // Width is larger than the container and right most part of the number is shown. Should be able to scroll left.
@ -172,7 +178,10 @@ void OverflowTextBlock::UpdateScrollButtons()
if (m_scrollingRight) if (m_scrollingRight)
{ {
m_scrollingRight = false; m_scrollingRight = false;
m_scrollLeft->Focus(::FocusState::Programmatic); if (m_scrollLeft != nullptr)
{
m_scrollLeft->Focus(::FocusState::Programmatic);
}
} }
} }
} }
@ -199,12 +208,13 @@ void OverflowTextBlock::UnregisterEventHandlers()
m_scrollRight->Click -= m_scrollRightClickEventToken; m_scrollRight->Click -= m_scrollRightClickEventToken;
} }
auto borderContainer = safe_cast<Border^>(GetTemplateChild("expressionborder")); if (m_expressionContainer != nullptr)
// Adding an extra check, in case the returned template is null
if (borderContainer != nullptr)
{ {
borderContainer->PointerEntered -= m_pointerEnteredEventToken; m_expressionContainer->ViewChanged -= m_containerViewChangedToken;
borderContainer->PointerExited -= m_pointerExitedEventToken;
} }
} }
void OverflowTextBlock::OnViewChanged(_In_opt_ Object^ /*sender*/, _In_opt_ ScrollViewerViewChangedEventArgs^ /*args*/)
{
UpdateScrollButtons();
}

View file

@ -34,6 +34,7 @@ namespace CalculatorApp
void OnPointerExited(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e); void OnPointerExited(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e);
void ShowHideScrollButtons(Windows::UI::Xaml::Visibility vLeft, Windows::UI::Xaml::Visibility vRight); void ShowHideScrollButtons(Windows::UI::Xaml::Visibility vLeft, Windows::UI::Xaml::Visibility vRight);
void OnTokensUpdatedPropertyChanged(bool oldValue, bool newValue); void OnTokensUpdatedPropertyChanged(bool oldValue, bool newValue);
void OnViewChanged(_In_opt_ Platform::Object ^sender, _In_opt_ Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs ^args);
void UpdateVisualState(); void UpdateVisualState();
void UpdateExpressionState(); void UpdateExpressionState();
@ -44,15 +45,15 @@ namespace CalculatorApp
double scrollRatio = 0.7; double scrollRatio = 0.7;
bool m_scrollingLeft; bool m_scrollingLeft;
bool m_scrollingRight; bool m_scrollingRight;
Windows::UI::Xaml::Controls::ListView^ m_listView; bool m_isAccessibilityViewControl;
Windows::UI::Xaml::Controls::ItemsControl^ m_itemsControl;
Windows::UI::Xaml::Controls::ScrollViewer^ m_expressionContainer; Windows::UI::Xaml::Controls::ScrollViewer^ m_expressionContainer;
Windows::UI::Xaml::Controls::Button^ m_scrollLeft; Windows::UI::Xaml::Controls::Button^ m_scrollLeft;
Windows::UI::Xaml::Controls::Button^ m_scrollRight; Windows::UI::Xaml::Controls::Button^ m_scrollRight;
Windows::Foundation::EventRegistrationToken m_scrollLeftClickEventToken; Windows::Foundation::EventRegistrationToken m_scrollLeftClickEventToken;
Windows::Foundation::EventRegistrationToken m_scrollRightClickEventToken; Windows::Foundation::EventRegistrationToken m_scrollRightClickEventToken;
Windows::Foundation::EventRegistrationToken m_pointerEnteredEventToken; Windows::Foundation::EventRegistrationToken m_containerViewChangedToken;
Windows::Foundation::EventRegistrationToken m_pointerExitedEventToken;
}; };
} }
} }

View file

@ -1,44 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "ExpressionItemContainerStyle.h"
#include "CalcViewModel/Common/DisplayExpressionToken.h"
using namespace CalculatorApp::Common;
namespace CalculatorApp
{
namespace Converters
{
Windows::UI::Xaml::Style^ ExpressionItemContainerStyle::SelectStyleCore(Platform::Object^ item, Windows::UI::Xaml::DependencyObject^ container)
{
DisplayExpressionToken^ token = dynamic_cast<DisplayExpressionToken^>(item);
if (token != nullptr)
{
Common::TokenType type = token->Type;
switch (type)
{
case TokenType::Operator:
if (token->IsTokenEditable)
{
return m_editableOperatorStyle;
}
else
{
return m_nonEditableOperatorStyle;
}
case TokenType::Operand:
return m_operandStyle;
case TokenType::Separator:
return m_separatorStyle;
default:
throw ref new Platform::Exception(E_FAIL, L"Invalid token type");
}
}
return m_separatorStyle;
}
}
}

View file

@ -1,71 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Converters
{
[Windows::UI::Xaml::Data::Bindable]
public ref class ExpressionItemContainerStyle sealed : public Windows::UI::Xaml::Controls::StyleSelector
{
public:
virtual Windows::UI::Xaml::Style^ SelectStyleCore(Platform::Object^ item, Windows::UI::Xaml::DependencyObject^ container) override;
property Windows::UI::Xaml::Style^ EditableOperatorStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_editableOperatorStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_editableOperatorStyle = val;
}
}
property Windows::UI::Xaml::Style^ OperandStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_operandStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_operandStyle = val;
}
}
property Windows::UI::Xaml::Style^ SeparatorStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_separatorStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_separatorStyle = val;
}
}
property Windows::UI::Xaml::Style^ NonEditableOperatorStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_nonEditableOperatorStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_nonEditableOperatorStyle = val;
}
}
private:
Windows::UI::Xaml::Style^ m_editableOperatorStyle;
Windows::UI::Xaml::Style^ m_nonEditableOperatorStyle;
Windows::UI::Xaml::Style^ m_operandStyle;
Windows::UI::Xaml::Style^ m_separatorStyle;
};
}
}

View file

@ -901,10 +901,7 @@
<value>የግራ ቅንፍ</value> <value>የግራ ቅንፍ</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>የግራ ቅንፍ፣ የክፍት ቅንፍ ቁጥር %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>የቀኝ ቅንፍ</value> <value>የቀኝ ቅንፍ</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>أقواس يسرى</value> <value>أقواس يسرى</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>القوس الأيسر، عدد الأقواس المفتوحة %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>أقواس يمنى</value> <value>أقواس يمنى</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Sol mötərizə</value> <value>Sol mötərizə</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Sol mötərizə, açıq mötərizənin sayı %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Sağ mötərizə</value> <value>Sağ mötərizə</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Левая дужка</value> <value>Левая дужка</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Левая дужка, пачатак адліку дужак (%1)</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Правая дужка</value> <value>Правая дужка</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Лява скоба</value> <value>Лява скоба</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Лява скоба, брой на отваряща скоба %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Дясна скоба</value> <value>Дясна скоба</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Parèntesi d'obertura</value> <value>Parèntesi d'obertura</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Parèntesi d'obertura, recompte de parèntesis d'obertura %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Parèntesi de tancament</value> <value>Parèntesi de tancament</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Levá závorka</value> <value>Levá závorka</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Levá závorka, počet otevřených závorek %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Pravá závorka</value> <value>Pravá závorka</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Venstreparentes</value> <value>Venstreparentes</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Venstre parentes, åben parentes antal %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Højreparentes</value> <value>Højreparentes</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Öffnende Klammer</value> <value>Öffnende Klammer</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Runde Klammer links, Anzahl der öffnenden Klammern: %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Schließende Klammer</value> <value>Schließende Klammer</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Αριστερή παρένθεση</value> <value>Αριστερή παρένθεση</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Αριστερή παρένθεση, πλήθος ανοιχτών παρενθέσεων %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Δεξιά παρένθεση</value> <value>Δεξιά παρένθεση</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Left parenthesis</value> <value>Left parenthesis</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Left parenthesis, open parenthesis count %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Right parenthesis</value> <value>Right parenthesis</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -3379,4 +3379,12 @@
<value>Microsoft Services Agreement</value> <value>Microsoft Services Agreement</value>
<comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment> <comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment>
</data> </data>
<data name="UnitAbbreviation_Pyeong" xml:space="preserve">
<value>Pyeong</value>
<comment>An abbreviation for a measurement unit of area.</comment>
</data>
<data name="UnitName_Pyeong" xml:space="preserve">
<value>Pyeong</value>
<comment>A measurement unit for area.</comment>
</data>
</root> </root>

View file

@ -901,10 +901,7 @@
<value>Paréntesis de apertura</value> <value>Paréntesis de apertura</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Paréntesis de apertura, número de paréntesis abiertos %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Paréntesis de cierre</value> <value>Paréntesis de cierre</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

View file

@ -901,10 +901,7 @@
<value>Paréntesis de apertura</value> <value>Paréntesis de apertura</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Abrir paréntesis, recuento de paréntesis abiertos %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Paréntesis de cierre</value> <value>Paréntesis de cierre</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>

Some files were not shown because too many files have changed in this diff Show more