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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ jobs:
steps:
- checkout: self
clean: true
- task: UniversalPackages@0
displayName: Download internals package
inputs:
@ -29,7 +29,7 @@ jobs:
downloadDirectory: $(Build.SourcesDirectory)
vstsFeed: WindowsApps
vstsFeedPackage: calculator-internals
vstsPackageVersion: 0.0.18
vstsPackageVersion: 0.0.22
- template: ./build-single-architecture.yaml
parameters:
@ -64,4 +64,4 @@ jobs:
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: Detect open source components
inputs:
sourceScanPath: $(Agent.BuildDirectory)
sourceScanPath: $(Agent.BuildDirectory)

View File

@ -19,6 +19,12 @@ jobs:
clean: outputs
variables:
skipComponentGovernanceDetection: true
SBMediaRootPath: '$(TEMP)\SBMedia'
SBPackagePath: '$(Build.ArtifactStagingDirectory)\storeBrokerPayload'
SBLogPath: '$(SBPackagePath)\StoreBroker.log'
FlightId: '161f0975-cb5f-475b-8ef6-26383c37621f'
AppId: '9WZDNCRFHVN5'
ProductId: '00009007199266248474'
steps:
- checkout: self
clean: true
@ -91,61 +97,74 @@ jobs:
downloadDirectory: $(Build.SourcesDirectory)
vstsFeed: WindowsApps
vstsFeedPackage: calculator-internals
vstsPackageVersion: 0.0.18
vstsPackageVersion: 0.0.22
- task: PkgESStoreBrokerPackage@10
displayName: Create StoreBroker Packages
env:
XES_SERIALPOSTBUILDREADY: True
- powershell: |
# Just modify this line to indicate where your en-us PDP file is. Leave the other lines alone.
$enUSPdpFilePath = "$(Build.SourcesDirectory)\PDP\en-US\PDP.xml"
# 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:
addToFlight: false
configPath: tools/Build/StoreBroker/SBCalculatorConfig.json
PDPRootPath: $(Build.SourcesDirectory)\PDP
imagesRootPath: $(Build.SourcesDirectory)\PDPMediaRoot
appxPath: $(Build.ArtifactStagingDirectory)\appxBundleSigned\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
useArtifactServiceForMedia: true
outPath: $(Build.ArtifactStagingDirectory)\StoreBrokerPayload
paToken: $(System.AccessToken)
logRootPath: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs
command: download
downloadDirectory: $(SBMediaRootPath)/$(SBMediaReleaseVersion)
vstsFeed: WindowsInboxApps
vstsFeedPackage: calculator-pdp-media
vstsPackageVersion: $(SBMediaReleaseVersion)
- task: MS-RDX-MRO.windows-store-publish-dev.package-task.store-package@2
displayName: Create StoreBroker Payload
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
displayName: Publish StoreBrokerPayload artifact
displayName: Publish StoreBroker Payload artifact
inputs:
pathtoPublish: '$(SBPackagePath)'
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
displayName: Flight package with StoreBroker
env:
XES_SERIALPOSTBUILDREADY: True
inputs:
packageToFlight: Custom
appId: 9WZDNCRFHVN5
flightId: 161f0975-cb5f-475b-8ef6-26383c37621f
submissionDataPath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.json
packagePath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.zip
updatePackageAction: AddPackages
logRootPath: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs
- task: PublishBuildArtifacts@1
displayName: Publish StoreBrokerLogs artifact
inputs:
artifactName: storeBrokerLogs
pathToPublish: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs
serviceEndpoint: StoreBrokerProxy
appId: '$(AppId)'
flightId: '$(FlightId)'
inputMethod: JsonAndZip
jsonPath: '$(SBPackagePath)\SBCalculator.json'
zipPath: '$(SBPackagePath)\SBCalculator.zip'
force: true
skipPolling: true
targetPublishMode: Immediate
logPath: '$(SBLogPath)'
- task: PkgESStoreBrokerAeroUpload@10
displayName: Upload to Aero flighting dashboard
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
productId: 00009007199266248474
flightId: 161f0975-cb5f-475b-8ef6-26383c37621f
submissionId: $(StoreBrokerFlight.WS_SubmissionId)
submissionDataPath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.json
packagePath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.zip
ProductId: '$(ProductId)'
FlightId: '$(FlightId)'
SubmissionId: '$(StoreBrokerFlight.WS_SubmissionId)'
SubmissionDataPath: '$(SBPackagePath)\SBCalculator.json'
PackagePath: '$(SBPackagePath)\SBCalculator.zip'
AeroEnvironment: Production
- task: PkgESLateTasks@10
displayName: Run PackageES LateTasks
env:
XES_DISABLEPROV: true
XES_DISABLEPROV: true

View File

@ -1,29 +1,20 @@
# This template contains jobs to run unit tests on the interactive test agents.
# This template contains jobs to run unit tests.
parameters:
platform: ''
reimageServiceConnection: ''
reimageSubscriptionId: ''
reimageResourceGroup: ''
runsettingsFileName: ''
jobs:
- job: UnitTests${{ parameters.platform }}
displayName: UnitTests ${{ parameters.platform }}
dependsOn: Build${{ parameters.platform }}
condition: succeeded()
pool:
name: Essential Experiences Interactive
workspace:
clean: outputs
vmImage: windows-2019
variables:
skipComponentGovernanceDetection: true
steps:
- 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
displayName: Download CalculatorUnitTests
@ -41,19 +32,4 @@ jobs:
displayName: Run CalculatorUnitTests
inputs:
testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.appx
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)"] }'
otherConsoleOptions: /Platform:${{ parameters.platform }}

View File

@ -179,7 +179,7 @@ bool CalcInput::TryAddDecimalPt()
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();
@ -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)
{
// 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)
{
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
// of it and catch it themselves or not needing this
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)

View File

@ -3,7 +3,6 @@
#include "Header Files/CalcEngine.h"
#include "Command.h"
#include "CalculatorVector.h"
#include "ExpressionCommand.h"
constexpr int ASCII_0 = 48;
@ -13,14 +12,19 @@ using namespace CalcEngine;
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()
{
m_lastOpStartIndex = -1;
@ -29,11 +33,11 @@ void CHistoryCollector::ReinitHistory()
m_bLastOpndBrace = false;
if (m_spTokens != nullptr)
{
m_spTokens->Clear();
m_spTokens->clear();
}
if (m_spCommands != nullptr)
{
m_spCommands->Clear();
m_spCommands->clear();
}
}
@ -55,13 +59,13 @@ CHistoryCollector::~CHistoryCollector()
if (m_spTokens != nullptr)
{
m_spTokens->Clear();
m_spTokens->clear();
}
}
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
bool fNegative = (numStr[0] == L'-');
bool fSciFmt = false;
@ -71,7 +75,7 @@ void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& ra
{
if (numStr[i] == m_decimalSymbol)
{
IFT(commands->Append(IDC_PNT));
commands->push_back(IDC_PNT);
if (!fSciFmt)
{
fDecimal = true;
@ -79,12 +83,12 @@ void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& ra
}
else if (numStr[i] == L'e')
{
IFT(commands->Append(IDC_EXP));
commands->push_back(IDC_EXP);
fSciFmt = true;
}
else if (numStr[i] == L'-')
{
IFT(commands->Append(IDC_SIGN));
commands->push_back(IDC_SIGN);
}
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;
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
}
void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool fNoRepetition)
void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool isIntegerMode, bool fNoRepetition)
{
int iCommandEnd = AddCommand(std::make_shared<CBinaryCommand>(nOpCode));
m_lastBinOpStartIndex = IchAddSzToEquationSz(L" ", -1);
IchAddSzToEquationSz(CCalcEngine::OpCodeToString(nOpCode), iCommandEnd);
IchAddSzToEquationSz(CCalcEngine::OpCodeToBinaryString(nOpCode, isIntegerMode), iCommandEnd);
IchAddSzToEquationSz(L" ", -1);
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 *)
// It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new
// one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^)
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher)
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode)
{
TruncateEquationSzFromIch(m_lastBinOpStartIndex);
if (fPrecInvToHigher)
{
EnclosePrecInversionBrackets();
}
AddBinOpToHistory(nOpCode);
AddBinOpToHistory(nOpCode, isIntgerMode);
}
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;
spExpressionCommand = std::make_shared<CUnaryCommand>(command);
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:
command = fInv ? static_cast<int>(CalculationManager::Command::CommandPOWE) : IDC_LN;
spExpressionCommand = std::make_shared<CUnaryCommand>(command);
@ -301,12 +329,6 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE a
// history of equations
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)
{
unsigned int addedItemIndex = m_pHistoryDisplay->AddToHistory(m_spTokens, m_spCommands, numStr);
@ -319,6 +341,16 @@ void CHistoryCollector::CompleteHistoryLine(wstring_view numStr)
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)
{
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)
{
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
ReinitHistory();
@ -339,26 +371,17 @@ int CHistoryCollector::IchAddSzToEquationSz(wstring_view str, int icommandIndex)
{
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))))
{
throw(CALC_E_OUTOFMEMORY);
}
unsigned int nTokens;
m_spTokens->GetSize(&nTokens);
return nTokens - 1;
m_spTokens->push_back(std::pair(wstring(str), icommandIndex));
return static_cast<int>(m_spTokens->size() - 1);
}
// 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)
{
if (FAILED(m_spTokens->InsertAt(ich, std::make_pair(wstring(str), icommandIndex))))
{
throw(CALC_E_OUTOFMEMORY);
}
m_spTokens->emplace(m_spTokens->begin() + ich, wstring(str), icommandIndex);
}
// Chops off the current equation string from the given index
@ -366,25 +389,23 @@ void CHistoryCollector::TruncateEquationSzFromIch(int ich)
{
// Truncate commands
int minIdx = -1;
unsigned int nTokens = 0;
std::pair<std::wstring, int> currentPair;
m_spTokens->GetSize(&nTokens);
unsigned int nTokens = static_cast<unsigned int>(m_spTokens->size());
for (unsigned int i = ich; i < nTokens; i++)
{
IFT(m_spTokens->GetAt(i, &currentPair));
const auto& currentPair = (*m_spTokens)[i];
int curTokenId = currentPair.second;
if (curTokenId != -1)
{
if ((minIdx != -1) || (curTokenId < minIdx))
{
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
@ -400,17 +421,11 @@ int CHistoryCollector::AddCommand(_In_ const std::shared_ptr<IExpressionCommand>
{
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)))
{
throw(CALC_E_OUTOFMEMORY);
}
unsigned int nCommands = 0;
m_spCommands->GetSize(&nCommands);
return nCommands - 1;
m_spCommands->push_back(spCommand);
return static_cast<int>(m_spCommands->size() - 1);
}
// 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;
}
unsigned int size;
IFT(m_spTokens->GetSize(&size));
for (unsigned int i = 0; i < size; ++i)
for (auto& token : *m_spTokens)
{
std::pair<std::wstring, int> token;
IFT(m_spTokens->GetAt(i, &token));
int commandPosition = token.second;
if (commandPosition != -1)
{
std::shared_ptr<IExpressionCommand> expCommand;
IFT(m_spCommands->GetAt(commandPosition, &expCommand));
const std::shared_ptr<IExpressionCommand>& expCommand = m_spCommands->at(commandPosition);
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)
{
token.first = opndCommand->GetString(radix, precision);
IFT(m_spTokens->SetAt(i, token));
opndCommand->SetCommands(GetOperandCommandsFromString(token.first));
}
}
}
}
SetExpressionDisplay();
}
@ -454,9 +464,9 @@ void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
}
// 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
bool fNegative = (numStr[0] == L'-');
@ -464,15 +474,15 @@ std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFrom
{
if (numStr[i] == m_decimalSymbol)
{
IFT(commands->Append(IDC_PNT));
commands->push_back(IDC_PNT);
}
else if (numStr[i] == L'e')
{
IFT(commands->Append(IDC_EXP));
commands->push_back(IDC_EXP);
}
else if (numStr[i] == L'-')
{
IFT(commands->Append(IDC_SIGN));
commands->push_back(IDC_SIGN);
}
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;
num += IDC_0;
IFT(commands->Append(num));
commands->push_back(num);
}
}
// If the number is negative, append a sign command at the end.
if (fNegative)
{
IFT(commands->Append(IDC_SIGN));
commands->push_back(IDC_SIGN);
}
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.
// 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)
{
for (const auto& sid : g_sids)
{
auto locKey = wstring{ sid };
auto locString = resourceProvider.GetCEngineString(locKey);
auto locString = resourceProvider.GetCEngineString(sid);
if (!locString.empty())
{
s_engineStrings[locKey] = locString;
s_engineStrings[sid] = locString;
}
}
}

View File

@ -16,6 +16,7 @@
#include <string>
#include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h"
#include "NumberFormattingUtils.h"
using namespace std;
using namespace CalcEngine;
@ -28,8 +29,13 @@ namespace
// 0 is returned. Higher the number, higher the precedence of the operator.
int NPrecedenceOfOp(int nopCode)
{
static uint8_t rgbPrec[] = { 0, 0, IDC_OR, 0, IDC_XOR, 0, IDC_AND, 1, IDC_ADD, 2, IDC_SUB, 2, IDC_RSHF,
3, IDC_LSHF, 3, IDC_MOD, 3, IDC_DIV, 3, IDC_MUL, 3, IDC_PWR, 4, IDC_ROOT, 4 };
static uint16_t rgbPrec[] = {
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;
iPrec = 0;
@ -76,6 +82,15 @@ void CCalcEngine::ClearTemporaryValues()
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)
{
if (wParam == IDC_SET_RESULT)
@ -103,6 +118,12 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_nTempCom = (int)wParam;
}
// Clear expression shown after = sign, when user do any action.
if (!m_bNoPrevEqu)
{
ClearDisplay();
}
if (m_bError)
{
if (wParam == IDC_CLEAR)
@ -124,9 +145,18 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
// Toggle Record/Display mode if appropriate.
if (m_bRecord)
{
if (IsOpInRange(wParam, IDC_AND, 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_BINEDITSTART + 63) || (IDC_INV == wParam) || (IDC_SIGN == wParam && 10 != m_radix))
if (IsBinOpCode(wParam) ||
IsUnaryOpCode(wParam) ||
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_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_HistoryCollector.ChangeLastBinOp(m_nOpCode, fPrecInvToHigher);
m_HistoryCollector.ChangeLastBinOp(m_nOpCode, fPrecInvToHigher, m_fIntegerMode);
DisplayAnnounceBinaryOperator();
return;
}
@ -270,10 +300,9 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
}
DisplayAnnounceBinaryOperator();
m_lastVal = m_currentVal;
m_nOpCode = (int)wParam;
m_HistoryCollector.AddBinOpToHistory(m_nOpCode);
m_HistoryCollector.AddBinOpToHistory(m_nOpCode, m_fIntegerMode);
m_bNoPrevEqu = m_bChangeOp = true;
return;
}
@ -303,7 +332,8 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
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())
{
@ -330,9 +360,13 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
/* reset the m_bInv flag and indicators if it is set
and have been used */
if (m_bInv
&& ((wParam == IDC_CHOP) || (wParam == IDC_SIN) || (wParam == IDC_COS) || (wParam == IDC_TAN) || (wParam == IDC_LN) || (wParam == IDC_DMS)
|| (wParam == IDC_DEGREES) || (wParam == IDC_SINH) || (wParam == IDC_COSH) || (wParam == IDC_TANH)))
if (m_bInv &&
((wParam == IDC_CHOP) || (wParam == IDC_SIN) || (wParam == IDC_COS) ||
(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;
}
@ -341,10 +375,10 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
}
// 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
if (m_nLastCom >= IDC_AND && m_nLastCom <= IDC_PWR)
if (IsBinOpCode(m_nLastCom))
{
m_currentVal = m_lastVal;
}
@ -377,14 +411,14 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_precedenceOpCount = m_nTempCom = m_nLastCom = m_nOpCode = 0;
m_nPrevOpCode = 0;
m_bNoPrevEqu = true;
m_carryBit = 0;
/* clear the parenthesis status box indicator, this will not be
cleared for CENTR */
if (nullptr != m_pCalcDisplay)
{
m_pCalcDisplay->SetParenthesisNumber(0);
m_pCalcDisplay->SetExpressionDisplay(
make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>());
ClearDisplay();
}
m_HistoryCollector.ClearHistoryLine(wstring());
@ -474,12 +508,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
if (!m_bError)
{
wstring groupedString = GroupDigitsPerRadix(m_numberString, m_radix);
m_HistoryCollector.CompleteHistoryLine(groupedString);
if (nullptr != m_pCalcDisplay)
{
m_pCalcDisplay->SetExpressionDisplay(
make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>());
}
m_HistoryCollector.CompleteEquation(groupedString);
}
m_bChangeOp = false;
@ -700,7 +729,6 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
case IDC_MCLEAR:
m_memoryValue = make_unique<Rational>(wParam == IDC_STORE ? TruncateNumForIntMath(m_currentVal) : 0);
break;
case IDC_PI:
if (!m_fIntegerMode)
{
@ -713,7 +741,43 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
}
HandleErrorCommand(wParam);
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:
// Toggle exponential notation display.
m_nFE = NUMOBJ_FMT(!(int)m_nFE);
@ -761,7 +825,7 @@ void CCalcEngine::ResolveHighestPrecedenceOperation()
{
m_currentVal = m_holdVal;
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
}
@ -863,11 +927,14 @@ struct FunctionNameElement
wstring gradString;
wstring inverseGradString; // Will fall back to gradString if empty
wstring programmerModeString;
bool hasAngleStrings = ((!radString.empty()) || (!inverseRadString.empty()) || (!gradString.empty()) || (!inverseGradString.empty()));
};
// 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_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_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_SQR, { SIDS_SQR } },
{ IDC_CUB, { SIDS_CUBE } },
@ -885,7 +960,19 @@ static const std::unordered_map<int, FunctionNameElement> unaryOperatorStringTab
{ IDC_REC, { SIDS_RECIPROC } },
{ IDC_DMS, { L"", SIDS_DEGREES } },
{ 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)
@ -893,7 +980,7 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
// Try to lookup the ID in the UFNE table
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;
if (!element.hasAngleStrings || ANGLE_DEG == angletype)
@ -941,6 +1028,32 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
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()
{
return m_currentVal >= m_maxTrigonometricNum;
@ -1007,3 +1120,14 @@ wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix)
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;
// Rotate Left with hi bit wrapped over to lo bit
case IDC_ROL:
case IDC_ROLC:
if (m_fIntegerMode)
{
result = Integer(rat);
@ -55,14 +55,23 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
uint64_t w64Bits = result.ToUInt64_t();
uint64_t msb = (w64Bits >> (m_dwWordBitWidth - 1)) & 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;
}
break;
// Rotate right with lo bit wrapped over to hi bit
case IDC_ROR:
case IDC_RORC:
if (m_fIntegerMode)
{
result = Integer(rat);
@ -70,7 +79,16 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
uint64_t w64Bits = result.ToUInt64_t();
uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0;
w64Bits >>= 1; // RShift by 1
w64Bits |= (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;
}
@ -133,6 +151,48 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
}
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. */
result = Invert(rat);
break;
@ -158,6 +218,10 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
result = Pow(10, rat);
break;
case IDC_POW2:
result = Pow(2, rat);
break;
case IDC_LN: /* Functions for natural log. */
result = m_bInv ? Exp(rat) : Log(rat);
break;
@ -202,6 +266,18 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
}
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 )
}
catch (uint32_t nErrCode)

View File

@ -28,6 +28,14 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
result ^= rhs;
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:
{
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;
}
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:
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.
result = Root(rhs, result);
break;
case IDC_LOGBASEX:
result = (Log(result) / Log(rhs));
break;
}
}
catch (uint32_t dwErrCode)

View File

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

View File

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

View File

@ -7,25 +7,48 @@
using namespace std;
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)
: m_maxHistorySize(maxSize)
{
}
unsigned int CalculatorHistory::AddToHistory(
_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens,
_In_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands,
_In_ wstring_view result)
_In_ shared_ptr<vector<pair<wstring, int>>> const& tokens,
_In_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands,
wstring_view result)
{
unsigned int addedIndex;
wstring generatedExpression;
shared_ptr<HISTORYITEM> spHistoryItem = make_shared<HISTORYITEM>();
spHistoryItem->historyItemVector.spTokens = tokens;
spHistoryItem->historyItemVector.spCommands = commands;
// 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
// in the history doesn't get broken for RTL languages
spHistoryItem->historyItemVector.expression = L'\u202d' + generatedExpression + L'\u202c';
@ -47,7 +70,7 @@ unsigned int CalculatorHistory::AddItem(_In_ shared_ptr<HISTORYITEM> const& spHi
return lastIndex;
}
bool CalculatorHistory::RemoveItem(_In_ unsigned int uIdx)
bool CalculatorHistory::RemoveItem(unsigned int uIdx)
{
if (uIdx > m_historyItems.size() - 1)
{
@ -63,17 +86,12 @@ vector<shared_ptr<HISTORYITEM>> const& CalculatorHistory::GetHistory()
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());
return m_historyItems.at(uIdx);
}
CalculatorHistory::~CalculatorHistory(void)
{
ClearHistory();
}
void CalculatorHistory::ClearHistory()
{
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.
#pragma once
@ -15,8 +15,8 @@ namespace CalculationManager
struct HISTORYITEMVECTOR
{
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> spCommands;
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> spTokens;
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> spCommands;
std::wstring expression;
std::wstring result;
};
@ -31,8 +31,8 @@ namespace CalculationManager
public:
CalculatorHistory(const size_t maxSize);
unsigned int AddToHistory(
_In_ std::shared_ptr<CalculatorVector<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::pair<std::wstring, int>>> const& spTokens,
_In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& spCommands,
std::wstring_view result);
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistory();
std::shared_ptr<HISTORYITEM> const& GetHistoryItem(unsigned int uIdx);
@ -43,7 +43,6 @@ namespace CalculationManager
{
return m_maxHistorySize;
}
~CalculatorHistory(void);
private:
std::vector<std::shared_ptr<HISTORYITEM>> m_historyItems;

View File

@ -75,14 +75,19 @@ namespace CalculationManager
m_displayCallback->MemoryItemChanged(indexOfMemory);
}
void CalculatorManager::InputChanged()
{
m_displayCallback->InputChanged();
}
/// <summary>
/// Call the callback function using passed in IDisplayHelper.
/// Used to set the expression display value on ViewModel
/// </summary>
/// <param name="expressionString">wstring representing expression to be displayed</param>
void CalculatorManager::SetExpressionDisplay(
_Inout_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens,
_Inout_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands)
_Inout_ shared_ptr<vector<pair<wstring, int>>> const& tokens,
_Inout_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands)
{
if (!m_inHistoryItemLoadMode)
{
@ -240,6 +245,7 @@ namespace CalculationManager
m_savedCommands.push_back(MapCommandForSerialize(command));
}
m_savedDegreeMode = m_currentDegreeMode;
InputChanged();
return;
}
@ -283,6 +289,30 @@ namespace CalculationManager
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandTANH));
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:
m_isExponentialFormat = !m_isExponentialFormat;
[[fallthrough]];
@ -290,6 +320,8 @@ namespace CalculationManager
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(command));
break;
}
InputChanged();
}
/// <summary>
@ -330,6 +362,7 @@ namespace CalculationManager
{
m_currentCalculatorEngine->PersistedMemObject(m_persistedPrimaryValue);
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
InputChanged();
}
/// <summary>
@ -376,6 +409,7 @@ namespace CalculationManager
this->MemorizedNumberSelect(indexOfMemory);
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
InputChanged();
}
/// <summary>
@ -606,9 +640,9 @@ namespace CalculationManager
if (pHistory)
{
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;
}
bool CalculatorManager::IsInputEmpty()
{
return m_currentCalculatorEngine->IsInputEmpty();
}
void CalculatorManager::SetInHistoryItemLoadMode(_In_ bool isHistoryItemLoadMode)
{
m_inHistoryItemLoadMode = isHistoryItemLoadMode;

View File

@ -91,8 +91,8 @@ namespace CalculationManager
void SetPrimaryDisplay(_In_ const std::wstring& displayString, _In_ bool isError) override;
void SetIsInError(bool isError) override;
void SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) override;
_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) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
@ -101,8 +101,8 @@ namespace CalculationManager
void MaxDigitsReached() override;
void BinaryOperatorReceived() override;
void MemoryItemChanged(unsigned int indexOfMemory) override;
CalculatorManager(ICalcDisplay* displayCallback, IResourceProvider* resourceProvider);
void InputChanged() override;
CalculatorManager(_In_ ICalcDisplay* displayCallback, _In_ IResourceProvider* resourceProvider);
void Reset(bool clearMemory = true);
void SetStandardMode();
@ -118,7 +118,8 @@ namespace CalculationManager
void MemorizedNumberClearAll();
bool IsEngineRecording();
std::vector<unsigned char> GetSavedCommands()
bool IsInputEmpty();
const std::vector<unsigned char>& GetSavedCommands() const
{
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.
#pragma once
#include <string_view>
namespace CalculationManager
{
class IResourceProvider
@ -19,6 +21,6 @@ namespace CalculationManager
// ids "sDecimal", "sThousand" and "sGrouping". See
// https://technet.microsoft.com/en-us/library/cc782655(v=ws.10).aspx
// 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,
CommandROR = 100,
CommandCOM = 101,
CommandSIN = 102,
CommandCOS = 103,
CommandTAN = 104,
@ -151,6 +152,34 @@ namespace CalculationManager
CommandINV = 146,
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,
CommandOR = 87,
CommandNot = 101,

View File

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

View File

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

View File

@ -4,7 +4,7 @@
#pragma once
#include <memory> // for std::shared_ptr
#include "CalculatorVector.h"
#include <vector>
#include "Command.h"
class ISerializeCommandVisitor;
@ -25,7 +25,7 @@ public:
class IUnaryCommand : public IOperatorCommand
{
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;
};
@ -39,7 +39,7 @@ public:
class IOpndCommand : public IExpressionCommand
{
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 ToggleSign() = 0;
virtual void RemoveFromEnd() = 0;
@ -47,7 +47,7 @@ public:
virtual bool IsSciFmt() const = 0;
virtual bool IsDecimalPresent() const = 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

View File

@ -81,6 +81,7 @@
#define IDC_ROL 99
#define IDC_ROR 100
#define IDC_COM 101
#define IDC_SIN 102
#define IDC_COS 103
#define IDC_TAN 104
@ -136,7 +137,44 @@
#define IDC_INV 146
#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_BINPOS0 700

View File

@ -14,10 +14,10 @@
*
\****************************************************************************/
#include <random>
#include "CCommand.h"
#include "EngineStrings.h"
#include "../Command.h"
#include "../CalculatorVector.h"
#include "../ExpressionCommand.h"
#include "RadixType.h"
#include "History.h" // for History Collector
@ -68,6 +68,10 @@ public:
{
return m_bError;
}
bool IsInputEmpty()
{
return m_input.IsEmpty() && (m_numberString.empty() || m_numberString == L"0");
}
bool FInRecordingState()
{
return m_bRecord;
@ -94,7 +98,7 @@ public:
{
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];
}
@ -103,6 +107,7 @@ public:
return GetString(IdStrFromCmdId(nOpCode));
}
static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype);
static std::wstring_view OpCodeToBinaryString(int nOpCode, bool isIntegerMode);
private:
bool m_fPrecedence;
@ -147,11 +152,16 @@ private:
NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode.
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
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
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_groupSeparator;
@ -165,12 +175,14 @@ private:
void DisplayAnnounceBinaryOperator();
void SetPrimaryDisplay(const std::wstring& szText, bool isError = false);
void ClearTemporaryValues();
void ClearDisplay();
CalcEngine::Rational TruncateNumForIntMath(CalcEngine::Rational const& rat);
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op);
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
void SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth);
int32_t DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth);
uint32_t NRadixFromRadixType(RADIX_TYPE radixtype);
double GenerateRandomNumber();
bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno);
void CheckAndAddLastBinOpToHistory(bool addToHistory = true);

View File

@ -66,6 +66,7 @@ namespace CalcEngine
bool TryBeginExponent();
void Backspace();
void SetDecimalSymbol(wchar_t decSymbol);
bool IsEmpty();
std::wstring ToString(uint32_t radix);
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_RECIPROCAL = L"34";
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_PERCENT = L"38";
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_INPUT_OVERFLOW = L"119";
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
inline constexpr std::array<std::wstring_view, 120> g_sids = { SIDS_PLUS_MINUS,
SIDS_C,
SIDS_CE,
SIDS_BACKSPACE,
SIDS_DECIMAL_SEPARATOR,
SIDS_EMPTY_STRING,
SIDS_AND,
SIDS_OR,
SIDS_XOR,
SIDS_LSH,
SIDS_RSH,
SIDS_DIVIDE,
SIDS_MULTIPLY,
SIDS_PLUS,
SIDS_MINUS,
SIDS_MOD,
SIDS_YROOT,
SIDS_POW_HAT,
SIDS_INT,
SIDS_ROL,
SIDS_ROR,
SIDS_NOT,
SIDS_SIN,
SIDS_COS,
SIDS_TAN,
SIDS_SINH,
SIDS_COSH,
SIDS_TANH,
SIDS_LN,
SIDS_LOG,
SIDS_SQRT,
SIDS_XPOW2,
SIDS_XPOW3,
SIDS_NFACTORIAL,
SIDS_RECIPROCAL,
SIDS_DMS,
SIDS_CUBEROOT,
SIDS_POWTEN,
SIDS_PERCENT,
SIDS_SCIENTIFIC_NOTATION,
SIDS_PI,
SIDS_EQUAL,
SIDS_MC,
SIDS_MR,
SIDS_MS,
SIDS_MPLUS,
SIDS_MMINUS,
SIDS_EXP,
SIDS_OPEN_PAREN,
SIDS_CLOSE_PAREN,
SIDS_0,
SIDS_1,
SIDS_2,
SIDS_3,
SIDS_4,
SIDS_5,
SIDS_6,
SIDS_7,
SIDS_8,
SIDS_9,
SIDS_A,
SIDS_B,
SIDS_C,
SIDS_D,
SIDS_E,
SIDS_F,
SIDS_FRAC,
SIDS_SIND,
SIDS_COSD,
SIDS_TAND,
SIDS_ASIND,
SIDS_ACOSD,
SIDS_ATAND,
SIDS_SINR,
SIDS_COSR,
SIDS_TANR,
SIDS_ASINR,
SIDS_ACOSR,
SIDS_ATANR,
SIDS_SING,
SIDS_COSG,
SIDS_TANG,
SIDS_ASING,
SIDS_ACOSG,
SIDS_ATANG,
SIDS_ASINH,
SIDS_ACOSH,
SIDS_ATANH,
SIDS_POWE,
SIDS_POWTEN2,
SIDS_SQRT2,
SIDS_SQR,
SIDS_CUBE,
SIDS_CUBERT,
SIDS_FACT,
SIDS_RECIPROC,
SIDS_DEGREES,
SIDS_NEGATE,
SIDS_RSH,
SIDS_DIVIDEBYZERO,
SIDS_DOMAIN,
SIDS_UNDEFINED,
SIDS_POS_INFINITY,
SIDS_NEG_INFINITY,
SIDS_ABORTED,
SIDS_NOMEM,
SIDS_TOOMANY,
SIDS_OVERFLOW,
SIDS_NORESULT,
SIDS_INSUFFICIENT_DATA,
SIDS_ERR_UNK_CH,
SIDS_ERR_UNK_FN,
SIDS_ERR_UNEX_NUM,
SIDS_ERR_UNEX_CH,
SIDS_ERR_UNEX_SZ,
SIDS_ERR_MISMATCH_CLOSE,
SIDS_ERR_UNEX_END,
SIDS_ERR_SG_INV_ERROR,
SIDS_ERR_INPUT_OVERFLOW,
SIDS_ERR_OUTPUT_OVERFLOW };
inline constexpr std::array<std::wstring_view, 152> g_sids =
{
SIDS_PLUS_MINUS,
SIDS_C,
SIDS_CE,
SIDS_BACKSPACE,
SIDS_DECIMAL_SEPARATOR,
SIDS_EMPTY_STRING,
SIDS_AND,
SIDS_OR,
SIDS_XOR,
SIDS_LSH,
SIDS_RSH,
SIDS_DIVIDE,
SIDS_MULTIPLY,
SIDS_PLUS,
SIDS_MINUS,
SIDS_MOD,
SIDS_YROOT,
SIDS_POW_HAT,
SIDS_INT,
SIDS_ROL,
SIDS_ROR,
SIDS_NOT,
SIDS_SIN,
SIDS_COS,
SIDS_TAN,
SIDS_SINH,
SIDS_COSH,
SIDS_TANH,
SIDS_LN,
SIDS_LOG,
SIDS_SQRT,
SIDS_XPOW2,
SIDS_XPOW3,
SIDS_NFACTORIAL,
SIDS_RECIPROCAL,
SIDS_DMS,
SIDS_POWTEN,
SIDS_PERCENT,
SIDS_SCIENTIFIC_NOTATION,
SIDS_PI,
SIDS_EQUAL,
SIDS_MC,
SIDS_MR,
SIDS_MS,
SIDS_MPLUS,
SIDS_MMINUS,
SIDS_EXP,
SIDS_OPEN_PAREN,
SIDS_CLOSE_PAREN,
SIDS_0,
SIDS_1,
SIDS_2,
SIDS_3,
SIDS_4,
SIDS_5,
SIDS_6,
SIDS_7,
SIDS_8,
SIDS_9,
SIDS_A,
SIDS_B,
SIDS_C,
SIDS_D,
SIDS_E,
SIDS_F,
SIDS_FRAC,
SIDS_SIND,
SIDS_COSD,
SIDS_TAND,
SIDS_ASIND,
SIDS_ACOSD,
SIDS_ATAND,
SIDS_SINR,
SIDS_COSR,
SIDS_TANR,
SIDS_ASINR,
SIDS_ACOSR,
SIDS_ATANR,
SIDS_SING,
SIDS_COSG,
SIDS_TANG,
SIDS_ASING,
SIDS_ACOSG,
SIDS_ATANG,
SIDS_ASINH,
SIDS_ACOSH,
SIDS_ATANH,
SIDS_POWE,
SIDS_POWTEN2,
SIDS_SQRT2,
SIDS_SQR,
SIDS_CUBE,
SIDS_CUBERT,
SIDS_FACT,
SIDS_RECIPROC,
SIDS_DEGREES,
SIDS_NEGATE,
SIDS_RSH,
SIDS_DIVIDEBYZERO,
SIDS_DOMAIN,
SIDS_UNDEFINED,
SIDS_POS_INFINITY,
SIDS_NEG_INFINITY,
SIDS_ABORTED,
SIDS_NOMEM,
SIDS_TOOMANY,
SIDS_OVERFLOW,
SIDS_NORESULT,
SIDS_INSUFFICIENT_DATA,
SIDS_ERR_UNK_CH,
SIDS_ERR_UNK_FN,
SIDS_ERR_UNEX_NUM,
SIDS_ERR_UNEX_CH,
SIDS_ERR_UNEX_SZ,
SIDS_ERR_MISMATCH_CLOSE,
SIDS_ERR_UNEX_END,
SIDS_ERR_SG_INV_ERROR,
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();
void AddOpndToHistory(std::wstring_view numStr, CalcEngine::Rational const& rat, bool fRepetition = false);
void RemoveLastOpndFromHistory();
void AddBinOpToHistory(int nOpCode, bool fNoRepetition = true);
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher);
void AddBinOpToHistory(int nOpCode, bool isIntgerMode, bool fNoRepetition = true);
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode);
void AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE angletype);
void AddOpenBraceToHistory();
void AddCloseBraceToHistory();
@ -31,6 +31,7 @@ public:
void EnclosePrecInversionBrackets();
bool FOpndAddedToHistory();
void CompleteHistoryLine(std::wstring_view numStr);
void CompleteEquation(std::wstring_view numStr);
void ClearHistoryLine(std::wstring_view errStr);
int AddCommand(_In_ const std::shared_ptr<IExpressionCommand>& spCommand);
void UpdateHistoryExpression(uint32_t radix, int32_t precision);
@ -50,8 +51,8 @@ private:
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
wchar_t m_decimalSymbol;
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_spTokens;
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
private:
void ReinitHistory();
@ -59,5 +60,5 @@ private:
void TruncateEquationSzFromIch(int ich);
void SetExpressionDisplay();
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
#include "../CalculatorVector.h"
#include "../ExpressionCommandInterface.h"
// 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 SetIsInError(bool isInError) = 0;
virtual void SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) = 0;
_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) = 0;
virtual void SetParenthesisNumber(_In_ unsigned int count) = 0;
virtual void OnNoRightParenAdded() = 0;
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 SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers) = 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.
#pragma once
#include "../ExpressionCommandInterface.h"
// Callback interface to be implemented by the clients of CCalcEngine if they require equation history
class IHistoryDisplay
{
public:
virtual ~IHistoryDisplay(){};
virtual unsigned int AddToHistory(
_In_ std::shared_ptr<CalculatorVector<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::pair<std::wstring, int>>> const& tokens,
_In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands,
_In_ std::wstring_view result) = 0;
};

View File

@ -16,8 +16,7 @@ namespace CalcManager::NumberFormattingUtils
return;
}
wstring::iterator iter;
for (iter = number.end() - 1;; iter--)
for (auto iter = number.end() - 1;; iter--)
{
if (*iter != L'0')
{
@ -25,9 +24,9 @@ namespace CalcManager::NumberFormattingUtils
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
//
// 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
//
// 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
//
// 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
//
// 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
//
// 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
//
// The given input is within the domain of the function but is beyond
// the range for which calc can successfully compute the answer
#define CALC_E_INVALIDRANGE ((uint32_t)0x80000006)
static constexpr uint32_t CALC_E_INVALIDRANGE = (uint32_t)0x80000006;
// CALC_E_OUTOFMEMORY
//
// 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
//
// 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
//
// 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)
@ -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);
@ -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)

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)
@ -167,7 +167,7 @@ void _destroynum(_In_ PNUMBER pnum)
//
//-----------------------------------------------------------------------------
void _destroyrat(_In_ PRAT prat)
void _destroyrat(_Frees_ptr_opt_ PRAT prat)
{
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;
@ -784,7 +784,7 @@ PRAT i32torat(_In_ int32_t ini32)
//
//-----------------------------------------------------------------------------
PRAT Ui32torat(_In_ uint32_t inui32)
PRAT Ui32torat(uint32_t inui32)
{
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();
@ -58,7 +58,7 @@ void _exprat(PRAT* px, int32_t precision)
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;
@ -150,7 +150,7 @@ void _lograt(PRAT* px, int32_t precision)
DESTROYTAYLOR();
}
void lograt(PRAT* px, int32_t precision)
void lograt(_Inout_ PRAT* px, int32_t precision)
{
bool fneglog;
@ -224,7 +224,7 @@ void lograt(PRAT* px, int32_t precision)
destroyrat(pwr);
}
void log10rat(PRAT* px, int32_t precision)
void log10rat(_Inout_ PRAT* px, int32_t 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
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
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);

View File

@ -190,7 +190,7 @@ void _gamma(PRAT* pn, uint32_t radix, int32_t precision)
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;

View File

@ -83,7 +83,7 @@ void asinanglerat(_Inout_ PRAT* pa, ANGLE_TYPE angletype, uint32_t radix, int32_
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;
@ -190,7 +190,7 @@ void _acosrat(PRAT* px, int32_t precision)
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);
@ -276,7 +276,7 @@ void _atanrat(PRAT* px, int32_t precision)
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;

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.
//-----------------------------------------------------------------------------
@ -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;
@ -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))
@ -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;

View File

@ -17,7 +17,7 @@
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;
@ -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;
@ -73,19 +73,19 @@ enum
FUNC_XOR
} 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);
}
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);
}
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);
@ -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))
@ -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
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(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix)
{
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(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix)
{
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.
@ -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(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix, int32_t precision)
{
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;
@ -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;
@ -614,7 +614,7 @@ bool lessnum(PNUMBER a, PNUMBER b)
//
//----------------------------------------------------------------------------
bool zernum(PNUMBER a)
bool zernum(_In_ PNUMBER a)
{
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;
@ -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.
// 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.
@ -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))
@ -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;
@ -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;
@ -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
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));

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 i32tonum(int32_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)
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 _destroynum(_In_ PNUMBER pnum);
extern void _destroyrat(_In_ PRAT prat);
extern void _destroynum(_Frees_ptr_opt_ PNUMBER pnum);
extern void _destroyrat(_Frees_ptr_opt_ PRAT prat);
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 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.
// 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;
@ -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;
@ -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;
@ -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;
@ -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;
@ -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;
@ -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;
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 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))
@ -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);
@ -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;
@ -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)

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);
_cosrat(px, radix, precision);
@ -257,7 +257,7 @@ void _tanrat(PRAT* px, uint32_t radix, int32_t precision)
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);
_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.
//-----------------------------------------------------------------------------
@ -88,7 +88,7 @@ void _sinhrat(PRAT* px, int32_t precision)
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;
@ -169,7 +169,7 @@ void _coshrat(PRAT* px, uint32_t radix, int32_t precision)
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;
@ -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;

View File

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

View File

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

View File

@ -43,7 +43,7 @@ namespace
ApplicationViewModel::ApplicationViewModel()
: m_CalculatorViewModel(nullptr)
, m_DateCalcViewModel(nullptr)
, m_GraphingCalcViewModel(nullptr)
, m_GraphingCalcViewModel(nullptr)
, m_ConverterViewModel(nullptr)
, m_PreviousMode(ViewMode::None)
, m_mode(ViewMode::None)
@ -86,7 +86,7 @@ void ApplicationViewModel::Initialize(ViewMode mode)
}
catch (const std::exception& e)
{
TraceLogger::GetInstance().LogStandardException(mode, __FUNCTIONW__, e);
TraceLogger::GetInstance()->LogStandardException(mode, __FUNCTIONW__, e);
if (!TryRecoverFromNavigationModeFailure())
{
// Could not navigate to standard mode either.
@ -96,7 +96,7 @@ void ApplicationViewModel::Initialize(ViewMode mode)
}
catch (Exception ^ e)
{
TraceLogger::GetInstance().LogPlatformException(mode, __FUNCTIONW__, e);
TraceLogger::GetInstance()->LogPlatformException(mode, __FUNCTIONW__, e);
if (!TryRecoverFromNavigationModeFailure())
{
// Could not navigate to standard mode either.
@ -160,7 +160,7 @@ void ApplicationViewModel::OnModeChanged()
}
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.
// 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
if (NavCategory::IsValidViewMode(m_PreviousMode))
{
TraceLogger::GetInstance().LogModeChange(m_mode);
TraceLogger::GetInstance()->LogModeChange(m_mode);
}
else
{
TraceLogger::GetInstance().LogWindowCreated(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
TraceLogger::GetInstance()->LogWindowCreated(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
}
RaisePropertyChanged(ClearMemoryVisibilityPropertyName);

View File

@ -315,12 +315,8 @@
<ClInclude Include="ApplicationViewModel.h" />
<ClInclude Include="Common\AlwaysSelectedCollectionView.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\NarratorAnnouncementHostFactory.h" />
<ClInclude Include="Common\Automation\NarratorNotifier.h" />
<ClInclude Include="Common\Automation\NotificationHost.h" />
<ClInclude Include="Common\BindableBase.h" />
<ClInclude Include="Common\BitLength.h" />
<ClInclude Include="Common\CalculatorButtonPressedEventArgs.h" />
@ -341,6 +337,7 @@
<ClInclude Include="Common\MyVirtualKey.h" />
<ClInclude Include="Common\NavCategory.h" />
<ClInclude Include="Common\NetworkManager.h" />
<ClInclude Include="Common\NumberBase.h" />
<ClInclude Include="Common\TraceActivity.h" />
<ClInclude Include="Common\TraceLogger.h" />
<ClInclude Include="Common\Utils.h" />
@ -361,16 +358,12 @@
<ClInclude Include="StandardCalculatorViewModel.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="UnitConverterViewModel.h" />
<ClInclude Include="ViewState.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ApplicationViewModel.cpp" />
<ClCompile Include="Common\AppResourceProvider.cpp" />
<ClCompile Include="Common\Automation\LiveRegionHost.cpp" />
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp" />
<ClCompile Include="Common\Automation\NarratorAnnouncementHostFactory.cpp" />
<ClCompile Include="Common\Automation\NarratorNotifier.cpp" />
<ClCompile Include="Common\Automation\NotificationHost.cpp" />
<ClCompile Include="Common\BindableBase.cpp" />
<ClCompile Include="Common\CalculatorButtonPressedEventArgs.cpp" />
<ClCompile Include="Common\CalculatorDisplay.cpp" />
@ -407,7 +400,6 @@
</ClCompile>
<ClCompile Include="StandardCalculatorViewModel.cpp" />
<ClCompile Include="UnitConverterViewModel.cpp" />
<ClCompile Include="ViewState.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CalcManager\CalcManager.vcxproj">
@ -440,12 +432,12 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<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>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<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>
<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>
</Project>

View File

@ -1,15 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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="DateCalculatorViewModel.cpp" />
<ClCompile Include="HistoryItemViewModel.cpp" />
<ClCompile Include="HistoryViewModel.cpp" />
<ClCompile Include="MemoryItemViewModel.cpp" />
<ClCompile Include="pch.cpp" />
<ClCompile Include="StandardCalculatorViewModel.cpp" />
<ClCompile Include="UnitConverterViewModel.cpp" />
<ClCompile Include="ViewState.cpp" />
<ClCompile Include="Common\AppResourceProvider.cpp">
<Filter>Common</Filter>
</ClCompile>
@ -58,63 +71,53 @@
<ClCompile Include="Common\Utils.cpp">
<Filter>Common</Filter>
</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">
<Filter>Common\Automation</Filter>
</ClCompile>
<ClCompile Include="Common\Automation\NotificationHost.cpp">
<Filter>Common\Automation</Filter>
</ClCompile>
<ClCompile Include="Common\Automation\LiveRegionHost.cpp">
<Filter>Common\Automation</Filter>
</ClCompile>
<ClCompile Include="DataLoaders\UnitConverterDataLoader.cpp">
<ClCompile Include="DataLoaders\CurrencyDataLoader.cpp">
<Filter>DataLoaders</Filter>
</ClCompile>
<ClCompile Include="DataLoaders\CurrencyHttpClient.cpp">
<Filter>DataLoaders</Filter>
</ClCompile>
<ClCompile Include="GraphingCalculator\GraphingCalculatorViewModel.cpp">
<Filter>GraphingCalculator</Filter>
<ClCompile Include="DataLoaders\UnitConverterDataLoader.cpp">
<Filter>DataLoaders</Filter>
</ClCompile>
<ClCompile Include="GraphingCalculator\EquationViewModel.cpp">
<Filter>GraphingCalculator</Filter>
</ClCompile>
<ClCompile Include="DataLoaders\CurrencyDataLoader.cpp">
<Filter>DataLoaders</Filter>
<ClCompile Include="GraphingCalculator\GraphingCalculatorViewModel.cpp">
<Filter>GraphingCalculator</Filter>
</ClCompile>
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp">
<Filter>Common\Automation</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="ApplicationViewModel.h" />
<ClInclude Include="DateCalculatorViewModel.h" />
<ClInclude Include="HistoryItemViewModel.h" />
<ClInclude Include="HistoryViewModel.h" />
<ClInclude Include="MemoryItemViewModel.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="StandardCalculatorViewModel.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="UnitConverterViewModel.h" />
<ClInclude Include="ViewState.h" />
<ClInclude Include="Common\AlwaysSelectedCollectionView.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\AppResourceProvider.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\BindableBase.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\AlwaysSelectedCollectionView.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\BitLength.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\CalculatorButtonPressedEventArgs.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\CalculatorButtonUser.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\CalculatorDisplay.h">
<Filter>Common</Filter>
</ClInclude>
@ -145,25 +148,22 @@
<ClInclude Include="Common\KeyboardShortcutManager.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\LocalizationStringUtil.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\LocalizationService.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\LocalizationSettings.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\NavCategory.h">
<ClInclude Include="Common\LocalizationStringUtil.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\MyVirtualKey.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\NetworkManager.h">
<ClInclude Include="Common\NavCategory.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\TraceActivity.h">
<ClInclude Include="Common\NetworkManager.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\TraceLogger.h">
@ -175,26 +175,14 @@
<ClInclude Include="Common\ValidatingConverters.h">
<Filter>Common</Filter>
</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">
<Filter>Common\Automation</Filter>
</ClInclude>
<ClInclude Include="Common\Automation\NotificationHost.h">
<Filter>Common\Automation</Filter>
<ClInclude Include="DataLoaders\CurrencyDataLoader.h">
<Filter>DataLoaders</Filter>
</ClInclude>
<ClInclude Include="Common\Automation\INarratorAnnouncementHost.h">
<Filter>Common\Automation</Filter>
</ClInclude>
<ClInclude Include="Common\Automation\LiveRegionHost.h">
<Filter>Common\Automation</Filter>
<ClInclude Include="DataLoaders\CurrencyHttpClient.h">
<Filter>DataLoaders</Filter>
</ClInclude>
<ClInclude Include="DataLoaders\ICurrencyHttpClient.h">
<Filter>DataLoaders</Filter>
@ -205,43 +193,38 @@
<ClInclude Include="DataLoaders\UnitConverterDataLoader.h">
<Filter>DataLoaders</Filter>
</ClInclude>
<ClInclude Include="Common\TraceActivity.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="DataLoaders\DataLoaderMockConstants.h">
<Filter>DataLoaders</Filter>
</ClInclude>
<ClInclude Include="DataLoaders\CurrencyHttpClient.h">
<Filter>DataLoaders</Filter>
<ClInclude Include="Common\Automation\NarratorAnnouncement.h">
<Filter>Common\Automation</Filter>
</ClInclude>
<ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h">
<Filter>GraphingCalculator</Filter>
<ClInclude Include="Common\BitLength.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\NumberBase.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="GraphingCalculator\EquationViewModel.h">
<Filter>GraphingCalculator</Filter>
</ClInclude>
<ClInclude Include="DataLoaders\CurrencyDataLoader.h">
<Filter>DataLoaders</Filter>
<ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h">
<Filter>GraphingCalculator</Filter>
</ClInclude>
<ClInclude Include="GraphingCalculatorEnums.h">
<Filter>Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="DataLoaders\DefaultFromToCurrency.json">
<Filter>DataLoaders</Filter>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Filter Include="Common\Automation">
<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>
<Page Include="$(MSBuildThisFileDirectory)DensityStyles\Compact.xaml" />
</ItemGroup>
</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.
#include "pch.h"
@ -14,9 +14,9 @@ AppResourceProvider::AppResourceProvider()
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;
}

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.
#pragma once
namespace CalculatorApp
{
class AppResourceProvider
public ref class AppResourceProvider sealed
{
public:
static AppResourceProvider& GetInstance();
static AppResourceProvider ^ GetInstance();
Platform::String ^ GetResourceString(_In_ Platform::String ^ key);
Platform::String ^ GetCEngineString(_In_ Platform::String ^ key);

View File

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

View File

@ -5,32 +5,6 @@
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
ref class NarratorAnnouncement sealed
{
@ -41,14 +15,14 @@ public
property Platform::String
^ 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);
@ -61,13 +35,13 @@ public
NarratorAnnouncement(
Platform::String ^ announcement,
Platform::String ^ activityId,
AutomationNotificationKind kind,
AutomationNotificationProcessing processing);
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind kind,
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing processing);
Platform::String ^ m_announcement;
Platform::String ^ m_activityId;
AutomationNotificationKind m_kind;
AutomationNotificationProcessing m_processing;
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind m_kind;
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing m_processing;
};
// CalculatorAnnouncement is intended to contain only static methods

View File

@ -5,7 +5,6 @@
#include "pch.h"
#include "NarratorNotifier.h"
#include "NarratorAnnouncementHostFactory.h"
using namespace CalculatorApp::Common::Automation;
using namespace Platform;
@ -17,14 +16,22 @@ DependencyProperty ^ NarratorNotifier::s_announcementProperty;
NarratorNotifier::NarratorNotifier()
{
m_announcementHost = NarratorAnnouncementHostFactory::MakeHost();
}
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.
// Declaration of the NarratorNotifier class.
#pragma once
#include "INarratorAnnouncementHost.h"
#include "NarratorAnnouncement.h"
namespace CalculatorApp::Common::Automation
{
@ -47,6 +47,6 @@ public
static Windows::UI::Xaml::DependencyProperty ^ s_announcementProperty;
private:
INarratorAnnouncementHost ^ m_announcementHost;
Windows::UI::Xaml::UIElement ^ m_announcementElement;
};
}

View File

@ -63,6 +63,10 @@ public
IsStandardMode = (int)CM::Command::ModeBasic,
None = (int)CM::Command::CommandNULL,
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,
Ror = (int)CM::Command::CommandROR,
Rol = (int)CM::Command::CommandROL,
@ -84,17 +88,38 @@ public
InvSinh = (int)CM::Command::CommandASINH,
InvCosh = (int)CM::Command::CommandACOSH,
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,
Dword = (int)CM::Command::CommandDword,
Word = (int)CM::Command::CommandWord,
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,
X,

View File

@ -9,6 +9,7 @@
using namespace CalculatorApp;
using namespace CalculationManager;
using namespace Platform;
using namespace std;
CalculatorDisplay::CalculatorDisplay()
@ -31,7 +32,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue
{
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(
_Inout_ std::shared_ptr<CalculatorVector<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::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands)
{
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 SetIsInError(bool isError) override;
void SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) override;
_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) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
@ -28,6 +28,7 @@ namespace CalculatorApp
void MaxDigitsReached() override;
void BinaryOperatorReceived() override;
void MemoryItemChanged(unsigned int indexOfMemory) override;
void InputChanged() override;
private:
Platform::WeakReference m_callbackReference;

View File

@ -11,13 +11,18 @@ using namespace concurrency;
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::System;
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,
// 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_wspcLParenSigned = c_wspc + L"([-+]?[(])*" + c_wspc;
static const wstring c_wspcRParens = c_wspc + L"[)]*" + c_wspc;
static const wstring c_signedDecFloat = L"[-+]?\\d*(\\d|[.])\\d*";
static const wstring c_signedDecFloat = L"(?:[-+]?(?:\\d+(\\.\\d*)?|\\.\\d+))";
static const wstring c_optionalENotation = L"(?:e[+-]?\\d+)?";
// Programmer Mode Integer patterns
// 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}";
// RegEx Patterns used by various modes
static const array<wregex, 1> standardModePatterns = { wregex(c_wspc + c_signedDecFloat + c_wspc) };
static const array<wregex, 2> scientificModePatterns = {
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_wspcRParens),
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + L"e[+-]?\\d+" + c_wspcRParens)
};
static const array<wregex, 1> standardModePatterns = { wregex(c_wspc + c_signedDecFloat + c_optionalENotation + c_wspc) };
static const array<wregex, 1> scientificModePatterns = { wregex(
L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_optionalENotation + c_wspcRParens) };
static const array<array<wregex, 5>, 4> programmerModePatterns = {
{ // Hex numbers like 5F, 4A0C, 0xa9, 0xFFull, 47CDh
{ 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 + 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)
{
@ -65,7 +69,7 @@ void CopyPasteManager::CopyToClipboard(String ^ stringToCopy)
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
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 1.3e12(as of now we allow 1.3e+12)
return create_task((dataPackageView->GetTextAsync(::StandardDataFormats::Text)))
.then(
[mode, modeType, programmerNumberBase, bitLengthType](String ^ pastedText) {
return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType);
},
task_continuation_context::use_arbitrary());
return create_async([dataPackageView, mode, modeType, programmerNumberBase, bitLengthType] {
return create_task(dataPackageView->GetTextAsync(::StandardDataFormats::Text))
.then(
[mode, modeType, programmerNumberBase, bitLengthType](String ^ pastedText) {
return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType);
},
task_continuation_context::use_arbitrary());
});
}
int CopyPasteManager::ClipboardTextFormat()
bool CopyPasteManager::HasStringToPaste()
{
const auto dataPackageView = Clipboard::GetContent();
for (int i = 0; i < RTL_NUMBER_OF(supportedFormats); i++)
{
if (dataPackageView->Contains(supportedFormats[i]))
{
return i;
}
}
return -1;
return Clipboard::GetContent()->Contains(StandardDataFormats::Text);
}
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
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType)
String
^ CopyPasteManager::ValidatePasteExpression(
String ^ pastedText,
ViewMode mode,
CategoryGroupType modeType,
NumberBase programmerNumberBase,
BitLength bitLengthType)
{
if (pastedText->Length() > MaxPasteableLength)
{
// return NoOp to indicate don't paste anything.
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"PastedExpressionSizeGreaterThanMaxAllowed");
return StringReference(PasteErrorString);
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"PastedExpressionSizeGreaterThanMaxAllowed");
return PasteErrorString;
}
wstring pasteExpression = pastedText->Data();
// 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
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 (!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.
// Operands vector will have the list of operands in the pasteExpression
vector<wstring> operands = ExtractOperands(pasteExpression, mode);
if (operands.empty())
auto operands = ExtractOperands(StringReference(pasteExpression.c_str()), mode);
if (operands->Size == 0)
{
// return NoOp to indicate don't paste anything.
return StringReference(PasteErrorString);
return PasteErrorString;
}
if (modeType == CategoryGroupType::Converter)
{
operands = { pasteExpression };
operands->Clear();
operands->Append(ref new String(pasteExpression.c_str()));
}
// validate each operand with patterns for different modes
if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType))
{
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"InvalidExpressionForPresentMode");
return StringReference(PasteErrorString);
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"InvalidExpressionForPresentMode");
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;
bool haveOperator = false;
bool startExpCounting = false;
@ -161,51 +162,72 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
bool isPreviousOpenParen = 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
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 (c_validCharacterSet.find(pasteExpression.at(i)) == wstring_view::npos)
if (validCharacterSet.find(currentChar) == wstring_view::npos)
{
continue;
}
if (operands.size() >= MaxOperandCount)
if (operands->Size >= MaxOperandCount)
{
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ExtractOperands", L"OperandCountGreaterThanMaxCount");
operands.clear();
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ExtractOperands", L"OperandCountGreaterThanMaxCount");
operands->Clear();
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++;
// to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999.
if (expLength > MaxExponentLength)
{
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ExtractOperands", L"ExponentLengthGreaterThanMaxLength");
operands.clear();
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ExtractOperands", L"ExponentLengthGreaterThanMaxLength");
operands->Clear();
return operands;
}
}
isPreviousOperator = false;
}
if ((mode != ViewMode::Programmer) && (pasteExpression.at(i) == L'e'))
else if (currentChar == L'e')
{
startExpCounting = true;
if (mode != ViewMode::Programmer)
{
startExpCounting = true;
}
isPreviousOperator = false;
}
if (((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-') || (pasteExpression.at(i) == L'*') || (pasteExpression.at(i) == L'/')))
else if (currentChar == L'+' || currentChar == L'-' || currentChar == L'*' || currentChar == L'/' || currentChar == L'^' || currentChar == 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(+-)
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;
continue;
@ -216,7 +238,7 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
expLength = 0;
haveOperator = 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;
}
else
@ -224,26 +246,31 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
isPreviousOperator = false;
}
isPreviousOpenParen = (pasteExpression.at(i) == L'(');
isPreviousOpenParen = (currentChar == L'(');
startOfExpression = false;
}
if (!haveOperator)
{
operands.clear();
operands.push_back(pasteExpression);
operands->Clear();
operands->Append(pasteExpression);
}
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;
}
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;
}
@ -260,14 +287,16 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
}
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)
{
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;
for (const auto& operand : operands)
@ -276,34 +305,34 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
bool operandMatched = false;
for (const auto& pattern : patterns)
{
operandMatched = operandMatched || regex_match(operand, pattern);
operandMatched = operandMatched || regex_match(operand->Data(), pattern);
}
if (operandMatched)
{
// 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.
const wstring operandValue = SanitizeOperand(operand);
auto operandValue = SanitizeOperand(operand);
// 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;
break;
}
// 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;
if (!TryOperandToULL(operandValue, programmerNumberBase, operandAsULL))
auto operandAsULL = TryOperandToULL(operandValue, programmerNumberBase);
if (operandAsULL == nullptr)
{
// Operand was empty, received invalid_argument, or received out_of_range. Input is invalid.
expMatched = false;
break;
}
if (operandAsULL > maxOperandValue)
if (operandAsULL->Value > maxOperandLengthAndValue.maxValue)
{
expMatched = false;
break;
@ -317,18 +346,23 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
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 uint64_t defaultMaxValue = 0;
CopyPasteMaxOperandLengthAndValue res;
if (mode == ViewMode::Standard)
{
return make_pair(MaxStandardOperandLength, defaultMaxValue);
res.maxLength = MaxStandardOperandLength;
res.maxValue = defaultMaxValue;
return res;
}
else if (mode == ViewMode::Scientific)
{
return make_pair(MaxScientificOperandLength, defaultMaxValue);
res.maxLength = MaxScientificOperandLength;
res.maxValue = defaultMaxValue;
return res;
}
else if (mode == ViewMode::Programmer)
{
@ -352,65 +386,69 @@ pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo
double bitsPerDigit = 0;
switch (programmerNumberBase)
{
case BinBase:
case NumberBase::BinBase:
bitsPerDigit = log2(2);
break;
case OctBase:
case NumberBase::OctBase:
bitsPerDigit = log2(8);
break;
case DecBase:
case NumberBase::DecBase:
bitsPerDigit = log2(10);
break;
case HexBase:
case NumberBase::HexBase:
bitsPerDigit = log2(16);
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));
return make_pair(maxLength, maxValue);
res.maxLength = maxLength;
res.maxValue = maxValue;
return res;
}
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.front() == L'-')
if (operand->Length() == 0 || operand->Data()[0] == L'-')
{
return false;
return nullptr;
}
int intBase;
switch (numberBase)
{
case HexBase:
case NumberBase::HexBase:
intBase = 16;
break;
case OctBase:
case NumberBase::OctBase:
intBase = 8;
break;
case BinBase:
case NumberBase::BinBase:
intBase = 2;
break;
default:
case DecBase:
case NumberBase::DecBase:
intBase = 10;
break;
}
@ -418,8 +456,7 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
wstring::size_type size = 0;
try
{
result = stoull(operand, &size, intBase);
return true;
return stoull(operand->Data(), &size, intBase);
}
catch (const invalid_argument&)
{
@ -430,14 +467,14 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
// 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)
{
return operand.length();
return operand->Length();
}
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 (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
{
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> suffixes{};
switch (numberBase)
{
case BinBase:
case NumberBase::BinBase:
prefixes = { L"0B", L"0Y" };
suffixes = { L"B" };
break;
case DecBase:
case NumberBase::DecBase:
prefixes = { L"-", L"0N" };
break;
case OctBase:
case NumberBase::OctBase:
prefixes = { L"0T", L"0O" };
break;
case HexBase:
case NumberBase::HexBase:
prefixes = { L"0X" };
suffixes = { L"H" };
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" };
suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end());
wstring operandUpper = operand;
wstring operandUpper = wstring(operand->Data());
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
// 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:
@ -556,8 +594,13 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
// Indian rupee(₹) - 8377
// pound(£) - 163
// 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 };
return Utils::RemoveUnwantedCharsFromWstring(input, unWantedChars, 18);
constexpr wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 };
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 "NavCategory.h"
#include "BitLength.h"
#include "NumberBase.h"
namespace CalculatorUnitTests
{
@ -14,78 +15,119 @@ namespace CalculatorUnitTests
namespace CalculatorApp
{
inline constexpr auto HexBase = 5;
inline constexpr auto DecBase = 6;
inline constexpr auto OctBase = 7;
inline constexpr auto BinBase = 8;
public
value struct CopyPasteMaxOperandLengthAndValue
{
unsigned int maxLength;
unsigned long long maxValue;
};
class CopyPasteManager
public ref class CopyPasteManager sealed
{
public:
static void CopyToClipboard(Platform::String ^ stringToCopy);
static concurrency::task<Platform::String ^> GetStringToPaste(
CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1,
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown);
static bool HasStringToPaste()
static Windows::Foundation::IAsyncOperation<
Platform::String
^> ^ GetStringToPaste(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, CalculatorApp::Common::NumberBase programmerNumberBase, CalculatorApp::Common::BitLength bitLengthType);
static bool HasStringToPaste();
static bool IsErrorMessage(Platform::String ^ message);
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
^ ValidatePasteExpression(
Platform::String ^ pastedText,
CalculatorApp::Common::ViewMode mode,
int programmerNumberBase,
CalculatorApp::Common::NumberBase programmerNumberBase,
CalculatorApp::Common::BitLength bitLengthType);
static Platform::String
^ ValidatePasteExpression(
Platform::String ^ pastedText,
CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase,
CalculatorApp::Common::NumberBase programmerNumberBase,
CalculatorApp::Common::BitLength bitLengthType);
static std::vector<std::wstring>
ExtractOperands(const std::wstring& pasteExpression, CalculatorApp::Common::ViewMode mode);
static CopyPasteMaxOperandLengthAndValue GetMaxOperandLengthAndValue(
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(
std::vector<std::wstring> operands,
Windows::Foundation::Collections::IVector<Platform::String ^> ^ operands,
CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1,
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown);
static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(
CalculatorApp::Common::NumberBase programmerNumberBase,
CalculatorApp::Common::BitLength bitLengthType);
static Platform::String ^ SanitizeOperand(Platform::String ^ operand);
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::CategoryGroupType modeType,
int programmerNumberBase = -1,
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown);
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);
CalculatorApp::Common::NumberBase programmerNumberBase);
static ULONG32 ProgrammerOperandLength(Platform::String ^ operand, CalculatorApp::Common::NumberBase numberBase);
static constexpr size_t MaxStandardOperandLength = 16;
static constexpr size_t MaxScientificOperandLength = 32;
static constexpr size_t MaxConverterInputLength = 16;
static constexpr size_t MaxOperandCount = 100;
static constexpr size_t MaxPasteableLength = 512;
static constexpr size_t MaxExponentLength = 4;
static constexpr size_t MaxProgrammerBitLength = 64;
static Platform::String ^ supportedFormats[];
friend class CalculatorUnitTests::CopyPasteManagerTest;
private:
static constexpr size_t MaxStandardOperandLengthValue = 16;
static constexpr size_t MaxScientificOperandLengthValue = 32;
static constexpr size_t MaxConverterInputLengthValue = 16;
static constexpr size_t MaxOperandCountValue = 100;
static constexpr size_t MaxExponentLengthValue = 4;
static constexpr size_t MaxProgrammerBitLengthValue = 64;
static constexpr size_t MaxPasteableLengthValue = 512;
};
}

View File

@ -9,6 +9,11 @@ using namespace Windows::Foundation;
using namespace Windows::Globalization;
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)
{
m_calendar = ref new Calendar();
@ -18,10 +23,9 @@ DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier)
// Adding Duration to a Date
// Returns: True if function succeeds to calculate the date else returns False
bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate)
IBox<DateTime> ^ DateCalculationEngine::AddDuration(DateTime startDate, DateDifference duration)
{
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
try
{
m_calendar->SetDateTime(startDate);
@ -50,7 +54,8 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
m_calendar->AddDays(duration.day);
}
*endDate = m_calendar->GetDateTime();
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
return m_calendar->GetDateTime();
}
catch (Platform::InvalidArgumentException ^ ex)
{
@ -58,17 +63,13 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
// Do nothing
return false;
return nullptr;
}
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
return true;
}
// Subtracting Duration from a Date
// 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();
@ -101,7 +102,18 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
{
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)
{
@ -109,17 +121,12 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
// 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
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 endDate;
@ -177,8 +184,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
{
// Operation failed due to out of bound result
// For example: 31st Dec, 9999 - last valid date
*difference = DateDifferenceUnknown;
return false;
return nullptr;
}
}
@ -194,8 +200,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
if (differenceInDates[unitIndex] == 0)
{
// differenceInDates[unitIndex] is unsigned, the value can't be negative
*difference = DateDifferenceUnknown;
return false;
return nullptr;
}
differenceInDates[unitIndex] -= 1;
pivotDate = tempPivotDate;
@ -220,8 +225,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
{
// Operation failed due to out of bound result
// For example: 31st Dec, 9999 - last valid date
*difference = DateDifferenceUnknown;
return false;
return nullptr;
}
}
} 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)
{
// daysDiff is unsigned, the value can't be negative
*difference = DateDifferenceUnknown;
return false;
return nullptr;
}
daysDiff = signedDaysDiff;
@ -244,11 +247,12 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
differenceInDates[3] = daysDiff;
difference->year = differenceInDates[0];
difference->month = differenceInDates[1];
difference->week = differenceInDates[2];
difference->day = differenceInDates[3];
return true;
DateDifference result;
result.year = differenceInDates[0];
result.month = differenceInDates[1];
result.week = differenceInDates[2];
result.day = differenceInDates[3];
return result;
}
// 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 DateDifference
public
value struct DateDifference
{
int year = 0;
int month = 0;
int week = 0;
int day = 0;
bool operator==(const DateDifference& dd) const
{
return year == dd.year && month == dd.month && week == dd.week && day == day;
}
int year;
int month;
int week;
int day;
};
const DateDifference DateDifferenceUnknown{ INT_MIN, INT_MIN, INT_MIN, INT_MIN };
class DateCalculationEngine
public
ref class DateCalculationEngine sealed
{
public:
// Constructor
DateCalculationEngine(_In_ Platform::String ^ calendarIdentifier);
// Public Methods
bool __nothrow
AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime* endDate);
bool __nothrow SubtractDuration(
_In_ Windows::Foundation::DateTime startDate,
_In_ const DateDifference& duration,
_Out_ Windows::Foundation::DateTime* endDate);
bool __nothrow TryGetDateDifference(
_In_ Windows::Foundation::DateTime date1,
_In_ Windows::Foundation::DateTime date2,
_In_ DateUnit outputFormat,
_Out_ DateDifference* difference);
Platform::IBox<Windows::Foundation::DateTime> ^ AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration);
Platform::IBox<Windows::Foundation::DateTime> ^ SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration);
Platform::IBox<
DateDifference> ^ TryGetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat);
private:
// 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");
}
wstring EngineResourceProvider::GetCEngineString(const wstring& id)
wstring EngineResourceProvider::GetCEngineString(wstring_view id)
{
const auto& localizationSettings = LocalizationSettings::GetInstance();
@ -43,7 +43,7 @@ namespace CalculatorApp
return numberGroupingString;
}
StringReference idRef(id.c_str());
StringReference idRef(id.data(), id.length());
String ^ str = m_resLoader->GetString(idRef);
return str->Begin();
}

View File

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

View File

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

View File

@ -94,16 +94,16 @@ LocalizationService::LocalizationService(_In_ const wchar_t * const overridedLan
m_locale = locale("");
}
auto resourceLoader = AppResourceProvider::GetInstance();
m_fontFamilyOverride = resourceLoader.GetResourceString(L"LocalizedFontFamilyOverride");
m_fontFamilyOverride = resourceLoader->GetResourceString(L"LocalizedFontFamilyOverride");
String ^ reserved = L"RESERVED_FOR_FONTLOC";
m_overrideFontApiValues = ((m_fontFamilyOverride != nullptr) && (m_fontFamilyOverride != reserved));
if (m_overrideFontApiValues)
{
String ^ localizedUICaptionFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride");
String ^ localizedUITextFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUITextFontSizeFactorOverride");
String ^ localizedFontWeightOverride = resourceLoader.GetResourceString(L"LocalizedFontWeightOverride");
String ^ localizedUICaptionFontSizeFactorOverride = resourceLoader->GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride");
String ^ localizedUITextFontSizeFactorOverride = resourceLoader->GetResourceString(L"LocalizedUITextFontSizeFactorOverride");
String ^ localizedFontWeightOverride = resourceLoader->GetResourceString(L"LocalizedFontWeightOverride");
// If any of the font overrides are modified then all of them need to be modified
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"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
make_pair<wstring, wstring>(L"94", L"Factorial"),
make_pair<wstring, wstring>(L"35", L"DegreeMinuteSecond"),
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
make_pair<wstring, wstring>(L"9", L"LeftShift"),
make_pair<wstring, wstring>(L"10", L"RightShift"),
make_pair<wstring, wstring>(L"LogBaseX", L"Logx"),
// Y Root scientific function
make_pair<wstring, wstring>(L"16", L"YRoot")
@ -521,12 +554,12 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
unordered_map<wstring, wstring> tokenToReadableNameMap{};
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)
{
wstring engineStr = resProvider.GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
wstring automationName = resProvider.GetResourceString(StringReference(keyPair.second.c_str()))->Data();
wstring engineStr = resProvider->GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
wstring automationName = resProvider->GetResourceString(StringReference(keyPair.second.c_str()))->Data();
tokenToReadableNameMap.emplace(engineStr + openParen, automationName);
}
@ -534,15 +567,15 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
for (const auto& keyPair : s_noParenEngineKeyResourceMap)
{
wstring engineStr = resProvider.GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
wstring automationName = resProvider.GetResourceString(StringReference(keyPair.second.c_str()))->Data();
wstring engineStr = resProvider->GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
wstring automationName = resProvider->GetResourceString(StringReference(keyPair.second.c_str()))->Data();
tokenToReadableNameMap.emplace(engineStr, automationName);
}
s_noParenEngineKeyResourceMap.clear();
// Also replace hyphens with "minus"
wstring minusText = resProvider.GetResourceString(L"minus")->Data();
wstring minusText = resProvider->GetResourceString(L"minus")->Data();
tokenToReadableNameMap.emplace(L"-", minusText);
return tokenToReadableNameMap;
@ -559,7 +592,7 @@ String ^ LocalizationService::GetNarratorReadableToken(String ^ rawToken)
}
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;
}
}

View File

@ -58,10 +58,11 @@ namespace CalculatorApp
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,
_In_ Platform::String ^ calendarIdentifier,
_In_ Platform::String ^ clockIdentifier) const;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter
^ GetRegionalSettingsAwareDateTimeFormatter(
_In_ Platform::String ^ format,
_In_ Platform::String ^ calendarIdentifier,
_In_ Platform::String ^ clockIdentifier) 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")
{
return ref new Platform::String(localizedString.c_str());
return localizedString;
}
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
for (; i < length; ++i)
{
wchar_t ch = localizedString[i];
wchar_t ch = localizedStringData[i];
if (!IsEnUsDigit(ch))
{
for (int j = 0; j < 10; ++j)
@ -281,18 +282,17 @@ namespace CalculatorApp
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();
rawValue->reserve(length);
for (size_t i = 0; i < length; i++)
std::wstringstream stream;
for (auto c = source->Begin(); c < source->End(); ++c)
{
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

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.
#pragma once
@ -9,50 +9,78 @@ namespace CalculatorApp
{
namespace Common
{
class LocalizationStringUtil
class LocalizationStringUtilInternal
{
public:
static std::wstring GetLocalizedString(const wchar_t* pMessage, ...)
static Platform::String ^ GetLocalizedString(Platform::String ^ pMessage, ...)
{
std::wstring returnString = L"";
const UINT32 length = 1024;
std::unique_ptr<wchar_t[]> spBuffer = std::unique_ptr<wchar_t[]>(new wchar_t[length]);
va_list args = NULL;
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);
if (fmtReturnVal != 0)
{
returnString = spBuffer.get();
return ref new Platform::String(spBuffer.get());
}
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())
else
{
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 ANGLE_ID = 15;
static constexpr int CURRENCY_ID = 16;
static constexpr int GRAPHING_ID = 17;
static constexpr int GRAPHING_ID = 17;
// ^^^ THESE CONSTANTS SHOULD NEVER CHANGE ^^^
// 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",
CategoryGroupType::Calculator,
MyVirtualKey::Number1,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Graphing,
GRAPHING_ID,
L"Graphing",
L"GraphingCalculatorMode",
L"\uF770",
CategoryGroupType::Calculator,
MyVirtualKey::Number5,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Scientific,
SCIENTIFIC_ID,
@ -82,6 +74,14 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
CategoryGroupType::Calculator,
MyVirtualKey::Number3,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Graphing,
GRAPHING_ID,
L"Graphing",
L"GraphingCalculatorMode",
L"\uF770",
CategoryGroupType::Calculator,
MyVirtualKey::Number5,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Date,
DATE_ID,
L"Date",
@ -169,7 +169,7 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
L"\uE945",
CategoryGroupType::Converter,
MyVirtualKey::None,
POSITIVE_ONLY },
SUPPORTS_NEGATIVE },
NavCategoryInitializer{ ViewMode::Data,
DATA_ID,
L"Data",
@ -193,7 +193,7 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
L"\uF515",
CategoryGroupType::Converter,
MyVirtualKey::None,
POSITIVE_ONLY } };
SUPPORTS_NEGATIVE } };
// This function should only be used when storing the mode to app data.
int NavCategory::Serialize(ViewMode mode)
@ -238,9 +238,7 @@ bool NavCategory::IsValidViewMode(ViewMode mode)
bool NavCategory::IsCalculatorViewMode(ViewMode mode)
{
// Historically, Calculator modes are Standard, Scientific, and Programmer.
return !IsDateCalculatorViewMode(mode)
&& !IsGraphingCalculatorViewMode(mode)
&& IsModeInCategoryGroup(mode, CategoryGroupType::Calculator);
return !IsDateCalculatorViewMode(mode) && !IsGraphingCalculatorViewMode(mode) && IsModeInCategoryGroup(mode, CategoryGroupType::Calculator);
}
bool NavCategory::IsGraphingCalculatorViewMode(ViewMode mode)
@ -383,33 +381,28 @@ NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupIniti
m_GroupType = groupInitializer.type;
auto resProvider = AppResourceProvider::GetInstance();
String ^ headerResourceKey = StringReference(groupInitializer.headerResourceKey);
String ^ modeResourceKey = StringReference(groupInitializer.modeResourceKey);
String ^ automationResourceKey = StringReference(groupInitializer.automationResourceKey);
m_Name = resProvider.GetResourceString(headerResourceKey);
String ^ groupMode = resProvider.GetResourceString(modeResourceKey);
String ^ automationName = resProvider.GetResourceString(automationResourceKey);
m_Name = resProvider->GetResourceString(StringReference(groupInitializer.headerResourceKey));
String ^ groupMode = resProvider->GetResourceString(StringReference(groupInitializer.modeResourceKey));
String ^ automationName = resProvider->GetResourceString(StringReference(groupInitializer.automationResourceKey));
String ^ navCategoryHeaderAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryHeader_AutomationNameFormat");
m_AutomationName =
ref new String(LocalizationStringUtil::GetLocalizedString(navCategoryHeaderAutomationNameFormat->Data(), automationName->Data()).c_str());
String ^ navCategoryHeaderAutomationNameFormat = resProvider->GetResourceString(L"NavCategoryHeader_AutomationNameFormat");
m_AutomationName = LocalizationStringUtil::GetLocalizedString(navCategoryHeaderAutomationNameFormat, automationName);
String ^ navCategoryItemAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryItem_AutomationNameFormat");
String ^ navCategoryItemAutomationNameFormat = resProvider->GetResourceString(L"NavCategoryItem_AutomationNameFormat");
for (const NavCategoryInitializer& categoryInitializer : s_categoryManifest)
{
if (categoryInitializer.groupType == groupInitializer.type)
{
String ^ nameResourceKey = StringReference(categoryInitializer.nameResourceKey);
String ^ categoryName = resProvider.GetResourceString(nameResourceKey + "Text");
String ^ categoryAutomationName = ref new String(
LocalizationStringUtil::GetLocalizedString(navCategoryItemAutomationNameFormat->Data(), categoryName->Data(), m_Name->Data()).c_str());
String ^ categoryName = resProvider->GetResourceString(nameResourceKey + "Text");
String ^ categoryAutomationName = LocalizationStringUtil::GetLocalizedString(navCategoryItemAutomationNameFormat, categoryName, m_Name);
m_Categories->Append(ref new NavCategory(
categoryName,
categoryAutomationName,
StringReference(categoryInitializer.glyph),
resProvider.GetResourceString(nameResourceKey + "AccessKey"),
resProvider->GetResourceString(nameResourceKey + "AccessKey"),
groupMode,
categoryInitializer.viewMode,
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 Concurrency;
using namespace std;
using namespace Platform;
using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Diagnostics;
@ -57,47 +58,43 @@ namespace CalculatorApp
TraceLogger::TraceLogger()
: g_calculatorProvider(
L"MicrosoftCalculator",
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 })
L"MicrosoftCalculator",
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 })
, // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
m_appLaunchActivity{ nullptr }
{
CoCreateGuid(&sessionGuid);
}
TraceLogger::~TraceLogger()
TraceLogger ^ TraceLogger::GetInstance()
{
}
TraceLogger& TraceLogger::GetInstance()
{
static TraceLogger s_selfInstance;
static TraceLogger ^ s_selfInstance = ref new TraceLogger();
return s_selfInstance;
}
bool TraceLogger::GetTraceLoggingProviderEnabled() const
bool TraceLogger::GetTraceLoggingProviderEnabled()
{
return g_calculatorProvider.Enabled();
}
#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));
}
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));
}
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));
}
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);
}
@ -117,7 +114,7 @@ namespace CalculatorApp
return true;
}
void TraceLogger::LogVisualStateChanged(ViewMode mode, wstring_view state, bool isAlwaysOnTop) const
void TraceLogger::LogVisualStateChanged(ViewMode mode, String ^ state, bool isAlwaysOnTop)
{
if (!GetTraceLoggingProviderEnabled())
{
@ -127,7 +124,7 @@ namespace CalculatorApp
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
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.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_VISUAL_STATE_CHANGED, fields);
@ -152,7 +149,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_WINDOW_ON_CREATED, fields);
}
void TraceLogger::LogModeChange(ViewMode mode) const
void TraceLogger::LogModeChange(ViewMode mode)
{
if (!GetTraceLoggingProviderEnabled())
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())
{
@ -183,7 +180,7 @@ namespace CalculatorApp
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())
{
@ -199,7 +196,7 @@ namespace CalculatorApp
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())
return;
@ -207,13 +204,13 @@ namespace CalculatorApp
LoggingFields fields{};
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"FunctionName", functionName);
fields.AddString(L"Message", errorString);
fields.AddString(L"FunctionName", functionName->Data());
fields.AddString(L"Message", errorString->Data());
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
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())
return;
@ -229,7 +226,7 @@ namespace CalculatorApp
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())
return;
@ -244,7 +241,7 @@ namespace CalculatorApp
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())
return;
@ -291,7 +288,7 @@ namespace CalculatorApp
}
}
void TraceLogger::UpdateWindowCount(size_t windowCount)
void TraceLogger::UpdateWindowCount(uint64 windowCount)
{
if (windowCount == 0)
{
@ -301,6 +298,11 @@ namespace CalculatorApp
currentWindowCount = windowCount;
}
void TraceLogger::DecreaseWindowCount()
{
currentWindowCount = 0;
}
void TraceLogger::LogButtonUsage()
{
if (!GetTraceLoggingProviderEnabled())
@ -348,7 +350,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_DATE_CALCULATION_MODE_USED, fields);
}
void TraceLogger::LogConverterInputReceived(ViewMode mode) const
void TraceLogger::LogConverterInputReceived(ViewMode mode)
{
if (!GetTraceLoggingProviderEnabled())
return;
@ -360,7 +362,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_CONVERTER_INPUT_RECEIVED, fields);
}
void TraceLogger::LogNavBarOpened() const
void TraceLogger::LogNavBarOpened()
{
if (!GetTraceLoggingProviderEnabled())
return;
@ -371,7 +373,7 @@ namespace CalculatorApp
LogLevel2Event(EVENT_NAME_NAV_BAR_OPENED, fields);
}
void TraceLogger::LogInputPasted(ViewMode mode) const
void TraceLogger::LogInputPasted(ViewMode mode)
{
if (!GetTraceLoggingProviderEnabled())
return;

View File

@ -28,33 +28,31 @@ namespace CalculatorApp
}
};
class TraceLogger
public
ref class TraceLogger sealed
{
public:
TraceLogger(_In_ TraceLogger const&) = delete;
TraceLogger const& operator=(_In_ TraceLogger const&) = delete;
~TraceLogger();
static TraceLogger& GetInstance();
bool GetTraceLoggingProviderEnabled() const;
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;
static TraceLogger ^ GetInstance();
bool GetTraceLoggingProviderEnabled();
void LogModeChange(CalculatorApp::Common::ViewMode mode);
void LogHistoryItemLoad(CalculatorApp::Common::ViewMode mode, int historyListSize, int loadedIndex);
void LogMemoryItemLoad(CalculatorApp::Common::ViewMode mode, int memoryListSize, int loadedIndex);
void UpdateButtonUsage(CalculatorApp::NumbersAndOperatorsEnum button, CalculatorApp::Common::ViewMode mode);
void LogButtonUsage();
void LogDateCalculationModeUsed(bool AddSubtractMode);
void UpdateWindowCount(size_t windowCount = 0);
void UpdateWindowCount(uint64 windowCount);
void DecreaseWindowCount();
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 LogConverterInputReceived(CalculatorApp::Common::ViewMode mode) const;
void LogNavBarOpened() const;
void LogError(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, std::wstring_view errorString);
void LogStandardException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e) const;
void LogWinRTException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ winrt::hresult_error const& e) const;
void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e) const;
void LogInputPasted(CalculatorApp::Common::ViewMode mode) const;
void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode);
void LogNavBarOpened();
void LogError(CalculatorApp::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString);
internal :
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);
void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e);
void LogInputPasted(CalculatorApp::Common::ViewMode mode);
private:
// Create an instance of TraceLogger
@ -64,11 +62,11 @@ namespace CalculatorApp
// sampling is involved in Microsoft's diagnostic data collection process.
// 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.
void LogLevel1Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
void LogLevel2Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
void LogLevel3Event(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);
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;
@ -76,7 +74,7 @@ namespace CalculatorApp
std::vector<int> windowIdLog;
GUID sessionGuid;
size_t currentWindowCount = 0;
uint64 currentWindowCount = 0;
winrt::Windows::Foundation::Diagnostics::LoggingActivity m_appLaunchActivity;
};

View File

@ -10,7 +10,6 @@
#include "Common/AppResourceProvider.h"
#include "Common/ExpressionCommandSerializer.h"
#include "Common/ExpressionCommandDeserializer.h"
#include "ViewState.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
@ -50,8 +49,8 @@ String ^ Utils::GetStringValue(String ^ input)
double Utils::GetDoubleFromWstring(wstring input)
{
wchar_t unWantedChars[] = { L' ', L',', 8234, 8235, 8236, 8237 };
wstring ws = RemoveUnwantedCharsFromWstring(input, unWantedChars, 6);
constexpr wchar_t unWantedChars[] = { L' ', L',', 8234, 8235, 8236, 8237 };
wstring ws = RemoveUnwantedCharsFromString(input, unWantedChars);
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 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(
_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens,
_In_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands,
_In_ shared_ptr<vector<pair<wstring, int>>> const& tokens,
_In_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands,
DataWriter ^ writer)
{
unsigned int commandsSize;
IFTPlatformException(commands->GetSize(&commandsSize));
// Save the size of the commands vector
writer->WriteUInt32(commandsSize);
writer->WriteUInt32(static_cast<unsigned int>(commands->size()));
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();
writer->WriteInt32(static_cast<int>(commandType));
exprCmd->Accept(cmdVisitor);
}
unsigned int tokensSize;
IFTPlatformException(tokens->GetSize(&tokensSize));
writer->WriteUInt32(tokensSize);
writer->WriteUInt32(static_cast<unsigned int>(tokens->size()));
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 intData = eachToken.second;
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();
CommandDeserializer cmdDeserializer(reader);
@ -143,26 +121,23 @@ const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::Deseri
auto commandTypeInt = reader->ReadInt32();
CalculationManager::CommandType commandType = static_cast<CalculationManager::CommandType>(commandTypeInt);
shared_ptr<IExpressionCommand> exprCmd = cmdDeserializer.Deserialize(commandType);
commandVector->Append(exprCmd);
commandVector->push_back(exprCmd);
}
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();
for (unsigned int i = 0; i < tokensSize; ++i)
{
pair<wstring, int> eachToken;
auto stringDataLen = reader->ReadUInt32();
auto stringData = reader->ReadString(stringDataLen);
auto intData = reader->ReadInt32();
eachToken.first = stringData->Data();
eachToken.second = intData;
tokenVector->Append(eachToken);
tokenVector->emplace_back(stringData->Data(), intData);
}
return tokenVector;

View File

@ -3,7 +3,6 @@
#pragma once
#include "CalcManager/CalculatorVector.h"
#include "CalcManager/ExpressionCommandInterface.h"
#include "DelegateCommand.h"
#include "GraphingInterfaces/GraphingEnums.h"
@ -210,7 +209,7 @@ public:
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##n##Property; \
\
public:
private:
// Utilities for DependencyProperties
namespace Utils
@ -401,27 +400,34 @@ namespace Utils
void IFTPlatformException(HRESULT hr);
Platform::String ^ GetStringValue(Platform::String ^ input);
bool IsLastCharacterTarget(std::wstring const& input, wchar_t target);
std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size);
// 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);
int GetWindowId();
void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher ^ currentDispatcher);
void SerializeCommandsAndTokens(
_In_ std::shared_ptr<CalculatorVector<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::pair<std::wstring, int>>> const& tokens,
_In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands,
Windows::Storage::Streams::DataWriter ^ writer);
const std::shared_ptr<CalculatorVector<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::shared_ptr<IExpressionCommand>>> DeserializeCommands(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();
bool IsDateTimeOlderThan(Windows::Foundation::DateTime dateTime, const long long duration);
concurrency::task<void> WriteFileToFolder(
Windows::Storage::IStorageFolder ^ folder,
Platform::String ^ fileName,
Platform::String ^ contents,
Windows::Storage::CreationCollisionOption collisionOption);
concurrency::task<Platform::String ^> ReadFileFromFolder(Windows::Storage::IStorageFolder ^ folder, Platform::String ^ fileName);
concurrency::task<void> WriteFileToFolder(Windows::Storage::IStorageFolder^ folder, 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);

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

View File

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

View File

@ -953,7 +953,7 @@ void UnitConverterDataLoader::GetConversionData(_In_ unordered_map<ViewMode, uno
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)

View File

@ -45,13 +45,13 @@ DateCalculatorViewModel::DateCalculatorViewModel()
, m_StrDateResult(L"")
, m_StrDateResultAutomationName(L"")
{
const auto& localizationSettings = LocalizationSettings::GetInstance();
const auto & localizationSettings = LocalizationSettings::GetInstance();
// Initialize Date Output format instances
InitializeDateOutputFormats(localizationSettings.GetCalendarIdentifier());
// 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
auto calendar = ref new Calendar();
// 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()
{
DateDifference dateDiff;
if (m_IsDateDiffMode)
{
DateTime clippedFromDate = ClipTime(FromDate, true);
DateTime clippedToDate = ClipTime(ToDate, true);
// 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;
if (m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat, &dateDiff))
DateDiffResultInDays = dateDiff->Value;
dateDiff = m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat);
if (dateDiff != nullptr)
{
DateDiffResult = dateDiff;
DateDiffResult = dateDiff->Value;
}
else
{
@ -140,26 +140,28 @@ void DateCalculatorViewModel::OnInputsChanged()
}
else
{
DateDifference dateDiff;
dateDiff.day = DaysOffset;
dateDiff.month = MonthsOffset;
dateDiff.year = YearsOffset;
DateTime dateTimeResult;
IBox<DateTime> ^ dateTimeResult;
if (m_IsAddMode)
{
// Add number of Days, Months and Years to a Date
IsOutOfBound = !m_dateCalcEngine->AddDuration(StartDate, dateDiff, &dateTimeResult);
dateTimeResult = m_dateCalcEngine->AddDuration(StartDate, dateDiff);
}
else
{
// 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)
{
DateResult = dateTimeResult;
DateResult = dateTimeResult->Value;
}
}
}
@ -172,17 +174,16 @@ void DateCalculatorViewModel::UpdateDisplayResult()
{
IsDiffInDays = false;
StrDateDiffResultInDays = L"";
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"CalculationFailed");
StrDateDiffResult = AppResourceProvider::GetInstance()->GetResourceString(L"CalculationFailed");
}
else if (m_dateDiffResultInDays.day == 0)
{
// to and from dates the same
IsDiffInDays = true;
StrDateDiffResultInDays = L"";
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates");
StrDateDiffResult = AppResourceProvider::GetInstance()->GetResourceString(L"Date_SameDates");
}
else if (m_dateDiffResult == DateDifferenceUnknown ||
(m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0))
else if (m_dateDiffResult == DateDifferenceUnknown || (m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0))
{
IsDiffInDays = true;
StrDateDiffResultInDays = L"";
@ -206,7 +207,7 @@ void DateCalculatorViewModel::UpdateDisplayResult()
if (m_isOutOfBound)
{
// Display Date out of bound message
StrDateResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_OutOfBoundMessage");
StrDateResult = AppResourceProvider::GetInstance()->GetResourceString(L"Date_OutOfBoundMessage");
}
else
{
@ -218,16 +219,14 @@ void DateCalculatorViewModel::UpdateDisplayResult()
void DateCalculatorViewModel::UpdateStrDateDiffResultAutomationName()
{
String ^ automationFormat = AppResourceProvider::GetInstance().GetResourceString(L"Date_DifferenceResultAutomationName");
wstring localizedAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat->Data(), StrDateDiffResult->Data());
StrDateDiffResultAutomationName = ref new String(localizedAutomationName.c_str());
String ^ automationFormat = AppResourceProvider::GetInstance()->GetResourceString(L"Date_DifferenceResultAutomationName");
StrDateDiffResultAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat, StrDateDiffResult);
}
void DateCalculatorViewModel::UpdateStrDateResultAutomationName()
{
String ^ automationFormat = AppResourceProvider::GetInstance().GetResourceString(L"Date_ResultingDateAutomationName");
wstring localizedAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat->Data(), StrDateResult->Data());
StrDateResultAutomationName = ref new String(localizedAutomationName.c_str());
String ^ automationFormat = AppResourceProvider::GetInstance()->GetResourceString(L"Date_ResultingDateAutomationName");
StrDateResultAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat, StrDateResult);
}
void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String ^ calendarIdentifier)
@ -247,21 +246,21 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
{
wstring result;
bool addDelimiter = false;
AppResourceProvider resourceLoader = AppResourceProvider::GetInstance();
AppResourceProvider ^ resourceLoader = AppResourceProvider::GetInstance();
auto yearCount = m_dateDiffResult.year;
if (yearCount > 0)
{
result += GetLocalizedNumberString(yearCount)->Data();
result += L" ";
result += L' ';
if (yearCount > 1)
{
result += resourceLoader.GetResourceString(L"Date_Years")->Data();
result += resourceLoader->GetResourceString(L"Date_Years")->Data();
}
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
@ -281,15 +280,15 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
}
result += GetLocalizedNumberString(monthCount)->Data();
result += L" ";
result += L' ';
if (monthCount > 1)
{
result += resourceLoader.GetResourceString(L"Date_Months")->Data();
result += resourceLoader->GetResourceString(L"Date_Months")->Data();
}
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 += L" ";
result += L' ';
if (weekCount > 1)
{
result += resourceLoader.GetResourceString(L"Date_Weeks")->Data();
result += resourceLoader->GetResourceString(L"Date_Weeks")->Data();
}
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 += L" ";
result += L' ';
if (dayCount > 1)
{
result += resourceLoader.GetResourceString(L"Date_Days")->Data();
result += resourceLoader->GetResourceString(L"Date_Days")->Data();
}
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
{
wstring result = GetLocalizedNumberString(m_dateDiffResultInDays.day)->Data();
result += L" ";
result += L' ';
// Display the result as '1 day' or 'N days'
if (m_dateDiffResultInDays.day > 1)
{
result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Days")->Data();
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Days")->Data();
}
else
{
result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Day")->Data();
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Day")->Data();
}
return ref new String(result.data());

View File

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

View File

@ -3,7 +3,6 @@
#pragma once
#include "CalcManager/CalculatorVector.h"
#include "CalcManager/ExpressionCommandInterface.h"
namespace CalculatorApp
@ -17,15 +16,15 @@ namespace CalculatorApp
HistoryItemViewModel(
Platform::String ^ expression,
Platform::String ^ result,
_In_ std::shared_ptr<CalculatorVector<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::pair<std::wstring, int>>> const& spTokens,
_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;
}
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& GetCommands()
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& GetCommands()
{
return m_spCommands;
}
@ -62,7 +61,7 @@ namespace CalculatorApp
private : static Platform::String
^ 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);
private:
@ -70,8 +69,8 @@ namespace CalculatorApp
Platform::String ^ m_accExpression;
Platform::String ^ m_accResult;
Platform::String ^ m_result;
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_spTokens;
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;
Items->IndexOf(e, &index);
TraceLogger::GetInstance().LogHistoryItemLoad((ViewMode)m_currentMode, ItemSize, (int)(index));
TraceLogger::GetInstance()->LogHistoryItemLoad((ViewMode)m_currentMode, ItemSize, (int)(index));
HistoryItemClicked(e);
}
@ -164,7 +164,11 @@ void HistoryViewModel::OnClearCommand(_In_ Platform::Object ^ e)
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()
{
ApplicationDataContainer ^ historyContainer = GetHistoryContainer(m_currentMode);
auto currentHistoryVector = m_calculatorManager->GetHistoryItems(m_currentMode);
auto const& currentHistoryVector = m_calculatorManager->GetHistoryItems(m_currentMode);
bool failure = false;
int index = 0;
Platform::String ^ serializedHistoryItem;
for (auto iter = currentHistoryVector.begin(); iter != currentHistoryVector.end(); ++iter)
for (auto const& item : currentHistoryVector)
{
try
{
serializedHistoryItem = SerializeHistoryItem(*iter);
serializedHistoryItem = SerializeHistoryItem(item);
historyContainer->Values->Insert(index.ToString(), serializedHistoryItem);
}
catch (Platform::Exception ^)
@ -370,10 +374,3 @@ void HistoryViewModel::UpdateItemSize()
{
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);
bool IsValid(_In_ CalculationManager::HISTORYITEM item);
void MakeHistoryClearedNarratorAnnouncement(Platform::String ^ resourceKey, Platform::String ^ &formatVariable);
friend class CalculatorDisplay;
void UpdateItemSize();
};

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@
#include "HistoryViewModel.h"
#include "MemoryItemViewModel.h"
#include "Common/BitLength.h"
#include "Common/NumberBase.h"
namespace CalculatorFunctionalTests
{
@ -19,7 +20,6 @@ namespace CalculatorFunctionalTests
namespace CalculatorUnitTests
{
class MultiWindowUnitTests;
class TimerTests;
}
namespace CalculatorApp
@ -30,55 +30,64 @@ namespace CalculatorApp
namespace ViewModel
{
#define ASCII_0 48
public
delegate void HideMemoryClickedHandler();
public
delegate void ProgModeRadixChangeHandler();
public delegate void HideMemoryClickedHandler();
public value struct ButtonInfo
{
NumbersAndOperatorsEnum buttonId;
bool canSendNegate;
};
[Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
StandardCalculatorViewModel();
void UpdateOperand(int pos, Platform::String ^ text);
void UpdatecommandsInRecordingMode();
int GetNumberBase();
void UpdateCommandsInRecordingMode();
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
OBSERVABLE_PROPERTY_RW(Platform::String ^, DisplayValue);
OBSERVABLE_PROPERTY_RW(HistoryViewModel ^, HistoryVM);
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError);
OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand);
OBSERVABLE_PROPERTY_RW(Platform::String ^, DisplayStringExpression);
OBSERVABLE_PROPERTY_R(HistoryViewModel ^, HistoryVM);
OBSERVABLE_PROPERTY_RW(bool, IsAlwaysOnTop);
OBSERVABLE_PROPERTY_R(bool, IsBinaryBitFlippingEnabled);
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_RW(Platform::String ^, DecimalDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String ^, HexDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String ^, OctalDisplayValue);
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String ^, BinaryDisplayValue);
OBSERVABLE_PROPERTY_R(Platform::String ^, DecimalDisplayValue);
OBSERVABLE_PROPERTY_R(Platform::String ^, HexDisplayValue);
OBSERVABLE_PROPERTY_R(Platform::String ^, OctalDisplayValue);
OBSERVABLE_NAMED_PROPERTY_R(Platform::String ^, BinaryDisplayValue);
OBSERVABLE_NAMED_PROPERTY_R(Windows::Foundation::Collections::IVector<bool> ^, BinaryDigits);
OBSERVABLE_PROPERTY_RW(Platform::String ^, HexDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, DecDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, OctDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, BinDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(bool, IsBinaryOperatorEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsUnaryOperatorEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsNegateEnabled);
OBSERVABLE_PROPERTY_R(Platform::String ^, HexDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_R(Platform::String ^, DecDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_R(Platform::String ^, OctDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_R(Platform::String ^, BinDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_R(bool, IsBinaryOperatorEnabled);
OBSERVABLE_PROPERTY_R(bool, IsUnaryOperatorEnabled);
OBSERVABLE_PROPERTY_R(bool, IsNegateEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsCurrentViewPinned);
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<MemoryItemViewModel ^> ^, MemorizedNumbers);
OBSERVABLE_PROPERTY_R(bool, IsCurrentViewPinned);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IVector<MemoryItemViewModel ^> ^, MemorizedNumbers);
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty);
OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked);
OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked);
OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CalculationResultAutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CalculationExpressionAutomationName);
OBSERVABLE_PROPERTY_RW(bool, IsShiftProgrammerChecked);
OBSERVABLE_PROPERTY_RW(int, CurrentRadixType);
OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreAlwaysOnTopResultsUpdated);
OBSERVABLE_PROPERTY_R(bool, IsFToEChecked);
OBSERVABLE_PROPERTY_R(bool, IsFToEEnabled);
OBSERVABLE_PROPERTY_R(bool, AreHEXButtonsEnabled);
OBSERVABLE_PROPERTY_R(Platform::String ^, CalculationResultAutomationName);
OBSERVABLE_PROPERTY_R(Platform::String ^, CalculationExpressionAutomationName);
OBSERVABLE_PROPERTY_R(bool, IsShiftProgrammerChecked);
OBSERVABLE_PROPERTY_R(CalculatorApp::Common::NumberBase, CurrentRadixType);
OBSERVABLE_PROPERTY_R(bool, AreTokensUpdated);
OBSERVABLE_PROPERTY_R(bool, AreAlwaysOnTopResultsUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled);
OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement);
OBSERVABLE_PROPERTY_R(bool, AreProgrammerRadixOperatorsEnabled);
OBSERVABLE_PROPERTY_R(bool, IsInputEmpty);
OBSERVABLE_PROPERTY_R(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement);
OBSERVABLE_PROPERTY_R(unsigned int, OpenParenthesisCount);
COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand);
@ -90,23 +99,6 @@ namespace CalculatorApp
COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract);
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
{
@ -125,29 +117,8 @@ namespace CalculatorApp
}
}
}
static property Platform::String ^ IsBitFlipCheckedPropertyName
{
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");
}
}
}
static property Platform::String
^ IsBitFlipCheckedPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsBitFlipChecked"); } }
property CalculatorApp::Common::BitLength ValueBitLength
{
@ -226,29 +197,8 @@ namespace CalculatorApp
}
}
}
static property Platform::String ^ IsProgrammerPropertyName
{
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");
}
}
}
static property Platform::String
^ IsProgrammerPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsProgrammer"); } }
property bool IsEditingEnabled
{
@ -300,65 +250,12 @@ namespace CalculatorApp
}
}
property int TokenPosition
{
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);
internal :
void OnPaste(Platform::String ^ pastedString);
void OnCopyCommand(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
void OnMemoryButtonPressed();
@ -368,15 +265,8 @@ namespace CalculatorApp
void OnMemoryClear(_In_ Platform::Object ^ memoryItemPosition);
void OnPinUnpinCommand(Platform::Object ^ parameter);
void SetPrimaryDisplay(_In_ std::wstring const& displayString, _In_ bool isError);
void OnInputChanged();
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 SetOpenParenthesisCountNarratorAnnouncement();
void OnNoRightParenAdded();
@ -393,14 +283,11 @@ namespace CalculatorApp
void Recalculate(bool fromHistory = false);
bool IsOperator(CalculationManager::Command cmdenum);
void FtoEButtonToggled();
void SwitchProgrammerModeBase(RADIX_TYPE calculatorBase);
void SwitchProgrammerModeBase(CalculatorApp::Common::NumberBase calculatorBase);
void SetMemorizedNumbersString();
void SwitchAngleType(NumbersAndOperatorsEnum num);
void ResetDisplay();
RADIX_TYPE GetCurrentRadixType()
{
return (RADIX_TYPE)m_CurrentRadixType;
}
void SetPrecision(int32_t precision);
void UpdateMaxIntDigits()
{
@ -410,12 +297,21 @@ namespace CalculatorApp
{
return m_CurrentAngleType;
}
void SelectHistoryItem(HistoryItemViewModel ^ item);
private:
void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers);
void UpdateProgrammerPanelDisplay();
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);
static RADIX_TYPE GetRadixTypeFromNumberBase(CalculatorApp::Common::NumberBase base);
NumbersAndOperatorsEnum m_CurrentAngleType;
wchar_t m_decimalSeparator;
CalculatorDisplay m_calculatorDisplay;
@ -443,15 +339,9 @@ namespace CalculatorApp
bool m_isStandard;
bool m_isScientific;
bool m_isProgrammer;
bool m_isAlwaysOnTop;
bool m_isBinaryBitFlippingEnabled;
bool m_isBitFlipChecked;
bool m_isShiftChecked;
bool m_isRtlLanguage;
int m_tokenPosition;
bool m_keyPressed;
bool m_operandUpdated;
bool m_completeTextSelection;
bool m_isLastOperationHistoryLoad;
CalculatorApp::Common::BitLength m_valueBitLength;
Platform::String ^ m_selectedExpressionLastData;
@ -473,15 +363,15 @@ namespace CalculatorApp
std::wstring AddPadding(std::wstring);
size_t LengthWithoutPadding(std::wstring);
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_tokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_commands;
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_tokens;
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_commands;
// Token types
bool IsUnaryOp(int nOpCode);
bool IsBinOp(int nOpcode);
bool IsTrigOp(int nOpCode);
bool IsOpnd(int nOpCode);
bool IsRecoverableCommand(int nOpCode);
bool IsUnaryOp(CalculationManager::Command command);
bool IsBinOp(CalculationManager::Command command);
bool IsTrigOp(CalculationManager::Command command);
bool IsOpnd(CalculationManager::Command command);
bool IsRecoverableCommand(CalculationManager::Command command);
CalculationManager::CommandType GetSelectedTokenType(_In_ unsigned int);
void SaveEditedCommand(_In_ unsigned int index, _In_ CalculationManager::Command command);
@ -494,7 +384,6 @@ namespace CalculatorApp
friend class CalculatorDisplay;
friend class CalculatorFunctionalTests::HistoryTests;
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;
auto resourceLoader = AppResourceProvider::GetInstance();
m_localizedValueFromFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromFormat);
m_localizedValueToFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueToFormat);
m_localizedConversionResultFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ConversionResultFormat);
m_localizedValueFromDecimalFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromDecimalFormat);
m_localizedInputUnitName = resourceLoader.GetResourceString(UnitConverterResourceKeys::InputUnit_Name);
m_localizedOutputUnitName = resourceLoader.GetResourceString(UnitConverterResourceKeys::OutputUnit_Name);
m_localizedValueFromFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueFromFormat);
m_localizedValueToFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueToFormat);
m_localizedConversionResultFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ConversionResultFormat);
m_localizedValueFromDecimalFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueFromDecimalFormat);
m_localizedInputUnitName = resourceLoader->GetResourceString(UnitConverterResourceKeys::InputUnit_Name);
m_localizedOutputUnitName = resourceLoader->GetResourceString(UnitConverterResourceKeys::OutputUnit_Name);
Unit1AutomationName = m_localizedInputUnitName;
Unit2AutomationName = m_localizedOutputUnitName;
@ -390,7 +390,7 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st
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;
Value2 = errorMsg;
m_relocalizeStringOnSwitch = false;
@ -476,10 +476,10 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter)
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 };
if (find(begin(OPERANDS), end(OPERANDS), command) != OPERANDS.end())
if (find(begin(OPERANDS), end(OPERANDS), command) != end(OPERANDS))
{
if (m_isInputBlocked)
{
@ -494,7 +494,7 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter)
m_model->SendCommand(command);
TraceLogger::GetInstance().LogConverterInputReceived(Mode);
TraceLogger::GetInstance()->LogConverterInputReceived(Mode);
}
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
// EventWriteClipboardPaste_Start();
// 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()
@ -650,7 +652,7 @@ void UnitConverterViewModel::OnCurrencyDataLoadFinished(bool didLoad)
ResetCategory();
StringReference key = didLoad ? UnitConverterResourceKeys::CurrencyRatesUpdated : UnitConverterResourceKeys::CurrencyRatesUpdateFailed;
String ^ announcement = AppResourceProvider::GetInstance().GetResourceString(key);
String ^ announcement = AppResourceProvider::GetInstance()->GetResourceString(key);
Announcement = CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(announcement);
}
@ -665,17 +667,18 @@ void UnitConverterViewModel::RefreshCurrencyRatios()
m_isCurrencyDataLoaded = false;
IsCurrencyLoadingVisible = true;
String ^ announcement = AppResourceProvider::GetInstance().GetResourceString(UnitConverterResourceKeys::UpdatingCurrencyRates);
String ^ announcement = AppResourceProvider::GetInstance()->GetResourceString(UnitConverterResourceKeys::UpdatingCurrencyRates);
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(
[this](const pair<bool, wstring>& refreshResult) {
[that](const pair<bool, wstring>& refreshResult) {
bool didLoad = refreshResult.first;
wstring timestamp = refreshResult.second;
OnCurrencyTimestampUpdated(timestamp, false /*isWeekOldData*/);
OnCurrencyDataLoadFinished(didLoad);
that->OnCurrencyTimestampUpdated(timestamp, false /*isWeekOldData*/);
that->OnCurrencyDataLoadFinished(didLoad);
},
task_continuation_context::use_current());
}
@ -878,22 +881,22 @@ NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId(const wch
void UnitConverterViewModel::OnPaste(String ^ stringToPaste)
{
// If pastedString is invalid("NoOp") then display pasteError else process the string
if (stringToPaste == StringReference(CopyPasteManager::PasteErrorString))
if (CopyPasteManager::IsErrorMessage(stringToPaste))
{
this->DisplayPasteError();
return;
}
TraceLogger::GetInstance().LogInputPasted(Mode);
TraceLogger::GetInstance()->LogInputPasted(Mode);
bool isFirstLegalChar = true;
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;
NumbersAndOperatorsEnum op = MapCharacterToButtonId(*it, canSendNegate);
NumbersAndOperatorsEnum op = MapCharacterToButtonId(ch, canSendNegate);
if (NumbersAndOperatorsEnum::None != op)
{
@ -929,7 +932,7 @@ void UnitConverterViewModel::OnPaste(String ^ stringToPaste)
}
}
accumulation += *it;
accumulation += ch;
UpdateInputBlocked(accumulation);
if (m_isInputBlocked)
{
@ -954,8 +957,7 @@ String ^ UnitConverterViewModel::GetLocalizedAutomationName(_In_ String ^ displa
format = m_localizedValueFromDecimalFormat;
}
wstring localizedResult = LocalizationStringUtil::GetLocalizedString(format->Data(), displayvalue->Data(), unitname->Data());
return ref new String(localizedResult.c_str());
return LocalizationStringUtil::GetLocalizedString(format, displayvalue, unitname);
}
String
@ -965,11 +967,7 @@ String
_In_ String ^ toValue,
_In_ String ^ toUnit)
{
String ^ localizedString =
ref new String(LocalizationStringUtil::GetLocalizedString(
m_localizedConversionResultFormat->Data(), fromValue->Data(), fromUnit->Data(), toValue->Data(), toUnit->Data())
.c_str());
return localizedString;
return LocalizationStringUtil::GetLocalizedString(m_localizedConversionResultFormat, fromValue, fromUnit, toValue, toUnit);
}
void UnitConverterViewModel::UpdateValue1AutomationName()
@ -990,9 +988,9 @@ void UnitConverterViewModel::UpdateValue2AutomationName()
void UnitConverterViewModel::OnMaxDigitsReached()
{
String ^ format = AppResourceProvider::GetInstance().GetResourceString(UnitConverterResourceKeys::MaxDigitsReachedFormat);
const wstring& announcement = LocalizationStringUtil::GetLocalizedString(format->Data(), m_lastAnnouncedConversionResult->Data());
Announcement = CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(StringReference(announcement.c_str()));
String ^ format = AppResourceProvider::GetInstance()->GetResourceString(UnitConverterResourceKeys::MaxDigitsReachedFormat);
auto announcement = LocalizationStringUtil::GetLocalizedString(format, m_lastAnnouncedConversionResult);
Announcement = CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(announcement);
}
bool UnitConverterViewModel::UnitsAreValid()
@ -1002,17 +1000,18 @@ bool UnitConverterViewModel::UnitsAreValid()
void UnitConverterViewModel::StartConversionResultTimer()
{
m_conversionResultTaskHelper = make_unique<ConversionResultTaskHelper>(CONVERSION_FINALIZED_DELAY_IN_MS, [this]() {
if (UnitsAreValid())
auto that(this);
m_conversionResultTaskHelper = make_unique<ConversionResultTaskHelper>(CONVERSION_FINALIZED_DELAY_IN_MS, [that]() {
if (that->UnitsAreValid())
{
String ^ valueFrom = m_Value1Active ? m_Value1 : m_Value2;
String ^ valueTo = m_Value1Active ? m_Value2 : m_Value1;
String ^ valueFrom = that->m_Value1Active ? that->m_Value1 : that->m_Value2;
String ^ valueTo = that->m_Value1Active ? that->m_Value2 : that->m_Value1;
}
});
}
String ^ SupplementaryResult::GetLocalizedAutomationName()
{
auto format = AppResourceProvider::GetInstance().GetResourceString("SupplementaryUnit_AutomationName");
return ref new String(LocalizationStringUtil::GetLocalizedString(format->Data(), this->Value->Data(), this->Unit->Name->Data()).c_str());
auto format = AppResourceProvider::GetInstance()->GetResourceString("SupplementaryUnit_AutomationName");
return LocalizationStringUtil::GetLocalizedString(format, this->Value, this->Unit->Name);
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<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>

View File

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

View File

@ -35,11 +35,11 @@ AboutFlyout::AboutFlyout()
this->SetVersionString();
Header->Text = resourceLoader.GetResourceString("AboutButton/Content");
Header->Text = resourceLoader->GetResourceString("AboutButton/Content");
auto copyrightText =
LocalizationStringUtil::GetLocalizedString(resourceLoader.GetResourceString("AboutControlCopyright")->Data(), to_wstring(BUILD_YEAR).c_str());
AboutControlCopyrightRun->Text = ref new String(copyrightText.c_str());
LocalizationStringUtil::GetLocalizedString(resourceLoader->GetResourceString("AboutControlCopyright"), StringReference(to_wstring(BUILD_YEAR).c_str()));
AboutControlCopyrightRun->Text = copyrightText;
}
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()
{
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;
}

View File

@ -18,18 +18,37 @@
<x:Double x:Key="EquationButtonOverlayPressedOpacity">0.5</x:Double>
<Color x:Key="AltHighColor">#FF000000</Color>
<Color x:Key="ChromeMediumLowColor">#FF2B2B2B</Color>
<Color x:Key="OperatorPanelScrollButtonBackgroundColor">#FF858585</Color>
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource AltHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppOperatorPanelBackground"
Opacity="0.4"
Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{StaticResource SystemBaseMediumHighColor}"/>
<RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush" Color="#18FFFFFF"/>
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush" Color="#30FFFFFF"/>
<RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush"
FallbackColor="#18FFFFFF"
Color="#18FFFFFF"/>
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush"
FallbackColor="#30FFFFFF"
Color="#30FFFFFF"/>
<SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="{ThemeResource SystemAccentColor}"/>
<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"/>
<RevealBorderBrush x:Key="AppControlForegroundTransparentRevealBorderBrush"
FallbackColor="Transparent"
@ -48,9 +67,10 @@
FallbackColor="{ThemeResource SystemChromeMediumColor}"
TintColor="{ThemeResource SystemChromeLowColor}"
TintOpacity="0.7"/>
<SolidColorBrush x:Key="EquationTextBoxTransparentBackgroundBrush" Color="Transparent"/>
<SolidColorBrush x:Key="EquationBoxPointerOverBackgroundBrush" Color="{ThemeResource SystemControlBackgroundAltMediumBrush}"/>
<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="EquationButtonOverlayBackgroundBrush" Color="White"/>
<SolidColorBrush x:Key="EquationButtonHideLineBackgroundBrush"
@ -77,6 +97,7 @@
<SolidColorBrush x:Key="EquationBrush14" Color="#FF018574"/>
<SolidColorBrush x:Key="EquationBrush15" Color="#FF10893E"/>
<SolidColorBrush x:Key="EquationBrush16" Color="#FF000000"/>
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<Thickness x:Key="HighContrastThicknessTop">0,0,0,0</Thickness>
@ -85,19 +106,39 @@
<Color x:Key="ChromeMediumLowColor">#FFE0E0E0</Color>
<x:Double x:Key="EquationButtonOverlayPointerOverOpacity">0.2</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="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppOperatorPanelBackground"
Opacity="0.4"
Color="{ThemeResource SystemAltMediumLowColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{StaticResource SystemBaseMediumHighColor}"/>
<RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush" Color="#17000000"/>
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush" Color="#30000000"/>
<RevealBackgroundBrush x:Key="AppControlHoverButtonFaceBrush"
FallbackColor="#17000000"
Color="#17000000"/>
<RevealBackgroundBrush x:Key="AppControlPressedButtonFaceBrush"
FallbackColor="#30000000"
Color="#30000000"/>
<SolidColorBrush x:Key="AppControlTransparentAccentColorBrush" Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="OperatorPanelScrollButtonBackgroundBrush" Color="{ThemeResource OperatorPanelScrollButtonBackgroundColor}"/>
<SolidColorBrush x:Key="AppControlForegroundAccentBrush" Color="{ThemeResource SystemAccentColor}"/>
<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"
FallbackColor="Transparent"
TargetTheme="Light"
@ -115,6 +156,11 @@
FallbackColor="{ThemeResource SystemChromeMediumColor}"
TintColor="{ThemeResource SystemChromeLowColor}"
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="EquationBoxHoverButtonForegroundBrush" Color="{ThemeResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="EquationBoxBorderBrush" Color="{ThemeResource TextControlBackground}"/>
@ -153,11 +199,13 @@
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="AppBackgroundAltMediumLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppOperatorPanelBackground" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppControlPageTextBaseMediumHighBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<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="AppControlPageTextBaseHighColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<SolidColorBrush x:Key="OperatorPanelScrollButtonBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppControlForegroundAccentBrush" Color="{ThemeResource SystemColorButtonTextColor}"/>
<SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<SolidColorBrush x:Key="AppControlForegroundTransparentRevealBorderBrush" Color="{ThemeResource SystemColorButtonTextColor}"/>
@ -165,9 +213,13 @@
<SolidColorBrush x:Key="AppControlBackgroundListAccentHighRevealBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppControlListLowRevealHighlightBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<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="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="EquationButtonHideLineBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="EquationButtonOverlayBackgroundBrush" Color="Transparent"/>
@ -191,6 +243,21 @@
<x:Double x:Key="PivotHeaderItemFontSize">15</x:Double>
<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="BodyFontSize">15</x:Double>
<x:Double x:Key="TitleFontSize">24</x:Double>
@ -200,13 +267,17 @@
<GridLength x:Key="HamburgerHeightGridLength">40</GridLength>
<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>
<!-- Numpad Standard/Scientific in Fill/Full -->
<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="CalcStandardOperatorCaptionSizeTiny">12</x:Double>
<!-- 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 -->
<Style x:Key="CalcButtonStyle" TargetType="Controls:CalculatorButton">
@ -263,7 +334,6 @@
<VisualState x:Name="KeyBoardEntry"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -297,6 +367,11 @@
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="12"/>
</Style>
<Style x:Key="NumericButtonStyle14"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="14"/>
</Style>
<Style x:Key="NumericButtonStyle16"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
@ -322,11 +397,28 @@
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="34"/>
</Style>
<Style x:Key="NumericButtonStyle38"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="38"/>
</Style>
<Style x:Key="NumericButtonStyle46"
BasedOn="{StaticResource NumericButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="FontSize" Value="46"/>
</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"
BasedOn="{StaticResource CalcButtonStyle}"
@ -384,7 +476,6 @@
<VisualState x:Name="KeyBoardEntry"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -412,13 +503,33 @@
</Setter>
</Style>
<Style x:Key="AccentCalcButtonStyle"
<Style x:Key="AccentEmphasizedCalcButtonStyle"
BasedOn="{StaticResource SymbolOperatorButtonStyle}"
TargetType="Controls:CalculatorButton">
<Setter Property="HoverBackground" Value="{ThemeResource AppControlHighlightAccentRevealBackgroundBrush}"/>
<Setter Property="HoverForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/>
<Setter Property="PressBackground" Value="{ThemeResource AppControlBackgroundListAccentHighRevealBackgroundBrush}"/>
<Setter Property="PressForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/>
<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 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>
<!-- RESULTS -->
@ -532,6 +643,123 @@
</Setter>
</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">
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
@ -574,7 +802,6 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -632,7 +859,6 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -738,7 +964,6 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="SelectionBorder" BorderThickness="0,0,0,2"/>
<ContentPresenter x:Name="ContentPresenter"
@ -768,6 +993,98 @@
<Setter Property="MinHeight" Value="0"/>
</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"
BasedOn="{StaticResource CaptionButtonStyle}"
TargetType="Button">
@ -802,7 +1119,6 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -983,7 +1299,6 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -1060,7 +1375,6 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
@ -1163,6 +1477,147 @@
</Setter>
</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">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Transparent"/>
@ -1390,9 +1845,9 @@
Grid.Column="0"
Grid.ColumnSpan="4"
Foreground="{ThemeResource SystemControlDescriptionTextForegroundBrush}"
x:Load="False"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Description}"/>
Content="{TemplateBinding Description}"
x:Load="False"/>
</Grid>

View File

@ -12,7 +12,6 @@
#include "CalcViewModel/Common/Automation/NarratorNotifier.h"
#include "CalcViewModel/Common/AppResourceProvider.h"
#include "CalcViewModel/Common/LocalizationSettings.h"
#include "CalcViewModel/ViewState.h"
#include "Views/MainPage.xaml.h"
using namespace CalculatorApp;
@ -94,31 +93,11 @@ bool App::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)
{
reader_writer_lock::scoped_lock lock(m_windowsMapLock);
m_secondaryWindows[frameService->GetViewId()] = frameService;
TraceLogger::GetInstance().UpdateWindowCount(m_secondaryWindows.size());
TraceLogger::GetInstance()->UpdateWindowCount(m_secondaryWindows.size());
}
WindowFrameService ^ App::GetWindowFromMap(int viewId)
@ -384,7 +363,7 @@ void App::OnAppLaunch(IActivatedEventArgs ^ args, String ^ argument)
}
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
@ -460,7 +439,7 @@ void App::OnActivated(IActivatedEventArgs ^ args)
void CalculatorApp::App::OnSuspending(Object ^ sender, SuspendingEventArgs ^ args)
{
TraceLogger::GetInstance().LogButtonUsage();
TraceLogger::GetInstance()->LogButtonUsage();
}
void App::DismissedEventHandler(SplashScreen ^ sender, Object ^ e)
@ -468,9 +447,5 @@ void App::DismissedEventHandler(SplashScreen ^ sender, Object ^ e)
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 OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs ^ args) override;
internal : static bool IsAnimationEnabled();
static Platform::String ^ GetAppViewState();
static float GetAppWindowHeight();
internal :
static bool IsAnimationEnabled();
void RemoveWindow(_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