Allow users to paste expressions with ^or % (#682)
This commit is contained in:
		@@ -17,7 +17,10 @@ using namespace Windows::ApplicationModel::DataTransfer;
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
String
 | 
			
		||||
    ^ CopyPasteManager::ValidatePasteExpression(
 | 
			
		||||
String ^ CopyPasteManager::ValidatePasteExpression(
 | 
			
		||||
        String ^ pastedText,
 | 
			
		||||
        ViewMode mode,
 | 
			
		||||
        CategoryGroupType modeType,
 | 
			
		||||
@@ -165,12 +167,29 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
 | 
			
		||||
    bool isPreviousOpenParen = false;
 | 
			
		||||
    bool isPreviousOperator = false;
 | 
			
		||||
 | 
			
		||||
    wstring validCharacterSet;
 | 
			
		||||
    switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
    case ViewMode::Standard:
 | 
			
		||||
        validCharacterSet = c_validStandardCharacterSet;
 | 
			
		||||
        break;
 | 
			
		||||
    case ViewMode::Scientific:
 | 
			
		||||
        validCharacterSet = c_validScientificCharacterSet;
 | 
			
		||||
        break;
 | 
			
		||||
    case ViewMode::Programmer:
 | 
			
		||||
        validCharacterSet = c_validProgrammerCharacterSet;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        validCharacterSet = c_validBasicCharacterSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This will have the exponent length
 | 
			
		||||
    size_t expLength = 0;
 | 
			
		||||
    for (size_t i = 0; i < pasteExpression.length(); i++)
 | 
			
		||||
    {
 | 
			
		||||
        wchar_t currentChar = pasteExpression.at(i);
 | 
			
		||||
        // if the current character is not a valid one don't process it
 | 
			
		||||
        if (c_validCharacterSet.find(pasteExpression.at(i)) == wstring_view::npos)
 | 
			
		||||
        if (validCharacterSet.find(currentChar) == wstring_view::npos)
 | 
			
		||||
        {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
@@ -182,9 +201,9 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
 | 
			
		||||
            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++;
 | 
			
		||||
 | 
			
		||||
@@ -196,16 +215,19 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
 | 
			
		||||
                    return operands;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            isPreviousOperator = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((mode != ViewMode::Programmer) && (pasteExpression.at(i) == L'e'))
 | 
			
		||||
        else if (currentChar == L'e')
 | 
			
		||||
        {
 | 
			
		||||
            if (mode != ViewMode::Programmer)
 | 
			
		||||
            {
 | 
			
		||||
                startExpCounting = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        if (((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-') || (pasteExpression.at(i) == L'*') || (pasteExpression.at(i) == L'/')))
 | 
			
		||||
            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'-'))
 | 
			
		||||
            if (currentChar == L'+' || currentChar == L'-')
 | 
			
		||||
            {
 | 
			
		||||
                // don't break the expression into operands if the encountered character corresponds to sign command(+-)
 | 
			
		||||
                if (isPreviousOpenParen || startOfExpression || isPreviousOperator
 | 
			
		||||
 
 | 
			
		||||
@@ -953,6 +953,20 @@ NumbersAndOperatorsEnum StandardCalculatorViewModel::MapCharacterToButtonId(cons
 | 
			
		||||
        mappedValue = NumbersAndOperatorsEnum::Divide;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case '^':
 | 
			
		||||
        if (IsScientific)
 | 
			
		||||
        {
 | 
			
		||||
            mappedValue = NumbersAndOperatorsEnum::XPowerY;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case '%':
 | 
			
		||||
        if (IsScientific || IsProgrammer)
 | 
			
		||||
        {
 | 
			
		||||
            mappedValue = NumbersAndOperatorsEnum::Mod;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case '=':
 | 
			
		||||
        mappedValue = NumbersAndOperatorsEnum::Equals;
 | 
			
		||||
        break;
 | 
			
		||||
 
 | 
			
		||||
@@ -630,7 +630,8 @@ namespace CalculatorUnitTests
 | 
			
		||||
                                     L"xyz",         L"ABab",
 | 
			
		||||
                                     L"e+234",       L"12345678912345678" /*boundary condition: greater than 16 digits*/,
 | 
			
		||||
                                     L"SIN(2)",      L"2+2==",
 | 
			
		||||
                                     L"2=+2" };
 | 
			
		||||
                                     L"2=+2",        L"2%2",
 | 
			
		||||
                                     L"10^2" };
 | 
			
		||||
 | 
			
		||||
        ASSERT_POSITIVE_TESTCASES(ValidateStandardPasteExpression, positiveInput);
 | 
			
		||||
        ASSERT_NEGATIVE_TESTCASES(ValidateStandardPasteExpression, negativeInput);
 | 
			
		||||
@@ -668,7 +669,11 @@ namespace CalculatorUnitTests
 | 
			
		||||
                                     "-(432+3232)",
 | 
			
		||||
                                     "-(+(-3213)+(-2312))",
 | 
			
		||||
                                     "-(-(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",
 | 
			
		||||
                                     L"xyz",
 | 
			
		||||
                                     L"ABab",
 | 
			
		||||
@@ -710,7 +715,10 @@ namespace CalculatorUnitTests
 | 
			
		||||
                                          L"1234ul",
 | 
			
		||||
                                          L"1234ULL",
 | 
			
		||||
                                          L"2+2=",
 | 
			
		||||
                                          L"2+2=   " };
 | 
			
		||||
                                          L"2+2=   ",
 | 
			
		||||
                                          L"A4C3%12",
 | 
			
		||||
                                          L"1233%AB",
 | 
			
		||||
                                          L"FFC1%F2" };
 | 
			
		||||
        String ^ qwordNegativeInput[] = { L"+123",
 | 
			
		||||
                                          L"1.23" /*floating number*/,
 | 
			
		||||
                                          L"1''2",
 | 
			
		||||
@@ -906,7 +914,8 @@ namespace CalculatorUnitTests
 | 
			
		||||
                                          L"1234ul",
 | 
			
		||||
                                          L"1234ULL",
 | 
			
		||||
                                          L"2+2=",
 | 
			
		||||
                                          L"2+2=   " };
 | 
			
		||||
                                          L"2+2=   ",
 | 
			
		||||
                                          L"823%21" };
 | 
			
		||||
        String ^ qwordNegativeInput[] = { L"1.23",
 | 
			
		||||
                                          L"1''2",
 | 
			
		||||
                                          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",
 | 
			
		||||
                                          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",
 | 
			
		||||
                                          L"1.23",
 | 
			
		||||
                                          L"1''2",
 | 
			
		||||
@@ -1084,7 +1093,8 @@ namespace CalculatorUnitTests
 | 
			
		||||
                                          L"1234uu",
 | 
			
		||||
                                          L"1234ulll",
 | 
			
		||||
                                          L"2+2==",
 | 
			
		||||
                                          L"2=+2" };
 | 
			
		||||
                                          L"2=+2",
 | 
			
		||||
                                          L"89%12"};
 | 
			
		||||
 | 
			
		||||
        ASSERT_POSITIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordPositiveInput);
 | 
			
		||||
        ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordNegativeInput);
 | 
			
		||||
@@ -1217,7 +1227,8 @@ namespace CalculatorUnitTests
 | 
			
		||||
                                          L"1111ULL",
 | 
			
		||||
                                          L"1010101010101010101010101011110110100100101010101001010101001010" /*boundary condition: max allowed digits 64*/,
 | 
			
		||||
                                          L"1+10=",
 | 
			
		||||
                                          L"1+10=   " };
 | 
			
		||||
                                          L"1+10=   ",
 | 
			
		||||
                                          L"1001%10" };
 | 
			
		||||
        String ^ qwordNegativeInput[] = {
 | 
			
		||||
            L"+10101",
 | 
			
		||||
            L"1.01",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user