Allow users to paste expressions with ^or % (#682)
This commit is contained in:
parent
00064fba11
commit
b97046ad67
@ -17,7 +17,10 @@ using namespace Windows::ApplicationModel::DataTransfer;
|
|||||||
|
|
||||||
String ^ CopyPasteManager::supportedFormats[] = { StandardDataFormats::Text };
|
String ^ CopyPasteManager::supportedFormats[] = { StandardDataFormats::Text };
|
||||||
|
|
||||||
static constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" };
|
static const wstring c_validBasicCharacterSet = L"0123456789+-.e";
|
||||||
|
static const wstring c_validStandardCharacterSet = c_validBasicCharacterSet + L"*/";
|
||||||
|
static const wstring c_validScientificCharacterSet = c_validStandardCharacterSet + L"()^%";
|
||||||
|
static const wstring c_validProgrammerCharacterSet = c_validStandardCharacterSet + L"()%abcdfABCDEF";
|
||||||
|
|
||||||
// The below values can not be "constexpr"-ed,
|
// The below values can not be "constexpr"-ed,
|
||||||
// as both wstring_view and wchar[] can not be concatenated
|
// as both wstring_view and wchar[] can not be concatenated
|
||||||
@ -102,8 +105,7 @@ String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode
|
|||||||
|
|
||||||
// return "NoOp" if pastedText is invalid else return pastedText
|
// return "NoOp" if pastedText is invalid else return pastedText
|
||||||
|
|
||||||
String
|
String ^ CopyPasteManager::ValidatePasteExpression(
|
||||||
^ CopyPasteManager::ValidatePasteExpression(
|
|
||||||
String ^ pastedText,
|
String ^ pastedText,
|
||||||
ViewMode mode,
|
ViewMode mode,
|
||||||
CategoryGroupType modeType,
|
CategoryGroupType modeType,
|
||||||
@ -165,12 +167,29 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
|
|||||||
bool isPreviousOpenParen = false;
|
bool isPreviousOpenParen = false;
|
||||||
bool isPreviousOperator = false;
|
bool isPreviousOperator = false;
|
||||||
|
|
||||||
|
wstring validCharacterSet;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ViewMode::Standard:
|
||||||
|
validCharacterSet = c_validStandardCharacterSet;
|
||||||
|
break;
|
||||||
|
case ViewMode::Scientific:
|
||||||
|
validCharacterSet = c_validScientificCharacterSet;
|
||||||
|
break;
|
||||||
|
case ViewMode::Programmer:
|
||||||
|
validCharacterSet = c_validProgrammerCharacterSet;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
validCharacterSet = c_validBasicCharacterSet;
|
||||||
|
}
|
||||||
|
|
||||||
// This will have the exponent length
|
// This will have the exponent length
|
||||||
size_t expLength = 0;
|
size_t expLength = 0;
|
||||||
for (size_t i = 0; i < pasteExpression.length(); i++)
|
for (size_t i = 0; i < pasteExpression.length(); i++)
|
||||||
{
|
{
|
||||||
|
wchar_t currentChar = pasteExpression.at(i);
|
||||||
// if the current character is not a valid one don't process it
|
// if the current character is not a valid one don't process it
|
||||||
if (c_validCharacterSet.find(pasteExpression.at(i)) == wstring_view::npos)
|
if (validCharacterSet.find(currentChar) == wstring_view::npos)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -182,9 +201,9 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
|
|||||||
return operands;
|
return operands;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startExpCounting)
|
if (currentChar >= L'0' && currentChar <= L'9')
|
||||||
{
|
{
|
||||||
if ((pasteExpression.at(i) >= L'0') && (pasteExpression.at(i) <= L'9'))
|
if (startExpCounting)
|
||||||
{
|
{
|
||||||
expLength++;
|
expLength++;
|
||||||
|
|
||||||
@ -196,16 +215,19 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
|
|||||||
return operands;
|
return operands;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
isPreviousOperator = false;
|
||||||
}
|
}
|
||||||
|
else if (currentChar == L'e')
|
||||||
if ((mode != ViewMode::Programmer) && (pasteExpression.at(i) == L'e'))
|
|
||||||
{
|
{
|
||||||
startExpCounting = true;
|
if (mode != ViewMode::Programmer)
|
||||||
|
{
|
||||||
|
startExpCounting = true;
|
||||||
|
}
|
||||||
|
isPreviousOperator = false;
|
||||||
}
|
}
|
||||||
|
else if (currentChar == L'+' || currentChar == L'-' || currentChar == L'*' || currentChar == L'/' || currentChar == L'^' || currentChar == L'%')
|
||||||
if (((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-') || (pasteExpression.at(i) == L'*') || (pasteExpression.at(i) == L'/')))
|
|
||||||
{
|
{
|
||||||
if ((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-'))
|
if (currentChar == L'+' || currentChar == L'-')
|
||||||
{
|
{
|
||||||
// don't break the expression into operands if the encountered character corresponds to sign command(+-)
|
// don't break the expression into operands if the encountered character corresponds to sign command(+-)
|
||||||
if (isPreviousOpenParen || startOfExpression || isPreviousOperator
|
if (isPreviousOpenParen || startOfExpression || isPreviousOperator
|
||||||
|
@ -953,6 +953,20 @@ NumbersAndOperatorsEnum StandardCalculatorViewModel::MapCharacterToButtonId(cons
|
|||||||
mappedValue = NumbersAndOperatorsEnum::Divide;
|
mappedValue = NumbersAndOperatorsEnum::Divide;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '^':
|
||||||
|
if (IsScientific)
|
||||||
|
{
|
||||||
|
mappedValue = NumbersAndOperatorsEnum::XPowerY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '%':
|
||||||
|
if (IsScientific || IsProgrammer)
|
||||||
|
{
|
||||||
|
mappedValue = NumbersAndOperatorsEnum::Mod;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
mappedValue = NumbersAndOperatorsEnum::Equals;
|
mappedValue = NumbersAndOperatorsEnum::Equals;
|
||||||
break;
|
break;
|
||||||
|
@ -630,7 +630,8 @@ namespace CalculatorUnitTests
|
|||||||
L"xyz", L"ABab",
|
L"xyz", L"ABab",
|
||||||
L"e+234", L"12345678912345678" /*boundary condition: greater than 16 digits*/,
|
L"e+234", L"12345678912345678" /*boundary condition: greater than 16 digits*/,
|
||||||
L"SIN(2)", L"2+2==",
|
L"SIN(2)", L"2+2==",
|
||||||
L"2=+2" };
|
L"2=+2", L"2%2",
|
||||||
|
L"10^2" };
|
||||||
|
|
||||||
ASSERT_POSITIVE_TESTCASES(ValidateStandardPasteExpression, positiveInput);
|
ASSERT_POSITIVE_TESTCASES(ValidateStandardPasteExpression, positiveInput);
|
||||||
ASSERT_NEGATIVE_TESTCASES(ValidateStandardPasteExpression, negativeInput);
|
ASSERT_NEGATIVE_TESTCASES(ValidateStandardPasteExpression, negativeInput);
|
||||||
@ -668,7 +669,11 @@ namespace CalculatorUnitTests
|
|||||||
"-(432+3232)",
|
"-(432+3232)",
|
||||||
"-(+(-3213)+(-2312))",
|
"-(+(-3213)+(-2312))",
|
||||||
"-(-(432+3232))",
|
"-(-(432+3232))",
|
||||||
L"1.2e23"/*unsigned exponent*/ };
|
L"1.2e23"/*unsigned exponent*/,
|
||||||
|
L"12^2",
|
||||||
|
L"-12.12^-2",
|
||||||
|
L"61%99"
|
||||||
|
L"-6.1%99" };
|
||||||
String ^ negativeInput[] = { L"abcdef",
|
String ^ negativeInput[] = { L"abcdef",
|
||||||
L"xyz",
|
L"xyz",
|
||||||
L"ABab",
|
L"ABab",
|
||||||
@ -710,7 +715,10 @@ namespace CalculatorUnitTests
|
|||||||
L"1234ul",
|
L"1234ul",
|
||||||
L"1234ULL",
|
L"1234ULL",
|
||||||
L"2+2=",
|
L"2+2=",
|
||||||
L"2+2= " };
|
L"2+2= ",
|
||||||
|
L"A4C3%12",
|
||||||
|
L"1233%AB",
|
||||||
|
L"FFC1%F2" };
|
||||||
String ^ qwordNegativeInput[] = { L"+123",
|
String ^ qwordNegativeInput[] = { L"+123",
|
||||||
L"1.23" /*floating number*/,
|
L"1.23" /*floating number*/,
|
||||||
L"1''2",
|
L"1''2",
|
||||||
@ -906,7 +914,8 @@ namespace CalculatorUnitTests
|
|||||||
L"1234ul",
|
L"1234ul",
|
||||||
L"1234ULL",
|
L"1234ULL",
|
||||||
L"2+2=",
|
L"2+2=",
|
||||||
L"2+2= " };
|
L"2+2= ",
|
||||||
|
L"823%21" };
|
||||||
String ^ qwordNegativeInput[] = { L"1.23",
|
String ^ qwordNegativeInput[] = { L"1.23",
|
||||||
L"1''2",
|
L"1''2",
|
||||||
L"'123",
|
L"'123",
|
||||||
@ -1060,7 +1069,7 @@ namespace CalculatorUnitTests
|
|||||||
{
|
{
|
||||||
String ^ qwordPositiveInput[] = { L"123", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85",
|
String ^ qwordPositiveInput[] = { L"123", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85",
|
||||||
L"\n 1+\n2 ", L"1\"2", L"(123)+(456)", L"0t1234", L"0T1234", L"0o1234", L"0O1234", L"1234u",
|
L"\n 1+\n2 ", L"1\"2", L"(123)+(456)", L"0t1234", L"0T1234", L"0o1234", L"0O1234", L"1234u",
|
||||||
L"1234ul", L"1234ULL", L"2+2=", L"2+2= " };
|
L"1234ul", L"1234ULL", L"2+2=", L"2+2= ", L"127%71" };
|
||||||
String ^ qwordNegativeInput[] = { L"+123",
|
String ^ qwordNegativeInput[] = { L"+123",
|
||||||
L"1.23",
|
L"1.23",
|
||||||
L"1''2",
|
L"1''2",
|
||||||
@ -1084,7 +1093,8 @@ namespace CalculatorUnitTests
|
|||||||
L"1234uu",
|
L"1234uu",
|
||||||
L"1234ulll",
|
L"1234ulll",
|
||||||
L"2+2==",
|
L"2+2==",
|
||||||
L"2=+2" };
|
L"2=+2",
|
||||||
|
L"89%12"};
|
||||||
|
|
||||||
ASSERT_POSITIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordPositiveInput);
|
ASSERT_POSITIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordPositiveInput);
|
||||||
ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordNegativeInput);
|
ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordNegativeInput);
|
||||||
@ -1217,7 +1227,8 @@ namespace CalculatorUnitTests
|
|||||||
L"1111ULL",
|
L"1111ULL",
|
||||||
L"1010101010101010101010101011110110100100101010101001010101001010" /*boundary condition: max allowed digits 64*/,
|
L"1010101010101010101010101011110110100100101010101001010101001010" /*boundary condition: max allowed digits 64*/,
|
||||||
L"1+10=",
|
L"1+10=",
|
||||||
L"1+10= " };
|
L"1+10= ",
|
||||||
|
L"1001%10" };
|
||||||
String ^ qwordNegativeInput[] = {
|
String ^ qwordNegativeInput[] = {
|
||||||
L"+10101",
|
L"+10101",
|
||||||
L"1.01",
|
L"1.01",
|
||||||
|
Loading…
Reference in New Issue
Block a user