Merge branch 'master' into master

This commit is contained in:
uhliksk 2019-03-25 23:05:01 +01:00 committed by GitHub
commit 061ba806e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
385 changed files with 3390 additions and 2370 deletions

View file

@ -5,7 +5,6 @@ root = true
[*] [*]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
end_of_line = crlf
charset = utf-8 charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true

1
.gitignore vendored
View file

@ -290,4 +290,5 @@ __pycache__/
# Calculator specific # Calculator specific
Generated Files/ Generated Files/
!/build/config/TRexDefs/** !/build/config/TRexDefs/**
!src/Calculator/TemporaryKey.pfx
!src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx !src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx

View file

@ -2,7 +2,7 @@
The Windows Calculator app is a modern Windows app written in C++ that ships pre-installed with Windows. The Windows Calculator app is a modern Windows app written in C++ that ships pre-installed with Windows.
The app provides standard, scientific, and programmer calculator functionality, as well as a set of converters between various units of measurement and currencies. The app provides standard, scientific, and programmer calculator functionality, as well as a set of converters between various units of measurement and currencies.
Calculator ships regularly with new features and bug fixes. You can get the latest version of Calculator in the [Microsoft Store.](https://www.microsoft.com/store/apps/9WZDNCRFHVN5) Calculator ships regularly with new features and bug fixes. You can get the latest version of Calculator in the [Microsoft Store](https://www.microsoft.com/store/apps/9WZDNCRFHVN5).
[![Build Status](https://dev.azure.com/ms/calculator/_apis/build/status/Calculator-CI?branchName=master)](https://dev.azure.com/ms/calculator/_build/latest?definitionId=57&branchName=master) [![Build Status](https://dev.azure.com/ms/calculator/_apis/build/status/Calculator-CI?branchName=master)](https://dev.azure.com/ms/calculator/_build/latest?definitionId=57&branchName=master)
@ -18,14 +18,14 @@ Calculator ships regularly with new features and bug fixes. You can get the late
## Getting started ## Getting started
Prerequisites: Prerequisites:
- Your computer must be running Windows 10, version 1803 or newer - Your computer must be running Windows 10, version 1803 or newer.
- Install the latest version of [Visual Studio](https://developer.microsoft.com/en-us/windows/downloads) (the free community edition is sufficient) - Install the latest version of [Visual Studio](https://developer.microsoft.com/en-us/windows/downloads) (the free community edition is sufficient).
- Install the "Universal Windows Platform Development" workload - Install the "Universal Windows Platform Development" workload.
- Install the optional "C++ Universal Windows Platform tools" component - Install the optional "C++ Universal Windows Platform tools" component.
- Install the latest Windows 10 SDK - Install the latest Windows 10 SDK.
![Visual Studio Installation Screenshot](docs/Images/VSInstallationScreenshot.png) ![Visual Studio Installation Screenshot](docs/Images/VSInstallationScreenshot.png)
- Install the [XAML Styler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension - Install the [XAML Styler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension.
- Get the code: - Get the code:
``` ```

View file

@ -15,30 +15,33 @@ name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
jobs: jobs:
- job: Localize - job: Localize
pool: pool:
name: Package ES Custom Demands Lab A vmImage: vs2017-win2016
demands: variables:
- ClientAlias -equals PKGESUTILAPPS skipComponentGovernanceDetection: true
workspace:
clean: outputs
steps: steps:
- checkout: self
clean: true
- task: PkgESSetupBuild@10 - task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
displayName: Initialize Package ES displayName: Send resources to Touchdown Build
inputs: inputs:
productName: Calculator teamId: 86
branchVersion: true authId: d3dd8113-65b3-4526-bdca-a00a7d1c37ba
authKey: $(LocServiceKey)
isPreview: false
relativePathRoot: src/Calculator/Resources/en-US/
resourceFilePath: '*.resw'
outputDirectoryRoot: src/Calculator/Resources/
- task: PkgESTouchdownLocService@10 - script: |
displayName: Package ES Touchdown Loc Service cd $(Build.SourcesDirectory)
git add -A
git diff --cached --exit-code
echo '##vso[task.setvariable variable=hasChanges]%errorlevel%'
git diff --cached > $(Build.ArtifactStagingDirectory)\LocalizedStrings.patch
displayName: Check for changes and create patch file
- task: PublishPipelineArtifact@0
displayName: Publish patch file as artifact
condition: eq(variables['hasChanges'], '1')
inputs: inputs:
IsCallToServiceStepSelected: true artifactName: Patch
IsCheckedInFileSelected: true targetPath: $(Build.ArtifactStagingDirectory)
CheckinFilesAtOriginFilePath: true
GitLocPath: Loc/Resources
LocConfigFile: build/config/LocConfigPackageEs.xml
AuthenticationMode: OAuth
ClientApplicationID: d3dd8113-65b3-4526-bdca-a00a7d1c37ba
ApplicationKeyID: $(LocServiceKey)
SendToLoc: true

View file

@ -9,8 +9,8 @@ pr: none
variables: variables:
versionMajor: 10 versionMajor: 10
versionMinor: 1902 versionMinor: 1903
versionBuild: $[counter('10.1902.*', 0)] versionBuild: $[counter('10.1903.*', 0)]
versionPatch: 0 versionPatch: 0
name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)' name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)'

View file

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

View file

@ -87,7 +87,7 @@ jobs:
downloadDirectory: $(Build.SourcesDirectory) downloadDirectory: $(Build.SourcesDirectory)
vstsFeed: WindowsApps vstsFeed: WindowsApps
vstsFeedPackage: calculator-internals vstsFeedPackage: calculator-internals
vstsPackageVersion: 0.0.7 vstsPackageVersion: 0.0.10
- task: PkgESStoreBrokerPackage@10 - task: PkgESStoreBrokerPackage@10
displayName: Create StoreBroker Packages displayName: Create StoreBroker Packages

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

Before After
Before After

View file

@ -9,6 +9,7 @@ In 2019, the Windows Calculator team is focused on:
* Iterating upon the existing app design based on the latest [Fluent Design guidelines](https://developer.microsoft.com/en-us/windows/apps/design) * Iterating upon the existing app design based on the latest [Fluent Design guidelines](https://developer.microsoft.com/en-us/windows/apps/design)
* Improving testing and diagnostics within the project * Improving testing and diagnostics within the project
* Investigating new features with a focus on addressing top user feedback, including: * Investigating new features with a focus on addressing top user feedback, including:
* Adding graphing mode
* Adding the ability for users to pin Calculator on top of other windows * Adding the ability for users to pin Calculator on top of other windows
* Providing additional customization options * Providing additional customization options
* [Your feature idea here] - please review our [new feature development process](https://github.com/Microsoft/calculator/blob/master/docs/NewFeatureProcess.md) to get started! * [Your feature idea here] - please review our [new feature development process](https://github.com/Microsoft/calculator/blob/master/docs/NewFeatureProcess.md) to get started!

View file

@ -11,9 +11,6 @@ namespace Calculator.UIAutomationLibrary.Components
/// <summary> /// <summary>
/// Physical Object Model for the app window. /// Physical Object Model for the app window.
/// POM is the implementation model of the app. /// POM is the implementation model of the app.
/// See following references to POM:
/// * https://blogs.msdn.microsoft.com/wltester/2011/11/14/object-model-design/
/// * https://blogs.msdn.microsoft.com/micahel/2005/06/03/how-do-i-invoke-thee-let-me-count-the-ways-the-physical-object-model/
/// See https://en.wikipedia.org/wiki/Model-based_testing for model-based testing. /// See https://en.wikipedia.org/wiki/Model-based_testing for model-based testing.
/// </summary> /// </summary>
public class MainPagePom : UIObject public class MainPagePom : UIObject

View file

@ -261,7 +261,7 @@ void CalcInput::SetDecimalSymbol(wchar_t decSymbol)
} }
} }
wstring CalcInput::ToString(uint32_t radix, bool isIntegerMode) wstring CalcInput::ToString(uint32_t radix)
{ {
// In theory both the base and exponent could be C_NUM_MAX_DIGITS long. // In theory both the base and exponent could be C_NUM_MAX_DIGITS long.
wstringstream resStream; wstringstream resStream;

View file

@ -3,6 +3,7 @@
#include "pch.h" #include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h"
bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y) bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y)
{ {

View file

@ -2,18 +2,25 @@
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
#pragma once
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Command.h" #include "Command.h"
#include "CalculatorVector.h" #include "CalculatorVector.h"
#include "ExpressionCommand.h" #include "ExpressionCommand.h"
#include "CalcException.h"
constexpr int ASCII_0 = 48; constexpr int ASCII_0 = 48;
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
namespace {
void IFT(HRESULT hr)
{
if (FAILED(hr))
{
throw hr;
}
}
}
void CHistoryCollector::ReinitHistory() void CHistoryCollector::ReinitHistory()
{ {
m_lastOpStartIndex = -1; m_lastOpStartIndex = -1;
@ -223,11 +230,11 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE a
{ {
angleOpCode = CalculationManager::Command::CommandDEG; angleOpCode = CalculationManager::Command::CommandDEG;
} }
if (angletype == ANGLE_RAD) else if (angletype == ANGLE_RAD)
{ {
angleOpCode = CalculationManager::Command::CommandRAD; angleOpCode = CalculationManager::Command::CommandRAD;
} }
if (angletype == ANGLE_GRAD) else // (angletype == ANGLE_GRAD)
{ {
angleOpCode = CalculationManager::Command::CommandGRAD; angleOpCode = CalculationManager::Command::CommandGRAD;
} }
@ -409,8 +416,11 @@ int CHistoryCollector::AddCommand(_In_ const std::shared_ptr<IExpressionCommand>
// To Update the operands in the Expression according to the current Radix // To Update the operands in the Expression according to the current Radix
void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precision) void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precision)
{ {
if (m_spTokens != nullptr) if (m_spTokens == nullptr)
{ {
return;
}
unsigned int size; unsigned int size;
IFT(m_spTokens->GetSize(&size)); IFT(m_spTokens->GetSize(&size));
@ -428,7 +438,7 @@ void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precisio
std::shared_ptr<COpndCommand> opndCommand = std::static_pointer_cast<COpndCommand>(expCommand); std::shared_ptr<COpndCommand> opndCommand = std::static_pointer_cast<COpndCommand>(expCommand);
if (opndCommand != nullptr) if (opndCommand != nullptr)
{ {
token.first = opndCommand->GetString(radix, precision, m_decimalSymbol); token.first = opndCommand->GetString(radix, precision);
IFT(m_spTokens->SetAt(i, token)); IFT(m_spTokens->SetAt(i, token));
opndCommand->SetCommands(GetOperandCommandsFromString(token.first)); opndCommand->SetCommands(GetOperandCommandsFromString(token.first));
} }
@ -437,7 +447,6 @@ void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precisio
} }
SetExpressionDisplay(); SetExpressionDisplay();
} }
}
void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol) void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
{ {

View file

@ -26,6 +26,7 @@
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
namespace {
// NPrecedenceOfOp // NPrecedenceOfOp
// //
// returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number // returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number
@ -35,20 +36,21 @@ INT NPrecedenceOfOp(int nopCode)
static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1, static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1,
IDC_ADD,2, IDC_SUB,2, IDC_RSHF,3, IDC_LSHF,3, IDC_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 }; IDC_MOD,3, IDC_DIV,3, IDC_MUL,3, IDC_PWR,4, IDC_ROOT, 4 };
int iPrec; unsigned int iPrec;
iPrec = 0; iPrec = 0;
while ((iPrec < ARRAYSIZE(rgbPrec)) && (nopCode != rgbPrec[iPrec])) while ((iPrec < size(rgbPrec)) && (nopCode != rgbPrec[iPrec]))
{ {
iPrec += 2; iPrec += 2;
} }
if (iPrec >= ARRAYSIZE(rgbPrec)) if (iPrec >= size(rgbPrec))
{ {
iPrec = 0; iPrec = 0;
} }
return rgbPrec[iPrec + 1]; return rgbPrec[iPrec + 1];
} }
}
// HandleErrorCommand // HandleErrorCommand
// //
@ -58,7 +60,7 @@ void CCalcEngine::HandleErrorCommand(WPARAM idc)
{ {
if (!IsGuiSettingOpCode(idc)) if (!IsGuiSettingOpCode(idc))
{ {
// we would have saved the prev command. Need to forget this state // We would have saved the prev command. Need to forget this state
m_nTempCom = m_nLastCom; m_nTempCom = m_nLastCom;
} }
} }
@ -180,7 +182,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
// BINARY OPERATORS: // BINARY OPERATORS:
if (IsBinOpCode(wParam)) if (IsBinOpCode(wParam))
{ {
/* Change the operation if last input was operation. */ // Change the operation if last input was operation.
if (IsBinOpCode(m_nLastCom)) if (IsBinOpCode(m_nLastCom))
{ {
INT nPrev; INT nPrev;
@ -544,6 +546,11 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx) if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx)
|| ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0))) || ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0)))
{ {
if (!m_openParenCount && !nx)
{
m_pCalcDisplay->OnNoRightParenAdded();
}
HandleErrorCommand(wParam); HandleErrorCommand(wParam);
break; break;
} }
@ -946,7 +953,7 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
// Try to lookup the ID in the UFNE table // Try to lookup the ID in the UFNE table
int ids = 0; int ids = 0;
int iufne = nOpCode - IDC_UNARYFIRST; int iufne = nOpCode - IDC_UNARYFIRST;
if (iufne >= 0 && iufne < ARRAYSIZE(rgUfne)) if (iufne >= 0 && (size_t)iufne < size(rgUfne))
{ {
if (fInv) if (fInv)
{ {
@ -1026,7 +1033,7 @@ wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision)
wstring numberString = GetStringForDisplay(rat, radix); wstring numberString = GetStringForDisplay(rat, radix);
if (!numberString.empty()) if (!numberString.empty())
{ {
//revert the precision to previously stored precision // Revert the precision to previously stored precision
ChangeConstants(m_radix, m_precision); ChangeConstants(m_radix, m_precision);
} }

View file

@ -107,7 +107,7 @@ void CCalcEngine::DisplayNum(void)
if (m_bRecord) if (m_bRecord)
{ {
// Display the string and return. // Display the string and return.
m_numberString = m_input.ToString(m_radix, m_fIntegerMode); m_numberString = m_input.ToString(m_radix);
} }
else else
{ {

View file

@ -6,6 +6,7 @@
using namespace CalcEngine; using namespace CalcEngine;
using namespace CalcEngine::RationalMath; using namespace CalcEngine::RationalMath;
using namespace std;
// To be called when either the radix or num width changes. You can use -1 in either of these values to mean // To be called when either the radix or num width changes. You can use -1 in either of these values to mean
// dont change that. // dont change that.
@ -55,7 +56,7 @@ LONG CCalcEngine::DwWordBitWidthFromeNumWidth(NUM_WIDTH /*numwidth*/)
static constexpr int nBitMax[] = { 64, 32, 16, 8 }; static constexpr int nBitMax[] = { 64, 32, 16, 8 };
LONG wmax = nBitMax[0]; LONG wmax = nBitMax[0];
if (m_numwidth >= 0 && m_numwidth < ARRAYSIZE(nBitMax)) if (m_numwidth >= 0 && (size_t)m_numwidth < size(nBitMax))
{ {
wmax = nBitMax[m_numwidth]; wmax = nBitMax[m_numwidth];
} }
@ -68,7 +69,7 @@ uint32_t CCalcEngine::NRadixFromRadixType(RADIX_TYPE radixtype)
uint32_t radix = 10; uint32_t radix = 10;
// convert special bases into symbolic values // convert special bases into symbolic values
if (radixtype >= 0 && radixtype < ARRAYSIZE(rgnRadish)) if (radixtype >= 0 && (size_t)radixtype < size(rgnRadish))
{ {
radix = rgnRadish[radixtype]; radix = rgnRadish[radixtype];
} }

View file

@ -1,26 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
class CalcException : std::exception
{
public:
CalcException(HRESULT hr)
{
m_hr = hr;
}
HRESULT GetException()
{
return m_hr;
}
private:
HRESULT m_hr;
};
void IFT(HRESULT hr)
{
if (FAILED(hr))
{
CalcException exception(hr);
throw(exception);
}
}

View file

@ -155,6 +155,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -169,6 +171,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -183,6 +187,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -197,6 +203,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -212,6 +220,8 @@
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -226,6 +236,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -240,6 +252,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -254,6 +268,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View file

@ -119,7 +119,6 @@
<ClInclude Include="Ratpack\ratpak.h"> <ClInclude Include="Ratpack\ratpak.h">
<Filter>RatPack</Filter> <Filter>RatPack</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="CalcException.h" />
<ClInclude Include="CalculatorVector.h" /> <ClInclude Include="CalculatorVector.h" />
<ClInclude Include="Header Files\CalcEngine.h"> <ClInclude Include="Header Files\CalcEngine.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
@ -136,9 +135,6 @@
<ClInclude Include="Header Files\History.h"> <ClInclude Include="Header Files\History.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Header Files\scimath.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UnitConverter.h" /> <ClInclude Include="UnitConverter.h" />
<ClInclude Include="CalculatorHistory.h" /> <ClInclude Include="CalculatorHistory.h" />
<ClInclude Include="CalculatorManager.h" /> <ClInclude Include="CalculatorManager.h" />

View file

@ -7,8 +7,7 @@
using namespace std; using namespace std;
using namespace CalculationManager; using namespace CalculationManager;
CalculatorHistory::CalculatorHistory(CALCULATOR_MODE eMode, size_t maxSize) : CalculatorHistory::CalculatorHistory(size_t maxSize) :
m_mode(eMode),
m_maxHistorySize(maxSize) m_maxHistorySize(maxSize)
{} {}
@ -35,15 +34,13 @@ unsigned int CalculatorHistory::AddToHistory(_In_ shared_ptr<CalculatorVector <p
unsigned int CalculatorHistory::AddItem(_In_ shared_ptr<HISTORYITEM> const &spHistoryItem) unsigned int CalculatorHistory::AddItem(_In_ shared_ptr<HISTORYITEM> const &spHistoryItem)
{ {
int lastIndex;
if (m_historyItems.size() >= m_maxHistorySize) if (m_historyItems.size() >= m_maxHistorySize)
{ {
m_historyItems.erase(m_historyItems.begin()); m_historyItems.erase(m_historyItems.begin());
} }
m_historyItems.push_back(spHistoryItem); m_historyItems.push_back(spHistoryItem);
lastIndex = static_cast<unsigned>(m_historyItems.size() - 1); unsigned int lastIndex = static_cast<unsigned>(m_historyItems.size() - 1);
return lastIndex; return lastIndex;
} }

View file

@ -31,7 +31,7 @@ namespace CalculationManager
{ {
public: public:
CalculatorHistory(CALCULATOR_MODE eMode, const size_t maxSize); 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, std::wstring_view result); 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, std::wstring_view result);
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistory(); std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistory();
std::shared_ptr<HISTORYITEM> const& GetHistoryItem(unsigned int uIdx); std::shared_ptr<HISTORYITEM> const& GetHistoryItem(unsigned int uIdx);
@ -43,7 +43,6 @@ namespace CalculationManager
private: private:
std::vector<std::shared_ptr<HISTORYITEM>> m_historyItems; std::vector<std::shared_ptr<HISTORYITEM>> m_historyItems;
CALCULATOR_MODE m_mode;
const size_t m_maxHistorySize; const size_t m_maxHistorySize;
}; };
} }

View file

@ -24,16 +24,16 @@ namespace CalculationManager
{ {
CalculatorManager::CalculatorManager(_In_ ICalcDisplay* displayCallback, _In_ IResourceProvider* resourceProvider) : CalculatorManager::CalculatorManager(_In_ ICalcDisplay* displayCallback, _In_ IResourceProvider* resourceProvider) :
m_displayCallback(displayCallback), m_displayCallback(displayCallback),
m_currentCalculatorEngine(nullptr),
m_resourceProvider(resourceProvider), m_resourceProvider(resourceProvider),
m_currentDegreeMode(Command::CommandNULL), m_inHistoryItemLoadMode(false),
m_savedDegreeMode(Command::CommandDEG), m_persistedPrimaryValue(),
m_isExponentialFormat(false), m_isExponentialFormat(false),
m_isAutoExponentialFormat(true), m_isAutoExponentialFormat(true),
m_persistedPrimaryValue(), m_currentDegreeMode(Command::CommandNULL),
m_currentCalculatorEngine(nullptr), m_savedDegreeMode(Command::CommandDEG),
m_pStdHistory(new CalculatorHistory(CM_STD, MAX_HISTORY_ITEMS)), m_pStdHistory(new CalculatorHistory(MAX_HISTORY_ITEMS)),
m_pSciHistory(new CalculatorHistory(CM_SCI, MAX_HISTORY_ITEMS)), m_pSciHistory(new CalculatorHistory(MAX_HISTORY_ITEMS))
m_inHistoryItemLoadMode(false)
{ {
CCalcEngine::InitialOneTimeOnlySetup(*m_resourceProvider); CCalcEngine::InitialOneTimeOnlySetup(*m_resourceProvider);
} }
@ -110,7 +110,6 @@ namespace CalculationManager
/// <summary> /// <summary>
/// Callback from the engine /// Callback from the engine
/// Used to set the current unmatched open parenthesis count
/// </summary> /// </summary>
/// <param name="parenthesisCount">string containing the parenthesis count</param> /// <param name="parenthesisCount">string containing the parenthesis count</param>
void CalculatorManager::SetParenDisplayText(const wstring& parenthesisCount) void CalculatorManager::SetParenDisplayText(const wstring& parenthesisCount)
@ -118,6 +117,14 @@ namespace CalculationManager
m_displayCallback->SetParenDisplayText(parenthesisCount); m_displayCallback->SetParenDisplayText(parenthesisCount);
} }
/// <summary>
/// Callback from the engine
/// </summary>
void CalculatorManager::OnNoRightParenAdded()
{
m_displayCallback->OnNoRightParenAdded();
}
/// <summary> /// <summary>
/// Reset CalculatorManager. /// Reset CalculatorManager.
/// Set the mode to the standard calculator /// Set the mode to the standard calculator
@ -289,11 +296,12 @@ namespace CalculationManager
m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(Command::CommandINV)); m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(Command::CommandINV));
m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(Command::CommandTANH)); m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(Command::CommandTANH));
break; break;
case Command::CommandFE:
m_isExponentialFormat = !m_isExponentialFormat;
case Command::CommandAE: case Command::CommandAE:
m_isAutoExponentialFormat = !m_isAutoExponentialFormat; m_isAutoExponentialFormat = !m_isAutoExponentialFormat;
// fall through break;
case Command::CommandFE:
m_isExponentialFormat = !m_isExponentialFormat;
[[fallthrough]];
default: default:
m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(command)); m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(command));
break; break;
@ -309,7 +317,10 @@ namespace CalculationManager
unsigned char CalculatorManager::MapCommandForSerialize(Command command) unsigned char CalculatorManager::MapCommandForSerialize(Command command)
{ {
unsigned int commandToSave = static_cast<unsigned int>(command); unsigned int commandToSave = static_cast<unsigned int>(command);
commandToSave > UCHAR_MAX ? commandToSave -= UCHAR_MAX : commandToSave; if (commandToSave > UCHAR_MAX)
{
commandToSave -= UCHAR_MAX;
}
return static_cast<unsigned char>(commandToSave); return static_cast<unsigned char>(commandToSave);
} }
@ -361,7 +372,7 @@ namespace CalculationManager
/// <param name = "serializedPrimaryDisplay">Serialized Rational of primary display</param> /// <param name = "serializedPrimaryDisplay">Serialized Rational of primary display</param>
void CalculatorManager::DeSerializePrimaryDisplay(const vector<long> &serializedPrimaryDisplay) void CalculatorManager::DeSerializePrimaryDisplay(const vector<long> &serializedPrimaryDisplay)
{ {
if (serializedPrimaryDisplay.size() == 0) if (serializedPrimaryDisplay.empty())
{ {
return; return;
} }
@ -491,8 +502,12 @@ namespace CalculationManager
void CalculatorManager::MemorizeNumber() void CalculatorManager::MemorizeNumber()
{ {
m_savedCommands.push_back(MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber)); m_savedCommands.push_back(MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber));
if (!(m_currentCalculatorEngine->FInErrorState()))
if (m_currentCalculatorEngine->FInErrorState())
{ {
return;
}
m_currentCalculatorEngine->ProcessCommand(IDC_STORE); m_currentCalculatorEngine->ProcessCommand(IDC_STORE);
auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject(); auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject();
@ -507,7 +522,6 @@ namespace CalculationManager
} }
this->SetMemorizedNumbersString(); this->SetMemorizedNumbersString();
} }
}
/// <summary> /// <summary>
/// Recall the memorized number. /// Recall the memorized number.
@ -517,12 +531,15 @@ namespace CalculationManager
void CalculatorManager::MemorizedNumberLoad(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberLoad(_In_ unsigned int indexOfMemory)
{ {
SaveMemoryCommand(MemoryCommand::MemorizedNumberLoad, indexOfMemory); SaveMemoryCommand(MemoryCommand::MemorizedNumberLoad, indexOfMemory);
if (!(m_currentCalculatorEngine->FInErrorState()))
if (m_currentCalculatorEngine->FInErrorState())
{ {
return;
}
this->MemorizedNumberSelect(indexOfMemory); this->MemorizedNumberSelect(indexOfMemory);
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL); m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
} }
}
/// <summary> /// <summary>
/// Do the addition to the selected memory /// Do the addition to the selected memory
@ -533,8 +550,12 @@ namespace CalculationManager
void CalculatorManager::MemorizedNumberAdd(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberAdd(_In_ unsigned int indexOfMemory)
{ {
SaveMemoryCommand(MemoryCommand::MemorizedNumberAdd, indexOfMemory); SaveMemoryCommand(MemoryCommand::MemorizedNumberAdd, indexOfMemory);
if (!(m_currentCalculatorEngine->FInErrorState()))
if (m_currentCalculatorEngine->FInErrorState())
{ {
return;
}
if (m_memorizedNumbers.empty()) if (m_memorizedNumbers.empty())
{ {
this->MemorizeNumber(); this->MemorizeNumber();
@ -551,7 +572,6 @@ namespace CalculationManager
m_displayCallback->MemoryItemChanged(indexOfMemory); m_displayCallback->MemoryItemChanged(indexOfMemory);
} }
}
void CalculatorManager::MemorizedNumberClear(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberClear(_In_ unsigned int indexOfMemory)
{ {
@ -571,8 +591,12 @@ namespace CalculationManager
void CalculatorManager::MemorizedNumberSubtract(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberSubtract(_In_ unsigned int indexOfMemory)
{ {
SaveMemoryCommand(MemoryCommand::MemorizedNumberSubtract, indexOfMemory); SaveMemoryCommand(MemoryCommand::MemorizedNumberSubtract, indexOfMemory);
if (!(m_currentCalculatorEngine->FInErrorState()))
if (m_currentCalculatorEngine->FInErrorState())
{ {
return;
}
// To add negative of the number on display to the memory -x = x - 2x // To add negative of the number on display to the memory -x = x - 2x
if (m_memorizedNumbers.empty()) if (m_memorizedNumbers.empty())
{ {
@ -592,7 +616,6 @@ namespace CalculationManager
m_displayCallback->MemoryItemChanged(indexOfMemory); m_displayCallback->MemoryItemChanged(indexOfMemory);
} }
}
/// <summary> /// <summary>
/// Clear all the memorized values /// Clear all the memorized values
@ -614,12 +637,14 @@ namespace CalculationManager
/// <param name="indexOfMemory">Index of the target memory</param> /// <param name="indexOfMemory">Index of the target memory</param>
void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory)
{ {
if (!(m_currentCalculatorEngine->FInErrorState())) if (m_currentCalculatorEngine->FInErrorState())
{ {
return;
}
auto memoryObject = m_memorizedNumbers.at(indexOfMemory); auto memoryObject = m_memorizedNumbers.at(indexOfMemory);
m_currentCalculatorEngine->PersistedMemObject(memoryObject); m_currentCalculatorEngine->PersistedMemObject(memoryObject);
} }
}
/// <summary> /// <summary>
/// Helper function that needs to be executed when memory is modified /// Helper function that needs to be executed when memory is modified
@ -628,15 +653,17 @@ namespace CalculationManager
/// <param name="indexOfMemory">Index of the target memory</param> /// <param name="indexOfMemory">Index of the target memory</param>
void CalculatorManager::MemorizedNumberChanged(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberChanged(_In_ unsigned int indexOfMemory)
{ {
if (!(m_currentCalculatorEngine->FInErrorState())) if (m_currentCalculatorEngine->FInErrorState())
{ {
return;
}
auto memoryObject = m_currentCalculatorEngine->PersistedMemObject(); auto memoryObject = m_currentCalculatorEngine->PersistedMemObject();
if (memoryObject != nullptr) if (memoryObject != nullptr)
{ {
m_memorizedNumbers.at(indexOfMemory) = *memoryObject; m_memorizedNumbers.at(indexOfMemory) = *memoryObject;
} }
} }
}
void CalculatorManager::SaveMemoryCommand(_In_ MemoryCommand command, _In_ unsigned int indexOfMemory) void CalculatorManager::SaveMemoryCommand(_In_ MemoryCommand command, _In_ unsigned int indexOfMemory)
{ {

View file

@ -42,7 +42,7 @@ namespace CalculationManager
MemorizedNumberClear = 335 MemorizedNumberClear = 335
}; };
class CalculatorManager sealed : public virtual ICalcDisplay class CalculatorManager final : public ICalcDisplay
{ {
private: private:
ICalcDisplay* const m_displayCallback; ICalcDisplay* const m_displayCallback;
@ -95,7 +95,8 @@ namespace CalculationManager
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override; void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(const std::wstring& parenthesisCount); void SetParenDisplayText(const std::wstring& parenthesisCount) override;
void OnNoRightParenAdded() override;
void DisplayPasteError(); void DisplayPasteError();
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;
@ -141,7 +142,7 @@ namespace CalculationManager
std::shared_ptr<HISTORYITEM> const& GetHistoryItem(_In_ unsigned int uIdx); std::shared_ptr<HISTORYITEM> const& GetHistoryItem(_In_ unsigned int uIdx);
bool RemoveHistoryItem(_In_ unsigned int uIdx); bool RemoveHistoryItem(_In_ unsigned int uIdx);
void ClearHistory(); void ClearHistory();
const size_t MaxHistorySize() const { return m_pHistory->MaxHistorySize(); } size_t MaxHistorySize() const { return m_pHistory->MaxHistorySize(); }
CalculationManager::Command GetCurrentDegreeMode(); CalculationManager::Command GetCurrentDegreeMode();
void SetHistory(_In_ CALCULATOR_MODE eMode, _In_ std::vector<std::shared_ptr<HISTORYITEM>> const& history); void SetHistory(_In_ CALCULATOR_MODE eMode, _In_ std::vector<std::shared_ptr<HISTORYITEM>> const& history);
void SetInHistoryItemLoadMode(_In_ bool isHistoryItemLoadMode); void SetInHistoryItemLoadMode(_In_ bool isHistoryItemLoadMode);

View file

@ -98,8 +98,8 @@ void CBinaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor)
COpndCommand::COpndCommand(shared_ptr<CalculatorVector<int>> const &commands, bool fNegative, bool fDecimal, bool fSciFmt) : COpndCommand::COpndCommand(shared_ptr<CalculatorVector<int>> const &commands, bool fNegative, bool fDecimal, bool fSciFmt) :
m_commands(commands), m_commands(commands),
m_fNegative(fNegative), m_fNegative(fNegative),
m_fDecimal(fDecimal),
m_fSciFmt(fSciFmt), m_fSciFmt(fSciFmt),
m_fDecimal(fDecimal),
m_fInitialized(false), m_fInitialized(false),
m_value{} m_value{}
{} {}
@ -287,7 +287,7 @@ const wstring & COpndCommand::GetToken(wchar_t decimalSymbol)
return m_token; return m_token;
} }
wstring COpndCommand::GetString(uint32_t radix, int32_t precision, wchar_t decimalSymbol) wstring COpndCommand::GetString(uint32_t radix, int32_t precision)
{ {
wstring result{}; wstring result{};
@ -303,4 +303,3 @@ void COpndCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor)
{ {
commandVisitor.Visit(*this); commandVisitor.Visit(*this);
} }

View file

@ -10,9 +10,9 @@ class CParentheses final : public IParenthesisCommand
{ {
public: public:
CParentheses(_In_ int command); CParentheses(_In_ int command);
int GetCommand() const; int GetCommand() const override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
private: private:
int m_command; int m_command;
@ -23,11 +23,11 @@ class CUnaryCommand final : public IUnaryCommand
public: public:
CUnaryCommand(int command); CUnaryCommand(int command);
CUnaryCommand(int command1, int command2); CUnaryCommand(int command1, int command2);
const std::shared_ptr<CalculatorVector<int>> & GetCommands() const; const std::shared_ptr<CalculatorVector<int>> & GetCommands() const override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void SetCommand(int command); void SetCommand(int command) override;
void SetCommands(int command1, int command2); void SetCommands(int command1, int command2) override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
private: private:
std::shared_ptr<CalculatorVector<int>> m_command; std::shared_ptr<CalculatorVector<int>> m_command;
@ -37,10 +37,10 @@ class CBinaryCommand final : public IBinaryCommand
{ {
public: public:
CBinaryCommand(int command); CBinaryCommand(int command);
void SetCommand(int command); void SetCommand(int command) override;
int GetCommand() const; int GetCommand() const override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
private: private:
int m_command; int m_command;
@ -56,18 +56,18 @@ public:
bool fSciFmt); bool fSciFmt);
void Initialize(CalcEngine::Rational const& rat); void Initialize(CalcEngine::Rational const& rat);
const std::shared_ptr<CalculatorVector<int>> & GetCommands() const; const std::shared_ptr<CalculatorVector<int>> & GetCommands() const override;
void SetCommands(std::shared_ptr<CalculatorVector<int>> const& commands); void SetCommands(std::shared_ptr<CalculatorVector<int>> const& commands) override;
void AppendCommand(int command); void AppendCommand(int command) override;
void ToggleSign(); void ToggleSign() override;
void RemoveFromEnd(); void RemoveFromEnd() override;
bool IsNegative() const; bool IsNegative() const override;
bool IsSciFmt() const; bool IsSciFmt() const override;
bool IsDecimalPresent() const; bool IsDecimalPresent() const override;
const std::wstring & GetToken(wchar_t decimalSymbol); const std::wstring & GetToken(wchar_t decimalSymbol) override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
std::wstring GetString(uint32_t radix, int32_t precision, wchar_t decimalSymbol); std::wstring GetString(uint32_t radix, int32_t precision);
private: private:
std::shared_ptr<CalculatorVector<int>> m_commands; std::shared_ptr<CalculatorVector<int>> m_commands;

View file

@ -30,7 +30,7 @@ public:
class IBinaryCommand : public IOperatorCommand class IBinaryCommand : public IOperatorCommand
{ {
public: public:
virtual void SetCommand(int command) = 0; virtual void SetCommand(int command) override = 0;
virtual int GetCommand() const = 0; virtual int GetCommand() const = 0;
}; };

View file

@ -22,7 +22,7 @@ namespace CalcEngine
bool IsEmpty() { return value.empty(); } bool IsEmpty() { return value.empty(); }
bool IsNegative() { return m_isNegative; } bool IsNegative() { return m_isNegative; }
void IsNegative(bool value) { m_isNegative = value; } void IsNegative(bool isNegative) { m_isNegative = isNegative; }
std::wstring value; std::wstring value;
@ -53,7 +53,7 @@ namespace CalcEngine
bool TryBeginExponent(); bool TryBeginExponent();
void Backspace(); void Backspace();
void SetDecimalSymbol(wchar_t decSymbol); void SetDecimalSymbol(wchar_t decSymbol);
std::wstring ToString(uint32_t radix, bool isIntegerMode); std::wstring ToString(uint32_t radix);
Rational ToRational(uint32_t radix, int32_t precision); Rational ToRational(uint32_t radix, int32_t precision);
private: private:

View file

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

View file

@ -61,7 +61,7 @@ void* zmalloc(size_t a)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void _dupnum(_In_ PNUMBER dest, _In_ PNUMBER src) void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src)
{ {
memcpy(dest, src, (int)(sizeof(NUMBER) + ((src)->cdigit)*(sizeof(MANTTYPE)))); memcpy(dest, src, (int)(sizeof(NUMBER) + ((src)->cdigit)*(sizeof(MANTTYPE))));
} }
@ -566,7 +566,7 @@ wchar_t NormalizeCharDigit(wchar_t c, uint32_t radix)
// is in the range where this is not ambiguous. // is in the range where this is not ambiguous.
if (size_t{ radix } >= DIGITS.find(L'A') && size_t { radix } <= DIGITS.find(L'Z')) if (size_t{ radix } >= DIGITS.find(L'A') && size_t { radix } <= DIGITS.find(L'Z'))
{ {
return toupper(c); return towupper(c);
} }
return c; return c;
@ -612,6 +612,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
break; break;
} }
// Drop through in the 'e'-as-a-digit case // Drop through in the 'e'-as-a-digit case
[[fallthrough]];
default: default:
state = machine[state][NZ]; state = machine[state][NZ];
break; break;
@ -646,7 +647,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
break; break;
case LD: case LD:
pnumret->exp++; pnumret->exp++;
// Fall through [[fallthrough]];
case DD: case DD:
{ {
curChar = NormalizeCharDigit(curChar, radix); curChar = NormalizeCharDigit(curChar, radix);
@ -1057,10 +1058,6 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, int autoformat, uint32
length = precision; length = precision;
} }
// 2 for signs, 1 for 'e'(or leading zero), 1 for dp, 1 for null and
// 10 for maximum exponent size.
int cchNum = (precision + 16);
// If there is a chance a round has to occur, round. // If there is a chance a round has to occur, round.
// - if number is zero no rounding // - if number is zero no rounding
// - if number of digits is less than the maximum output no rounding // - if number of digits is less than the maximum output no rounding
@ -1274,7 +1271,7 @@ PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision)
// Convert p and q of rational form from internal base to requested base. // Convert p and q of rational form from internal base to requested base.
// Scale by largest power of BASEX possible. // Scale by largest power of BASEX possible.
long scaleby = min(temprat->pp->exp, temprat->pq->exp); long scaleby = min(temprat->pp->exp, temprat->pq->exp);
scaleby = max(scaleby, 0); scaleby = max(scaleby, 0l);
temprat->pp->exp -= scaleby; temprat->pp->exp -= scaleby;
temprat->pq->exp -= scaleby; temprat->pq->exp -= scaleby;

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -16,7 +16,7 @@
#include "pch.h" #include "pch.h"
#include "ratpak.h" #include "ratpak.h"
using namespace std;
void lshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void lshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
@ -216,4 +216,3 @@ void modrat( PRAT *pa, PRAT b )
destroyrat( tmp ); destroyrat( tmp );
} }

View file

@ -38,7 +38,7 @@ using namespace std;
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gcdrat( PRAT *pa, uint32_t radix, int32_t precision) void gcdrat( PRAT *pa, int32_t precision)
{ {
PNUMBER pgcd= nullptr; PNUMBER pgcd= nullptr;

View file

@ -1,480 +1,482 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// Autogenerated by _dumprawrat in support.c #pragma once
NUMBER init_num_one= {
// Autogenerated by _dumprawrat in support.cpp
inline const NUMBER init_num_one= {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_two= { inline const NUMBER init_num_two= {
1, 1,
1, 1,
0, 0,
{ 2,} { 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_five= { inline const NUMBER init_num_five= {
1, 1,
1, 1,
0, 0,
{ 5,} { 5,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_six= { inline const NUMBER init_num_six= {
1, 1,
1, 1,
0, 0,
{ 6,} { 6,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_ten= { inline const NUMBER init_num_ten= {
1, 1,
1, 1,
0, 0,
{ 10,} { 10,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_smallest = { inline const NUMBER init_p_rat_smallest = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_smallest = { inline const NUMBER init_q_rat_smallest = {
1, 1,
4, 4,
0, 0,
{ 0, 190439170, 901055854, 10097,} { 0, 190439170, 901055854, 10097,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_negsmallest = { inline const NUMBER init_p_rat_negsmallest = {
-1, -1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_negsmallest = { inline const NUMBER init_q_rat_negsmallest = {
1, 1,
4, 4,
0, 0,
{ 0, 190439170, 901055854, 10097,} { 0, 190439170, 901055854, 10097,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_pt_eight_five = { inline const NUMBER init_p_pt_eight_five = {
1, 1,
1, 1,
0, 0,
{ 85,} { 85,}
}; };
NUMBER init_q_pt_eight_five = { inline const NUMBER init_q_pt_eight_five = {
1, 1,
1, 1,
0, 0,
{ 100,} { 100,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_six = { inline const NUMBER init_p_rat_six = {
1, 1,
1, 1,
0, 0,
{ 6,} { 6,}
}; };
NUMBER init_q_rat_six = { inline const NUMBER init_q_rat_six = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_two = { inline const NUMBER init_p_rat_two = {
1, 1,
1, 1,
0, 0,
{ 2,} { 2,}
}; };
NUMBER init_q_rat_two = { inline const NUMBER init_q_rat_two = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_zero = { inline const NUMBER init_p_rat_zero = {
1, 1,
1, 1,
0, 0,
{ 0,} { 0,}
}; };
NUMBER init_q_rat_zero = { inline const NUMBER init_q_rat_zero = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_one = { inline const NUMBER init_p_rat_one = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_one = { inline const NUMBER init_q_rat_one = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_neg_one = { inline const NUMBER init_p_rat_neg_one = {
-1, -1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_neg_one = { inline const NUMBER init_q_rat_neg_one = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_half = { inline const NUMBER init_p_rat_half = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_half = { inline const NUMBER init_q_rat_half = {
1, 1,
1, 1,
0, 0,
{ 2,} { 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_ten = { inline const NUMBER init_p_rat_ten = {
1, 1,
1, 1,
0, 0,
{ 10,} { 10,}
}; };
NUMBER init_q_rat_ten = { inline const NUMBER init_q_rat_ten = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_pi = { inline const NUMBER init_p_pi = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
NUMBER init_q_pi = { inline const NUMBER init_q_pi = {
1, 1,
6, 6,
0, 0,
{ 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,} { 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_two_pi = { inline const NUMBER init_p_two_pi = {
1, 1,
6, 6,
0, 0,
{ 251055792, 567796700, 1773504224, 1198217877, 428852897, 17,} { 251055792, 567796700, 1773504224, 1198217877, 428852897, 17,}
}; };
NUMBER init_q_two_pi = { inline const NUMBER init_q_two_pi = {
1, 1,
6, 6,
0, 0,
{ 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,} { 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_pi_over_two = { inline const NUMBER init_p_pi_over_two = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
NUMBER init_q_pi_over_two = { inline const NUMBER init_q_pi_over_two = {
1, 1,
6, 6,
0, 0,
{ 429277156, 92748659, 1573365737, 1740753005, 1019699561, 5,} { 429277156, 92748659, 1573365737, 1740753005, 1019699561, 5,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_one_pt_five_pi = { inline const NUMBER init_p_one_pt_five_pi = {
1, 1,
6, 6,
0, 0,
{ 1241201312, 270061909, 1051574664, 1924965045, 1340320627, 70,} { 1241201312, 270061909, 1051574664, 1924965045, 1340320627, 70,}
}; };
NUMBER init_q_one_pt_five_pi = { inline const NUMBER init_q_one_pt_five_pi = {
1, 1,
6, 6,
0, 0,
{ 1579671539, 1837970263, 1067644340, 523549916, 2119366659, 14,} { 1579671539, 1837970263, 1067644340, 523549916, 2119366659, 14,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_e_to_one_half = { inline const NUMBER init_p_e_to_one_half = {
1, 1,
6, 6,
0, 0,
{ 256945612, 216219427, 223516738, 477442596, 581063757, 23,} { 256945612, 216219427, 223516738, 477442596, 581063757, 23,}
}; };
NUMBER init_q_e_to_one_half = { inline const NUMBER init_q_e_to_one_half = {
1, 1,
6, 6,
0, 0,
{ 1536828363, 698484484, 1127331835, 224219346, 245499408, 14,} { 1536828363, 698484484, 1127331835, 224219346, 245499408, 14,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_exp = { inline const NUMBER init_p_rat_exp = {
1, 1,
6, 6,
0, 0,
{ 943665199, 1606559160, 1094967530, 1759391384, 1671799163, 1123581,} { 943665199, 1606559160, 1094967530, 1759391384, 1671799163, 1123581,}
}; };
NUMBER init_q_rat_exp = { inline const NUMBER init_q_rat_exp = {
1, 1,
6, 6,
0, 0,
{ 879242208, 2022880100, 617392930, 1374929092, 1367479163, 413342,} { 879242208, 2022880100, 617392930, 1374929092, 1367479163, 413342,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_ln_ten = { inline const NUMBER init_p_ln_ten = {
1, 1,
6, 6,
0, 0,
{ 2086268922, 165794492, 1416063951, 1851428830, 1893239400, 65366841,} { 2086268922, 165794492, 1416063951, 1851428830, 1893239400, 65366841,}
}; };
NUMBER init_q_ln_ten = { inline const NUMBER init_q_ln_ten = {
1, 1,
6, 6,
0, 0,
{ 26790652, 564532679, 783998273, 216030448, 1564709968, 28388458,} { 26790652, 564532679, 783998273, 216030448, 1564709968, 28388458,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_ln_two = { inline const NUMBER init_p_ln_two = {
1, 1,
6, 6,
0, 0,
{ 1789230241, 1057927868, 715399197, 908801241, 1411265331, 3,} { 1789230241, 1057927868, 715399197, 908801241, 1411265331, 3,}
}; };
NUMBER init_q_ln_two = { inline const NUMBER init_q_ln_two = {
1, 1,
6, 6,
0, 0,
{ 1559869847, 1930657510, 1228561531, 219003871, 593099283, 5,} { 1559869847, 1930657510, 1228561531, 219003871, 593099283, 5,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rad_to_deg = { inline const NUMBER init_p_rad_to_deg = {
1, 1,
6, 6,
0, 0,
{ 2127722024, 1904928383, 2016479213, 2048947859, 1578647346, 492,} { 2127722024, 1904928383, 2016479213, 2048947859, 1578647346, 492,}
}; };
NUMBER init_q_rad_to_deg = { inline const NUMBER init_q_rad_to_deg = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rad_to_grad = { inline const NUMBER init_p_rad_to_grad = {
1, 1,
6, 6,
0, 0,
{ 2125526288, 684931327, 570267400, 129125085, 1038224725, 547,} { 2125526288, 684931327, 570267400, 129125085, 1038224725, 547,}
}; };
NUMBER init_q_rad_to_grad = { inline const NUMBER init_q_rad_to_grad = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_qword = { inline const NUMBER init_p_rat_qword = {
1, 1,
3, 3,
0, 0,
{ 2147483647, 2147483647, 3,} { 2147483647, 2147483647, 3,}
}; };
NUMBER init_q_rat_qword = { inline const NUMBER init_q_rat_qword = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_dword = { inline const NUMBER init_p_rat_dword = {
1, 1,
2, 2,
0, 0,
{ 2147483647, 1,} { 2147483647, 1,}
}; };
NUMBER init_q_rat_dword = { inline const NUMBER init_q_rat_dword = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_max_long = { inline const NUMBER init_p_rat_max_long = {
1, 1,
1, 1,
0, 0,
{ 2147483647,} { 2147483647,}
}; };
NUMBER init_q_rat_max_long = { inline const NUMBER init_q_rat_max_long = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_min_long = { inline const NUMBER init_p_rat_min_long = {
-1, -1,
2, 2,
0, 0,
{ 0, 1,} { 0, 1,}
}; };
NUMBER init_q_rat_min_long = { inline const NUMBER init_q_rat_min_long = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_word = { inline const NUMBER init_p_rat_word = {
1, 1,
1, 1,
0, 0,
{ 65535,} { 65535,}
}; };
NUMBER init_q_rat_word = { inline const NUMBER init_q_rat_word = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_byte = { inline const NUMBER init_p_rat_byte = {
1, 1,
1, 1,
0, 0,
{ 255,} { 255,}
}; };
NUMBER init_q_rat_byte = { inline const NUMBER init_q_rat_byte = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_400 = { inline const NUMBER init_p_rat_400 = {
1, 1,
1, 1,
0, 0,
{ 400,} { 400,}
}; };
NUMBER init_q_rat_400 = { inline const NUMBER init_q_rat_400 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_360 = { inline const NUMBER init_p_rat_360 = {
1, 1,
1, 1,
0, 0,
{ 360,} { 360,}
}; };
NUMBER init_q_rat_360 = { inline const NUMBER init_q_rat_360 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_200 = { inline const NUMBER init_p_rat_200 = {
1, 1,
1, 1,
0, 0,
{ 200,} { 200,}
}; };
NUMBER init_q_rat_200 = { inline const NUMBER init_q_rat_200 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_180 = { inline const NUMBER init_p_rat_180 = {
1, 1,
1, 1,
0, 0,
{ 180,} { 180,}
}; };
NUMBER init_q_rat_180 = { inline const NUMBER init_q_rat_180 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_max_exp = { inline const NUMBER init_p_rat_max_exp = {
1, 1,
1, 1,
0, 0,
{ 100000,} { 100000,}
}; };
NUMBER init_q_rat_max_exp = { inline const NUMBER init_q_rat_max_exp = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_min_exp = { inline const NUMBER init_p_rat_min_exp = {
-1, -1,
1, 1,
0, 0,
{ 100000,} { 100000,}
}; };
NUMBER init_q_rat_min_exp = { inline const NUMBER init_q_rat_min_exp = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_max_fact = { inline const NUMBER init_p_rat_max_fact = {
1, 1,
1, 1,
0, 0,
{ 3249, } { 3249, }
}; };
NUMBER init_q_rat_max_fact = { inline const NUMBER init_q_rat_max_fact = {
1, 1,
1, 1,
0, 0,
{ 1, } { 1, }
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_min_fact = { inline const NUMBER init_p_rat_min_fact = {
-1, -1,
1, 1,
0, 0,
{ 1000, } { 1000, }
}; };
NUMBER init_q_rat_min_fact = { inline const NUMBER init_q_rat_min_fact = {
1, 1,
1, 1,
0, 0,

View file

@ -231,7 +231,7 @@ memmove( (x)->pp->mant, &((x)->pp->mant[trim]), sizeof(MANTTYPE)*((x)->pp->cdigi
(x)->pp->cdigit -= trim; \ (x)->pp->cdigit -= trim; \
(x)->pp->exp += trim; \ (x)->pp->exp += trim; \
} \ } \
trim = min((x)->pp->exp,(x)->pq->exp);\ trim = std::min((x)->pp->exp,(x)->pq->exp);\
(x)->pp->exp -= trim;\ (x)->pp->exp -= trim;\
(x)->pq->exp -= trim;\ (x)->pq->exp -= trim;\
} }
@ -417,7 +417,7 @@ extern void tanrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
// angle type // angle type
extern void tananglerat( _Inout_ PRAT *px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision); extern void tananglerat( _Inout_ PRAT *px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
extern void _dupnum(_In_ PNUMBER dest, _In_ PNUMBER src); extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src);
extern void _destroynum( _In_ PNUMBER pnum ); extern void _destroynum( _In_ PNUMBER pnum );
extern void _destroyrat( _In_ PRAT prat ); extern void _destroyrat( _In_ PRAT prat );
@ -430,7 +430,7 @@ extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision);
extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision); extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision);
extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision); extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision);
extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b ); extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b );
extern void gcdrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision); extern void gcdrat( _Inout_ PRAT *pa, int32_t precision);
extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix);
extern void mulnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b ); extern void mulnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b );

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -31,8 +31,8 @@ static int cbitsofprecision = 0;
#define READRAWNUM(v) #define READRAWNUM(v)
#define DUMPRAWRAT(v) _dumprawrat(#v,v, wcout) #define DUMPRAWRAT(v) _dumprawrat(#v,v, wcout)
#define DUMPRAWNUM(v) fprintf( stderr, \ #define DUMPRAWNUM(v) fprintf( stderr, \
"// Autogenerated by _dumprawrat in support.c\n" ); \ "// Autogenerated by _dumprawrat in support.cpp\n" ); \
fprintf( stderr, "NUMBER init_" #v "= {\n" ); \ fprintf( stderr, "inline const NUMBER init_" #v "= {\n" ); \
_dumprawnum(v, wcout); \ _dumprawnum(v, wcout); \
fprintf( stderr, "};\n" ) fprintf( stderr, "};\n" )

View file

@ -109,22 +109,8 @@ CategorySelectionInitializer UnitConverter::SetCurrentCategory(const Category& i
vector<Unit>& unitVector = m_categoryToUnits[m_currentCategory]; vector<Unit>& unitVector = m_categoryToUnits[m_currentCategory];
for (unsigned int i = 0; i < unitVector.size(); i++) for (unsigned int i = 0; i < unitVector.size(); i++)
{ {
if (unitVector[i].id == m_fromType.id) unitVector[i].isConversionSource = (unitVector[i].id == m_fromType.id);
{ unitVector[i].isConversionTarget = (unitVector[i].id == m_toType.id);
unitVector[i].isConversionSource = true;
}
else
{
unitVector[i].isConversionSource = false;
}
if (unitVector[i].id == m_toType.id)
{
unitVector[i].isConversionTarget = true;
}
else
{
unitVector[i].isConversionTarget = false;
}
} }
m_currentCategory = input; m_currentCategory = input;
if (!m_currentCategory.supportsNegative && m_currentDisplay.front() == L'-') if (!m_currentCategory.supportsNegative && m_currentDisplay.front() == L'-')
@ -156,8 +142,11 @@ Category UnitConverter::GetCurrentCategory()
/// <param name="toType">Unit struct we are converting to</param> /// <param name="toType">Unit struct we are converting to</param>
void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType) void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType)
{ {
if (CheckLoad()) if (!CheckLoad())
{ {
return;
}
m_fromType = fromType; m_fromType = fromType;
m_toType = toType; m_toType = toType;
Calculate(); Calculate();
@ -165,7 +154,6 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType
UpdateCurrencySymbols(); UpdateCurrencySymbols();
UpdateViewModel(); UpdateViewModel();
} }
}
/// <summary> /// <summary>
/// Switches the active field, indicating that we are now entering data into /// Switches the active field, indicating that we are now entering data into
@ -181,8 +169,11 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType
/// </param> /// </param>
void UnitConverter::SwitchActive(const wstring& newValue) void UnitConverter::SwitchActive(const wstring& newValue)
{ {
if (CheckLoad()) if (!CheckLoad())
{ {
return;
}
swap(m_fromType, m_toType); swap(m_fromType, m_toType);
swap(m_currentHasDecimal, m_returnHasDecimal); swap(m_currentHasDecimal, m_returnHasDecimal);
m_returnDisplay = m_currentDisplay; m_returnDisplay = m_currentDisplay;
@ -198,7 +189,6 @@ void UnitConverter::SwitchActive(const wstring& newValue)
m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second); m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second);
} }
} }
}
wstring UnitConverter::CategoryToString(const Category& c, const wchar_t * delimiter) wstring UnitConverter::CategoryToString(const Category& c, const wchar_t * delimiter)
{ {
@ -291,8 +281,11 @@ wstring UnitConverter::ConversionDataToString(ConversionData d, const wchar_t *
/// </summary> /// </summary>
wstring UnitConverter::Serialize() wstring UnitConverter::Serialize()
{ {
if (CheckLoad()) if (!CheckLoad())
{ {
return wstring();
}
wstringstream out(wstringstream::out); wstringstream out(wstringstream::out);
const wchar_t * delimiter = L";"; const wchar_t * delimiter = L";";
@ -302,8 +295,8 @@ wstring UnitConverter::Serialize()
out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter; out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter;
out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|"; out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|";
wstringstream categoryString(wstringstream::out); wstringstream categoryString(wstringstream::out);
wstringstream categoryToUnitString(wstringstream::out);; wstringstream categoryToUnitString(wstringstream::out);
wstringstream unitToUnitToDoubleString(wstringstream::out);; wstringstream unitToUnitToDoubleString(wstringstream::out);
for (const Category& c : m_categories) for (const Category& c : m_categories)
{ {
categoryString << CategoryToString(c, delimiter) << ","; categoryString << CategoryToString(c, delimiter) << ",";
@ -336,11 +329,6 @@ wstring UnitConverter::Serialize()
wstring test = out.str(); wstring test = out.str();
return test; return test;
} }
else
{
return wstring();
}
}
/// <summary> /// <summary>
/// De-Serializes the data in the converter from a string /// De-Serializes the data in the converter from a string
@ -349,8 +337,12 @@ wstring UnitConverter::Serialize()
void UnitConverter::DeSerialize(const wstring& serializedData) void UnitConverter::DeSerialize(const wstring& serializedData)
{ {
Reset(); Reset();
if (!serializedData.empty())
if (serializedData.empty())
{ {
return;
}
vector<wstring> outerTokens = StringToVector(serializedData, L"|"); vector<wstring> outerTokens = StringToVector(serializedData, L"|");
assert(outerTokens.size() == EXPECTEDSERIALIZEDTOKENCOUNT); assert(outerTokens.size() == EXPECTEDSERIALIZEDTOKENCOUNT);
m_fromType = StringToUnit(outerTokens[0]); m_fromType = StringToUnit(outerTokens[0]);
@ -398,7 +390,6 @@ void UnitConverter::DeSerialize(const wstring& serializedData)
} }
UpdateViewModel(); UpdateViewModel();
} }
}
/// <summary> /// <summary>
/// De-Serializes the data in the converter from a string /// De-Serializes the data in the converter from a string
@ -406,8 +397,11 @@ void UnitConverter::DeSerialize(const wstring& serializedData)
/// <param name="userPreferences">wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it</param> /// <param name="userPreferences">wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it</param>
void UnitConverter::RestoreUserPreferences(const wstring& userPreferences) void UnitConverter::RestoreUserPreferences(const wstring& userPreferences)
{ {
if (!userPreferences.empty()) if (userPreferences.empty())
{ {
return;
}
vector<wstring> outerTokens = StringToVector(userPreferences, L"|"); vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
if (outerTokens.size() == 3) if (outerTokens.size() == 3)
{ {
@ -416,7 +410,6 @@ void UnitConverter::RestoreUserPreferences(const wstring& userPreferences)
m_currentCategory = StringToCategory(outerTokens[2]); m_currentCategory = StringToCategory(outerTokens[2]);
} }
} }
}
/// <summary> /// <summary>
/// Serializes the Category and Associated Units in the converter and returns it as a string /// Serializes the Category and Associated Units in the converter and returns it as a string
@ -479,7 +472,7 @@ wstring UnitConverter::Unquote(const wstring& s)
} }
if (cursor == s.end()) if (cursor == s.end())
{ {
//badly formatted // Badly formatted
break; break;
} }
else else
@ -503,8 +496,11 @@ wstring UnitConverter::Unquote(const wstring& s)
/// <param name="command">Command enum representing the command that was entered</param> /// <param name="command">Command enum representing the command that was entered</param>
void UnitConverter::SendCommand(Command command) void UnitConverter::SendCommand(Command command)
{ {
if (CheckLoad()) if (!CheckLoad())
{ {
return;
}
// TODO: Localization of characters // TODO: Localization of characters
bool clearFront = false; bool clearFront = false;
if (m_currentDisplay == L"0") if (m_currentDisplay == L"0")
@ -641,7 +637,6 @@ void UnitConverter::SendCommand(Command command)
UpdateViewModel(); UpdateViewModel();
} }
}
/// <summary> /// <summary>
/// Sets the callback interface to send display update calls to /// Sets the callback interface to send display update calls to
@ -844,8 +839,11 @@ void UnitConverter::Reset()
ClearValues(); ClearValues();
m_switchedActive = false; m_switchedActive = false;
if (!m_categories.empty()) if (m_categories.empty())
{ {
return;
}
m_currentCategory = m_categories[0]; m_currentCategory = m_categories[0];
m_categoryToUnits.clear(); m_categoryToUnits.clear();
@ -885,7 +883,6 @@ void UnitConverter::Reset()
InitializeSelectedUnits(); InitializeSelectedUnits();
Calculate(); Calculate();
} }
}
/// <summary> /// <summary>
/// Sets the active data loader based on the input category. /// Sets the active data loader based on the input category.
@ -1029,8 +1026,11 @@ void UnitConverter::Calculate()
/// <param name="input">wstring to trim</param> /// <param name="input">wstring to trim</param>
void UnitConverter::TrimString(wstring& returnString) void UnitConverter::TrimString(wstring& returnString)
{ {
if (returnString.find(L'.') != m_returnDisplay.npos) if (returnString.find(L'.') == m_returnDisplay.npos)
{ {
return;
}
wstring::iterator iter; wstring::iterator iter;
for (iter = returnString.end() - 1; ;iter--) for (iter = returnString.end() - 1; ;iter--)
{ {
@ -1045,7 +1045,6 @@ void UnitConverter::TrimString(wstring& returnString)
returnString.erase(returnString.end()-1, returnString.end()); returnString.erase(returnString.end()-1, returnString.end());
} }
} }
}
/// <summary> /// <summary>
/// Rounds the given double to the given number of significant digits /// Rounds the given double to the given number of significant digits

View file

@ -51,7 +51,7 @@ namespace UnitConversionManager
// null checks. // null checks.
// //
// unitId, name, abbreviation, isConversionSource, isConversionTarget, isWhimsical // unitId, name, abbreviation, isConversionSource, isConversionTarget, isWhimsical
const Unit EMPTY_UNIT = Unit{ -1, L"", L"", true, true, false }; inline const Unit EMPTY_UNIT = Unit{ -1, L"", L"", true, true, false };
struct Category struct Category
{ {

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
@ -7,11 +7,16 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
// Windows headers define min/max macros.
// Disable it for project code.
#define NOMINMAX
#include <assert.h> #include <assert.h>
#include <windows.h> #include <windows.h>
#include <winerror.h> #include <winerror.h>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <iterator>
#include <string> #include <string>
#include <memory> #include <memory>
#include <vector> #include <vector>

View file

@ -32,14 +32,11 @@ using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input; using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media; using namespace Windows::UI::Xaml::Media;
namespace CalculatorApp::ViewModel::ApplicationViewModelProperties namespace
{ {
StringReference Mode(L"Mode"); StringReference CategoriesPropertyName(L"Categories");
StringReference PreviousMode(L"PreviousMode"); StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility");
StringReference ClearMemoryVisibility(L"ClearMemoryVisibility"); StringReference AppBarVisibilityPropertyName(L"AppBarVisibility");
StringReference AppBarVisibility(L"AppBarVisibility");
StringReference CategoryName(L"CategoryName");
StringReference Categories(L"Categories");
} }
ApplicationViewModel::ApplicationViewModel() : ApplicationViewModel::ApplicationViewModel() :
@ -60,7 +57,7 @@ void ApplicationViewModel::Mode::set(ViewMode value)
PreviousMode = m_mode; PreviousMode = m_mode;
m_mode = value; m_mode = value;
OnModeChanged(); OnModeChanged();
RaisePropertyChanged(ApplicationViewModelProperties::Mode); RaisePropertyChanged(ModePropertyName);
} }
} }
@ -69,7 +66,7 @@ void ApplicationViewModel::Categories::set(IObservableVector<NavCategoryGroup^>^
if (m_categories != value) if (m_categories != value)
{ {
m_categories = value; m_categories = value;
RaisePropertyChanged(ApplicationViewModelProperties::Categories); RaisePropertyChanged(CategoriesPropertyName);
} }
} }
@ -163,11 +160,11 @@ void ApplicationViewModel::OnModeChanged()
// //
// Save the changed mode, so that the new window launches in this mode. // Save the changed mode, so that the new window launches in this mode.
// Don't save until after we have adjusted to the new mode, so we don't save a mode that fails to load. // Don't save until after we have adjusted to the new mode, so we don't save a mode that fails to load.
ApplicationData::Current->LocalSettings->Values->Insert(ApplicationViewModelProperties::Mode, NavCategory::Serialize(m_mode)); ApplicationData::Current->LocalSettings->Values->Insert(ModePropertyName, NavCategory::Serialize(m_mode));
TraceLogger::GetInstance().LogModeChangeEnd(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread())); TraceLogger::GetInstance().LogModeChangeEnd(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
RaisePropertyChanged(ApplicationViewModelProperties::ClearMemoryVisibility); RaisePropertyChanged(ClearMemoryVisibilityPropertyName);
RaisePropertyChanged(ApplicationViewModelProperties::AppBarVisibility); RaisePropertyChanged(AppBarVisibilityPropertyName);
} }
void ApplicationViewModel::OnCopyCommand(Object^ parameter) void ApplicationViewModel::OnCopyCommand(Object^ parameter)

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
@ -11,16 +11,6 @@ namespace CalculatorApp
{ {
namespace ViewModel namespace ViewModel
{ {
namespace ApplicationViewModelProperties
{
extern Platform::StringReference Mode;
extern Platform::StringReference PreviousMode;
extern Platform::StringReference ClearMemoryVisibility;
extern Platform::StringReference AppBarVisibility;
extern Platform::StringReference CategoryName;
extern Platform::StringReference Categories;
}
[Windows::UI::Xaml::Data::Bindable] [Windows::UI::Xaml::Data::Bindable]
public ref class ApplicationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged public ref class ApplicationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{ {
@ -32,9 +22,9 @@ namespace CalculatorApp
OBSERVABLE_OBJECT(); OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_RW(StandardCalculatorViewModel^, CalculatorViewModel); OBSERVABLE_PROPERTY_RW(StandardCalculatorViewModel^, CalculatorViewModel);
OBSERVABLE_PROPERTY_RW(DateCalculatorViewModel^, DateCalcViewModel); OBSERVABLE_PROPERTY_RW(DateCalculatorViewModel^, DateCalcViewModel);
OBSERVABLE_PROPERTY_RW(CalculatorApp::ViewModel::UnitConverterViewModel^, ConverterViewModel); OBSERVABLE_PROPERTY_RW(UnitConverterViewModel^, ConverterViewModel);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::ViewMode, PreviousMode); OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::ViewMode, PreviousMode);
OBSERVABLE_PROPERTY_RW(Platform::String^, CategoryName); OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, CategoryName);
COMMAND_FOR_METHOD(CopyCommand, ApplicationViewModel::OnCopyCommand); COMMAND_FOR_METHOD(CopyCommand, ApplicationViewModel::OnCopyCommand);
COMMAND_FOR_METHOD(PasteCommand, ApplicationViewModel::OnPasteCommand); COMMAND_FOR_METHOD(PasteCommand, ApplicationViewModel::OnPasteCommand);
@ -48,6 +38,13 @@ namespace CalculatorApp
void set(CalculatorApp::Common::ViewMode value); void set(CalculatorApp::Common::ViewMode value);
} }
static property Platform::String^ ModePropertyName
{
Platform::String^ get()
{
return Platform::StringReference(L"Mode");
}
}
property Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup^>^ Categories property Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup^>^ Categories
{ {

View file

@ -154,6 +154,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -172,6 +174,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -190,6 +194,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -208,6 +214,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -226,6 +234,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -244,6 +254,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -262,6 +274,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -280,6 +294,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View file

@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once
#include "pch.h" #include "pch.h"
#include "AppResourceProvider.h" #include "AppResourceProvider.h"

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
@ -20,6 +20,8 @@ namespace CalculatorApp::Common::Automation
StringReference CategoryNameChanged(L"CategoryNameChanged"); StringReference CategoryNameChanged(L"CategoryNameChanged");
StringReference UpdateCurrencyRates(L"UpdateCurrencyRates"); StringReference UpdateCurrencyRates(L"UpdateCurrencyRates");
StringReference DisplayCopied(L"DisplayCopied"); StringReference DisplayCopied(L"DisplayCopied");
StringReference OpenParenthesisCountChanged(L"OpenParenthesisCountChanged");
StringReference NoParenthesisAdded(L"NoParenthesisAdded");
} }
} }
@ -142,3 +144,21 @@ NarratorAnnouncement^ CalculatorAnnouncement::GetDisplayCopiedAnnouncement(Strin
AutomationNotificationKind::ActionCompleted, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent); AutomationNotificationProcessing::ImportantMostRecent);
} }
NarratorAnnouncement^ CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(String^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::OpenParenthesisCountChanged,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(String^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::NoParenthesisAdded,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
@ -90,5 +90,8 @@ namespace CalculatorApp::Common::Automation
static NarratorAnnouncement^ GetUpdateCurrencyRatesAnnouncement(Platform::String^ announcement); static NarratorAnnouncement^ GetUpdateCurrencyRatesAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetDisplayCopiedAnnouncement(Platform::String^ announcement); static NarratorAnnouncement^ GetDisplayCopiedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetOpenParenthesisCountChangedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetNoRightParenthesisAddedAnnouncement(Platform::String ^ announcement);
}; };
} }

View file

@ -29,8 +29,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue
{ {
if (m_callbackReference) if (m_callbackReference)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetPrimaryDisplay(displayStringValue, isError); calcVM->SetPrimaryDisplay(displayStringValue, isError);
} }
@ -41,20 +40,29 @@ void CalculatorDisplay::SetParenDisplayText(_In_ const std::wstring& parenthesis
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetParenthesisCount(parenthesisCount); calcVM->SetParenthesisCount(parenthesisCount);
} }
} }
} }
void CalculatorDisplay::OnNoRightParenAdded()
{
if (m_callbackReference != nullptr)
{
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
{
calcVM->OnNoRightParenAdded();
}
}
}
void CalculatorDisplay::SetIsInError(bool isError) void CalculatorDisplay::SetIsInError(bool isError)
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->IsInError = isError; calcVM->IsInError = isError;
} }
@ -65,8 +73,7 @@ void CalculatorDisplay::SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorV
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if(auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetExpressionDisplay(tokens, commands); calcVM->SetExpressionDisplay(tokens, commands);
} }
@ -77,8 +84,7 @@ void CalculatorDisplay::SetMemorizedNumbers(_In_ const vector<std::wstring>& new
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetMemorizedNumbers(newMemorizedNumbers); calcVM->SetMemorizedNumbers(newMemorizedNumbers);
} }
@ -89,8 +95,7 @@ void CalculatorDisplay::OnHistoryItemAdded(_In_ unsigned int addedItemIndex)
{ {
if (m_historyCallbackReference != nullptr) if (m_historyCallbackReference != nullptr)
{ {
auto historyVM = m_historyCallbackReference.Resolve<ViewModel::HistoryViewModel>(); if (auto historyVM = m_historyCallbackReference.Resolve<ViewModel::HistoryViewModel>())
if (historyVM)
{ {
historyVM->OnHistoryItemAdded(addedItemIndex); historyVM->OnHistoryItemAdded(addedItemIndex);
} }
@ -101,8 +106,7 @@ void CalculatorDisplay::MaxDigitsReached()
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->OnMaxDigitsReached(); calcVM->OnMaxDigitsReached();
} }
@ -113,8 +117,7 @@ void CalculatorDisplay::BinaryOperatorReceived()
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->OnBinaryOperatorReceived(); calcVM->OnBinaryOperatorReceived();
} }
@ -125,8 +128,7 @@ void CalculatorDisplay::MemoryItemChanged(unsigned int indexOfMemory)
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->OnMemoryItemChanged(indexOfMemory); calcVM->OnMemoryItemChanged(indexOfMemory);
} }

View file

@ -22,6 +22,7 @@ namespace CalculatorApp
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override; void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override;
void OnNoRightParenAdded() override;
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;
void MemoryItemChanged(unsigned int indexOfMemory) override; void MemoryItemChanged(unsigned int indexOfMemory) override;

View file

@ -15,7 +15,6 @@ using namespace Windows::Foundation;
using namespace Windows::System; using namespace Windows::System;
using namespace Windows::ApplicationModel::DataTransfer; using namespace Windows::ApplicationModel::DataTransfer;
size_t maxOperandLength;
unsigned long long maxOperandNumber; unsigned long long maxOperandNumber;
String^ CopyPasteManager::supportedFormats[] = String^ CopyPasteManager::supportedFormats[] =
@ -130,7 +129,7 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m
if (pastedText->Length() > MaxPasteableLength) if (pastedText->Length() > MaxPasteableLength)
{ {
// return NoOp to indicate don't paste anything. // return NoOp to indicate don't paste anything.
TraceLogger::GetInstance().LogInvalidInputPasted(L"PastedExpressionSizeGreaterThanMaxAllowed", L"MoreThanMaxInput", mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"PastedExpressionSizeGreaterThanMaxAllowed", mode, programmerNumberBase, bitLengthType);
return StringReference(PasteErrorString); return StringReference(PasteErrorString);
} }
@ -140,7 +139,7 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m
String^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression); String^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression);
// Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333 // Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333
pasteExpression = Utils::RemoveUnwantedCharsFromWstring(englishString->Data()); pasteExpression = RemoveUnwantedCharsFromWstring(englishString->Data());
// If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste. // If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste.
if (!pasteExpression.empty() && pasteExpression.back() == L'=') if (!pasteExpression.empty() && pasteExpression.back() == L'=')
@ -165,7 +164,7 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m
// validate each operand with patterns for different modes // validate each operand with patterns for different modes
if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType)) if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType))
{ {
TraceLogger::GetInstance().LogInvalidInputPasted(L"InvalidExpressionForPresentMode", pastedText->Data(), mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"InvalidExpressionForPresentMode", mode, programmerNumberBase, bitLengthType);
return StringReference(PasteErrorString); return StringReference(PasteErrorString);
} }
@ -194,7 +193,7 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
if (operands.size() >= MaxOperandCount) if (operands.size() >= MaxOperandCount)
{ {
TraceLogger::GetInstance().LogInvalidInputPasted(L"OperandCountGreaterThanMaxCount", pasteExpression.c_str(), mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"OperandCountGreaterThanMaxCount", mode, programmerNumberBase, bitLengthType);
operands.clear(); operands.clear();
return operands; return operands;
} }
@ -208,7 +207,7 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
// to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999. // to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999.
if (expLength > MaxExponentLength) if (expLength > MaxExponentLength)
{ {
TraceLogger::GetInstance().LogInvalidInputPasted(L"ExponentLengthGreaterThanMaxLength", pasteExpression.c_str(), mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"ExponentLengthGreaterThanMaxLength", mode, programmerNumberBase, bitLengthType);
operands.clear(); operands.clear();
return operands; return operands;
} }
@ -405,7 +404,7 @@ wstring CopyPasteManager::SanitizeOperand(const wstring& operand)
{ {
wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-' }; wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-' };
return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, ARRAYSIZE(unWantedChars)); return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, static_cast<int>(size(unWantedChars)));
} }
bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, unsigned long long int& result) bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, unsigned long long int& result)
@ -533,7 +532,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end()); suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end());
wstring operandUpper = operand; wstring operandUpper = operand;
transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), toupper); transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper);
// Detect if there is a suffix and subtract its length // Detect if there is a suffix and subtract its length
// Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value). // Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value).
@ -568,3 +567,21 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
return len; return len;
} }
// return wstring after removing characters like space, comma, double quotes, and monetary prefix currency symbols supported by the Windows keyboard:
// yen or yuan(¥) - 165
// unspecified currency sign(¤) - 164
// Ghanaian cedi(₵) - 8373
// dollar or peso($) - 36
// colón(₡) - 8353
// won(₩) - 8361
// shekel(₪) - 8362
// naira(₦) - 8358
// Indian rupee(₹) - 8377
// pound(£) - 163
// euro(€) - 8364
wstring CopyPasteManager::RemoveUnwantedCharsFromWstring(const wstring& input)
{
wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 };
return Utils::RemoveUnwantedCharsFromWstring(input, unWantedChars, 18);
}

View file

@ -58,6 +58,7 @@ namespace CalculatorApp
static size_t OperandLength(std::wstring operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1); static size_t OperandLength(std::wstring operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1);
static size_t StandardScientificOperandLength(std::wstring operand); static size_t StandardScientificOperandLength(std::wstring operand);
static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase); static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase);
static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input);
static constexpr size_t MaxStandardOperandLength = 16; static constexpr size_t MaxStandardOperandLength = 16;
static constexpr size_t MaxScientificOperandLength = 32; static constexpr size_t MaxScientificOperandLength = 32;

View file

@ -12,6 +12,7 @@ using namespace CalculatorApp::Common::DateCalculation;
DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier) DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier)
{ {
m_calendar = ref new Calendar(); m_calendar = ref new Calendar();
m_calendar->ChangeTimeZone("UTC");
m_calendar->ChangeCalendarSystem(calendarIdentifier); m_calendar->ChangeCalendarSystem(calendarIdentifier);
} }

View file

@ -43,7 +43,6 @@ static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyControlS
static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyInverseChordsForButtons; static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyInverseChordsForButtons;
static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyControlInverseChordsForButtons; static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyControlInverseChordsForButtons;
static const TimeSpan c_lightUpTime = { 500000 }; // Quarter of a second
static multimap<int, bool> s_ShiftKeyPressed; static multimap<int, bool> s_ShiftKeyPressed;
static multimap<int, bool> s_ControlKeyPressed; static multimap<int, bool> s_ControlKeyPressed;
static multimap<int, bool> s_ShiftButtonChecked; static multimap<int, bool> s_ShiftButtonChecked;
@ -83,11 +82,13 @@ namespace CalculatorApp
// The button will go into the visual Pressed state with this call // The button will go into the visual Pressed state with this call
VisualStateManager::GoToState(button, "Pressed", true); VisualStateManager::GoToState(button, "Pressed", true);
// This timer will fire after c_lightUpTime and make the button // This timer will fire after lightUpTime and make the button
// go back to the normal state. // go back to the normal state.
// This timer will only fire once after which it will be destroyed // This timer will only fire once after which it will be destroyed
auto timer = ref new DispatcherTimer(); auto timer = ref new DispatcherTimer();
timer->Interval = c_lightUpTime; TimeSpan lightUpTime{};
lightUpTime.Duration = 500000L; // Half second (in 100-ns units)
timer->Interval = lightUpTime;
WeakReference timerWeakReference(timer); WeakReference timerWeakReference(timer);
WeakReference buttonWeakReference(button); WeakReference buttonWeakReference(button);
@ -579,9 +580,9 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto currentControlKeyPressed = s_ControlKeyPressed.find(viewId); auto currControlKeyPressed = s_ControlKeyPressed.find(viewId);
if (currentControlKeyPressed != s_ControlKeyPressed.end()) if (currControlKeyPressed != s_ControlKeyPressed.end())
{ {
s_ControlKeyPressed.erase(viewId); s_ControlKeyPressed.erase(viewId);
s_ControlKeyPressed.insert(std::make_pair(viewId, true)); s_ControlKeyPressed.insert(std::make_pair(viewId, true));
@ -593,9 +594,9 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto currentShiftKeyPressed = s_ShiftKeyPressed.find(viewId); auto currShiftKeyPressed = s_ShiftKeyPressed.find(viewId);
if (currentShiftKeyPressed != s_ShiftKeyPressed.end()) if (currShiftKeyPressed != s_ShiftKeyPressed.end())
{ {
s_ShiftKeyPressed.erase(viewId); s_ShiftKeyPressed.erase(viewId);
s_ShiftKeyPressed.insert(std::make_pair(viewId, true)); s_ShiftKeyPressed.insert(std::make_pair(viewId, true));
@ -636,7 +637,7 @@ void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow^ sender, KeyEventArgs^ a
int viewId = Utils::GetWindowId(); int viewId = Utils::GetWindowId();
auto key = args->VirtualKey; auto key = args->VirtualKey;
if (args->VirtualKey == VirtualKey::Shift) if (key == VirtualKey::Shift)
{ {
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
@ -649,14 +650,14 @@ void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow^ sender, KeyEventArgs^ a
s_ShiftKeyPressed.insert(std::make_pair(viewId, false)); s_ShiftKeyPressed.insert(std::make_pair(viewId, false));
} }
} }
else if (args->VirtualKey == VirtualKey::Control) else if (key == VirtualKey::Control)
{ {
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto currentControlKeyPressed = s_ControlKeyPressed.find(viewId); auto currControlKeyPressed = s_ControlKeyPressed.find(viewId);
if (currentControlKeyPressed != s_ControlKeyPressed.end()) if (currControlKeyPressed != s_ControlKeyPressed.end())
{ {
s_ControlKeyPressed.erase(viewId); s_ControlKeyPressed.erase(viewId);
s_ControlKeyPressed.insert(std::make_pair(viewId, false)); s_ControlKeyPressed.insert(std::make_pair(viewId, false));

View file

@ -4,6 +4,8 @@
#pragma once #pragma once
#include "LocalizationService.h" #include "LocalizationService.h"
#include <iterator>
namespace CalculatorApp namespace CalculatorApp
{ {
namespace Common namespace Common
@ -26,8 +28,9 @@ namespace CalculatorApp
m_digitSymbols.at(i) = formatter->FormatUInt(i)->Data()[0]; m_digitSymbols.at(i) = formatter->FormatUInt(i)->Data()[0];
} }
wchar_t resolvedName[LOCALE_NAME_MAX_LENGTH];
result = ResolveLocaleName(formatter->ResolvedLanguage->Data(), result = ResolveLocaleName(formatter->ResolvedLanguage->Data(),
m_resolvedName, resolvedName,
LOCALE_NAME_MAX_LENGTH); LOCALE_NAME_MAX_LENGTH);
if (result == 0) if (result == 0)
{ {
@ -35,31 +38,32 @@ namespace CalculatorApp
} }
else else
{ {
m_resolvedName = resolvedName;
wchar_t decimalString[LocaleSettingBufferSize] = L""; wchar_t decimalString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_SDECIMAL, LOCALE_SDECIMAL,
decimalString, decimalString,
ARRAYSIZE(decimalString)); static_cast<int>(std::size(decimalString)));
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
} }
wchar_t groupingSymbolString[LocaleSettingBufferSize] = L""; wchar_t groupingSymbolString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_STHOUSAND, LOCALE_STHOUSAND,
groupingSymbolString, groupingSymbolString,
ARRAYSIZE(groupingSymbolString)); static_cast<int>(std::size(groupingSymbolString)));
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
} }
wchar_t numberGroupingString[LocaleSettingBufferSize] = L""; wchar_t numberGroupingString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_SGROUPING, LOCALE_SGROUPING,
numberGroupingString, numberGroupingString,
ARRAYSIZE(numberGroupingString)); static_cast<int>(std::size(numberGroupingString)));
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
@ -70,14 +74,14 @@ namespace CalculatorApp
result = ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, result = ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_SLIST, LOCALE_SLIST,
listSeparatorString, listSeparatorString,
ARRAYSIZE(listSeparatorString)); // Max length of the expected return value is 4 static_cast<int>(std::size(listSeparatorString))); // Max length of the expected return value is 4
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
} }
int currencyTrailingDigits = 0; int currencyTrailingDigits = 0;
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER, LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER,
(LPWSTR)&currencyTrailingDigits, (LPWSTR)&currencyTrailingDigits,
sizeof(currencyTrailingDigits) / sizeof(WCHAR)); sizeof(currencyTrailingDigits) / sizeof(WCHAR));
@ -120,7 +124,7 @@ namespace CalculatorApp
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_IFIRSTDAYOFWEEK, // The first day in a week LOCALE_IFIRSTDAYOFWEEK, // The first day in a week
reinterpret_cast<PWSTR>(day), // Argument is of type PWSTR reinterpret_cast<PWSTR>(day), // Argument is of type PWSTR
ARRAYSIZE(day)); // Max return size are 80 characters static_cast<int>(std::size(day))); // Max return size are 80 characters
// The LOCALE_IFIRSTDAYOFWEEK integer value varies from 0, 1, .. 6 for Monday, Tuesday, ... Sunday // The LOCALE_IFIRSTDAYOFWEEK integer value varies from 0, 1, .. 6 for Monday, Tuesday, ... Sunday
// DayOfWeek enum value varies from 0, 1, .. 6 for Sunday, Monday, ... Saturday // DayOfWeek enum value varies from 0, 1, .. 6 for Sunday, Monday, ... Saturday
@ -147,7 +151,7 @@ namespace CalculatorApp
Platform::String^ GetLocaleName() const Platform::String^ GetLocaleName() const
{ {
return ref new Platform::String(m_resolvedName); return ref new Platform::String(m_resolvedName.c_str());
} }
bool IsDigitEnUsSetting() const bool IsDigitEnUsSetting() const
@ -377,7 +381,7 @@ namespace CalculatorApp
Platform::String^ m_calendarIdentifier; Platform::String^ m_calendarIdentifier;
Windows::Globalization::DayOfWeek m_firstDayOfWeek; Windows::Globalization::DayOfWeek m_firstDayOfWeek;
int m_currencySymbolPrecedence; int m_currencySymbolPrecedence;
wchar_t m_resolvedName[LOCALE_NAME_MAX_LENGTH]; std::wstring m_resolvedName;
int m_currencyTrailingDigits; int m_currencyTrailingDigits;
static const unsigned int LocaleSettingBufferSize = 16; static const unsigned int LocaleSettingBufferSize = 16;
}; };

View file

@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once
#include "pch.h" #include "pch.h"
#include "TraceLogger.h" #include "TraceLogger.h"
#include "NetworkManager.h" #include "NetworkManager.h"
@ -59,7 +57,7 @@ namespace CalculatorApp
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_BEGIN = L"MemoryFlyoutOpenBegin"; constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_BEGIN = L"MemoryFlyoutOpenBegin";
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_END = L"MemoryFlyoutOpenEnd"; constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_END = L"MemoryFlyoutOpenEnd";
constexpr auto EVENT_NAME_MEMORY_CLEAR_ALL = L"MemoryClearAll"; constexpr auto EVENT_NAME_MEMORY_CLEAR_ALL = L"MemoryClearAll";
constexpr auto EVENT_NAME_INVALID_INPUT_PASTED = L"InvalidInputPasted"; constexpr auto EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED = L"InvalidPastedInputOccurred";
constexpr auto EVENT_NAME_VALID_INPUT_PASTED = L"ValidInputPasted"; constexpr auto EVENT_NAME_VALID_INPUT_PASTED = L"ValidInputPasted";
constexpr auto EVENT_NAME_BITFLIP_PANE_CLICKED = L"BitFlipPaneClicked"; constexpr auto EVENT_NAME_BITFLIP_PANE_CLICKED = L"BitFlipPaneClicked";
constexpr auto EVENT_NAME_BITFLIP_BUTTONS_USED = L"BitFlipToggleButtonUsed"; constexpr auto EVENT_NAME_BITFLIP_BUTTONS_USED = L"BitFlipToggleButtonUsed";
@ -81,6 +79,9 @@ namespace CalculatorApp
constexpr auto EVENT_NAME_EXCEPTION = L"Exception"; constexpr auto EVENT_NAME_EXCEPTION = L"Exception";
constexpr auto PDT_PRIVACY_DATA_TAG = L"PartA_PrivTags";
constexpr auto PDT_PRODUCT_AND_SERVICE_USAGE = 0x0000'0000'0200'0000u;
#ifdef SEND_TELEMETRY #ifdef SEND_TELEMETRY
// c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords // c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords
// c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords // c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords
@ -176,7 +177,7 @@ namespace CalculatorApp
{ {
iterMap->second.insert(iterMap->second.begin(), L"Programmer"); iterMap->second.insert(iterMap->second.begin(), L"Programmer");
} }
else else if (isStandard)
{ {
iterMap->second.insert(iterMap->second.begin(), L"Standard"); iterMap->second.insert(iterMap->second.begin(), L"Standard");
} }
@ -199,7 +200,7 @@ namespace CalculatorApp
{ {
iterMap->second[memoryPosition] = L"Programmer"; iterMap->second[memoryPosition] = L"Programmer";
} }
else else if (isStandard)
{ {
iterMap->second[memoryPosition] = L"Standard"; iterMap->second[memoryPosition] = L"Standard";
} }
@ -641,17 +642,17 @@ namespace CalculatorApp
LogTelemetryEvent(EVENT_NAME_SINGLE_MEMORY_USED, fields); LogTelemetryEvent(EVENT_NAME_SINGLE_MEMORY_USED, fields);
} }
void TraceLogger::LogInvalidInputPasted(wstring_view reason, wstring_view pastedExpression, ViewMode mode, int programmerNumberBase, int bitLengthType) void TraceLogger::LogInvalidPastedInputOccurred(wstring_view reason, ViewMode mode, int programmerNumberBase, int bitLengthType)
{ {
if (!GetTraceLoggingProviderEnabled()) return; if (!GetTraceLoggingProviderEnabled()) return;
LoggingFields fields{}; LoggingFields fields{};
fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data()); fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"Reason", reason); fields.AddString(L"Reason", reason);
fields.AddString(L"PastedExpression", pastedExpression);
fields.AddString(L"ProgrammerNumberBase", GetProgrammerType(programmerNumberBase).c_str()); fields.AddString(L"ProgrammerNumberBase", GetProgrammerType(programmerNumberBase).c_str());
fields.AddString(L"BitLengthType", GetProgrammerType(bitLengthType).c_str()); fields.AddString(L"BitLengthType", GetProgrammerType(bitLengthType).c_str());
LogTelemetryEvent(EVENT_NAME_INVALID_INPUT_PASTED, fields); fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogTelemetryEvent(EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED, fields);
} }
void TraceLogger::LogValidInputPasted(ViewMode mode) const void TraceLogger::LogValidInputPasted(ViewMode mode) const
@ -872,6 +873,7 @@ namespace CalculatorApp
if (!m_dateDiffUsageLoggedInSession) if (!m_dateDiffUsageLoggedInSession)
{ {
LoggingFields fields{}; LoggingFields fields{};
fields.AddUInt32(L"WindowId", windowId);
LogTelemetryEvent(EVENT_NAME_DATE_DIFFERENCE_USED, fields); LogTelemetryEvent(EVENT_NAME_DATE_DIFFERENCE_USED, fields);
m_dateDiffUsageLoggedInSession = true; m_dateDiffUsageLoggedInSession = true;

View file

@ -64,7 +64,7 @@ namespace CalculatorApp
void LogMemoryFlyoutOpenBegin(unsigned int) const; void LogMemoryFlyoutOpenBegin(unsigned int) const;
void LogDebug(std::wstring_view debugData); void LogDebug(std::wstring_view debugData);
void LogMemoryFlyoutOpenEnd(unsigned int) const; void LogMemoryFlyoutOpenEnd(unsigned int) const;
void LogInvalidInputPasted(std::wstring_view reason, std::wstring_view pastedExpression, CalculatorApp::Common::ViewMode mode, int ProgrammerNumberBase, int bitLengthType); void LogInvalidPastedInputOccurred(std::wstring_view reason, CalculatorApp::Common::ViewMode mode, int ProgrammerNumberBase, int bitLengthType);
void LogValidInputPasted(CalculatorApp::Common::ViewMode mode) const; void LogValidInputPasted(CalculatorApp::Common::ViewMode mode) const;
void UpdateFunctionUsage(int func); void UpdateFunctionUsage(int func);
void LogFunctionUsage(int); void LogFunctionUsage(int);

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// //
@ -54,7 +54,7 @@ double Utils::GetDoubleFromWstring(wstring input)
return ::atof(inputString.c_str()); return ::atof(inputString.c_str());
} }
//returns windowId for the current view // Returns windowId for the current view
int Utils::GetWindowId() int Utils::GetWindowId()
{ {
int windowId = -1; int windowId = -1;
@ -80,20 +80,13 @@ void Utils::RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Core
} }
} }
// returns if the last character of a wstring is the target wchar_t // Returns if the last character of a wstring is the target wchar_t
bool Utils::IsLastCharacterTarget(_In_ wstring const &input, _In_ wchar_t target) bool Utils::IsLastCharacterTarget(_In_ wstring const &input, _In_ wchar_t target)
{ {
return !input.empty() && input.back() == target; return !input.empty() && input.back() == target;
} }
//return wstring after removing characters like space, comma, and double quotes // Return wstring after removing characters specified by unwantedChars array
wstring Utils::RemoveUnwantedCharsFromWstring(wstring input)
{
wchar_t unWantedChars[] = { L' ', L',', L'"', 8234, 8235, 8236, 8237 };
return RemoveUnwantedCharsFromWstring(input, unWantedChars, 6);
}
//return wstring after removing characters specified by unwantedChars array
wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedChars, unsigned int size) wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedChars, unsigned int size)
{ {
for (unsigned int i = 0; i < size; ++i) for (unsigned int i = 0; i < size; ++i)
@ -110,7 +103,7 @@ void Utils::SerializeCommandsAndTokens(_In_ shared_ptr<CalculatorVector <pair<ws
unsigned int commandsSize; unsigned int commandsSize;
IFTPlatformException(commands->GetSize(&commandsSize)); IFTPlatformException(commands->GetSize(&commandsSize));
// save the size of the commands vector // Save the size of the commands vector
writer->WriteUInt32(commandsSize); writer->WriteUInt32(commandsSize);
SerializeCommandVisitor cmdVisitor(writer); SerializeCommandVisitor cmdVisitor(writer);

View file

@ -42,10 +42,16 @@
}\ }\
} private: t m_##n; public: } private: t m_##n; public:
#define NAMED_OBSERVABLE_PROPERTY_RW(t, n)\ #define OBSERVABLE_NAMED_PROPERTY_R(t, n)\
OBSERVABLE_PROPERTY_R(t, n)\
internal: static property Platform::String^ n##PropertyName {\
Platform::String^ get() { return Platform::StringReference(L#n); }\
} public:
#define OBSERVABLE_NAMED_PROPERTY_RW(t, n)\
OBSERVABLE_PROPERTY_RW(t, n)\ OBSERVABLE_PROPERTY_RW(t, n)\
private: property Platform::StringReference n##_PropertyName {\ internal: static property Platform::String^ n##PropertyName {\
Platform::StringReference get() { return Platform::StringReference(L#n); }\ Platform::String^ get() { return Platform::StringReference(L#n); }\
} public: } public:
#define OBSERVABLE_PROPERTY_FIELD(n) m_##n #define OBSERVABLE_PROPERTY_FIELD(n) m_##n
@ -280,7 +286,6 @@ namespace Utils
Platform::String^ GetStringValue(Platform::String^ input); Platform::String^ GetStringValue(Platform::String^ input);
bool IsLastCharacterTarget(std::wstring const &input, wchar_t target); bool IsLastCharacterTarget(std::wstring const &input, wchar_t target);
std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size); std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size);
std::wstring RemoveUnwantedCharsFromWstring(std::wstring input);
double GetDoubleFromWstring(std::wstring input); double GetDoubleFromWstring(std::wstring input);
int GetWindowId(); int GetWindowId();
void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher^ currentDispatcher); void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher^ currentDispatcher);

View file

@ -275,7 +275,7 @@ pair<wstring, wstring> CurrencyDataLoader::GetCurrencyRatioEquality(_In_ const U
{ {
double ratio = (iter2->second).ratio; double ratio = (iter2->second).ratio;
// Round the raio to FORMATTER_DIGIT_COUNT digits using int math. // Round the ratio to FORMATTER_DIGIT_COUNT digits using int math.
// Ex: to round 1.23456 to three digits, use // Ex: to round 1.23456 to three digits, use
// ((int) 1.23456 * (10^3)) / (10^3) // ((int) 1.23456 * (10^3)) / (10^3)
double scale = pow(10, FORMATTER_DIGIT_COUNT); double scale = pow(10, FORMATTER_DIGIT_COUNT);

View file

@ -22,14 +22,14 @@ using namespace Windows::Globalization;
using namespace Windows::Globalization::DateTimeFormatting; using namespace Windows::Globalization::DateTimeFormatting;
using namespace Windows::System::UserProfile; using namespace Windows::System::UserProfile;
namespace CalculatorApp::ViewModel::DateCalculatorViewModelProperties namespace
{ {
StringReference StrDateDiffResult(L"StrDateDiffResult"); StringReference StrDateDiffResultPropertyName(L"StrDateDiffResult");
StringReference StrDateDiffResultAutomationName(L"StrDateDiffResultAutomationName"); StringReference StrDateDiffResultAutomationNamePropertyName(L"StrDateDiffResultAutomationName");
StringReference StrDateDiffResultInDays(L"StrDateDiffResultInDays"); StringReference StrDateDiffResultInDaysPropertyName(L"StrDateDiffResultInDays");
StringReference StrDateResult(L"StrDateResult"); StringReference StrDateResultPropertyName(L"StrDateResult");
StringReference StrDateResultAutomationName(L"StrDateResultAutomationName"); StringReference StrDateResultAutomationNamePropertyName(L"StrDateResultAutomationName");
StringReference IsDiffInDays(L"IsDiffInDays"); StringReference IsDiffInDaysPropertyName(L"IsDiffInDays");
} }
DateCalculatorViewModel::DateCalculatorViewModel() : DateCalculatorViewModel::DateCalculatorViewModel() :
@ -43,11 +43,7 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
m_StrDateDiffResultAutomationName(L""), m_StrDateDiffResultAutomationName(L""),
m_StrDateDiffResultInDays(L""), m_StrDateDiffResultInDays(L""),
m_StrDateResult(L""), m_StrDateResult(L""),
m_StrDateResultAutomationName(L""), m_StrDateResultAutomationName(L"")
m_fromDate({ 0 }),
m_toDate({ 0 }),
m_startDate({ 0 }),
m_dateResult({ 0 })
{ {
const auto& localizationSettings = LocalizationSettings::GetInstance(); const auto& localizationSettings = LocalizationSettings::GetInstance();
@ -56,24 +52,24 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
// Initialize Date Calc engine // Initialize Date Calc engine
m_dateCalcEngine = make_shared<DateCalculationEngine>(localizationSettings.GetCalendarIdentifier()); m_dateCalcEngine = make_shared<DateCalculationEngine>(localizationSettings.GetCalendarIdentifier());
// Initialize dates of DatePicker controls to today's date // Initialize dates of DatePicker controls to today's date
auto calendar = ref new Calendar(); auto calendar = ref new Calendar();
// We force the timezone to UTC, in order to avoid being affected by Daylight Saving Time
// when we calculate the difference between 2 dates.
calendar->ChangeTimeZone("UTC");
auto today = calendar->GetDateTime(); auto today = calendar->GetDateTime();
// FromDate and ToDate should be clipped (adjusted to a consistent hour in UTC) // FromDate and ToDate should be clipped (adjusted to a consistent hour in UTC)
m_fromDate = today; m_fromDate = ClipTime(today);
m_toDate = today; m_toDate = ClipTime(today);
FromDate = ClipTime(today);
ToDate = ClipTime(today);
// StartDate should not be clipped // StartDate should not be clipped
StartDate = today; m_startDate = today;
m_dateResult = today; m_dateResult = today;
// Initialize the list separator delimiter appended with a space at the end, e.g. ", " // Initialize the list separator delimiter appended with a space at the end, e.g. ", "
// This will be used for date difference formatting: Y years, M months, W weeks, D days // This will be used for date difference formatting: Y years, M months, W weeks, D days
m_listSeparator = ref new String((localizationSettings.GetListSeparator() + L" ").c_str()); m_listSeparator = localizationSettings.GetListSeparator() + L" ";
// Initialize the output results // Initialize the output results
UpdateDisplayResult(); UpdateDisplayResult();
@ -86,15 +82,6 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
m_offsetValues->Append(ref new String(numberStr.c_str())); m_offsetValues->Append(ref new String(numberStr.c_str()));
} }
/* In the ClipTime function, we used to change timezone to UTC before clipping the time.
The comment from the previous developers said this was done to eliminate the effects of
Daylight Savings Time. We can't think of a good reason why this change in timezone is
necessary and did find bugs related to the change, therefore, we have removed the
change. Just in case, we will see if the clipped time is ever a different day from the
original day, which would hopefully indicate the change in timezone was actually
necessary. We will collect telemetry if we find this case. If we don't see any
telemetry events after the application has been used for some time, we will feel safe
and can remove this function. */
DayOfWeek trueDayOfWeek = calendar->DayOfWeek; DayOfWeek trueDayOfWeek = calendar->DayOfWeek;
DateTime clippedTime = ClipTime(today); DateTime clippedTime = ClipTime(today);
@ -110,18 +97,18 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
void DateCalculatorViewModel::OnPropertyChanged(_In_ String^ prop) void DateCalculatorViewModel::OnPropertyChanged(_In_ String^ prop)
{ {
if (prop == DateCalculatorViewModelProperties::StrDateDiffResult) if (prop == StrDateDiffResultPropertyName)
{ {
UpdateStrDateDiffResultAutomationName(); UpdateStrDateDiffResultAutomationName();
} }
else if (prop == DateCalculatorViewModelProperties::StrDateResult) else if (prop == StrDateResultPropertyName)
{ {
UpdateStrDateResultAutomationName(); UpdateStrDateResultAutomationName();
} }
else if (prop != DateCalculatorViewModelProperties::StrDateDiffResultAutomationName else if (prop != StrDateDiffResultAutomationNamePropertyName
&& prop != DateCalculatorViewModelProperties::StrDateDiffResultInDays && prop != StrDateDiffResultInDaysPropertyName
&& prop != DateCalculatorViewModelProperties::StrDateResultAutomationName && prop != StrDateResultAutomationNamePropertyName
&& prop != DateCalculatorViewModelProperties::IsDiffInDays) && prop != IsDiffInDaysPropertyName)
{ {
OnInputsChanged(); OnInputsChanged();
} }
@ -245,22 +232,23 @@ void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String^ calendarI
String^ DateCalculatorViewModel::GetDateDiffString() const String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
String^ result = L""; wstring result;
bool addDelimiter = false; bool addDelimiter = false;
AppResourceProvider resourceLoader = AppResourceProvider::GetInstance(); AppResourceProvider resourceLoader = AppResourceProvider::GetInstance();
auto yearCount = m_dateDiffResult.year; auto yearCount = m_dateDiffResult.year;
if (yearCount > 0) if (yearCount > 0)
{ {
result = String::Concat(GetLocalizedNumberString(yearCount), L" "); result += GetLocalizedNumberString(yearCount)->Data();
result += L" ";
if (yearCount > 1) if (yearCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Years")); result += resourceLoader.GetResourceString(L"Date_Years")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Year")); result += resourceLoader.GetResourceString(L"Date_Year")->Data();
} }
// set the flags to add a delimiter whenever the next unit is added // set the flags to add a delimiter whenever the next unit is added
@ -272,22 +260,23 @@ String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
if (addDelimiter) if (addDelimiter)
{ {
result = String::Concat(result, m_listSeparator); result += m_listSeparator;
} }
else else
{ {
addDelimiter = true; addDelimiter = true;
} }
result = String::Concat(result, String::Concat(GetLocalizedNumberString(monthCount), L" ")); result += GetLocalizedNumberString(monthCount)->Data();
result += L" ";
if (monthCount > 1) if (monthCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Months")); result += resourceLoader.GetResourceString(L"Date_Months")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Month")); result += resourceLoader.GetResourceString(L"Date_Month")->Data();
} }
} }
@ -296,22 +285,23 @@ String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
if (addDelimiter) if (addDelimiter)
{ {
result = String::Concat(result, m_listSeparator); result += m_listSeparator;
} }
else else
{ {
addDelimiter = true; addDelimiter = true;
} }
result = String::Concat(result, String::Concat(GetLocalizedNumberString(weekCount), L" ")); result += GetLocalizedNumberString(weekCount)->Data();
result += L" ";
if (weekCount > 1) if (weekCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Weeks")); result += resourceLoader.GetResourceString(L"Date_Weeks")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Week")); result += resourceLoader.GetResourceString(L"Date_Week")->Data();
} }
} }
@ -320,43 +310,45 @@ String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
if (addDelimiter) if (addDelimiter)
{ {
result = String::Concat(result, m_listSeparator); result += m_listSeparator;
} }
else else
{ {
addDelimiter = true; addDelimiter = true;
} }
result = String::Concat(result, String::Concat(GetLocalizedNumberString(dayCount), L" ")); result += GetLocalizedNumberString(dayCount)->Data();
result += L" ";
if (dayCount > 1) if (dayCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Days")); result += resourceLoader.GetResourceString(L"Date_Days")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Day")); result += resourceLoader.GetResourceString(L"Date_Day")->Data();
} }
} }
return result; return ref new String(result.data());
} }
String^ DateCalculatorViewModel::GetDateDiffStringInDays() const String^ DateCalculatorViewModel::GetDateDiffStringInDays() const
{ {
String^ strDateUnit; wstring result = GetLocalizedNumberString(m_dateDiffResultInDays.day)->Data();
result += L" ";
// Display the result as '1 day' or 'N days' // Display the result as '1 day' or 'N days'
if (m_dateDiffResultInDays.day > 1) if (m_dateDiffResultInDays.day > 1)
{ {
strDateUnit = AppResourceProvider::GetInstance().GetResourceString(L"Date_Days"); result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Days")->Data();
} }
else else
{ {
strDateUnit = AppResourceProvider::GetInstance().GetResourceString(L"Date_Day"); result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Day")->Data();
} }
return String::Concat(GetLocalizedNumberString(m_dateDiffResultInDays.day), String::Concat(L" ", strDateUnit)); return ref new String(result.data());
} }
void DateCalculatorViewModel::OnCopyCommand(Platform::Object^ parameter) void DateCalculatorViewModel::OnCopyCommand(Platform::Object^ parameter)
@ -378,13 +370,14 @@ String^ DateCalculatorViewModel::GetLocalizedNumberString(int value) const
return ref new String(numberStr.c_str()); return ref new String(numberStr.c_str());
} }
// Adjusts the given DateTime to 12AM of the same day // Adjusts the given DateTime to 12AM (UTC) of the same day
DateTime DateCalculatorViewModel::ClipTime(DateTime dateTime) DateTime DateCalculatorViewModel::ClipTime(DateTime dateTime)
{ {
auto calendar = ref new Calendar(); auto calendar = ref new Calendar();
calendar->ChangeTimeZone("UTC");
calendar->SetDateTime(dateTime); calendar->SetDateTime(dateTime);
calendar->Period = 1; calendar->Period = calendar->FirstPeriodInThisDay;
calendar->Hour = 12; calendar->Hour = calendar->FirstHourInThisPeriod;
calendar->Minute = 0; calendar->Minute = 0;
calendar->Second = 0; calendar->Second = 0;
calendar->Nanosecond = 0; calendar->Nanosecond = 0;

View file

@ -23,7 +23,7 @@ namespace CalculatorApp
// Input Properties // Input Properties
OBSERVABLE_PROPERTY_RW(bool, IsDateDiffMode); OBSERVABLE_PROPERTY_RW(bool, IsDateDiffMode);
OBSERVABLE_PROPERTY_RW(bool, IsAddMode); OBSERVABLE_PROPERTY_RW(bool, IsAddMode);
OBSERVABLE_PROPERTY_RW(bool, IsDiffInDays); // If diff is only in days or the dates are the same, OBSERVABLE_PROPERTY_R(bool, IsDiffInDays); // If diff is only in days or the dates are the same,
// then show only one result and avoid redundancy // then show only one result and avoid redundancy
OBSERVABLE_PROPERTY_RW(int, DaysOffset); OBSERVABLE_PROPERTY_RW(int, DaysOffset);
@ -82,11 +82,11 @@ namespace CalculatorApp
} }
// Output Properties // Output Properties
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResult); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResult);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResultAutomationName); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResultAutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResultInDays); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResultInDays);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateResult); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateResult);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateResultAutomationName); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateResultAutomationName);
COMMAND_FOR_METHOD(CopyCommand, DateCalculatorViewModel::OnCopyCommand); COMMAND_FOR_METHOD(CopyCommand, DateCalculatorViewModel::OnCopyCommand);
@ -104,8 +104,6 @@ namespace CalculatorApp
Platform::String^ GetLocalizedNumberString(int value) const; Platform::String^ GetLocalizedNumberString(int value) const;
static Windows::Foundation::DateTime ClipTime(Windows::Foundation::DateTime dateTime); static Windows::Foundation::DateTime ClipTime(Windows::Foundation::DateTime dateTime);
static void CheckClipTimeSameDay(Windows::Globalization::Calendar^ reference);
property bool IsOutOfBound property bool IsOutOfBound
{ {
bool get() { return m_isOutOfBound; } bool get() { return m_isOutOfBound; }
@ -146,7 +144,7 @@ namespace CalculatorApp
CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat;
CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter^ m_dateTimeFormatter; Windows::Globalization::DateTimeFormatting::DateTimeFormatter^ m_dateTimeFormatter;
Platform::String^ m_listSeparator; std::wstring m_listSeparator;
}; };
} }
} }

View file

@ -291,7 +291,6 @@ void HistoryViewModel::SaveHistory()
// this serializes a history item into a base64 encoded string // this serializes a history item into a base64 encoded string
Platform::String^ HistoryViewModel::SerializeHistoryItem(_In_ std::shared_ptr<CalculationManager::HISTORYITEM> const &item) Platform::String^ HistoryViewModel::SerializeHistoryItem(_In_ std::shared_ptr<CalculationManager::HISTORYITEM> const &item)
{ {
HRESULT hr = S_OK;
DataWriter^ writer = ref new DataWriter(); DataWriter^ writer = ref new DataWriter();
auto expr = item->historyItemVector.expression; auto expr = item->historyItemVector.expression;
auto result = item->historyItemVector.result; auto result = item->historyItemVector.result;

View file

@ -30,17 +30,13 @@ constexpr int StandardModePrecision = 16;
constexpr int ScientificModePrecision = 32; constexpr int ScientificModePrecision = 32;
constexpr int ProgrammerModePrecision = 64; constexpr int ProgrammerModePrecision = 64;
namespace CalculatorApp::ViewModel namespace
{ {
namespace CalculatorViewModelProperties StringReference IsStandardPropertyName(L"IsStandard");
{ StringReference IsScientificPropertyName(L"IsScientific");
StringReference IsMemoryEmpty(L"IsMemoryEmpty"); StringReference IsProgrammerPropertyName(L"IsProgrammer");
StringReference IsScientific(L"IsScientific"); StringReference DisplayValuePropertyName(L"DisplayValue");
StringReference IsStandard(L"IsStandard"); StringReference CalculationResultAutomationNamePropertyName(L"CalculationResultAutomationName");
StringReference IsProgrammer(L"IsProgrammer");
StringReference DisplayValue(L"DisplayValue");
StringReference IsInError(L"IsInError");
StringReference BinaryDisplayValue(L"BinaryDisplayValue");
} }
namespace CalculatorResourceKeys namespace CalculatorResourceKeys
@ -53,6 +49,8 @@ namespace CalculatorApp::ViewModel
StringReference OctButton(L"Format_OctButtonValue"); StringReference OctButton(L"Format_OctButtonValue");
StringReference BinButton(L"Format_BinButtonValue"); StringReference BinButton(L"Format_BinButtonValue");
StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix"); StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix");
StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix");
StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement");
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback"); StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback");
StringReference MemorySave(L"Format_MemorySave"); StringReference MemorySave(L"Format_MemorySave");
@ -61,7 +59,6 @@ namespace CalculatorApp::ViewModel
StringReference MemoryCleared(L"Memory_Cleared"); StringReference MemoryCleared(L"Memory_Cleared");
StringReference DisplayCopied(L"Display_Copied"); StringReference DisplayCopied(L"Display_Copied");
} }
}
StandardCalculatorViewModel::StandardCalculatorViewModel() : StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_DisplayValue(L"0"), m_DisplayValue(L"0"),
@ -93,7 +90,9 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_localizedMemorySavedAutomationFormat(nullptr), m_localizedMemorySavedAutomationFormat(nullptr),
m_localizedMemoryItemChangedAutomationFormat(nullptr), m_localizedMemoryItemChangedAutomationFormat(nullptr),
m_localizedMemoryItemClearedAutomationFormat(nullptr), m_localizedMemoryItemClearedAutomationFormat(nullptr),
m_localizedMemoryCleared(nullptr) m_localizedMemoryCleared(nullptr),
m_localizedOpenParenthesisCountChangedAutomationFormat(nullptr),
m_localizedNoRightParenthesisAddedFormat(nullptr)
{ {
WeakReference calculatorViewModel(this); WeakReference calculatorViewModel(this);
m_calculatorDisplay.SetCallback(calculatorViewModel); m_calculatorDisplay.SetCallback(calculatorViewModel);
@ -179,7 +178,6 @@ String^ StandardCalculatorViewModel::CalculateNarratorDisplayValue(_In_ wstring
String^ StandardCalculatorViewModel::GetNarratorStringReadRawNumbers(_In_ String^ localizedDisplayValue) String^ StandardCalculatorViewModel::GetNarratorStringReadRawNumbers(_In_ String^ localizedDisplayValue)
{ {
wstringstream wss; wstringstream wss;
RADIX_TYPE radix = static_cast<RADIX_TYPE>(CurrentRadixType);
auto& locSettings = LocalizationSettings::GetInstance(); auto& locSettings = LocalizationSettings::GetInstance();
// Insert a space after each digit in the string, to force Narrator to read them as separate numbers. // Insert a space after each digit in the string, to force Narrator to read them as separate numbers.
@ -228,6 +226,34 @@ void StandardCalculatorViewModel::SetParenthesisCount(_In_ const wstring& parent
} }
} }
void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement()
{
String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount);
wstring localizedParenthesisCount = parenthesisCount->Data();
LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
CalculatorResourceKeys::OpenParenthesisCountAutomationFormat,
m_localizedOpenParenthesisCountChangedAutomationFormat,
localizedParenthesisCount.c_str());
Announcement = CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(announcement);
}
void StandardCalculatorViewModel::OnNoRightParenAdded()
{
SetNoParenAddedNarratorAnnouncement();
}
void StandardCalculatorViewModel::SetNoParenAddedNarratorAnnouncement()
{
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
CalculatorResourceKeys::NoParenthesisAdded,
m_localizedNoRightParenthesisAddedFormat);
Announcement = CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(announcement);
}
void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType) void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType)
{ {
if (selectedExpressionCommandType == CommandType::OperandCommand) if (selectedExpressionCommandType == CommandType::OperandCommand)
@ -437,50 +463,50 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
displayExpressionToken->CommandIndex = 0; displayExpressionToken->CommandIndex = 0;
} }
wchar_t ch; wchar_t ch = 0;
if ((cmdenum >= Command::Command0) && (cmdenum <= Command::Command9)) if ((cmdenum >= Command::Command0) && (cmdenum <= Command::Command9))
{ {
switch (cmdenum) switch (cmdenum)
{ {
case Command::Command0: case Command::Command0:
ch = '0'; ch = L'0';
break; break;
case Command::Command1: case Command::Command1:
ch = '1'; ch = L'1';
break; break;
case Command::Command2: case Command::Command2:
ch = '2'; ch = L'2';
break; break;
case Command::Command3: case Command::Command3:
ch = '3'; ch = L'3';
break; break;
case Command::Command4: case Command::Command4:
ch = '4'; ch = L'4';
break; break;
case Command::Command5: case Command::Command5:
ch = '5'; ch = L'5';
break; break;
case Command::Command6: case Command::Command6:
ch = '6'; ch = L'6';
break; break;
case Command::Command7: case Command::Command7:
ch = '7'; ch = L'7';
break; break;
case Command::Command8: case Command::Command8:
ch = '8'; ch = L'8';
break; break;
case Command::Command9: case Command::Command9:
ch = '9'; ch = L'9';
break; break;
} }
} }
else if (cmdenum == Command::CommandPNT) else if (cmdenum == Command::CommandPNT)
{ {
ch = '.'; ch = L'.';
} }
else if (cmdenum == Command::CommandBACK) else if (cmdenum == Command::CommandBACK)
{ {
ch = 'x'; ch = L'x';
} }
else else
{ {
@ -497,7 +523,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
{ {
// Clear older text; // Clear older text;
m_selectedExpressionLastData = L""; m_selectedExpressionLastData = L"";
if (ch == 'x') if (ch == L'x')
{ {
temp[0] = L'\0'; temp[0] = L'\0';
commandIndex = 0; commandIndex = 0;
@ -512,7 +538,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
} }
else else
{ {
if (ch == 'x') if (ch == L'x')
{ {
if (commandIndex == 0) if (commandIndex == 0)
{ {
@ -529,7 +555,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
} }
temp[i++] = data[j]; temp[i++] = data[j];
} }
temp[i] = '\0'; temp[i] = L'\0';
commandIndex -= 1; commandIndex -= 1;
} }
else else
@ -537,6 +563,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
length = m_selectedExpressionLastData->Length() + 1; length = m_selectedExpressionLastData->Length() + 1;
if (length > 50) if (length > 50)
{ {
delete [] temp;
return; return;
} }
for (; i < length; ++i) for (; i < length; ++i)
@ -548,7 +575,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
} }
temp[i] = data[j++]; temp[i] = data[j++];
} }
temp[i] = '\0'; temp[i] = L'\0';
commandIndex += 1; commandIndex += 1;
} }
} }
@ -562,8 +589,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
bool StandardCalculatorViewModel::IsOperator(Command cmdenum) bool StandardCalculatorViewModel::IsOperator(Command cmdenum)
{ {
if ((cmdenum == Command::Command0) || (cmdenum == Command::Command1) || (cmdenum == Command::Command2) || (cmdenum == Command::Command3) || (cmdenum == Command::Command4) || (cmdenum == Command::Command5) if ((cmdenum >= Command::Command0 && cmdenum <= Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK)
|| (cmdenum == Command::Command6) || (cmdenum == Command::Command7) || (cmdenum == Command::Command8) || (cmdenum == Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK)
|| (cmdenum == Command::CommandEXP) || (cmdenum == Command::CommandFE) || (cmdenum == Command::CommandAE) || (cmdenum == Command::ModeBasic) || (cmdenum == Command::ModeProgrammer) || (cmdenum == Command::ModeScientific) || (cmdenum == Command::CommandEXP) || (cmdenum == Command::CommandFE) || (cmdenum == Command::CommandAE) || (cmdenum == Command::ModeBasic) || (cmdenum == Command::ModeProgrammer) || (cmdenum == Command::ModeScientific)
|| (cmdenum == Command::CommandINV) || (cmdenum == Command::CommandCENTR) || (cmdenum == Command::CommandDEG) || (cmdenum == Command::CommandRAD) || (cmdenum == Command::CommandGRAD) || (cmdenum == Command::CommandINV) || (cmdenum == Command::CommandCENTR) || (cmdenum == Command::CommandDEG) || (cmdenum == Command::CommandRAD) || (cmdenum == Command::CommandGRAD)
|| ((cmdenum >= Command::CommandBINEDITSTART) && (cmdenum <= Command::CommandBINEDITEND))) || ((cmdenum >= Command::CommandBINEDITSTART) && (cmdenum <= Command::CommandBINEDITEND)))
@ -588,7 +614,6 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter)
m_feedbackForButtonPress = CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParameter(parameter); m_feedbackForButtonPress = CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParameter(parameter);
NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter); NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter);
Command cmdenum = ConvertToOperatorsEnum(numOpEnum); Command cmdenum = ConvertToOperatorsEnum(numOpEnum);
bool isOperator = IsOperator(cmdenum);
TraceLogger::GetInstance().UpdateFunctionUsage((int)numOpEnum); TraceLogger::GetInstance().UpdateFunctionUsage((int)numOpEnum);
@ -659,8 +684,7 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter)
{ {
m_CurrentAngleType = numOpEnum; m_CurrentAngleType = numOpEnum;
} }
if ((cmdenum == Command::Command0) || (cmdenum == Command::Command1) || (cmdenum == Command::Command2) || (cmdenum == Command::Command3) || (cmdenum == Command::Command4) || (cmdenum == Command::Command5) if ((cmdenum >= Command::Command0 && cmdenum <= Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK) || (cmdenum == Command::CommandEXP))
|| (cmdenum == Command::Command6) || (cmdenum == Command::Command7) || (cmdenum == Command::Command8) || (cmdenum == Command::Command9) || (cmdenum == Command::CommandPNT) || (cmdenum == Command::CommandBACK) || (cmdenum == Command::CommandEXP))
{ {
IsOperatorCommand = false; IsOperatorCommand = false;
} }
@ -782,7 +806,6 @@ void StandardCalculatorViewModel::OnPaste(String^ pastedString, ViewMode mode)
bool isFirstLegalChar = true; bool isFirstLegalChar = true;
m_standardCalculatorManager.SendCommand(Command::CommandCENTR); m_standardCalculatorManager.SendCommand(Command::CommandCENTR);
bool sendNegate = false; bool sendNegate = false;
bool processedExp = false;
bool processedDigit = false; bool processedDigit = false;
bool sentEquals = false; bool sentEquals = false;
bool isPreviousOperator = false; bool isPreviousOperator = false;
@ -1281,30 +1304,30 @@ void StandardCalculatorViewModel::Deserialize(Array<unsigned char>^ state)
void StandardCalculatorViewModel::OnPropertyChanged(String^ propertyname) void StandardCalculatorViewModel::OnPropertyChanged(String^ propertyname)
{ {
if (propertyname == CalculatorViewModelProperties::IsScientific) if (propertyname == IsScientificPropertyName)
{ {
if (IsScientific) if (IsScientific)
{ {
OnButtonPressed(NumbersAndOperatorsEnum::IsScientificMode); OnButtonPressed(NumbersAndOperatorsEnum::IsScientificMode);
} }
} }
else if (propertyname == CalculatorViewModelProperties::IsProgrammer) else if (propertyname == IsProgrammerPropertyName)
{ {
if (IsProgrammer) if (IsProgrammer)
{ {
OnButtonPressed(NumbersAndOperatorsEnum::IsProgrammerMode); OnButtonPressed(NumbersAndOperatorsEnum::IsProgrammerMode);
} }
} }
else if (propertyname == CalculatorViewModelProperties::IsStandard) else if (propertyname == IsStandardPropertyName)
{ {
if (IsStandard) if (IsStandard)
{ {
OnButtonPressed(NumbersAndOperatorsEnum::IsStandardMode); OnButtonPressed(NumbersAndOperatorsEnum::IsStandardMode);
} }
} }
else if (propertyname == CalculatorViewModelProperties::DisplayValue) else if (propertyname == DisplayValuePropertyName)
{ {
RaisePropertyChanged(CalculationResultAutomationName_PropertyName); RaisePropertyChanged(CalculationResultAutomationNamePropertyName);
Announcement = GetDisplayUpdatedNarratorAnnouncement(); Announcement = GetDisplayUpdatedNarratorAnnouncement();
} }
} }
@ -1407,7 +1430,6 @@ ANGLE_TYPE GetAngleTypeFromCommand(Command command)
void StandardCalculatorViewModel::SaveEditedCommand(_In_ unsigned int tokenPosition, _In_ Command command) void StandardCalculatorViewModel::SaveEditedCommand(_In_ unsigned int tokenPosition, _In_ Command command)
{ {
pair<wstring, int> token; pair<wstring, int> token;
bool fNegative = false;
bool handleOperand = false; bool handleOperand = false;
int nOpCode = static_cast<int>(command); int nOpCode = static_cast<int>(command);
wstring updatedToken = L""; wstring updatedToken = L"";
@ -1658,7 +1680,7 @@ bool StandardCalculatorViewModel::IsOpnd(int nOpCode)
Command::CommandPNT Command::CommandPNT
}; };
for (int i = 0; i < ARRAYSIZE(opnd); i++) for (unsigned int i = 0; i < size(opnd); i++)
{ {
if (nOpCode == static_cast<int>(opnd[i])) if (nOpCode == static_cast<int>(opnd[i]))
{ {
@ -1689,7 +1711,7 @@ bool StandardCalculatorViewModel::IsUnaryOp(int nOpCode)
Command::CommandCUB Command::CommandCUB
}; };
for (int i = 0; i < ARRAYSIZE(unaryOp); i++) for (unsigned int i = 0; i < size(unaryOp); i++)
{ {
if (nOpCode == static_cast<int>(unaryOp[i])) if (nOpCode == static_cast<int>(unaryOp[i]))
{ {
@ -1716,7 +1738,7 @@ bool StandardCalculatorViewModel::IsTrigOp(int nOpCode)
Command::CommandATAN Command::CommandATAN
}; };
for (int i = 0; i < ARRAYSIZE(trigOp); i++) for (unsigned int i = 0; i < size(trigOp); i++)
{ {
if (nOpCode == static_cast<int>(trigOp[i])) if (nOpCode == static_cast<int>(trigOp[i]))
{ {
@ -1739,7 +1761,7 @@ bool StandardCalculatorViewModel::IsBinOp(int nOpCode)
Command::CommandPWR Command::CommandPWR
}; };
for (int i = 0; i < ARRAYSIZE(binOp); i++) for (unsigned int i = 0; i < size(binOp); i++)
{ {
if (nOpCode == static_cast<int>(binOp[i])) if (nOpCode == static_cast<int>(binOp[i]))
{ {
@ -1773,7 +1795,7 @@ bool StandardCalculatorViewModel::IsRecoverableCommand(int nOpCode)
Command::CommandF Command::CommandF
}; };
for (int i = 0; i < ARRAYSIZE(recoverableCommands); i++) for (unsigned int i = 0; i < size(recoverableCommands); i++)
{ {
if (nOpCode == static_cast<int>(recoverableCommands[i])) if (nOpCode == static_cast<int>(recoverableCommands[i]))
{ {
@ -1991,7 +2013,7 @@ void StandardCalculatorViewModel::UpdatecommandsInRecordingMode()
} }
else else
{ {
//reset all vars // Reset all vars
isDecimal = false; isDecimal = false;
isNegative = false; isNegative = false;
isExpMode = false; isExpMode = false;

View file

@ -31,12 +31,6 @@ namespace CalculatorApp
#define ASCII_0 48 #define ASCII_0 48
public delegate void HideMemoryClickedHandler(); public delegate void HideMemoryClickedHandler();
public delegate void ProgModeRadixChangeHandler(); public delegate void ProgModeRadixChangeHandler();
namespace CalculatorViewModelProperties
{
extern Platform::StringReference IsMemoryEmpty;
extern Platform::StringReference IsInError;
extern Platform::StringReference BinaryDisplayValue;
}
[Windows::UI::Xaml::Data::Bindable] [Windows::UI::Xaml::Data::Bindable]
public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
@ -51,14 +45,14 @@ namespace CalculatorApp
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged); OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayValue);
OBSERVABLE_PROPERTY_RW(HistoryViewModel^, HistoryVM); OBSERVABLE_PROPERTY_RW(HistoryViewModel^, HistoryVM);
OBSERVABLE_PROPERTY_RW(bool, IsInError); OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError);
OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand); OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand);
OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayStringExpression); OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayStringExpression);
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<Common::DisplayExpressionToken^>^, ExpressionTokens); OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<Common::DisplayExpressionToken^>^, ExpressionTokens);
OBSERVABLE_PROPERTY_RW(Platform::String^, DecimalDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, DecimalDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, OctalDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, OctalDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, BinaryDisplayValue); OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, BinaryDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue_AutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String^, DecDisplayValue_AutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, DecDisplayValue_AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String^, OctDisplayValue_AutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, OctDisplayValue_AutomationName);
@ -69,21 +63,21 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsCurrentViewPinned); OBSERVABLE_PROPERTY_RW(bool, IsCurrentViewPinned);
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<MemoryItemViewModel^>^, MemorizedNumbers); OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<MemoryItemViewModel^>^, MemorizedNumbers);
OBSERVABLE_PROPERTY_RW(bool, IsMemoryEmpty); OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty);
OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked); OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked);
OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled); OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsAutoEChecked); OBSERVABLE_PROPERTY_RW(bool, IsAutoEChecked);
OBSERVABLE_PROPERTY_RW(bool, IsAutoEEnabled); OBSERVABLE_PROPERTY_RW(bool, IsAutoEEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked); OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked);
OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled); OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled);
NAMED_OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationResultAutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationResultAutomationName);
NAMED_OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationExpressionAutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationExpressionAutomationName);
OBSERVABLE_PROPERTY_RW(bool, IsShiftProgrammerChecked); OBSERVABLE_PROPERTY_RW(bool, IsShiftProgrammerChecked);
OBSERVABLE_PROPERTY_RW(bool, IsQwordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsQwordEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsDwordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDwordEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsWordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsWordEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled); OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled);
OBSERVABLE_PROPERTY_RW(Platform::String^, OpenParenthesisCount); OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, OpenParenthesisCount);
OBSERVABLE_PROPERTY_RW(int, CurrentRadixType); OBSERVABLE_PROPERTY_RW(int, CurrentRadixType);
OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated); OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled); OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled);
@ -293,6 +287,9 @@ namespace CalculatorApp
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands); void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands);
void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands); void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands);
void SetParenthesisCount(_In_ const std::wstring& parenthesisCount); void SetParenthesisCount(_In_ const std::wstring& parenthesisCount);
void SetOpenParenthesisCountNarratorAnnouncement();
void OnNoRightParenAdded();
void SetNoParenAddedNarratorAnnouncement();
void OnMaxDigitsReached(); void OnMaxDigitsReached();
void OnBinaryOperatorReceived(); void OnBinaryOperatorReceived();
void OnMemoryItemChanged(unsigned int indexOfMemory); void OnMemoryItemChanged(unsigned int indexOfMemory);
@ -342,6 +339,8 @@ namespace CalculatorApp
Platform::String^ m_localizedMemoryItemChangedAutomationFormat; Platform::String^ m_localizedMemoryItemChangedAutomationFormat;
Platform::String^ m_localizedMemoryItemClearedAutomationFormat; Platform::String^ m_localizedMemoryItemClearedAutomationFormat;
Platform::String^ m_localizedMemoryCleared; Platform::String^ m_localizedMemoryCleared;
Platform::String^ m_localizedOpenParenthesisCountChangedAutomationFormat;
Platform::String^ m_localizedNoRightParenthesisAddedFormat;
bool m_pinned; bool m_pinned;
bool m_isOperandEnabled; bool m_isOperandEnabled;

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
@ -53,36 +53,29 @@ constexpr size_t SELECTED_TARGET_UNIT = 2;
// x millisecond delay before we consider conversion to be final // x millisecond delay before we consider conversion to be final
constexpr unsigned int CONVERSION_FINALIZED_DELAY_IN_MS = 1000; constexpr unsigned int CONVERSION_FINALIZED_DELAY_IN_MS = 1000;
const wregex regexTrimSpacesStart = wregex(L"^\\s+");
const wregex regexTrimSpacesEnd = wregex(L"\\s+$");
namespace CalculatorApp::ViewModel namespace
{ {
namespace UnitConverterViewModelProperties StringReference CurrentCategoryPropertyName(L"CurrentCategory");
{ StringReference Unit1AutomationNamePropertyName(L"Unit1AutomationName");
StringReference CurrentCategory(L"CurrentCategory"); StringReference Unit2AutomationNamePropertyName(L"Unit2AutomationName");
StringReference Unit1(L"Unit1"); StringReference Unit1PropertyName(L"Unit1");
StringReference Unit2(L"Unit2"); StringReference Unit2PropertyName(L"Unit2");
StringReference Value1Active(L"Value1Active"); StringReference Value1PropertyName(L"Value1");
StringReference Value2Active(L"Value2Active"); StringReference Value2PropertyName(L"Value2");
StringReference Value1(L"Value1"); StringReference Value1ActivePropertyName(L"Value1Active");
StringReference Value2(L"Value2"); StringReference Value2ActivePropertyName(L"Value2Active");
StringReference Value1AutomationName(L"Value1AutomationName"); StringReference Value1AutomationNamePropertyName(L"Value1AutomationName");
StringReference Value2AutomationName(L"Value2AutomationName"); StringReference Value2AutomationNamePropertyName(L"Value2AutomationName");
StringReference SupplementaryVisibility(L"SupplementaryVisibility"); StringReference CurrencySymbol1PropertyName(L"CurrencySymbol1");
StringReference SupplementaryResults(L"SupplementaryResults"); StringReference CurrencySymbol2PropertyName(L"CurrencySymbol2");
StringReference Unit1AutomationName(L"Unit1AutomationName"); StringReference CurrencySymbolVisibilityPropertyName(L"CurrencySymbolVisibility");
StringReference Unit2AutomationName(L"Unit2AutomationName"); StringReference SupplementaryVisibilityPropertyName(L"SupplementaryVisibility");
StringReference CurrencySymbol1(L"CurrencySymbol1");
StringReference CurrencySymbol2(L"CurrencySymbol2");
StringReference CurrencySymbolVisibility(L"CurrencySymbolVisibility");
StringReference CurrencyRatioEquality(L"CurrencyRatioEquality");
StringReference CurrencyRatioEqualityAutomationName(L"CurrencyRatioEqualityAutomationName");
StringReference NetworkBehavior(L"NetworkBehavior");
StringReference CurrencyDataLoadFailed(L"CurrencyDataLoadFailed");
StringReference CurrencyDataIsWeekOld(L"CurrencyDataIsWeekOld");
StringReference IsCurrencyLoadingVisible(L"IsCurrencyLoadingVisible");
} }
namespace UnitConverterResourceKeys namespace CalculatorApp::ViewModel::UnitConverterResourceKeys
{ {
StringReference ValueFromFormat(L"Format_ValueFrom"); StringReference ValueFromFormat(L"Format_ValueFrom");
StringReference ValueFromDecimalFormat(L"Format_ValueFrom_Decimal"); StringReference ValueFromDecimalFormat(L"Format_ValueFrom_Decimal");
@ -95,7 +88,6 @@ namespace CalculatorApp::ViewModel
StringReference CurrencyRatesUpdated(L"CurrencyRatesUpdated"); StringReference CurrencyRatesUpdated(L"CurrencyRatesUpdated");
StringReference CurrencyRatesUpdateFailed(L"CurrencyRatesUpdateFailed"); StringReference CurrencyRatesUpdateFailed(L"CurrencyRatesUpdateFailed");
} }
}
UnitConverterViewModel::UnitConverterViewModel(const shared_ptr<UCM::IUnitConverter>& model) : UnitConverterViewModel::UnitConverterViewModel(const shared_ptr<UCM::IUnitConverter>& model) :
m_model(model), m_model(model),
@ -202,13 +194,11 @@ void UnitConverterViewModel::BuildUnitList(const vector<UCM::Unit>& modelUnitLis
m_Units->Clear(); m_Units->Clear();
for (const UCM::Unit& modelUnit : modelUnitList) for (const UCM::Unit& modelUnit : modelUnitList)
{ {
if (modelUnit.isWhimsical) if (!modelUnit.isWhimsical)
{ {
continue;
}
m_Units->Append(ref new Unit(modelUnit)); m_Units->Append(ref new Unit(modelUnit));
} }
}
if (m_Units->Size == 0) if (m_Units->Size == 0)
{ {
@ -281,8 +271,8 @@ void UnitConverterViewModel::OnSwitchActive(Platform::Object^ unused)
Utils::Swap(&m_localizedValueFromFormat, &m_localizedValueToFormat); Utils::Swap(&m_localizedValueFromFormat, &m_localizedValueToFormat);
Utils::Swap(&m_Unit1AutomationName, &m_Unit2AutomationName); Utils::Swap(&m_Unit1AutomationName, &m_Unit2AutomationName);
RaisePropertyChanged(UnitConverterViewModelProperties::Unit1AutomationName); RaisePropertyChanged(Unit1AutomationNamePropertyName);
RaisePropertyChanged(UnitConverterViewModelProperties::Unit2AutomationName); RaisePropertyChanged(Unit2AutomationNamePropertyName);
m_isInputBlocked = false; m_isInputBlocked = false;
m_model->SwitchActive(m_valueFromUnlocalized); m_model->SwitchActive(m_valueFromUnlocalized);
@ -348,10 +338,15 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
if (pos != wstring::npos) if (pos != wstring::npos)
{ {
currencyResult.erase(pos, currencyCode.length()); currencyResult.erase(pos, currencyCode.length());
pos = currencyResult.find(L'\u00a0'); // non-breaking space std::wsmatch sm;
if (pos != wstring::npos) if (regex_search(currencyResult, sm, regexTrimSpacesStart))
{ {
currencyResult.erase(pos, 1); currencyResult.erase(sm.prefix().length(), sm.length());
}
if (regex_search(currencyResult, sm, regexTrimSpacesEnd))
{
currencyResult.erase(sm.prefix().length(), sm.length());
} }
} }
@ -556,13 +551,13 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop)
{ {
static bool isCategoryChanging = false; static bool isCategoryChanging = false;
if (prop->Equals(UnitConverterViewModelProperties::CurrentCategory)) if (prop == CurrentCategoryPropertyName)
{ {
isCategoryChanging = true; isCategoryChanging = true;
CategoryChanged->Execute(nullptr); CategoryChanged->Execute(nullptr);
isCategoryChanging = false; isCategoryChanging = false;
} }
else if (prop->Equals(UnitConverterViewModelProperties::Unit1) || prop->Equals(UnitConverterViewModelProperties::Unit2)) else if (prop == Unit1PropertyName || prop == Unit2PropertyName)
{ {
// Category changes will handle updating units after they've both been updated. // Category changes will handle updating units after they've both been updated.
// This event should only be used to update units from explicit user interaction. // This event should only be used to update units from explicit user interaction.
@ -571,7 +566,7 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop)
UnitChanged->Execute(nullptr); UnitChanged->Execute(nullptr);
} }
// Get the localized automation name for each CalculationResults field // Get the localized automation name for each CalculationResults field
if (prop->Equals(UnitConverterViewModelProperties::Unit1)) if (prop == Unit1PropertyName)
{ {
UpdateValue1AutomationName(); UpdateValue1AutomationName();
} }
@ -580,15 +575,15 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop)
UpdateValue2AutomationName(); UpdateValue2AutomationName();
} }
} }
else if (prop->Equals(UnitConverterViewModelProperties::Value1)) else if (prop == Value1PropertyName)
{ {
UpdateValue1AutomationName(); UpdateValue1AutomationName();
} }
else if (prop->Equals(UnitConverterViewModelProperties::Value2)) else if (prop == Value2PropertyName)
{ {
UpdateValue2AutomationName(); UpdateValue2AutomationName();
} }
else if (prop->Equals(UnitConverterViewModelProperties::Value1Active) || prop->Equals(UnitConverterViewModelProperties::Value2Active)) else if (prop == Value1ActivePropertyName || prop == Value2ActivePropertyName)
{ {
// if one of the values is activated, and as a result both are true, it means // if one of the values is activated, and as a result both are true, it means
// that we're trying to switch. // that we're trying to switch.
@ -600,11 +595,11 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop)
UpdateValue1AutomationName(); UpdateValue1AutomationName();
UpdateValue2AutomationName(); UpdateValue2AutomationName();
} }
else if (prop->Equals(UnitConverterViewModelProperties::SupplementaryResults)) else if (prop == SupplementaryResultsPropertyName)
{ {
RaisePropertyChanged(UnitConverterViewModelProperties::SupplementaryVisibility); RaisePropertyChanged(SupplementaryVisibilityPropertyName);
} }
else if (prop->Equals(UnitConverterViewModelProperties::Value1AutomationName)) else if (prop == Value1AutomationNamePropertyName)
{ {
m_isValue1Updating = false; m_isValue1Updating = false;
if (!m_isValue2Updating) if (!m_isValue2Updating)
@ -612,7 +607,7 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop)
AnnounceConversionResult(); AnnounceConversionResult();
} }
} }
else if (prop->Equals(UnitConverterViewModelProperties::Value2AutomationName)) else if (prop == Value2AutomationNamePropertyName)
{ {
m_isValue2Updating = false; m_isValue2Updating = false;
if (!m_isValue1Updating) if (!m_isValue1Updating)
@ -620,9 +615,9 @@ void UnitConverterViewModel::OnPropertyChanged(Platform::String^ prop)
AnnounceConversionResult(); AnnounceConversionResult();
} }
} }
else if (prop->Equals(UnitConverterViewModelProperties::CurrencySymbol1) || prop->Equals(UnitConverterViewModelProperties::CurrencySymbol2)) else if (prop == CurrencySymbol1PropertyName || prop == CurrencySymbol2PropertyName)
{ {
RaisePropertyChanged(UnitConverterViewModelProperties::CurrencySymbolVisibility); RaisePropertyChanged(CurrencySymbolVisibilityPropertyName);
} }
} }
@ -643,11 +638,9 @@ String^ UnitConverterViewModel::Serialize()
String^ serializedData = ref new String(wstring(out.str()).c_str()); String^ serializedData = ref new String(wstring(out.str()).c_str());
return serializedData; return serializedData;
} }
else
{
return nullptr; return nullptr;
} }
}
void UnitConverterViewModel::Deserialize(Platform::String^ state) void UnitConverterViewModel::Deserialize(Platform::String^ state)
{ {
@ -849,7 +842,7 @@ void UnitConverterViewModel::RefreshSupplementaryResults()
} }
m_cacheMutex.unlock(); m_cacheMutex.unlock();
RaisePropertyChanged(UnitConverterViewModelProperties::SupplementaryResults); RaisePropertyChanged(SupplementaryResultsPropertyName);
//EventWriteConverterSupplementaryResultsUpdated(); //EventWriteConverterSupplementaryResultsUpdated();
} }
@ -879,14 +872,11 @@ void UnitConverterViewModel::UpdateInputBlocked(_In_ const wstring& currencyInpu
{ {
// currencyInput is in en-US and has the default decimal separator, so this is safe to do. // currencyInput is in en-US and has the default decimal separator, so this is safe to do.
auto posOfDecimal = currencyInput.find(L'.'); auto posOfDecimal = currencyInput.find(L'.');
m_isInputBlocked = false;
if (posOfDecimal != wstring::npos && IsCurrencyCurrentCategory) if (posOfDecimal != wstring::npos && IsCurrencyCurrentCategory)
{ {
m_isInputBlocked = (posOfDecimal + static_cast<size_t>(m_currencyMaxFractionDigits) + 1 == currencyInput.length()); m_isInputBlocked = (posOfDecimal + static_cast<size_t>(m_currencyMaxFractionDigits) + 1 == currencyInput.length());
} }
else
{
m_isInputBlocked = false;
}
} }
NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId( NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId(
@ -988,7 +978,7 @@ void UnitConverterViewModel::OnPaste(String^ stringToPaste, ViewMode mode)
} }
// Negate is only allowed if it's the first legal character, which is handled above. // Negate is only allowed if it's the first legal character, which is handled above.
if (NumbersAndOperatorsEnum::None != op && NumbersAndOperatorsEnum::Negate != op) if (NumbersAndOperatorsEnum::Negate != op)
{ {
UCM::Command cmd = CommandFromButtonId(op); UCM::Command cmd = CommandFromButtonId(op);
m_model->SendCommand(cmd); m_model->SendCommand(cmd);

View file

@ -138,25 +138,6 @@ namespace CalculatorApp
return ref new Activatable<TActivatable>(activatable); return ref new Activatable<TActivatable>(activatable);
} }
namespace UnitConverterViewModelProperties
{
extern Platform::StringReference CurrentCategory;
extern Platform::StringReference Unit1;
extern Platform::StringReference Unit2;
extern Platform::StringReference Value1Active;
extern Platform::StringReference Value2Active;
extern Platform::StringReference SupplementaryVisibility;
extern Platform::StringReference SupplementaryResults;
extern Platform::StringReference CurrencySymbol1;
extern Platform::StringReference CurrencySymbol2;
extern Platform::StringReference CurrencySymbolVisibility;
extern Platform::StringReference CurrencyRatioEquality;
extern Platform::StringReference NetworkBehavior;
extern Platform::StringReference CurrencyDataLoadFailed;
extern Platform::StringReference CurrencyDataIsWeekOld;
extern Platform::StringReference IsCurrencyLoadingVisible;
}
[Windows::UI::Xaml::Data::Bindable] [Windows::UI::Xaml::Data::Bindable]
public ref class UnitConverterViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged public ref class UnitConverterViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{ {
@ -176,7 +157,7 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencySymbol2); OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencySymbol2);
OBSERVABLE_PROPERTY_RW(Unit^, Unit2); OBSERVABLE_PROPERTY_RW(Unit^, Unit2);
OBSERVABLE_PROPERTY_RW(Platform::String^, Value2); OBSERVABLE_PROPERTY_RW(Platform::String^, Value2);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<SupplementaryResult^>^, SupplementaryResults); OBSERVABLE_NAMED_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<SupplementaryResult^>^, SupplementaryResults);
OBSERVABLE_PROPERTY_RW(bool, Value1Active); OBSERVABLE_PROPERTY_RW(bool, Value1Active);
OBSERVABLE_PROPERTY_RW(bool, Value2Active); OBSERVABLE_PROPERTY_RW(bool, Value2Active);
OBSERVABLE_PROPERTY_RW(Platform::String^, Value1AutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, Value1AutomationName);
@ -187,14 +168,14 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsDropDownOpen); OBSERVABLE_PROPERTY_RW(bool, IsDropDownOpen);
OBSERVABLE_PROPERTY_RW(bool, IsDropDownEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDropDownEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsCurrencyLoadingVisible); OBSERVABLE_NAMED_PROPERTY_RW(bool, IsCurrencyLoadingVisible);
OBSERVABLE_PROPERTY_RW(bool, IsCurrencyCurrentCategory); OBSERVABLE_PROPERTY_RW(bool, IsCurrencyCurrentCategory);
OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyRatioEquality); OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyRatioEquality);
OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyRatioEqualityAutomationName); OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyRatioEqualityAutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyTimestamp); OBSERVABLE_PROPERTY_RW(Platform::String^, CurrencyTimestamp);
OBSERVABLE_PROPERTY_RW(CalculatorApp::NetworkAccessBehavior, NetworkBehavior); OBSERVABLE_NAMED_PROPERTY_RW(CalculatorApp::NetworkAccessBehavior, NetworkBehavior);
OBSERVABLE_PROPERTY_RW(bool, CurrencyDataLoadFailed); OBSERVABLE_NAMED_PROPERTY_RW(bool, CurrencyDataLoadFailed);
OBSERVABLE_PROPERTY_RW(bool, CurrencyDataIsWeekOld); OBSERVABLE_NAMED_PROPERTY_RW(bool, CurrencyDataIsWeekOld);
property Windows::UI::Xaml::Visibility SupplementaryVisibility property Windows::UI::Xaml::Visibility SupplementaryVisibility
{ {

View file

@ -10,6 +10,10 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
// Windows headers define min/max macros.
// Disable it for project code.
#define NOMINMAX
#include <windows.h> #include <windows.h>
#include <collection.h> #include <collection.h>
@ -26,7 +30,7 @@
#include <sstream> #include <sstream>
#include <concrt.h> #include <concrt.h>
#include <regex> #include <regex>
#include <iterator>
// C++\WinRT Headers // C++\WinRT Headers
#include "winrt/base.h" #include "winrt/base.h"
#include "winrt/Windows.Foundation.Diagnostics.h" #include "winrt/Windows.Foundation.Diagnostics.h"

View file

@ -38,7 +38,7 @@
<Paragraph> <Paragraph>
<Run x:Name="AboutFlyoutVersion"/> <Run x:Name="AboutFlyoutVersion"/>
<LineBreak/> <LineBreak/>
<Run x:Uid="AboutControlCopyright"/> <Run x:Name="AboutControlCopyrightRun"/>
</Paragraph> </Paragraph>
</RichTextBlock> </RichTextBlock>
<HyperlinkButton x:Name="AboutFlyoutEULA" <HyperlinkButton x:Name="AboutFlyoutEULA"

View file

@ -8,6 +8,7 @@
#include "CalcViewModel/Common/LocalizationStringUtil.h" #include "CalcViewModel/Common/LocalizationStringUtil.h"
#include "CalcViewModel/Common/TraceLogger.h" #include "CalcViewModel/Common/TraceLogger.h"
using namespace std;
using namespace CalculatorApp; using namespace CalculatorApp;
using namespace CalculatorApp::Common; using namespace CalculatorApp::Common;
using namespace Platform; using namespace Platform;
@ -19,6 +20,10 @@ using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives; using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data; using namespace Windows::UI::Xaml::Data;
#ifndef BUILD_YEAR
#define BUILD_YEAR 2019
#endif
AboutFlyout::AboutFlyout() AboutFlyout::AboutFlyout()
{ {
auto locService = LocalizationService::GetInstance(); auto locService = LocalizationService::GetInstance();
@ -31,6 +36,10 @@ AboutFlyout::AboutFlyout()
this->SetVersionString(); 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());
} }
void AboutFlyout::FeedbackButton_Click(_In_ Object^ sender, _In_ RoutedEventArgs^ e) void AboutFlyout::FeedbackButton_Click(_In_ Object^ sender, _In_ RoutedEventArgs^ e)

View file

@ -371,12 +371,13 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"/> <VisualState x:Name="Active">
<VisualState x:Name="Normal">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="Light"/> <Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="textContainer"
@ -390,7 +391,7 @@
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
FontWeight="SemiBold" FontWeight="Light"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}" Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -457,12 +458,13 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"/> <VisualState x:Name="Active">
<VisualState x:Name="Normal">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="Light"/> <Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
<Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="textContainer"
@ -476,7 +478,7 @@
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
FontWeight="SemiBold" FontWeight="Light"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}" Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -544,12 +546,13 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"/> <VisualState x:Name="Active">
<VisualState x:Name="Normal">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="Light"/> <Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="textContainer"
@ -563,7 +566,7 @@
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
FontWeight="SemiBold" FontWeight="Light"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}" Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 384 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 484 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

After

Width:  |  Height:  |  Size: 728 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 234 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 441 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 470 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 511 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 557 B

After

Width:  |  Height:  |  Size: 503 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 683 B

After

Width:  |  Height:  |  Size: 634 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 296 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 331 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

After

Width:  |  Height:  |  Size: 390 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 690 B

After

Width:  |  Height:  |  Size: 484 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 996 B

After

Width:  |  Height:  |  Size: 728 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 180 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

After

Width:  |  Height:  |  Size: 193 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 231 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 262 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 474 B

After

Width:  |  Height:  |  Size: 284 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 491 B

After

Width:  |  Height:  |  Size: 303 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 505 B

After

Width:  |  Height:  |  Size: 311 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

After

Width:  |  Height:  |  Size: 370 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 445 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 665 B

After

Width:  |  Height:  |  Size: 471 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

After

Width:  |  Height:  |  Size: 506 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

After

Width:  |  Height:  |  Size: 507 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 867 B

After

Width:  |  Height:  |  Size: 639 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 180 B

Before After
Before After

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