Merge with upstream/master
|
@ -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
|
@ -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
|
|
@ -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
|
|
|
@ -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)'
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 3 MiB |
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.1 MiB |
|
@ -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!
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
root = true
|
|
||||||
|
|
||||||
[*.{xaml,cpp,h}]
|
|
||||||
charset = utf-8-bom
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.{cpp,h}]
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -406,37 +413,39 @@ int CHistoryCollector::AddCommand(_In_ const std::shared_ptr<IExpressionCommand>
|
||||||
return nCommands - 1;
|
return nCommands - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//To Update the operands in the Expression according to the current Radix
|
// To Update the operands in the Expression according to the current Radix
|
||||||
void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precision)
|
void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precision)
|
||||||
{
|
{
|
||||||
if (m_spTokens != nullptr)
|
if (m_spTokens == nullptr)
|
||||||
{
|
{
|
||||||
unsigned int size;
|
return;
|
||||||
IFT(m_spTokens->GetSize(&size));
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < size; ++i)
|
unsigned int size;
|
||||||
|
IFT(m_spTokens->GetSize(&size));
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
std::pair<std::wstring, int> token;
|
||||||
|
IFT(m_spTokens->GetAt(i, &token));
|
||||||
|
int commandPosition = token.second;
|
||||||
|
if (commandPosition != -1)
|
||||||
{
|
{
|
||||||
std::pair<std::wstring, int> token;
|
std::shared_ptr<IExpressionCommand> expCommand;
|
||||||
IFT(m_spTokens->GetAt(i, &token));
|
IFT(m_spCommands->GetAt(commandPosition, &expCommand));
|
||||||
int commandPosition = token.second;
|
if (expCommand != nullptr && CalculationManager::CommandType::OperandCommand == expCommand->GetCommandType())
|
||||||
if (commandPosition != -1)
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<IExpressionCommand> expCommand;
|
std::shared_ptr<COpndCommand> opndCommand = std::static_pointer_cast<COpndCommand>(expCommand);
|
||||||
IFT(m_spCommands->GetAt(commandPosition, &expCommand));
|
if (opndCommand != nullptr)
|
||||||
if (expCommand != nullptr && CalculationManager::CommandType::OperandCommand == expCommand->GetCommandType())
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<COpndCommand> opndCommand = std::static_pointer_cast<COpndCommand>(expCommand);
|
token.first = opndCommand->GetString(radix, precision);
|
||||||
if (opndCommand != nullptr)
|
IFT(m_spTokens->SetAt(i, token));
|
||||||
{
|
opndCommand->SetCommands(GetOperandCommandsFromString(token.first));
|
||||||
token.first = opndCommand->GetString(radix, precision);
|
|
||||||
IFT(m_spTokens->SetAt(i, token));
|
|
||||||
opndCommand->SetCommands(GetOperandCommandsFromString(token.first));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetExpressionDisplay();
|
|
||||||
}
|
}
|
||||||
|
SetExpressionDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
|
void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
|
||||||
|
@ -444,7 +453,7 @@ void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
|
||||||
m_decimalSymbol = decimalSymbol;
|
m_decimalSymbol = decimalSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Update the commands corresponding to the passed string Number
|
// Update the commands corresponding to the passed string Number
|
||||||
std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr)
|
std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr)
|
||||||
{
|
{
|
||||||
std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>();
|
std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>();
|
||||||
|
|
|
@ -26,39 +26,41 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace CalcEngine;
|
using namespace CalcEngine;
|
||||||
|
|
||||||
// NPrecedenceOfOp
|
namespace {
|
||||||
//
|
// NPrecedenceOfOp
|
||||||
// returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number
|
//
|
||||||
// 0 is returned. Higher the number, higher the precedence of the operator.
|
// returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number
|
||||||
INT NPrecedenceOfOp(int nopCode)
|
// 0 is returned. Higher the number, higher the precedence of the operator.
|
||||||
{
|
INT NPrecedenceOfOp(int nopCode)
|
||||||
static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1,
|
{
|
||||||
IDC_ADD,2, IDC_SUB,2, IDC_RSHF,3, IDC_LSHF,3,
|
static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1,
|
||||||
IDC_MOD,3, IDC_DIV,3, IDC_MUL,3, IDC_PWR,4, IDC_ROOT, 4 };
|
IDC_ADD,2, IDC_SUB,2, IDC_RSHF,3, IDC_LSHF,3,
|
||||||
int iPrec;
|
IDC_MOD,3, IDC_DIV,3, IDC_MUL,3, IDC_PWR,4, IDC_ROOT, 4 };
|
||||||
|
unsigned int iPrec;
|
||||||
|
|
||||||
iPrec = 0;
|
|
||||||
while ((iPrec < ARRAYSIZE(rgbPrec)) && (nopCode != rgbPrec[iPrec]))
|
|
||||||
{
|
|
||||||
iPrec += 2;
|
|
||||||
}
|
|
||||||
if (iPrec >= ARRAYSIZE(rgbPrec))
|
|
||||||
{
|
|
||||||
iPrec = 0;
|
iPrec = 0;
|
||||||
}
|
while ((iPrec < size(rgbPrec)) && (nopCode != rgbPrec[iPrec]))
|
||||||
return rgbPrec[iPrec + 1];
|
{
|
||||||
|
iPrec += 2;
|
||||||
|
}
|
||||||
|
if (iPrec >= size(rgbPrec))
|
||||||
|
{
|
||||||
|
iPrec = 0;
|
||||||
|
}
|
||||||
|
return rgbPrec[iPrec + 1];
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleErrorCommand
|
// HandleErrorCommand
|
||||||
//
|
//
|
||||||
// When it is discovered by the state machine that at this point the input is not valid (eg. "1+)"), we want to proceed as though this input never
|
// When it is discovered by the state machine that at this point the input is not valid (eg. "1+)"), we want to proceed as though this input never
|
||||||
// occurred and may be some feedback to user like Beep. The rest of input can then continue by just ignoring this command.
|
// occurred and may be some feedback to user like Beep. The rest of input can then continue by just ignoring this command.
|
||||||
void CCalcEngine::HandleErrorCommand(WPARAM idc)
|
void CCalcEngine::HandleErrorCommand(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;
|
||||||
}
|
}
|
||||||
|
@ -940,7 +947,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)
|
||||||
{
|
{
|
||||||
|
@ -1020,7 +1027,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
|
||||||
|
|
||||||
uint64_t w64Bits = result.ToUInt64_t();
|
uint64_t w64Bits = result.ToUInt64_t();
|
||||||
uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0;
|
uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0;
|
||||||
w64Bits >>= 1; //RShift by 1
|
w64Bits >>= 1; // RShift by 1
|
||||||
w64Bits |= (lsb << (m_dwWordBitWidth - 1));
|
w64Bits |= (lsb << (m_dwWordBitWidth - 1));
|
||||||
|
|
||||||
result = w64Bits;
|
result = w64Bits;
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
class CalcException : public std::exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CalcException(HRESULT hr)
|
|
||||||
{
|
|
||||||
m_hr = hr;
|
|
||||||
}
|
|
||||||
HRESULT GetException()
|
|
||||||
{
|
|
||||||
return m_hr;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
HRESULT m_hr;
|
|
||||||
};
|
|
||||||
|
|
||||||
void IFT(HRESULT hr)
|
|
||||||
{
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
CalcException exception(hr);
|
|
||||||
throw(exception);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -24,15 +24,15 @@ 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_inHistoryItemLoadMode(false),
|
||||||
|
m_persistedPrimaryValue(),
|
||||||
|
m_isExponentialFormat(false),
|
||||||
m_currentDegreeMode(Command::CommandNULL),
|
m_currentDegreeMode(Command::CommandNULL),
|
||||||
m_savedDegreeMode(Command::CommandDEG),
|
m_savedDegreeMode(Command::CommandDEG),
|
||||||
m_isExponentialFormat(false),
|
m_pStdHistory(new CalculatorHistory(MAX_HISTORY_ITEMS)),
|
||||||
m_persistedPrimaryValue(),
|
m_pSciHistory(new CalculatorHistory(MAX_HISTORY_ITEMS))
|
||||||
m_currentCalculatorEngine(nullptr),
|
|
||||||
m_pStdHistory(new CalculatorHistory(CM_STD, MAX_HISTORY_ITEMS)),
|
|
||||||
m_pSciHistory(new CalculatorHistory(CM_SCI, MAX_HISTORY_ITEMS)),
|
|
||||||
m_inHistoryItemLoadMode(false)
|
|
||||||
{
|
{
|
||||||
CCalcEngine::InitialOneTimeOnlySetup(*m_resourceProvider);
|
CCalcEngine::InitialOneTimeOnlySetup(*m_resourceProvider);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,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)
|
||||||
|
@ -117,6 +116,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
|
||||||
|
@ -285,7 +292,7 @@ namespace CalculationManager
|
||||||
break;
|
break;
|
||||||
case Command::CommandFE:
|
case Command::CommandFE:
|
||||||
m_isExponentialFormat = !m_isExponentialFormat;
|
m_isExponentialFormat = !m_isExponentialFormat;
|
||||||
// fall through
|
[[fallthrough]];
|
||||||
default:
|
default:
|
||||||
m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(command));
|
m_currentCalculatorEngine->ProcessCommand(static_cast<WPARAM>(command));
|
||||||
break;
|
break;
|
||||||
|
@ -301,7 +308,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +363,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;
|
||||||
}
|
}
|
||||||
|
@ -428,9 +438,9 @@ namespace CalculationManager
|
||||||
if (*commandItr >= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber) &&
|
if (*commandItr >= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber) &&
|
||||||
*commandItr <= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizedNumberClearAll))
|
*commandItr <= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizedNumberClearAll))
|
||||||
{
|
{
|
||||||
//MemoryCommands(which have values above 255) are pushed on m_savedCommands upon casting to unsigned char.
|
// MemoryCommands(which have values above 255) are pushed on m_savedCommands upon casting to unsigned char.
|
||||||
//SerializeCommands uses m_savedCommands, which is then used in DeSerializeCommands.
|
// SerializeCommands uses m_savedCommands, which is then used in DeSerializeCommands.
|
||||||
//Hence, a simple cast to MemoryCommand is not sufficient.
|
// Hence, a simple cast to MemoryCommand is not sufficient.
|
||||||
MemoryCommand memoryCommand = static_cast<MemoryCommand>(*commandItr + UCHAR_MAX + 1);
|
MemoryCommand memoryCommand = static_cast<MemoryCommand>(*commandItr + UCHAR_MAX + 1);
|
||||||
unsigned int indexOfMemory = 0;
|
unsigned int indexOfMemory = 0;
|
||||||
switch (memoryCommand)
|
switch (memoryCommand)
|
||||||
|
@ -483,22 +493,25 @@ 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())
|
||||||
{
|
{
|
||||||
m_currentCalculatorEngine->ProcessCommand(IDC_STORE);
|
return;
|
||||||
|
|
||||||
auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject();
|
|
||||||
if (memoryObjectPtr != nullptr)
|
|
||||||
{
|
|
||||||
m_memorizedNumbers.insert(m_memorizedNumbers.begin(), *memoryObjectPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_memorizedNumbers.size() > m_maximumMemorySize)
|
|
||||||
{
|
|
||||||
m_memorizedNumbers.resize(m_maximumMemorySize);
|
|
||||||
}
|
|
||||||
this->SetMemorizedNumbersString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_currentCalculatorEngine->ProcessCommand(IDC_STORE);
|
||||||
|
|
||||||
|
auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject();
|
||||||
|
if (memoryObjectPtr != nullptr)
|
||||||
|
{
|
||||||
|
m_memorizedNumbers.insert(m_memorizedNumbers.begin(), *memoryObjectPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_memorizedNumbers.size() > m_maximumMemorySize)
|
||||||
|
{
|
||||||
|
m_memorizedNumbers.resize(m_maximumMemorySize);
|
||||||
|
}
|
||||||
|
this->SetMemorizedNumbersString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -509,11 +522,14 @@ 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())
|
||||||
{
|
{
|
||||||
this->MemorizedNumberSelect(indexOfMemory);
|
return;
|
||||||
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->MemorizedNumberSelect(indexOfMemory);
|
||||||
|
m_currentCalculatorEngine->ProcessCommand(IDC_RECALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -525,24 +541,27 @@ 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())
|
||||||
{
|
{
|
||||||
if (m_memorizedNumbers.empty())
|
return;
|
||||||
{
|
|
||||||
this->MemorizeNumber();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->MemorizedNumberSelect(indexOfMemory);
|
|
||||||
m_currentCalculatorEngine->ProcessCommand(IDC_MPLUS);
|
|
||||||
|
|
||||||
this->MemorizedNumberChanged(indexOfMemory);
|
|
||||||
|
|
||||||
this->SetMemorizedNumbersString();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_displayCallback->MemoryItemChanged(indexOfMemory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_memorizedNumbers.empty())
|
||||||
|
{
|
||||||
|
this->MemorizeNumber();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->MemorizedNumberSelect(indexOfMemory);
|
||||||
|
m_currentCalculatorEngine->ProcessCommand(IDC_MPLUS);
|
||||||
|
|
||||||
|
this->MemorizedNumberChanged(indexOfMemory);
|
||||||
|
|
||||||
|
this->SetMemorizedNumbersString();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_displayCallback->MemoryItemChanged(indexOfMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalculatorManager::MemorizedNumberClear(_In_ unsigned int indexOfMemory)
|
void CalculatorManager::MemorizedNumberClear(_In_ unsigned int indexOfMemory)
|
||||||
|
@ -563,27 +582,30 @@ 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())
|
||||||
{
|
{
|
||||||
// To add negative of the number on display to the memory -x = x - 2x
|
return;
|
||||||
if (m_memorizedNumbers.empty())
|
|
||||||
{
|
|
||||||
this->MemorizeNumber();
|
|
||||||
this->MemorizedNumberSubtract(0);
|
|
||||||
this->MemorizedNumberSubtract(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->MemorizedNumberSelect(indexOfMemory);
|
|
||||||
m_currentCalculatorEngine->ProcessCommand(IDC_MMINUS);
|
|
||||||
|
|
||||||
this->MemorizedNumberChanged(indexOfMemory);
|
|
||||||
|
|
||||||
this->SetMemorizedNumbersString();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_displayCallback->MemoryItemChanged(indexOfMemory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To add negative of the number on display to the memory -x = x - 2x
|
||||||
|
if (m_memorizedNumbers.empty())
|
||||||
|
{
|
||||||
|
this->MemorizeNumber();
|
||||||
|
this->MemorizedNumberSubtract(0);
|
||||||
|
this->MemorizedNumberSubtract(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->MemorizedNumberSelect(indexOfMemory);
|
||||||
|
m_currentCalculatorEngine->ProcessCommand(IDC_MMINUS);
|
||||||
|
|
||||||
|
this->MemorizedNumberChanged(indexOfMemory);
|
||||||
|
|
||||||
|
this->SetMemorizedNumbersString();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_displayCallback->MemoryItemChanged(indexOfMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -606,11 +628,13 @@ 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())
|
||||||
{
|
{
|
||||||
auto memoryObject = m_memorizedNumbers.at(indexOfMemory);
|
return;
|
||||||
m_currentCalculatorEngine->PersistedMemObject(memoryObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto memoryObject = m_memorizedNumbers.at(indexOfMemory);
|
||||||
|
m_currentCalculatorEngine->PersistedMemObject(memoryObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -620,13 +644,15 @@ 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())
|
||||||
{
|
{
|
||||||
auto memoryObject = m_currentCalculatorEngine->PersistedMemObject();
|
return;
|
||||||
if (memoryObject != nullptr)
|
}
|
||||||
{
|
|
||||||
m_memorizedNumbers.at(indexOfMemory) = *memoryObject;
|
auto memoryObject = m_currentCalculatorEngine->PersistedMemObject();
|
||||||
}
|
if (memoryObject != nullptr)
|
||||||
|
{
|
||||||
|
m_memorizedNumbers.at(indexOfMemory) = *memoryObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -94,7 +94,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;
|
||||||
|
@ -140,7 +141,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);
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace CalculationManager
|
||||||
CommandFAC = 113,
|
CommandFAC = 113,
|
||||||
CommandREC = 114,
|
CommandREC = 114,
|
||||||
CommandDMS = 115,
|
CommandDMS = 115,
|
||||||
CommandCUBEROOT = 116, //x ^ 1/3
|
CommandCUBEROOT = 116, // x ^ 1/3
|
||||||
CommandPOW10 = 117, // 10 ^ x
|
CommandPOW10 = 117, // 10 ^ x
|
||||||
CommandPERCENT = 118,
|
CommandPERCENT = 118,
|
||||||
|
|
||||||
|
|
|
@ -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{}
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
#define IDC_FAC 113
|
#define IDC_FAC 113
|
||||||
#define IDC_REC 114
|
#define IDC_REC 114
|
||||||
#define IDC_DMS 115
|
#define IDC_DMS 115
|
||||||
#define IDC_CUBEROOT 116 //x ^ 1/3
|
#define IDC_CUBEROOT 116 // x ^ 1/3
|
||||||
#define IDC_POW10 117 // 10 ^ x
|
#define IDC_POW10 117 // 10 ^ x
|
||||||
#define IDC_PERCENT 118
|
#define IDC_PERCENT 118
|
||||||
#define IDC_UNARYLAST IDC_PERCENT
|
#define IDC_UNARYLAST IDC_PERCENT
|
||||||
|
|
|
@ -85,7 +85,7 @@ private:
|
||||||
// if it hasn't yet been computed
|
// if it hasn't yet been computed
|
||||||
bool m_bChangeOp; /* Flag for changing operation. */
|
bool m_bChangeOp; /* Flag for changing operation. */
|
||||||
bool m_bRecord; // Global mode: recording or displaying
|
bool m_bRecord; // Global mode: recording or displaying
|
||||||
bool m_bSetCalcState; //Flag for setting the engine result state
|
bool m_bSetCalcState; // Flag for setting the engine result state
|
||||||
CalcEngine::CalcInput m_input; // Global calc input object for decimal strings
|
CalcEngine::CalcInput m_input; // Global calc input object for decimal strings
|
||||||
eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */
|
eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */
|
||||||
CalcEngine::Rational m_maxTrigonometricNum;
|
CalcEngine::Rational m_maxTrigonometricNum;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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))));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -1270,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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
@ -211,9 +211,8 @@ void modrat( PRAT *pa, PRAT b )
|
||||||
remnum( &((*pa)->pp), tmp->pp, BASEX );
|
remnum( &((*pa)->pp), tmp->pp, BASEX );
|
||||||
mulnumx( &((*pa)->pq), tmp->pq );
|
mulnumx( &((*pa)->pq), tmp->pq );
|
||||||
|
|
||||||
//Get *pa back in the integer over integer form.
|
// Get *pa back in the integer over integer form.
|
||||||
RENORMALIZE(*pa);
|
RENORMALIZE(*pa);
|
||||||
|
|
||||||
destroyrat( tmp );
|
destroyrat( tmp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ void fracrat( PRAT *pa , uint32_t radix, int32_t precision)
|
||||||
|
|
||||||
remnum( &((*pa)->pp), (*pa)->pq, BASEX );
|
remnum( &((*pa)->pp), (*pa)->pq, BASEX );
|
||||||
|
|
||||||
//Get *pa back in the integer over integer form.
|
// Get *pa back in the integer over integer form.
|
||||||
RENORMALIZE(*pa);
|
RENORMALIZE(*pa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -225,7 +225,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;\
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,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 );
|
||||||
|
|
|
@ -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" )
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ UnitConverter::UnitConverter(_In_ const shared_ptr<IConverterDataLoader>& dataLo
|
||||||
{
|
{
|
||||||
m_dataLoader = dataLoader;
|
m_dataLoader = dataLoader;
|
||||||
m_currencyDataLoader = currencyDataLoader;
|
m_currencyDataLoader = currencyDataLoader;
|
||||||
//declaring the delimiter character conversion map
|
// declaring the delimiter character conversion map
|
||||||
quoteConversions[L'|'] = L"{p}";
|
quoteConversions[L'|'] = L"{p}";
|
||||||
quoteConversions[L'['] = L"{lc}";
|
quoteConversions[L'['] = L"{lc}";
|
||||||
quoteConversions[L']'] = L"{rc}";
|
quoteConversions[L']'] = L"{rc}";
|
||||||
|
@ -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,15 +142,17 @@ 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())
|
||||||
{
|
{
|
||||||
m_fromType = fromType;
|
return;
|
||||||
m_toType = toType;
|
|
||||||
Calculate();
|
|
||||||
|
|
||||||
UpdateCurrencySymbols();
|
|
||||||
UpdateViewModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_fromType = fromType;
|
||||||
|
m_toType = toType;
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
UpdateCurrencySymbols();
|
||||||
|
UpdateViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -181,22 +169,24 @@ 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())
|
||||||
{
|
{
|
||||||
swap(m_fromType, m_toType);
|
return;
|
||||||
swap(m_currentHasDecimal, m_returnHasDecimal);
|
}
|
||||||
m_returnDisplay = m_currentDisplay;
|
|
||||||
m_currentDisplay = newValue;
|
|
||||||
m_currentHasDecimal = (m_currentDisplay.find(L'.') != m_currentDisplay.npos);
|
|
||||||
m_switchedActive = true;
|
|
||||||
|
|
||||||
if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr)
|
swap(m_fromType, m_toType);
|
||||||
{
|
swap(m_currentHasDecimal, m_returnHasDecimal);
|
||||||
shared_ptr<ICurrencyConverterDataLoader> currencyDataLoader = GetCurrencyConverterDataLoader();
|
m_returnDisplay = m_currentDisplay;
|
||||||
const pair<wstring, wstring> currencyRatios = currencyDataLoader->GetCurrencyRatioEquality(m_fromType, m_toType);
|
m_currentDisplay = newValue;
|
||||||
|
m_currentHasDecimal = (m_currentDisplay.find(L'.') != m_currentDisplay.npos);
|
||||||
|
m_switchedActive = true;
|
||||||
|
|
||||||
m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second);
|
if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr)
|
||||||
}
|
{
|
||||||
|
shared_ptr<ICurrencyConverterDataLoader> currencyDataLoader = GetCurrencyConverterDataLoader();
|
||||||
|
const pair<wstring, wstring> currencyRatios = currencyDataLoader->GetCurrencyRatioEquality(m_fromType, m_toType);
|
||||||
|
|
||||||
|
m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,55 +281,53 @@ wstring UnitConverter::ConversionDataToString(ConversionData d, const wchar_t *
|
||||||
/// </summary>
|
/// </summary>
|
||||||
wstring UnitConverter::Serialize()
|
wstring UnitConverter::Serialize()
|
||||||
{
|
{
|
||||||
if (CheckLoad())
|
if (!CheckLoad())
|
||||||
{
|
|
||||||
wstringstream out(wstringstream::out);
|
|
||||||
const wchar_t * delimiter = L";";
|
|
||||||
|
|
||||||
out << UnitToString(m_fromType, delimiter) << "|";
|
|
||||||
out << UnitToString(m_toType, delimiter) << "|";
|
|
||||||
out << CategoryToString(m_currentCategory, delimiter) << "|";
|
|
||||||
out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter;
|
|
||||||
out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|";
|
|
||||||
wstringstream categoryString(wstringstream::out);
|
|
||||||
wstringstream categoryToUnitString(wstringstream::out);
|
|
||||||
wstringstream unitToUnitToDoubleString(wstringstream::out);
|
|
||||||
for (const Category& c : m_categories)
|
|
||||||
{
|
|
||||||
categoryString << CategoryToString(c, delimiter) << ",";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& cur : m_categoryToUnits)
|
|
||||||
{
|
|
||||||
categoryToUnitString << CategoryToString(cur.first, delimiter) << "[";
|
|
||||||
for (const Unit& u : cur.second)
|
|
||||||
{
|
|
||||||
categoryToUnitString << UnitToString(u, delimiter) << ",";
|
|
||||||
}
|
|
||||||
categoryToUnitString << "[" << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& cur : m_ratioMap)
|
|
||||||
{
|
|
||||||
unitToUnitToDoubleString << UnitToString(cur.first, delimiter) << "[";
|
|
||||||
for (const auto& curConversion : cur.second)
|
|
||||||
{
|
|
||||||
unitToUnitToDoubleString << UnitToString(curConversion.first, delimiter) << ":";
|
|
||||||
unitToUnitToDoubleString << ConversionDataToString(curConversion.second, delimiter) << ":,";
|
|
||||||
}
|
|
||||||
unitToUnitToDoubleString << "[" << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
out << categoryString.str() << "|";
|
|
||||||
out << categoryToUnitString.str() << "|";
|
|
||||||
out << unitToUnitToDoubleString.str() << "|";
|
|
||||||
wstring test = out.str();
|
|
||||||
return test;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return wstring();
|
return wstring();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wstringstream out(wstringstream::out);
|
||||||
|
const wchar_t * delimiter = L";";
|
||||||
|
|
||||||
|
out << UnitToString(m_fromType, delimiter) << "|";
|
||||||
|
out << UnitToString(m_toType, delimiter) << "|";
|
||||||
|
out << CategoryToString(m_currentCategory, delimiter) << "|";
|
||||||
|
out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter;
|
||||||
|
out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|";
|
||||||
|
wstringstream categoryString(wstringstream::out);
|
||||||
|
wstringstream categoryToUnitString(wstringstream::out);
|
||||||
|
wstringstream unitToUnitToDoubleString(wstringstream::out);
|
||||||
|
for (const Category& c : m_categories)
|
||||||
|
{
|
||||||
|
categoryString << CategoryToString(c, delimiter) << ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& cur : m_categoryToUnits)
|
||||||
|
{
|
||||||
|
categoryToUnitString << CategoryToString(cur.first, delimiter) << "[";
|
||||||
|
for (const Unit& u : cur.second)
|
||||||
|
{
|
||||||
|
categoryToUnitString << UnitToString(u, delimiter) << ",";
|
||||||
|
}
|
||||||
|
categoryToUnitString << "[" << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& cur : m_ratioMap)
|
||||||
|
{
|
||||||
|
unitToUnitToDoubleString << UnitToString(cur.first, delimiter) << "[";
|
||||||
|
for (const auto& curConversion : cur.second)
|
||||||
|
{
|
||||||
|
unitToUnitToDoubleString << UnitToString(curConversion.first, delimiter) << ":";
|
||||||
|
unitToUnitToDoubleString << ConversionDataToString(curConversion.second, delimiter) << ":,";
|
||||||
|
}
|
||||||
|
unitToUnitToDoubleString << "[" << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
out << categoryString.str() << "|";
|
||||||
|
out << categoryToUnitString.str() << "|";
|
||||||
|
out << unitToUnitToDoubleString.str() << "|";
|
||||||
|
wstring test = out.str();
|
||||||
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -349,55 +337,58 @@ wstring UnitConverter::Serialize()
|
||||||
void UnitConverter::DeSerialize(const wstring& serializedData)
|
void UnitConverter::DeSerialize(const wstring& serializedData)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
if (!serializedData.empty())
|
|
||||||
|
if (serializedData.empty())
|
||||||
{
|
{
|
||||||
vector<wstring> outerTokens = StringToVector(serializedData, L"|");
|
return;
|
||||||
assert(outerTokens.size() == EXPECTEDSERIALIZEDTOKENCOUNT);
|
|
||||||
m_fromType = StringToUnit(outerTokens[0]);
|
|
||||||
m_toType = StringToUnit(outerTokens[1]);
|
|
||||||
m_currentCategory = StringToCategory(outerTokens[2]);
|
|
||||||
vector<wstring> stateDataTokens = StringToVector(outerTokens[3], L";");
|
|
||||||
assert(stateDataTokens.size() == EXPECTEDSTATEDATATOKENCOUNT);
|
|
||||||
m_currentHasDecimal = (stateDataTokens[0].compare(L"1") == 0);
|
|
||||||
m_returnHasDecimal = (stateDataTokens[1].compare(L"1") == 0);
|
|
||||||
m_switchedActive = (stateDataTokens[2].compare(L"1") == 0);
|
|
||||||
m_currentDisplay = stateDataTokens[3];
|
|
||||||
m_returnDisplay = stateDataTokens[4];
|
|
||||||
vector<wstring> categoryListTokens = StringToVector(outerTokens[4], L",");
|
|
||||||
for (wstring token : categoryListTokens)
|
|
||||||
{
|
|
||||||
m_categories.push_back(StringToCategory(token));
|
|
||||||
}
|
|
||||||
vector<wstring> unitVectorTokens = StringToVector(outerTokens[5], L"]");
|
|
||||||
for (wstring unitVector : unitVectorTokens)
|
|
||||||
{
|
|
||||||
vector<wstring> mapcomponents = StringToVector(unitVector, L"[");
|
|
||||||
assert(mapcomponents.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT);
|
|
||||||
Category key = StringToCategory(mapcomponents[0]);
|
|
||||||
vector<wstring> units = StringToVector(mapcomponents[1], L",");
|
|
||||||
for (wstring unit : units)
|
|
||||||
{
|
|
||||||
m_categoryToUnits[key].push_back(StringToUnit(unit));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vector<wstring> ratioMapTokens = StringToVector(outerTokens[6], L"]");
|
|
||||||
for (wstring token : ratioMapTokens)
|
|
||||||
{
|
|
||||||
vector<wstring> ratioMapComponentTokens = StringToVector(token, L"[");
|
|
||||||
assert(ratioMapComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT);
|
|
||||||
Unit key = StringToUnit(ratioMapComponentTokens[0]);
|
|
||||||
vector<wstring> ratioMapList = StringToVector(ratioMapComponentTokens[1], L",");
|
|
||||||
for (wstring subtoken : ratioMapList)
|
|
||||||
{
|
|
||||||
vector<wstring> ratioMapSubComponentTokens = StringToVector(subtoken, L":");
|
|
||||||
assert(ratioMapSubComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT);
|
|
||||||
Unit subkey = StringToUnit(ratioMapSubComponentTokens[0]);
|
|
||||||
ConversionData conversion = StringToConversionData(ratioMapSubComponentTokens[1]);
|
|
||||||
m_ratioMap[key][subkey] = conversion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateViewModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<wstring> outerTokens = StringToVector(serializedData, L"|");
|
||||||
|
assert(outerTokens.size() == EXPECTEDSERIALIZEDTOKENCOUNT);
|
||||||
|
m_fromType = StringToUnit(outerTokens[0]);
|
||||||
|
m_toType = StringToUnit(outerTokens[1]);
|
||||||
|
m_currentCategory = StringToCategory(outerTokens[2]);
|
||||||
|
vector<wstring> stateDataTokens = StringToVector(outerTokens[3], L";");
|
||||||
|
assert(stateDataTokens.size() == EXPECTEDSTATEDATATOKENCOUNT);
|
||||||
|
m_currentHasDecimal = (stateDataTokens[0].compare(L"1") == 0);
|
||||||
|
m_returnHasDecimal = (stateDataTokens[1].compare(L"1") == 0);
|
||||||
|
m_switchedActive = (stateDataTokens[2].compare(L"1") == 0);
|
||||||
|
m_currentDisplay = stateDataTokens[3];
|
||||||
|
m_returnDisplay = stateDataTokens[4];
|
||||||
|
vector<wstring> categoryListTokens = StringToVector(outerTokens[4], L",");
|
||||||
|
for (wstring token : categoryListTokens)
|
||||||
|
{
|
||||||
|
m_categories.push_back(StringToCategory(token));
|
||||||
|
}
|
||||||
|
vector<wstring> unitVectorTokens = StringToVector(outerTokens[5], L"]");
|
||||||
|
for (wstring unitVector : unitVectorTokens)
|
||||||
|
{
|
||||||
|
vector<wstring> mapcomponents = StringToVector(unitVector, L"[");
|
||||||
|
assert(mapcomponents.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT);
|
||||||
|
Category key = StringToCategory(mapcomponents[0]);
|
||||||
|
vector<wstring> units = StringToVector(mapcomponents[1], L",");
|
||||||
|
for (wstring unit : units)
|
||||||
|
{
|
||||||
|
m_categoryToUnits[key].push_back(StringToUnit(unit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<wstring> ratioMapTokens = StringToVector(outerTokens[6], L"]");
|
||||||
|
for (wstring token : ratioMapTokens)
|
||||||
|
{
|
||||||
|
vector<wstring> ratioMapComponentTokens = StringToVector(token, L"[");
|
||||||
|
assert(ratioMapComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT);
|
||||||
|
Unit key = StringToUnit(ratioMapComponentTokens[0]);
|
||||||
|
vector<wstring> ratioMapList = StringToVector(ratioMapComponentTokens[1], L",");
|
||||||
|
for (wstring subtoken : ratioMapList)
|
||||||
|
{
|
||||||
|
vector<wstring> ratioMapSubComponentTokens = StringToVector(subtoken, L":");
|
||||||
|
assert(ratioMapSubComponentTokens.size() == EXPECTEDMAPCOMPONENTTOKENCOUNT);
|
||||||
|
Unit subkey = StringToUnit(ratioMapSubComponentTokens[0]);
|
||||||
|
ConversionData conversion = StringToConversionData(ratioMapSubComponentTokens[1]);
|
||||||
|
m_ratioMap[key][subkey] = conversion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -406,15 +397,17 @@ 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())
|
||||||
{
|
{
|
||||||
vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
|
return;
|
||||||
if (outerTokens.size() == 3)
|
}
|
||||||
{
|
|
||||||
m_fromType = StringToUnit(outerTokens[0]);
|
vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
|
||||||
m_toType = StringToUnit(outerTokens[1]);
|
if (outerTokens.size() == 3)
|
||||||
m_currentCategory = StringToCategory(outerTokens[2]);
|
{
|
||||||
}
|
m_fromType = StringToUnit(outerTokens[0]);
|
||||||
|
m_toType = StringToUnit(outerTokens[1]);
|
||||||
|
m_currentCategory = StringToCategory(outerTokens[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +434,7 @@ wstring UnitConverter::Quote(const wstring& s)
|
||||||
{
|
{
|
||||||
wstringstream quotedString(wstringstream::out);
|
wstringstream quotedString(wstringstream::out);
|
||||||
|
|
||||||
//Iterate over the delimiter characters we need to quote
|
// Iterate over the delimiter characters we need to quote
|
||||||
wstring::const_iterator cursor = s.begin();
|
wstring::const_iterator cursor = s.begin();
|
||||||
while(cursor != s.end())
|
while(cursor != s.end())
|
||||||
{
|
{
|
||||||
|
@ -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,144 +496,146 @@ 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())
|
||||||
{
|
{
|
||||||
//TODO: Localization of characters
|
return;
|
||||||
bool clearFront = false;
|
}
|
||||||
if (m_currentDisplay == L"0")
|
|
||||||
|
// TODO: Localization of characters
|
||||||
|
bool clearFront = false;
|
||||||
|
if (m_currentDisplay == L"0")
|
||||||
|
{
|
||||||
|
clearFront = true;
|
||||||
|
}
|
||||||
|
bool clearBack = false;
|
||||||
|
if ((m_currentHasDecimal && m_currentDisplay.size() - 1 >= MAXIMUMDIGITSALLOWED) || (!m_currentHasDecimal && m_currentDisplay.size() >= MAXIMUMDIGITSALLOWED))
|
||||||
|
{
|
||||||
|
clearBack = true;
|
||||||
|
}
|
||||||
|
if (command != Command::Negate && m_switchedActive)
|
||||||
|
{
|
||||||
|
ClearValues();
|
||||||
|
m_switchedActive = false;
|
||||||
|
clearFront = true;
|
||||||
|
clearBack = false;
|
||||||
|
}
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case Command::Zero:
|
||||||
|
m_currentDisplay += L"0";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::One:
|
||||||
|
m_currentDisplay += L"1";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Two:
|
||||||
|
m_currentDisplay += L"2";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Three:
|
||||||
|
m_currentDisplay += L"3";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Four:
|
||||||
|
m_currentDisplay += L"4";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Five:
|
||||||
|
m_currentDisplay += L"5";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Six:
|
||||||
|
m_currentDisplay += L"6";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Seven:
|
||||||
|
m_currentDisplay += L"7";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Eight:
|
||||||
|
m_currentDisplay += L"8";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Nine:
|
||||||
|
m_currentDisplay += L"9";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Decimal:
|
||||||
|
clearFront = false;
|
||||||
|
clearBack = false;
|
||||||
|
if (!m_currentHasDecimal)
|
||||||
{
|
{
|
||||||
clearFront = true;
|
m_currentDisplay += L".";
|
||||||
|
m_currentHasDecimal = true;
|
||||||
}
|
}
|
||||||
bool clearBack = false;
|
break;
|
||||||
if ((m_currentHasDecimal && m_currentDisplay.size() - 1 >= MAXIMUMDIGITSALLOWED) || (!m_currentHasDecimal && m_currentDisplay.size() >= MAXIMUMDIGITSALLOWED))
|
|
||||||
|
case Command::Backspace:
|
||||||
|
clearFront = false;
|
||||||
|
clearBack = false;
|
||||||
|
if ((m_currentDisplay.front() != '-' && m_currentDisplay.size() > 1) || m_currentDisplay.size() > 2)
|
||||||
{
|
{
|
||||||
clearBack = true;
|
if (m_currentDisplay.back() == '.')
|
||||||
}
|
|
||||||
if (command != Command::Negate && m_switchedActive)
|
|
||||||
{
|
|
||||||
ClearValues();
|
|
||||||
m_switchedActive = false;
|
|
||||||
clearFront = true;
|
|
||||||
clearBack = false;
|
|
||||||
}
|
|
||||||
switch (command)
|
|
||||||
{
|
|
||||||
case Command::Zero:
|
|
||||||
m_currentDisplay += L"0";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::One:
|
|
||||||
m_currentDisplay += L"1";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Two:
|
|
||||||
m_currentDisplay += L"2";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Three:
|
|
||||||
m_currentDisplay += L"3";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Four:
|
|
||||||
m_currentDisplay += L"4";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Five:
|
|
||||||
m_currentDisplay += L"5";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Six:
|
|
||||||
m_currentDisplay += L"6";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Seven:
|
|
||||||
m_currentDisplay += L"7";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Eight:
|
|
||||||
m_currentDisplay += L"8";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Nine:
|
|
||||||
m_currentDisplay += L"9";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Decimal:
|
|
||||||
clearFront = false;
|
|
||||||
clearBack = false;
|
|
||||||
if (!m_currentHasDecimal)
|
|
||||||
{
|
{
|
||||||
m_currentDisplay += L".";
|
m_currentHasDecimal = false;
|
||||||
m_currentHasDecimal = true;
|
|
||||||
}
|
}
|
||||||
break;
|
m_currentDisplay.pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_currentDisplay = L"0";
|
||||||
|
m_currentHasDecimal = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Command::Backspace:
|
case Command::Negate:
|
||||||
clearFront = false;
|
clearFront = false;
|
||||||
clearBack = false;
|
clearBack = false;
|
||||||
if ((m_currentDisplay.front() != '-' && m_currentDisplay.size() > 1) || m_currentDisplay.size() > 2)
|
if (m_currentCategory.supportsNegative)
|
||||||
|
{
|
||||||
|
if (m_currentDisplay.front() == '-')
|
||||||
{
|
{
|
||||||
if (m_currentDisplay.back() == '.')
|
m_currentDisplay.erase(0, 1);
|
||||||
{
|
|
||||||
m_currentHasDecimal = false;
|
|
||||||
}
|
|
||||||
m_currentDisplay.pop_back();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_currentDisplay = L"0";
|
m_currentDisplay.insert(0, 1, '-');
|
||||||
m_currentHasDecimal = false;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Negate:
|
|
||||||
clearFront = false;
|
|
||||||
clearBack = false;
|
|
||||||
if (m_currentCategory.supportsNegative)
|
|
||||||
{
|
|
||||||
if (m_currentDisplay.front() == '-')
|
|
||||||
{
|
|
||||||
m_currentDisplay.erase(0, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_currentDisplay.insert(0, 1, '-');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Clear:
|
|
||||||
clearFront = false;
|
|
||||||
clearBack = false;
|
|
||||||
ClearValues();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Reset:
|
|
||||||
clearFront = false;
|
|
||||||
clearBack = false;
|
|
||||||
ClearValues();
|
|
||||||
Reset();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Clear:
|
||||||
|
clearFront = false;
|
||||||
|
clearBack = false;
|
||||||
|
ClearValues();
|
||||||
|
break;
|
||||||
|
|
||||||
if (clearFront)
|
case Command::Reset:
|
||||||
{
|
clearFront = false;
|
||||||
m_currentDisplay.erase(0, 1);
|
clearBack = false;
|
||||||
}
|
ClearValues();
|
||||||
if (clearBack)
|
Reset();
|
||||||
{
|
break;
|
||||||
m_currentDisplay.erase(m_currentDisplay.size() - 1, 1);
|
|
||||||
m_vmCallback->MaxDigitsReached();
|
|
||||||
}
|
|
||||||
|
|
||||||
Calculate();
|
default:
|
||||||
|
break;
|
||||||
UpdateViewModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (clearFront)
|
||||||
|
{
|
||||||
|
m_currentDisplay.erase(0, 1);
|
||||||
|
}
|
||||||
|
if (clearBack)
|
||||||
|
{
|
||||||
|
m_currentDisplay.erase(m_currentDisplay.size() - 1, 1);
|
||||||
|
m_vmCallback->MaxDigitsReached();
|
||||||
|
}
|
||||||
|
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
UpdateViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -728,7 +723,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
||||||
vector<SuggestedValueIntermediate> intermediateVector;
|
vector<SuggestedValueIntermediate> intermediateVector;
|
||||||
vector<SuggestedValueIntermediate> intermediateWhimsicalVector;
|
vector<SuggestedValueIntermediate> intermediateWhimsicalVector;
|
||||||
unordered_map<Unit, ConversionData, UnitHash> ratios = m_ratioMap[m_fromType];
|
unordered_map<Unit, ConversionData, UnitHash> ratios = m_ratioMap[m_fromType];
|
||||||
//Calculate converted values for every other unit type in this category, along with their magnitude
|
// Calculate converted values for every other unit type in this category, along with their magnitude
|
||||||
for (const auto& cur : ratios)
|
for (const auto& cur : ratios)
|
||||||
{
|
{
|
||||||
if (cur.first != m_fromType && cur.first != m_toType)
|
if (cur.first != m_fromType && cur.first != m_toType)
|
||||||
|
@ -745,7 +740,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
|
// Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
|
||||||
sort(intermediateVector.begin(), intermediateVector.end(), []
|
sort(intermediateVector.begin(), intermediateVector.end(), []
|
||||||
(SuggestedValueIntermediate first, SuggestedValueIntermediate second)
|
(SuggestedValueIntermediate first, SuggestedValueIntermediate second)
|
||||||
{
|
{
|
||||||
|
@ -759,7 +754,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings
|
// Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings
|
||||||
for (const auto& entry : intermediateVector)
|
for (const auto& entry : intermediateVector)
|
||||||
{
|
{
|
||||||
wstring roundedString;
|
wstring roundedString;
|
||||||
|
@ -783,7 +778,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Whimsicals are determined differently
|
// The Whimsicals are determined differently
|
||||||
//Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
|
// Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
|
||||||
sort(intermediateWhimsicalVector.begin(), intermediateWhimsicalVector.end(), []
|
sort(intermediateWhimsicalVector.begin(), intermediateWhimsicalVector.end(), []
|
||||||
(SuggestedValueIntermediate first, SuggestedValueIntermediate second)
|
(SuggestedValueIntermediate first, SuggestedValueIntermediate second)
|
||||||
{
|
{
|
||||||
|
@ -797,7 +792,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings
|
// Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings
|
||||||
vector<tuple<wstring, Unit>> whimsicalReturnVector;
|
vector<tuple<wstring, Unit>> whimsicalReturnVector;
|
||||||
|
|
||||||
for (const auto& entry : intermediateWhimsicalVector)
|
for (const auto& entry : intermediateWhimsicalVector)
|
||||||
|
@ -844,47 +839,49 @@ void UnitConverter::Reset()
|
||||||
ClearValues();
|
ClearValues();
|
||||||
m_switchedActive = false;
|
m_switchedActive = false;
|
||||||
|
|
||||||
if (!m_categories.empty())
|
if (m_categories.empty())
|
||||||
{
|
{
|
||||||
m_currentCategory = m_categories[0];
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_categoryToUnits.clear();
|
m_currentCategory = m_categories[0];
|
||||||
m_ratioMap.clear();
|
|
||||||
bool readyCategoryFound = false;
|
m_categoryToUnits.clear();
|
||||||
for (const Category& category : m_categories)
|
m_ratioMap.clear();
|
||||||
|
bool readyCategoryFound = false;
|
||||||
|
for (const Category& category : m_categories)
|
||||||
|
{
|
||||||
|
shared_ptr<IConverterDataLoader> activeDataLoader = GetDataLoaderForCategory(category);
|
||||||
|
if (activeDataLoader == nullptr)
|
||||||
{
|
{
|
||||||
shared_ptr<IConverterDataLoader> activeDataLoader = GetDataLoaderForCategory(category);
|
// The data loader is different depending on the category, e.g. currency data loader
|
||||||
if (activeDataLoader == nullptr)
|
// is different from the static data loader.
|
||||||
{
|
// If there is no data loader for this category, continue.
|
||||||
// The data loader is different depending on the category, e.g. currency data loader
|
continue;
|
||||||
// is different from the static data loader.
|
|
||||||
// If there is no data loader for this category, continue.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<Unit> units = activeDataLoader->LoadOrderedUnits(category);
|
|
||||||
m_categoryToUnits[category] = units;
|
|
||||||
|
|
||||||
// Just because the units are empty, doesn't mean the user can't select this category,
|
|
||||||
// we just want to make sure we don't let an unready category be the default.
|
|
||||||
if (!units.empty())
|
|
||||||
{
|
|
||||||
for (Unit u : units)
|
|
||||||
{
|
|
||||||
m_ratioMap[u] = activeDataLoader->LoadOrderedRatios(u);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!readyCategoryFound)
|
|
||||||
{
|
|
||||||
m_currentCategory = category;
|
|
||||||
readyCategoryFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeSelectedUnits();
|
vector<Unit> units = activeDataLoader->LoadOrderedUnits(category);
|
||||||
Calculate();
|
m_categoryToUnits[category] = units;
|
||||||
|
|
||||||
|
// Just because the units are empty, doesn't mean the user can't select this category,
|
||||||
|
// we just want to make sure we don't let an unready category be the default.
|
||||||
|
if (!units.empty())
|
||||||
|
{
|
||||||
|
for (Unit u : units)
|
||||||
|
{
|
||||||
|
m_ratioMap[u] = activeDataLoader->LoadOrderedRatios(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readyCategoryFound)
|
||||||
|
{
|
||||||
|
m_currentCategory = category;
|
||||||
|
readyCategoryFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitializeSelectedUnits();
|
||||||
|
Calculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1029,22 +1026,24 @@ 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)
|
||||||
{
|
{
|
||||||
wstring::iterator iter;
|
return;
|
||||||
for (iter = returnString.end() - 1; ;iter--)
|
}
|
||||||
|
|
||||||
|
wstring::iterator iter;
|
||||||
|
for (iter = returnString.end() - 1; ;iter--)
|
||||||
|
{
|
||||||
|
if (*iter != L'0')
|
||||||
{
|
{
|
||||||
if (*iter != L'0')
|
returnString.erase(iter + 1, returnString.end());
|
||||||
{
|
break;
|
||||||
returnString.erase(iter + 1, returnString.end());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*(returnString.end()-1) == L'.')
|
|
||||||
{
|
|
||||||
returnString.erase(returnString.end()-1, returnString.end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (*(returnString.end()-1) == L'.')
|
||||||
|
{
|
||||||
|
returnString.erase(returnString.end()-1, returnString.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -26,6 +26,7 @@ constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" };
|
||||||
// [\s\x85] means white-space characters
|
// [\s\x85] means white-space characters
|
||||||
static const wstring c_wspc = L"[\\s\\x85]*";
|
static const wstring c_wspc = L"[\\s\\x85]*";
|
||||||
static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc;
|
static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc;
|
||||||
|
static const wstring c_wspcLParenSigned = c_wspc + L"([-+]?[(])*" + c_wspc;
|
||||||
static const wstring c_wspcRParens = c_wspc + L"[)]*" + c_wspc;
|
static const wstring c_wspcRParens = c_wspc + L"[)]*" + c_wspc;
|
||||||
static const wstring c_signedDecFloat = L"[-+]?\\d*(\\d|[.])\\d*";
|
static const wstring c_signedDecFloat = L"[-+]?\\d*(\\d|[.])\\d*";
|
||||||
|
|
||||||
|
@ -44,8 +45,8 @@ static const array<wregex, 1> standardModePatterns =
|
||||||
};
|
};
|
||||||
static const array<wregex, 2> scientificModePatterns =
|
static const array<wregex, 2> scientificModePatterns =
|
||||||
{
|
{
|
||||||
wregex(c_wspcLParens + c_signedDecFloat + c_wspcRParens),
|
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_wspcRParens),
|
||||||
wregex(c_wspcLParens + c_signedDecFloat + L"[e]([+]|[-])+\\d+" + c_wspcRParens)
|
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + L"[e]([+]|[-])+\\d+" + c_wspcRParens)
|
||||||
};
|
};
|
||||||
static const array<array<wregex, 5>, 4> programmerModePatterns =
|
static const array<array<wregex, 5>, 4> programmerModePatterns =
|
||||||
{ {
|
{ {
|
||||||
|
@ -129,7 +130,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +140,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'=')
|
||||||
|
@ -164,7 +165,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +194,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;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +208,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;
|
||||||
}
|
}
|
||||||
|
@ -402,9 +403,9 @@ pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo
|
||||||
|
|
||||||
wstring CopyPasteManager::SanitizeOperand(const wstring& operand)
|
wstring CopyPasteManager::SanitizeOperand(const wstring& operand)
|
||||||
{
|
{
|
||||||
wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-' };
|
wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-', L'+' };
|
||||||
|
|
||||||
return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, ARRAYSIZE(unWantedChars));
|
return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, static_cast<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)
|
||||||
|
@ -567,3 +568,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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "LocalizationService.h"
|
#include "LocalizationService.h"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
namespace CalculatorApp
|
namespace CalculatorApp
|
||||||
{
|
{
|
||||||
namespace Common
|
namespace Common
|
||||||
|
@ -41,7 +43,7 @@ namespace CalculatorApp
|
||||||
result = GetLocaleInfoEx(m_resolvedName.c_str(),
|
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");
|
||||||
|
@ -51,7 +53,7 @@ namespace CalculatorApp
|
||||||
result = GetLocaleInfoEx(m_resolvedName.c_str(),
|
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");
|
||||||
|
@ -61,7 +63,7 @@ namespace CalculatorApp
|
||||||
result = GetLocaleInfoEx(m_resolvedName.c_str(),
|
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");
|
||||||
|
@ -72,7 +74,7 @@ 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");
|
||||||
|
@ -122,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
|
||||||
|
|
|
@ -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
|
||||||
|
@ -102,7 +103,7 @@ namespace CalculatorApp
|
||||||
g_calculatorProvider(
|
g_calculatorProvider(
|
||||||
L"MicrosoftCalculator",
|
L"MicrosoftCalculator",
|
||||||
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), // Microsoft Telemetry group
|
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), // Microsoft Telemetry group
|
||||||
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }), //Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
|
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }), // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
|
||||||
m_appLaunchActivity{ nullptr }
|
m_appLaunchActivity{ nullptr }
|
||||||
{
|
{
|
||||||
// initialize the function array
|
// initialize the function array
|
||||||
|
@ -481,9 +482,9 @@ namespace CalculatorApp
|
||||||
LogTelemetryEvent(EVENT_NAME_MEMORY_BODY_OPENED, fields);
|
LogTelemetryEvent(EVENT_NAME_MEMORY_BODY_OPENED, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
//If calculator is launched in any mode other than standard then this call will come which is not intended. But there is no way to avoid it.
|
// If calculator is launched in any mode other than standard then this call will come which is not intended. But there is no way to avoid it.
|
||||||
//So don't use this function to analyze the count of mode change in session instead use CalculatorViewedInSession and ConverterViewedInSession to do that.
|
// So don't use this function to analyze the count of mode change in session instead use CalculatorViewedInSession and ConverterViewedInSession to do that.
|
||||||
//Use of this function is to analyze perf of mode change.
|
// Use of this function is to analyze perf of mode change.
|
||||||
void TraceLogger::LogModeChangeBegin(ViewMode fromMode, ViewMode toMode, int windowId)
|
void TraceLogger::LogModeChangeBegin(ViewMode fromMode, ViewMode toMode, int windowId)
|
||||||
{
|
{
|
||||||
if (!GetTraceLoggingProviderEnabled()) return;
|
if (!GetTraceLoggingProviderEnabled()) return;
|
||||||
|
@ -498,7 +499,7 @@ namespace CalculatorApp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//comment: same as LogModeChangeBegin
|
// comment: same as LogModeChangeBegin
|
||||||
void TraceLogger::LogModeChangeEnd(ViewMode toMode, int windowId) const
|
void TraceLogger::LogModeChangeEnd(ViewMode toMode, int windowId) const
|
||||||
{
|
{
|
||||||
if (!GetTraceLoggingProviderEnabled()) return;
|
if (!GetTraceLoggingProviderEnabled()) return;
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -181,8 +168,8 @@ void DateCalculatorViewModel::UpdateDisplayResult()
|
||||||
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates");
|
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates");
|
||||||
}
|
}
|
||||||
else if ((m_dateDiffResult.year == 0) &&
|
else if ((m_dateDiffResult.year == 0) &&
|
||||||
(m_dateDiffResult.month == 0) &&
|
(m_dateDiffResult.month == 0) &&
|
||||||
(m_dateDiffResult.week == 0))
|
(m_dateDiffResult.week == 0))
|
||||||
{
|
{
|
||||||
IsDiffInDays = true;
|
IsDiffInDays = true;
|
||||||
StrDateDiffResultInDays = L"";
|
StrDateDiffResultInDays = L"";
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -23,8 +23,8 @@ 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);
|
||||||
OBSERVABLE_PROPERTY_RW(int, MonthsOffset);
|
OBSERVABLE_PROPERTY_RW(int, MonthsOffset);
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,37 +30,34 @@ 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
|
||||||
{
|
{
|
||||||
StringReference CalculatorExpression(L"Format_CalculatorExpression");
|
StringReference CalculatorExpression(L"Format_CalculatorExpression");
|
||||||
StringReference CalculatorResults(L"Format_CalculatorResults");
|
StringReference CalculatorResults(L"Format_CalculatorResults");
|
||||||
StringReference CalculatorResults_DecimalSeparator_Announced(L"Format_CalculatorResults_Decimal");
|
StringReference CalculatorResults_DecimalSeparator_Announced(L"Format_CalculatorResults_Decimal");
|
||||||
StringReference HexButton(L"Format_HexButtonValue");
|
StringReference HexButton(L"Format_HexButtonValue");
|
||||||
StringReference DecButton(L"Format_DecButtonValue");
|
StringReference DecButton(L"Format_DecButtonValue");
|
||||||
StringReference OctButton(L"Format_OctButtonValue");
|
StringReference OctButton(L"Format_OctButtonValue");
|
||||||
StringReference BinButton(L"Format_BinButtonValue");
|
StringReference BinButton(L"Format_BinButtonValue");
|
||||||
StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix");
|
StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix");
|
||||||
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
|
StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix");
|
||||||
StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback");
|
StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement");
|
||||||
StringReference MemorySave(L"Format_MemorySave");
|
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
|
||||||
StringReference MemoryItemChanged(L"Format_MemorySlotChanged");
|
StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback");
|
||||||
StringReference MemoryItemCleared(L"Format_MemorySlotCleared");
|
StringReference MemorySave(L"Format_MemorySave");
|
||||||
StringReference MemoryCleared(L"Memory_Cleared");
|
StringReference MemoryItemChanged(L"Format_MemorySlotChanged");
|
||||||
StringReference DisplayCopied(L"Display_Copied");
|
StringReference MemoryItemCleared(L"Format_MemorySlotCleared");
|
||||||
}
|
StringReference MemoryCleared(L"Memory_Cleared");
|
||||||
|
StringReference DisplayCopied(L"Display_Copied");
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardCalculatorViewModel::StandardCalculatorViewModel() :
|
StandardCalculatorViewModel::StandardCalculatorViewModel() :
|
||||||
|
@ -92,7 +89,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);
|
||||||
|
@ -226,6 +225,34 @@ void StandardCalculatorViewModel::SetParenthesisCount(_In_ const wstring& parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement()
|
||||||
|
{
|
||||||
|
String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount);
|
||||||
|
wstring localizedParenthesisCount = parenthesisCount->Data();
|
||||||
|
LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
|
||||||
|
|
||||||
|
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
|
||||||
|
CalculatorResourceKeys::OpenParenthesisCountAutomationFormat,
|
||||||
|
m_localizedOpenParenthesisCountChangedAutomationFormat,
|
||||||
|
localizedParenthesisCount.c_str());
|
||||||
|
|
||||||
|
Announcement = CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(announcement);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardCalculatorViewModel::OnNoRightParenAdded()
|
||||||
|
{
|
||||||
|
SetNoParenAddedNarratorAnnouncement();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardCalculatorViewModel::SetNoParenAddedNarratorAnnouncement()
|
||||||
|
{
|
||||||
|
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
|
||||||
|
CalculatorResourceKeys::NoParenthesisAdded,
|
||||||
|
m_localizedNoRightParenthesisAddedFormat);
|
||||||
|
|
||||||
|
Announcement = CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(announcement);
|
||||||
|
}
|
||||||
|
|
||||||
void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType)
|
void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType)
|
||||||
{
|
{
|
||||||
if (selectedExpressionCommandType == CommandType::OperandCommand)
|
if (selectedExpressionCommandType == CommandType::OperandCommand)
|
||||||
|
@ -483,7 +510,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
|
||||||
|
|
||||||
if (IsOperandTextCompletelySelected)
|
if (IsOperandTextCompletelySelected)
|
||||||
{
|
{
|
||||||
//Clear older text;
|
// Clear older text;
|
||||||
m_selectedExpressionLastData = L"";
|
m_selectedExpressionLastData = L"";
|
||||||
if (ch == L'x')
|
if (ch == L'x')
|
||||||
{
|
{
|
||||||
|
@ -525,6 +552,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)
|
||||||
|
@ -550,8 +578,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::ModeBasic) || (cmdenum == Command::ModeProgrammer) || (cmdenum == Command::ModeScientific)
|
|| (cmdenum == Command::CommandEXP) || (cmdenum == Command::CommandFE) || (cmdenum == Command::ModeBasic) || (cmdenum == Command::ModeProgrammer) || (cmdenum == Command::ModeScientific)
|
||||||
|| (cmdenum == Command::CommandINV) || (cmdenum == Command::CommandCENTR) || (cmdenum == Command::CommandDEG) || (cmdenum == Command::CommandRAD) || (cmdenum == Command::CommandGRAD)
|
|| (cmdenum == Command::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)))
|
||||||
|
@ -624,8 +651,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;
|
||||||
}
|
}
|
||||||
|
@ -1162,10 +1188,10 @@ Array<unsigned char>^ StandardCalculatorViewModel::Serialize()
|
||||||
writer->WriteInt32(data);
|
writer->WriteInt32(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
//For ProgrammerMode
|
// For ProgrammerMode
|
||||||
writer->WriteUInt32(static_cast<UINT32>(CurrentRadixType));
|
writer->WriteUInt32(static_cast<UINT32>(CurrentRadixType));
|
||||||
|
|
||||||
//Serialize commands of calculator manager
|
// Serialize commands of calculator manager
|
||||||
vector<unsigned char> serializedCommand = m_standardCalculatorManager.SerializeCommands();
|
vector<unsigned char> serializedCommand = m_standardCalculatorManager.SerializeCommands();
|
||||||
writer->WriteUInt32(static_cast<UINT32>(serializedCommand.size()));
|
writer->WriteUInt32(static_cast<UINT32>(serializedCommand.size()));
|
||||||
writer->WriteBytes(ref new Array<unsigned char>(serializedCommand.data(), static_cast<unsigned int>(serializedCommand.size())));
|
writer->WriteBytes(ref new Array<unsigned char>(serializedCommand.data(), static_cast<unsigned int>(serializedCommand.size())));
|
||||||
|
@ -1175,7 +1201,7 @@ Array<unsigned char>^ StandardCalculatorViewModel::Serialize()
|
||||||
Utils::SerializeCommandsAndTokens(m_tokens, m_commands, writer);
|
Utils::SerializeCommandsAndTokens(m_tokens, m_commands, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Convert viewmodel data in writer to bytes
|
// Convert viewmodel data in writer to bytes
|
||||||
IBuffer^ buffer = writer->DetachBuffer();
|
IBuffer^ buffer = writer->DetachBuffer();
|
||||||
DataReader^ reader = DataReader::FromBuffer(buffer);
|
DataReader^ reader = DataReader::FromBuffer(buffer);
|
||||||
Platform::Array<unsigned char>^ viewModelDataAsBytes = ref new Array<unsigned char>(buffer->Length);
|
Platform::Array<unsigned char>^ viewModelDataAsBytes = ref new Array<unsigned char>(buffer->Length);
|
||||||
|
@ -1223,7 +1249,7 @@ void StandardCalculatorViewModel::Deserialize(Array<unsigned char>^ state)
|
||||||
m_standardCalculatorManager.DeSerializePrimaryDisplay(serializedPrimaryDisplay);
|
m_standardCalculatorManager.DeSerializePrimaryDisplay(serializedPrimaryDisplay);
|
||||||
|
|
||||||
CurrentRadixType = reader->ReadUInt32();
|
CurrentRadixType = reader->ReadUInt32();
|
||||||
//Read command data and Deserialize
|
// Read command data and Deserialize
|
||||||
UINT32 modeldatalength = reader->ReadUInt32();
|
UINT32 modeldatalength = reader->ReadUInt32();
|
||||||
Array<unsigned char>^ modelDataAsBytes = ref new Array<unsigned char>(modeldatalength);
|
Array<unsigned char>^ modelDataAsBytes = ref new Array<unsigned char>(modeldatalength);
|
||||||
reader->ReadBytes(modelDataAsBytes);
|
reader->ReadBytes(modelDataAsBytes);
|
||||||
|
@ -1242,30 +1268,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1614,7 +1640,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]))
|
||||||
{
|
{
|
||||||
|
@ -1645,7 +1671,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]))
|
||||||
{
|
{
|
||||||
|
@ -1672,7 +1698,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]))
|
||||||
{
|
{
|
||||||
|
@ -1695,7 +1721,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]))
|
||||||
{
|
{
|
||||||
|
@ -1729,7 +1755,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]))
|
||||||
{
|
{
|
||||||
|
@ -1947,7 +1973,7 @@ void StandardCalculatorViewModel::UpdatecommandsInRecordingMode()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//reset all vars
|
// Reset all vars
|
||||||
isDecimal = false;
|
isDecimal = false;
|
||||||
isNegative = false;
|
isNegative = false;
|
||||||
isExpMode = false;
|
isExpMode = false;
|
||||||
|
|
|
@ -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,19 +63,19 @@ 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, 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);
|
||||||
|
@ -276,7 +270,7 @@ namespace CalculatorApp
|
||||||
|
|
||||||
NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate);
|
NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate);
|
||||||
|
|
||||||
//Memory feature related methods. They are internal because they need to called from the MainPage code-behind
|
// Memory feature related methods. They are internal because they need to called from the MainPage code-behind
|
||||||
void OnMemoryButtonPressed();
|
void OnMemoryButtonPressed();
|
||||||
void OnMemoryItemPressed(Platform::Object^ memoryItemPosition);
|
void OnMemoryItemPressed(Platform::Object^ memoryItemPosition);
|
||||||
void OnMemoryAdd(Platform::Object^ memoryItemPosition);
|
void OnMemoryAdd(Platform::Object^ memoryItemPosition);
|
||||||
|
@ -290,6 +284,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);
|
||||||
|
@ -337,6 +334,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;
|
||||||
|
|
|
@ -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,48 +53,40 @@ 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");
|
||||||
StringReference ValueToFormat(L"Format_ValueTo");
|
StringReference ValueToFormat(L"Format_ValueTo");
|
||||||
StringReference ConversionResultFormat(L"Format_ConversionResult");
|
StringReference ConversionResultFormat(L"Format_ConversionResult");
|
||||||
StringReference InputUnit_Name(L"InputUnit_Name");
|
StringReference InputUnit_Name(L"InputUnit_Name");
|
||||||
StringReference OutputUnit_Name(L"OutputUnit_Name");
|
StringReference OutputUnit_Name(L"OutputUnit_Name");
|
||||||
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
|
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
|
||||||
StringReference UpdatingCurrencyRates(L"UpdatingCurrencyRates");
|
StringReference UpdatingCurrencyRates(L"UpdatingCurrencyRates");
|
||||||
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) :
|
||||||
|
@ -202,12 +194,10 @@ 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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +474,7 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object^ parameter)
|
||||||
NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter);
|
NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter);
|
||||||
UCM::Command command = CommandFromButtonId(numOpEnum);
|
UCM::Command command = CommandFromButtonId(numOpEnum);
|
||||||
|
|
||||||
//Don't clear the display if combo box is open and escape is pressed
|
// Don't clear the display if combo box is open and escape is pressed
|
||||||
if (command == UCM::Command::Clear && IsDropDownOpen)
|
if (command == UCM::Command::Clear && IsDropDownOpen)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -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,10 +638,8 @@ 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)
|
||||||
|
@ -674,7 +667,7 @@ void UnitConverterViewModel::Deserialize(Platform::String^ state)
|
||||||
RaisePropertyChanged(nullptr); // Update since all props have been updated.
|
RaisePropertyChanged(nullptr); // Update since all props have been updated.
|
||||||
}
|
}
|
||||||
|
|
||||||
//Saving User Preferences of Category and Associated-Units across Sessions.
|
// Saving User Preferences of Category and Associated-Units across Sessions.
|
||||||
void UnitConverterViewModel::SaveUserPreferences()
|
void UnitConverterViewModel::SaveUserPreferences()
|
||||||
{
|
{
|
||||||
if (UnitsAreValid())
|
if (UnitsAreValid())
|
||||||
|
@ -695,7 +688,7 @@ void UnitConverterViewModel::SaveUserPreferences()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Restoring User Preferences of Category and Associated-Units.
|
// Restoring User Preferences of Category and Associated-Units.
|
||||||
void UnitConverterViewModel::RestoreUserPreferences()
|
void UnitConverterViewModel::RestoreUserPreferences()
|
||||||
{
|
{
|
||||||
if (!IsCurrencyCurrentCategory)
|
if (!IsCurrencyCurrentCategory)
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -243,7 +224,7 @@ namespace CalculatorApp
|
||||||
Platform::String^ Serialize();
|
Platform::String^ Serialize();
|
||||||
void Deserialize(Platform::String^ state);
|
void Deserialize(Platform::String^ state);
|
||||||
|
|
||||||
//Saving And Restoring User Preferences of Category and Associated-Units across Sessions.
|
// Saving And Restoring User Preferences of Category and Associated-Units across Sessions.
|
||||||
void SaveUserPreferences();
|
void SaveUserPreferences();
|
||||||
void RestoreUserPreferences();
|
void RestoreUserPreferences();
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -9,7 +9,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalcManager", "CalcManager\
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3A5DF651-B8A1-45CA-9135-964A6FC7F5D1}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3A5DF651-B8A1-45CA-9135-964A6FC7F5D1}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
|
||||||
nuget.config = nuget.config
|
nuget.config = nuget.config
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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}"
|
||||||
|
|
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 384 B |
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 484 B |
Before Width: | Height: | Size: 806 B After Width: | Height: | Size: 728 B |
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 456 B After Width: | Height: | Size: 441 B |
Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 470 B |
Before Width: | Height: | Size: 532 B After Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 557 B After Width: | Height: | Size: 503 B |
Before Width: | Height: | Size: 683 B After Width: | Height: | Size: 634 B |
Before Width: | Height: | Size: 485 B After Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 524 B After Width: | Height: | Size: 331 B |
Before Width: | Height: | Size: 577 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 690 B After Width: | Height: | Size: 484 B |
Before Width: | Height: | Size: 996 B After Width: | Height: | Size: 728 B |
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 384 B After Width: | Height: | Size: 193 B |
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 262 B |
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 284 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 303 B |
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 558 B After Width: | Height: | Size: 370 B |
Before Width: | Height: | Size: 630 B After Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 665 B After Width: | Height: | Size: 471 B |
Before Width: | Height: | Size: 707 B After Width: | Height: | Size: 506 B |
Before Width: | Height: | Size: 737 B After Width: | Height: | Size: 507 B |
Before Width: | Height: | Size: 867 B After Width: | Height: | Size: 639 B |
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 384 B After Width: | Height: | Size: 193 B |
Before Width: | Height: | Size: 384 B After Width: | Height: | Size: 193 B |
Before Width: | Height: | Size: 384 B After Width: | Height: | Size: 193 B |
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 234 B |