merge with master

This commit is contained in:
Rudy Huyn 2019-12-02 19:36:54 -08:00
parent 39885668ae
commit 73d6a32add
247 changed files with 27860 additions and 8218 deletions

View File

@ -7,11 +7,9 @@
trigger: trigger:
- master - master
- servicing/* - servicing/*
- feature/*
pr: pr:
- master - master
- servicing/* - servicing/*
- feature/*
name: 0.$(Date:yyMM).$(DayOfMonth)$(Rev:rr).0 name: 0.$(Date:yyMM).$(DayOfMonth)$(Rev:rr).0
@ -43,15 +41,9 @@ jobs:
- template: ./templates/run-unit-tests.yaml - template: ./templates/run-unit-tests.yaml
parameters: parameters:
platform: x64 platform: x64
reimageServiceConnection: essential-experiences-interactive-reimage
reimageSubscriptionId: a8f5eb47-e59c-44b4-8e42-e70811a047b5
reimageResourceGroup: EETestPublic
- template: ./templates/run-unit-tests.yaml - template: ./templates/run-unit-tests.yaml
parameters: parameters:
platform: x86 platform: x86
reimageServiceConnection: essential-experiences-interactive-reimage
reimageSubscriptionId: a8f5eb47-e59c-44b4-8e42-e70811a047b5
reimageResourceGroup: EETestPublic
- template: ./templates/package-appxbundle.yaml - template: ./templates/package-appxbundle.yaml

View File

@ -15,11 +15,10 @@ name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
jobs: jobs:
- job: Localize - job: Localize
pool: pool:
vmImage: vs2017-win2016 vmImage: windows-2019
variables: variables:
skipComponentGovernanceDetection: true skipComponentGovernanceDetection: true
steps: steps:
- task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1 - task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
displayName: Send resources to Touchdown Build displayName: Send resources to Touchdown Build
inputs: inputs:

View File

@ -9,8 +9,8 @@ pr: none
variables: variables:
versionMajor: 10 versionMajor: 10
versionMinor: 1907 versionMinor: 1910
versionBuild: $[counter('10.1907.*', 0)] versionBuild: $[counter('10.1910.*', 0)]
versionPatch: 0 versionPatch: 0
name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)' name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)'
@ -48,16 +48,10 @@ jobs:
- template: ./templates/run-unit-tests.yaml - template: ./templates/run-unit-tests.yaml
parameters: parameters:
platform: x64 platform: x64
reimageServiceConnection: macool-sandbox-interactiveDesktopRS5
reimageSubscriptionId: 012a8008-c00f-45b3-9828-41ebba30141d
reimageResourceGroup: interactiveDesktopRS5
- template: ./templates/run-unit-tests.yaml - template: ./templates/run-unit-tests.yaml
parameters: parameters:
platform: x86 platform: x86
reimageServiceConnection: macool-sandbox-interactiveDesktopRS5
reimageSubscriptionId: 012a8008-c00f-45b3-9828-41ebba30141d
reimageResourceGroup: interactiveDesktopRS5
- template: ./templates/package-appxbundle.yaml - template: ./templates/package-appxbundle.yaml

View File

@ -29,7 +29,7 @@ jobs:
downloadDirectory: $(Build.SourcesDirectory) downloadDirectory: $(Build.SourcesDirectory)
vstsFeed: WindowsApps vstsFeed: WindowsApps
vstsFeedPackage: calculator-internals vstsFeedPackage: calculator-internals
vstsPackageVersion: 0.0.18 vstsPackageVersion: 0.0.22
- template: ./build-single-architecture.yaml - template: ./build-single-architecture.yaml
parameters: parameters:

View File

@ -19,6 +19,12 @@ jobs:
clean: outputs clean: outputs
variables: variables:
skipComponentGovernanceDetection: true skipComponentGovernanceDetection: true
SBMediaRootPath: '$(TEMP)\SBMedia'
SBPackagePath: '$(Build.ArtifactStagingDirectory)\storeBrokerPayload'
SBLogPath: '$(SBPackagePath)\StoreBroker.log'
FlightId: '161f0975-cb5f-475b-8ef6-26383c37621f'
AppId: '9WZDNCRFHVN5'
ProductId: '00009007199266248474'
steps: steps:
- checkout: self - checkout: self
clean: true clean: true
@ -91,59 +97,72 @@ jobs:
downloadDirectory: $(Build.SourcesDirectory) downloadDirectory: $(Build.SourcesDirectory)
vstsFeed: WindowsApps vstsFeed: WindowsApps
vstsFeedPackage: calculator-internals vstsFeedPackage: calculator-internals
vstsPackageVersion: 0.0.18 vstsPackageVersion: 0.0.22
- task: PkgESStoreBrokerPackage@10 - powershell: |
displayName: Create StoreBroker Packages # Just modify this line to indicate where your en-us PDP file is. Leave the other lines alone.
env: $enUSPdpFilePath = "$(Build.SourcesDirectory)\PDP\en-US\PDP.xml"
XES_SERIALPOSTBUILDREADY: True
# This is going to save the release value from the PDP file to $(SBMediaReleaseVersion)
# which you can then refer to in the UniversalPackages task.
$release = ([xml](Get-Content $enUSPdpFilePath)).ProductDescription.Release.Trim()
Write-Host "##vso[task.setvariable variable=SBMediaReleaseVersion;]$release"
displayName: Determine the PDP Media release version from the en-us PDP file
- task: UniversalPackages@0
displayName: Download PDP media (screenshots, trailers) universal package
inputs: inputs:
addToFlight: false command: download
configPath: tools/Build/StoreBroker/SBCalculatorConfig.json downloadDirectory: $(SBMediaRootPath)/$(SBMediaReleaseVersion)
PDPRootPath: $(Build.SourcesDirectory)\PDP vstsFeed: WindowsInboxApps
imagesRootPath: $(Build.SourcesDirectory)\PDPMediaRoot vstsFeedPackage: calculator-pdp-media
appxPath: $(Build.ArtifactStagingDirectory)\appxBundleSigned\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle vstsPackageVersion: $(SBMediaReleaseVersion)
useArtifactServiceForMedia: true
outPath: $(Build.ArtifactStagingDirectory)\StoreBrokerPayload - task: MS-RDX-MRO.windows-store-publish-dev.package-task.store-package@2
paToken: $(System.AccessToken) displayName: Create StoreBroker Payload
logRootPath: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs inputs:
serviceEndpoint: StoreBrokerProxy
sbConfigPath: Tools/Build/StoreBroker/SBCalculatorConfig.json
sourceFolder: $(Build.ArtifactStagingDirectory)/appxBundleSigned
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
pdpPath: '$(Build.SourcesDirectory)\PDP'
pdpInclude: PDP.xml
pdpMediaPath: '$(SBMediaRootPath)'
outSBPackagePath: '$(SBPackagePath)'
outSBName: SBCalculator
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1
displayName: Publish StoreBrokerPayload artifact displayName: Publish StoreBroker Payload artifact
inputs: inputs:
pathtoPublish: '$(SBPackagePath)'
artifactName: storeBrokerPayload artifactName: storeBrokerPayload
pathToPublish: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload
- task: PkgESStoreBrokerFlight@10 - task: MS-RDX-MRO.windows-store-publish-dev.flight-task.store-flight@2
displayName: 'Flight StoreBroker Payload to team ring'
name: StoreBrokerFlight name: StoreBrokerFlight
displayName: Flight package with StoreBroker
env:
XES_SERIALPOSTBUILDREADY: True
inputs: inputs:
packageToFlight: Custom serviceEndpoint: StoreBrokerProxy
appId: 9WZDNCRFHVN5 appId: '$(AppId)'
flightId: 161f0975-cb5f-475b-8ef6-26383c37621f flightId: '$(FlightId)'
submissionDataPath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.json inputMethod: JsonAndZip
packagePath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.zip jsonPath: '$(SBPackagePath)\SBCalculator.json'
updatePackageAction: AddPackages zipPath: '$(SBPackagePath)\SBCalculator.zip'
logRootPath: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs force: true
skipPolling: true
- task: PublishBuildArtifacts@1 targetPublishMode: Immediate
displayName: Publish StoreBrokerLogs artifact logPath: '$(SBLogPath)'
inputs:
artifactName: storeBrokerLogs
pathToPublish: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs
- task: PkgESStoreBrokerAeroUpload@10 - task: PkgESStoreBrokerAeroUpload@10
displayName: Upload to Aero flighting dashboard displayName: Upload to Aero flighting dashboard
env: env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken) SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs: inputs:
productId: 00009007199266248474 ProductId: '$(ProductId)'
flightId: 161f0975-cb5f-475b-8ef6-26383c37621f FlightId: '$(FlightId)'
submissionId: $(StoreBrokerFlight.WS_SubmissionId) SubmissionId: '$(StoreBrokerFlight.WS_SubmissionId)'
submissionDataPath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.json SubmissionDataPath: '$(SBPackagePath)\SBCalculator.json'
packagePath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.zip PackagePath: '$(SBPackagePath)\SBCalculator.zip'
AeroEnvironment: Production
- task: PkgESLateTasks@10 - task: PkgESLateTasks@10
displayName: Run PackageES LateTasks displayName: Run PackageES LateTasks

View File

@ -1,30 +1,21 @@
# This template contains jobs to run unit tests on the interactive test agents. # This template contains jobs to run unit tests.
parameters: parameters:
platform: '' platform: ''
reimageServiceConnection: '' runsettingsFileName: ''
reimageSubscriptionId: ''
reimageResourceGroup: ''
jobs: jobs:
- job: UnitTests${{ parameters.platform }} - job: UnitTests${{ parameters.platform }}
displayName: UnitTests ${{ parameters.platform }} displayName: UnitTests ${{ parameters.platform }}
dependsOn: Build${{ parameters.platform }} dependsOn: Build${{ parameters.platform }}
condition: succeeded()
pool: pool:
name: Essential Experiences Interactive vmImage: windows-2019
workspace:
clean: outputs
variables: variables:
skipComponentGovernanceDetection: true skipComponentGovernanceDetection: true
steps: steps:
- checkout: none - checkout: none
- powershell: Write-Host "##vso[task.setvariable variable=agentInstanceId;isOutput=true]$($env:AgentName -replace '\D+' -as [int])"
name: LogAgentStep
displayName: Log this agent's instance for later cleanup
env:
AgentName: $(Agent.Name)
- task: DownloadBuildArtifacts@0 - task: DownloadBuildArtifacts@0
displayName: Download CalculatorUnitTests displayName: Download CalculatorUnitTests
inputs: inputs:
@ -42,18 +33,3 @@ jobs:
inputs: inputs:
testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.appx testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.appx
otherConsoleOptions: /Platform:${{ parameters.platform }} otherConsoleOptions: /Platform:${{ parameters.platform }}
- job: CleanUpUnitTests${{ parameters.platform }}
dependsOn: UnitTests${{ parameters.platform }}
condition: and(always(), ne(dependencies.UnitTests${{ parameters.platform }}.Outputs['LogAgentStep.agentInstanceId'], ''))
pool: server
variables:
agentInstanceId: $[ dependencies.UnitTests${{ parameters.platform }}.outputs['LogAgentStep.agentInstanceId'] ]
steps:
- task: InvokeRESTAPI@1
displayName: Reimage test machine
inputs:
connectionType: connectedServiceNameARM
azureServiceConnection: ${{ parameters.reimageServiceConnection }}
urlSuffix: subscriptions/${{ parameters.reimageSubscriptionId }}/resourceGroups/${{ parameters.reimageResourceGroup }}/providers/Microsoft.Compute/virtualMachineScaleSets/essential/reimage?api-version=2018-10-01
body: '{ "instanceIds": ["$(agentInstanceId)"] }'

View File

@ -179,7 +179,7 @@ bool CalcInput::TryAddDecimalPt()
if (m_base.IsEmpty()) if (m_base.IsEmpty())
{ {
m_base.value += L"0"; // Add a leading zero m_base.value += L'0'; // Add a leading zero
} }
m_decPtIndex = m_base.value.size(); m_decPtIndex = m_base.value.size();
@ -261,6 +261,11 @@ void CalcInput::SetDecimalSymbol(wchar_t decSymbol)
} }
} }
bool CalcInput::IsEmpty()
{
return m_base.IsEmpty() && !m_hasExponent && m_exponent.IsEmpty() && !m_hasDecimal;
}
wstring CalcInput::ToString(uint32_t radix) wstring CalcInput::ToString(uint32_t radix)
{ {
// In theory both the base and exponent could be C_NUM_MAX_DIGITS long. // In theory both the base and exponent could be C_NUM_MAX_DIGITS long.

View File

@ -11,14 +11,14 @@ bool IsOpInRange(OpCode op, uint32_t x, uint32_t y)
bool IsBinOpCode(OpCode opCode) bool IsBinOpCode(OpCode opCode)
{ {
return IsOpInRange(opCode, IDC_AND, IDC_PWR); return IsOpInRange(opCode, IDC_AND, IDC_PWR) || IsOpInRange(opCode, IDC_BINARYEXTENDEDFIRST, IDC_BINARYEXTENDEDLAST);
} }
// WARNING: IDC_SIGN is a special unary op but still this doesn't catch this. Caller has to be aware // WARNING: IDC_SIGN is a special unary op but still this doesn't catch this. Caller has to be aware
// of it and catch it themselves or not needing this // of it and catch it themselves or not needing this
bool IsUnaryOpCode(OpCode opCode) bool IsUnaryOpCode(OpCode opCode)
{ {
return IsOpInRange(opCode, IDC_UNARYFIRST, IDC_UNARYLAST); return (IsOpInRange(opCode, IDC_UNARYFIRST, IDC_UNARYLAST) || IsOpInRange(opCode, IDC_UNARYEXTENDEDFIRST, IDC_UNARYEXTENDEDLAST));
} }
bool IsDigitOpCode(OpCode opCode) bool IsDigitOpCode(OpCode opCode)

View File

@ -3,7 +3,6 @@
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Command.h" #include "Command.h"
#include "CalculatorVector.h"
#include "ExpressionCommand.h" #include "ExpressionCommand.h"
constexpr int ASCII_0 = 48; constexpr int ASCII_0 = 48;
@ -13,14 +12,19 @@ using namespace CalcEngine;
namespace namespace
{ {
void IFT(ResultCode hr) template <typename T>
static void Truncate(vector<T>& v, unsigned int index)
{ {
if (FAILED(hr)) if (index >= v.size())
{ {
throw hr; throw E_BOUNDS;
} }
auto startIter = v.begin() + index;
v.erase(startIter, v.end());
} }
} }
void CHistoryCollector::ReinitHistory() void CHistoryCollector::ReinitHistory()
{ {
m_lastOpStartIndex = -1; m_lastOpStartIndex = -1;
@ -29,11 +33,11 @@ void CHistoryCollector::ReinitHistory()
m_bLastOpndBrace = false; m_bLastOpndBrace = false;
if (m_spTokens != nullptr) if (m_spTokens != nullptr)
{ {
m_spTokens->Clear(); m_spTokens->clear();
} }
if (m_spCommands != nullptr) if (m_spCommands != nullptr)
{ {
m_spCommands->Clear(); m_spCommands->clear();
} }
} }
@ -55,13 +59,13 @@ CHistoryCollector::~CHistoryCollector()
if (m_spTokens != nullptr) if (m_spTokens != nullptr)
{ {
m_spTokens->Clear(); m_spTokens->clear();
} }
} }
void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& rat, bool fRepetition) void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& rat, bool fRepetition)
{ {
std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>(); std::shared_ptr<std::vector<int>> commands = std::make_shared<vector<int>>();
// Check for negate // Check for negate
bool fNegative = (numStr[0] == L'-'); bool fNegative = (numStr[0] == L'-');
bool fSciFmt = false; bool fSciFmt = false;
@ -71,7 +75,7 @@ void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& ra
{ {
if (numStr[i] == m_decimalSymbol) if (numStr[i] == m_decimalSymbol)
{ {
IFT(commands->Append(IDC_PNT)); commands->push_back(IDC_PNT);
if (!fSciFmt) if (!fSciFmt)
{ {
fDecimal = true; fDecimal = true;
@ -79,12 +83,12 @@ void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& ra
} }
else if (numStr[i] == L'e') else if (numStr[i] == L'e')
{ {
IFT(commands->Append(IDC_EXP)); commands->push_back(IDC_EXP);
fSciFmt = true; fSciFmt = true;
} }
else if (numStr[i] == L'-') else if (numStr[i] == L'-')
{ {
IFT(commands->Append(IDC_SIGN)); commands->push_back(IDC_SIGN);
} }
else if (numStr[i] == L'+') else if (numStr[i] == L'+')
{ {
@ -95,7 +99,7 @@ void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& ra
{ {
int num = static_cast<int>(numStr[i]) - ASCII_0; int num = static_cast<int>(numStr[i]) - ASCII_0;
num += IDC_0; num += IDC_0;
IFT(commands->Append(num)); commands->push_back(num);
} }
} }
@ -120,12 +124,12 @@ void CHistoryCollector::RemoveLastOpndFromHistory()
// This will not restore the m_lastBinOpStartIndex, as it isn't possible to remove that also later // This will not restore the m_lastBinOpStartIndex, as it isn't possible to remove that also later
} }
void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool fNoRepetition) void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool isIntegerMode, bool fNoRepetition)
{ {
int iCommandEnd = AddCommand(std::make_shared<CBinaryCommand>(nOpCode)); int iCommandEnd = AddCommand(std::make_shared<CBinaryCommand>(nOpCode));
m_lastBinOpStartIndex = IchAddSzToEquationSz(L" ", -1); m_lastBinOpStartIndex = IchAddSzToEquationSz(L" ", -1);
IchAddSzToEquationSz(CCalcEngine::OpCodeToString(nOpCode), iCommandEnd); IchAddSzToEquationSz(CCalcEngine::OpCodeToBinaryString(nOpCode, isIntegerMode), iCommandEnd);
IchAddSzToEquationSz(L" ", -1); IchAddSzToEquationSz(L" ", -1);
if (fNoRepetition) if (fNoRepetition)
@ -138,14 +142,14 @@ void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool fNoRepetition)
// This is expected to be called when a binary op in the last say 1+2+ is changing to another one say 1+2* (+ changed to *) // This is expected to be called when a binary op in the last say 1+2+ is changing to another one say 1+2* (+ changed to *)
// It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new // It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new
// one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^) // one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^)
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher) void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode)
{ {
TruncateEquationSzFromIch(m_lastBinOpStartIndex); TruncateEquationSzFromIch(m_lastBinOpStartIndex);
if (fPrecInvToHigher) if (fPrecInvToHigher)
{ {
EnclosePrecInversionBrackets(); EnclosePrecInversionBrackets();
} }
AddBinOpToHistory(nOpCode); AddBinOpToHistory(nOpCode, isIntgerMode);
} }
void CHistoryCollector::PushLastOpndStart(int ichOpndStart) void CHistoryCollector::PushLastOpndStart(int ichOpndStart)
@ -266,6 +270,30 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE a
command = fInv ? static_cast<int>(CalculationManager::Command::CommandATANH) : IDC_TANH; command = fInv ? static_cast<int>(CalculationManager::Command::CommandATANH) : IDC_TANH;
spExpressionCommand = std::make_shared<CUnaryCommand>(command); spExpressionCommand = std::make_shared<CUnaryCommand>(command);
break; break;
case IDC_SEC:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandASEC) : IDC_SEC;
spExpressionCommand = std::make_shared<CUnaryCommand>(static_cast<int>(angleOpCode), command);
break;
case IDC_CSC:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandACSC) : IDC_CSC;
spExpressionCommand = std::make_shared<CUnaryCommand>(static_cast<int>(angleOpCode), command);
break;
case IDC_COT:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandACOT) : IDC_COT;
spExpressionCommand = std::make_shared<CUnaryCommand>(static_cast<int>(angleOpCode), command);
break;
case IDC_SECH:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandASECH) : IDC_SECH;
spExpressionCommand = std::make_shared<CUnaryCommand>(command);
break;
case IDC_CSCH:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandACSCH) : IDC_CSCH;
spExpressionCommand = std::make_shared<CUnaryCommand>(command);
break;
case IDC_COTH:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandACOTH) : IDC_COTH;
spExpressionCommand = std::make_shared<CUnaryCommand>(command);
break;
case IDC_LN: case IDC_LN:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandPOWE) : IDC_LN; command = fInv ? static_cast<int>(CalculationManager::Command::CommandPOWE) : IDC_LN;
spExpressionCommand = std::make_shared<CUnaryCommand>(command); spExpressionCommand = std::make_shared<CUnaryCommand>(command);
@ -301,12 +329,6 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE a
// history of equations // history of equations
void CHistoryCollector::CompleteHistoryLine(wstring_view numStr) void CHistoryCollector::CompleteHistoryLine(wstring_view numStr)
{ {
if (nullptr != m_pCalcDisplay)
{
m_pCalcDisplay->SetExpressionDisplay(
std::make_shared<CalculatorVector<std::pair<std::wstring, int>>>(), std::make_shared<CalculatorVector<std::shared_ptr<IExpressionCommand>>>());
}
if (nullptr != m_pHistoryDisplay) if (nullptr != m_pHistoryDisplay)
{ {
unsigned int addedItemIndex = m_pHistoryDisplay->AddToHistory(m_spTokens, m_spCommands, numStr); unsigned int addedItemIndex = m_pHistoryDisplay->AddToHistory(m_spTokens, m_spCommands, numStr);
@ -319,6 +341,16 @@ void CHistoryCollector::CompleteHistoryLine(wstring_view numStr)
ReinitHistory(); ReinitHistory();
} }
void CHistoryCollector::CompleteEquation(std::wstring_view numStr)
{
// Add only '=' token and not add EQU command, because
// EQU command breaks loading from history (it duplicate history entries).
IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_EQU), -1);
SetExpressionDisplay();
CompleteHistoryLine(numStr);
}
void CHistoryCollector::ClearHistoryLine(wstring_view errStr) void CHistoryCollector::ClearHistoryLine(wstring_view errStr)
{ {
if (errStr.empty()) // in case of error let the display stay as it is if (errStr.empty()) // in case of error let the display stay as it is
@ -326,7 +358,7 @@ void CHistoryCollector::ClearHistoryLine(wstring_view errStr)
if (nullptr != m_pCalcDisplay) if (nullptr != m_pCalcDisplay)
{ {
m_pCalcDisplay->SetExpressionDisplay( m_pCalcDisplay->SetExpressionDisplay(
std::make_shared<CalculatorVector<std::pair<std::wstring, int>>>(), std::make_shared<CalculatorVector<std::shared_ptr<IExpressionCommand>>>()); std::make_shared<std::vector<std::pair<std::wstring, int>>>(), std::make_shared<std::vector<std::shared_ptr<IExpressionCommand>>>());
} }
m_iCurLineHistStart = -1; // It will get recomputed at the first Opnd m_iCurLineHistStart = -1; // It will get recomputed at the first Opnd
ReinitHistory(); ReinitHistory();
@ -339,26 +371,17 @@ int CHistoryCollector::IchAddSzToEquationSz(wstring_view str, int icommandIndex)
{ {
if (m_spTokens == nullptr) if (m_spTokens == nullptr)
{ {
m_spTokens = std::make_shared<CalculatorVector<std::pair<std::wstring, int>>>(); m_spTokens = std::make_shared<std::vector<std::pair<std::wstring, int>>>();
} }
if (FAILED(m_spTokens->Append(std::make_pair(wstring(str), icommandIndex)))) m_spTokens->push_back(std::pair(wstring(str), icommandIndex));
{ return static_cast<int>(m_spTokens->size() - 1);
throw(CALC_E_OUTOFMEMORY);
}
unsigned int nTokens;
m_spTokens->GetSize(&nTokens);
return nTokens - 1;
} }
// Inserts a given string into the global m_pszEquation at the given index ich taking care of reallocations etc. // Inserts a given string into the global m_pszEquation at the given index ich taking care of reallocations etc.
void CHistoryCollector::InsertSzInEquationSz(wstring_view str, int icommandIndex, int ich) void CHistoryCollector::InsertSzInEquationSz(wstring_view str, int icommandIndex, int ich)
{ {
if (FAILED(m_spTokens->InsertAt(ich, std::make_pair(wstring(str), icommandIndex)))) m_spTokens->emplace(m_spTokens->begin() + ich, wstring(str), icommandIndex);
{
throw(CALC_E_OUTOFMEMORY);
}
} }
// Chops off the current equation string from the given index // Chops off the current equation string from the given index
@ -366,25 +389,23 @@ void CHistoryCollector::TruncateEquationSzFromIch(int ich)
{ {
// Truncate commands // Truncate commands
int minIdx = -1; int minIdx = -1;
unsigned int nTokens = 0; unsigned int nTokens = static_cast<unsigned int>(m_spTokens->size());
std::pair<std::wstring, int> currentPair;
m_spTokens->GetSize(&nTokens);
for (unsigned int i = ich; i < nTokens; i++) for (unsigned int i = ich; i < nTokens; i++)
{ {
IFT(m_spTokens->GetAt(i, &currentPair)); const auto& currentPair = (*m_spTokens)[i];
int curTokenId = currentPair.second; int curTokenId = currentPair.second;
if (curTokenId != -1) if (curTokenId != -1)
{ {
if ((minIdx != -1) || (curTokenId < minIdx)) if ((minIdx != -1) || (curTokenId < minIdx))
{ {
minIdx = curTokenId; minIdx = curTokenId;
IFT(m_spCommands->Truncate(minIdx)); Truncate(*m_spCommands, minIdx);
} }
} }
} }
IFT(m_spTokens->Truncate(ich)); Truncate(*m_spTokens, ich);
} }
// Adds the m_pszEquation into the running history text // Adds the m_pszEquation into the running history text
@ -400,17 +421,11 @@ int CHistoryCollector::AddCommand(_In_ const std::shared_ptr<IExpressionCommand>
{ {
if (m_spCommands == nullptr) if (m_spCommands == nullptr)
{ {
m_spCommands = std::make_shared<CalculatorVector<std::shared_ptr<IExpressionCommand>>>(); m_spCommands = std::make_shared<std::vector<std::shared_ptr<IExpressionCommand>>>();
} }
if (FAILED(m_spCommands->Append(spCommand))) m_spCommands->push_back(spCommand);
{ return static_cast<int>(m_spCommands->size() - 1);
throw(CALC_E_OUTOFMEMORY);
}
unsigned int nCommands = 0;
m_spCommands->GetSize(&nCommands);
return nCommands - 1;
} }
// To Update the operands in the Expression according to the current Radix // To Update the operands in the Expression according to the current Radix
@ -421,30 +436,25 @@ void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precisio
return; return;
} }
unsigned int size; for (auto& token : *m_spTokens)
IFT(m_spTokens->GetSize(&size));
for (unsigned int i = 0; i < size; ++i)
{ {
std::pair<std::wstring, int> token;
IFT(m_spTokens->GetAt(i, &token));
int commandPosition = token.second; int commandPosition = token.second;
if (commandPosition != -1) if (commandPosition != -1)
{ {
std::shared_ptr<IExpressionCommand> expCommand; const std::shared_ptr<IExpressionCommand>& expCommand = m_spCommands->at(commandPosition);
IFT(m_spCommands->GetAt(commandPosition, &expCommand));
if (expCommand != nullptr && CalculationManager::CommandType::OperandCommand == expCommand->GetCommandType()) if (expCommand != nullptr && CalculationManager::CommandType::OperandCommand == expCommand->GetCommandType())
{ {
std::shared_ptr<COpndCommand> opndCommand = std::static_pointer_cast<COpndCommand>(expCommand); const std::shared_ptr<COpndCommand>& opndCommand = std::static_pointer_cast<COpndCommand>(expCommand);
if (opndCommand != nullptr) if (opndCommand != nullptr)
{ {
token.first = opndCommand->GetString(radix, precision); token.first = opndCommand->GetString(radix, precision);
IFT(m_spTokens->SetAt(i, token));
opndCommand->SetCommands(GetOperandCommandsFromString(token.first)); opndCommand->SetCommands(GetOperandCommandsFromString(token.first));
} }
} }
} }
} }
SetExpressionDisplay(); SetExpressionDisplay();
} }
@ -454,9 +464,9 @@ void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
} }
// Update the commands corresponding to the passed string Number // Update the commands corresponding to the passed string Number
std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr) std::shared_ptr<std::vector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr)
{ {
std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>(); std::shared_ptr<std::vector<int>> commands = std::make_shared<std::vector<int>>();
// Check for negate // Check for negate
bool fNegative = (numStr[0] == L'-'); bool fNegative = (numStr[0] == L'-');
@ -464,15 +474,15 @@ std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFrom
{ {
if (numStr[i] == m_decimalSymbol) if (numStr[i] == m_decimalSymbol)
{ {
IFT(commands->Append(IDC_PNT)); commands->push_back(IDC_PNT);
} }
else if (numStr[i] == L'e') else if (numStr[i] == L'e')
{ {
IFT(commands->Append(IDC_EXP)); commands->push_back(IDC_EXP);
} }
else if (numStr[i] == L'-') else if (numStr[i] == L'-')
{ {
IFT(commands->Append(IDC_SIGN)); commands->push_back(IDC_SIGN);
} }
else if (numStr[i] == L'+') else if (numStr[i] == L'+')
{ {
@ -483,14 +493,14 @@ std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFrom
{ {
int num = static_cast<int>(numStr[i]) - ASCII_0; int num = static_cast<int>(numStr[i]) - ASCII_0;
num += IDC_0; num += IDC_0;
IFT(commands->Append(num)); commands->push_back(num);
} }
} }
// If the number is negative, append a sign command at the end. // If the number is negative, append a sign command at the end.
if (fNegative) if (fNegative)
{ {
IFT(commands->Append(IDC_SIGN)); commands->push_back(IDC_SIGN);
} }
return commands; return commands;
} }

View File

@ -24,17 +24,16 @@ static constexpr wstring_view DEFAULT_NUMBER_STR = L"0";
// Read strings for keys, errors, trig types, etc. // Read strings for keys, errors, trig types, etc.
// These will be copied from the resources to local memory. // These will be copied from the resources to local memory.
unordered_map<wstring, wstring> CCalcEngine::s_engineStrings; unordered_map<wstring_view, wstring> CCalcEngine::s_engineStrings;
void CCalcEngine::LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider) void CCalcEngine::LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider)
{ {
for (const auto& sid : g_sids) for (const auto& sid : g_sids)
{ {
auto locKey = wstring{ sid }; auto locString = resourceProvider.GetCEngineString(sid);
auto locString = resourceProvider.GetCEngineString(locKey);
if (!locString.empty()) if (!locString.empty())
{ {
s_engineStrings[locKey] = locString; s_engineStrings[sid] = locString;
} }
} }
} }

View File

@ -16,6 +16,7 @@
#include <string> #include <string>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h" #include "Header Files/CalcUtils.h"
#include "NumberFormattingUtils.h"
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
@ -28,8 +29,13 @@ namespace
// 0 is returned. Higher the number, higher the precedence of the operator. // 0 is returned. Higher the number, higher the precedence of the operator.
int NPrecedenceOfOp(int nopCode) int NPrecedenceOfOp(int nopCode)
{ {
static uint8_t rgbPrec[] = { 0, 0, IDC_OR, 0, IDC_XOR, 0, IDC_AND, 1, IDC_ADD, 2, IDC_SUB, 2, IDC_RSHF, static uint16_t rgbPrec[] = {
3, IDC_LSHF, 3, IDC_MOD, 3, IDC_DIV, 3, IDC_MUL, 3, IDC_PWR, 4, IDC_ROOT, 4 }; 0,0, IDC_OR,0, IDC_XOR,0,
IDC_AND,1, IDC_NAND,1, IDC_NOR,1,
IDC_ADD,2, IDC_SUB,2,
IDC_RSHF,3, IDC_LSHF,3, IDC_RSHFL,3,
IDC_MOD,3, IDC_DIV,3, IDC_MUL,3,
IDC_PWR,4, IDC_ROOT,4, IDC_LOGBASEX,4 };
unsigned int iPrec; unsigned int iPrec;
iPrec = 0; iPrec = 0;
@ -76,6 +82,15 @@ void CCalcEngine::ClearTemporaryValues()
m_bError = false; m_bError = false;
} }
void CCalcEngine::ClearDisplay()
{
if (nullptr != m_pCalcDisplay)
{
m_pCalcDisplay->SetExpressionDisplay(
make_shared<vector<pair<wstring, int>>>(), make_shared<vector<shared_ptr<IExpressionCommand>>>());
}
}
void CCalcEngine::ProcessCommand(OpCode wParam) void CCalcEngine::ProcessCommand(OpCode wParam)
{ {
if (wParam == IDC_SET_RESULT) if (wParam == IDC_SET_RESULT)
@ -103,6 +118,12 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_nTempCom = (int)wParam; m_nTempCom = (int)wParam;
} }
// Clear expression shown after = sign, when user do any action.
if (!m_bNoPrevEqu)
{
ClearDisplay();
}
if (m_bError) if (m_bError)
{ {
if (wParam == IDC_CLEAR) if (wParam == IDC_CLEAR)
@ -124,9 +145,18 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
// Toggle Record/Display mode if appropriate. // Toggle Record/Display mode if appropriate.
if (m_bRecord) if (m_bRecord)
{ {
if (IsOpInRange(wParam, IDC_AND, IDC_MMINUS) || IsOpInRange(wParam, IDC_OPENP, IDC_CLOSEP) || IsOpInRange(wParam, IDM_HEX, IDM_BIN) if (IsBinOpCode(wParam) ||
|| IsOpInRange(wParam, IDM_QWORD, IDM_BYTE) || IsOpInRange(wParam, IDM_DEG, IDM_GRAD) IsUnaryOpCode(wParam) ||
|| IsOpInRange(wParam, IDC_BINEDITSTART, IDC_BINEDITSTART + 63) || (IDC_INV == wParam) || (IDC_SIGN == wParam && 10 != m_radix)) IsOpInRange(wParam, IDC_FE, IDC_MMINUS) ||
IsOpInRange(wParam, IDC_OPENP, IDC_CLOSEP) ||
IsOpInRange(wParam, IDM_HEX, IDM_BIN) ||
IsOpInRange(wParam, IDM_QWORD, IDM_BYTE) ||
IsOpInRange(wParam, IDM_DEG, IDM_GRAD) ||
IsOpInRange(wParam, IDC_BINEDITSTART, IDC_BINEDITEND) ||
(IDC_INV == wParam) ||
(IDC_SIGN == wParam && 10 != m_radix) ||
(IDC_RAND == wParam) ||
(IDC_EULER == wParam))
{ {
m_bRecord = false; m_bRecord = false;
m_currentVal = m_input.ToRational(m_radix, m_precision); m_currentVal = m_input.ToRational(m_radix, m_precision);
@ -193,7 +223,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_nPrevOpCode = 0; // Once the precedence inversion has put additional brackets, its no longer required m_nPrevOpCode = 0; // Once the precedence inversion has put additional brackets, its no longer required
} }
} }
m_HistoryCollector.ChangeLastBinOp(m_nOpCode, fPrecInvToHigher); m_HistoryCollector.ChangeLastBinOp(m_nOpCode, fPrecInvToHigher, m_fIntegerMode);
DisplayAnnounceBinaryOperator(); DisplayAnnounceBinaryOperator();
return; return;
} }
@ -270,10 +300,9 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
} }
DisplayAnnounceBinaryOperator(); DisplayAnnounceBinaryOperator();
m_lastVal = m_currentVal; m_lastVal = m_currentVal;
m_nOpCode = (int)wParam; m_nOpCode = (int)wParam;
m_HistoryCollector.AddBinOpToHistory(m_nOpCode); m_HistoryCollector.AddBinOpToHistory(m_nOpCode, m_fIntegerMode);
m_bNoPrevEqu = m_bChangeOp = true; m_bNoPrevEqu = m_bChangeOp = true;
return; return;
} }
@ -303,7 +332,8 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_HistoryCollector.AddUnaryOpToHistory((int)wParam, m_bInv, m_angletype); m_HistoryCollector.AddUnaryOpToHistory((int)wParam, m_bInv, m_angletype);
} }
if ((wParam == IDC_SIN) || (wParam == IDC_COS) || (wParam == IDC_TAN) || (wParam == IDC_SINH) || (wParam == IDC_COSH) || (wParam == IDC_TANH)) if ((wParam == IDC_SIN) || (wParam == IDC_COS) || (wParam == IDC_TAN) || (wParam == IDC_SINH) || (wParam == IDC_COSH) || (wParam == IDC_TANH)
|| (wParam == IDC_SEC) || (wParam == IDC_CSC) || (wParam == IDC_COT) || (wParam == IDC_SECH) || (wParam == IDC_CSCH) || (wParam == IDC_COTH))
{ {
if (IsCurrentTooBigForTrig()) if (IsCurrentTooBigForTrig())
{ {
@ -330,9 +360,13 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
/* reset the m_bInv flag and indicators if it is set /* reset the m_bInv flag and indicators if it is set
and have been used */ and have been used */
if (m_bInv if (m_bInv &&
&& ((wParam == IDC_CHOP) || (wParam == IDC_SIN) || (wParam == IDC_COS) || (wParam == IDC_TAN) || (wParam == IDC_LN) || (wParam == IDC_DMS) ((wParam == IDC_CHOP) || (wParam == IDC_SIN) || (wParam == IDC_COS) ||
|| (wParam == IDC_DEGREES) || (wParam == IDC_SINH) || (wParam == IDC_COSH) || (wParam == IDC_TANH))) (wParam == IDC_TAN) || (wParam == IDC_LN) || (wParam == IDC_DMS) ||
(wParam == IDC_DEGREES) || (wParam == IDC_SINH) || (wParam == IDC_COSH) ||
(wParam == IDC_TANH) || (wParam == IDC_SEC) || (wParam == IDC_CSC) ||
(wParam == IDC_COT) || (wParam == IDC_SECH) || (wParam == IDC_CSCH) ||
(wParam == IDC_COTH)))
{ {
m_bInv = false; m_bInv = false;
} }
@ -341,10 +375,10 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
} }
// Tiny binary edit windows clicked. Toggle that bit and update display // Tiny binary edit windows clicked. Toggle that bit and update display
if (IsOpInRange(wParam, IDC_BINEDITSTART, IDC_BINEDITSTART + 63)) if (IsOpInRange(wParam, IDC_BINEDITSTART, IDC_BINEDITEND))
{ {
// Same reasoning as for unary operators. We need to seed it previous number // Same reasoning as for unary operators. We need to seed it previous number
if (m_nLastCom >= IDC_AND && m_nLastCom <= IDC_PWR) if (IsBinOpCode(m_nLastCom))
{ {
m_currentVal = m_lastVal; m_currentVal = m_lastVal;
} }
@ -377,14 +411,14 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_precedenceOpCount = m_nTempCom = m_nLastCom = m_nOpCode = 0; m_precedenceOpCount = m_nTempCom = m_nLastCom = m_nOpCode = 0;
m_nPrevOpCode = 0; m_nPrevOpCode = 0;
m_bNoPrevEqu = true; m_bNoPrevEqu = true;
m_carryBit = 0;
/* clear the parenthesis status box indicator, this will not be /* clear the parenthesis status box indicator, this will not be
cleared for CENTR */ cleared for CENTR */
if (nullptr != m_pCalcDisplay) if (nullptr != m_pCalcDisplay)
{ {
m_pCalcDisplay->SetParenthesisNumber(0); m_pCalcDisplay->SetParenthesisNumber(0);
m_pCalcDisplay->SetExpressionDisplay( ClearDisplay();
make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>());
} }
m_HistoryCollector.ClearHistoryLine(wstring()); m_HistoryCollector.ClearHistoryLine(wstring());
@ -474,12 +508,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
if (!m_bError) if (!m_bError)
{ {
wstring groupedString = GroupDigitsPerRadix(m_numberString, m_radix); wstring groupedString = GroupDigitsPerRadix(m_numberString, m_radix);
m_HistoryCollector.CompleteHistoryLine(groupedString); m_HistoryCollector.CompleteEquation(groupedString);
if (nullptr != m_pCalcDisplay)
{
m_pCalcDisplay->SetExpressionDisplay(
make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>());
}
} }
m_bChangeOp = false; m_bChangeOp = false;
@ -700,7 +729,6 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
case IDC_MCLEAR: case IDC_MCLEAR:
m_memoryValue = make_unique<Rational>(wParam == IDC_STORE ? TruncateNumForIntMath(m_currentVal) : 0); m_memoryValue = make_unique<Rational>(wParam == IDC_STORE ? TruncateNumForIntMath(m_currentVal) : 0);
break; break;
case IDC_PI: case IDC_PI:
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
@ -713,7 +741,43 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
} }
HandleErrorCommand(wParam); HandleErrorCommand(wParam);
break; break;
case IDC_RAND:
if (!m_fIntegerMode)
{
CheckAndAddLastBinOpToHistory(); // rand is like entering the number
wstringstream str;
str << fixed << setprecision(m_precision) << GenerateRandomNumber();
auto rat = StringToRat(false, str.str(), false, L"", m_radix, m_precision);
if (rat != nullptr)
{
m_currentVal = Rational{ rat };
}
else
{
m_currentVal = Rational{ 0 };
}
destroyrat(rat);
DisplayNum();
m_bInv = false;
break;
}
HandleErrorCommand(wParam);
break;
case IDC_EULER:
if (!m_fIntegerMode)
{
CheckAndAddLastBinOpToHistory(); // e is like entering the number
m_currentVal = Rational{ rat_exp };
DisplayNum();
m_bInv = false;
break;
}
HandleErrorCommand(wParam);
break;
case IDC_FE: case IDC_FE:
// Toggle exponential notation display. // Toggle exponential notation display.
m_nFE = NUMOBJ_FMT(!(int)m_nFE); m_nFE = NUMOBJ_FMT(!(int)m_nFE);
@ -761,7 +825,7 @@ void CCalcEngine::ResolveHighestPrecedenceOperation()
{ {
m_currentVal = m_holdVal; m_currentVal = m_holdVal;
DisplayNum(); // to update the m_numberString DisplayNum(); // to update the m_numberString
m_HistoryCollector.AddBinOpToHistory(m_nOpCode, false); m_HistoryCollector.AddBinOpToHistory(m_nOpCode, m_fIntegerMode, false);
m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); // Adding the repeated last op to history m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); // Adding the repeated last op to history
} }
@ -863,11 +927,14 @@ struct FunctionNameElement
wstring gradString; wstring gradString;
wstring inverseGradString; // Will fall back to gradString if empty wstring inverseGradString; // Will fall back to gradString if empty
wstring programmerModeString;
bool hasAngleStrings = ((!radString.empty()) || (!inverseRadString.empty()) || (!gradString.empty()) || (!inverseGradString.empty())); bool hasAngleStrings = ((!radString.empty()) || (!inverseRadString.empty()) || (!gradString.empty()) || (!inverseGradString.empty()));
}; };
// Table for each unary operator // Table for each unary operator
static const std::unordered_map<int, FunctionNameElement> unaryOperatorStringTable = { static const std::unordered_map<int, FunctionNameElement> operatorStringTable =
{
{ IDC_CHOP, { L"", SIDS_FRAC } }, { IDC_CHOP, { L"", SIDS_FRAC } },
{ IDC_SIN, { SIDS_SIND, SIDS_ASIND, SIDS_SINR, SIDS_ASINR, SIDS_SING, SIDS_ASING } }, { IDC_SIN, { SIDS_SIND, SIDS_ASIND, SIDS_SINR, SIDS_ASINR, SIDS_SING, SIDS_ASING } },
@ -878,6 +945,14 @@ static const std::unordered_map<int, FunctionNameElement> unaryOperatorStringTab
{ IDC_COSH, { L"", SIDS_ACOSH } }, { IDC_COSH, { L"", SIDS_ACOSH } },
{ IDC_TANH, { L"", SIDS_ATANH } }, { IDC_TANH, { L"", SIDS_ATANH } },
{ IDC_SEC, { SIDS_SECD, SIDS_ASECD, SIDS_SECR, SIDS_ASECR, SIDS_SECG, SIDS_ASECG } },
{ IDC_CSC, { SIDS_CSCD, SIDS_ACSCD, SIDS_CSCR, SIDS_ACSCR, SIDS_CSCG, SIDS_ACSCG } },
{ IDC_COT, { SIDS_COTD, SIDS_ACOTD, SIDS_COTR, SIDS_ACOTR, SIDS_COTG, SIDS_ACOTG } },
{ IDC_SECH, { SIDS_SECH, SIDS_ASECH } },
{ IDC_CSCH, { SIDS_CSCH, SIDS_ACSCH } },
{ IDC_COTH, { SIDS_COTH, SIDS_ACOTH } },
{ IDC_LN, { L"", SIDS_POWE } }, { IDC_LN, { L"", SIDS_POWE } },
{ IDC_SQR, { SIDS_SQR } }, { IDC_SQR, { SIDS_SQR } },
{ IDC_CUB, { SIDS_CUBE } }, { IDC_CUB, { SIDS_CUBE } },
@ -885,7 +960,19 @@ static const std::unordered_map<int, FunctionNameElement> unaryOperatorStringTab
{ IDC_REC, { SIDS_RECIPROC } }, { IDC_REC, { SIDS_RECIPROC } },
{ IDC_DMS, { L"", SIDS_DEGREES } }, { IDC_DMS, { L"", SIDS_DEGREES } },
{ IDC_SIGN, { SIDS_NEGATE } }, { IDC_SIGN, { SIDS_NEGATE } },
{ IDC_DEGREES, { SIDS_DEGREES } } { IDC_DEGREES, { SIDS_DEGREES } },
{ IDC_POW2, { SIDS_TWOPOWX } },
{ IDC_LOGBASEX, { SIDS_LOGBASEX } },
{ IDC_ABS, { SIDS_ABS } },
{ IDC_CEIL, { SIDS_CEIL } },
{ IDC_FLOOR, { SIDS_FLOOR } },
{ IDC_NAND, { SIDS_NAND } },
{ IDC_NOR, { SIDS_NOR } },
{ IDC_RSHFL, { SIDS_RSH } },
{ IDC_RORC, { SIDS_ROR } },
{ IDC_ROLC, { SIDS_ROL } },
{ IDC_CUBEROOT, {SIDS_CUBEROOT} },
{ IDC_MOD, {SIDS_MOD, L"", L"", L"", L"", L"", SIDS_PROGRAMMER_MOD} },
}; };
wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype) wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype)
@ -893,7 +980,7 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
// Try to lookup the ID in the UFNE table // Try to lookup the ID in the UFNE table
wstring ids = L""; wstring ids = L"";
if (auto pair = unaryOperatorStringTable.find(nOpCode); pair != unaryOperatorStringTable.end()) if (auto pair = operatorStringTable.find(nOpCode); pair != operatorStringTable.end())
{ {
const FunctionNameElement& element = pair->second; const FunctionNameElement& element = pair->second;
if (!element.hasAngleStrings || ANGLE_DEG == angletype) if (!element.hasAngleStrings || ANGLE_DEG == angletype)
@ -941,6 +1028,32 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
return OpCodeToString(nOpCode); return OpCodeToString(nOpCode);
} }
wstring_view CCalcEngine::OpCodeToBinaryString(int nOpCode, bool isIntegerMode)
{
// Try to lookup the ID in the UFNE table
wstring ids = L"";
if (auto pair = operatorStringTable.find(nOpCode); pair != operatorStringTable.end())
{
if (isIntegerMode && !pair->second.programmerModeString.empty())
{
ids = pair->second.programmerModeString;
}
else
{
ids = pair->second.degreeString;
}
}
if (!ids.empty())
{
return GetString(ids);
}
// If we didn't find an ID in the table, use the op code.
return OpCodeToString(nOpCode);
}
bool CCalcEngine::IsCurrentTooBigForTrig() bool CCalcEngine::IsCurrentTooBigForTrig()
{ {
return m_currentVal >= m_maxTrigonometricNum; return m_currentVal >= m_maxTrigonometricNum;
@ -1007,3 +1120,14 @@ wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix)
return result; return result;
} }
double CCalcEngine::GenerateRandomNumber()
{
if (m_randomGeneratorEngine == nullptr)
{
random_device rd;
m_randomGeneratorEngine = std::make_unique<std::mt19937>(rd());
m_distr = std::make_unique<std::uniform_real_distribution<>>(0, 1);
}
return (*m_distr.get())(*m_randomGeneratorEngine.get());
}

View File

@ -46,8 +46,8 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
} }
break; break;
// Rotate Left with hi bit wrapped over to lo bit
case IDC_ROL: case IDC_ROL:
case IDC_ROLC:
if (m_fIntegerMode) if (m_fIntegerMode)
{ {
result = Integer(rat); result = Integer(rat);
@ -55,14 +55,23 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
uint64_t w64Bits = result.ToUInt64_t(); uint64_t w64Bits = result.ToUInt64_t();
uint64_t msb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; uint64_t msb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
w64Bits <<= 1; // LShift by 1 w64Bits <<= 1; // LShift by 1
w64Bits |= msb; // Set the prev Msb as the current Lsb
if (op == IDC_ROL)
{
w64Bits |= msb; // Set the prev Msb as the current Lsb
}
else
{
w64Bits |= m_carryBit; // Set the carry bit as the LSB
m_carryBit = msb; // Store the msb as the next carry bit
}
result = w64Bits; result = w64Bits;
} }
break; break;
// Rotate right with lo bit wrapped over to hi bit
case IDC_ROR: case IDC_ROR:
case IDC_RORC:
if (m_fIntegerMode) if (m_fIntegerMode)
{ {
result = Integer(rat); result = Integer(rat);
@ -70,7 +79,16 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
uint64_t w64Bits = result.ToUInt64_t(); uint64_t w64Bits = result.ToUInt64_t();
uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0; uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0;
w64Bits >>= 1; // RShift by 1 w64Bits >>= 1; // RShift by 1
w64Bits |= (lsb << (m_dwWordBitWidth - 1));
if (op == IDC_ROR)
{
w64Bits |= (lsb << (m_dwWordBitWidth - 1));
}
else
{
w64Bits |= (m_carryBit << (m_dwWordBitWidth - 1));
m_carryBit = lsb;
}
result = w64Bits; result = w64Bits;
} }
@ -133,6 +151,48 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
} }
break; break;
case IDC_SEC:
if (!m_fIntegerMode)
{
result = m_bInv ? ACos(Invert(rat), m_angletype) : Invert(Cos(rat, m_angletype));
}
break;
case IDC_CSC:
if (!m_fIntegerMode)
{
result = m_bInv ? ASin(Invert(rat), m_angletype) : Invert(Sin(rat, m_angletype));
}
break;
case IDC_COT:
if (!m_fIntegerMode)
{
result = m_bInv ? ATan(Invert(rat), m_angletype) : Invert(Tan(rat, m_angletype));
}
break;
case IDC_SECH:
if (!m_fIntegerMode)
{
result = m_bInv ? ACosh(Invert(rat)) : Invert(Cosh(rat));
}
break;
case IDC_CSCH:
if (!m_fIntegerMode)
{
result = m_bInv ? ASinh(Invert(rat)) : Invert(Sinh(rat));
}
break;
case IDC_COTH:
if (!m_fIntegerMode)
{
result = m_bInv ? ATanh(Invert(rat)) : Invert(Tanh(rat));
}
break;
case IDC_REC: /* Reciprocal. */ case IDC_REC: /* Reciprocal. */
result = Invert(rat); result = Invert(rat);
break; break;
@ -158,6 +218,10 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
result = Pow(10, rat); result = Pow(10, rat);
break; break;
case IDC_POW2:
result = Pow(2, rat);
break;
case IDC_LN: /* Functions for natural log. */ case IDC_LN: /* Functions for natural log. */
result = m_bInv ? Exp(rat) : Log(rat); result = m_bInv ? Exp(rat) : Log(rat);
break; break;
@ -202,6 +266,18 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
} }
break; break;
} }
case IDC_CEIL:
result = (Frac(rat) > 0) ? Integer(rat + 1) : Integer(rat);
break;
case IDC_FLOOR:
result = (Frac(rat) < 0) ? Integer(rat - 1 ) : Integer(rat);
break;
case IDC_ABS:
result = Abs(rat);
break;
} // end switch( op ) } // end switch( op )
} }
catch (uint32_t nErrCode) catch (uint32_t nErrCode)

View File

@ -28,6 +28,14 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
result ^= rhs; result ^= rhs;
break; break;
case IDC_NAND:
result = (result & rhs) ^ m_chopNumbers[m_numwidth];
break;
case IDC_NOR:
result = (result | rhs) ^ m_chopNumbers[m_numwidth];
break;
case IDC_RSHF: case IDC_RSHF:
{ {
if (m_fIntegerMode && result >= m_dwWordBitWidth) // Lsh/Rsh >= than current word size is always 0 if (m_fIntegerMode && result >= m_dwWordBitWidth) // Lsh/Rsh >= than current word size is always 0
@ -52,7 +60,16 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
} }
break; break;
} }
case IDC_RSHFL:
{
if (m_fIntegerMode && result >= m_dwWordBitWidth) // Lsh/Rsh >= than current word size is always 0
{
throw CALC_E_NORESULT;
}
result = rhs >> result;
break;
}
case IDC_LSHF: case IDC_LSHF:
if (m_fIntegerMode && result >= m_dwWordBitWidth) // Lsh/Rsh >= than current word size is always 0 if (m_fIntegerMode && result >= m_dwWordBitWidth) // Lsh/Rsh >= than current word size is always 0
{ {
@ -140,6 +157,10 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
case IDC_ROOT: // Calculates rhs to the result(th) root. case IDC_ROOT: // Calculates rhs to the result(th) root.
result = Root(rhs, result); result = Root(rhs, result);
break; break;
case IDC_LOGBASEX:
result = (Log(result) / Log(rhs));
break;
} }
} }
catch (uint32_t dwErrCode) catch (uint32_t dwErrCode)

View File

@ -78,24 +78,32 @@
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -175,6 +183,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles> <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
<EnablePREfast>true</EnablePREfast>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -209,6 +218,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles> <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
<EnablePREfast>true</EnablePREfast>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -244,6 +254,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles> <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
<EnablePREfast>true</EnablePREfast>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -278,6 +289,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles> <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
<EnablePREfast>true</EnablePREfast>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -289,7 +301,6 @@
<ClInclude Include="CalculatorHistory.h" /> <ClInclude Include="CalculatorHistory.h" />
<ClInclude Include="CalculatorManager.h" /> <ClInclude Include="CalculatorManager.h" />
<ClInclude Include="CalculatorResource.h" /> <ClInclude Include="CalculatorResource.h" />
<ClInclude Include="CalculatorVector.h" />
<ClInclude Include="Command.h" /> <ClInclude Include="Command.h" />
<ClInclude Include="ExpressionCommand.h" /> <ClInclude Include="ExpressionCommand.h" />
<ClInclude Include="ExpressionCommandInterface.h" /> <ClInclude Include="ExpressionCommandInterface.h" />

View File

@ -120,7 +120,6 @@
<ClInclude Include="Ratpack\ratpak.h"> <ClInclude Include="Ratpack\ratpak.h">
<Filter>RatPack</Filter> <Filter>RatPack</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="CalculatorVector.h" />
<ClInclude Include="Header Files\CalcEngine.h"> <ClInclude Include="Header Files\CalcEngine.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@ -7,25 +7,48 @@
using namespace std; using namespace std;
using namespace CalculationManager; using namespace CalculationManager;
namespace
{
static wstring GetGeneratedExpression(const vector<pair<wstring, int>>& tokens)
{
wstring expression;
bool isFirst = true;
for (auto const& token : tokens)
{
if (isFirst)
{
isFirst = false;
}
else
{
expression += L' ';
}
expression.append(token.first);
}
return expression;
}
}
CalculatorHistory::CalculatorHistory(size_t maxSize) CalculatorHistory::CalculatorHistory(size_t maxSize)
: m_maxHistorySize(maxSize) : m_maxHistorySize(maxSize)
{ {
} }
unsigned int CalculatorHistory::AddToHistory( unsigned int CalculatorHistory::AddToHistory(
_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens, _In_ shared_ptr<vector<pair<wstring, int>>> const& tokens,
_In_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands, _In_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands,
_In_ wstring_view result) wstring_view result)
{ {
unsigned int addedIndex; unsigned int addedIndex;
wstring generatedExpression;
shared_ptr<HISTORYITEM> spHistoryItem = make_shared<HISTORYITEM>(); shared_ptr<HISTORYITEM> spHistoryItem = make_shared<HISTORYITEM>();
spHistoryItem->historyItemVector.spTokens = tokens; spHistoryItem->historyItemVector.spTokens = tokens;
spHistoryItem->historyItemVector.spCommands = commands; spHistoryItem->historyItemVector.spCommands = commands;
// to be changed when pszexp is back // to be changed when pszexp is back
tokens->GetString(&generatedExpression); wstring generatedExpression = GetGeneratedExpression(*tokens);
// Prefixing and suffixing the special Unicode markers to ensure that the expression // Prefixing and suffixing the special Unicode markers to ensure that the expression
// in the history doesn't get broken for RTL languages // in the history doesn't get broken for RTL languages
spHistoryItem->historyItemVector.expression = L'\u202d' + generatedExpression + L'\u202c'; spHistoryItem->historyItemVector.expression = L'\u202d' + generatedExpression + L'\u202c';
@ -47,7 +70,7 @@ unsigned int CalculatorHistory::AddItem(_In_ shared_ptr<HISTORYITEM> const& spHi
return lastIndex; return lastIndex;
} }
bool CalculatorHistory::RemoveItem(_In_ unsigned int uIdx) bool CalculatorHistory::RemoveItem(unsigned int uIdx)
{ {
if (uIdx > m_historyItems.size() - 1) if (uIdx > m_historyItems.size() - 1)
{ {
@ -63,17 +86,12 @@ vector<shared_ptr<HISTORYITEM>> const& CalculatorHistory::GetHistory()
return m_historyItems; return m_historyItems;
} }
shared_ptr<HISTORYITEM> const& CalculatorHistory::GetHistoryItem(_In_ unsigned int uIdx) shared_ptr<HISTORYITEM> const& CalculatorHistory::GetHistoryItem(unsigned int uIdx)
{ {
assert(uIdx >= 0 && uIdx < m_historyItems.size()); assert(uIdx >= 0 && uIdx < m_historyItems.size());
return m_historyItems.at(uIdx); return m_historyItems.at(uIdx);
} }
CalculatorHistory::~CalculatorHistory(void)
{
ClearHistory();
}
void CalculatorHistory::ClearHistory() void CalculatorHistory::ClearHistory()
{ {
m_historyItems.clear(); m_historyItems.clear();

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
@ -15,8 +15,8 @@ namespace CalculationManager
struct HISTORYITEMVECTOR struct HISTORYITEMVECTOR
{ {
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> spTokens; std::shared_ptr<std::vector<std::pair<std::wstring, int>>> spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> spCommands; std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> spCommands;
std::wstring expression; std::wstring expression;
std::wstring result; std::wstring result;
}; };
@ -31,8 +31,8 @@ namespace CalculationManager
public: public:
CalculatorHistory(const size_t maxSize); CalculatorHistory(const size_t maxSize);
unsigned int AddToHistory( unsigned int AddToHistory(
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& spTokens, _In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& spTokens,
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& spCommands, _In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& spCommands,
std::wstring_view result); std::wstring_view result);
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistory(); std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistory();
std::shared_ptr<HISTORYITEM> const& GetHistoryItem(unsigned int uIdx); std::shared_ptr<HISTORYITEM> const& GetHistoryItem(unsigned int uIdx);
@ -43,7 +43,6 @@ namespace CalculationManager
{ {
return m_maxHistorySize; return m_maxHistorySize;
} }
~CalculatorHistory(void);
private: private:
std::vector<std::shared_ptr<HISTORYITEM>> m_historyItems; std::vector<std::shared_ptr<HISTORYITEM>> m_historyItems;

View File

@ -75,14 +75,19 @@ namespace CalculationManager
m_displayCallback->MemoryItemChanged(indexOfMemory); m_displayCallback->MemoryItemChanged(indexOfMemory);
} }
void CalculatorManager::InputChanged()
{
m_displayCallback->InputChanged();
}
/// <summary> /// <summary>
/// Call the callback function using passed in IDisplayHelper. /// Call the callback function using passed in IDisplayHelper.
/// Used to set the expression display value on ViewModel /// Used to set the expression display value on ViewModel
/// </summary> /// </summary>
/// <param name="expressionString">wstring representing expression to be displayed</param> /// <param name="expressionString">wstring representing expression to be displayed</param>
void CalculatorManager::SetExpressionDisplay( void CalculatorManager::SetExpressionDisplay(
_Inout_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens, _Inout_ shared_ptr<vector<pair<wstring, int>>> const& tokens,
_Inout_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands) _Inout_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands)
{ {
if (!m_inHistoryItemLoadMode) if (!m_inHistoryItemLoadMode)
{ {
@ -240,6 +245,7 @@ namespace CalculationManager
m_savedCommands.push_back(MapCommandForSerialize(command)); m_savedCommands.push_back(MapCommandForSerialize(command));
} }
m_savedDegreeMode = m_currentDegreeMode; m_savedDegreeMode = m_currentDegreeMode;
InputChanged();
return; return;
} }
@ -283,6 +289,30 @@ namespace CalculationManager
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV)); m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandTANH)); m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandTANH));
break; break;
case Command::CommandASEC:
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandSEC));
break;
case Command::CommandACSC:
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandCSC));
break;
case Command::CommandACOT:
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandCOT));
break;
case Command::CommandASECH:
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandSECH));
break;
case Command::CommandACSCH:
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandCSCH));
break;
case Command::CommandACOTH:
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandCOTH));
break;
case Command::CommandFE: case Command::CommandFE:
m_isExponentialFormat = !m_isExponentialFormat; m_isExponentialFormat = !m_isExponentialFormat;
[[fallthrough]]; [[fallthrough]];
@ -290,6 +320,8 @@ namespace CalculationManager
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(command)); m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(command));
break; break;
} }
InputChanged();
} }
/// <summary> /// <summary>
@ -330,6 +362,7 @@ namespace CalculationManager
{ {
m_currentCalculatorEngine->PersistedMemObject(m_persistedPrimaryValue); m_currentCalculatorEngine->PersistedMemObject(m_persistedPrimaryValue);
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL); m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
InputChanged();
} }
/// <summary> /// <summary>
@ -376,6 +409,7 @@ namespace CalculationManager
this->MemorizedNumberSelect(indexOfMemory); this->MemorizedNumberSelect(indexOfMemory);
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL); m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
InputChanged();
} }
/// <summary> /// <summary>
@ -606,9 +640,9 @@ namespace CalculationManager
if (pHistory) if (pHistory)
{ {
pHistory->ClearHistory(); pHistory->ClearHistory();
for (unsigned int i = 0; i < history.size(); ++i) for (auto const& historyItem : history)
{ {
pHistory->AddItem(history[i]); pHistory->AddItem(historyItem);
} }
} }
} }
@ -638,6 +672,11 @@ namespace CalculationManager
return m_currentCalculatorEngine->FInRecordingState() ? true : false; return m_currentCalculatorEngine->FInRecordingState() ? true : false;
} }
bool CalculatorManager::IsInputEmpty()
{
return m_currentCalculatorEngine->IsInputEmpty();
}
void CalculatorManager::SetInHistoryItemLoadMode(_In_ bool isHistoryItemLoadMode) void CalculatorManager::SetInHistoryItemLoadMode(_In_ bool isHistoryItemLoadMode)
{ {
m_inHistoryItemLoadMode = isHistoryItemLoadMode; m_inHistoryItemLoadMode = isHistoryItemLoadMode;

View File

@ -91,8 +91,8 @@ namespace CalculationManager
void SetPrimaryDisplay(_In_ const std::wstring& displayString, _In_ bool isError) override; void SetPrimaryDisplay(_In_ const std::wstring& displayString, _In_ bool isError) override;
void SetIsInError(bool isError) override; void SetIsInError(bool isError) override;
void SetExpressionDisplay( void SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens, _Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) override; _Inout_ std::shared_ptr<std::vector<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 SetParenthesisNumber(_In_ unsigned int parenthesisCount) override; void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
@ -101,8 +101,8 @@ namespace CalculationManager
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;
void MemoryItemChanged(unsigned int indexOfMemory) override; void MemoryItemChanged(unsigned int indexOfMemory) override;
void InputChanged() override;
CalculatorManager(ICalcDisplay* displayCallback, IResourceProvider* resourceProvider); CalculatorManager(_In_ ICalcDisplay* displayCallback, _In_ IResourceProvider* resourceProvider);
void Reset(bool clearMemory = true); void Reset(bool clearMemory = true);
void SetStandardMode(); void SetStandardMode();
@ -118,7 +118,8 @@ namespace CalculationManager
void MemorizedNumberClearAll(); void MemorizedNumberClearAll();
bool IsEngineRecording(); bool IsEngineRecording();
std::vector<unsigned char> GetSavedCommands() bool IsInputEmpty();
const std::vector<unsigned char>& GetSavedCommands() const
{ {
return m_savedCommands; return m_savedCommands;
} }

View File

@ -1,8 +1,10 @@
// 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_view>
namespace CalculationManager namespace CalculationManager
{ {
class IResourceProvider class IResourceProvider
@ -19,6 +21,6 @@ namespace CalculationManager
// ids "sDecimal", "sThousand" and "sGrouping". See // ids "sDecimal", "sThousand" and "sGrouping". See
// https://technet.microsoft.com/en-us/library/cc782655(v=ws.10).aspx // https://technet.microsoft.com/en-us/library/cc782655(v=ws.10).aspx
// for what these values refer to. // for what these values refer to.
virtual std::wstring GetCEngineString(const std::wstring& id) = 0; virtual std::wstring GetCEngineString(std::wstring_view id) = 0;
}; };
} }

View File

@ -97,6 +97,7 @@ namespace CalculationManager
CommandROL = 99, CommandROL = 99,
CommandROR = 100, CommandROR = 100,
CommandCOM = 101, CommandCOM = 101,
CommandSIN = 102, CommandSIN = 102,
CommandCOS = 103, CommandCOS = 103,
CommandTAN = 104, CommandTAN = 104,
@ -151,6 +152,34 @@ namespace CalculationManager
CommandINV = 146, CommandINV = 146,
CommandSET_RESULT = 147, CommandSET_RESULT = 147,
CommandSEC = 400,
CommandASEC = 401,
CommandCSC = 402,
CommandACSC = 403,
CommandCOT = 404,
CommandACOT = 405,
CommandSECH = 406,
CommandASECH = 407,
CommandCSCH = 408,
CommandACSCH = 409,
CommandCOTH = 410,
CommandACOTH = 411,
CommandPOW2 = 412, // 2 ^ x
CommandAbs = 413,
CommandFloor = 414,
CommandCeil = 415,
CommandROLC = 416,
CommandRORC = 417,
CommandLogBaseX = 500,
CommandNand = 501,
CommandNor = 502,
CommandRSHFL = 505,
CommandRand = 600,
CommandEuler = 601,
CommandAnd = 86, CommandAnd = 86,
CommandOR = 87, CommandOR = 87,
CommandNot = 101, CommandNot = 101,

View File

@ -3,7 +3,6 @@
#include <string> #include <string>
#include "Header Files/CCommand.h" #include "Header Files/CCommand.h"
#include "CalculatorVector.h"
#include "ExpressionCommand.h" #include "ExpressionCommand.h"
using namespace std; using namespace std;
@ -35,18 +34,18 @@ void CParentheses::Accept(_In_ ISerializeCommandVisitor& commandVisitor)
CUnaryCommand::CUnaryCommand(int command) CUnaryCommand::CUnaryCommand(int command)
{ {
m_command = make_shared<CalculatorVector<int>>(); m_command = make_shared<vector<int>>();
m_command->Append(command); m_command->push_back(command);
} }
CUnaryCommand::CUnaryCommand(int command1, int command2) CUnaryCommand::CUnaryCommand(int command1, int command2)
{ {
m_command = make_shared<CalculatorVector<int>>(); m_command = make_shared<vector<int>>();
m_command->Append(command1); m_command->push_back(command1);
m_command->Append(command2); m_command->push_back(command2);
} }
const shared_ptr<CalculatorVector<int>>& CUnaryCommand::GetCommands() const const shared_ptr<vector<int>>& CUnaryCommand::GetCommands() const
{ {
return m_command; return m_command;
} }
@ -58,15 +57,15 @@ CalculationManager::CommandType CUnaryCommand::GetCommandType() const
void CUnaryCommand::SetCommand(int command) void CUnaryCommand::SetCommand(int command)
{ {
m_command->Clear(); m_command->clear();
m_command->Append(command); m_command->push_back(command);
} }
void CUnaryCommand::SetCommands(int command1, int command2) void CUnaryCommand::SetCommands(int command1, int command2)
{ {
m_command->Clear(); m_command->clear();
m_command->Append(command1); m_command->push_back(command1);
m_command->Append(command2); m_command->push_back(command2);
} }
void CUnaryCommand::Accept(_In_ ISerializeCommandVisitor& commandVisitor) void CUnaryCommand::Accept(_In_ ISerializeCommandVisitor& commandVisitor)
@ -99,7 +98,7 @@ void CBinaryCommand::Accept(_In_ ISerializeCommandVisitor& commandVisitor)
commandVisitor.Visit(*this); commandVisitor.Visit(*this);
} }
COpndCommand::COpndCommand(shared_ptr<CalculatorVector<int>> const& commands, bool fNegative, bool fDecimal, bool fSciFmt) COpndCommand::COpndCommand(shared_ptr<vector<int>> const& commands, bool fNegative, bool fDecimal, bool fSciFmt)
: m_commands(commands) : m_commands(commands)
, m_fNegative(fNegative) , m_fNegative(fNegative)
, m_fSciFmt(fSciFmt) , m_fSciFmt(fSciFmt)
@ -115,27 +114,25 @@ void COpndCommand::Initialize(Rational const& rat)
m_fInitialized = true; m_fInitialized = true;
} }
const shared_ptr<CalculatorVector<int>>& COpndCommand::GetCommands() const const shared_ptr<vector<int>>& COpndCommand::GetCommands() const
{ {
return m_commands; return m_commands;
} }
void COpndCommand::SetCommands(shared_ptr<CalculatorVector<int>> const& commands) void COpndCommand::SetCommands(shared_ptr<vector<int>> const& commands)
{ {
m_commands = commands; m_commands = commands;
} }
void COpndCommand::AppendCommand(int command) void COpndCommand::AppendCommand(int command)
{ {
unsigned int nCommands;
m_commands->GetSize(&nCommands);
if (m_fSciFmt) if (m_fSciFmt)
{ {
ClearAllAndAppendCommand(static_cast<CalculationManager::Command>(command)); ClearAllAndAppendCommand(static_cast<CalculationManager::Command>(command));
} }
else else
{ {
m_commands->Append(command); m_commands->push_back(command);
} }
if (command == IDC_PNT) if (command == IDC_PNT)
@ -146,14 +143,8 @@ void COpndCommand::AppendCommand(int command)
void COpndCommand::ToggleSign() void COpndCommand::ToggleSign()
{ {
unsigned int commandCount; for (int nOpCode : *m_commands)
m_commands->GetSize(&commandCount);
for (unsigned int i = 0; i < commandCount; i++)
{ {
int nOpCode;
m_commands->GetAt(i, &nOpCode);
if (nOpCode != IDC_0) if (nOpCode != IDC_0)
{ {
m_fNegative = !m_fNegative; m_fNegative = !m_fNegative;
@ -170,8 +161,7 @@ void COpndCommand::RemoveFromEnd()
} }
else else
{ {
unsigned int nCommands; const size_t nCommands = m_commands->size();
m_commands->GetSize(&nCommands);
if (nCommands == 1) if (nCommands == 1)
{ {
@ -179,13 +169,14 @@ void COpndCommand::RemoveFromEnd()
} }
else else
{ {
int nOpCode; int nOpCode = m_commands->at(nCommands - 1);
m_commands->GetAt(nCommands - 1, &nOpCode);
if (nOpCode == IDC_PNT) if (nOpCode == IDC_PNT)
{ {
m_fDecimal = false; m_fDecimal = false;
} }
m_commands->RemoveAt(nCommands - 1);
m_commands->pop_back();
} }
} }
} }
@ -212,8 +203,8 @@ CalculationManager::CommandType COpndCommand::GetCommandType() const
void COpndCommand::ClearAllAndAppendCommand(CalculationManager::Command command) void COpndCommand::ClearAllAndAppendCommand(CalculationManager::Command command)
{ {
m_commands->Clear(); m_commands->clear();
m_commands->Append(static_cast<int>(command)); m_commands->push_back(static_cast<int>(command));
m_fSciFmt = false; m_fSciFmt = false;
m_fNegative = false; m_fNegative = false;
m_fDecimal = false; m_fDecimal = false;
@ -223,31 +214,29 @@ const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
{ {
static const wchar_t chZero = L'0'; static const wchar_t chZero = L'0';
unsigned int nCommands; const size_t nCommands = m_commands->size();
m_commands->GetSize(&nCommands);
m_token.clear(); m_token.clear();
int nOpCode;
for (unsigned int i = 0; i < nCommands; i++) for (size_t i = 0; i < nCommands; i++)
{ {
m_commands->GetAt(i, &nOpCode); int nOpCode = (*m_commands)[i];
if (nOpCode == IDC_PNT) if (nOpCode == IDC_PNT)
{ {
m_token.append(wstring{ decimalSymbol }); m_token += decimalSymbol;
} }
else if (nOpCode == IDC_EXP) else if (nOpCode == IDC_EXP)
{ {
m_token.append(&chExp); m_token += chExp;
int nextOpCode; int nextOpCode = m_commands->at(i + 1);
m_commands->GetAt(i + 1, &nextOpCode);
if (nextOpCode != IDC_SIGN) if (nextOpCode != IDC_SIGN)
{ {
m_token.append(&chPlus); m_token += chPlus;
} }
} }
else if (nOpCode == IDC_SIGN) else if (nOpCode == IDC_SIGN)
{ {
m_token.append(&chNegate); m_token += chNegate;
} }
else else
{ {
@ -257,7 +246,7 @@ const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
} }
// Remove zeros // Remove zeros
for (unsigned int i = 0; i < m_token.size(); i++) for (size_t i = 0; i < m_token.size(); i++)
{ {
if (m_token.at(i) != chZero) if (m_token.at(i) != chZero)
{ {
@ -272,29 +261,26 @@ const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
if (m_fNegative) if (m_fNegative)
{ {
m_token.insert(0, &chNegate); m_token.insert(0, 1, chNegate);
} }
return m_token; return m_token;
} }
} }
m_token.clear(); m_token = chZero;
m_token.append(&chZero);
return m_token; return m_token;
} }
wstring COpndCommand::GetString(uint32_t radix, int32_t precision) wstring COpndCommand::GetString(uint32_t radix, int32_t precision)
{ {
wstring result{};
if (m_fInitialized) if (m_fInitialized)
{ {
result = m_value.ToString(radix, eNUMOBJ_FMT::FMT_FLOAT, precision); return m_value.ToString(radix, eNUMOBJ_FMT::FMT_FLOAT, precision);
} }
return result; return wstring{};
} }
void COpndCommand::Accept(_In_ ISerializeCommandVisitor& commandVisitor) void COpndCommand::Accept(_In_ ISerializeCommandVisitor& commandVisitor)

View File

@ -23,14 +23,14 @@ class CUnaryCommand final : public IUnaryCommand
public: public:
CUnaryCommand(int command); CUnaryCommand(int command);
CUnaryCommand(int command1, int command2); CUnaryCommand(int command1, int command2);
const std::shared_ptr<CalculatorVector<int>>& GetCommands() const override; const std::shared_ptr<std::vector<int>>& GetCommands() const override;
CalculationManager::CommandType GetCommandType() const override; CalculationManager::CommandType GetCommandType() const override;
void SetCommand(int command) override; void SetCommand(int command) override;
void SetCommands(int command1, int command2) override; void SetCommands(int command1, int command2) override;
void Accept(_In_ ISerializeCommandVisitor& commandVisitor) override; void Accept(_In_ ISerializeCommandVisitor& commandVisitor) override;
private: private:
std::shared_ptr<CalculatorVector<int>> m_command; std::shared_ptr<std::vector<int>> m_command;
}; };
class CBinaryCommand final : public IBinaryCommand class CBinaryCommand final : public IBinaryCommand
@ -49,11 +49,11 @@ private:
class COpndCommand final : public IOpndCommand class COpndCommand final : public IOpndCommand
{ {
public: public:
COpndCommand(std::shared_ptr<CalculatorVector<int>> const& commands, bool fNegative, bool fDecimal, bool fSciFmt); COpndCommand(std::shared_ptr<std::vector<int>> const& commands, bool fNegative, bool fDecimal, bool fSciFmt);
void Initialize(CalcEngine::Rational const& rat); void Initialize(CalcEngine::Rational const& rat);
const std::shared_ptr<CalculatorVector<int>>& GetCommands() const override; const std::shared_ptr<std::vector<int>>& GetCommands() const override;
void SetCommands(std::shared_ptr<CalculatorVector<int>> const& commands) override; void SetCommands(std::shared_ptr<std::vector<int>> const& commands) override;
void AppendCommand(int command) override; void AppendCommand(int command) override;
void ToggleSign() override; void ToggleSign() override;
void RemoveFromEnd() override; void RemoveFromEnd() override;
@ -66,7 +66,7 @@ public:
std::wstring GetString(uint32_t radix, int32_t precision); std::wstring GetString(uint32_t radix, int32_t precision);
private: private:
std::shared_ptr<CalculatorVector<int>> m_commands; std::shared_ptr<std::vector<int>> m_commands;
bool m_fNegative; bool m_fNegative;
bool m_fSciFmt; bool m_fSciFmt;
bool m_fDecimal; bool m_fDecimal;

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include <memory> // for std::shared_ptr #include <memory> // for std::shared_ptr
#include "CalculatorVector.h" #include <vector>
#include "Command.h" #include "Command.h"
class ISerializeCommandVisitor; class ISerializeCommandVisitor;
@ -25,7 +25,7 @@ public:
class IUnaryCommand : public IOperatorCommand class IUnaryCommand : public IOperatorCommand
{ {
public: public:
virtual const std::shared_ptr<CalculatorVector<int>>& GetCommands() const = 0; virtual const std::shared_ptr<std::vector<int>>& GetCommands() const = 0;
virtual void SetCommands(int command1, int command2) = 0; virtual void SetCommands(int command1, int command2) = 0;
}; };
@ -39,7 +39,7 @@ public:
class IOpndCommand : public IExpressionCommand class IOpndCommand : public IExpressionCommand
{ {
public: public:
virtual const std::shared_ptr<CalculatorVector<int>>& GetCommands() const = 0; virtual const std::shared_ptr<std::vector<int>>& GetCommands() const = 0;
virtual void AppendCommand(int command) = 0; virtual void AppendCommand(int command) = 0;
virtual void ToggleSign() = 0; virtual void ToggleSign() = 0;
virtual void RemoveFromEnd() = 0; virtual void RemoveFromEnd() = 0;
@ -47,7 +47,7 @@ public:
virtual bool IsSciFmt() const = 0; virtual bool IsSciFmt() const = 0;
virtual bool IsDecimalPresent() const = 0; virtual bool IsDecimalPresent() const = 0;
virtual const std::wstring& GetToken(wchar_t decimalSymbol) = 0; virtual const std::wstring& GetToken(wchar_t decimalSymbol) = 0;
virtual void SetCommands(std::shared_ptr<CalculatorVector<int>> const& commands) = 0; virtual void SetCommands(std::shared_ptr<std::vector<int>> const& commands) = 0;
}; };
class IParenthesisCommand : public IExpressionCommand class IParenthesisCommand : public IExpressionCommand

View File

@ -81,6 +81,7 @@
#define IDC_ROL 99 #define IDC_ROL 99
#define IDC_ROR 100 #define IDC_ROR 100
#define IDC_COM 101 #define IDC_COM 101
#define IDC_SIN 102 #define IDC_SIN 102
#define IDC_COS 103 #define IDC_COS 103
#define IDC_TAN 104 #define IDC_TAN 104
@ -136,7 +137,44 @@
#define IDC_INV 146 #define IDC_INV 146
#define IDC_SET_RESULT 147 #define IDC_SET_RESULT 147
#define IDC_LASTCONTROL IDC_SET_RESULT #define IDC_STRING_MAPPED_VALUES 400
#define IDC_UNARYEXTENDEDFIRST IDC_STRING_MAPPED_VALUES
#define IDC_SEC 400 // Secant
// 401 reserved for inverse
#define IDC_CSC 402 // Cosecant
// 403 reserved for inverse
#define IDC_COT 404 // Cotangent
// 405 reserved for inverse
#define IDC_SECH 406 //Hyperbolic Secant
// 407 reserved for inverse
#define IDC_CSCH 408 //Hyperbolic Cosecant
// 409 reserved for inverse
#define IDC_COTH 410 //Hyperbolic Cotangent
// 411 reserved for inverse
#define IDC_POW2 412 // 2 ^ x
#define IDC_ABS 413 // Absolute Value
#define IDC_FLOOR 414 // Floor
#define IDC_CEIL 415 // Ceiling
#define IDC_ROLC 416 // Rotate Left Circular
#define IDC_RORC 417 // Rotate Right Circular
#define IDC_UNARYEXTENDEDLAST IDC_RORC
#define IDC_LASTCONTROL IDC_CEIL
#define IDC_BINARYEXTENDEDFIRST 500
#define IDC_LOGBASEX 500 // logx(y)
#define IDC_NAND 501 // Nand
#define IDC_NOR 502 // Nor
#define IDC_RSHFL 505 //Right Shift Logical
#define IDC_BINARYEXTENDEDLAST IDC_RSHFL
#define IDC_RAND 600 // Random
#define IDC_EULER 601 // e Constant
#define IDC_BINEDITSTART 700 #define IDC_BINEDITSTART 700
#define IDC_BINPOS0 700 #define IDC_BINPOS0 700

View File

@ -14,10 +14,10 @@
* *
\****************************************************************************/ \****************************************************************************/
#include <random>
#include "CCommand.h" #include "CCommand.h"
#include "EngineStrings.h" #include "EngineStrings.h"
#include "../Command.h" #include "../Command.h"
#include "../CalculatorVector.h"
#include "../ExpressionCommand.h" #include "../ExpressionCommand.h"
#include "RadixType.h" #include "RadixType.h"
#include "History.h" // for History Collector #include "History.h" // for History Collector
@ -68,6 +68,10 @@ public:
{ {
return m_bError; return m_bError;
} }
bool IsInputEmpty()
{
return m_input.IsEmpty() && (m_numberString.empty() || m_numberString == L"0");
}
bool FInRecordingState() bool FInRecordingState()
{ {
return m_bRecord; return m_bRecord;
@ -94,7 +98,7 @@ public:
{ {
return s_engineStrings[std::to_wstring(ids)]; return s_engineStrings[std::to_wstring(ids)];
} }
static std::wstring_view GetString(std::wstring ids) static std::wstring_view GetString(std::wstring_view ids)
{ {
return s_engineStrings[ids]; return s_engineStrings[ids];
} }
@ -103,6 +107,7 @@ public:
return GetString(IdStrFromCmdId(nOpCode)); return GetString(IdStrFromCmdId(nOpCode));
} }
static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype); static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype);
static std::wstring_view OpCodeToBinaryString(int nOpCode, bool isIntegerMode);
private: private:
bool m_fPrecedence; bool m_fPrecedence;
@ -147,11 +152,16 @@ private:
NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode. NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode.
int32_t m_dwWordBitWidth; // # of bits in currently selected word size int32_t m_dwWordBitWidth; // # of bits in currently selected word size
std::unique_ptr<std::mt19937> m_randomGeneratorEngine;
std::unique_ptr<std::uniform_real_distribution<>> m_distr;
uint64_t m_carryBit;
CHistoryCollector m_HistoryCollector; // Accumulator of each line of history as various commands are processed CHistoryCollector m_HistoryCollector; // Accumulator of each line of history as various commands are processed
std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement
std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers
static std::unordered_map<std::wstring, std::wstring> s_engineStrings; // the string table shared across all instances static std::unordered_map<std::wstring_view, std::wstring> s_engineStrings; // the string table shared across all instances
wchar_t m_decimalSeparator; wchar_t m_decimalSeparator;
wchar_t m_groupSeparator; wchar_t m_groupSeparator;
@ -165,12 +175,14 @@ private:
void DisplayAnnounceBinaryOperator(); void DisplayAnnounceBinaryOperator();
void SetPrimaryDisplay(const std::wstring& szText, bool isError = false); void SetPrimaryDisplay(const std::wstring& szText, bool isError = false);
void ClearTemporaryValues(); void ClearTemporaryValues();
void ClearDisplay();
CalcEngine::Rational TruncateNumForIntMath(CalcEngine::Rational const& rat); CalcEngine::Rational TruncateNumForIntMath(CalcEngine::Rational const& rat);
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op); CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op);
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs); CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
void SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth); void SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth);
int32_t DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth); int32_t DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth);
uint32_t NRadixFromRadixType(RADIX_TYPE radixtype); uint32_t NRadixFromRadixType(RADIX_TYPE radixtype);
double GenerateRandomNumber();
bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno); bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno);
void CheckAndAddLastBinOpToHistory(bool addToHistory = true); void CheckAndAddLastBinOpToHistory(bool addToHistory = true);

View File

@ -66,6 +66,7 @@ namespace CalcEngine
bool TryBeginExponent(); bool TryBeginExponent();
void Backspace(); void Backspace();
void SetDecimalSymbol(wchar_t decSymbol); void SetDecimalSymbol(wchar_t decSymbol);
bool IsEmpty();
std::wstring ToString(uint32_t radix); std::wstring ToString(uint32_t radix);
Rational ToRational(uint32_t radix, int32_t precision); Rational ToRational(uint32_t radix, int32_t precision);

View File

@ -87,7 +87,6 @@ inline constexpr auto SIDS_XPOW3 = L"32";
inline constexpr auto SIDS_NFACTORIAL = L"33"; inline constexpr auto SIDS_NFACTORIAL = L"33";
inline constexpr auto SIDS_RECIPROCAL = L"34"; inline constexpr auto SIDS_RECIPROCAL = L"34";
inline constexpr auto SIDS_DMS = L"35"; inline constexpr auto SIDS_DMS = L"35";
inline constexpr auto SIDS_CUBEROOT = L"36";
inline constexpr auto SIDS_POWTEN = L"37"; inline constexpr auto SIDS_POWTEN = L"37";
inline constexpr auto SIDS_PERCENT = L"38"; inline constexpr auto SIDS_PERCENT = L"38";
inline constexpr auto SIDS_SCIENTIFIC_NOTATION = L"39"; inline constexpr auto SIDS_SCIENTIFIC_NOTATION = L"39";
@ -172,125 +171,193 @@ inline constexpr auto SIDS_ERR_UNEX_END = L"117";
inline constexpr auto SIDS_ERR_SG_INV_ERROR = L"118"; inline constexpr auto SIDS_ERR_SG_INV_ERROR = L"118";
inline constexpr auto SIDS_ERR_INPUT_OVERFLOW = L"119"; inline constexpr auto SIDS_ERR_INPUT_OVERFLOW = L"119";
inline constexpr auto SIDS_ERR_OUTPUT_OVERFLOW = L"120"; inline constexpr auto SIDS_ERR_OUTPUT_OVERFLOW = L"120";
inline constexpr auto SIDS_SECD = L"SecDeg";
inline constexpr auto SIDS_SECR = L"SecRad";
inline constexpr auto SIDS_SECG = L"SecGrad";
inline constexpr auto SIDS_ASECD = L"InverseSecDeg";
inline constexpr auto SIDS_ASECR = L"InverseSecRad";
inline constexpr auto SIDS_ASECG = L"InverseSecGrad";
inline constexpr auto SIDS_CSCD = L"CscDeg";
inline constexpr auto SIDS_CSCR = L"CscRad";
inline constexpr auto SIDS_CSCG = L"CscGrad";
inline constexpr auto SIDS_ACSCD = L"InverseCscDeg";
inline constexpr auto SIDS_ACSCR = L"InverseCscRad";
inline constexpr auto SIDS_ACSCG = L"InverseCscGrad";
inline constexpr auto SIDS_COTD = L"CotDeg";
inline constexpr auto SIDS_COTR = L"CotRad";
inline constexpr auto SIDS_COTG = L"CotGrad";
inline constexpr auto SIDS_ACOTD = L"InverseCotDeg";
inline constexpr auto SIDS_ACOTR = L"InverseCotRad";
inline constexpr auto SIDS_ACOTG = L"InverseCotGrad";
inline constexpr auto SIDS_SECH = L"Sech";
inline constexpr auto SIDS_ASECH = L"InverseSech";
inline constexpr auto SIDS_CSCH = L"Csch";
inline constexpr auto SIDS_ACSCH = L"InverseCsch";
inline constexpr auto SIDS_COTH = L"Coth";
inline constexpr auto SIDS_ACOTH = L"InverseCoth";
inline constexpr auto SIDS_TWOPOWX = L"TwoPowX";
inline constexpr auto SIDS_LOGBASEX = L"LogBaseX";
inline constexpr auto SIDS_ABS = L"Abs";
inline constexpr auto SIDS_FLOOR = L"Floor";
inline constexpr auto SIDS_CEIL = L"Ceil";
inline constexpr auto SIDS_NAND = L"Nand";
inline constexpr auto SIDS_NOR = L"Nor";
inline constexpr auto SIDS_CUBEROOT = L"CubeRoot";
inline constexpr auto SIDS_PROGRAMMER_MOD = L"ProgrammerMod";
// Include the resource key ID from above into this vector to load it into memory for the engine to use // Include the resource key ID from above into this vector to load it into memory for the engine to use
inline constexpr std::array<std::wstring_view, 120> g_sids = { SIDS_PLUS_MINUS, inline constexpr std::array<std::wstring_view, 152> g_sids =
SIDS_C, {
SIDS_CE, SIDS_PLUS_MINUS,
SIDS_BACKSPACE, SIDS_C,
SIDS_DECIMAL_SEPARATOR, SIDS_CE,
SIDS_EMPTY_STRING, SIDS_BACKSPACE,
SIDS_AND, SIDS_DECIMAL_SEPARATOR,
SIDS_OR, SIDS_EMPTY_STRING,
SIDS_XOR, SIDS_AND,
SIDS_LSH, SIDS_OR,
SIDS_RSH, SIDS_XOR,
SIDS_DIVIDE, SIDS_LSH,
SIDS_MULTIPLY, SIDS_RSH,
SIDS_PLUS, SIDS_DIVIDE,
SIDS_MINUS, SIDS_MULTIPLY,
SIDS_MOD, SIDS_PLUS,
SIDS_YROOT, SIDS_MINUS,
SIDS_POW_HAT, SIDS_MOD,
SIDS_INT, SIDS_YROOT,
SIDS_ROL, SIDS_POW_HAT,
SIDS_ROR, SIDS_INT,
SIDS_NOT, SIDS_ROL,
SIDS_SIN, SIDS_ROR,
SIDS_COS, SIDS_NOT,
SIDS_TAN, SIDS_SIN,
SIDS_SINH, SIDS_COS,
SIDS_COSH, SIDS_TAN,
SIDS_TANH, SIDS_SINH,
SIDS_LN, SIDS_COSH,
SIDS_LOG, SIDS_TANH,
SIDS_SQRT, SIDS_LN,
SIDS_XPOW2, SIDS_LOG,
SIDS_XPOW3, SIDS_SQRT,
SIDS_NFACTORIAL, SIDS_XPOW2,
SIDS_RECIPROCAL, SIDS_XPOW3,
SIDS_DMS, SIDS_NFACTORIAL,
SIDS_CUBEROOT, SIDS_RECIPROCAL,
SIDS_POWTEN, SIDS_DMS,
SIDS_PERCENT, SIDS_POWTEN,
SIDS_SCIENTIFIC_NOTATION, SIDS_PERCENT,
SIDS_PI, SIDS_SCIENTIFIC_NOTATION,
SIDS_EQUAL, SIDS_PI,
SIDS_MC, SIDS_EQUAL,
SIDS_MR, SIDS_MC,
SIDS_MS, SIDS_MR,
SIDS_MPLUS, SIDS_MS,
SIDS_MMINUS, SIDS_MPLUS,
SIDS_EXP, SIDS_MMINUS,
SIDS_OPEN_PAREN, SIDS_EXP,
SIDS_CLOSE_PAREN, SIDS_OPEN_PAREN,
SIDS_0, SIDS_CLOSE_PAREN,
SIDS_1, SIDS_0,
SIDS_2, SIDS_1,
SIDS_3, SIDS_2,
SIDS_4, SIDS_3,
SIDS_5, SIDS_4,
SIDS_6, SIDS_5,
SIDS_7, SIDS_6,
SIDS_8, SIDS_7,
SIDS_9, SIDS_8,
SIDS_A, SIDS_9,
SIDS_B, SIDS_A,
SIDS_C, SIDS_B,
SIDS_D, SIDS_C,
SIDS_E, SIDS_D,
SIDS_F, SIDS_E,
SIDS_FRAC, SIDS_F,
SIDS_SIND, SIDS_FRAC,
SIDS_COSD, SIDS_SIND,
SIDS_TAND, SIDS_COSD,
SIDS_ASIND, SIDS_TAND,
SIDS_ACOSD, SIDS_ASIND,
SIDS_ATAND, SIDS_ACOSD,
SIDS_SINR, SIDS_ATAND,
SIDS_COSR, SIDS_SINR,
SIDS_TANR, SIDS_COSR,
SIDS_ASINR, SIDS_TANR,
SIDS_ACOSR, SIDS_ASINR,
SIDS_ATANR, SIDS_ACOSR,
SIDS_SING, SIDS_ATANR,
SIDS_COSG, SIDS_SING,
SIDS_TANG, SIDS_COSG,
SIDS_ASING, SIDS_TANG,
SIDS_ACOSG, SIDS_ASING,
SIDS_ATANG, SIDS_ACOSG,
SIDS_ASINH, SIDS_ATANG,
SIDS_ACOSH, SIDS_ASINH,
SIDS_ATANH, SIDS_ACOSH,
SIDS_POWE, SIDS_ATANH,
SIDS_POWTEN2, SIDS_POWE,
SIDS_SQRT2, SIDS_POWTEN2,
SIDS_SQR, SIDS_SQRT2,
SIDS_CUBE, SIDS_SQR,
SIDS_CUBERT, SIDS_CUBE,
SIDS_FACT, SIDS_CUBERT,
SIDS_RECIPROC, SIDS_FACT,
SIDS_DEGREES, SIDS_RECIPROC,
SIDS_NEGATE, SIDS_DEGREES,
SIDS_RSH, SIDS_NEGATE,
SIDS_DIVIDEBYZERO, SIDS_RSH,
SIDS_DOMAIN, SIDS_DIVIDEBYZERO,
SIDS_UNDEFINED, SIDS_DOMAIN,
SIDS_POS_INFINITY, SIDS_UNDEFINED,
SIDS_NEG_INFINITY, SIDS_POS_INFINITY,
SIDS_ABORTED, SIDS_NEG_INFINITY,
SIDS_NOMEM, SIDS_ABORTED,
SIDS_TOOMANY, SIDS_NOMEM,
SIDS_OVERFLOW, SIDS_TOOMANY,
SIDS_NORESULT, SIDS_OVERFLOW,
SIDS_INSUFFICIENT_DATA, SIDS_NORESULT,
SIDS_ERR_UNK_CH, SIDS_INSUFFICIENT_DATA,
SIDS_ERR_UNK_FN, SIDS_ERR_UNK_CH,
SIDS_ERR_UNEX_NUM, SIDS_ERR_UNK_FN,
SIDS_ERR_UNEX_CH, SIDS_ERR_UNEX_NUM,
SIDS_ERR_UNEX_SZ, SIDS_ERR_UNEX_CH,
SIDS_ERR_MISMATCH_CLOSE, SIDS_ERR_UNEX_SZ,
SIDS_ERR_UNEX_END, SIDS_ERR_MISMATCH_CLOSE,
SIDS_ERR_SG_INV_ERROR, SIDS_ERR_UNEX_END,
SIDS_ERR_INPUT_OVERFLOW, SIDS_ERR_SG_INV_ERROR,
SIDS_ERR_OUTPUT_OVERFLOW }; SIDS_ERR_INPUT_OVERFLOW,
SIDS_ERR_OUTPUT_OVERFLOW,
SIDS_SECD,
SIDS_SECG,
SIDS_SECR,
SIDS_ASECD,
SIDS_ASECR,
SIDS_ASECG,
SIDS_CSCD,
SIDS_CSCR,
SIDS_CSCG,
SIDS_ACSCD,
SIDS_ACSCR,
SIDS_ACSCG,
SIDS_COTD,
SIDS_COTR,
SIDS_COTG,
SIDS_ACOTD,
SIDS_ACOTR,
SIDS_ACOTG,
SIDS_SECH,
SIDS_ASECH,
SIDS_CSCH,
SIDS_ACSCH,
SIDS_COTH,
SIDS_ACOTH,
SIDS_TWOPOWX,
SIDS_LOGBASEX,
SIDS_ABS,
SIDS_FLOOR,
SIDS_CEIL,
SIDS_NAND,
SIDS_NOR,
SIDS_CUBEROOT,
SIDS_PROGRAMMER_MOD,
};

View File

@ -21,8 +21,8 @@ public:
~CHistoryCollector(); ~CHistoryCollector();
void AddOpndToHistory(std::wstring_view numStr, CalcEngine::Rational const& rat, bool fRepetition = false); void AddOpndToHistory(std::wstring_view numStr, CalcEngine::Rational const& rat, bool fRepetition = false);
void RemoveLastOpndFromHistory(); void RemoveLastOpndFromHistory();
void AddBinOpToHistory(int nOpCode, bool fNoRepetition = true); void AddBinOpToHistory(int nOpCode, bool isIntgerMode, bool fNoRepetition = true);
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher); void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode);
void AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE angletype); void AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE angletype);
void AddOpenBraceToHistory(); void AddOpenBraceToHistory();
void AddCloseBraceToHistory(); void AddCloseBraceToHistory();
@ -31,6 +31,7 @@ public:
void EnclosePrecInversionBrackets(); void EnclosePrecInversionBrackets();
bool FOpndAddedToHistory(); bool FOpndAddedToHistory();
void CompleteHistoryLine(std::wstring_view numStr); void CompleteHistoryLine(std::wstring_view numStr);
void CompleteEquation(std::wstring_view numStr);
void ClearHistoryLine(std::wstring_view errStr); void ClearHistoryLine(std::wstring_view errStr);
int AddCommand(_In_ const std::shared_ptr<IExpressionCommand>& spCommand); int AddCommand(_In_ const std::shared_ptr<IExpressionCommand>& spCommand);
void UpdateHistoryExpression(uint32_t radix, int32_t precision); void UpdateHistoryExpression(uint32_t radix, int32_t precision);
@ -50,8 +51,8 @@ private:
int m_curOperandIndex; // Stack index for the above stack int m_curOperandIndex; // Stack index for the above stack
bool m_bLastOpndBrace; // iff the last opnd in history is already braced so we can avoid putting another one for unary operator bool m_bLastOpndBrace; // iff the last opnd in history is already braced so we can avoid putting another one for unary operator
wchar_t m_decimalSymbol; wchar_t m_decimalSymbol;
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_spTokens; std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands; std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
private: private:
void ReinitHistory(); void ReinitHistory();
@ -59,5 +60,5 @@ private:
void TruncateEquationSzFromIch(int ich); void TruncateEquationSzFromIch(int ich);
void SetExpressionDisplay(); void SetExpressionDisplay();
void InsertSzInEquationSz(std::wstring_view str, int icommandIndex, int ich); void InsertSzInEquationSz(std::wstring_view str, int icommandIndex, int ich);
std::shared_ptr<CalculatorVector<int>> GetOperandCommandsFromString(std::wstring_view numStr); std::shared_ptr<std::vector<int>> GetOperandCommandsFromString(std::wstring_view numStr);
}; };

View File

@ -3,7 +3,6 @@
#pragma once #pragma once
#include "../CalculatorVector.h"
#include "../ExpressionCommandInterface.h" #include "../ExpressionCommandInterface.h"
// Callback interface to be implemented by the clients of CCalcEngine // Callback interface to be implemented by the clients of CCalcEngine
@ -13,8 +12,8 @@ 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( virtual void SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens, _Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) = 0; _Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands) = 0;
virtual void SetParenthesisNumber(_In_ unsigned int count) = 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.
@ -22,4 +21,5 @@ public:
virtual void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) = 0; virtual void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) = 0;
virtual void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers) = 0; virtual void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers) = 0;
virtual void MemoryItemChanged(unsigned int indexOfMemory) = 0; virtual void MemoryItemChanged(unsigned int indexOfMemory) = 0;
virtual void InputChanged() = 0;
}; };

View File

@ -1,15 +1,17 @@
// 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 "../ExpressionCommandInterface.h"
// Callback interface to be implemented by the clients of CCalcEngine if they require equation history // Callback interface to be implemented by the clients of CCalcEngine if they require equation history
class IHistoryDisplay class IHistoryDisplay
{ {
public: public:
virtual ~IHistoryDisplay(){}; virtual ~IHistoryDisplay(){};
virtual unsigned int AddToHistory( virtual unsigned int AddToHistory(
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens, _In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands, _In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands,
_In_ std::wstring_view result) = 0; _In_ std::wstring_view result) = 0;
}; };

View File

@ -16,8 +16,7 @@ namespace CalcManager::NumberFormattingUtils
return; return;
} }
wstring::iterator iter; for (auto iter = number.end() - 1;; iter--)
for (iter = number.end() - 1;; iter--)
{ {
if (*iter != L'0') if (*iter != L'0')
{ {
@ -25,9 +24,9 @@ namespace CalcManager::NumberFormattingUtils
break; break;
} }
} }
if (*(number.end() - 1) == L'.') if (number.back() == L'.')
{ {
number.erase(number.end() - 1, number.end()); number.pop_back();
} }
} }

View File

@ -41,45 +41,45 @@ typedef int32_t ResultCode;
// CALC_E_DIVIDEBYZERO // CALC_E_DIVIDEBYZERO
// //
// The current operation would require a divide by zero to complete // The current operation would require a divide by zero to complete
#define CALC_E_DIVIDEBYZERO ((uint32_t)0x80000000) static constexpr uint32_t CALC_E_DIVIDEBYZERO = (uint32_t)0x80000000;
// CALC_E_DOMAIN // CALC_E_DOMAIN
// //
// The given input is not within the domain of this function // The given input is not within the domain of this function
#define CALC_E_DOMAIN ((uint32_t)0x80000001) static constexpr uint32_t CALC_E_DOMAIN = (uint32_t)0x80000001;
// CALC_E_INDEFINITE // CALC_E_INDEFINITE
// //
// The result of this function is undefined // The result of this function is undefined
#define CALC_E_INDEFINITE ((uint32_t)0x80000002) static constexpr uint32_t CALC_E_INDEFINITE = (uint32_t)0x80000002;
// CALC_E_POSINFINITY // CALC_E_POSINFINITY
// //
// The result of this function is Positive Infinity. // The result of this function is Positive Infinity.
#define CALC_E_POSINFINITY ((uint32_t)0x80000003) static constexpr uint32_t CALC_E_POSINFINITY = (uint32_t)0x80000003;
// CALC_E_NEGINFINITY // CALC_E_NEGINFINITY
// //
// The result of this function is Negative Infinity // The result of this function is Negative Infinity
#define CALC_E_NEGINFINITY ((uint32_t)0x80000004) static constexpr uint32_t CALC_E_NEGINFINITY = (uint32_t)0x80000004;
// CALC_E_INVALIDRANGE // CALC_E_INVALIDRANGE
// //
// The given input is within the domain of the function but is beyond // The given input is within the domain of the function but is beyond
// the range for which calc can successfully compute the answer // the range for which calc can successfully compute the answer
#define CALC_E_INVALIDRANGE ((uint32_t)0x80000006) static constexpr uint32_t CALC_E_INVALIDRANGE = (uint32_t)0x80000006;
// CALC_E_OUTOFMEMORY // CALC_E_OUTOFMEMORY
// //
// There is not enough free memory to complete the requested function // There is not enough free memory to complete the requested function
#define CALC_E_OUTOFMEMORY ((uint32_t)0x80000007) static constexpr uint32_t CALC_E_OUTOFMEMORY = (uint32_t)0x80000007;
// CALC_E_OVERFLOW // CALC_E_OVERFLOW
// //
// The result of this operation is an overflow // The result of this operation is an overflow
#define CALC_E_OVERFLOW ((uint32_t)0x80000008) static constexpr uint32_t CALC_E_OVERFLOW = (uint32_t)0x80000008;
// CALC_E_NORESULT // CALC_E_NORESULT
// //
// The result of this operation is undefined // The result of this operation is undefined
#define CALC_E_NORESULT ((uint32_t)0x80000009) static constexpr uint32_t CALC_E_NORESULT = (uint32_t)0x80000009;

View File

@ -34,7 +34,7 @@ void _mulnumx(PNUMBER* pa, PNUMBER b);
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void mulnumx(PNUMBER* pa, PNUMBER b) void mulnumx(_Inout_ PNUMBER* pa, _In_ PNUMBER b)
{ {
if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0) if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0)
@ -172,7 +172,7 @@ void _mulnumx(PNUMBER* pa, PNUMBER b)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void numpowi32x(_Inout_ PNUMBER* proot, _In_ int32_t power) void numpowi32x(_Inout_ PNUMBER* proot, int32_t power)
{ {
PNUMBER lret = i32tonum(1, BASEX); PNUMBER lret = i32tonum(1, BASEX);
@ -215,7 +215,7 @@ void _divnumx(PNUMBER* pa, PNUMBER b, int32_t precision);
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void divnumx(PNUMBER* pa, PNUMBER b, int32_t precision) void divnumx(_Inout_ PNUMBER* pa, _In_ PNUMBER b, int32_t precision)
{ {
if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0) if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0)

View File

@ -145,7 +145,7 @@ void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void _destroynum(_In_ PNUMBER pnum) void _destroynum(_Frees_ptr_opt_ PNUMBER pnum)
{ {
if (pnum != nullptr) if (pnum != nullptr)
@ -167,7 +167,7 @@ void _destroynum(_In_ PNUMBER pnum)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void _destroyrat(_In_ PRAT prat) void _destroyrat(_Frees_ptr_opt_ PRAT prat)
{ {
if (prat != nullptr) if (prat != nullptr)
@ -760,7 +760,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PRAT i32torat(_In_ int32_t ini32) PRAT i32torat(int32_t ini32)
{ {
PRAT pratret = nullptr; PRAT pratret = nullptr;
@ -784,7 +784,7 @@ PRAT i32torat(_In_ int32_t ini32)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PRAT Ui32torat(_In_ uint32_t inui32) PRAT Ui32torat(uint32_t inui32)
{ {
PRAT pratret = nullptr; PRAT pratret = nullptr;

View File

@ -39,7 +39,7 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void _exprat(PRAT* px, int32_t precision) void _exprat(_Inout_ PRAT* px, int32_t precision)
{ {
CREATETAYLOR(); CREATETAYLOR();
@ -58,7 +58,7 @@ void _exprat(PRAT* px, int32_t precision)
DESTROYTAYLOR(); DESTROYTAYLOR();
} }
void exprat(PRAT* px, uint32_t radix, int32_t precision) void exprat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT pwr = nullptr; PRAT pwr = nullptr;
@ -150,7 +150,7 @@ void _lograt(PRAT* px, int32_t precision)
DESTROYTAYLOR(); DESTROYTAYLOR();
} }
void lograt(PRAT* px, int32_t precision) void lograt(_Inout_ PRAT* px, int32_t precision)
{ {
bool fneglog; bool fneglog;
@ -224,7 +224,7 @@ void lograt(PRAT* px, int32_t precision)
destroyrat(pwr); destroyrat(pwr);
} }
void log10rat(PRAT* px, int32_t precision) void log10rat(_Inout_ PRAT* px, int32_t precision)
{ {
lograt(px, precision); lograt(px, precision);
@ -267,7 +267,7 @@ bool IsEven(PRAT x, uint32_t radix, int32_t precision)
// //
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void powrat(PRAT* px, PRAT y, uint32_t radix, int32_t precision) void powrat(_Inout_ PRAT* px, _In_ PRAT y, uint32_t radix, int32_t precision)
{ {
// Handle cases where px or y is 0 by calling powratcomp directly // Handle cases where px or y is 0 by calling powratcomp directly
if (zerrat(*px) || zerrat(y)) if (zerrat(*px) || zerrat(y))
@ -294,7 +294,7 @@ void powrat(PRAT* px, PRAT y, uint32_t radix, int32_t precision)
} }
} }
void powratNumeratorDenominator(PRAT* px, PRAT y, uint32_t radix, int32_t precision) void powratNumeratorDenominator(_Inout_ PRAT* px, _In_ PRAT y, uint32_t radix, int32_t precision)
{ {
// Prepare rationals // Prepare rationals
PRAT yNumerator = nullptr; PRAT yNumerator = nullptr;
@ -403,7 +403,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(_Inout_ PRAT* px, _In_ PRAT y, uint32_t radix, int32_t precision)
{ {
int32_t sign = SIGN(*px); int32_t sign = SIGN(*px);

View File

@ -190,7 +190,7 @@ void _gamma(PRAT* pn, uint32_t radix, int32_t precision)
destroyrat(sum); destroyrat(sum);
} }
void factrat(PRAT* px, uint32_t radix, int32_t precision) void factrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT fact = nullptr; PRAT fact = nullptr;

View File

@ -83,7 +83,7 @@ void asinanglerat(_Inout_ PRAT* pa, ANGLE_TYPE angletype, uint32_t radix, int32_
ascalerat(pa, angletype, precision); ascalerat(pa, angletype, precision);
} }
void asinrat(PRAT* px, uint32_t radix, int32_t precision) void asinrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT pret = nullptr; PRAT pret = nullptr;
@ -190,7 +190,7 @@ void _acosrat(PRAT* px, int32_t precision)
DESTROYTAYLOR(); DESTROYTAYLOR();
} }
void acosrat(PRAT* px, uint32_t radix, int32_t precision) void acosrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
int32_t sgn = SIGN(*px); int32_t sgn = SIGN(*px);
@ -276,7 +276,7 @@ void _atanrat(PRAT* px, int32_t precision)
DESTROYTAYLOR(); DESTROYTAYLOR();
} }
void atanrat(PRAT* px, uint32_t radix, int32_t precision) void atanrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT tmpx = nullptr; PRAT tmpx = nullptr;

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.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -47,7 +47,7 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void asinhrat(PRAT* px, uint32_t radix, int32_t precision) void asinhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT neg_pt_eight_five = nullptr; PRAT neg_pt_eight_five = nullptr;
@ -101,7 +101,7 @@ void asinhrat(PRAT* px, uint32_t radix, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void acoshrat(PRAT* px, uint32_t radix, int32_t precision) void acoshrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
if (rat_lt(*px, rat_one, precision)) if (rat_lt(*px, rat_one, precision))
@ -138,7 +138,7 @@ void acoshrat(PRAT* px, uint32_t radix, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void atanhrat(PRAT* px, int32_t precision) void atanhrat(_Inout_ PRAT* px, int32_t precision)
{ {
PRAT ptmp = nullptr; PRAT ptmp = nullptr;

View File

@ -17,7 +17,7 @@
using namespace std; using namespace std;
void lshrat(PRAT* pa, PRAT b, uint32_t radix, int32_t precision) void lshrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision)
{ {
PRAT pwr = nullptr; PRAT pwr = nullptr;
@ -40,7 +40,7 @@ void lshrat(PRAT* pa, PRAT b, uint32_t radix, int32_t precision)
} }
} }
void rshrat(PRAT* pa, PRAT b, uint32_t radix, int32_t precision) void rshrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision)
{ {
PRAT pwr = nullptr; PRAT pwr = nullptr;
@ -73,19 +73,19 @@ enum
FUNC_XOR FUNC_XOR
} BOOL_FUNCS; } BOOL_FUNCS;
void andrat(PRAT* pa, PRAT b, uint32_t radix, int32_t precision) void andrat(_Inout_ PRAT* pa, _In_ 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(_Inout_ PRAT* pa, _In_ 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(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision)
{ {
boolrat(pa, b, FUNC_XOR, radix, precision); boolrat(pa, b, FUNC_XOR, radix, precision);
@ -191,7 +191,7 @@ void boolnum(PNUMBER* pa, PNUMBER b, int func)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void remrat(PRAT* pa, PRAT b) void remrat(_Inout_ PRAT* pa, _In_ PRAT b)
{ {
if (zerrat(b)) if (zerrat(b))
@ -228,7 +228,7 @@ void remrat(PRAT* pa, PRAT b)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void modrat(PRAT* pa, PRAT b) void modrat(_Inout_ PRAT* pa, _In_ PRAT b)
{ {
// contrary to remrat(X, 0) returning 0, modrat(X, 0) must return X // contrary to remrat(X, 0) returning 0, modrat(X, 0) must return X
if (zerrat(b)) if (zerrat(b))

View File

@ -43,7 +43,7 @@ using namespace std;
void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix); void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix);
void addnum(PNUMBER* pa, PNUMBER b, uint32_t radix) void addnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix)
{ {
if (b->cdigit > 1 || b->mant[0] != 0) if (b->cdigit > 1 || b->mant[0] != 0)
@ -186,7 +186,7 @@ void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
void _mulnum(PNUMBER* pa, PNUMBER b, uint32_t radix); void _mulnum(PNUMBER* pa, PNUMBER b, uint32_t radix);
void mulnum(PNUMBER* pa, PNUMBER b, uint32_t radix) void mulnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix)
{ {
if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0) if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0)
@ -302,7 +302,7 @@ void _mulnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void remnum(PNUMBER* pa, PNUMBER b, uint32_t radix) void remnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix)
{ {
PNUMBER tmp = nullptr; // tmp is the working remainder. PNUMBER tmp = nullptr; // tmp is the working remainder.
@ -365,7 +365,7 @@ void remnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision); void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision);
void divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision) void divnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix, int32_t precision)
{ {
if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0) if (b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0)
@ -489,7 +489,7 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool equnum(PNUMBER a, PNUMBER b) bool equnum(_In_ PNUMBER a, _In_ PNUMBER b)
{ {
int32_t diff; int32_t diff;
@ -555,7 +555,7 @@ bool equnum(PNUMBER a, PNUMBER b)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool lessnum(PNUMBER a, PNUMBER b) bool lessnum(_In_ PNUMBER a, _In_ PNUMBER b)
{ {
int32_t diff; int32_t diff;
@ -614,7 +614,7 @@ bool lessnum(PNUMBER a, PNUMBER b)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool zernum(PNUMBER a) bool zernum(_In_ PNUMBER a)
{ {
int32_t length; int32_t length;

View File

@ -37,7 +37,7 @@ using namespace std;
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gcdrat(PRAT* pa, int32_t precision) void gcdrat(_Inout_ PRAT* pa, int32_t precision)
{ {
PNUMBER pgcd = nullptr; PNUMBER pgcd = nullptr;
@ -70,7 +70,7 @@ void gcdrat(PRAT* pa, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void fracrat(PRAT* pa, uint32_t radix, int32_t precision) void fracrat(_Inout_ PRAT* pa, uint32_t radix, int32_t precision)
{ {
// Only do the flatrat operation if number is nonzero. // Only do the flatrat operation if number is nonzero.
// and only if the bottom part is not one. // and only if the bottom part is not one.
@ -98,7 +98,7 @@ void fracrat(PRAT* pa, uint32_t radix, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void mulrat(PRAT* pa, PRAT b, int32_t precision) void mulrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
{ {
// Only do the multiply if it isn't zero. // Only do the multiply if it isn't zero.
@ -132,7 +132,7 @@ void mulrat(PRAT* pa, PRAT b, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void divrat(PRAT* pa, PRAT b, int32_t precision) void divrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
{ {
if (!zernum((*pa)->pp)) if (!zernum((*pa)->pp))
@ -182,7 +182,7 @@ void divrat(PRAT* pa, PRAT b, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void subrat(PRAT* pa, PRAT b, int32_t precision) void subrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
{ {
b->pp->sign *= -1; b->pp->sign *= -1;
@ -203,7 +203,7 @@ void subrat(PRAT* pa, PRAT b, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void addrat(PRAT* pa, PRAT b, int32_t precision) void addrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
{ {
PNUMBER bot = nullptr; PNUMBER bot = nullptr;
@ -255,7 +255,7 @@ void addrat(PRAT* pa, PRAT b, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void rootrat(PRAT* py, PRAT n, uint32_t radix, int32_t precision) void rootrat(_Inout_ PRAT* py, _In_ PRAT n, uint32_t radix, int32_t precision)
{ {
// Initialize 1/n // Initialize 1/n
PRAT oneovern = nullptr; PRAT oneovern = nullptr;
@ -280,7 +280,7 @@ void rootrat(PRAT* py, PRAT n, uint32_t radix, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool zerrat(PRAT a) bool zerrat(_In_ PRAT a)
{ {
return (zernum(a->pp)); return (zernum(a->pp));

View File

@ -369,7 +369,7 @@ extern PNUMBER i32factnum(int32_t ini32, uint32_t radix);
extern PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix); extern PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix);
extern PNUMBER i32tonum(int32_t ini32, uint32_t radix); extern PNUMBER i32tonum(int32_t ini32, uint32_t radix);
extern PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix); extern PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix);
extern PNUMBER numtonRadixx(PNUMBER a, uint32_t radix); extern PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix);
// creates a empty/undefined rational representation (p/q) // creates a empty/undefined rational representation (p/q)
extern PRAT _createrat(void); extern PRAT _createrat(void);
@ -446,8 +446,8 @@ extern void tananglerat(_Inout_ PRAT* px, ANGLE_TYPE angletype, uint32_t radix,
extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src); extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src);
extern void _destroynum(_In_ PNUMBER pnum); extern void _destroynum(_Frees_ptr_opt_ PNUMBER pnum);
extern void _destroyrat(_In_ PRAT prat); extern void _destroyrat(_Frees_ptr_opt_ PRAT prat);
extern void addnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix); extern void addnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix);
extern void addrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision); extern void addrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision);
extern void andrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void andrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);

View File

@ -296,7 +296,7 @@ void ChangeConstants(uint32_t radix, int32_t precision)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void intrat(PRAT* px, uint32_t radix, int32_t precision) void intrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
// Only do the intrat operation if number is nonzero. // Only do the intrat operation if number is nonzero.
// and only if the bottom part is not one. // and only if the bottom part is not one.
@ -328,7 +328,7 @@ void intrat(PRAT* px, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool rat_equ(PRAT a, PRAT b, int32_t precision) bool rat_equ(_In_ PRAT a, _In_ PRAT b, int32_t precision)
{ {
PRAT rattmp = nullptr; PRAT rattmp = nullptr;
@ -351,7 +351,7 @@ bool rat_equ(PRAT a, PRAT b, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool rat_ge(PRAT a, PRAT b, int32_t precision) bool rat_ge(_In_ PRAT a, _In_ PRAT b, int32_t precision)
{ {
PRAT rattmp = nullptr; PRAT rattmp = nullptr;
@ -375,7 +375,7 @@ bool rat_ge(PRAT a, PRAT b, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool rat_gt(PRAT a, PRAT b, int32_t precision) bool rat_gt(_In_ PRAT a, _In_ PRAT b, int32_t precision)
{ {
PRAT rattmp = nullptr; PRAT rattmp = nullptr;
@ -399,7 +399,7 @@ bool rat_gt(PRAT a, PRAT b, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool rat_le(PRAT a, PRAT b, int32_t precision) bool rat_le(_In_ PRAT a, _In_ PRAT b, int32_t precision)
{ {
PRAT rattmp = nullptr; PRAT rattmp = nullptr;
@ -423,7 +423,7 @@ bool rat_le(PRAT a, PRAT b, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool rat_lt(PRAT a, PRAT b, int32_t precision) bool rat_lt(_In_ PRAT a, _In_ PRAT b, int32_t precision)
{ {
PRAT rattmp = nullptr; PRAT rattmp = nullptr;
@ -447,7 +447,7 @@ bool rat_lt(PRAT a, PRAT b, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool rat_neq(PRAT a, PRAT b, int32_t precision) bool rat_neq(_In_ PRAT a, _In_ PRAT b, int32_t precision)
{ {
PRAT rattmp = nullptr; PRAT rattmp = nullptr;
@ -470,7 +470,7 @@ bool rat_neq(PRAT a, PRAT b, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void scale(PRAT* px, PRAT scalefact, uint32_t radix, int32_t precision) void scale(_Inout_ PRAT* px, _In_ PRAT scalefact, uint32_t radix, int32_t precision)
{ {
PRAT pret = nullptr; PRAT pret = nullptr;
DUPRAT(pret, *px); DUPRAT(pret, *px);
@ -503,7 +503,7 @@ void scale(PRAT* px, PRAT scalefact, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void scale2pi(PRAT* px, uint32_t radix, int32_t precision) void scale2pi(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT pret = nullptr; PRAT pret = nullptr;
PRAT my_two_pi = nullptr; PRAT my_two_pi = nullptr;
@ -546,7 +546,7 @@ void scale2pi(PRAT* px, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void inbetween(PRAT* px, PRAT range, int32_t precision) void inbetween(_In_ PRAT* px, _In_ PRAT range, int32_t precision)
{ {
if (rat_gt(*px, range, precision)) if (rat_gt(*px, range, precision))
@ -575,7 +575,7 @@ void inbetween(PRAT* px, PRAT range, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void _dumprawrat(const wchar_t* varname, PRAT rat, wostream& out) void _dumprawrat(_In_ const wchar_t* varname, _In_ PRAT rat, wostream& out)
{ {
_dumprawnum(varname, rat->pp, out); _dumprawnum(varname, rat->pp, out);
@ -593,7 +593,7 @@ void _dumprawrat(const wchar_t* varname, PRAT rat, wostream& out)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void _dumprawnum(const wchar_t* varname, PNUMBER num, wostream& out) void _dumprawnum(_In_ const wchar_t* varname, _In_ PNUMBER num, wostream& out)
{ {
int i; int i;
@ -676,7 +676,7 @@ void _readconstants(void)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void trimit(PRAT* px, int32_t precision) void trimit(_Inout_ PRAT* px, int32_t precision)
{ {
if (!g_ftrueinfinite) if (!g_ftrueinfinite)

View File

@ -187,7 +187,7 @@ void _cosrat(PRAT* px, uint32_t radix, int32_t precision)
} }
} }
void cosrat(PRAT* px, uint32_t radix, int32_t precision) void cosrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
scale2pi(px, radix, precision); scale2pi(px, radix, precision);
_cosrat(px, radix, precision); _cosrat(px, radix, precision);
@ -257,7 +257,7 @@ void _tanrat(PRAT* px, uint32_t radix, int32_t precision)
destroyrat(ptmp); destroyrat(ptmp);
} }
void tanrat(PRAT* px, uint32_t radix, int32_t precision) void tanrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
scale2pi(px, radix, precision); scale2pi(px, radix, precision);
_tanrat(px, radix, precision); _tanrat(px, radix, precision);

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.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -88,7 +88,7 @@ void _sinhrat(PRAT* px, int32_t precision)
DESTROYTAYLOR(); DESTROYTAYLOR();
} }
void sinhrat(PRAT* px, uint32_t radix, int32_t precision) void sinhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT tmpx = nullptr; PRAT tmpx = nullptr;
@ -169,7 +169,7 @@ void _coshrat(PRAT* px, uint32_t radix, int32_t precision)
DESTROYTAYLOR(); DESTROYTAYLOR();
} }
void coshrat(PRAT* px, uint32_t radix, int32_t precision) void coshrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT tmpx = nullptr; PRAT tmpx = nullptr;
@ -211,7 +211,7 @@ void coshrat(PRAT* px, uint32_t radix, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void tanhrat(PRAT* px, uint32_t radix, int32_t precision) void tanhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{ {
PRAT ptmp = nullptr; PRAT ptmp = nullptr;

View File

@ -401,43 +401,43 @@ void UnitConverter::SendCommand(Command command)
switch (command) switch (command)
{ {
case Command::Zero: case Command::Zero:
m_currentDisplay += L"0"; m_currentDisplay += L'0';
break; break;
case Command::One: case Command::One:
m_currentDisplay += L"1"; m_currentDisplay += L'1';
break; break;
case Command::Two: case Command::Two:
m_currentDisplay += L"2"; m_currentDisplay += L'2';
break; break;
case Command::Three: case Command::Three:
m_currentDisplay += L"3"; m_currentDisplay += L'3';
break; break;
case Command::Four: case Command::Four:
m_currentDisplay += L"4"; m_currentDisplay += L'4';
break; break;
case Command::Five: case Command::Five:
m_currentDisplay += L"5"; m_currentDisplay += L'5';
break; break;
case Command::Six: case Command::Six:
m_currentDisplay += L"6"; m_currentDisplay += L'6';
break; break;
case Command::Seven: case Command::Seven:
m_currentDisplay += L"7"; m_currentDisplay += L'7';
break; break;
case Command::Eight: case Command::Eight:
m_currentDisplay += L"8"; m_currentDisplay += L'8';
break; break;
case Command::Nine: case Command::Nine:
m_currentDisplay += L"9"; m_currentDisplay += L'9';
break; break;
case Command::Decimal: case Command::Decimal:
@ -445,7 +445,7 @@ void UnitConverter::SendCommand(Command command)
clearBack = false; clearBack = false;
if (!m_currentHasDecimal) if (!m_currentHasDecimal)
{ {
m_currentDisplay += L"."; m_currentDisplay += L'.';
m_currentHasDecimal = true; m_currentHasDecimal = true;
} }
break; break;

View File

@ -22,3 +22,5 @@
#include <winerror.h> #include <winerror.h>
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
#include <random>
#include <iomanip>

View File

@ -43,7 +43,7 @@ namespace
ApplicationViewModel::ApplicationViewModel() ApplicationViewModel::ApplicationViewModel()
: m_CalculatorViewModel(nullptr) : m_CalculatorViewModel(nullptr)
, m_DateCalcViewModel(nullptr) , m_DateCalcViewModel(nullptr)
, m_GraphingCalcViewModel(nullptr) , m_GraphingCalcViewModel(nullptr)
, m_ConverterViewModel(nullptr) , m_ConverterViewModel(nullptr)
, m_PreviousMode(ViewMode::None) , m_PreviousMode(ViewMode::None)
, m_mode(ViewMode::None) , m_mode(ViewMode::None)
@ -86,7 +86,7 @@ void ApplicationViewModel::Initialize(ViewMode mode)
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
TraceLogger::GetInstance().LogStandardException(mode, __FUNCTIONW__, e); TraceLogger::GetInstance()->LogStandardException(mode, __FUNCTIONW__, e);
if (!TryRecoverFromNavigationModeFailure()) if (!TryRecoverFromNavigationModeFailure())
{ {
// Could not navigate to standard mode either. // Could not navigate to standard mode either.
@ -96,7 +96,7 @@ void ApplicationViewModel::Initialize(ViewMode mode)
} }
catch (Exception ^ e) catch (Exception ^ e)
{ {
TraceLogger::GetInstance().LogPlatformException(mode, __FUNCTIONW__, e); TraceLogger::GetInstance()->LogPlatformException(mode, __FUNCTIONW__, e);
if (!TryRecoverFromNavigationModeFailure()) if (!TryRecoverFromNavigationModeFailure())
{ {
// Could not navigate to standard mode either. // Could not navigate to standard mode either.
@ -160,7 +160,7 @@ void ApplicationViewModel::OnModeChanged()
} }
auto resProvider = AppResourceProvider::GetInstance(); auto resProvider = AppResourceProvider::GetInstance();
CategoryName = resProvider.GetResourceString(NavCategory::GetNameResourceKey(m_mode)); CategoryName = resProvider->GetResourceString(NavCategory::GetNameResourceKey(m_mode));
// Cast mode to an int in order to save it to app data. // Cast mode to an int in order to save it to app data.
// Save the changed mode, so that the new window launches in this mode. // Save the changed mode, so that the new window launches in this mode.
@ -170,11 +170,11 @@ void ApplicationViewModel::OnModeChanged()
// Log ModeChange event when not first launch, log WindowCreated on first launch // Log ModeChange event when not first launch, log WindowCreated on first launch
if (NavCategory::IsValidViewMode(m_PreviousMode)) if (NavCategory::IsValidViewMode(m_PreviousMode))
{ {
TraceLogger::GetInstance().LogModeChange(m_mode); TraceLogger::GetInstance()->LogModeChange(m_mode);
} }
else else
{ {
TraceLogger::GetInstance().LogWindowCreated(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread())); TraceLogger::GetInstance()->LogWindowCreated(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
} }
RaisePropertyChanged(ClearMemoryVisibilityPropertyName); RaisePropertyChanged(ClearMemoryVisibilityPropertyName);

View File

@ -315,12 +315,8 @@
<ClInclude Include="ApplicationViewModel.h" /> <ClInclude Include="ApplicationViewModel.h" />
<ClInclude Include="Common\AlwaysSelectedCollectionView.h" /> <ClInclude Include="Common\AlwaysSelectedCollectionView.h" />
<ClInclude Include="Common\AppResourceProvider.h" /> <ClInclude Include="Common\AppResourceProvider.h" />
<ClInclude Include="Common\Automation\INarratorAnnouncementHost.h" />
<ClInclude Include="Common\Automation\LiveRegionHost.h" />
<ClInclude Include="Common\Automation\NarratorAnnouncement.h" /> <ClInclude Include="Common\Automation\NarratorAnnouncement.h" />
<ClInclude Include="Common\Automation\NarratorAnnouncementHostFactory.h" />
<ClInclude Include="Common\Automation\NarratorNotifier.h" /> <ClInclude Include="Common\Automation\NarratorNotifier.h" />
<ClInclude Include="Common\Automation\NotificationHost.h" />
<ClInclude Include="Common\BindableBase.h" /> <ClInclude Include="Common\BindableBase.h" />
<ClInclude Include="Common\BitLength.h" /> <ClInclude Include="Common\BitLength.h" />
<ClInclude Include="Common\CalculatorButtonPressedEventArgs.h" /> <ClInclude Include="Common\CalculatorButtonPressedEventArgs.h" />
@ -341,6 +337,7 @@
<ClInclude Include="Common\MyVirtualKey.h" /> <ClInclude Include="Common\MyVirtualKey.h" />
<ClInclude Include="Common\NavCategory.h" /> <ClInclude Include="Common\NavCategory.h" />
<ClInclude Include="Common\NetworkManager.h" /> <ClInclude Include="Common\NetworkManager.h" />
<ClInclude Include="Common\NumberBase.h" />
<ClInclude Include="Common\TraceActivity.h" /> <ClInclude Include="Common\TraceActivity.h" />
<ClInclude Include="Common\TraceLogger.h" /> <ClInclude Include="Common\TraceLogger.h" />
<ClInclude Include="Common\Utils.h" /> <ClInclude Include="Common\Utils.h" />
@ -361,16 +358,12 @@
<ClInclude Include="StandardCalculatorViewModel.h" /> <ClInclude Include="StandardCalculatorViewModel.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
<ClInclude Include="UnitConverterViewModel.h" /> <ClInclude Include="UnitConverterViewModel.h" />
<ClInclude Include="ViewState.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="ApplicationViewModel.cpp" /> <ClCompile Include="ApplicationViewModel.cpp" />
<ClCompile Include="Common\AppResourceProvider.cpp" /> <ClCompile Include="Common\AppResourceProvider.cpp" />
<ClCompile Include="Common\Automation\LiveRegionHost.cpp" />
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp" /> <ClCompile Include="Common\Automation\NarratorAnnouncement.cpp" />
<ClCompile Include="Common\Automation\NarratorAnnouncementHostFactory.cpp" />
<ClCompile Include="Common\Automation\NarratorNotifier.cpp" /> <ClCompile Include="Common\Automation\NarratorNotifier.cpp" />
<ClCompile Include="Common\Automation\NotificationHost.cpp" />
<ClCompile Include="Common\BindableBase.cpp" /> <ClCompile Include="Common\BindableBase.cpp" />
<ClCompile Include="Common\CalculatorButtonPressedEventArgs.cpp" /> <ClCompile Include="Common\CalculatorButtonPressedEventArgs.cpp" />
<ClCompile Include="Common\CalculatorDisplay.cpp" /> <ClCompile Include="Common\CalculatorDisplay.cpp" />
@ -407,7 +400,6 @@
</ClCompile> </ClCompile>
<ClCompile Include="StandardCalculatorViewModel.cpp" /> <ClCompile Include="StandardCalculatorViewModel.cpp" />
<ClCompile Include="UnitConverterViewModel.cpp" /> <ClCompile Include="UnitConverterViewModel.cpp" />
<ClCompile Include="ViewState.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\CalcManager\CalcManager.vcxproj"> <ProjectReference Include="..\CalcManager\CalcManager.vcxproj">
@ -440,12 +432,12 @@
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets')" /> <Import Project="..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets')" />
</ImportGroup> </ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup> <PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see https://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets'))" /> <Error Condition="!Exists('..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets'))" />
</Target> </Target>
</Project> </Project>

View File

@ -1,15 +1,28 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<Filter Include="Common">
<UniqueIdentifier>{1daab7c4-63f6-4266-a259-f34acad66d09}</UniqueIdentifier>
</Filter>
<Filter Include="Common\Automation">
<UniqueIdentifier>{8d4edf06-c312-4312-978a-b6c2beb8295a}</UniqueIdentifier>
</Filter>
<Filter Include="DataLoaders">
<UniqueIdentifier>{0184f727-b8aa-4af8-a699-63f1b56e7853}</UniqueIdentifier>
</Filter>
<Filter Include="GraphingCalculator">
<UniqueIdentifier>{cf7dca32-9727-4f98-83c3-1c0ca7dd1e0c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="ApplicationViewModel.cpp" /> <ClCompile Include="ApplicationViewModel.cpp" />
<ClCompile Include="DateCalculatorViewModel.cpp" /> <ClCompile Include="DateCalculatorViewModel.cpp" />
<ClCompile Include="HistoryItemViewModel.cpp" /> <ClCompile Include="HistoryItemViewModel.cpp" />
<ClCompile Include="HistoryViewModel.cpp" /> <ClCompile Include="HistoryViewModel.cpp" />
<ClCompile Include="MemoryItemViewModel.cpp" /> <ClCompile Include="MemoryItemViewModel.cpp" />
<ClCompile Include="pch.cpp" />
<ClCompile Include="StandardCalculatorViewModel.cpp" /> <ClCompile Include="StandardCalculatorViewModel.cpp" />
<ClCompile Include="UnitConverterViewModel.cpp" /> <ClCompile Include="UnitConverterViewModel.cpp" />
<ClCompile Include="ViewState.cpp" />
<ClCompile Include="Common\AppResourceProvider.cpp"> <ClCompile Include="Common\AppResourceProvider.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
@ -58,63 +71,53 @@
<ClCompile Include="Common\Utils.cpp"> <ClCompile Include="Common\Utils.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp">
<Filter>Common\Automation</Filter>
</ClCompile>
<ClCompile Include="Common\Automation\NarratorAnnouncementHostFactory.cpp">
<Filter>Common\Automation</Filter>
</ClCompile>
<ClCompile Include="Common\Automation\NarratorNotifier.cpp"> <ClCompile Include="Common\Automation\NarratorNotifier.cpp">
<Filter>Common\Automation</Filter> <Filter>Common\Automation</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Common\Automation\NotificationHost.cpp"> <ClCompile Include="DataLoaders\CurrencyDataLoader.cpp">
<Filter>Common\Automation</Filter>
</ClCompile>
<ClCompile Include="Common\Automation\LiveRegionHost.cpp">
<Filter>Common\Automation</Filter>
</ClCompile>
<ClCompile Include="DataLoaders\UnitConverterDataLoader.cpp">
<Filter>DataLoaders</Filter> <Filter>DataLoaders</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DataLoaders\CurrencyHttpClient.cpp"> <ClCompile Include="DataLoaders\CurrencyHttpClient.cpp">
<Filter>DataLoaders</Filter> <Filter>DataLoaders</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GraphingCalculator\GraphingCalculatorViewModel.cpp"> <ClCompile Include="DataLoaders\UnitConverterDataLoader.cpp">
<Filter>GraphingCalculator</Filter> <Filter>DataLoaders</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GraphingCalculator\EquationViewModel.cpp"> <ClCompile Include="GraphingCalculator\EquationViewModel.cpp">
<Filter>GraphingCalculator</Filter> <Filter>GraphingCalculator</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DataLoaders\CurrencyDataLoader.cpp"> <ClCompile Include="GraphingCalculator\GraphingCalculatorViewModel.cpp">
<Filter>DataLoaders</Filter> <Filter>GraphingCalculator</Filter>
</ClCompile>
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp">
<Filter>Common\Automation</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="ApplicationViewModel.h" /> <ClInclude Include="ApplicationViewModel.h" />
<ClInclude Include="DateCalculatorViewModel.h" /> <ClInclude Include="DateCalculatorViewModel.h" />
<ClInclude Include="HistoryItemViewModel.h" /> <ClInclude Include="HistoryItemViewModel.h" />
<ClInclude Include="HistoryViewModel.h" /> <ClInclude Include="HistoryViewModel.h" />
<ClInclude Include="MemoryItemViewModel.h" /> <ClInclude Include="MemoryItemViewModel.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="StandardCalculatorViewModel.h" /> <ClInclude Include="StandardCalculatorViewModel.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="UnitConverterViewModel.h" /> <ClInclude Include="UnitConverterViewModel.h" />
<ClInclude Include="ViewState.h" /> <ClInclude Include="Common\AlwaysSelectedCollectionView.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\AppResourceProvider.h"> <ClInclude Include="Common\AppResourceProvider.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\BindableBase.h"> <ClInclude Include="Common\BindableBase.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\AlwaysSelectedCollectionView.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\BitLength.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\CalculatorButtonPressedEventArgs.h"> <ClInclude Include="Common\CalculatorButtonPressedEventArgs.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\CalculatorButtonUser.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\CalculatorDisplay.h"> <ClInclude Include="Common\CalculatorDisplay.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
@ -145,25 +148,22 @@
<ClInclude Include="Common\KeyboardShortcutManager.h"> <ClInclude Include="Common\KeyboardShortcutManager.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\LocalizationStringUtil.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\LocalizationService.h"> <ClInclude Include="Common\LocalizationService.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\LocalizationSettings.h"> <ClInclude Include="Common\LocalizationSettings.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\NavCategory.h"> <ClInclude Include="Common\LocalizationStringUtil.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\MyVirtualKey.h"> <ClInclude Include="Common\MyVirtualKey.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\NetworkManager.h"> <ClInclude Include="Common\NavCategory.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\TraceActivity.h"> <ClInclude Include="Common\NetworkManager.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\TraceLogger.h"> <ClInclude Include="Common\TraceLogger.h">
@ -175,26 +175,14 @@
<ClInclude Include="Common\ValidatingConverters.h"> <ClInclude Include="Common\ValidatingConverters.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\CalculatorButtonUser.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\Automation\NarratorAnnouncement.h">
<Filter>Common\Automation</Filter>
</ClInclude>
<ClInclude Include="Common\Automation\NarratorAnnouncementHostFactory.h">
<Filter>Common\Automation</Filter>
</ClInclude>
<ClInclude Include="Common\Automation\NarratorNotifier.h"> <ClInclude Include="Common\Automation\NarratorNotifier.h">
<Filter>Common\Automation</Filter> <Filter>Common\Automation</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\Automation\NotificationHost.h"> <ClInclude Include="DataLoaders\CurrencyDataLoader.h">
<Filter>Common\Automation</Filter> <Filter>DataLoaders</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\Automation\INarratorAnnouncementHost.h"> <ClInclude Include="DataLoaders\CurrencyHttpClient.h">
<Filter>Common\Automation</Filter> <Filter>DataLoaders</Filter>
</ClInclude>
<ClInclude Include="Common\Automation\LiveRegionHost.h">
<Filter>Common\Automation</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DataLoaders\ICurrencyHttpClient.h"> <ClInclude Include="DataLoaders\ICurrencyHttpClient.h">
<Filter>DataLoaders</Filter> <Filter>DataLoaders</Filter>
@ -205,43 +193,38 @@
<ClInclude Include="DataLoaders\UnitConverterDataLoader.h"> <ClInclude Include="DataLoaders\UnitConverterDataLoader.h">
<Filter>DataLoaders</Filter> <Filter>DataLoaders</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\TraceActivity.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="DataLoaders\DataLoaderMockConstants.h"> <ClInclude Include="DataLoaders\DataLoaderMockConstants.h">
<Filter>DataLoaders</Filter> <Filter>DataLoaders</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DataLoaders\CurrencyHttpClient.h"> <ClInclude Include="Common\Automation\NarratorAnnouncement.h">
<Filter>DataLoaders</Filter> <Filter>Common\Automation</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h"> <ClInclude Include="Common\BitLength.h">
<Filter>GraphingCalculator</Filter> <Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\NumberBase.h">
<Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GraphingCalculator\EquationViewModel.h"> <ClInclude Include="GraphingCalculator\EquationViewModel.h">
<Filter>GraphingCalculator</Filter> <Filter>GraphingCalculator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DataLoaders\CurrencyDataLoader.h"> <ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h">
<Filter>DataLoaders</Filter> <Filter>GraphingCalculator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GraphingCalculatorEnums.h"> <ClInclude Include="GraphingCalculatorEnums.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" />
<None Include="DataLoaders\DefaultFromToCurrency.json"> <None Include="DataLoaders\DefaultFromToCurrency.json">
<Filter>DataLoaders</Filter> <Filter>DataLoaders</Filter>
</None> </None>
<None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="Common\Automation"> <Page Include="$(MSBuildThisFileDirectory)DensityStyles\Compact.xaml" />
<UniqueIdentifier>{98717b14-c8c7-4fb6-9861-abb9124b34f0}</UniqueIdentifier>
</Filter>
<Filter Include="GraphingCalculator">
<UniqueIdentifier>{07311281-a1fd-4dd9-baef-007f159e33ed}</UniqueIdentifier>
</Filter>
<Filter Include="Common">
<UniqueIdentifier>{14ddcbc1-10a4-4940-ad53-3a751b9ebea0}</UniqueIdentifier>
</Filter>
<Filter Include="DataLoaders">
<UniqueIdentifier>{b017a5e6-6d25-4799-a517-99f88d65b82f}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

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.
#include "pch.h" #include "pch.h"
@ -14,9 +14,9 @@ AppResourceProvider::AppResourceProvider()
m_cEngineStringResLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings"); m_cEngineStringResLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
} }
AppResourceProvider& AppResourceProvider::GetInstance() AppResourceProvider ^ AppResourceProvider::GetInstance()
{ {
static AppResourceProvider s_instance; static AppResourceProvider ^ s_instance = ref new AppResourceProvider();
return s_instance; return s_instance;
} }

View File

@ -1,14 +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
namespace CalculatorApp namespace CalculatorApp
{ {
class AppResourceProvider public ref class AppResourceProvider sealed
{ {
public: public:
static AppResourceProvider& GetInstance(); static AppResourceProvider ^ GetInstance();
Platform::String ^ GetResourceString(_In_ Platform::String ^ key); Platform::String ^ GetResourceString(_In_ Platform::String ^ key);
Platform::String ^ GetCEngineString(_In_ Platform::String ^ key); Platform::String ^ GetCEngineString(_In_ Platform::String ^ key);

View File

@ -6,6 +6,7 @@
using namespace CalculatorApp::Common::Automation; using namespace CalculatorApp::Common::Automation;
using namespace Platform; using namespace Platform;
using namespace Windows::UI::Xaml::Automation::Peers;
namespace CalculatorApp::Common::Automation namespace CalculatorApp::Common::Automation
{ {

View File

@ -5,32 +5,6 @@
namespace CalculatorApp::Common::Automation namespace CalculatorApp::Common::Automation
{ {
// These enum types are copied from the types available in
// Windows::UI::Xaml::Automation::Peers in the RS3 SDK.
// When this app switches to min version RS3, these custom
// enums should be removed and the Windows types should be used
// instead.
// TODO - MSFT 12735088
public
enum class AutomationNotificationKind
{
ItemAdded = 0,
ItemRemoved = 1,
ActionCompleted = 2,
ActionAborted = 3,
Other = 4
};
public
enum class AutomationNotificationProcessing
{
ImportantAll = 0,
ImportantMostRecent = 1,
All = 2,
MostRecent = 3,
CurrentThenMostRecent = 4
};
public public
ref class NarratorAnnouncement sealed ref class NarratorAnnouncement sealed
{ {
@ -41,14 +15,14 @@ public
property Platform::String property Platform::String
^ ActivityId { Platform::String ^ get(); } ^ ActivityId { Platform::String ^ get(); }
property AutomationNotificationKind Kind property Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind Kind
{ {
AutomationNotificationKind get(); Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind get();
} }
property AutomationNotificationProcessing Processing property Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing Processing
{ {
AutomationNotificationProcessing get(); Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing get();
} }
static bool IsValid(NarratorAnnouncement ^ announcement); static bool IsValid(NarratorAnnouncement ^ announcement);
@ -61,13 +35,13 @@ public
NarratorAnnouncement( NarratorAnnouncement(
Platform::String ^ announcement, Platform::String ^ announcement,
Platform::String ^ activityId, Platform::String ^ activityId,
AutomationNotificationKind kind, Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind kind,
AutomationNotificationProcessing processing); Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing processing);
Platform::String ^ m_announcement; Platform::String ^ m_announcement;
Platform::String ^ m_activityId; Platform::String ^ m_activityId;
AutomationNotificationKind m_kind; Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind m_kind;
AutomationNotificationProcessing m_processing; Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing m_processing;
}; };
// CalculatorAnnouncement is intended to contain only static methods // CalculatorAnnouncement is intended to contain only static methods

View File

@ -5,7 +5,6 @@
#include "pch.h" #include "pch.h"
#include "NarratorNotifier.h" #include "NarratorNotifier.h"
#include "NarratorAnnouncementHostFactory.h"
using namespace CalculatorApp::Common::Automation; using namespace CalculatorApp::Common::Automation;
using namespace Platform; using namespace Platform;
@ -17,14 +16,22 @@ DependencyProperty ^ NarratorNotifier::s_announcementProperty;
NarratorNotifier::NarratorNotifier() NarratorNotifier::NarratorNotifier()
{ {
m_announcementHost = NarratorAnnouncementHostFactory::MakeHost();
} }
void NarratorNotifier::Announce(NarratorAnnouncement ^ announcement) void NarratorNotifier::Announce(NarratorAnnouncement ^ announcement)
{ {
if (NarratorAnnouncement::IsValid(announcement) && m_announcementHost != nullptr) if (NarratorAnnouncement::IsValid(announcement))
{ {
m_announcementHost->Announce(announcement); if (m_announcementElement == nullptr)
{
m_announcementElement = ref new Windows::UI::Xaml::Controls::TextBlock();
}
auto peer = FrameworkElementAutomationPeer::FromElement(m_announcementElement);
if (peer != nullptr)
{
peer->RaiseNotificationEvent(announcement->Kind, announcement->Processing, announcement->Announcement, announcement->ActivityId);
}
} }
} }

View File

@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// Declaration of the NarratorNotifier class. // Declaration of the NarratorNotifier class.
#pragma once #pragma once
#include "INarratorAnnouncementHost.h" #include "NarratorAnnouncement.h"
namespace CalculatorApp::Common::Automation namespace CalculatorApp::Common::Automation
{ {
@ -47,6 +47,6 @@ public
static Windows::UI::Xaml::DependencyProperty ^ s_announcementProperty; static Windows::UI::Xaml::DependencyProperty ^ s_announcementProperty;
private: private:
INarratorAnnouncementHost ^ m_announcementHost; Windows::UI::Xaml::UIElement ^ m_announcementElement;
}; };
} }

View File

@ -63,6 +63,10 @@ public
IsStandardMode = (int)CM::Command::ModeBasic, IsStandardMode = (int)CM::Command::ModeBasic,
None = (int)CM::Command::CommandNULL, None = (int)CM::Command::CommandNULL,
IsProgrammerMode = (int)CM::Command::ModeProgrammer, IsProgrammerMode = (int)CM::Command::ModeProgrammer,
DecButton = (int)CM::Command::CommandDec,
OctButton = (int)CM::Command::CommandOct,
HexButton = (int)CM::Command::CommandHex,
BinButton = (int)CM::Command::CommandBin,
And = (int)CM::Command::CommandAnd, And = (int)CM::Command::CommandAnd,
Ror = (int)CM::Command::CommandROR, Ror = (int)CM::Command::CommandROR,
Rol = (int)CM::Command::CommandROL, Rol = (int)CM::Command::CommandROL,
@ -84,17 +88,38 @@ public
InvSinh = (int)CM::Command::CommandASINH, InvSinh = (int)CM::Command::CommandASINH,
InvCosh = (int)CM::Command::CommandACOSH, InvCosh = (int)CM::Command::CommandACOSH,
InvTanh = (int)CM::Command::CommandATANH, InvTanh = (int)CM::Command::CommandATANH,
Cube = (int) CM::Command::CommandCUB,
DMS = (int) CM::Command::CommandDMS,
Hyp = (int)CM::Command::CommandHYP,
HexButton = (int)CM::Command::CommandHex,
DecButton = (int)CM::Command::CommandDec,
OctButton = (int)CM::Command::CommandOct,
BinButton = (int)CM::Command::CommandBin,
Qword = (int)CM::Command::CommandQword, Qword = (int)CM::Command::CommandQword,
Dword = (int)CM::Command::CommandDword, Dword = (int)CM::Command::CommandDword,
Word = (int)CM::Command::CommandWord, Word = (int)CM::Command::CommandWord,
Byte = (int)CM::Command::CommandByte, Byte = (int)CM::Command::CommandByte,
Cube = (int)CM::Command::CommandCUB,
DMS = (int)CM::Command::CommandDMS,
Hyp = (int) CM::Command::CommandHYP,
Sec = (int) CM::Command::CommandSEC,
Csc = (int) CM::Command::CommandCSC,
Cot = (int) CM::Command::CommandCOT,
InvSec = (int) CM::Command::CommandASEC,
InvCsc = (int) CM::Command::CommandACSC,
InvCot = (int) CM::Command::CommandACOT,
Sech = (int) CM::Command::CommandSECH,
Csch = (int) CM::Command::CommandCSCH,
Coth = (int) CM::Command::CommandCOTH,
InvSech = (int) CM::Command::CommandASECH,
InvCsch = (int) CM::Command::CommandACSCH,
InvCoth = (int) CM::Command::CommandACOTH,
CubeRoot = (int) CM::Command::CommandCUBEROOT,
TwoPowerX = (int) CM::Command::CommandPOW2,
LogBaseX = (int) CM::Command::CommandLogBaseX,
Nand = (int) CM::Command::CommandNand,
Nor = (int) CM::Command::CommandNor,
Abs = (int) CM::Command::CommandAbs,
Floor = (int) CM::Command::CommandFloor,
Ceil = (int) CM::Command::CommandCeil,
Rand = (int) CM::Command::CommandRand,
Euler = (int) CM::Command::CommandEuler,
RshL = (int)CM::Command::CommandRSHFL,
RolC = (int)CM::Command::CommandROLC,
RorC = (int)CM::Command::CommandRORC,
Plot, Plot,
X, X,

View File

@ -9,6 +9,7 @@
using namespace CalculatorApp; using namespace CalculatorApp;
using namespace CalculationManager; using namespace CalculationManager;
using namespace Platform;
using namespace std; using namespace std;
CalculatorDisplay::CalculatorDisplay() CalculatorDisplay::CalculatorDisplay()
@ -31,7 +32,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue
{ {
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>()) if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
{ {
calcVM->SetPrimaryDisplay(displayStringValue, isError); calcVM->SetPrimaryDisplay(StringReference(displayStringValue.c_str()), isError);
} }
} }
} }
@ -70,8 +71,8 @@ void CalculatorDisplay::SetIsInError(bool isError)
} }
void CalculatorDisplay::SetExpressionDisplay( void CalculatorDisplay::SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens, _Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) _Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands)
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
@ -136,3 +137,14 @@ void CalculatorDisplay::MemoryItemChanged(unsigned int indexOfMemory)
} }
} }
} }
void CalculatorDisplay::InputChanged()
{
if (m_callbackReference != nullptr)
{
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
{
calcVM->OnInputChanged();
}
}
}

View File

@ -19,8 +19,8 @@ namespace CalculatorApp
void SetPrimaryDisplay(_In_ const std::wstring& displayString, _In_ bool isError) override; void SetPrimaryDisplay(_In_ const std::wstring& displayString, _In_ bool isError) override;
void SetIsInError(bool isError) override; void SetIsInError(bool isError) override;
void SetExpressionDisplay( void SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens, _Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) override; _Inout_ std::shared_ptr<std::vector<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 SetParenthesisNumber(_In_ unsigned int parenthesisCount) override; void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
@ -28,6 +28,7 @@ namespace CalculatorApp
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;
void MemoryItemChanged(unsigned int indexOfMemory) override; void MemoryItemChanged(unsigned int indexOfMemory) override;
void InputChanged() override;
private: private:
Platform::WeakReference m_callbackReference; Platform::WeakReference m_callbackReference;

View File

@ -11,13 +11,18 @@ using namespace concurrency;
using namespace CalculatorApp; using namespace CalculatorApp;
using namespace CalculatorApp::Common; using namespace CalculatorApp::Common;
using namespace Platform; using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation; using namespace Windows::Foundation;
using namespace Windows::System; using namespace Windows::System;
using namespace Windows::ApplicationModel::DataTransfer; using namespace Windows::ApplicationModel::DataTransfer;
using namespace Windows::Foundation::Collections;
String ^ CopyPasteManager::supportedFormats[] = { StandardDataFormats::Text }; StringReference PasteErrorString(L"NoOp");
static constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" }; static const wstring c_validBasicCharacterSet = L"0123456789+-.e";
static const wstring c_validStandardCharacterSet = c_validBasicCharacterSet + L"*/";
static const wstring c_validScientificCharacterSet = c_validStandardCharacterSet + L"()^%";
static const wstring c_validProgrammerCharacterSet = c_validStandardCharacterSet + L"()%abcdfABCDEF";
// The below values can not be "constexpr"-ed, // The below values can not be "constexpr"-ed,
// as both wstring_view and wchar[] can not be concatenated // as both wstring_view and wchar[] can not be concatenated
@ -26,7 +31,8 @@ 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;
static const wstring c_wspcLParenSigned = c_wspc + L"([-+]?[(])*" + c_wspc; static const wstring c_wspcLParenSigned = c_wspc + L"([-+]?[(])*" + c_wspc;
static const wstring c_wspcRParens = c_wspc + L"[)]*" + c_wspc; static const wstring c_wspcRParens = c_wspc + L"[)]*" + c_wspc;
static const wstring c_signedDecFloat = L"[-+]?\\d*(\\d|[.])\\d*"; static const wstring c_signedDecFloat = L"(?:[-+]?(?:\\d+(\\.\\d*)?|\\.\\d+))";
static const wstring c_optionalENotation = L"(?:e[+-]?\\d+)?";
// Programmer Mode Integer patterns // Programmer Mode Integer patterns
// Support digit separators ` (WinDbg/MASM), ' (C++), and _ (C# and other languages) // Support digit separators ` (WinDbg/MASM), ' (C++), and _ (C# and other languages)
@ -37,11 +43,9 @@ static const wstring c_binProgrammerChars = L"[0-1]+((_|'|`)[0-1]+)*";
static const wstring c_uIntSuffixes = L"[uU]?[lL]{0,2}"; static const wstring c_uIntSuffixes = L"[uU]?[lL]{0,2}";
// RegEx Patterns used by various modes // RegEx Patterns used by various modes
static const array<wregex, 1> standardModePatterns = { wregex(c_wspc + c_signedDecFloat + c_wspc) }; static const array<wregex, 1> standardModePatterns = { wregex(c_wspc + c_signedDecFloat + c_optionalENotation + c_wspc) };
static const array<wregex, 2> scientificModePatterns = { static const array<wregex, 1> scientificModePatterns = { wregex(
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_wspcRParens), L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_optionalENotation + c_wspcRParens) };
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + L"e[+-]?\\d+" + c_wspcRParens)
};
static const array<array<wregex, 5>, 4> programmerModePatterns = { static const array<array<wregex, 5>, 4> programmerModePatterns = {
{ // Hex numbers like 5F, 4A0C, 0xa9, 0xFFull, 47CDh { // Hex numbers like 5F, 4A0C, 0xa9, 0xFFull, 47CDh
{ wregex(c_wspcLParens + L"(0[xX])?" + c_hexProgrammerChars + c_uIntSuffixes + c_wspcRParens), { wregex(c_wspcLParens + L"(0[xX])?" + c_hexProgrammerChars + c_uIntSuffixes + c_wspcRParens),
@ -55,7 +59,7 @@ static const array<array<wregex, 5>, 4> programmerModePatterns = {
{ wregex(c_wspcLParens + L"(0[byBY])?" + c_binProgrammerChars + c_uIntSuffixes + c_wspcRParens), { wregex(c_wspcLParens + L"(0[byBY])?" + c_binProgrammerChars + c_uIntSuffixes + c_wspcRParens),
wregex(c_wspcLParens + c_binProgrammerChars + L"[bB]?" + c_wspcRParens) } } wregex(c_wspcLParens + c_binProgrammerChars + L"[bB]?" + c_wspcRParens) } }
}; };
static const array<wregex, 1> unitConverterPatterns = { wregex(c_wspc + L"[-+]?\\d*[.]?\\d*" + c_wspc) }; static const array<wregex, 1> unitConverterPatterns = { wregex(c_wspc + c_signedDecFloat + c_wspc) };
void CopyPasteManager::CopyToClipboard(String ^ stringToCopy) void CopyPasteManager::CopyToClipboard(String ^ stringToCopy)
{ {
@ -65,7 +69,7 @@ void CopyPasteManager::CopyToClipboard(String ^ stringToCopy)
Clipboard::SetContent(dataPackage); Clipboard::SetContent(dataPackage);
} }
task<String ^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType) IAsyncOperation<String ^> ^ CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupType modeType, NumberBase programmerNumberBase, BitLength bitLengthType)
{ {
// Retrieve the text in the clipboard // Retrieve the text in the clipboard
auto dataPackageView = Clipboard::GetContent(); auto dataPackageView = Clipboard::GetContent();
@ -75,51 +79,47 @@ task<String ^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupTy
//-- add support to allow pasting for expressions like .2 , -.2 //-- add support to allow pasting for expressions like .2 , -.2
//-- add support to allow pasting for expressions like 1.3e12(as of now we allow 1.3e+12) //-- add support to allow pasting for expressions like 1.3e12(as of now we allow 1.3e+12)
return create_task((dataPackageView->GetTextAsync(::StandardDataFormats::Text))) return create_async([dataPackageView, mode, modeType, programmerNumberBase, bitLengthType] {
.then( return create_task(dataPackageView->GetTextAsync(::StandardDataFormats::Text))
[mode, modeType, programmerNumberBase, bitLengthType](String ^ pastedText) { .then(
return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType); [mode, modeType, programmerNumberBase, bitLengthType](String ^ pastedText) {
}, return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType);
task_continuation_context::use_arbitrary()); },
task_continuation_context::use_arbitrary());
});
} }
int CopyPasteManager::ClipboardTextFormat() bool CopyPasteManager::HasStringToPaste()
{ {
const auto dataPackageView = Clipboard::GetContent(); return Clipboard::GetContent()->Contains(StandardDataFormats::Text);
for (int i = 0; i < RTL_NUMBER_OF(supportedFormats); i++)
{
if (dataPackageView->Contains(supportedFormats[i]))
{
return i;
}
}
return -1;
} }
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, int programmerNumberBase, BitLength bitLengthType) String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, NumberBase programmerNumberBase, BitLength bitLengthType)
{ {
return CopyPasteManager::ValidatePasteExpression(pastedText, mode, NavCategory::GetGroupType(mode), programmerNumberBase, bitLengthType); return ValidatePasteExpression(pastedText, mode, NavCategory::GetGroupType(mode), programmerNumberBase, bitLengthType);
} }
// return "NoOp" if pastedText is invalid else return pastedText // return "NoOp" if pastedText is invalid else return pastedText
String
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType) ^ CopyPasteManager::ValidatePasteExpression(
String ^ pastedText,
ViewMode mode,
CategoryGroupType modeType,
NumberBase programmerNumberBase,
BitLength bitLengthType)
{ {
if (pastedText->Length() > MaxPasteableLength) if (pastedText->Length() > MaxPasteableLength)
{ {
// return NoOp to indicate don't paste anything. // return NoOp to indicate don't paste anything.
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"PastedExpressionSizeGreaterThanMaxAllowed"); TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"PastedExpressionSizeGreaterThanMaxAllowed");
return StringReference(PasteErrorString); return PasteErrorString;
} }
wstring pasteExpression = pastedText->Data();
// Get english translated expression // Get english translated expression
String ^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression); String ^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pastedText);
// Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333 // Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333
pasteExpression = RemoveUnwantedCharsFromWstring(englishString->Data()); auto pasteExpression = wstring(RemoveUnwantedCharsFromString(englishString)->Data());
// If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste. // If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste.
if (!pasteExpression.empty() && pasteExpression.back() == L'=') if (!pasteExpression.empty() && pasteExpression.back() == L'=')
@ -129,31 +129,32 @@ String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode
// Extract operands from the expression to make regex comparison easy and quick. For whole expression it was taking too much of time. // Extract operands from the expression to make regex comparison easy and quick. For whole expression it was taking too much of time.
// Operands vector will have the list of operands in the pasteExpression // Operands vector will have the list of operands in the pasteExpression
vector<wstring> operands = ExtractOperands(pasteExpression, mode); auto operands = ExtractOperands(StringReference(pasteExpression.c_str()), mode);
if (operands.empty()) if (operands->Size == 0)
{ {
// return NoOp to indicate don't paste anything. // return NoOp to indicate don't paste anything.
return StringReference(PasteErrorString); return PasteErrorString;
} }
if (modeType == CategoryGroupType::Converter) if (modeType == CategoryGroupType::Converter)
{ {
operands = { pasteExpression }; operands->Clear();
operands->Append(ref new String(pasteExpression.c_str()));
} }
// validate each operand with patterns for different modes // validate each operand with patterns for different modes
if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType)) if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType))
{ {
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"InvalidExpressionForPresentMode"); TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"InvalidExpressionForPresentMode");
return StringReference(PasteErrorString); return PasteErrorString;
} }
return ref new String(pastedText->Data()); return pastedText;
} }
vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression, ViewMode mode) IVector<Platform::String ^> ^ CopyPasteManager::ExtractOperands(Platform::String ^ pasteExpression, ViewMode mode)
{ {
vector<wstring> operands{}; auto operands = ref new Vector<Platform::String ^>();
size_t lastIndex = 0; size_t lastIndex = 0;
bool haveOperator = false; bool haveOperator = false;
bool startExpCounting = false; bool startExpCounting = false;
@ -161,51 +162,72 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
bool isPreviousOpenParen = false; bool isPreviousOpenParen = false;
bool isPreviousOperator = false; bool isPreviousOperator = false;
wstring validCharacterSet;
switch (mode)
{
case ViewMode::Standard:
validCharacterSet = c_validStandardCharacterSet;
break;
case ViewMode::Scientific:
validCharacterSet = c_validScientificCharacterSet;
break;
case ViewMode::Programmer:
validCharacterSet = c_validProgrammerCharacterSet;
break;
default:
validCharacterSet = c_validBasicCharacterSet;
}
// This will have the exponent length // This will have the exponent length
size_t expLength = 0; size_t expLength = 0;
for (size_t i = 0; i < pasteExpression.length(); i++) int i = -1;
for (auto currentChar : pasteExpression)
{ {
++i;
// if the current character is not a valid one don't process it // if the current character is not a valid one don't process it
if (c_validCharacterSet.find(pasteExpression.at(i)) == wstring_view::npos) if (validCharacterSet.find(currentChar) == wstring_view::npos)
{ {
continue; continue;
} }
if (operands.size() >= MaxOperandCount) if (operands->Size >= MaxOperandCount)
{ {
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ExtractOperands", L"OperandCountGreaterThanMaxCount"); TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ExtractOperands", L"OperandCountGreaterThanMaxCount");
operands.clear(); operands->Clear();
return operands; return operands;
} }
if (startExpCounting) if (currentChar >= L'0' && currentChar <= L'9')
{ {
if ((pasteExpression.at(i) >= L'0') && (pasteExpression.at(i) <= L'9')) if (startExpCounting)
{ {
expLength++; expLength++;
// to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999. // to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999.
if (expLength > MaxExponentLength) if (expLength > MaxExponentLength)
{ {
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ExtractOperands", L"ExponentLengthGreaterThanMaxLength"); TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ExtractOperands", L"ExponentLengthGreaterThanMaxLength");
operands.clear(); operands->Clear();
return operands; return operands;
} }
} }
isPreviousOperator = false;
} }
else if (currentChar == L'e')
if ((mode != ViewMode::Programmer) && (pasteExpression.at(i) == L'e'))
{ {
startExpCounting = true; if (mode != ViewMode::Programmer)
{
startExpCounting = true;
}
isPreviousOperator = false;
} }
else if (currentChar == L'+' || currentChar == L'-' || currentChar == L'*' || currentChar == L'/' || currentChar == L'^' || currentChar == L'%')
if (((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-') || (pasteExpression.at(i) == L'*') || (pasteExpression.at(i) == L'/')))
{ {
if ((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-')) if (currentChar == L'+' || currentChar == L'-')
{ {
// don't break the expression into operands if the encountered character corresponds to sign command(+-) // don't break the expression into operands if the encountered character corresponds to sign command(+-)
if (isPreviousOpenParen || startOfExpression || isPreviousOperator if (isPreviousOpenParen || startOfExpression || isPreviousOperator
|| ((mode != ViewMode::Programmer) && !((i != 0) && (pasteExpression.at(i - 1) != L'e')))) || ((mode != ViewMode::Programmer) && !((i != 0) && pasteExpression->Data()[i - 1] != L'e')))
{ {
isPreviousOperator = false; isPreviousOperator = false;
continue; continue;
@ -216,7 +238,7 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
expLength = 0; expLength = 0;
haveOperator = true; haveOperator = true;
isPreviousOperator = true; isPreviousOperator = true;
operands.push_back(pasteExpression.substr(lastIndex, i - lastIndex)); operands->Append(ref new String(wstring(pasteExpression->Data()).substr(lastIndex, i - lastIndex).c_str()));
lastIndex = i + 1; lastIndex = i + 1;
} }
else else
@ -224,26 +246,31 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
isPreviousOperator = false; isPreviousOperator = false;
} }
isPreviousOpenParen = (pasteExpression.at(i) == L'('); isPreviousOpenParen = (currentChar == L'(');
startOfExpression = false; startOfExpression = false;
} }
if (!haveOperator) if (!haveOperator)
{ {
operands.clear(); operands->Clear();
operands.push_back(pasteExpression); operands->Append(pasteExpression);
} }
else else
{ {
operands.push_back(pasteExpression.substr(lastIndex, pasteExpression.length() - 1)); operands->Append(ref new String(wstring(pasteExpression->Data()).substr(lastIndex, pasteExpression->Length() - 1).c_str()));
} }
return operands; return operands;
} }
bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType) bool CopyPasteManager::ExpressionRegExMatch(
IVector<String ^> ^ operands,
ViewMode mode,
CategoryGroupType modeType,
NumberBase programmerNumberBase,
BitLength bitLengthType)
{ {
if (operands.empty()) if (operands->Size == 0)
{ {
return false; return false;
} }
@ -260,14 +287,16 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
} }
else if (mode == ViewMode::Programmer) else if (mode == ViewMode::Programmer)
{ {
patterns.assign(programmerModePatterns[programmerNumberBase - HexBase].begin(), programmerModePatterns[programmerNumberBase - HexBase].end()); patterns.assign(
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].begin(),
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].end());
} }
else if (modeType == CategoryGroupType::Converter) else if (modeType == CategoryGroupType::Converter)
{ {
patterns.assign(unitConverterPatterns.begin(), unitConverterPatterns.end()); patterns.assign(unitConverterPatterns.begin(), unitConverterPatterns.end());
} }
const auto [maxOperandLength, maxOperandValue] = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType); auto maxOperandLengthAndValue = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType);
bool expMatched = true; bool expMatched = true;
for (const auto& operand : operands) for (const auto& operand : operands)
@ -276,34 +305,34 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
bool operandMatched = false; bool operandMatched = false;
for (const auto& pattern : patterns) for (const auto& pattern : patterns)
{ {
operandMatched = operandMatched || regex_match(operand, pattern); operandMatched = operandMatched || regex_match(operand->Data(), pattern);
} }
if (operandMatched) if (operandMatched)
{ {
// 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.
const wstring operandValue = SanitizeOperand(operand); auto 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) > maxOperandLengthAndValue.maxLength)
{ {
expMatched = false; expMatched = false;
break; break;
} }
// If maxOperandValue is set and the operandValue exceeds it, break and return. // If maxOperandValue is set and the operandValue exceeds it, break and return.
if (maxOperandValue != 0) if (maxOperandLengthAndValue.maxValue != 0)
{ {
unsigned long long int operandAsULL = 0; auto operandAsULL = TryOperandToULL(operandValue, programmerNumberBase);
if (!TryOperandToULL(operandValue, programmerNumberBase, operandAsULL)) if (operandAsULL == nullptr)
{ {
// Operand was empty, received invalid_argument, or received out_of_range. Input is invalid. // Operand was empty, received invalid_argument, or received out_of_range. Input is invalid.
expMatched = false; expMatched = false;
break; break;
} }
if (operandAsULL > maxOperandValue) if (operandAsULL->Value > maxOperandLengthAndValue.maxValue)
{ {
expMatched = false; expMatched = false;
break; break;
@ -317,18 +346,23 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
return expMatched; return expMatched;
} }
pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType) CopyPasteMaxOperandLengthAndValue
CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, NumberBase programmerNumberBase, BitLength bitLengthType)
{ {
constexpr size_t defaultMaxOperandLength = 0; constexpr size_t defaultMaxOperandLength = 0;
constexpr uint64_t defaultMaxValue = 0; constexpr uint64_t defaultMaxValue = 0;
CopyPasteMaxOperandLengthAndValue res;
if (mode == ViewMode::Standard) if (mode == ViewMode::Standard)
{ {
return make_pair(MaxStandardOperandLength, defaultMaxValue); res.maxLength = MaxStandardOperandLength;
res.maxValue = defaultMaxValue;
return res;
} }
else if (mode == ViewMode::Scientific) else if (mode == ViewMode::Scientific)
{ {
return make_pair(MaxScientificOperandLength, defaultMaxValue); res.maxLength = MaxScientificOperandLength;
res.maxValue = defaultMaxValue;
return res;
} }
else if (mode == ViewMode::Programmer) else if (mode == ViewMode::Programmer)
{ {
@ -352,65 +386,69 @@ pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo
double bitsPerDigit = 0; double bitsPerDigit = 0;
switch (programmerNumberBase) switch (programmerNumberBase)
{ {
case BinBase: case NumberBase::BinBase:
bitsPerDigit = log2(2); bitsPerDigit = log2(2);
break; break;
case OctBase: case NumberBase::OctBase:
bitsPerDigit = log2(8); bitsPerDigit = log2(8);
break; break;
case DecBase: case NumberBase::DecBase:
bitsPerDigit = log2(10); bitsPerDigit = log2(10);
break; break;
case HexBase: case NumberBase::HexBase:
bitsPerDigit = log2(16); bitsPerDigit = log2(16);
break; break;
} }
unsigned int signBit = (programmerNumberBase == DecBase) ? 1 : 0; unsigned int signBit = (programmerNumberBase == NumberBase::DecBase) ? 1 : 0;
const auto maxLength = static_cast<size_t>(ceil((bitLength - signBit) / bitsPerDigit)); const auto maxLength = static_cast<unsigned int>(ceil((bitLength - signBit) / bitsPerDigit));
const uint64_t maxValue = UINT64_MAX >> (MaxProgrammerBitLength - (bitLength - signBit)); const uint64_t maxValue = UINT64_MAX >> (MaxProgrammerBitLength - (bitLength - signBit));
return make_pair(maxLength, maxValue); res.maxLength = maxLength;
res.maxValue = maxValue;
return res;
} }
else if (modeType == CategoryGroupType::Converter) else if (modeType == CategoryGroupType::Converter)
{ {
return make_pair(MaxConverterInputLength, defaultMaxValue); res.maxLength = MaxConverterInputLength;
res.maxValue = defaultMaxValue;
return res;
} }
return make_pair(defaultMaxOperandLength, defaultMaxValue); res.maxLength = defaultMaxOperandLength;
res.maxValue = defaultMaxValue;
return res;
} }
wstring CopyPasteManager::SanitizeOperand(const wstring& operand) Platform::String ^ CopyPasteManager::SanitizeOperand(Platform::String ^ operand)
{ {
wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-', L'+' }; constexpr wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-', L'+' };
return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, static_cast<int>(size(unWantedChars))); return ref new String(Utils::RemoveUnwantedCharsFromString(operand->Data(), unWantedChars).c_str());
} }
bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, unsigned long long int& result) IBox<unsigned long long int> ^ CopyPasteManager::TryOperandToULL(String ^ operand, NumberBase numberBase)
{ {
result = 0; if (operand->Length() == 0 || operand->Data()[0] == L'-')
if (operand.length() == 0 || operand.front() == L'-')
{ {
return false; return nullptr;
} }
int intBase; int intBase;
switch (numberBase) switch (numberBase)
{ {
case HexBase: case NumberBase::HexBase:
intBase = 16; intBase = 16;
break; break;
case OctBase: case NumberBase::OctBase:
intBase = 8; intBase = 8;
break; break;
case BinBase: case NumberBase::BinBase:
intBase = 2; intBase = 2;
break; break;
default: default:
case DecBase: case NumberBase::DecBase:
intBase = 10; intBase = 10;
break; break;
} }
@ -418,8 +456,7 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
wstring::size_type size = 0; wstring::size_type size = 0;
try try
{ {
result = stoull(operand, &size, intBase); return stoull(operand->Data(), &size, intBase);
return true;
} }
catch (const invalid_argument&) catch (const invalid_argument&)
{ {
@ -430,14 +467,14 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
// Do nothing // Do nothing
} }
return false; return nullptr;
} }
size_t CopyPasteManager::OperandLength(const wstring& operand, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase) ULONG32 CopyPasteManager::OperandLength(Platform::String ^ operand, ViewMode mode, CategoryGroupType modeType, NumberBase programmerNumberBase)
{ {
if (modeType == CategoryGroupType::Converter) if (modeType == CategoryGroupType::Converter)
{ {
return operand.length(); return operand->Length();
} }
switch (mode) switch (mode)
@ -454,45 +491,46 @@ size_t CopyPasteManager::OperandLength(const wstring& operand, ViewMode mode, Ca
} }
} }
size_t CopyPasteManager::StandardScientificOperandLength(const wstring& operand) ULONG32 CopyPasteManager::StandardScientificOperandLength(Platform::String ^ operand)
{ {
const bool hasDecimal = operand.find('.') != wstring::npos; auto operandWstring = wstring(operand->Data());
const bool hasDecimal = operandWstring.find('.') != wstring::npos;
if (hasDecimal) if (hasDecimal)
{ {
if (operand.length() >= 2) if (operandWstring.length() >= 2)
{ {
if ((operand[0] == L'0') && (operand[1] == L'.')) if ((operandWstring[0] == L'0') && (operandWstring[1] == L'.'))
{ {
return operand.length() - 2; return static_cast<ULONG32>(operandWstring.length() - 2);
} }
else else
{ {
return operand.length() - 1; return static_cast<ULONG32>(operandWstring.length() - 1);
} }
} }
} }
return operand.length(); return static_cast<ULONG32>(operandWstring.length());
} }
size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int numberBase) ULONG32 CopyPasteManager::ProgrammerOperandLength(Platform::String ^ operand, NumberBase numberBase)
{ {
vector<wstring> prefixes{}; vector<wstring> prefixes{};
vector<wstring> suffixes{}; vector<wstring> suffixes{};
switch (numberBase) switch (numberBase)
{ {
case BinBase: case NumberBase::BinBase:
prefixes = { L"0B", L"0Y" }; prefixes = { L"0B", L"0Y" };
suffixes = { L"B" }; suffixes = { L"B" };
break; break;
case DecBase: case NumberBase::DecBase:
prefixes = { L"-", L"0N" }; prefixes = { L"-", L"0N" };
break; break;
case OctBase: case NumberBase::OctBase:
prefixes = { L"0T", L"0O" }; prefixes = { L"0T", L"0O" };
break; break;
case HexBase: case NumberBase::HexBase:
prefixes = { L"0X" }; prefixes = { L"0X" };
suffixes = { L"H" }; suffixes = { L"H" };
break; break;
@ -505,10 +543,10 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
const array<wstring, 5> uintSuffixes = { L"ULL", L"UL", L"LL", L"U", L"L" }; const array<wstring, 5> uintSuffixes = { L"ULL", L"UL", L"LL", L"U", L"L" };
suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end()); suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end());
wstring operandUpper = operand; wstring operandUpper = wstring(operand->Data());
transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper); transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper);
size_t len = operand.length(); 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).
@ -541,7 +579,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
} }
} }
return len; return static_cast<ULONG32>(len);
} }
// return wstring after removing characters like space, comma, double quotes, and monetary prefix currency symbols supported by the Windows keyboard: // return wstring after removing characters like space, comma, double quotes, and monetary prefix currency symbols supported by the Windows keyboard:
@ -556,8 +594,13 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
// Indian rupee(₹) - 8377 // Indian rupee(₹) - 8377
// pound(£) - 163 // pound(£) - 163
// euro(€) - 8364 // euro(€) - 8364
wstring CopyPasteManager::RemoveUnwantedCharsFromWstring(const wstring& input) Platform::String ^ CopyPasteManager::RemoveUnwantedCharsFromString(Platform::String ^ input)
{ {
wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 }; constexpr wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 };
return Utils::RemoveUnwantedCharsFromWstring(input, unWantedChars, 18); return ref new String(Utils::RemoveUnwantedCharsFromString(input->Data(), unWantedChars).c_str());
}
bool CopyPasteManager::IsErrorMessage(Platform::String ^ message)
{
return message == PasteErrorString;
} }

View File

@ -6,6 +6,7 @@
#include "AppResourceProvider.h" #include "AppResourceProvider.h"
#include "NavCategory.h" #include "NavCategory.h"
#include "BitLength.h" #include "BitLength.h"
#include "NumberBase.h"
namespace CalculatorUnitTests namespace CalculatorUnitTests
{ {
@ -14,78 +15,119 @@ namespace CalculatorUnitTests
namespace CalculatorApp namespace CalculatorApp
{ {
inline constexpr auto HexBase = 5; public
inline constexpr auto DecBase = 6; value struct CopyPasteMaxOperandLengthAndValue
inline constexpr auto OctBase = 7; {
inline constexpr auto BinBase = 8; unsigned int maxLength;
unsigned long long maxValue;
};
class CopyPasteManager public ref class CopyPasteManager sealed
{ {
public: public:
static void CopyToClipboard(Platform::String ^ stringToCopy); static void CopyToClipboard(Platform::String ^ stringToCopy);
static concurrency::task<Platform::String ^> GetStringToPaste( static Windows::Foundation::IAsyncOperation<
CalculatorApp::Common::ViewMode mode, Platform::String
CalculatorApp::Common::CategoryGroupType modeType, ^> ^ GetStringToPaste(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, CalculatorApp::Common::NumberBase programmerNumberBase, CalculatorApp::Common::BitLength bitLengthType);
int programmerNumberBase = -1, static bool HasStringToPaste();
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown); static bool IsErrorMessage(Platform::String ^ message);
static bool HasStringToPaste() static property unsigned int MaxPasteableLength
{ {
return ClipboardTextFormat() >= 0; unsigned int get()
{
return MaxPasteableLengthValue;
}
}
static property unsigned int MaxOperandCount
{
unsigned int get()
{
return MaxOperandCountValue;
}
}
static property unsigned int MaxStandardOperandLength
{
unsigned int get()
{
return MaxStandardOperandLengthValue;
}
}
static property unsigned int MaxScientificOperandLength
{
unsigned int get()
{
return MaxScientificOperandLengthValue;
}
} }
static constexpr auto PasteErrorString = L"NoOp"; static property unsigned int MaxConverterInputLength
{
unsigned int get()
{
return MaxConverterInputLengthValue;
}
}
static property unsigned int MaxExponentLength
{
unsigned int get()
{
return MaxExponentLengthValue;
}
}
static property unsigned int MaxProgrammerBitLength
{
unsigned int get()
{
return MaxProgrammerBitLengthValue;
}
}
private:
static int ClipboardTextFormat();
static Platform::String static Platform::String
^ ValidatePasteExpression( ^ ValidatePasteExpression(
Platform::String ^ pastedText, Platform::String ^ pastedText,
CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::ViewMode mode,
int programmerNumberBase, CalculatorApp::Common::NumberBase programmerNumberBase,
CalculatorApp::Common::BitLength bitLengthType); CalculatorApp::Common::BitLength bitLengthType);
static Platform::String static Platform::String
^ ValidatePasteExpression( ^ ValidatePasteExpression(
Platform::String ^ pastedText, Platform::String ^ pastedText,
CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType, CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase, CalculatorApp::Common::NumberBase programmerNumberBase,
CalculatorApp::Common::BitLength bitLengthType); CalculatorApp::Common::BitLength bitLengthType);
static CopyPasteMaxOperandLengthAndValue GetMaxOperandLengthAndValue(
static std::vector<std::wstring> CalculatorApp::Common::ViewMode mode,
ExtractOperands(const std::wstring& pasteExpression, CalculatorApp::Common::ViewMode mode); CalculatorApp::Common::CategoryGroupType modeType,
CalculatorApp::Common::NumberBase programmerNumberBase,
CalculatorApp::Common::BitLength bitLengthType);
static Windows::Foundation::Collections::IVector<
Platform::String ^> ^ ExtractOperands(Platform::String ^ pasteExpression, CalculatorApp::Common::ViewMode mode);
static bool ExpressionRegExMatch( static bool ExpressionRegExMatch(
std::vector<std::wstring> operands, Windows::Foundation::Collections::IVector<Platform::String ^> ^ operands,
CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType, CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1, CalculatorApp::Common::NumberBase programmerNumberBase,
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown); CalculatorApp::Common::BitLength bitLengthType);
static Platform::String ^ SanitizeOperand(Platform::String ^ operand);
static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue( static Platform::String ^ RemoveUnwantedCharsFromString(Platform::String ^ input);
static Platform::IBox<unsigned long long int> ^ TryOperandToULL(Platform::String ^ operand, CalculatorApp::Common::NumberBase numberBase);
static ULONG32 StandardScientificOperandLength(Platform::String ^ operand);
static ULONG32 OperandLength(
Platform::String ^ operand,
CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType, CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1, CalculatorApp::Common::NumberBase programmerNumberBase);
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown); static ULONG32 ProgrammerOperandLength(Platform::String ^ operand, CalculatorApp::Common::NumberBase numberBase);
static std::wstring SanitizeOperand(const std::wstring& operand);
static bool TryOperandToULL(const std::wstring& operand, int numberBase, unsigned long long int& result);
static size_t OperandLength(
const std::wstring& operand,
CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1);
static size_t StandardScientificOperandLength(const std::wstring& operand);
static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase);
static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input);
static constexpr size_t MaxStandardOperandLength = 16; private:
static constexpr size_t MaxScientificOperandLength = 32; static constexpr size_t MaxStandardOperandLengthValue = 16;
static constexpr size_t MaxConverterInputLength = 16; static constexpr size_t MaxScientificOperandLengthValue = 32;
static constexpr size_t MaxOperandCount = 100; static constexpr size_t MaxConverterInputLengthValue = 16;
static constexpr size_t MaxPasteableLength = 512; static constexpr size_t MaxOperandCountValue = 100;
static constexpr size_t MaxExponentLength = 4; static constexpr size_t MaxExponentLengthValue = 4;
static constexpr size_t MaxProgrammerBitLength = 64; static constexpr size_t MaxProgrammerBitLengthValue = 64;
static constexpr size_t MaxPasteableLengthValue = 512;
static Platform::String ^ supportedFormats[];
friend class CalculatorUnitTests::CopyPasteManagerTest;
}; };
} }

View File

@ -9,6 +9,11 @@ using namespace Windows::Foundation;
using namespace Windows::Globalization; using namespace Windows::Globalization;
using namespace CalculatorApp::Common::DateCalculation; using namespace CalculatorApp::Common::DateCalculation;
bool operator==(const DateDifference& l, const DateDifference& r)
{
return l.year == r.year && l.month == r.month && l.week == r.week && l.day == r.day;
}
DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier) DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier)
{ {
m_calendar = ref new Calendar(); m_calendar = ref new Calendar();
@ -18,10 +23,9 @@ DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier)
// Adding Duration to a Date // Adding Duration to a 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::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate) IBox<DateTime> ^ DateCalculationEngine::AddDuration(DateTime startDate, DateDifference duration)
{ {
auto currentCalendarSystem = m_calendar->GetCalendarSystem(); auto currentCalendarSystem = m_calendar->GetCalendarSystem();
try try
{ {
m_calendar->SetDateTime(startDate); m_calendar->SetDateTime(startDate);
@ -50,7 +54,8 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
m_calendar->AddDays(duration.day); m_calendar->AddDays(duration.day);
} }
*endDate = m_calendar->GetDateTime(); m_calendar->ChangeCalendarSystem(currentCalendarSystem);
return m_calendar->GetDateTime();
} }
catch (Platform::InvalidArgumentException ^ ex) catch (Platform::InvalidArgumentException ^ ex)
{ {
@ -58,17 +63,13 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
m_calendar->ChangeCalendarSystem(currentCalendarSystem); m_calendar->ChangeCalendarSystem(currentCalendarSystem);
// Do nothing // Do nothing
return false; return nullptr;
} }
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
return true;
} }
// Subtracting Duration from a Date // Subtracting Duration from a 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) IBox<DateTime> ^ DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ DateDifference duration)
{ {
auto currentCalendarSystem = m_calendar->GetCalendarSystem(); auto currentCalendarSystem = m_calendar->GetCalendarSystem();
@ -101,7 +102,18 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
{ {
m_calendar->AddYears(-duration.year); m_calendar->AddYears(-duration.year);
} }
*endDate = m_calendar->GetDateTime(); m_calendar->ChangeCalendarSystem(currentCalendarSystem);
auto dateTime = m_calendar->GetDateTime();
// Check that the UniversalTime value is not negative
if (dateTime.UniversalTime >= 0)
{
return dateTime;
}
else
{
return nullptr;
}
} }
catch (Platform::InvalidArgumentException ^ ex) catch (Platform::InvalidArgumentException ^ ex)
{ {
@ -109,17 +121,12 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
m_calendar->ChangeCalendarSystem(currentCalendarSystem); m_calendar->ChangeCalendarSystem(currentCalendarSystem);
// Do nothing // Do nothing
return false; return nullptr;
} }
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
// Check that the UniversalTime value is not negative
return (endDate->UniversalTime >= 0);
} }
// Calculate the difference between two dates // Calculate the difference between two dates
bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference* difference) IBox<DateDifference> ^ DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat)
{ {
DateTime startDate; DateTime startDate;
DateTime endDate; DateTime endDate;
@ -177,8 +184,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
{ {
// Operation failed due to out of bound result // Operation failed due to out of bound result
// For example: 31st Dec, 9999 - last valid date // For example: 31st Dec, 9999 - last valid date
*difference = DateDifferenceUnknown; return nullptr;
return false;
} }
} }
@ -194,8 +200,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
if (differenceInDates[unitIndex] == 0) if (differenceInDates[unitIndex] == 0)
{ {
// differenceInDates[unitIndex] is unsigned, the value can't be negative // differenceInDates[unitIndex] is unsigned, the value can't be negative
*difference = DateDifferenceUnknown; return nullptr;
return false;
} }
differenceInDates[unitIndex] -= 1; differenceInDates[unitIndex] -= 1;
pivotDate = tempPivotDate; pivotDate = tempPivotDate;
@ -220,8 +225,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
{ {
// Operation failed due to out of bound result // Operation failed due to out of bound result
// For example: 31st Dec, 9999 - last valid date // For example: 31st Dec, 9999 - last valid date
*difference = DateDifferenceUnknown; return nullptr;
return false;
} }
} }
} while (tempDaysDiff != 0); // dates are the same - exit the loop } while (tempDaysDiff != 0); // dates are the same - exit the loop
@ -232,8 +236,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
if (signedDaysDiff < 0) if (signedDaysDiff < 0)
{ {
// daysDiff is unsigned, the value can't be negative // daysDiff is unsigned, the value can't be negative
*difference = DateDifferenceUnknown; return nullptr;
return false;
} }
daysDiff = signedDaysDiff; daysDiff = signedDaysDiff;
@ -244,11 +247,12 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
differenceInDates[3] = daysDiff; differenceInDates[3] = daysDiff;
difference->year = differenceInDates[0]; DateDifference result;
difference->month = differenceInDates[1]; result.year = differenceInDates[0];
difference->week = differenceInDates[2]; result.month = differenceInDates[1];
difference->day = differenceInDates[3]; result.week = differenceInDates[2];
return true; result.day = differenceInDates[3];
return result;
} }
// Private Methods // Private Methods

View File

@ -29,39 +29,30 @@ namespace CalculatorApp
}; };
// Struct to store the difference between two Dates in the form of Years, Months , Weeks // Struct to store the difference between two Dates in the form of Years, Months , Weeks
struct DateDifference public
value struct DateDifference
{ {
int year = 0; int year;
int month = 0; int month;
int week = 0; int week;
int day = 0; int day;
bool operator==(const DateDifference& dd) const
{
return year == dd.year && month == dd.month && week == dd.week && day == day;
}
}; };
const DateDifference DateDifferenceUnknown{ INT_MIN, INT_MIN, INT_MIN, INT_MIN }; const DateDifference DateDifferenceUnknown{ INT_MIN, INT_MIN, INT_MIN, INT_MIN };
class DateCalculationEngine public
ref class DateCalculationEngine sealed
{ {
public: public:
// Constructor // Constructor
DateCalculationEngine(_In_ Platform::String ^ calendarIdentifier); DateCalculationEngine(_In_ Platform::String ^ calendarIdentifier);
// Public Methods // Public Methods
bool __nothrow
AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime* endDate); Platform::IBox<Windows::Foundation::DateTime> ^ AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration);
bool __nothrow SubtractDuration( Platform::IBox<Windows::Foundation::DateTime> ^ SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration);
_In_ Windows::Foundation::DateTime startDate, Platform::IBox<
_In_ const DateDifference& duration, DateDifference> ^ TryGetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat);
_Out_ Windows::Foundation::DateTime* endDate);
bool __nothrow TryGetDateDifference(
_In_ Windows::Foundation::DateTime date1,
_In_ Windows::Foundation::DateTime date2,
_In_ DateUnit outputFormat,
_Out_ DateDifference* difference);
private: private:
// Private Variables // Private Variables
@ -76,3 +67,5 @@ namespace CalculatorApp
} }
} }
} }
bool operator==(const CalculatorApp::Common::DateCalculation::DateDifference& l, const CalculatorApp::Common::DateCalculation::DateDifference& r);

View File

@ -17,7 +17,7 @@ namespace CalculatorApp
m_resLoader = ResourceLoader::GetForViewIndependentUse("CEngineStrings"); m_resLoader = ResourceLoader::GetForViewIndependentUse("CEngineStrings");
} }
wstring EngineResourceProvider::GetCEngineString(const wstring& id) wstring EngineResourceProvider::GetCEngineString(wstring_view id)
{ {
const auto& localizationSettings = LocalizationSettings::GetInstance(); const auto& localizationSettings = LocalizationSettings::GetInstance();
@ -43,7 +43,7 @@ namespace CalculatorApp
return numberGroupingString; return numberGroupingString;
} }
StringReference idRef(id.c_str()); StringReference idRef(id.data(), id.length());
String ^ str = m_resLoader->GetString(idRef); String ^ str = m_resLoader->GetString(idRef);
return str->Begin(); return str->Begin();
} }

View File

@ -11,7 +11,7 @@ namespace CalculatorApp
{ {
public: public:
EngineResourceProvider(); EngineResourceProvider();
virtual std::wstring GetCEngineString(const std::wstring& id) override; virtual std::wstring GetCEngineString(std::wstring_view id) override;
private: private:
Windows::ApplicationModel::Resources::ResourceLoader ^ m_resLoader; Windows::ApplicationModel::Resources::ResourceLoader ^ m_resLoader;

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.
#include "pch.h" #include "pch.h"
@ -47,13 +47,13 @@ COpndCommand CommandDeserializer::DeserializeOperand()
bool fDecimal = m_dataReader->ReadBoolean(); bool fDecimal = m_dataReader->ReadBoolean();
bool fSciFmt = m_dataReader->ReadBoolean(); bool fSciFmt = m_dataReader->ReadBoolean();
std::shared_ptr<CalculatorVector<int>> cmdVector = std::make_shared<CalculatorVector<int>>(); std::shared_ptr<std::vector<int>> cmdVector = std::make_shared<std::vector<int>>();
auto cmdVectorSize = m_dataReader->ReadUInt32(); auto cmdVectorSize = m_dataReader->ReadUInt32();
for (unsigned int j = 0; j < cmdVectorSize; ++j) for (unsigned int j = 0; j < cmdVectorSize; ++j)
{ {
int eachOpndcmd = m_dataReader->ReadInt32(); int eachOpndcmd = m_dataReader->ReadInt32();
cmdVector->Append(eachOpndcmd); cmdVector->push_back(eachOpndcmd);
} }
return COpndCommand(cmdVector, fNegative, fDecimal, fSciFmt); return COpndCommand(cmdVector, fNegative, fDecimal, fSciFmt);
@ -68,7 +68,6 @@ CParentheses CommandDeserializer::DeserializeParentheses()
CUnaryCommand CommandDeserializer::DeserializeUnary() CUnaryCommand CommandDeserializer::DeserializeUnary()
{ {
auto cmdSize = m_dataReader->ReadUInt32(); auto cmdSize = m_dataReader->ReadUInt32();
std::shared_ptr<CalculatorVector<int>> cmdVector = std::make_shared<CalculatorVector<int>>();
if (cmdSize == 1) if (cmdSize == 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.
#include "pch.h" #include "pch.h"
@ -18,28 +18,22 @@ void SerializeCommandVisitor::Visit(_In_ COpndCommand& opndCmd)
m_dataWriter->WriteBoolean(opndCmd.IsDecimalPresent()); m_dataWriter->WriteBoolean(opndCmd.IsDecimalPresent());
m_dataWriter->WriteBoolean(opndCmd.IsSciFmt()); m_dataWriter->WriteBoolean(opndCmd.IsSciFmt());
auto opndCmds = opndCmd.GetCommands(); const auto& opndCmds = opndCmd.GetCommands();
unsigned int opndCmdSize; unsigned int opndCmdSize = static_cast<unsigned int>(opndCmds->size());
opndCmds->GetSize(&opndCmdSize);
m_dataWriter->WriteUInt32(opndCmdSize); m_dataWriter->WriteUInt32(opndCmdSize);
for (unsigned int j = 0; j < opndCmdSize; ++j) for (int eachOpndcmd : *opndCmds)
{ {
int eachOpndcmd;
opndCmds->GetAt(j, &eachOpndcmd);
m_dataWriter->WriteInt32(eachOpndcmd); m_dataWriter->WriteInt32(eachOpndcmd);
} }
} }
void SerializeCommandVisitor::Visit(_In_ CUnaryCommand& unaryCmd) void SerializeCommandVisitor::Visit(_In_ CUnaryCommand& unaryCmd)
{ {
auto cmds = unaryCmd.GetCommands(); const auto& cmds = unaryCmd.GetCommands();
unsigned int cmdSize; unsigned int cmdSize = static_cast<unsigned int>(cmds->size());
cmds->GetSize(&cmdSize);
m_dataWriter->WriteUInt32(cmdSize); m_dataWriter->WriteUInt32(cmdSize);
for (unsigned int j = 0; j < cmdSize; ++j) for (int eachOpndcmd : *cmds)
{ {
int eachOpndcmd;
cmds->GetAt(j, &eachOpndcmd);
m_dataWriter->WriteInt32(eachOpndcmd); m_dataWriter->WriteInt32(eachOpndcmd);
} }
} }

View File

@ -431,9 +431,9 @@ void KeyboardShortcutManager::OnCharacterReceivedHandler(CoreWindow ^ sender, Ch
{ {
wchar_t character = static_cast<wchar_t>(args->KeyCode); wchar_t character = static_cast<wchar_t>(args->KeyCode);
auto buttons = s_CharacterForButtons.find(viewId)->second.equal_range(character); auto buttons = s_CharacterForButtons.find(viewId)->second.equal_range(character);
RunFirstEnabledButtonCommand(buttons);
LightUpButtons(buttons); LightUpButtons(buttons);
RunFirstEnabledButtonCommand(buttons);
} }
} }
} }
@ -519,7 +519,7 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow ^ sender, KeyEventArgs
auto navView = buttons.first->second.Resolve<MUXC::NavigationView>(); auto navView = buttons.first->second.Resolve<MUXC::NavigationView>();
auto appViewModel = safe_cast<ApplicationViewModel ^>(navView->DataContext); auto appViewModel = safe_cast<ApplicationViewModel ^>(navView->DataContext);
appViewModel->Mode = ViewMode::Date; appViewModel->Mode = ViewMode::Date;
auto categoryName = AppResourceProvider::GetInstance().GetResourceString(L"DateCalculationModeText"); auto categoryName = AppResourceProvider::GetInstance()->GetResourceString(L"DateCalculationModeText");
appViewModel->CategoryName = categoryName; appViewModel->CategoryName = categoryName;
auto menuItems = static_cast<IObservableVector<Object ^> ^>(navView->MenuItemsSource); auto menuItems = static_cast<IObservableVector<Object ^> ^>(navView->MenuItemsSource);
@ -601,8 +601,6 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow ^ sender, KeyEventArgs
LightUpButtons(buttons); LightUpButtons(buttons);
} }
} }
RunFirstEnabledButtonCommand(buttons);
} }
} }
} }

View File

@ -94,16 +94,16 @@ LocalizationService::LocalizationService(_In_ const wchar_t * const overridedLan
m_locale = locale(""); m_locale = locale("");
} }
auto resourceLoader = AppResourceProvider::GetInstance(); auto resourceLoader = AppResourceProvider::GetInstance();
m_fontFamilyOverride = resourceLoader.GetResourceString(L"LocalizedFontFamilyOverride"); m_fontFamilyOverride = resourceLoader->GetResourceString(L"LocalizedFontFamilyOverride");
String ^ reserved = L"RESERVED_FOR_FONTLOC"; String ^ reserved = L"RESERVED_FOR_FONTLOC";
m_overrideFontApiValues = ((m_fontFamilyOverride != nullptr) && (m_fontFamilyOverride != reserved)); m_overrideFontApiValues = ((m_fontFamilyOverride != nullptr) && (m_fontFamilyOverride != reserved));
if (m_overrideFontApiValues) if (m_overrideFontApiValues)
{ {
String ^ localizedUICaptionFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride"); String ^ localizedUICaptionFontSizeFactorOverride = resourceLoader->GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride");
String ^ localizedUITextFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUITextFontSizeFactorOverride"); String ^ localizedUITextFontSizeFactorOverride = resourceLoader->GetResourceString(L"LocalizedUITextFontSizeFactorOverride");
String ^ localizedFontWeightOverride = resourceLoader.GetResourceString(L"LocalizedFontWeightOverride"); String ^ localizedFontWeightOverride = resourceLoader->GetResourceString(L"LocalizedFontWeightOverride");
// If any of the font overrides are modified then all of them need to be modified // If any of the font overrides are modified then all of them need to be modified
assert(localizedFontWeightOverride != reserved); assert(localizedFontWeightOverride != reserved);
@ -503,16 +503,49 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
make_pair<wstring, wstring>(L"27", L"HyperbolicTangent"), make_pair<wstring, wstring>(L"27", L"HyperbolicTangent"),
make_pair<wstring, wstring>(L"87", L"InverseHyperbolicTangent"), make_pair<wstring, wstring>(L"87", L"InverseHyperbolicTangent"),
// Secant permutations
make_pair<wstring, wstring>(L"SecDeg", L"SecantDegrees"),
make_pair<wstring, wstring>(L"SecRad", L"SecantRadians"),
make_pair<wstring, wstring>(L"SecGrad", L"SecantGradians"),
make_pair<wstring, wstring>(L"InverseSecDeg", L"InverseSecantDegrees"),
make_pair<wstring, wstring>(L"InverseSecRad", L"InverseSecantRadians"),
make_pair<wstring, wstring>(L"InverseSecGrad", L"InverseSecantGradians"),
make_pair<wstring, wstring>(L"Sech", L"HyperbolicSecant"),
make_pair<wstring, wstring>(L"InverseSech", L"InverseHyperbolicSecant"),
// Cosecant permutations
make_pair<wstring, wstring>(L"CscDeg", L"CosecantDegrees"),
make_pair<wstring, wstring>(L"CscRad", L"CosecantRadians"),
make_pair<wstring, wstring>(L"CscGrad", L"CosecantGradians"),
make_pair<wstring, wstring>(L"InverseCscDeg", L"InverseCosecantDegrees"),
make_pair<wstring, wstring>(L"InverseCscRad", L"InverseCosecantRadians"),
make_pair<wstring, wstring>(L"InverseCscGrad", L"InverseCosecantGradians"),
make_pair<wstring, wstring>(L"Csch", L"HyperbolicCosecant"),
make_pair<wstring, wstring>(L"InverseCsch", L"InverseHyperbolicCosecant"),
// Cotangent permutations
make_pair<wstring, wstring>(L"CotDeg", L"CotangentDegrees"),
make_pair<wstring, wstring>(L"CotRad", L"CotangentRadians"),
make_pair<wstring, wstring>(L"CotGrad", L"CotangentGradians"),
make_pair<wstring, wstring>(L"InverseCotDeg", L"InverseCotangentDegrees"),
make_pair<wstring, wstring>(L"InverseCotRad", L"InverseCotangentRadians"),
make_pair<wstring, wstring>(L"InverseCotGrad", L"InverseCotangentGradians"),
make_pair<wstring, wstring>(L"Coth", L"HyperbolicCotangent"),
make_pair<wstring, wstring>(L"InverseCoth", L"InverseHyperbolicCotangent"),
// Miscellaneous Scientific functions // Miscellaneous Scientific functions
make_pair<wstring, wstring>(L"94", L"Factorial"), make_pair<wstring, wstring>(L"94", L"Factorial"),
make_pair<wstring, wstring>(L"35", L"DegreeMinuteSecond"), make_pair<wstring, wstring>(L"35", L"DegreeMinuteSecond"),
make_pair<wstring, wstring>(L"28", L"NaturalLog"), make_pair<wstring, wstring>(L"28", L"NaturalLog"),
make_pair<wstring, wstring>(L"91", L"Square") make_pair<wstring, wstring>(L"91", L"Square"),
make_pair<wstring, wstring>(L"CubeRoot", L"CubeRoot"),
make_pair<wstring, wstring>(L"Abs", L"AbsoluteValue")
}; };
static vector<pair<wstring, wstring>> s_noParenEngineKeyResourceMap = { // Programmer mode functions static vector<pair<wstring, wstring>> s_noParenEngineKeyResourceMap = { // Programmer mode functions
make_pair<wstring, wstring>(L"9", L"LeftShift"), make_pair<wstring, wstring>(L"9", L"LeftShift"),
make_pair<wstring, wstring>(L"10", L"RightShift"), make_pair<wstring, wstring>(L"10", L"RightShift"),
make_pair<wstring, wstring>(L"LogBaseX", L"Logx"),
// Y Root scientific function // Y Root scientific function
make_pair<wstring, wstring>(L"16", L"YRoot") make_pair<wstring, wstring>(L"16", L"YRoot")
@ -521,12 +554,12 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
unordered_map<wstring, wstring> tokenToReadableNameMap{}; unordered_map<wstring, wstring> tokenToReadableNameMap{};
auto resProvider = AppResourceProvider::GetInstance(); auto resProvider = AppResourceProvider::GetInstance();
static const wstring openParen = resProvider.GetCEngineString(StringReference(s_openParenResourceKey))->Data(); static const wstring openParen = resProvider->GetCEngineString(StringReference(s_openParenResourceKey))->Data();
for (const auto& keyPair : s_parenEngineKeyResourceMap) for (const auto& keyPair : s_parenEngineKeyResourceMap)
{ {
wstring engineStr = resProvider.GetCEngineString(StringReference(keyPair.first.c_str()))->Data(); wstring engineStr = resProvider->GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
wstring automationName = resProvider.GetResourceString(StringReference(keyPair.second.c_str()))->Data(); wstring automationName = resProvider->GetResourceString(StringReference(keyPair.second.c_str()))->Data();
tokenToReadableNameMap.emplace(engineStr + openParen, automationName); tokenToReadableNameMap.emplace(engineStr + openParen, automationName);
} }
@ -534,15 +567,15 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
for (const auto& keyPair : s_noParenEngineKeyResourceMap) for (const auto& keyPair : s_noParenEngineKeyResourceMap)
{ {
wstring engineStr = resProvider.GetCEngineString(StringReference(keyPair.first.c_str()))->Data(); wstring engineStr = resProvider->GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
wstring automationName = resProvider.GetResourceString(StringReference(keyPair.second.c_str()))->Data(); wstring automationName = resProvider->GetResourceString(StringReference(keyPair.second.c_str()))->Data();
tokenToReadableNameMap.emplace(engineStr, automationName); tokenToReadableNameMap.emplace(engineStr, automationName);
} }
s_noParenEngineKeyResourceMap.clear(); s_noParenEngineKeyResourceMap.clear();
// Also replace hyphens with "minus" // Also replace hyphens with "minus"
wstring minusText = resProvider.GetResourceString(L"minus")->Data(); wstring minusText = resProvider->GetResourceString(L"minus")->Data();
tokenToReadableNameMap.emplace(L"-", minusText); tokenToReadableNameMap.emplace(L"-", minusText);
return tokenToReadableNameMap; return tokenToReadableNameMap;
@ -559,7 +592,7 @@ String ^ LocalizationService::GetNarratorReadableToken(String ^ rawToken)
} }
else else
{ {
static const String ^ openParen = AppResourceProvider::GetInstance().GetCEngineString(StringReference(s_openParenResourceKey)); static const String ^ openParen = AppResourceProvider::GetInstance()->GetCEngineString(StringReference(s_openParenResourceKey));
return ref new String(itr->second.c_str()) + L" " + openParen; return ref new String(itr->second.c_str()) + L" " + openParen;
} }
} }

View File

@ -58,10 +58,11 @@ namespace CalculatorApp
Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter() const; Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter() const;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format) const; Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format) const;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter( Windows::Globalization::DateTimeFormatting::DateTimeFormatter
_In_ Platform::String ^ format, ^ GetRegionalSettingsAwareDateTimeFormatter(
_In_ Platform::String ^ calendarIdentifier, _In_ Platform::String ^ format,
_In_ Platform::String ^ clockIdentifier) const; _In_ Platform::String ^ calendarIdentifier,
_In_ Platform::String ^ clockIdentifier) const;
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter() const; Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter() const;

View File

@ -169,20 +169,21 @@ namespace CalculatorApp
} }
} }
Platform::String ^ GetEnglishValueFromLocalizedDigits(const std::wstring& localizedString) const Platform::String ^ GetEnglishValueFromLocalizedDigits(Platform::String ^ localizedString) const
{ {
if (m_resolvedName == L"en-US") if (m_resolvedName == L"en-US")
{ {
return ref new Platform::String(localizedString.c_str()); return localizedString;
} }
size_t i = 0; size_t i = 0;
size_t length = localizedString.size(); auto localizedStringData = localizedString->Data();
size_t length = localizedString->Length();
std::unique_ptr<wchar_t[]> englishString(new wchar_t[length + 1]); // +1 for the null termination std::unique_ptr<wchar_t[]> englishString(new wchar_t[length + 1]); // +1 for the null termination
for (; i < length; ++i) for (; i < length; ++i)
{ {
wchar_t ch = localizedString[i]; wchar_t ch = localizedStringData[i];
if (!IsEnUsDigit(ch)) if (!IsEnUsDigit(ch))
{ {
for (int j = 0; j < 10; ++j) for (int j = 0; j < 10; ++j)
@ -281,18 +282,17 @@ namespace CalculatorApp
return m_numberGrouping; return m_numberGrouping;
} }
void RemoveGroupSeparators(const wchar_t* value, const size_t length, std::wstring* rawValue) const Platform::String ^ RemoveGroupSeparators(Platform::String ^ source) const
{ {
rawValue->clear(); std::wstringstream stream;
rawValue->reserve(length); for (auto c = source->Begin(); c < source->End(); ++c)
for (size_t i = 0; i < length; i++)
{ {
if (value[i] != L' ' && value[i] != m_numberGroupSeparator) if (*c != L' ' && *c != m_numberGroupSeparator)
{ {
rawValue->append(1, value[i]); stream << *c;
} }
} }
return ref new Platform::String(stream.str().c_str());
} }
Platform::String ^ GetCalendarIdentifier() const Platform::String ^ GetCalendarIdentifier() const

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
@ -9,50 +9,78 @@ namespace CalculatorApp
{ {
namespace Common namespace Common
{ {
class LocalizationStringUtil class LocalizationStringUtilInternal
{ {
public: public:
static std::wstring GetLocalizedString(const wchar_t* pMessage, ...) static Platform::String ^ GetLocalizedString(Platform::String ^ pMessage, ...)
{ {
std::wstring returnString = L""; std::wstring returnString = L"";
const UINT32 length = 1024; const UINT32 length = 1024;
std::unique_ptr<wchar_t[]> spBuffer = std::unique_ptr<wchar_t[]>(new wchar_t[length]); std::unique_ptr<wchar_t[]> spBuffer = std::unique_ptr<wchar_t[]>(new wchar_t[length]);
va_list args = NULL; va_list args = NULL;
va_start(args, pMessage); va_start(args, pMessage);
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pMessage, 0, 0, spBuffer.get(), length, &args); DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pMessage->Data(), 0, 0, spBuffer.get(), length, &args);
va_end(args); va_end(args);
if (fmtReturnVal != 0) if (fmtReturnVal != 0)
{ {
returnString = spBuffer.get(); return ref new Platform::String(spBuffer.get());
} }
else
return returnString;
}
template <typename... T>
static Platform::String^ GetLocalizedNarratorAnnouncement(Platform::String^ resourceKey, Platform::String^& formatVariable, T*... params)
{
EnsureInitialization(resourceKey, formatVariable);
return StringReference(GetLocalizedString(formatVariable->Data(), params...).c_str());
}
private:
static void EnsureInitialization(Platform::String^ resourceKey, Platform::String^& formatVariable)
{
if (resourceKey == nullptr || resourceKey->IsEmpty())
{ {
return; return ref new Platform::String();
} }
// If the formatVariable already has a value, we don't need to set it again. Simply return.
if (formatVariable != nullptr && !formatVariable->IsEmpty())
{
return;
}
formatVariable = AppResourceProvider::GetInstance().GetResourceString(resourceKey);
} }
}; };
public
ref class LocalizationStringUtil sealed
{
public:
static Platform::String
^ GetLocalizedString(Platform::String ^ pMessage)
{
return LocalizationStringUtilInternal::GetLocalizedString(pMessage);
}
static Platform::String
^ GetLocalizedString(
Platform::String ^ pMessage,
Platform::String ^ param1)
{
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data());
}
static Platform::String
^ GetLocalizedString(
Platform::String ^ pMessage,
Platform::String ^ param1,
Platform::String ^ param2)
{
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data(), param2->Data());
}
static Platform::String
^ GetLocalizedString(
Platform::String ^ pMessage,
Platform::String ^ param1,
Platform::String ^ param2,
Platform::String
^ param3)
{
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data(), param2->Data(), param3->Data());
}
static Platform::String
^ GetLocalizedString(
Platform::String ^ pMessage,
Platform::String ^ param1,
Platform::String ^ param2,
Platform::String ^ param3,
Platform::String ^ param4)
{
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data(), param2->Data(), param3->Data(), param4->Data());
}
};
} }
} }

View File

@ -46,7 +46,7 @@ static constexpr int DATA_ID = 13;
static constexpr int PRESSURE_ID = 14; static constexpr int PRESSURE_ID = 14;
static constexpr int ANGLE_ID = 15; static constexpr int ANGLE_ID = 15;
static constexpr int CURRENCY_ID = 16; static constexpr int CURRENCY_ID = 16;
static constexpr int GRAPHING_ID = 17; static constexpr int GRAPHING_ID = 17;
// ^^^ THESE CONSTANTS SHOULD NEVER CHANGE ^^^ // ^^^ THESE CONSTANTS SHOULD NEVER CHANGE ^^^
// The order of items in this list determines the order of items in the menu. // The order of items in this list determines the order of items in the menu.
@ -57,14 +57,6 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
L"\uE8EF", L"\uE8EF",
CategoryGroupType::Calculator, CategoryGroupType::Calculator,
MyVirtualKey::Number1, MyVirtualKey::Number1,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Graphing,
GRAPHING_ID,
L"Graphing",
L"GraphingCalculatorMode",
L"\uF770",
CategoryGroupType::Calculator,
MyVirtualKey::Number5,
SUPPORTS_ALL }, SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Scientific, NavCategoryInitializer{ ViewMode::Scientific,
SCIENTIFIC_ID, SCIENTIFIC_ID,
@ -82,6 +74,14 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
CategoryGroupType::Calculator, CategoryGroupType::Calculator,
MyVirtualKey::Number3, MyVirtualKey::Number3,
SUPPORTS_ALL }, SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Graphing,
GRAPHING_ID,
L"Graphing",
L"GraphingCalculatorMode",
L"\uF770",
CategoryGroupType::Calculator,
MyVirtualKey::Number5,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Date, NavCategoryInitializer{ ViewMode::Date,
DATE_ID, DATE_ID,
L"Date", L"Date",
@ -169,7 +169,7 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
L"\uE945", L"\uE945",
CategoryGroupType::Converter, CategoryGroupType::Converter,
MyVirtualKey::None, MyVirtualKey::None,
POSITIVE_ONLY }, SUPPORTS_NEGATIVE },
NavCategoryInitializer{ ViewMode::Data, NavCategoryInitializer{ ViewMode::Data,
DATA_ID, DATA_ID,
L"Data", L"Data",
@ -193,7 +193,7 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
L"\uF515", L"\uF515",
CategoryGroupType::Converter, CategoryGroupType::Converter,
MyVirtualKey::None, MyVirtualKey::None,
POSITIVE_ONLY } }; SUPPORTS_NEGATIVE } };
// This function should only be used when storing the mode to app data. // This function should only be used when storing the mode to app data.
int NavCategory::Serialize(ViewMode mode) int NavCategory::Serialize(ViewMode mode)
@ -238,9 +238,7 @@ bool NavCategory::IsValidViewMode(ViewMode mode)
bool NavCategory::IsCalculatorViewMode(ViewMode mode) bool NavCategory::IsCalculatorViewMode(ViewMode mode)
{ {
// Historically, Calculator modes are Standard, Scientific, and Programmer. // Historically, Calculator modes are Standard, Scientific, and Programmer.
return !IsDateCalculatorViewMode(mode) return !IsDateCalculatorViewMode(mode) && !IsGraphingCalculatorViewMode(mode) && IsModeInCategoryGroup(mode, CategoryGroupType::Calculator);
&& !IsGraphingCalculatorViewMode(mode)
&& IsModeInCategoryGroup(mode, CategoryGroupType::Calculator);
} }
bool NavCategory::IsGraphingCalculatorViewMode(ViewMode mode) bool NavCategory::IsGraphingCalculatorViewMode(ViewMode mode)
@ -383,33 +381,28 @@ NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupIniti
m_GroupType = groupInitializer.type; m_GroupType = groupInitializer.type;
auto resProvider = AppResourceProvider::GetInstance(); auto resProvider = AppResourceProvider::GetInstance();
String ^ headerResourceKey = StringReference(groupInitializer.headerResourceKey); m_Name = resProvider->GetResourceString(StringReference(groupInitializer.headerResourceKey));
String ^ modeResourceKey = StringReference(groupInitializer.modeResourceKey); String ^ groupMode = resProvider->GetResourceString(StringReference(groupInitializer.modeResourceKey));
String ^ automationResourceKey = StringReference(groupInitializer.automationResourceKey); String ^ automationName = resProvider->GetResourceString(StringReference(groupInitializer.automationResourceKey));
m_Name = resProvider.GetResourceString(headerResourceKey);
String ^ groupMode = resProvider.GetResourceString(modeResourceKey);
String ^ automationName = resProvider.GetResourceString(automationResourceKey);
String ^ navCategoryHeaderAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryHeader_AutomationNameFormat"); String ^ navCategoryHeaderAutomationNameFormat = resProvider->GetResourceString(L"NavCategoryHeader_AutomationNameFormat");
m_AutomationName = m_AutomationName = LocalizationStringUtil::GetLocalizedString(navCategoryHeaderAutomationNameFormat, automationName);
ref new String(LocalizationStringUtil::GetLocalizedString(navCategoryHeaderAutomationNameFormat->Data(), automationName->Data()).c_str());
String ^ navCategoryItemAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryItem_AutomationNameFormat"); String ^ navCategoryItemAutomationNameFormat = resProvider->GetResourceString(L"NavCategoryItem_AutomationNameFormat");
for (const NavCategoryInitializer& categoryInitializer : s_categoryManifest) for (const NavCategoryInitializer& categoryInitializer : s_categoryManifest)
{ {
if (categoryInitializer.groupType == groupInitializer.type) if (categoryInitializer.groupType == groupInitializer.type)
{ {
String ^ nameResourceKey = StringReference(categoryInitializer.nameResourceKey); String ^ nameResourceKey = StringReference(categoryInitializer.nameResourceKey);
String ^ categoryName = resProvider.GetResourceString(nameResourceKey + "Text"); String ^ categoryName = resProvider->GetResourceString(nameResourceKey + "Text");
String ^ categoryAutomationName = ref new String( String ^ categoryAutomationName = LocalizationStringUtil::GetLocalizedString(navCategoryItemAutomationNameFormat, categoryName, m_Name);
LocalizationStringUtil::GetLocalizedString(navCategoryItemAutomationNameFormat->Data(), categoryName->Data(), m_Name->Data()).c_str());
m_Categories->Append(ref new NavCategory( m_Categories->Append(ref new NavCategory(
categoryName, categoryName,
categoryAutomationName, categoryAutomationName,
StringReference(categoryInitializer.glyph), StringReference(categoryInitializer.glyph),
resProvider.GetResourceString(nameResourceKey + "AccessKey"), resProvider->GetResourceString(nameResourceKey + "AccessKey"),
groupMode, groupMode,
categoryInitializer.viewMode, categoryInitializer.viewMode,
categoryInitializer.supportsNegative)); categoryInitializer.supportsNegative));

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp::Common
{
public
enum class NumberBase
{
Unknown = -1,
HexBase = 5,
DecBase = 6,
OctBase = 7,
BinBase = 8
};
};

View File

@ -10,6 +10,7 @@ using namespace CalculatorApp;
using namespace CalculatorApp::Common; using namespace CalculatorApp::Common;
using namespace Concurrency; using namespace Concurrency;
using namespace std; using namespace std;
using namespace Platform;
using namespace winrt; using namespace winrt;
using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Diagnostics; using namespace winrt::Windows::Foundation::Diagnostics;
@ -57,47 +58,43 @@ namespace CalculatorApp
TraceLogger::TraceLogger() TraceLogger::TraceLogger()
: g_calculatorProvider( : g_calculatorProvider(
L"MicrosoftCalculator", L"MicrosoftCalculator",
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }),
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }) GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 })
, // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0} , // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
m_appLaunchActivity{ nullptr } m_appLaunchActivity{ nullptr }
{ {
CoCreateGuid(&sessionGuid); CoCreateGuid(&sessionGuid);
} }
TraceLogger::~TraceLogger() TraceLogger ^ TraceLogger::GetInstance()
{ {
} static TraceLogger ^ s_selfInstance = ref new TraceLogger();
TraceLogger& TraceLogger::GetInstance()
{
static TraceLogger s_selfInstance;
return s_selfInstance; return s_selfInstance;
} }
bool TraceLogger::GetTraceLoggingProviderEnabled() const bool TraceLogger::GetTraceLoggingProviderEnabled()
{ {
return g_calculatorProvider.Enabled(); return g_calculatorProvider.Enabled();
} }
#pragma region Tracing methods #pragma region Tracing methods
void TraceLogger::LogLevel1Event(wstring_view eventName, LoggingFields fields) const void TraceLogger::LogLevel1Event(wstring_view eventName, LoggingFields fields)
{ {
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_1)); g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_1));
} }
void TraceLogger::LogLevel2Event(wstring_view eventName, LoggingFields fields) const void TraceLogger::LogLevel2Event(wstring_view eventName, LoggingFields fields)
{ {
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_2)); g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_2));
} }
void TraceLogger::LogLevel3Event(wstring_view eventName, LoggingFields fields) const void TraceLogger::LogLevel3Event(wstring_view eventName, LoggingFields fields)
{ {
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_3)); g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_3));
} }
unique_ptr<TraceActivity> TraceLogger::CreateTraceActivity(wstring_view eventName, LoggingFields fields) const unique_ptr<TraceActivity> TraceLogger::CreateTraceActivity(wstring_view eventName, LoggingFields fields)
{ {
return make_unique<TraceActivity>(g_calculatorProvider, eventName, fields); return make_unique<TraceActivity>(g_calculatorProvider, eventName, fields);
} }
@ -117,7 +114,7 @@ namespace CalculatorApp
return true; return true;
} }
void TraceLogger::LogVisualStateChanged(ViewMode mode, wstring_view state, bool isAlwaysOnTop) const void TraceLogger::LogVisualStateChanged(ViewMode mode, String ^ state, bool isAlwaysOnTop)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
{ {
@ -127,7 +124,7 @@ namespace CalculatorApp
LoggingFields fields{}; LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid); fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data()); fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"VisualState", state); fields.AddString(L"VisualState", state->Data());
fields.AddBoolean(L"IsAlwaysOnTop", isAlwaysOnTop); fields.AddBoolean(L"IsAlwaysOnTop", isAlwaysOnTop);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE); fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_VISUAL_STATE_CHANGED, fields); LogLevel2Event(EVENT_NAME_VISUAL_STATE_CHANGED, fields);
@ -152,7 +149,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_WINDOW_ON_CREATED, fields); LogLevel2Event(EVENT_NAME_WINDOW_ON_CREATED, fields);
} }
void TraceLogger::LogModeChange(ViewMode mode) const void TraceLogger::LogModeChange(ViewMode mode)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;
@ -167,7 +164,7 @@ namespace CalculatorApp
} }
} }
void TraceLogger::LogHistoryItemLoad(ViewMode mode, int historyListSize, int loadedIndex) const void TraceLogger::LogHistoryItemLoad(ViewMode mode, int historyListSize, int loadedIndex)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
{ {
@ -183,7 +180,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_HISTORY_ITEM_LOAD, fields); LogLevel2Event(EVENT_NAME_HISTORY_ITEM_LOAD, fields);
} }
void TraceLogger::LogMemoryItemLoad(ViewMode mode, int memoryListSize, int loadedIndex) const void TraceLogger::LogMemoryItemLoad(ViewMode mode, int memoryListSize, int loadedIndex)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
{ {
@ -199,7 +196,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_MEMORY_ITEM_LOAD, fields); LogLevel2Event(EVENT_NAME_MEMORY_ITEM_LOAD, fields);
} }
void TraceLogger::LogError(ViewMode mode, wstring_view functionName, wstring_view errorString) void TraceLogger::LogError(ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;
@ -207,13 +204,13 @@ namespace CalculatorApp
LoggingFields fields{}; LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid); fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data()); fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"FunctionName", functionName); fields.AddString(L"FunctionName", functionName->Data());
fields.AddString(L"Message", errorString); fields.AddString(L"Message", errorString->Data());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE); fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_EXCEPTION, fields); LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
} }
void TraceLogger::LogStandardException(ViewMode mode, wstring_view functionName, const exception& e) const void TraceLogger::LogStandardException(ViewMode mode, wstring_view functionName, const exception& e)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;
@ -229,7 +226,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_EXCEPTION, fields); LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
} }
void TraceLogger::LogWinRTException(ViewMode mode, wstring_view functionName, hresult_error const& e) const void TraceLogger::LogWinRTException(ViewMode mode, wstring_view functionName, hresult_error const& e)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;
@ -244,7 +241,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_EXCEPTION, fields); LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
} }
void TraceLogger::LogPlatformException(ViewMode mode, wstring_view functionName, Platform::Exception ^ e) const void TraceLogger::LogPlatformException(ViewMode mode, wstring_view functionName, Platform::Exception ^ e)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;
@ -291,7 +288,7 @@ namespace CalculatorApp
} }
} }
void TraceLogger::UpdateWindowCount(size_t windowCount) void TraceLogger::UpdateWindowCount(uint64 windowCount)
{ {
if (windowCount == 0) if (windowCount == 0)
{ {
@ -301,6 +298,11 @@ namespace CalculatorApp
currentWindowCount = windowCount; currentWindowCount = windowCount;
} }
void TraceLogger::DecreaseWindowCount()
{
currentWindowCount = 0;
}
void TraceLogger::LogButtonUsage() void TraceLogger::LogButtonUsage()
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
@ -348,7 +350,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_DATE_CALCULATION_MODE_USED, fields); LogLevel2Event(EVENT_NAME_DATE_CALCULATION_MODE_USED, fields);
} }
void TraceLogger::LogConverterInputReceived(ViewMode mode) const void TraceLogger::LogConverterInputReceived(ViewMode mode)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;
@ -360,7 +362,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_CONVERTER_INPUT_RECEIVED, fields); LogLevel2Event(EVENT_NAME_CONVERTER_INPUT_RECEIVED, fields);
} }
void TraceLogger::LogNavBarOpened() const void TraceLogger::LogNavBarOpened()
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;
@ -371,7 +373,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_NAV_BAR_OPENED, fields); LogLevel2Event(EVENT_NAME_NAV_BAR_OPENED, fields);
} }
void TraceLogger::LogInputPasted(ViewMode mode) const void TraceLogger::LogInputPasted(ViewMode mode)
{ {
if (!GetTraceLoggingProviderEnabled()) if (!GetTraceLoggingProviderEnabled())
return; return;

View File

@ -28,33 +28,31 @@ namespace CalculatorApp
} }
}; };
class TraceLogger public
ref class TraceLogger sealed
{ {
public: public:
TraceLogger(_In_ TraceLogger const&) = delete; static TraceLogger ^ GetInstance();
TraceLogger const& operator=(_In_ TraceLogger const&) = delete; bool GetTraceLoggingProviderEnabled();
~TraceLogger(); void LogModeChange(CalculatorApp::Common::ViewMode mode);
static TraceLogger& GetInstance(); void LogHistoryItemLoad(CalculatorApp::Common::ViewMode mode, int historyListSize, int loadedIndex);
bool GetTraceLoggingProviderEnabled() const; void LogMemoryItemLoad(CalculatorApp::Common::ViewMode mode, int memoryListSize, int loadedIndex);
void LogModeChange(CalculatorApp::Common::ViewMode mode) const;
void LogHistoryItemLoad(CalculatorApp::Common::ViewMode mode, int historyListSize, int loadedIndex) const;
void LogMemoryItemLoad(CalculatorApp::Common::ViewMode mode, int memoryListSize, int loadedIndex) const;
void UpdateButtonUsage(CalculatorApp::NumbersAndOperatorsEnum button, CalculatorApp::Common::ViewMode mode); void UpdateButtonUsage(CalculatorApp::NumbersAndOperatorsEnum button, CalculatorApp::Common::ViewMode mode);
void LogButtonUsage(); void LogButtonUsage();
void LogDateCalculationModeUsed(bool AddSubtractMode); void LogDateCalculationModeUsed(bool AddSubtractMode);
void UpdateWindowCount(size_t windowCount = 0); void UpdateWindowCount(uint64 windowCount);
void DecreaseWindowCount();
bool IsWindowIdInLog(int windowId); bool IsWindowIdInLog(int windowId);
void LogVisualStateChanged(CalculatorApp::Common::ViewMode mode, std::wstring_view state, bool isAlwaysOnTop = false) const; void LogVisualStateChanged(CalculatorApp::Common::ViewMode mode, Platform::String ^ state, bool isAlwaysOnTop);
void LogWindowCreated(CalculatorApp::Common::ViewMode mode, int windowId); void LogWindowCreated(CalculatorApp::Common::ViewMode mode, int windowId);
void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode) const; void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode);
void LogNavBarOpened() const; void LogNavBarOpened();
void LogError(CalculatorApp::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString);
void LogError(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, std::wstring_view errorString); internal :
void LogStandardException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e) const; void LogStandardException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e);
void LogWinRTException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ winrt::hresult_error const& e) const; void LogWinRTException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ winrt::hresult_error const& e);
void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e) const; void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e);
void LogInputPasted(CalculatorApp::Common::ViewMode mode) const; void LogInputPasted(CalculatorApp::Common::ViewMode mode);
private: private:
// Create an instance of TraceLogger // Create an instance of TraceLogger
@ -64,11 +62,11 @@ namespace CalculatorApp
// sampling is involved in Microsoft's diagnostic data collection process. // sampling is involved in Microsoft's diagnostic data collection process.
// These keywords provide additional input into how frequently an event might be sampled. // These keywords provide additional input into how frequently an event might be sampled.
// The lower the level of the keyword, the higher the possibility that the corresponding event may be sampled. // The lower the level of the keyword, the higher the possibility that the corresponding event may be sampled.
void LogLevel1Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const; void LogLevel1Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
void LogLevel2Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const; void LogLevel2Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
void LogLevel3Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const; void LogLevel3Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
std::unique_ptr<TraceActivity> CreateTraceActivity(std::wstring_view activityName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const; std::unique_ptr<TraceActivity> CreateTraceActivity(std::wstring_view activityName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
winrt::Windows::Foundation::Diagnostics::LoggingChannel g_calculatorProvider; winrt::Windows::Foundation::Diagnostics::LoggingChannel g_calculatorProvider;
@ -76,7 +74,7 @@ namespace CalculatorApp
std::vector<int> windowIdLog; std::vector<int> windowIdLog;
GUID sessionGuid; GUID sessionGuid;
size_t currentWindowCount = 0; uint64 currentWindowCount = 0;
winrt::Windows::Foundation::Diagnostics::LoggingActivity m_appLaunchActivity; winrt::Windows::Foundation::Diagnostics::LoggingActivity m_appLaunchActivity;
}; };

View File

@ -10,7 +10,6 @@
#include "Common/AppResourceProvider.h" #include "Common/AppResourceProvider.h"
#include "Common/ExpressionCommandSerializer.h" #include "Common/ExpressionCommandSerializer.h"
#include "Common/ExpressionCommandDeserializer.h" #include "Common/ExpressionCommandDeserializer.h"
#include "ViewState.h"
using namespace CalculatorApp; using namespace CalculatorApp;
using namespace CalculatorApp::Common; using namespace CalculatorApp::Common;
@ -50,8 +49,8 @@ String ^ Utils::GetStringValue(String ^ input)
double Utils::GetDoubleFromWstring(wstring input) double Utils::GetDoubleFromWstring(wstring input)
{ {
wchar_t unWantedChars[] = { L' ', L',', 8234, 8235, 8236, 8237 }; constexpr wchar_t unWantedChars[] = { L' ', L',', 8234, 8235, 8236, 8237 };
wstring ws = RemoveUnwantedCharsFromWstring(input, unWantedChars, 6); wstring ws = RemoveUnwantedCharsFromString(input, unWantedChars);
return stod(ws); return stod(ws);
} }
@ -83,47 +82,26 @@ bool Utils::IsLastCharacterTarget(_In_ wstring const& input, _In_ wchar_t target
return !input.empty() && input.back() == target; return !input.empty() && input.back() == target;
} }
// Return wstring after removing characters specified by unwantedChars array
wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedChars, unsigned int size)
{
for (unsigned int i = 0; i < size; ++i)
{
input.erase(remove(input.begin(), input.end(), unwantedChars[i]), input.end());
}
return input;
}
void Utils::SerializeCommandsAndTokens( void Utils::SerializeCommandsAndTokens(
_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens, _In_ shared_ptr<vector<pair<wstring, int>>> const& tokens,
_In_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands, _In_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands,
DataWriter ^ writer) DataWriter ^ writer)
{ {
unsigned int commandsSize;
IFTPlatformException(commands->GetSize(&commandsSize));
// Save the size of the commands vector // Save the size of the commands vector
writer->WriteUInt32(commandsSize); writer->WriteUInt32(static_cast<unsigned int>(commands->size()));
SerializeCommandVisitor cmdVisitor(writer); SerializeCommandVisitor cmdVisitor(writer);
for (unsigned int i = 0; i < commandsSize; ++i) for (const auto& exprCmd : *commands)
{ {
shared_ptr<IExpressionCommand> exprCmd;
IFTPlatformException(commands->GetAt(i, &exprCmd));
CalculationManager::CommandType commandType = exprCmd->GetCommandType(); CalculationManager::CommandType commandType = exprCmd->GetCommandType();
writer->WriteInt32(static_cast<int>(commandType)); writer->WriteInt32(static_cast<int>(commandType));
exprCmd->Accept(cmdVisitor); exprCmd->Accept(cmdVisitor);
} }
unsigned int tokensSize; writer->WriteUInt32(static_cast<unsigned int>(tokens->size()));
IFTPlatformException(tokens->GetSize(&tokensSize));
writer->WriteUInt32(tokensSize);
for (unsigned int i = 0; i < tokensSize; ++i) for (const auto& eachToken : *tokens)
{ {
pair<wstring, int> eachToken;
IFTPlatformException(tokens->GetAt(i, &eachToken));
auto stringData = ref new Platform::String(eachToken.first.c_str()); auto stringData = ref new Platform::String(eachToken.first.c_str());
auto intData = eachToken.second; auto intData = eachToken.second;
writer->WriteUInt32(writer->MeasureString(stringData)); writer->WriteUInt32(writer->MeasureString(stringData));
@ -132,9 +110,9 @@ void Utils::SerializeCommandsAndTokens(
} }
} }
const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::DeserializeCommands(DataReader ^ reader) const shared_ptr<vector<shared_ptr<IExpressionCommand>>> Utils::DeserializeCommands(DataReader ^ reader)
{ {
shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> commandVector = make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>(); auto commandVector = make_shared<vector<shared_ptr<IExpressionCommand>>>();
auto commandVectorSize = reader->ReadUInt32(); auto commandVectorSize = reader->ReadUInt32();
CommandDeserializer cmdDeserializer(reader); CommandDeserializer cmdDeserializer(reader);
@ -143,26 +121,23 @@ const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::Deseri
auto commandTypeInt = reader->ReadInt32(); auto commandTypeInt = reader->ReadInt32();
CalculationManager::CommandType commandType = static_cast<CalculationManager::CommandType>(commandTypeInt); CalculationManager::CommandType commandType = static_cast<CalculationManager::CommandType>(commandTypeInt);
shared_ptr<IExpressionCommand> exprCmd = cmdDeserializer.Deserialize(commandType); shared_ptr<IExpressionCommand> exprCmd = cmdDeserializer.Deserialize(commandType);
commandVector->Append(exprCmd); commandVector->push_back(exprCmd);
} }
return commandVector; return commandVector;
} }
const shared_ptr<CalculatorVector<pair<wstring, int>>> Utils::DeserializeTokens(DataReader ^ reader) const shared_ptr<vector<pair<wstring, int>>> Utils::DeserializeTokens(DataReader ^ reader)
{ {
shared_ptr<CalculatorVector<pair<wstring, int>>> tokenVector = make_shared<CalculatorVector<pair<wstring, int>>>(); auto tokenVector = make_shared<vector<pair<wstring, int>>>();
auto tokensSize = reader->ReadUInt32(); auto tokensSize = reader->ReadUInt32();
for (unsigned int i = 0; i < tokensSize; ++i) for (unsigned int i = 0; i < tokensSize; ++i)
{ {
pair<wstring, int> eachToken;
auto stringDataLen = reader->ReadUInt32(); auto stringDataLen = reader->ReadUInt32();
auto stringData = reader->ReadString(stringDataLen); auto stringData = reader->ReadString(stringDataLen);
auto intData = reader->ReadInt32(); auto intData = reader->ReadInt32();
eachToken.first = stringData->Data(); tokenVector->emplace_back(stringData->Data(), intData);
eachToken.second = intData;
tokenVector->Append(eachToken);
} }
return tokenVector; return tokenVector;

View File

@ -3,7 +3,6 @@
#pragma once #pragma once
#include "CalcManager/CalculatorVector.h"
#include "CalcManager/ExpressionCommandInterface.h" #include "CalcManager/ExpressionCommandInterface.h"
#include "DelegateCommand.h" #include "DelegateCommand.h"
#include "GraphingInterfaces/GraphingEnums.h" #include "GraphingInterfaces/GraphingEnums.h"
@ -210,7 +209,7 @@ public:
private: \ private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##n##Property; \ static Windows::UI::Xaml::DependencyProperty ^ s_##n##Property; \
\ \
public: private:
// Utilities for DependencyProperties // Utilities for DependencyProperties
namespace Utils namespace Utils
@ -401,27 +400,34 @@ namespace Utils
void IFTPlatformException(HRESULT hr); void IFTPlatformException(HRESULT hr);
Platform::String ^ GetStringValue(Platform::String ^ input); Platform::String ^ GetStringValue(Platform::String ^ input);
bool IsLastCharacterTarget(std::wstring const& input, wchar_t target); bool IsLastCharacterTarget(std::wstring const& input, wchar_t target);
std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size);
// Return wstring after removing characters specified by unwantedChars array
template <size_t N>
std::wstring RemoveUnwantedCharsFromString(std::wstring inputString, const wchar_t (&unwantedChars)[N])
{
for (const wchar_t unwantedChar : unwantedChars)
{
inputString.erase(std::remove(inputString.begin(), inputString.end(), unwantedChar), inputString.end());
}
return inputString;
}
double GetDoubleFromWstring(std::wstring input); double GetDoubleFromWstring(std::wstring input);
int GetWindowId(); int GetWindowId();
void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher ^ currentDispatcher); void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher ^ currentDispatcher);
void SerializeCommandsAndTokens( void SerializeCommandsAndTokens(
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens, _In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands, _In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands,
Windows::Storage::Streams::DataWriter ^ writer); Windows::Storage::Streams::DataWriter ^ writer);
const std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> DeserializeCommands(Windows::Storage::Streams::DataReader ^ reader); const std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> DeserializeCommands(Windows::Storage::Streams::DataReader ^ reader);
const std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> DeserializeTokens(Windows::Storage::Streams::DataReader ^ reader); const std::shared_ptr<std::vector<std::pair<std::wstring, int>>> DeserializeTokens(Windows::Storage::Streams::DataReader ^ reader);
Windows::Foundation::DateTime GetUniversalSystemTime(); Windows::Foundation::DateTime GetUniversalSystemTime();
bool IsDateTimeOlderThan(Windows::Foundation::DateTime dateTime, const long long duration); bool IsDateTimeOlderThan(Windows::Foundation::DateTime dateTime, const long long duration);
concurrency::task<void> WriteFileToFolder( concurrency::task<void> WriteFileToFolder(Windows::Storage::IStorageFolder^ folder, Platform::String^ fileName, Platform::String^ contents, Windows::Storage::CreationCollisionOption collisionOption);
Windows::Storage::IStorageFolder ^ folder, concurrency::task<Platform::String^> ReadFileFromFolder(Windows::Storage::IStorageFolder^ folder, Platform::String^ fileName);
Platform::String ^ fileName,
Platform::String ^ contents,
Windows::Storage::CreationCollisionOption collisionOption);
concurrency::task<Platform::String ^> ReadFileFromFolder(Windows::Storage::IStorageFolder ^ folder, Platform::String ^ fileName);
bool AreColorsEqual(const Windows::UI::Color& color1, const Windows::UI::Color& color2); bool AreColorsEqual(const Windows::UI::Color& color1, const Windows::UI::Color& color2);

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.
#include "pch.h" #include "pch.h"
@ -132,8 +132,8 @@ CurrencyDataLoader::CurrencyDataLoader(_In_ unique_ptr<ICurrencyHttpClient> clie
m_ratioFormatter->IsDecimalPointAlwaysDisplayed = true; m_ratioFormatter->IsDecimalPointAlwaysDisplayed = true;
m_ratioFormatter->FractionDigits = FORMATTER_RATE_FRACTION_PADDING; m_ratioFormatter->FractionDigits = FORMATTER_RATE_FRACTION_PADDING;
m_ratioFormat = AppResourceProvider::GetInstance().GetResourceString(L"CurrencyFromToRatioFormat")->Data(); m_ratioFormat = AppResourceProvider::GetInstance()->GetResourceString(L"CurrencyFromToRatioFormat");
m_timestampFormat = AppResourceProvider::GetInstance().GetResourceString(L"CurrencyTimestampFormat")->Data(); m_timestampFormat = AppResourceProvider::GetInstance()->GetResourceString(L"CurrencyTimestampFormat");
} }
CurrencyDataLoader::~CurrencyDataLoader() CurrencyDataLoader::~CurrencyDataLoader()
@ -300,16 +300,18 @@ pair<wstring, wstring> CurrencyDataLoader::GetCurrencyRatioEquality(_In_ const U
double ratio = (iter2->second).ratio; double ratio = (iter2->second).ratio;
double rounded = RoundCurrencyRatio(ratio); double rounded = RoundCurrencyRatio(ratio);
wstring digitSymbol = wstring{ LocalizationSettings::GetInstance().GetDigitSymbolFromEnUsDigit(L'1') }; auto digit = LocalizationSettings::GetInstance().GetDigitSymbolFromEnUsDigit(L'1');
wstring roundedFormat = m_ratioFormatter->Format(rounded)->Data(); auto digitSymbol = ref new String(&digit, 1);
auto roundedFormat = m_ratioFormatter->Format(rounded);
wstring ratioString = LocalizationStringUtil::GetLocalizedString( auto ratioString = LocalizationStringUtil::GetLocalizedString(
m_ratioFormat.c_str(), digitSymbol.c_str(), unit1.abbreviation.c_str(), roundedFormat.c_str(), unit2.abbreviation.c_str()); m_ratioFormat, digitSymbol, StringReference(unit1.abbreviation.c_str()), roundedFormat, StringReference(unit2.abbreviation.c_str()));
wstring accessibleRatioString = LocalizationStringUtil::GetLocalizedString( auto accessibleRatioString =
m_ratioFormat.c_str(), digitSymbol.c_str(), unit1.accessibleName.c_str(), roundedFormat.c_str(), unit2.accessibleName.c_str()); LocalizationStringUtil::GetLocalizedString(
m_ratioFormat, digitSymbol, StringReference(unit1.accessibleName.c_str()), roundedFormat, StringReference(unit2.accessibleName.c_str()));
return make_pair(ratioString, accessibleRatioString); return make_pair(ratioString->Data(), accessibleRatioString->Data());
} }
} }
} }
@ -349,12 +351,12 @@ future<bool> CurrencyDataLoader::TryLoadDataFromCacheAsync()
} }
catch (Exception ^ ex) catch (Exception ^ ex)
{ {
TraceLogger::GetInstance().LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex); TraceLogger::GetInstance()->LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex);
co_return false; co_return false;
} }
catch (const exception& e) catch (const exception& e)
{ {
TraceLogger::GetInstance().LogStandardException(ViewMode::Currency, __FUNCTIONW__, e); TraceLogger::GetInstance()->LogStandardException(ViewMode::Currency, __FUNCTIONW__, e);
co_return false; co_return false;
} }
catch (...) catch (...)
@ -459,12 +461,12 @@ future<bool> CurrencyDataLoader::TryLoadDataFromWebAsync()
} }
catch (Exception ^ ex) catch (Exception ^ ex)
{ {
TraceLogger::GetInstance().LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex); TraceLogger::GetInstance()->LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex);
co_return false; co_return false;
} }
catch (const exception& e) catch (const exception& e)
{ {
TraceLogger::GetInstance().LogStandardException(ViewMode::Currency, __FUNCTIONW__, e); TraceLogger::GetInstance()->LogStandardException(ViewMode::Currency, __FUNCTIONW__, e);
co_return false; co_return false;
} }
catch (...) catch (...)
@ -480,7 +482,7 @@ future<bool> CurrencyDataLoader::TryLoadDataFromWebOverrideAsync()
if (!didLoad) if (!didLoad)
{ {
m_loadStatus = CurrencyLoadStatus::FailedToLoad; m_loadStatus = CurrencyLoadStatus::FailedToLoad;
TraceLogger::GetInstance().LogError(ViewMode::Currency, L"CurrencyDataLoader::TryLoadDataFromWebOverrideAsync", L"UserRequestedRefreshFailed"); TraceLogger::GetInstance()->LogError(ViewMode::Currency, L"CurrencyDataLoader::TryLoadDataFromWebOverrideAsync", L"UserRequestedRefreshFailed");
} }
co_return didLoad; co_return didLoad;
@ -747,21 +749,19 @@ void CurrencyDataLoader::UpdateDisplayedTimestamp()
} }
wstring CurrencyDataLoader::GetCurrencyTimestamp() wstring CurrencyDataLoader::GetCurrencyTimestamp()
{ {
wstring timestamp = L"";
DateTime epoch{}; DateTime epoch{};
if (m_cacheTimestamp.UniversalTime != epoch.UniversalTime) if (m_cacheTimestamp.UniversalTime != epoch.UniversalTime)
{ {
DateTimeFormatter ^ dateFormatter = ref new DateTimeFormatter(L"{month.abbreviated} {day.integer}, {year.full}"); DateTimeFormatter ^ dateFormatter = ref new DateTimeFormatter(L"shortdate");
wstring date = dateFormatter->Format(m_cacheTimestamp)->Data(); auto date = dateFormatter->Format(m_cacheTimestamp);
DateTimeFormatter ^ timeFormatter = ref new DateTimeFormatter(L"shorttime"); DateTimeFormatter ^ timeFormatter = ref new DateTimeFormatter(L"shorttime");
wstring time = timeFormatter->Format(m_cacheTimestamp)->Data(); auto time = timeFormatter->Format(m_cacheTimestamp);
timestamp = LocalizationStringUtil::GetLocalizedString(m_timestampFormat.c_str(), date.c_str(), time.c_str()); return LocalizationStringUtil::GetLocalizedString(m_timestampFormat, date, time)->Data();
} }
return timestamp; return L"";
} }
#pragma optimize("", off) // Turn off optimizations to work around DevDiv 393321 #pragma optimize("", off) // Turn off optimizations to work around DevDiv 393321

View File

@ -124,9 +124,9 @@ namespace CalculatorApp
std::shared_ptr<UCM::IViewModelCurrencyCallback> m_vmCallback; std::shared_ptr<UCM::IViewModelCurrencyCallback> m_vmCallback;
Windows::Globalization::NumberFormatting::DecimalFormatter ^ m_ratioFormatter; Windows::Globalization::NumberFormatting::DecimalFormatter ^ m_ratioFormatter;
std::wstring m_ratioFormat; Platform::String ^ m_ratioFormat;
Windows::Foundation::DateTime m_cacheTimestamp; Windows::Foundation::DateTime m_cacheTimestamp;
std::wstring m_timestampFormat; Platform::String ^ m_timestampFormat;
CurrencyLoadStatus m_loadStatus; CurrencyLoadStatus m_loadStatus;

View File

@ -953,7 +953,7 @@ void UnitConverterDataLoader::GetConversionData(_In_ unordered_map<ViewMode, uno
wstring UnitConverterDataLoader::GetLocalizedStringName(String ^ stringId) wstring UnitConverterDataLoader::GetLocalizedStringName(String ^ stringId)
{ {
return AppResourceProvider::GetInstance().GetResourceString(stringId)->Data(); return AppResourceProvider::GetInstance()->GetResourceString(stringId)->Data();
} }
void UnitConverterDataLoader::GetExplicitConversionData(_In_ unordered_map<int, unordered_map<int, UCM::ConversionData>>& unitToUnitConversionList) void UnitConverterDataLoader::GetExplicitConversionData(_In_ unordered_map<int, unordered_map<int, UCM::ConversionData>>& unitToUnitConversionList)

View File

@ -45,13 +45,13 @@ DateCalculatorViewModel::DateCalculatorViewModel()
, m_StrDateResult(L"") , m_StrDateResult(L"")
, m_StrDateResultAutomationName(L"") , m_StrDateResultAutomationName(L"")
{ {
const auto& localizationSettings = LocalizationSettings::GetInstance(); const auto & localizationSettings = LocalizationSettings::GetInstance();
// Initialize Date Output format instances // Initialize Date Output format instances
InitializeDateOutputFormats(localizationSettings.GetCalendarIdentifier()); InitializeDateOutputFormats(localizationSettings.GetCalendarIdentifier());
// Initialize Date Calc engine // Initialize Date Calc engine
m_dateCalcEngine = make_shared<DateCalculationEngine>(localizationSettings.GetCalendarIdentifier()); m_dateCalcEngine = ref new DateCalculationEngine(localizationSettings.GetCalendarIdentifier());
// Initialize dates of DatePicker controls to today's date // Initialize dates of DatePicker controls to today's date
auto calendar = ref new Calendar(); auto calendar = ref new Calendar();
// We force the timezone to UTC, in order to avoid being affected by Daylight Saving Time // We force the timezone to UTC, in order to avoid being affected by Daylight Saving Time
@ -111,20 +111,20 @@ void DateCalculatorViewModel::OnPropertyChanged(_In_ String ^ prop)
void DateCalculatorViewModel::OnInputsChanged() void DateCalculatorViewModel::OnInputsChanged()
{ {
DateDifference dateDiff;
if (m_IsDateDiffMode) if (m_IsDateDiffMode)
{ {
DateTime clippedFromDate = ClipTime(FromDate, true); DateTime clippedFromDate = ClipTime(FromDate, true);
DateTime clippedToDate = ClipTime(ToDate, true); DateTime clippedToDate = ClipTime(ToDate, true);
// Calculate difference between two dates // Calculate difference between two dates
if (m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat, &dateDiff)) auto dateDiff = m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat);
if (dateDiff != nullptr)
{ {
DateDiffResultInDays = dateDiff; DateDiffResultInDays = dateDiff->Value;
if (m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat, &dateDiff)) dateDiff = m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat);
if (dateDiff != nullptr)
{ {
DateDiffResult = dateDiff; DateDiffResult = dateDiff->Value;
} }
else else
{ {
@ -140,26 +140,28 @@ void DateCalculatorViewModel::OnInputsChanged()
} }
else else
{ {
DateDifference dateDiff;
dateDiff.day = DaysOffset; dateDiff.day = DaysOffset;
dateDiff.month = MonthsOffset; dateDiff.month = MonthsOffset;
dateDiff.year = YearsOffset; dateDiff.year = YearsOffset;
DateTime dateTimeResult; IBox<DateTime> ^ dateTimeResult;
if (m_IsAddMode) if (m_IsAddMode)
{ {
// Add number of Days, Months and Years to a Date // Add number of Days, Months and Years to a Date
IsOutOfBound = !m_dateCalcEngine->AddDuration(StartDate, dateDiff, &dateTimeResult); dateTimeResult = m_dateCalcEngine->AddDuration(StartDate, dateDiff);
} }
else else
{ {
// Subtract number of Days, Months and Years from a Date // Subtract number of Days, Months and Years from a Date
IsOutOfBound = !m_dateCalcEngine->SubtractDuration(StartDate, dateDiff, &dateTimeResult); dateTimeResult = m_dateCalcEngine->SubtractDuration(StartDate, dateDiff);
} }
IsOutOfBound = dateTimeResult == nullptr;
if (!m_isOutOfBound) if (!m_isOutOfBound)
{ {
DateResult = dateTimeResult; DateResult = dateTimeResult->Value;
} }
} }
} }
@ -172,17 +174,16 @@ void DateCalculatorViewModel::UpdateDisplayResult()
{ {
IsDiffInDays = false; IsDiffInDays = false;
StrDateDiffResultInDays = L""; StrDateDiffResultInDays = L"";
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"CalculationFailed"); StrDateDiffResult = AppResourceProvider::GetInstance()->GetResourceString(L"CalculationFailed");
} }
else if (m_dateDiffResultInDays.day == 0) else if (m_dateDiffResultInDays.day == 0)
{ {
// to and from dates the same // to and from dates the same
IsDiffInDays = true; IsDiffInDays = true;
StrDateDiffResultInDays = L""; StrDateDiffResultInDays = L"";
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates"); StrDateDiffResult = AppResourceProvider::GetInstance()->GetResourceString(L"Date_SameDates");
} }
else if (m_dateDiffResult == DateDifferenceUnknown || else if (m_dateDiffResult == DateDifferenceUnknown || (m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0))
(m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0))
{ {
IsDiffInDays = true; IsDiffInDays = true;
StrDateDiffResultInDays = L""; StrDateDiffResultInDays = L"";
@ -206,7 +207,7 @@ void DateCalculatorViewModel::UpdateDisplayResult()
if (m_isOutOfBound) if (m_isOutOfBound)
{ {
// Display Date out of bound message // Display Date out of bound message
StrDateResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_OutOfBoundMessage"); StrDateResult = AppResourceProvider::GetInstance()->GetResourceString(L"Date_OutOfBoundMessage");
} }
else else
{ {
@ -218,16 +219,14 @@ void DateCalculatorViewModel::UpdateDisplayResult()
void DateCalculatorViewModel::UpdateStrDateDiffResultAutomationName() void DateCalculatorViewModel::UpdateStrDateDiffResultAutomationName()
{ {
String ^ automationFormat = AppResourceProvider::GetInstance().GetResourceString(L"Date_DifferenceResultAutomationName"); String ^ automationFormat = AppResourceProvider::GetInstance()->GetResourceString(L"Date_DifferenceResultAutomationName");
wstring localizedAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat->Data(), StrDateDiffResult->Data()); StrDateDiffResultAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat, StrDateDiffResult);
StrDateDiffResultAutomationName = ref new String(localizedAutomationName.c_str());
} }
void DateCalculatorViewModel::UpdateStrDateResultAutomationName() void DateCalculatorViewModel::UpdateStrDateResultAutomationName()
{ {
String ^ automationFormat = AppResourceProvider::GetInstance().GetResourceString(L"Date_ResultingDateAutomationName"); String ^ automationFormat = AppResourceProvider::GetInstance()->GetResourceString(L"Date_ResultingDateAutomationName");
wstring localizedAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat->Data(), StrDateResult->Data()); StrDateResultAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat, StrDateResult);
StrDateResultAutomationName = ref new String(localizedAutomationName.c_str());
} }
void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String ^ calendarIdentifier) void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String ^ calendarIdentifier)
@ -247,21 +246,21 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
{ {
wstring result; wstring result;
bool addDelimiter = false; bool addDelimiter = false;
AppResourceProvider resourceLoader = AppResourceProvider::GetInstance(); AppResourceProvider ^ resourceLoader = AppResourceProvider::GetInstance();
auto yearCount = m_dateDiffResult.year; auto yearCount = m_dateDiffResult.year;
if (yearCount > 0) if (yearCount > 0)
{ {
result += GetLocalizedNumberString(yearCount)->Data(); result += GetLocalizedNumberString(yearCount)->Data();
result += L" "; result += L' ';
if (yearCount > 1) if (yearCount > 1)
{ {
result += resourceLoader.GetResourceString(L"Date_Years")->Data(); result += resourceLoader->GetResourceString(L"Date_Years")->Data();
} }
else else
{ {
result += resourceLoader.GetResourceString(L"Date_Year")->Data(); result += resourceLoader->GetResourceString(L"Date_Year")->Data();
} }
// set the flags to add a delimiter whenever the next unit is added // set the flags to add a delimiter whenever the next unit is added
@ -281,15 +280,15 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
} }
result += GetLocalizedNumberString(monthCount)->Data(); result += GetLocalizedNumberString(monthCount)->Data();
result += L" "; result += L' ';
if (monthCount > 1) if (monthCount > 1)
{ {
result += resourceLoader.GetResourceString(L"Date_Months")->Data(); result += resourceLoader->GetResourceString(L"Date_Months")->Data();
} }
else else
{ {
result += resourceLoader.GetResourceString(L"Date_Month")->Data(); result += resourceLoader->GetResourceString(L"Date_Month")->Data();
} }
} }
@ -306,15 +305,15 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
} }
result += GetLocalizedNumberString(weekCount)->Data(); result += GetLocalizedNumberString(weekCount)->Data();
result += L" "; result += L' ';
if (weekCount > 1) if (weekCount > 1)
{ {
result += resourceLoader.GetResourceString(L"Date_Weeks")->Data(); result += resourceLoader->GetResourceString(L"Date_Weeks")->Data();
} }
else else
{ {
result += resourceLoader.GetResourceString(L"Date_Week")->Data(); result += resourceLoader->GetResourceString(L"Date_Week")->Data();
} }
} }
@ -331,15 +330,15 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
} }
result += GetLocalizedNumberString(dayCount)->Data(); result += GetLocalizedNumberString(dayCount)->Data();
result += L" "; result += L' ';
if (dayCount > 1) if (dayCount > 1)
{ {
result += resourceLoader.GetResourceString(L"Date_Days")->Data(); result += resourceLoader->GetResourceString(L"Date_Days")->Data();
} }
else else
{ {
result += resourceLoader.GetResourceString(L"Date_Day")->Data(); result += resourceLoader->GetResourceString(L"Date_Day")->Data();
} }
} }
@ -349,16 +348,16 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
String ^ DateCalculatorViewModel::GetDateDiffStringInDays() const String ^ DateCalculatorViewModel::GetDateDiffStringInDays() const
{ {
wstring result = GetLocalizedNumberString(m_dateDiffResultInDays.day)->Data(); wstring result = GetLocalizedNumberString(m_dateDiffResultInDays.day)->Data();
result += L" "; result += L' ';
// Display the result as '1 day' or 'N days' // Display the result as '1 day' or 'N days'
if (m_dateDiffResultInDays.day > 1) if (m_dateDiffResultInDays.day > 1)
{ {
result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Days")->Data(); result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Days")->Data();
} }
else else
{ {
result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Day")->Data(); result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Day")->Data();
} }
return ref new String(result.data()); return ref new String(result.data());

View File

@ -176,7 +176,7 @@ namespace CalculatorApp
CalculatorApp::Common::DateCalculation::DateDifference m_dateDiffResultInDays; CalculatorApp::Common::DateCalculation::DateDifference m_dateDiffResultInDays;
// Private members // Private members
std::shared_ptr<CalculatorApp::Common::DateCalculation::DateCalculationEngine> m_dateCalcEngine; CalculatorApp::Common::DateCalculation::DateCalculationEngine ^ m_dateCalcEngine;
CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat;
CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ m_dateTimeFormatter; Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ m_dateTimeFormatter;

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.
#include "pch.h" #include "pch.h"
@ -13,8 +13,8 @@ using namespace Platform;
HistoryItemViewModel::HistoryItemViewModel( HistoryItemViewModel::HistoryItemViewModel(
String ^ expression, String ^ expression,
String ^ result, String ^ result,
_In_ const shared_ptr<CalculatorVector<pair<wstring, int>>>& spTokens, _In_ const shared_ptr<vector<pair<wstring, int>>>& spTokens,
_In_ const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>>& spCommands) _In_ const shared_ptr<vector<shared_ptr<IExpressionCommand>>>& spCommands)
: m_expression(expression) : m_expression(expression)
, m_result(result) , m_result(result)
, m_spTokens(spTokens) , m_spTokens(spTokens)
@ -27,47 +27,17 @@ HistoryItemViewModel::HistoryItemViewModel(
String String
^ HistoryItemViewModel::GetAccessibleExpressionFromTokens( ^ HistoryItemViewModel::GetAccessibleExpressionFromTokens(
_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& spTokens, _In_ shared_ptr<vector<pair<wstring, int>>> const& spTokens,
_In_ String ^ fallbackExpression) _In_ String ^ fallbackExpression)
{ {
// updating accessibility names for expression and result // updating accessibility names for expression and result
wstringstream accExpression{}; wstringstream accExpression{};
accExpression << L""; accExpression << L"";
unsigned int nTokens; for (const auto& tokenItem : *spTokens)
HRESULT hr = spTokens->GetSize(&nTokens);
if (SUCCEEDED(hr))
{ {
pair<wstring, int> tokenItem; accExpression << LocalizationService::GetNarratorReadableToken(StringReference(tokenItem.first.c_str()))->Data();
for (unsigned int i = 0; i < nTokens; i++)
{
hr = spTokens->GetAt(i, &tokenItem);
if (FAILED(hr))
{
break;
}
wstring token = tokenItem.first;
accExpression << LocalizationService::GetNarratorReadableToken(StringReference(token.c_str()))->Data();
}
} }
if (SUCCEEDED(hr)) return ref new String(accExpression.str().c_str());
{
wstring expressionSuffix{};
hr = spTokens->GetExpressionSuffix(&expressionSuffix);
if (SUCCEEDED(hr))
{
accExpression << expressionSuffix;
}
}
if (FAILED(hr))
{
return LocalizationService::GetNarratorReadableString(fallbackExpression);
}
else
{
return ref new String(accExpression.str().c_str());
}
} }

View File

@ -3,7 +3,6 @@
#pragma once #pragma once
#include "CalcManager/CalculatorVector.h"
#include "CalcManager/ExpressionCommandInterface.h" #include "CalcManager/ExpressionCommandInterface.h"
namespace CalculatorApp namespace CalculatorApp
@ -17,15 +16,15 @@ namespace CalculatorApp
HistoryItemViewModel( HistoryItemViewModel(
Platform::String ^ expression, Platform::String ^ expression,
Platform::String ^ result, Platform::String ^ result,
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& spTokens, _In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& spTokens,
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& spCommands); _In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& spCommands);
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& GetTokens() std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& GetTokens()
{ {
return m_spTokens; return m_spTokens;
} }
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& GetCommands() std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& GetCommands()
{ {
return m_spCommands; return m_spCommands;
} }
@ -62,7 +61,7 @@ namespace CalculatorApp
private : static Platform::String private : static Platform::String
^ GetAccessibleExpressionFromTokens( ^ GetAccessibleExpressionFromTokens(
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& spTokens, _In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& spTokens,
_In_ Platform::String ^ fallbackExpression); _In_ Platform::String ^ fallbackExpression);
private: private:
@ -70,8 +69,8 @@ namespace CalculatorApp
Platform::String ^ m_accExpression; Platform::String ^ m_accExpression;
Platform::String ^ m_accResult; Platform::String ^ m_accResult;
Platform::String ^ m_result; Platform::String ^ m_result;
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_spTokens; std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands; std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
}; };
} }
} }

View File

@ -120,7 +120,7 @@ void HistoryViewModel::ShowItem(_In_ HistoryItemViewModel ^ e)
{ {
unsigned int index; unsigned int index;
Items->IndexOf(e, &index); Items->IndexOf(e, &index);
TraceLogger::GetInstance().LogHistoryItemLoad((ViewMode)m_currentMode, ItemSize, (int)(index)); TraceLogger::GetInstance()->LogHistoryItemLoad((ViewMode)m_currentMode, ItemSize, (int)(index));
HistoryItemClicked(e); HistoryItemClicked(e);
} }
@ -164,7 +164,11 @@ void HistoryViewModel::OnClearCommand(_In_ Platform::Object ^ e)
UpdateItemSize(); UpdateItemSize();
} }
MakeHistoryClearedNarratorAnnouncement(HistoryResourceKeys::HistoryCleared, m_localizedHistoryCleared); if (m_localizedHistoryCleared == nullptr)
{
m_localizedHistoryCleared = AppResourceProvider::GetInstance()->GetResourceString(HistoryResourceKeys::HistoryCleared);
}
HistoryAnnouncement = CalculatorAnnouncement::GetHistoryClearedAnnouncement(m_localizedHistoryCleared);
} }
} }
@ -263,16 +267,16 @@ void HistoryViewModel::ClearHistory()
void HistoryViewModel::SaveHistory() void HistoryViewModel::SaveHistory()
{ {
ApplicationDataContainer ^ historyContainer = GetHistoryContainer(m_currentMode); ApplicationDataContainer ^ historyContainer = GetHistoryContainer(m_currentMode);
auto currentHistoryVector = m_calculatorManager->GetHistoryItems(m_currentMode); auto const& currentHistoryVector = m_calculatorManager->GetHistoryItems(m_currentMode);
bool failure = false; bool failure = false;
int index = 0; int index = 0;
Platform::String ^ serializedHistoryItem; Platform::String ^ serializedHistoryItem;
for (auto iter = currentHistoryVector.begin(); iter != currentHistoryVector.end(); ++iter) for (auto const& item : currentHistoryVector)
{ {
try try
{ {
serializedHistoryItem = SerializeHistoryItem(*iter); serializedHistoryItem = SerializeHistoryItem(item);
historyContainer->Values->Insert(index.ToString(), serializedHistoryItem); historyContainer->Values->Insert(index.ToString(), serializedHistoryItem);
} }
catch (Platform::Exception ^) catch (Platform::Exception ^)
@ -370,10 +374,3 @@ void HistoryViewModel::UpdateItemSize()
{ {
ItemSize = Items->Size; ItemSize = Items->Size;
} }
void HistoryViewModel::MakeHistoryClearedNarratorAnnouncement(String ^ resourceKey, String ^ &formatVariable)
{
String ^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(resourceKey, formatVariable);
HistoryAnnouncement = CalculatorAnnouncement::GetHistoryClearedAnnouncement(announcement);
}

View File

@ -68,8 +68,6 @@ namespace CalculatorApp
void UpdateHistoryVectorLength(_In_ int newValue, _In_ CalculationManager::CALCULATOR_MODE cMode); void UpdateHistoryVectorLength(_In_ int newValue, _In_ CalculationManager::CALCULATOR_MODE cMode);
bool IsValid(_In_ CalculationManager::HISTORYITEM item); bool IsValid(_In_ CalculationManager::HISTORYITEM item);
void MakeHistoryClearedNarratorAnnouncement(Platform::String ^ resourceKey, Platform::String ^ &formatVariable);
friend class CalculatorDisplay; friend class CalculatorDisplay;
void UpdateItemSize(); void UpdateItemSize();
}; };

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@
#include "HistoryViewModel.h" #include "HistoryViewModel.h"
#include "MemoryItemViewModel.h" #include "MemoryItemViewModel.h"
#include "Common/BitLength.h" #include "Common/BitLength.h"
#include "Common/NumberBase.h"
namespace CalculatorFunctionalTests namespace CalculatorFunctionalTests
{ {
@ -19,7 +20,6 @@ namespace CalculatorFunctionalTests
namespace CalculatorUnitTests namespace CalculatorUnitTests
{ {
class MultiWindowUnitTests; class MultiWindowUnitTests;
class TimerTests;
} }
namespace CalculatorApp namespace CalculatorApp
@ -30,55 +30,64 @@ namespace CalculatorApp
namespace ViewModel namespace ViewModel
{ {
#define ASCII_0 48 #define ASCII_0 48
public public delegate void HideMemoryClickedHandler();
delegate void HideMemoryClickedHandler();
public public value struct ButtonInfo
delegate void ProgModeRadixChangeHandler(); {
NumbersAndOperatorsEnum buttonId;
bool canSendNegate;
};
[Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged [Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{ {
public: public:
StandardCalculatorViewModel(); StandardCalculatorViewModel();
void UpdateOperand(int pos, Platform::String ^ text); void UpdateOperand(int pos, Platform::String ^ text);
void UpdatecommandsInRecordingMode(); void UpdateCommandsInRecordingMode();
int GetNumberBase();
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged); OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
OBSERVABLE_PROPERTY_RW(Platform::String ^, DisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String ^, DisplayValue);
OBSERVABLE_PROPERTY_RW(HistoryViewModel ^, HistoryVM); OBSERVABLE_PROPERTY_R(HistoryViewModel ^, HistoryVM);
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError); OBSERVABLE_PROPERTY_RW(bool, IsAlwaysOnTop);
OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand); OBSERVABLE_PROPERTY_R(bool, IsBinaryBitFlippingEnabled);
OBSERVABLE_PROPERTY_RW(Platform::String ^, DisplayStringExpression); PROPERTY_R(bool, IsOperandUpdatedUsingViewModel);
PROPERTY_R(int, TokenPosition);
PROPERTY_R(bool, IsOperandTextCompletelySelected);
PROPERTY_R(bool, KeyPressed);
PROPERTY_R(Platform::String ^, SelectedExpressionLastData);
OBSERVABLE_NAMED_PROPERTY_R(bool, IsInError);
OBSERVABLE_PROPERTY_R(bool, IsOperatorCommand);
OBSERVABLE_PROPERTY_R(Platform::String ^, DisplayStringExpression);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Common::DisplayExpressionToken ^> ^, ExpressionTokens); OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Common::DisplayExpressionToken ^> ^, ExpressionTokens);
OBSERVABLE_PROPERTY_RW(Platform::String ^, DecimalDisplayValue); OBSERVABLE_PROPERTY_R(Platform::String ^, DecimalDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String ^, HexDisplayValue); OBSERVABLE_PROPERTY_R(Platform::String ^, HexDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String ^, OctalDisplayValue); OBSERVABLE_PROPERTY_R(Platform::String ^, OctalDisplayValue);
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String ^, BinaryDisplayValue); OBSERVABLE_NAMED_PROPERTY_R(Platform::String ^, BinaryDisplayValue);
OBSERVABLE_NAMED_PROPERTY_R(Windows::Foundation::Collections::IVector<bool> ^, BinaryDigits); OBSERVABLE_NAMED_PROPERTY_R(Windows::Foundation::Collections::IVector<bool> ^, BinaryDigits);
OBSERVABLE_PROPERTY_RW(Platform::String ^, HexDisplayValue_AutomationName); OBSERVABLE_PROPERTY_R(Platform::String ^, HexDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, DecDisplayValue_AutomationName); OBSERVABLE_PROPERTY_R(Platform::String ^, DecDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, OctDisplayValue_AutomationName); OBSERVABLE_PROPERTY_R(Platform::String ^, OctDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, BinDisplayValue_AutomationName); OBSERVABLE_PROPERTY_R(Platform::String ^, BinDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(bool, IsBinaryOperatorEnabled); OBSERVABLE_PROPERTY_R(bool, IsBinaryOperatorEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsUnaryOperatorEnabled); OBSERVABLE_PROPERTY_R(bool, IsUnaryOperatorEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsNegateEnabled); OBSERVABLE_PROPERTY_R(bool, IsNegateEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsCurrentViewPinned); OBSERVABLE_PROPERTY_R(bool, IsCurrentViewPinned);
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<MemoryItemViewModel ^> ^, MemorizedNumbers); OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IVector<MemoryItemViewModel ^> ^, MemorizedNumbers);
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty); OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty);
OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked); OBSERVABLE_PROPERTY_R(bool, IsFToEChecked);
OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled); OBSERVABLE_PROPERTY_R(bool, IsFToEEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked); OBSERVABLE_PROPERTY_R(bool, AreHEXButtonsEnabled);
OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled); OBSERVABLE_PROPERTY_R(Platform::String ^, CalculationResultAutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CalculationResultAutomationName); OBSERVABLE_PROPERTY_R(Platform::String ^, CalculationExpressionAutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CalculationExpressionAutomationName); OBSERVABLE_PROPERTY_R(bool, IsShiftProgrammerChecked);
OBSERVABLE_PROPERTY_RW(bool, IsShiftProgrammerChecked); OBSERVABLE_PROPERTY_R(CalculatorApp::Common::NumberBase, CurrentRadixType);
OBSERVABLE_PROPERTY_RW(int, CurrentRadixType); OBSERVABLE_PROPERTY_R(bool, AreTokensUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated); OBSERVABLE_PROPERTY_R(bool, AreAlwaysOnTopResultsUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreAlwaysOnTopResultsUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled); OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled);
OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled); OBSERVABLE_PROPERTY_R(bool, AreProgrammerRadixOperatorsEnabled);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement); OBSERVABLE_PROPERTY_R(bool, IsInputEmpty);
OBSERVABLE_PROPERTY_R(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement);
OBSERVABLE_PROPERTY_R(unsigned int, OpenParenthesisCount); OBSERVABLE_PROPERTY_R(unsigned int, OpenParenthesisCount);
COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand); COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand);
@ -90,23 +99,6 @@ namespace CalculatorApp
COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract); COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract);
event HideMemoryClickedHandler ^ HideMemoryClicked; event HideMemoryClickedHandler ^ HideMemoryClicked;
event ProgModeRadixChangeHandler ^ ProgModeRadixChange;
property bool IsShiftChecked
{
bool get()
{
return m_isShiftChecked;
}
void set(bool value)
{
if (m_isShiftChecked != value)
{
m_isShiftChecked = value;
RaisePropertyChanged(L"IsShiftChecked");
}
}
}
property bool IsBitFlipChecked property bool IsBitFlipChecked
{ {
@ -125,29 +117,8 @@ namespace CalculatorApp
} }
} }
} }
static property Platform::String ^ IsBitFlipCheckedPropertyName static property Platform::String
{ ^ IsBitFlipCheckedPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsBitFlipChecked"); } }
Platform::String ^ get()
{
return Platform::StringReference(L"IsBitFlipChecked");
}
}
property bool IsBinaryBitFlippingEnabled
{
bool get()
{
return m_isBinaryBitFlippingEnabled;
}
void set(bool value)
{
if (m_isBinaryBitFlippingEnabled != value)
{
m_isBinaryBitFlippingEnabled = value;
RaisePropertyChanged(L"IsBinaryBitFlippingEnabled");
}
}
}
property CalculatorApp::Common::BitLength ValueBitLength property CalculatorApp::Common::BitLength ValueBitLength
{ {
@ -226,29 +197,8 @@ namespace CalculatorApp
} }
} }
} }
static property Platform::String ^ IsProgrammerPropertyName static property Platform::String
{ ^ IsProgrammerPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsProgrammer"); } }
Platform::String ^ get()
{
return Platform::StringReference(L"IsProgrammer");
}
}
property bool IsAlwaysOnTop
{
bool get()
{
return m_isAlwaysOnTop;
}
void set(bool value)
{
if (m_isAlwaysOnTop != value)
{
m_isAlwaysOnTop = value;
RaisePropertyChanged(L"IsAlwaysOnTop");
}
}
}
property bool IsEditingEnabled property bool IsEditingEnabled
{ {
@ -300,65 +250,12 @@ namespace CalculatorApp
} }
} }
property int TokenPosition internal :
{ void OnPaste(Platform::String ^ pastedString);
int get()
{
return m_tokenPosition;
}
void set(int value)
{
m_tokenPosition = value;
}
}
property Platform::String^ SelectedExpressionLastData
{
Platform::String^ get() { return m_selectedExpressionLastData; }
void set(Platform::String^ value) { m_selectedExpressionLastData = value; }
}
property bool KeyPressed
{
bool get()
{
return m_keyPressed;
}
void set(bool value)
{
m_keyPressed = value;
}
}
property bool IsOperandUpdatedUsingViewModel
{
bool get()
{
return m_operandUpdated;
}
void set(bool value)
{
m_operandUpdated = value;
}
}
property bool IsOperandTextCompletelySelected
{
bool get()
{
return m_completeTextSelection;
}
void set(bool value)
{
m_completeTextSelection = value;
}
}
internal : void OnPaste(Platform::String ^ pastedString);
void OnCopyCommand(Platform::Object ^ parameter); void OnCopyCommand(Platform::Object ^ parameter);
void OnPasteCommand(Platform::Object ^ parameter); void OnPasteCommand(Platform::Object ^ parameter);
NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate); ButtonInfo MapCharacterToButtonId(char16 ch);
// Memory feature related methods. They are internal because they need to called from the MainPage code-behind // Memory feature related methods. They are internal because they need to called from the MainPage code-behind
void OnMemoryButtonPressed(); void OnMemoryButtonPressed();
@ -368,15 +265,8 @@ namespace CalculatorApp
void OnMemoryClear(_In_ Platform::Object ^ memoryItemPosition); void OnMemoryClear(_In_ Platform::Object ^ memoryItemPosition);
void OnPinUnpinCommand(Platform::Object ^ parameter); void OnPinUnpinCommand(Platform::Object ^ parameter);
void SetPrimaryDisplay(_In_ std::wstring const& displayString, _In_ bool isError); void OnInputChanged();
void DisplayPasteError(); void DisplayPasteError();
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 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_ unsigned int parenthesisCount); void SetParenthesisCount(_In_ unsigned int parenthesisCount);
void SetOpenParenthesisCountNarratorAnnouncement(); void SetOpenParenthesisCountNarratorAnnouncement();
void OnNoRightParenAdded(); void OnNoRightParenAdded();
@ -393,14 +283,11 @@ namespace CalculatorApp
void Recalculate(bool fromHistory = false); void Recalculate(bool fromHistory = false);
bool IsOperator(CalculationManager::Command cmdenum); bool IsOperator(CalculationManager::Command cmdenum);
void FtoEButtonToggled(); void FtoEButtonToggled();
void SwitchProgrammerModeBase(RADIX_TYPE calculatorBase); void SwitchProgrammerModeBase(CalculatorApp::Common::NumberBase calculatorBase);
void SetMemorizedNumbersString(); void SetMemorizedNumbersString();
void SwitchAngleType(NumbersAndOperatorsEnum num); void SwitchAngleType(NumbersAndOperatorsEnum num);
void ResetDisplay(); void ResetDisplay();
RADIX_TYPE GetCurrentRadixType()
{
return (RADIX_TYPE)m_CurrentRadixType;
}
void SetPrecision(int32_t precision); void SetPrecision(int32_t precision);
void UpdateMaxIntDigits() void UpdateMaxIntDigits()
{ {
@ -410,12 +297,21 @@ namespace CalculatorApp
{ {
return m_CurrentAngleType; return m_CurrentAngleType;
} }
void SelectHistoryItem(HistoryItemViewModel ^ item);
private: private:
void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers); void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers);
void UpdateProgrammerPanelDisplay(); void UpdateProgrammerPanelDisplay();
void HandleUpdatedOperandData(CalculationManager::Command cmdenum); void HandleUpdatedOperandData(CalculationManager::Command cmdenum);
void SetPrimaryDisplay(_In_ Platform::String ^ displayStringValue, _In_ bool isError);
void SetExpressionDisplay(
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands);
void SetHistoryExpressionDisplay(
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands);
void SetTokens(_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens);
NumbersAndOperatorsEnum ConvertIntegerToNumbersAndOperatorsEnum(unsigned int parameter); NumbersAndOperatorsEnum ConvertIntegerToNumbersAndOperatorsEnum(unsigned int parameter);
static RADIX_TYPE GetRadixTypeFromNumberBase(CalculatorApp::Common::NumberBase base);
NumbersAndOperatorsEnum m_CurrentAngleType; NumbersAndOperatorsEnum m_CurrentAngleType;
wchar_t m_decimalSeparator; wchar_t m_decimalSeparator;
CalculatorDisplay m_calculatorDisplay; CalculatorDisplay m_calculatorDisplay;
@ -443,15 +339,9 @@ namespace CalculatorApp
bool m_isStandard; bool m_isStandard;
bool m_isScientific; bool m_isScientific;
bool m_isProgrammer; bool m_isProgrammer;
bool m_isAlwaysOnTop;
bool m_isBinaryBitFlippingEnabled;
bool m_isBitFlipChecked; bool m_isBitFlipChecked;
bool m_isShiftChecked;
bool m_isRtlLanguage; bool m_isRtlLanguage;
int m_tokenPosition;
bool m_keyPressed;
bool m_operandUpdated; bool m_operandUpdated;
bool m_completeTextSelection;
bool m_isLastOperationHistoryLoad; bool m_isLastOperationHistoryLoad;
CalculatorApp::Common::BitLength m_valueBitLength; CalculatorApp::Common::BitLength m_valueBitLength;
Platform::String ^ m_selectedExpressionLastData; Platform::String ^ m_selectedExpressionLastData;
@ -473,15 +363,15 @@ namespace CalculatorApp
std::wstring AddPadding(std::wstring); std::wstring AddPadding(std::wstring);
size_t LengthWithoutPadding(std::wstring); size_t LengthWithoutPadding(std::wstring);
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_tokens; std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_tokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_commands; std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_commands;
// Token types // Token types
bool IsUnaryOp(int nOpCode); bool IsUnaryOp(CalculationManager::Command command);
bool IsBinOp(int nOpcode); bool IsBinOp(CalculationManager::Command command);
bool IsTrigOp(int nOpCode); bool IsTrigOp(CalculationManager::Command command);
bool IsOpnd(int nOpCode); bool IsOpnd(CalculationManager::Command command);
bool IsRecoverableCommand(int nOpCode); bool IsRecoverableCommand(CalculationManager::Command command);
CalculationManager::CommandType GetSelectedTokenType(_In_ unsigned int); CalculationManager::CommandType GetSelectedTokenType(_In_ unsigned int);
void SaveEditedCommand(_In_ unsigned int index, _In_ CalculationManager::Command command); void SaveEditedCommand(_In_ unsigned int index, _In_ CalculationManager::Command command);
@ -494,7 +384,6 @@ namespace CalculatorApp
friend class CalculatorDisplay; friend class CalculatorDisplay;
friend class CalculatorFunctionalTests::HistoryTests; friend class CalculatorFunctionalTests::HistoryTests;
friend class CalculatorUnitTests::MultiWindowUnitTests; friend class CalculatorUnitTests::MultiWindowUnitTests;
friend class CalculatorUnitTests::TimerTests;
}; };
} }
} }

View File

@ -137,12 +137,12 @@ UnitConverterViewModel::UnitConverterViewModel(const shared_ptr<UCM::IUnitConver
m_currencyMaxFractionDigits = m_currencyFormatter->FractionDigits; m_currencyMaxFractionDigits = m_currencyFormatter->FractionDigits;
auto resourceLoader = AppResourceProvider::GetInstance(); auto resourceLoader = AppResourceProvider::GetInstance();
m_localizedValueFromFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromFormat); m_localizedValueFromFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueFromFormat);
m_localizedValueToFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueToFormat); m_localizedValueToFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueToFormat);
m_localizedConversionResultFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ConversionResultFormat); m_localizedConversionResultFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ConversionResultFormat);
m_localizedValueFromDecimalFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromDecimalFormat); m_localizedValueFromDecimalFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueFromDecimalFormat);
m_localizedInputUnitName = resourceLoader.GetResourceString(UnitConverterResourceKeys::InputUnit_Name); m_localizedInputUnitName = resourceLoader->GetResourceString(UnitConverterResourceKeys::InputUnit_Name);
m_localizedOutputUnitName = resourceLoader.GetResourceString(UnitConverterResourceKeys::OutputUnit_Name); m_localizedOutputUnitName = resourceLoader->GetResourceString(UnitConverterResourceKeys::OutputUnit_Name);
Unit1AutomationName = m_localizedInputUnitName; Unit1AutomationName = m_localizedInputUnitName;
Unit2AutomationName = m_localizedOutputUnitName; Unit2AutomationName = m_localizedOutputUnitName;
@ -390,7 +390,7 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st
void UnitConverterViewModel::DisplayPasteError() void UnitConverterViewModel::DisplayPasteError()
{ {
String ^ errorMsg = AppResourceProvider::GetInstance().GetCEngineString(StringReference(SIDS_DOMAIN)); /*SIDS_DOMAIN is for "invalid input"*/ String ^ errorMsg = AppResourceProvider::GetInstance()->GetCEngineString(StringReference(SIDS_DOMAIN)); /*SIDS_DOMAIN is for "invalid input"*/
Value1 = errorMsg; Value1 = errorMsg;
Value2 = errorMsg; Value2 = errorMsg;
m_relocalizeStringOnSwitch = false; m_relocalizeStringOnSwitch = false;
@ -476,10 +476,10 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter)
return; return;
} }
static const vector<UCM::Command> OPERANDS = { UCM::Command::Zero, UCM::Command::One, UCM::Command::Two, UCM::Command::Three, UCM::Command::Four, static constexpr UCM::Command OPERANDS[] = { UCM::Command::Zero, UCM::Command::One, UCM::Command::Two, UCM::Command::Three, UCM::Command::Four,
UCM::Command::Five, UCM::Command::Six, UCM::Command::Seven, UCM::Command::Eight, UCM::Command::Nine }; UCM::Command::Five, UCM::Command::Six, UCM::Command::Seven, UCM::Command::Eight, UCM::Command::Nine };
if (find(begin(OPERANDS), end(OPERANDS), command) != OPERANDS.end()) if (find(begin(OPERANDS), end(OPERANDS), command) != end(OPERANDS))
{ {
if (m_isInputBlocked) if (m_isInputBlocked)
{ {
@ -494,7 +494,7 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter)
m_model->SendCommand(command); m_model->SendCommand(command);
TraceLogger::GetInstance().LogConverterInputReceived(Mode); TraceLogger::GetInstance()->LogConverterInputReceived(Mode);
} }
void UnitConverterViewModel::OnCopyCommand(Platform::Object ^ parameter) void UnitConverterViewModel::OnCopyCommand(Platform::Object ^ parameter)
@ -515,8 +515,10 @@ void UnitConverterViewModel::OnPasteCommand(Platform::Object ^ parameter)
// Ensure that the paste happens on the UI thread // Ensure that the paste happens on the UI thread
// EventWriteClipboardPaste_Start(); // EventWriteClipboardPaste_Start();
// Any converter ViewMode is fine here. // Any converter ViewMode is fine here.
CopyPasteManager::GetStringToPaste(m_Mode, NavCategory::GetGroupType(m_Mode))
.then([this](String ^ pastedString) { OnPaste(pastedString); }, concurrency::task_continuation_context::use_current()); auto that(this);
create_task(CopyPasteManager::GetStringToPaste(m_Mode, NavCategory::GetGroupType(m_Mode), NumberBase::Unknown, BitLength::BitLengthUnknown))
.then([that](String ^ pastedString) { that->OnPaste(pastedString); }, concurrency::task_continuation_context::use_current());
} }
void UnitConverterViewModel::InitializeView() void UnitConverterViewModel::InitializeView()
@ -650,7 +652,7 @@ void UnitConverterViewModel::OnCurrencyDataLoadFinished(bool didLoad)
ResetCategory(); 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);
Announcement = CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(announcement); Announcement = CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(announcement);
} }
@ -665,17 +667,18 @@ void UnitConverterViewModel::RefreshCurrencyRatios()
m_isCurrencyDataLoaded = false; m_isCurrencyDataLoaded = false;
IsCurrencyLoadingVisible = true; IsCurrencyLoadingVisible = true;
String ^ announcement = AppResourceProvider::GetInstance().GetResourceString(UnitConverterResourceKeys::UpdatingCurrencyRates); String ^ announcement = AppResourceProvider::GetInstance()->GetResourceString(UnitConverterResourceKeys::UpdatingCurrencyRates);
Announcement = CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(announcement); Announcement = CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(announcement);
auto refreshTask = create_task([this] { return m_model->RefreshCurrencyRatios().get(); }); auto that(this);
auto refreshTask = create_task([that] { return that->m_model->RefreshCurrencyRatios().get(); });
refreshTask.then( refreshTask.then(
[this](const pair<bool, wstring>& refreshResult) { [that](const pair<bool, wstring>& refreshResult) {
bool didLoad = refreshResult.first; bool didLoad = refreshResult.first;
wstring timestamp = refreshResult.second; wstring timestamp = refreshResult.second;
OnCurrencyTimestampUpdated(timestamp, false /*isWeekOldData*/); that->OnCurrencyTimestampUpdated(timestamp, false /*isWeekOldData*/);
OnCurrencyDataLoadFinished(didLoad); that->OnCurrencyDataLoadFinished(didLoad);
}, },
task_continuation_context::use_current()); task_continuation_context::use_current());
} }
@ -878,22 +881,22 @@ NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId(const wch
void UnitConverterViewModel::OnPaste(String ^ stringToPaste) void UnitConverterViewModel::OnPaste(String ^ stringToPaste)
{ {
// If pastedString is invalid("NoOp") then display pasteError else process the string // If pastedString is invalid("NoOp") then display pasteError else process the string
if (stringToPaste == StringReference(CopyPasteManager::PasteErrorString)) if (CopyPasteManager::IsErrorMessage(stringToPaste))
{ {
this->DisplayPasteError(); this->DisplayPasteError();
return; return;
} }
TraceLogger::GetInstance().LogInputPasted(Mode); TraceLogger::GetInstance()->LogInputPasted(Mode);
bool isFirstLegalChar = true; bool isFirstLegalChar = true;
bool sendNegate = false; bool sendNegate = false;
wstring accumulation = L""; wstring accumulation;
for (auto it = stringToPaste->Begin(); it != stringToPaste->End(); it++) for (const auto ch : stringToPaste)
{ {
bool canSendNegate = false; bool canSendNegate = false;
NumbersAndOperatorsEnum op = MapCharacterToButtonId(*it, canSendNegate); NumbersAndOperatorsEnum op = MapCharacterToButtonId(ch, canSendNegate);
if (NumbersAndOperatorsEnum::None != op) if (NumbersAndOperatorsEnum::None != op)
{ {
@ -929,7 +932,7 @@ void UnitConverterViewModel::OnPaste(String ^ stringToPaste)
} }
} }
accumulation += *it; accumulation += ch;
UpdateInputBlocked(accumulation); UpdateInputBlocked(accumulation);
if (m_isInputBlocked) if (m_isInputBlocked)
{ {
@ -954,8 +957,7 @@ String ^ UnitConverterViewModel::GetLocalizedAutomationName(_In_ String ^ displa
format = m_localizedValueFromDecimalFormat; format = m_localizedValueFromDecimalFormat;
} }
wstring localizedResult = LocalizationStringUtil::GetLocalizedString(format->Data(), displayvalue->Data(), unitname->Data()); return LocalizationStringUtil::GetLocalizedString(format, displayvalue, unitname);
return ref new String(localizedResult.c_str());
} }
String String
@ -965,11 +967,7 @@ String
_In_ String ^ toValue, _In_ String ^ toValue,
_In_ String ^ toUnit) _In_ String ^ toUnit)
{ {
String ^ localizedString = return LocalizationStringUtil::GetLocalizedString(m_localizedConversionResultFormat, fromValue, fromUnit, toValue, toUnit);
ref new String(LocalizationStringUtil::GetLocalizedString(
m_localizedConversionResultFormat->Data(), fromValue->Data(), fromUnit->Data(), toValue->Data(), toUnit->Data())
.c_str());
return localizedString;
} }
void UnitConverterViewModel::UpdateValue1AutomationName() void UnitConverterViewModel::UpdateValue1AutomationName()
@ -990,9 +988,9 @@ void UnitConverterViewModel::UpdateValue2AutomationName()
void UnitConverterViewModel::OnMaxDigitsReached() void UnitConverterViewModel::OnMaxDigitsReached()
{ {
String ^ format = AppResourceProvider::GetInstance().GetResourceString(UnitConverterResourceKeys::MaxDigitsReachedFormat); String ^ format = AppResourceProvider::GetInstance()->GetResourceString(UnitConverterResourceKeys::MaxDigitsReachedFormat);
const wstring& announcement = LocalizationStringUtil::GetLocalizedString(format->Data(), m_lastAnnouncedConversionResult->Data()); auto announcement = LocalizationStringUtil::GetLocalizedString(format, m_lastAnnouncedConversionResult);
Announcement = CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(StringReference(announcement.c_str())); Announcement = CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(announcement);
} }
bool UnitConverterViewModel::UnitsAreValid() bool UnitConverterViewModel::UnitsAreValid()
@ -1002,17 +1000,18 @@ bool UnitConverterViewModel::UnitsAreValid()
void UnitConverterViewModel::StartConversionResultTimer() void UnitConverterViewModel::StartConversionResultTimer()
{ {
m_conversionResultTaskHelper = make_unique<ConversionResultTaskHelper>(CONVERSION_FINALIZED_DELAY_IN_MS, [this]() { auto that(this);
if (UnitsAreValid()) m_conversionResultTaskHelper = make_unique<ConversionResultTaskHelper>(CONVERSION_FINALIZED_DELAY_IN_MS, [that]() {
if (that->UnitsAreValid())
{ {
String ^ valueFrom = m_Value1Active ? m_Value1 : m_Value2; String ^ valueFrom = that->m_Value1Active ? that->m_Value1 : that->m_Value2;
String ^ valueTo = m_Value1Active ? m_Value2 : m_Value1; String ^ valueTo = that->m_Value1Active ? that->m_Value2 : that->m_Value1;
} }
}); });
} }
String ^ SupplementaryResult::GetLocalizedAutomationName() String ^ SupplementaryResult::GetLocalizedAutomationName()
{ {
auto format = AppResourceProvider::GetInstance().GetResourceString("SupplementaryUnit_AutomationName"); auto format = AppResourceProvider::GetInstance()->GetResourceString("SupplementaryUnit_AutomationName");
return ref new String(LocalizationStringUtil::GetLocalizedString(format->Data(), this->Value->Data(), this->Unit->Name->Data()).c_str()); return LocalizationStringUtil::GetLocalizedString(format, this->Value, this->Unit->Name);
} }

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Microsoft.UI.Xaml" version="2.0.181018003.1" targetFramework="native" /> <package id="Microsoft.UI.Xaml" version="2.2.190830001" targetFramework="native" />
</packages> </packages>

View File

@ -31,6 +31,8 @@
#include <regex> #include <regex>
#include <iterator> #include <iterator>
#include <intsafe.h> #include <intsafe.h>
#include <ppltasks.h>
// C++\WinRT Headers // C++\WinRT Headers
#include "winrt/base.h" #include "winrt/base.h"
#include "winrt/Windows.Foundation.Diagnostics.h" #include "winrt/Windows.Foundation.Diagnostics.h"

View File

@ -35,11 +35,11 @@ AboutFlyout::AboutFlyout()
this->SetVersionString(); this->SetVersionString();
Header->Text = resourceLoader.GetResourceString("AboutButton/Content"); Header->Text = resourceLoader->GetResourceString("AboutButton/Content");
auto copyrightText = auto copyrightText =
LocalizationStringUtil::GetLocalizedString(resourceLoader.GetResourceString("AboutControlCopyright")->Data(), to_wstring(BUILD_YEAR).c_str()); LocalizationStringUtil::GetLocalizedString(resourceLoader->GetResourceString("AboutControlCopyright"), StringReference(to_wstring(BUILD_YEAR).c_str()));
AboutControlCopyrightRun->Text = ref new String(copyrightText.c_str()); AboutControlCopyrightRun->Text = copyrightText;
} }
void AboutFlyout::FeedbackButton_Click(_In_ Object ^ sender, _In_ RoutedEventArgs ^ e) void AboutFlyout::FeedbackButton_Click(_In_ Object ^ sender, _In_ RoutedEventArgs ^ e)
@ -53,7 +53,7 @@ void AboutFlyout::FeedbackButton_Click(_In_ Object ^ sender, _In_ RoutedEventArg
void AboutFlyout::SetVersionString() void AboutFlyout::SetVersionString()
{ {
PackageVersion version = Package::Current->Id->Version; PackageVersion version = Package::Current->Id->Version;
String ^ appName = AppResourceProvider::GetInstance().GetResourceString(L"AppName"); String ^ appName = AppResourceProvider::GetInstance()->GetResourceString(L"AppName");
AboutFlyoutVersion->Text = appName + L" " + version.Major + L"." + version.Minor + L"." + version.Build + L"." + version.Revision; AboutFlyoutVersion->Text = appName + L" " + version.Major + L"." + version.Minor + L"." + version.Build + L"." + version.Revision;
} }

View File

@ -18,18 +18,37 @@
<x:Double x:Key="EquationButtonOverlayPressedOpacity">0.5</x:Double> <x:Double x:Key="EquationButtonOverlayPressedOpacity">0.5</x:Double>
<Color x:Key="AltHighColor">#FF000000</Color> <Color x:Key="AltHighColor">#FF000000</Color>
<Color x:Key="ChromeMediumLowColor">#FF2B2B2B</Color> <Color x:Key="ChromeMediumLowColor">#FF2B2B2B</Color>
<Color x:Key="OperatorPanelScrollButtonBackgroundColor">#FF858585</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="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"/>
<SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemAltMediumLowColor}"/> <SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppOperatorPanelBackground"
Opacity="0.4"
Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{StaticResource SystemBaseMediumHighColor}"/> <SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{StaticResource SystemBaseMediumHighColor}"/>
<RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush" Color="#18FFFFFF"/> <RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush"
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush" Color="#30FFFFFF"/> FallbackColor="#18FFFFFF"
Color="#18FFFFFF"/>
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush"
FallbackColor="#30FFFFFF"
Color="#30FFFFFF"/>
<SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="{ThemeResource SystemAccentColor}"/> <SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{StaticResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="AppControlForegroundAccentBrush" Color="{ThemeResource SystemAccentColor}"/> <SolidColorBrush x:Key="OperatorPanelScrollButtonBackgroundBrush" Color="{ThemeResource OperatorPanelScrollButtonBackgroundColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonBrush"
Opacity="0.4"
Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonToggledBrush"
Opacity="0.4"
Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonHoverBrush"
Opacity="0.9"
Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="Red"/> <SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="Red"/>
<RevealBorderBrush x:Key="AppControlForegroundTransparentRevealBorderBrush" <RevealBorderBrush x:Key="AppControlForegroundTransparentRevealBorderBrush"
FallbackColor="Transparent" FallbackColor="Transparent"
@ -48,9 +67,10 @@
FallbackColor="{ThemeResource SystemChromeMediumColor}" FallbackColor="{ThemeResource SystemChromeMediumColor}"
TintColor="{ThemeResource SystemChromeLowColor}" TintColor="{ThemeResource SystemChromeLowColor}"
TintOpacity="0.7"/> TintOpacity="0.7"/>
<SolidColorBrush x:Key="EquationTextBoxTransparentBackgroundBrush" Color="Transparent"/>
<SolidColorBrush x:Key="EquationBoxPointerOverBackgroundBrush" Color="{ThemeResource SystemControlBackgroundAltMediumBrush}"/> <SolidColorBrush x:Key="EquationBoxPointerOverBackgroundBrush" Color="{ThemeResource SystemControlBackgroundAltMediumBrush}"/>
<SolidColorBrush x:Key="EquationBoxHoverButtonForegroundBrush" Color="{ThemeResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="EquationBoxHoverButtonForegroundBrush" Color="{ThemeResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="AppChromeAcrylicOperatorFlyoutBackgroundBrush" Color="#FF2F2F2F"/>
<SolidColorBrush x:Key="EquationTextBoxTransparentBackgroundBrush" Color="Transparent"/>
<SolidColorBrush x:Key="EquationBoxBorderBrush" Color="{ThemeResource TextControlBackground}"/> <SolidColorBrush x:Key="EquationBoxBorderBrush" Color="{ThemeResource TextControlBackground}"/>
<SolidColorBrush x:Key="EquationButtonOverlayBackgroundBrush" Color="White"/> <SolidColorBrush x:Key="EquationButtonOverlayBackgroundBrush" Color="White"/>
<SolidColorBrush x:Key="EquationButtonHideLineBackgroundBrush" <SolidColorBrush x:Key="EquationButtonHideLineBackgroundBrush"
@ -77,6 +97,7 @@
<SolidColorBrush x:Key="EquationBrush14" Color="#FF018574"/> <SolidColorBrush x:Key="EquationBrush14" Color="#FF018574"/>
<SolidColorBrush x:Key="EquationBrush15" Color="#FF10893E"/> <SolidColorBrush x:Key="EquationBrush15" Color="#FF10893E"/>
<SolidColorBrush x:Key="EquationBrush16" Color="#FF000000"/> <SolidColorBrush x:Key="EquationBrush16" Color="#FF000000"/>
</ResourceDictionary> </ResourceDictionary>
<ResourceDictionary x:Key="Light"> <ResourceDictionary x:Key="Light">
<Thickness x:Key="HighContrastThicknessTop">0,0,0,0</Thickness> <Thickness x:Key="HighContrastThicknessTop">0,0,0,0</Thickness>
@ -85,19 +106,39 @@
<Color x:Key="ChromeMediumLowColor">#FFE0E0E0</Color> <Color x:Key="ChromeMediumLowColor">#FFE0E0E0</Color>
<x:Double x:Key="EquationButtonOverlayPointerOverOpacity">0.2</x:Double> <x:Double x:Key="EquationButtonOverlayPointerOverOpacity">0.2</x:Double>
<x:Double x:Key="EquationButtonOverlayPressedOpacity">0.4</x:Double> <x:Double x:Key="EquationButtonOverlayPressedOpacity">0.4</x:Double>
<Color x:Key="OperatorPanelScrollButtonBackgroundColor">#FF858585</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="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"/>
<SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemAltMediumLowColor}"/> <SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppOperatorPanelBackground"
Opacity="0.4"
Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{StaticResource SystemBaseMediumHighColor}"/> <SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{StaticResource SystemBaseMediumHighColor}"/>
<RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush" Color="#17000000"/> <RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush"
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush" Color="#30000000"/> FallbackColor="#17000000"
Color="#17000000"/>
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush"
FallbackColor="#30000000"
Color="#30000000"/>
<SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="{ThemeResource SystemAccentColor}"/> <SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{StaticResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="OperatorPanelScrollButtonBackgroundBrush" Color="{ThemeResource OperatorPanelScrollButtonBackgroundColor}"/>
<SolidColorBrush x:Key="AppControlForegroundAccentBrush" Color="{ThemeResource SystemAccentColor}"/> <SolidColorBrush x:Key="AppControlForegroundAccentBrush" Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="Red"/> <SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="Red"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonBrush"
Opacity="0.4"
Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonToggledBrush"
Opacity="0.4"
Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonHoverBrush"
Opacity="0.7"
Color="{ThemeResource SystemAccentColor}"/>
<RevealBorderBrush x:Key="AppControlForegroundTransparentRevealBorderBrush" <RevealBorderBrush x:Key="AppControlForegroundTransparentRevealBorderBrush"
FallbackColor="Transparent" FallbackColor="Transparent"
TargetTheme="Light" TargetTheme="Light"
@ -115,6 +156,11 @@
FallbackColor="{ThemeResource SystemChromeMediumColor}" FallbackColor="{ThemeResource SystemChromeMediumColor}"
TintColor="{ThemeResource SystemChromeLowColor}" TintColor="{ThemeResource SystemChromeLowColor}"
TintOpacity="0.7"/> TintOpacity="0.7"/>
<AcrylicBrush x:Key="AppChromeAcrylicOperatorFlyoutBackgroundBrush"
BackgroundSource="HostBackdrop"
FallbackColor="{ThemeResource SystemChromeMediumColor}"
TintColor="{ThemeResource SystemChromeLowColor}"
TintOpacity="0.8"/>
<SolidColorBrush x:Key="EquationBoxPointerOverBackgroundBrush" Color="{ThemeResource SystemControlBackgroundAltMediumBrush}"/> <SolidColorBrush x:Key="EquationBoxPointerOverBackgroundBrush" Color="{ThemeResource SystemControlBackgroundAltMediumBrush}"/>
<SolidColorBrush x:Key="EquationBoxHoverButtonForegroundBrush" Color="{ThemeResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="EquationBoxHoverButtonForegroundBrush" Color="{ThemeResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="EquationBoxBorderBrush" Color="{ThemeResource TextControlBackground}"/> <SolidColorBrush x:Key="EquationBoxBorderBrush" Color="{ThemeResource TextControlBackground}"/>
@ -153,11 +199,13 @@
<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}"/>
<SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppOperatorPanelBackground" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{ThemeResource SystemColorWindowTextColor}"/> <SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<SolidColorBrush x:Key="AppControlHoverButtonFaceBrush" Color="{ThemeResource SystemColorHighlightColor}"/> <SolidColorBrush x:Key="AppControlHoverButtonFaceBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="AppControlPressedButtonFaceBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="AppControlPressedButtonFaceBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="Transparent"/> <SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="Transparent"/>
<SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/> <SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<SolidColorBrush x:Key="OperatorPanelScrollButtonBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppControlForegroundAccentBrush" Color="{ThemeResource SystemColorButtonTextColor}"/> <SolidColorBrush x:Key="AppControlForegroundAccentBrush" Color="{ThemeResource SystemColorButtonTextColor}"/>
<SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/> <SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<SolidColorBrush x:Key="AppControlForegroundTransparentRevealBorderBrush" Color="{ThemeResource SystemColorButtonTextColor}"/> <SolidColorBrush x:Key="AppControlForegroundTransparentRevealBorderBrush" Color="{ThemeResource SystemColorButtonTextColor}"/>
@ -165,9 +213,13 @@
<SolidColorBrush x:Key="AppControlBackgroundListAccentHighRevealBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="AppControlBackgroundListAccentHighRevealBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppControlListLowRevealHighlightBrush" Color="{ThemeResource SystemColorHighlightColor}"/> <SolidColorBrush x:Key="AppControlListLowRevealHighlightBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="AppChromeAcrylicHostBackdropMediumLowBrush" Color="{ThemeResource SystemColorWindowColor}"/> <SolidColorBrush x:Key="AppChromeAcrylicHostBackdropMediumLowBrush" Color="{ThemeResource SystemColorWindowColor}"/>
<SolidColorBrush x:Key="EquationBoxBorderBrush" Color="{ThemeResource SystemColorButtonTextColor}"/> <SolidColorBrush x:Key="AppChromeAcrylicOperatorFlyoutBackgroundBrush" Color="{ThemeResource SystemColorWindowColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonBrush" Color="{ThemeResource SystemColorWindowColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonToggledBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="AppControlHighlightCalcButtonHoverBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="EquationBoxPointerOverBackgroundBrush" Color="{ThemeResource SystemColorHighlightColor}"/> <SolidColorBrush x:Key="EquationBoxPointerOverBackgroundBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="EquationBoxHoverButtonForegroundBrush" Color="{ThemeResource SystemColorButtonTextColor}"/> <SolidColorBrush x:Key="EquationBoxHoverButtonForegroundBrush" Color="{ThemeResource SystemColorCaptionTextColor}"/>
<SolidColorBrush x:Key="EquationBoxBorderBrush" Color="{ThemeResource SystemColorButtonTextColor}"/>
<SolidColorBrush x:Key="AppControlTransparentButtonBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="AppControlTransparentButtonBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="EquationButtonHideLineBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="EquationButtonHideLineBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="EquationButtonOverlayBackgroundBrush" Color="Transparent"/> <SolidColorBrush x:Key="EquationButtonOverlayBackgroundBrush" Color="Transparent"/>
@ -191,6 +243,21 @@
<x:Double x:Key="PivotHeaderItemFontSize">15</x:Double> <x:Double x:Key="PivotHeaderItemFontSize">15</x:Double>
<FontWeight x:Key="PivotHeaderItemThemeFontWeight">SemiBold</FontWeight> <FontWeight x:Key="PivotHeaderItemThemeFontWeight">SemiBold</FontWeight>
<x:Double x:Key="OperatorPanelButtonRowSizeLarge">64</x:Double>
<x:Double x:Key="OperatorPanelFontSizeLarge">24</x:Double>
<x:Double x:Key="OperatorPanelGlyphFontSizeLarge">24</x:Double>
<x:Double x:Key="OperatorPanelChevronFontSizeLarge">16</x:Double>
<x:Double x:Key="OperatorPanelButtonRowSizeMedium">64</x:Double>
<x:Double x:Key="OperatorPanelFontSizeMedium">16</x:Double>
<x:Double x:Key="OperatorPanelGlyphFontSizeMedium">20</x:Double>
<x:Double x:Key="OperatorPanelChevronFontSizeMedium">10</x:Double>
<x:Double x:Key="OperatorPanelButtonRowSizeSmall">38</x:Double>
<x:Double x:Key="OperatorPanelFontSizeSmall">12</x:Double>
<x:Double x:Key="OperatorPanelGlyphFontSizeSmall">16</x:Double>
<x:Double x:Key="OperatorPanelChevronFontSizeSmall">8</x:Double>
<x:Double x:Key="CaptionFontSize">12</x:Double> <x:Double x:Key="CaptionFontSize">12</x:Double>
<x:Double x:Key="BodyFontSize">15</x:Double> <x:Double x:Key="BodyFontSize">15</x:Double>
<x:Double x:Key="TitleFontSize">24</x:Double> <x:Double x:Key="TitleFontSize">24</x:Double>
@ -200,13 +267,17 @@
<GridLength x:Key="HamburgerHeightGridLength">40</GridLength> <GridLength x:Key="HamburgerHeightGridLength">40</GridLength>
<x:Double x:Key="CalcButtonCaptionSize">34</x:Double> <x:Double x:Key="CalcButtonCaptionSize">34</x:Double>
<x:Double x:Key="CalcButtonTextIconCaptionSize">38</x:Double>
<x:Double x:Key="CalcStandardOperatorCaptionSizeExtraLarge">48</x:Double>
<x:Double x:Key="CalcStandardOperatorCaptionSizeLarge">24</x:Double> <x:Double x:Key="CalcStandardOperatorCaptionSizeLarge">24</x:Double>
<!-- Numpad Standard/Scientific in Fill/Full --> <!-- Numpad Standard/Scientific in Fill/Full -->
<x:Double x:Key="CalcStandardOperatorCaptionSize">20</x:Double> <x:Double x:Key="CalcStandardOperatorCaptionSize">20</x:Double>
<x:Double x:Key="CalcStandardOperatorTextIconCaptionSize">22</x:Double>
<x:Double x:Key="CalcStandardOperatorCaptionSizeSmall">15</x:Double> <x:Double x:Key="CalcStandardOperatorCaptionSizeSmall">15</x:Double>
<x:Double x:Key="CalcStandardOperatorCaptionSizeTiny">12</x:Double> <x:Double x:Key="CalcStandardOperatorCaptionSizeTiny">12</x:Double>
<!-- Standard Operators Standard/Scientific in Fill/Full --> <!-- Standard Operators Standard/Scientific in Fill/Full -->
<x:Double x:Key="CalcOperatorCaptionSize">15</x:Double> <x:Double x:Key="CalcOperatorCaptionSize">14</x:Double>
<x:Double x:Key="CalcOperatorTextIconCaptionSize">16</x:Double>
<!-- Base style for calc buttons --> <!-- Base style for calc buttons -->
<Style x:Key="CalcButtonStyle" TargetType="Controls:CalculatorButton"> <Style x:Key="CalcButtonStyle" TargetType="Controls:CalculatorButton">
@ -263,7 +334,6 @@
<VisualState x:Name="KeyBoardEntry"/> <VisualState x:Name="KeyBoardEntry"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -297,6 +367,11 @@
TargetType="Controls:CalculatorButton"> TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="12"/> <Setter Property="FontSize" Value="12"/>
</Style> </Style>
<Style x:Key="NumericButtonStyle14"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="14"/>
</Style>
<Style x:Key="NumericButtonStyle16" <Style x:Key="NumericButtonStyle16"
BasedOn="{StaticResource NumericButtonStyle}" BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton"> TargetType="Controls:CalculatorButton">
@ -322,11 +397,28 @@
TargetType="Controls:CalculatorButton"> TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="34"/> <Setter Property="FontSize" Value="34"/>
</Style> </Style>
<Style x:Key="NumericButtonStyle38"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="38"/>
</Style>
<Style x:Key="NumericButtonStyle46" <Style x:Key="NumericButtonStyle46"
BasedOn="{StaticResource NumericButtonStyle}" BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton"> TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="46"/> <Setter Property="FontSize" Value="46"/>
</Style> </Style>
<Style x:Key="NumericButtonStyle48"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="48"/>
</Style>
<Style x:Key="SymbolOperatorKeypadButtonStyle"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="FontFamily" Value="{StaticResource CalculatorFontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
</Style>
<Style x:Key="OperatorButtonStyle" <Style x:Key="OperatorButtonStyle"
BasedOn="{StaticResource CalcButtonStyle}" BasedOn="{StaticResource CalcButtonStyle}"
@ -384,7 +476,6 @@
<VisualState x:Name="KeyBoardEntry"/> <VisualState x:Name="KeyBoardEntry"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -412,13 +503,33 @@
</Setter> </Setter>
</Style> </Style>
<Style x:Key="AccentCalcButtonStyle" <Style x:Key="AccentEmphasizedCalcButtonStyle"
BasedOn="{StaticResource SymbolOperatorButtonStyle}" BasedOn="{StaticResource SymbolOperatorButtonStyle}"
TargetType="Controls:CalculatorButton"> TargetType="Controls:CalculatorButton">
<Setter Property="HoverBackground" Value="{ThemeResource AppControlHighlightAccentRevealBackgroundBrush}"/> <Setter Property="HoverBackground" Value="{ThemeResource AppControlHighlightCalcButtonHoverBrush}"/>
<Setter Property="HoverForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/> <Setter Property="HoverForeground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="PressBackground" Value="{ThemeResource AppControlBackgroundListAccentHighRevealBackgroundBrush}"/> <Setter Property="PressBackground" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
<Setter Property="PressForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/> <Setter Property="PressForeground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource AppControlHighlightCalcButtonBrush}"/>
</Style>
<Style x:Key="EmphasizedCalcButtonStyle"
BasedOn="{StaticResource SymbolOperatorButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="HoverBackground" Value="{ThemeResource AppControlHighlightCalcButtonHoverBrush}"/>
<Setter Property="HoverForeground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="PressBackground" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
<Setter Property="PressForeground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
</Style>
<Style x:Key="AccentEmphasizedOperatorCalcButtonStyle"
BasedOn="{StaticResource OperatorButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="HoverBackground" Value="{ThemeResource AppControlHighlightCalcButtonHoverBrush}"/>
<Setter Property="HoverForeground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="PressBackground" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
<Setter Property="PressForeground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource AppControlHighlightCalcButtonBrush}"/>
</Style> </Style>
<!-- RESULTS --> <!-- RESULTS -->
@ -532,6 +643,123 @@
</Setter> </Setter>
</Style> </Style>
<Style x:Key="OperatorPanelButtonStyle" TargetType="Controls:OperatorPanelButton">
<Setter Property="FontSize" Value="{StaticResource CaptionFontSize}"/>
<Setter Property="GlyphFontSize" Value="{StaticResource CaptionFontSize}"/>
<Setter Property="ChevronFontSize" Value="{StaticResource CaptionFontSize}"/>
<Setter Property="Padding" Value="8,0,8,0"/>
<Setter Property="MinWidth" Value="32"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:OperatorPanelButton">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="RootGrid.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlHoverButtonFaceBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="RootGrid.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlPressedButtonFaceBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
<Setter Target="ContentPresenter.BorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlPressedButtonFaceBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="CheckedPointerOver">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlPressedButtonFaceBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="CheckedPressed">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlPressedButtonFaceBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="CheckedDisabled">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
<Setter Target="ContentPresenter.BorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="Sizing">
<VisualState x:Name="NormalSize">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="SmallSize">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
BorderBrush="{ThemeResource AppControlForegroundTransparentRevealBorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
FontSize="{TemplateBinding FontSize}"
FontWeight="Normal"
AutomationProperties.AccessibilityView="Raw"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}">
<StackPanel Orientation="Horizontal">
<FontIcon Margin="0,2,8,0"
VerticalAlignment="Center"
FontFamily="{StaticResource CalculatorFontFamily}"
FontSize="{TemplateBinding GlyphFontSize}"
Glyph="{TemplateBinding Glyph}"/>
<TextBlock x:Name="trigTextBlock"
VerticalAlignment="Center"
FontSize="{TemplateBinding FontSize}"
Text="{TemplateBinding Text}"/>
<FontIcon Margin="8,4,0,0"
VerticalAlignment="Center"
FontFamily="{StaticResource CalculatorFontFamily}"
FontSize="{TemplateBinding ChevronFontSize}"
Glyph="&#xE70D;"/>
</StackPanel>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CaptionButtonStyle" TargetType="Button"> <Style x:Key="CaptionButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/> <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/> <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
@ -574,7 +802,6 @@
</VisualState> </VisualState>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -632,7 +859,6 @@
</VisualState> </VisualState>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -738,7 +964,6 @@
</VisualState> </VisualState>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<Border x:Name="SelectionBorder" BorderThickness="0,0,0,2"/> <Border x:Name="SelectionBorder" BorderThickness="0,0,0,2"/>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
@ -768,6 +993,98 @@
<Setter Property="MinHeight" Value="0"/> <Setter Property="MinHeight" Value="0"/>
</Style> </Style>
<Style x:Key="CaptionToggleEmphasizedButtonStyle"
BasedOn="{StaticResource CaptionToggleButtonStyle}"
TargetType="ToggleButton">
<Setter Property="Background" Value="{ThemeResource AppBackgroundAltMediumLowBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlHoverButtonFaceBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlPressedButtonFaceBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
<Setter Target="ContentPresenter.BorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlHighlightCalcButtonToggledBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="CheckedPointerOver">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlHighlightCalcButtonHoverBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="CheckedPressed">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="RootGrid.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="CheckedDisabled">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
<Setter Target="ContentPresenter.BorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="Sizing">
<VisualState x:Name="NormalSize">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="SmallSize">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
BorderBrush="{ThemeResource AppControlForegroundTransparentRevealBorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ProgWordSizeButtonStyle" <Style x:Key="ProgWordSizeButtonStyle"
BasedOn="{StaticResource CaptionButtonStyle}" BasedOn="{StaticResource CaptionButtonStyle}"
TargetType="Button"> TargetType="Button">
@ -802,7 +1119,6 @@
</VisualState> </VisualState>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -983,7 +1299,6 @@
</VisualState> </VisualState>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -1060,7 +1375,6 @@
</VisualState> </VisualState>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" <ContentPresenter x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -1163,6 +1477,147 @@
</Setter> </Setter>
</Style> </Style>
<Style x:Key="OperatorPanelFlyoutStyle" TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="1"/>
<Setter Property="Background" Value="{ThemeResource AppChromeAcrylicOperatorFlyoutBackgroundBrush}"/>
<Setter Property="Margin" Value="0,-3,0,0"/>
<Setter Property="MaxWidth" Value="Infinity"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="FlyoutPresenter">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Controls:OperatorPanelListView">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="TabNavigation" Value="Once"/>
<Setter Property="IsSwipeEnabled" Value="True"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="SelectionMode" Value="None"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled"/>
<Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False"/>
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled"/>
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="False"/>
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
<Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
<Setter Property="ItemContainerTransitions">
<Setter.Value>
<TransitionCollection>
<AddDeleteThemeTransition/>
<ContentThemeTransition/>
<ReorderThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Height="Auto"
VerticalAlignment="Stretch"
Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListViewItem">
<Setter Property="MinHeight" Value="0"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:OperatorPanelListView">
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid x:Name="Grid">
<Grid.Resources>
<SolidColorBrush x:Key="ButtonBackgroundPointerOver" Color="{ThemeResource OperatorPanelScrollButtonBackgroundColor}"/>
<SolidColorBrush x:Key="ButtonBackgroundPressed" Color="{ThemeResource OperatorPanelScrollButtonBackgroundColor}"/>
<SolidColorBrush x:Key="ButtonForegroundPointerOver" Color="{ThemeResource SystemAltMediumHighColor}"/>
<SolidColorBrush x:Key="ButtonBorderBrushPointerOver" Color="{ThemeResource SystemBaseMediumLowColor}"/>
<SolidColorBrush x:Key="ButtonForegroundPressed" Color="{ThemeResource SystemAltMediumHighColor}"/>
</Grid.Resources>
<Grid.ColumnDefinitions/>
<ScrollViewer x:Name="ScrollViewer"
AutomationProperties.AccessibilityView="Raw"
BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}"
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}"
TabNavigation="{TemplateBinding TabNavigation}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ItemsPresenter x:Name="Content"
Padding="{TemplateBinding Padding}"
Footer="{TemplateBinding Footer}"
FooterTemplate="{TemplateBinding FooterTemplate}"
FooterTransitions="{TemplateBinding FooterTransitions}"
Header="{TemplateBinding Header}"
HeaderTemplate="{TemplateBinding HeaderTemplate}"
HeaderTransitions="{TemplateBinding HeaderTransitions}"/>
</ScrollViewer>
<Button x:Name="ScrollLeft"
MinWidth="20"
Padding="0"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Background="{ThemeResource OperatorPanelScrollButtonBackgroundBrush}"
Foreground="{ThemeResource SystemAltMediumHighColor}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Content="&#xE76B;"
IsTabStop="False"
Visibility="Collapsed"/>
<Button x:Name="ScrollRight"
MinWidth="20"
Padding="0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="{ThemeResource OperatorPanelScrollButtonBackgroundBrush}"
Foreground="{ThemeResource SystemAltMediumHighColor}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Content="&#xE76C;"
IsTabStop="False"
Visibility="Collapsed"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Name="EquationTextBoxButtonStyle" TargetType="Button"> <Style x:Name="EquationTextBoxButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent"/> <Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Transparent"/> <Setter Property="Foreground" Value="Transparent"/>
@ -1390,9 +1845,9 @@
Grid.Column="0" Grid.Column="0"
Grid.ColumnSpan="4" Grid.ColumnSpan="4"
Foreground="{ThemeResource SystemControlDescriptionTextForegroundBrush}" Foreground="{ThemeResource SystemControlDescriptionTextForegroundBrush}"
x:Load="False"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Description}"/> Content="{TemplateBinding Description}"
x:Load="False"/>
</Grid> </Grid>

View File

@ -12,7 +12,6 @@
#include "CalcViewModel/Common/Automation/NarratorNotifier.h" #include "CalcViewModel/Common/Automation/NarratorNotifier.h"
#include "CalcViewModel/Common/AppResourceProvider.h" #include "CalcViewModel/Common/AppResourceProvider.h"
#include "CalcViewModel/Common/LocalizationSettings.h" #include "CalcViewModel/Common/LocalizationSettings.h"
#include "CalcViewModel/ViewState.h"
#include "Views/MainPage.xaml.h" #include "Views/MainPage.xaml.h"
using namespace CalculatorApp; using namespace CalculatorApp;
@ -94,31 +93,11 @@ bool App::IsAnimationEnabled()
return App::m_isAnimationEnabled; return App::m_isAnimationEnabled;
} }
/// <summary>
/// Return the current application view state. The value
/// will match one of the constants in the ViewState namespace.
/// </summary>
String ^ App::GetAppViewState()
{
String ^ newViewState;
CoreWindow ^ window = CoreWindow::GetForCurrentThread();
if ((window->Bounds.Width >= 560) && (window->Bounds.Height >= 356))
{
newViewState = ViewState::DockedView;
}
else
{
newViewState = ViewState::Snap;
}
return newViewState;
}
void App::AddWindowToMap(_In_ WindowFrameService ^ frameService) void App::AddWindowToMap(_In_ WindowFrameService ^ frameService)
{ {
reader_writer_lock::scoped_lock lock(m_windowsMapLock); reader_writer_lock::scoped_lock lock(m_windowsMapLock);
m_secondaryWindows[frameService->GetViewId()] = frameService; m_secondaryWindows[frameService->GetViewId()] = frameService;
TraceLogger::GetInstance().UpdateWindowCount(m_secondaryWindows.size()); TraceLogger::GetInstance()->UpdateWindowCount(m_secondaryWindows.size());
} }
WindowFrameService ^ App::GetWindowFromMap(int viewId) WindowFrameService ^ App::GetWindowFromMap(int viewId)
@ -384,7 +363,7 @@ void App::OnAppLaunch(IActivatedEventArgs ^ args, String ^ argument)
} }
else else
{ {
TraceLogger::GetInstance().LogError(ViewMode::None, L"App::OnAppLaunch", L"Null_ActivationViewSwitcher"); TraceLogger::GetInstance()->LogError(ViewMode::None, L"App::OnAppLaunch", L"Null_ActivationViewSwitcher");
} }
} }
// Set the preLaunched flag to false // Set the preLaunched flag to false
@ -460,7 +439,7 @@ void App::OnActivated(IActivatedEventArgs ^ args)
void CalculatorApp::App::OnSuspending(Object ^ sender, SuspendingEventArgs ^ args) void CalculatorApp::App::OnSuspending(Object ^ sender, SuspendingEventArgs ^ args)
{ {
TraceLogger::GetInstance().LogButtonUsage(); TraceLogger::GetInstance()->LogButtonUsage();
} }
void App::DismissedEventHandler(SplashScreen ^ sender, Object ^ e) void App::DismissedEventHandler(SplashScreen ^ sender, Object ^ e)
@ -468,9 +447,5 @@ void App::DismissedEventHandler(SplashScreen ^ sender, Object ^ e)
SetupJumpList(); SetupJumpList();
} }
float App::GetAppWindowHeight()
{
CoreWindow ^ window = CoreWindow::GetForCurrentThread();
return window->Bounds.Height;
}

View File

@ -29,9 +29,8 @@ namespace CalculatorApp
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^ args) override; virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^ args) override;
virtual void OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs ^ args) override; virtual void OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs ^ args) override;
internal : static bool IsAnimationEnabled(); internal :
static Platform::String ^ GetAppViewState(); static bool IsAnimationEnabled();
static float GetAppWindowHeight();
void RemoveWindow(_In_ WindowFrameService ^ frameService); void RemoveWindow(_In_ WindowFrameService ^ frameService);
void RemoveSecondaryWindow(_In_ WindowFrameService ^ frameService); void RemoveSecondaryWindow(_In_ WindowFrameService ^ frameService);

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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