Improve error handling by displaying an error message (#1075)
* wire up error messages * more errors * fix crash on render error * Always show copy and cut * PR comments * Fix spelling
This commit is contained in:
		@@ -11,6 +11,7 @@ using namespace Graphing;
 | 
			
		||||
using namespace Platform;
 | 
			
		||||
using namespace Platform::Collections;
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Windows::ApplicationModel::Resources;
 | 
			
		||||
using namespace Windows::UI;
 | 
			
		||||
using namespace Windows::UI::Xaml;
 | 
			
		||||
using namespace Windows::Foundation::Collections;
 | 
			
		||||
@@ -36,7 +37,7 @@ namespace CalculatorApp::ViewModel
 | 
			
		||||
        : m_AnalysisErrorVisible{ false }
 | 
			
		||||
        , m_FunctionLabelIndex{ functionLabelIndex }
 | 
			
		||||
        , m_KeyGraphFeaturesItems{ ref new Vector<KeyGraphFeaturesItem ^>() }
 | 
			
		||||
        , m_resourceLoader{ Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView() }
 | 
			
		||||
        , m_resourceLoader{ ::ResourceLoader::GetForCurrentView() }
 | 
			
		||||
    {
 | 
			
		||||
        if (equation == nullptr)
 | 
			
		||||
        {
 | 
			
		||||
@@ -72,11 +73,14 @@ namespace CalculatorApp::ViewModel
 | 
			
		||||
        AddKeyGraphFeature(m_resourceLoader->GetString(L"YIntercept"), graphEquation->YIntercept, m_resourceLoader->GetString(L"KGFYInterceptNone"));
 | 
			
		||||
        AddKeyGraphFeature(m_resourceLoader->GetString(L"Minima"), graphEquation->Minima, m_resourceLoader->GetString(L"KGFMinimaNone"));
 | 
			
		||||
        AddKeyGraphFeature(m_resourceLoader->GetString(L"Maxima"), graphEquation->Maxima, m_resourceLoader->GetString(L"KGFMaximaNone"));
 | 
			
		||||
        AddKeyGraphFeature(m_resourceLoader->GetString(L"InflectionPoints"), graphEquation->InflectionPoints, m_resourceLoader->GetString(L"KGFInflectionPointsNone"));
 | 
			
		||||
        AddKeyGraphFeature(
 | 
			
		||||
            m_resourceLoader->GetString(L"InflectionPoints"), graphEquation->InflectionPoints, m_resourceLoader->GetString(L"KGFInflectionPointsNone"));
 | 
			
		||||
        AddKeyGraphFeature(
 | 
			
		||||
            m_resourceLoader->GetString(L"VerticalAsymptotes"), graphEquation->VerticalAsymptotes, m_resourceLoader->GetString(L"KGFVerticalAsymptotesNone"));
 | 
			
		||||
        AddKeyGraphFeature(
 | 
			
		||||
            m_resourceLoader->GetString(L"HorizontalAsymptotes"), graphEquation->HorizontalAsymptotes, m_resourceLoader->GetString(L"KGFHorizontalAsymptotesNone"));
 | 
			
		||||
            m_resourceLoader->GetString(L"HorizontalAsymptotes"),
 | 
			
		||||
            graphEquation->HorizontalAsymptotes,
 | 
			
		||||
            m_resourceLoader->GetString(L"KGFHorizontalAsymptotesNone"));
 | 
			
		||||
        AddKeyGraphFeature(
 | 
			
		||||
            m_resourceLoader->GetString(L"ObliqueAsymptotes"), graphEquation->ObliqueAsymptotes, m_resourceLoader->GetString(L"KGFObliqueAsymptotesNone"));
 | 
			
		||||
        AddParityKeyGraphFeature(graphEquation);
 | 
			
		||||
@@ -299,4 +303,154 @@ namespace CalculatorApp::ViewModel
 | 
			
		||||
 | 
			
		||||
        KeyGraphFeaturesItems->Append(tooComplexItem);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String ^ EquationViewModel::EquationErrorText(ErrorType errorType, int errorCode)
 | 
			
		||||
    {
 | 
			
		||||
        auto resLoader = ResourceLoader::GetForCurrentView();
 | 
			
		||||
        if (errorType == ::ErrorType::Evaluation)
 | 
			
		||||
        {
 | 
			
		||||
            switch (static_cast<EvaluationErrorCode>(errorCode))
 | 
			
		||||
            {
 | 
			
		||||
            case (EvaluationErrorCode::Overflow):
 | 
			
		||||
                return resLoader->GetString(L"Overflow");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::RequireRadiansMode):
 | 
			
		||||
                return resLoader->GetString(L"RequireRadiansMode");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::TooComplexToSolve):
 | 
			
		||||
                return resLoader->GetString(L"TooComplexToSolve");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::RequireDegreesMode):
 | 
			
		||||
                return resLoader->GetString(L"RequireDegreesMode");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::FactorialInvalidArgument):
 | 
			
		||||
            case (EvaluationErrorCode::Factorial2InvalidArgument):
 | 
			
		||||
                return resLoader->GetString(L"FactorialInvalidArgument");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::FactorialCannotPerformOnLargeNumber):
 | 
			
		||||
                return resLoader->GetString(L"FactorialCannotPerformOnLargeNumber");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::ModuloCannotPerformOnFloat):
 | 
			
		||||
                return resLoader->GetString(L"ModuloCannotPerformOnFloat");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::EquationTooComplexToSolve):
 | 
			
		||||
            case (EvaluationErrorCode::EquationTooComplexToSolveSymbolic):
 | 
			
		||||
            case (EvaluationErrorCode::EquationTooComplexToPlot):
 | 
			
		||||
            case (EvaluationErrorCode::InequalityTooComplexToSolve):
 | 
			
		||||
            case (EvaluationErrorCode::GE_TooComplexToSolve):
 | 
			
		||||
                return resLoader->GetString(L"TooComplexToSolve");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::EquationHasNoSolution):
 | 
			
		||||
            case (EvaluationErrorCode::InequalityHasNoSolution):
 | 
			
		||||
                return resLoader->GetString(L"EquationHasNoSolution");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::DivideByZero):
 | 
			
		||||
                return resLoader->GetString(L"DivideByZero");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::MutuallyExclusiveConditions):
 | 
			
		||||
                return resLoader->GetString(L"MutuallyExclusiveConditions");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::OutOfDomain):
 | 
			
		||||
                return resLoader->GetString(L"OutOfDomain");
 | 
			
		||||
                break;
 | 
			
		||||
            case (EvaluationErrorCode::GE_NotSupported):
 | 
			
		||||
                return resLoader->GetString(L"GE_NotSupported");
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return resLoader->GetString(L"GeneralError");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (errorType == ::ErrorType::Syntax)
 | 
			
		||||
        {
 | 
			
		||||
            switch (static_cast<SyntaxErrorCode>(errorCode))
 | 
			
		||||
            {
 | 
			
		||||
            case (SyntaxErrorCode::ParenthesisMismatch):
 | 
			
		||||
                return resLoader->GetString(L"ParenthesisMismatch");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::UnmatchedParenthesis):
 | 
			
		||||
                return resLoader->GetString(L"UnmatchedParenthesis");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::TooManyDecimalPoints):
 | 
			
		||||
                return resLoader->GetString(L"TooManyDecimalPoints");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::DecimalPointWithoutDigits):
 | 
			
		||||
                return resLoader->GetString(L"DecimalPointWithoutDigits");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::UnexpectedEndOfExpression):
 | 
			
		||||
                return resLoader->GetString(L"UnexpectedEndOfExpression");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::UnexpectedToken):
 | 
			
		||||
                return resLoader->GetString(L"UnexpectedToken");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::InvalidToken):
 | 
			
		||||
                return resLoader->GetString(L"InvalidToken");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::TooManyEquals):
 | 
			
		||||
                return resLoader->GetString(L"TooManyEquals");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::EqualWithoutGraphVariable):
 | 
			
		||||
                return resLoader->GetString(L"EqualWithoutGraphVariable");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::InvalidEquationSyntax):
 | 
			
		||||
            case (SyntaxErrorCode::InvalidEquationFormat):
 | 
			
		||||
                return resLoader->GetString(L"InvalidEquationSyntax");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::EmptyExpression):
 | 
			
		||||
                return resLoader->GetString(L"EmptyExpression");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::EqualWithoutEquation):
 | 
			
		||||
                return resLoader->GetString(L"EqualWithoutEquation");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::ExpectParenthesisAfterFunctionName):
 | 
			
		||||
                return resLoader->GetString(L"ExpectParenthesisAfterFunctionName");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::IncorrectNumParameter):
 | 
			
		||||
                return resLoader->GetString(L"IncorrectNumParameter");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::InvalidVariableNameFormat):
 | 
			
		||||
                return resLoader->GetString(L"InvalidVariableNameFormat");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::BracketMismatch):
 | 
			
		||||
                return resLoader->GetString(L"BracketMismatch");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::UnmatchedBracket):
 | 
			
		||||
                return resLoader->GetString(L"UnmatchedBracket");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::CannotUseIInReal):
 | 
			
		||||
                return resLoader->GetString(L"CannotUseIInReal");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::InvalidNumberDigit):
 | 
			
		||||
                return resLoader->GetString(L"InvalidNumberDigit");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::InvalidNumberBase):
 | 
			
		||||
                return resLoader->GetString(L"InvalidNumberBase");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::InvalidVariableSpecification):
 | 
			
		||||
                return resLoader->GetString(L"InvalidVariableSpecification");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::ExpectingLogicalOperands):
 | 
			
		||||
            case (SyntaxErrorCode::ExpectingScalarOperands):
 | 
			
		||||
                return resLoader->GetString(L"ExpectingLogicalOperands");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::CannotUseIndexVarInOpLimits):
 | 
			
		||||
                return resLoader->GetString(L"CannotUseIndexVarInOpLimits");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::CannotUseIndexVarInLimPoint):
 | 
			
		||||
                return resLoader->GetString(L"Overflow");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::CannotUseComplexInfinityInReal):
 | 
			
		||||
                return resLoader->GetString(L"CannotUseComplexInfinityInReal");
 | 
			
		||||
                break;
 | 
			
		||||
            case (SyntaxErrorCode::CannotUseIInInequalitySolving):
 | 
			
		||||
                return resLoader->GetString(L"CannotUseIInInequalitySolving");
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return resLoader->GetString(L"GeneralError");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return resLoader->GetString(L"GeneralError");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -103,6 +103,8 @@ public
 | 
			
		||||
 | 
			
		||||
        void PopulateKeyGraphFeatures(GraphControl::KeyGraphFeaturesInfo ^ info);
 | 
			
		||||
 | 
			
		||||
        static Platform::String ^ EquationErrorText(GraphControl::ErrorType errorType, int errorCode);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        void AddKeyGraphFeature(Platform::String ^ title, Platform::String ^ expression, Platform::String ^ errorString);
 | 
			
		||||
        void AddKeyGraphFeature(
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, EquationButtonContentIndex);
 | 
			
		||||
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, HasError);
 | 
			
		||||
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, IsAddEquationMode);
 | 
			
		||||
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, MathEquation);
 | 
			
		||||
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, ErrorText);
 | 
			
		||||
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, IsEquationLineDisabled);
 | 
			
		||||
 | 
			
		||||
EquationTextBox::EquationTextBox()
 | 
			
		||||
@@ -432,12 +433,12 @@ void EquationTextBox::OnRichEditMenuOpened(Object ^ /*sender*/, Object ^ /*args*
 | 
			
		||||
 | 
			
		||||
    if (m_richEditBox != nullptr && m_cutMenuItem != nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        m_cutMenuItem->IsEnabled = m_richEditBox->TextDocument->CanCopy() && m_richEditBox->TextDocument->Selection->Length > 0;
 | 
			
		||||
        m_cutMenuItem->IsEnabled = m_richEditBox->TextDocument->CanCopy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_richEditBox != nullptr && m_copyMenuItem != nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        m_copyMenuItem->IsEnabled = m_richEditBox->TextDocument->CanCopy() && m_richEditBox->TextDocument->Selection->Length > 0;
 | 
			
		||||
        m_copyMenuItem->IsEnabled = m_richEditBox->TextDocument->CanCopy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_richEditBox != nullptr && m_pasteMenuItem != nullptr)
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ namespace CalculatorApp
 | 
			
		||||
            DEPENDENCY_PROPERTY(Platform::String ^, MathEquation);
 | 
			
		||||
            DEPENDENCY_PROPERTY_WITH_CALLBACK(bool, HasError);
 | 
			
		||||
            DEPENDENCY_PROPERTY_WITH_CALLBACK(bool, IsAddEquationMode);
 | 
			
		||||
            DEPENDENCY_PROPERTY(Platform::String ^, ErrorText);
 | 
			
		||||
            DEPENDENCY_PROPERTY(bool, IsEquationLineDisabled);
 | 
			
		||||
 | 
			
		||||
            PROPERTY_R(bool, HasFocus);
 | 
			
		||||
 
 | 
			
		||||
@@ -4106,7 +4106,163 @@
 | 
			
		||||
    <value>Unable to calculate the range for this function.</value>
 | 
			
		||||
    <comment>Error displayed when Range is not returned from the analyzer.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="equationAnalysisBack.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
 | 
			
		||||
  <data name="Overflow" xml:space="preserve">
 | 
			
		||||
    <value>Overflow (the number is too large)</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the number is too large. To see this error, assign a large number to variable a, then keep doing "a:=a*a" until it happens.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="RequireRadiansMode" xml:space="preserve">
 | 
			
		||||
    <value>Radians mode is required to graph this equation.</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when radians is required.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="TooComplexToSolve" xml:space="preserve">
 | 
			
		||||
    <value>This function is too complex to graph</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the equation is too complex.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="RequireDegreesMode" xml:space="preserve">
 | 
			
		||||
    <value>Degrees mode is required to graph this function</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when degrees is required</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="FactorialInvalidArgument" xml:space="preserve">
 | 
			
		||||
    <value>The factorial function has an invalid argument</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a factorial function has an invalid argument.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="FactorialCannotPerformOnLargeNumber" xml:space="preserve">
 | 
			
		||||
    <value>The factorial function has an argument that is too large to graph</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a factorial has a large n</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="ModuloCannotPerformOnFloat" xml:space="preserve">
 | 
			
		||||
    <value>Modulo can only be used with whole numbers</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when modulo is used with a float.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="EquationHasNoSolution" xml:space="preserve">
 | 
			
		||||
    <value>The equation has no solution</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the equation has no solution.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="DivideByZero" xml:space="preserve">
 | 
			
		||||
    <value>Cannot divide by zero</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a divison by zero occurs.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="MutuallyExclusiveConditions" xml:space="preserve">
 | 
			
		||||
    <value>The equation contains logical conditions that are mutually exclusive</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when mutually exclusive conditions are used.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
    <data name="OutOfDomain" xml:space="preserve">
 | 
			
		||||
    <value>Equation is out of domain</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the equation is out of domain.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
    <data name="GE_NotSupported" xml:space="preserve">
 | 
			
		||||
    <value>Graphing this equation is not supported</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the equation is not supported.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="ParenthesisMismatch" xml:space="preserve">
 | 
			
		||||
    <value>The equation is missing an opening parenthesis</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the equation is missing a (</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="UnmatchedParenthesis" xml:space="preserve">
 | 
			
		||||
    <value>The equation is missing a closing parenthesis</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the equation is missing a )</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="TooManyDecimalPoints" xml:space="preserve">
 | 
			
		||||
    <value>There are too many decimal points in a number</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a number has too many decimals. Ex: 1.2.3</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="DecimalPointWithoutDigits" xml:space="preserve">
 | 
			
		||||
    <value>A decimal point is missing digits</value>
 | 
			
		||||
    <comment>Error that occurs during graphing with a decimal point without digits</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="UnexpectedEndOfExpression" xml:space="preserve">
 | 
			
		||||
    <value>Unexpected end of expression</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the expression ends unexpectedly. Ex: 3-4*</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="UnexpectedToken" xml:space="preserve">
 | 
			
		||||
    <value>Unexpected characters in the expression</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when there is an unexpected token.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="InvalidToken" xml:space="preserve">
 | 
			
		||||
    <value>Invalid characters in the expression</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when there is an invalid token.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="TooManyEquals" xml:space="preserve">
 | 
			
		||||
    <value>There are too many equal signs</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when there are too many equals.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="EqualWithoutGraphVariable" xml:space="preserve">
 | 
			
		||||
    <value>The function must contain at least one x or y variable</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the equation is missing x or y.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="InvalidEquationSyntax" xml:space="preserve">
 | 
			
		||||
    <value>Invalid expression</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when an invalid syntax is used.</comment>
 | 
			
		||||
    </data>
 | 
			
		||||
    <data name="EmptyExpression" xml:space="preserve">
 | 
			
		||||
    <value>The expression is empty</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the expression is empty</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
    <data name="EqualWithoutEquation" xml:space="preserve">
 | 
			
		||||
    <value>Equal was used without an equation</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when equal is used without an equation. Ex: sin(x=y)</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="ExpectParenthesisAfterFunctionName" xml:space="preserve">
 | 
			
		||||
    <value>Parenthesis missing after function name</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when parenthesis are missing after a function.</comment>
 | 
			
		||||
    </data>
 | 
			
		||||
  <data name="IncorrectNumParameter" xml:space="preserve">
 | 
			
		||||
    <value>A mathematical operation has the incorrect number of parameters</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a function has the wrong number of parameters</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="InvalidVariableNameFormat" xml:space="preserve">
 | 
			
		||||
    <value>A variable name is invalid</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a variable name is invalid.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="BracketMismatch" xml:space="preserve">
 | 
			
		||||
    <value>The equation is missing an opening bracket</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a { is missing</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="UnmatchedBracket" xml:space="preserve">
 | 
			
		||||
    <value>The equation is missing a closing bracket</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a } is missing.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="CannotUseIInReal" xml:space="preserve">
 | 
			
		||||
    <value>"i" and "I" cannot be used as variable names</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when i or I is used.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="GeneralError" xml:space="preserve">
 | 
			
		||||
    <value>The equation could not be graphed</value>
 | 
			
		||||
    <comment>General error that occurs during graphing.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="InvalidNumberDigit" xml:space="preserve">
 | 
			
		||||
    <value>The digit could not be resolved for the given base</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when trying to use bases incorrect. Ex: base(2,1020).</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="InvalidNumberBase" xml:space="preserve">
 | 
			
		||||
    <value>The base must be greater than 2 and less than 36</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when the base is out of range.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="InvalidVariableSpecification" xml:space="preserve">
 | 
			
		||||
    <value>A mathematical operation requires one of its paramaters to be a variable</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when a function requires a variable in a particular position. Ex: 2nd argument of deriv.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="ExpectingLogicalOperands" xml:space="preserve">
 | 
			
		||||
    <value>Equation is mixing logical and scalar operands</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when operands are mixed. Such as true and 1.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="CannotUseIndexVarInOpLimits" xml:space="preserve">
 | 
			
		||||
    <value>x or y cannot be used in the upper or lower limits</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when x or y is used in integral upper limits.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="CannotUseIndexVarInLimPoint" xml:space="preserve">
 | 
			
		||||
    <value>x or y cannot be used in the limit point</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when x or y is used in the limit point.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="CannotUseComplexInfinityInReal" xml:space="preserve">
 | 
			
		||||
    <value>Cannot use complex infinity</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when complex infinity is used</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="CannotUseIInInequalitySolving" xml:space="preserve">
 | 
			
		||||
    <value>Cannot use complex numbers in inequalities</value>
 | 
			
		||||
    <comment>Error that occurs during graphing when complex numbers are used in inequalities.</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
    <data name="equationAnalysisBack.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
 | 
			
		||||
    <value>Back</value>
 | 
			
		||||
    <comment>This is the tooltip for the back button in the equation analysis page in the graphing calculator</comment>
 | 
			
		||||
  </data>
 | 
			
		||||
 
 | 
			
		||||
@@ -324,6 +324,7 @@
 | 
			
		||||
                                                <Setter Target="EquationBoxBorder.BorderThickness" Value="1"/>
 | 
			
		||||
                                                <Setter Target="EquationBoxBorder.BorderBrush" Value="{ThemeResource EquationBoxErrorBorderBrush}"/>
 | 
			
		||||
                                                <Setter Target="EquationBoxBorder.Background" Value="{ThemeResource EquationBoxErrorBackgroundBrush}"/>
 | 
			
		||||
                                                <Setter Target="RemoveButton.Visibility" Value="Visible"/>
 | 
			
		||||
                                                <Setter Target="ErrorIcon.Visibility" Value="Visible"/>
 | 
			
		||||
                                            </VisualState.Setters>
 | 
			
		||||
                                        </VisualState>
 | 
			
		||||
@@ -344,7 +345,7 @@
 | 
			
		||||
                                                <Setter Target="ColorChooserButton.Visibility" Value="Collapsed"/>
 | 
			
		||||
                                                <Setter Target="FunctionButton.Visibility" Value="Collapsed"/>
 | 
			
		||||
                                                <Setter Target="RemoveButton.Visibility" Value="Visible"/>
 | 
			
		||||
                                                <Setter Target="ErrorIcon.Visibility" Value="Collapsed"/>
 | 
			
		||||
                                                <Setter Target="ErrorIcon.Visibility" Value="Visible"/>
 | 
			
		||||
                                            </VisualState.Setters>
 | 
			
		||||
                                        </VisualState>
 | 
			
		||||
                                        <VisualState x:Name="Disabled">
 | 
			
		||||
@@ -568,6 +569,7 @@
 | 
			
		||||
                                            <ColumnDefinition Width="Auto"/>
 | 
			
		||||
                                            <ColumnDefinition Width="Auto"/>
 | 
			
		||||
                                            <ColumnDefinition Width="Auto"/>
 | 
			
		||||
                                            <ColumnDefinition Width="Auto"/>
 | 
			
		||||
                                        </Grid.ColumnDefinitions>
 | 
			
		||||
                                        <controls:MathRichEditBox x:Name="MathRichEditBox"
 | 
			
		||||
                                                                  x:Uid="mathRichEditBox"
 | 
			
		||||
@@ -698,7 +700,18 @@
 | 
			
		||||
                                                </ResourceDictionary>
 | 
			
		||||
                                            </ToggleButton.Resources>
 | 
			
		||||
                                        </ToggleButton>
 | 
			
		||||
                                        <Grid x:Name="RemoveButtonPanel" Grid.Column="3">
 | 
			
		||||
                                        <FontIcon x:Name="ErrorIcon"
 | 
			
		||||
                                                  Grid.Column="3"
 | 
			
		||||
                                                  MinWidth="28"
 | 
			
		||||
                                                  VerticalAlignment="Stretch"
 | 
			
		||||
                                                  Foreground="{ThemeResource ButtonForeground}"
 | 
			
		||||
                                                  FontFamily="{ThemeResource SymbolThemeFontFamily}"
 | 
			
		||||
                                                  FontSize="16"
 | 
			
		||||
                                                  AutomationProperties.AccessibilityView="Raw"
 | 
			
		||||
                                                  Glyph=""
 | 
			
		||||
                                                  ToolTipService.ToolTip="{TemplateBinding ErrorText}"
 | 
			
		||||
                                                  Visibility="Collapsed"/>
 | 
			
		||||
                                        <Grid x:Name="RemoveButtonPanel" Grid.Column="4">
 | 
			
		||||
                                            <Button x:Name="RemoveButton"
 | 
			
		||||
                                                    x:Uid="removeButton"
 | 
			
		||||
                                                    MinWidth="34"
 | 
			
		||||
@@ -737,7 +750,7 @@
 | 
			
		||||
                                            </Button>
 | 
			
		||||
                                        </Grid>
 | 
			
		||||
                                        <Button x:Name="DeleteButton"
 | 
			
		||||
                                                Grid.Column="3"
 | 
			
		||||
                                                Grid.Column="4"
 | 
			
		||||
                                                MinWidth="34"
 | 
			
		||||
                                                Margin="1,2"
 | 
			
		||||
                                                VerticalAlignment="Stretch"
 | 
			
		||||
@@ -774,16 +787,6 @@
 | 
			
		||||
                                                </ResourceDictionary>
 | 
			
		||||
                                            </Button.Resources>
 | 
			
		||||
                                        </Button>
 | 
			
		||||
                                        <FontIcon x:Name="ErrorIcon"
 | 
			
		||||
                                                  Grid.Column="3"
 | 
			
		||||
                                                  MinWidth="28"
 | 
			
		||||
                                                  VerticalAlignment="Stretch"
 | 
			
		||||
                                                  Foreground="{ThemeResource ButtonForeground}"
 | 
			
		||||
                                                  FontFamily="{ThemeResource SymbolThemeFontFamily}"
 | 
			
		||||
                                                  FontSize="16"
 | 
			
		||||
                                                  AutomationProperties.AccessibilityView="Raw"
 | 
			
		||||
                                                  Glyph=""
 | 
			
		||||
                                                  Visibility="Collapsed"/>
 | 
			
		||||
                                    </Grid>
 | 
			
		||||
                                </Border>
 | 
			
		||||
                            </Grid>
 | 
			
		||||
@@ -823,7 +826,8 @@
 | 
			
		||||
                </ListView.ItemContainerStyle>
 | 
			
		||||
                <ListView.ItemTemplate>
 | 
			
		||||
                    <DataTemplate x:DataType="vm:EquationViewModel">
 | 
			
		||||
                        <controls:EquationTextBox x:Uid="EquationInputButton"
 | 
			
		||||
                        <controls:EquationTextBox x:Name="EquationInputButton"
 | 
			
		||||
                                                  x:Uid="EquationInputButton"
 | 
			
		||||
                                                  Margin="1,0,1,2"
 | 
			
		||||
                                                  Style="{StaticResource EquationTextBoxStyle}"
 | 
			
		||||
                                                  DataContext="{x:Bind Mode=OneWay}"
 | 
			
		||||
@@ -833,6 +837,7 @@
 | 
			
		||||
                                                  EquationColor="{x:Bind local:EquationInputArea.ToSolidColorBrush(LineColor), Mode=OneWay}"
 | 
			
		||||
                                                  EquationFormatRequested="EquationTextBox_EquationFormatRequested"
 | 
			
		||||
                                                  EquationSubmitted="EquationTextBox_Submitted"
 | 
			
		||||
                                                  ErrorText="{x:Bind vm:EquationViewModel.EquationErrorText(GraphEquation.GraphErrorType, GraphEquation.GraphErrorCode), Mode=OneWay}"
 | 
			
		||||
                                                  GotFocus="EquationTextBox_GotFocus"
 | 
			
		||||
                                                  HasError="{x:Bind GraphEquation.HasGraphError, Mode=OneWay}"
 | 
			
		||||
                                                  IsAddEquationMode="{x:Bind IsLastItemInList, Mode=OneWay}"
 | 
			
		||||
 
 | 
			
		||||
@@ -297,6 +297,8 @@ namespace GraphControl
 | 
			
		||||
    {
 | 
			
		||||
        optional<vector<shared_ptr<IEquation>>> initResult = nullopt;
 | 
			
		||||
        bool successful = false;
 | 
			
		||||
        m_errorCode = 0;
 | 
			
		||||
        m_errorType = 0;
 | 
			
		||||
 | 
			
		||||
        if (m_renderMain && m_graph != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
@@ -345,7 +347,7 @@ namespace GraphControl
 | 
			
		||||
                    parsableEquation += s_getGraphClosingTags;
 | 
			
		||||
 | 
			
		||||
                    // Wire up the corresponding error to an error message in the UI at some point
 | 
			
		||||
                    if (!(expr = m_solver->ParseInput(parsableEquation)))
 | 
			
		||||
                    if (!(expr = m_solver->ParseInput(parsableEquation, m_errorCode, m_errorType)))
 | 
			
		||||
                    {
 | 
			
		||||
                        co_return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -356,7 +358,7 @@ namespace GraphControl
 | 
			
		||||
                request += s_getGraphClosingTags;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (graphExpression = m_solver->ParseInput(request))
 | 
			
		||||
            if (graphExpression = m_solver->ParseInput(request, m_errorCode, m_errorType))
 | 
			
		||||
            {
 | 
			
		||||
                initResult = TryInitializeGraph(keepCurrentView, graphExpression.get());
 | 
			
		||||
 | 
			
		||||
@@ -386,8 +388,13 @@ namespace GraphControl
 | 
			
		||||
                        // If we failed to render then we have already lost the previous graph
 | 
			
		||||
                        shouldKeepPreviousGraph = false;
 | 
			
		||||
                        initResult = nullopt;
 | 
			
		||||
                        m_solver->HRErrorToErrorInfo(m_renderMain->GetRenderError(), m_errorCode, m_errorType);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_solver->HRErrorToErrorInfo(m_graph->GetInitializationError(), m_errorCode, m_errorType);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (initResult == nullopt)
 | 
			
		||||
@@ -398,7 +405,7 @@ namespace GraphControl
 | 
			
		||||
                    initResult = m_graph->TryInitialize();
 | 
			
		||||
                    if (initResult != nullopt)
 | 
			
		||||
                    {
 | 
			
		||||
                        UpdateGraphOptions(m_graph->GetOptions(), validEqs);
 | 
			
		||||
                        UpdateGraphOptions(m_graph->GetOptions(), vector<Equation^>());
 | 
			
		||||
                        SetGraphArgs(m_graph);
 | 
			
		||||
 | 
			
		||||
                        m_renderMain->Graph = m_graph;
 | 
			
		||||
@@ -431,6 +438,8 @@ namespace GraphControl
 | 
			
		||||
        {
 | 
			
		||||
            if (!eq->IsValidated)
 | 
			
		||||
            {
 | 
			
		||||
                eq->GraphErrorType = static_cast<ErrorType>(m_errorType);
 | 
			
		||||
                eq->GraphErrorCode = m_errorCode;
 | 
			
		||||
                eq->HasGraphError = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -457,7 +466,7 @@ namespace GraphControl
 | 
			
		||||
        request += equation->GetRequest()->Data();
 | 
			
		||||
        request += s_getGraphClosingTags;
 | 
			
		||||
 | 
			
		||||
        if (unique_ptr<IExpression> graphExpression = m_solver->ParseInput(request))
 | 
			
		||||
        if (unique_ptr<IExpression> graphExpression = m_solver->ParseInput(request, m_errorCode, m_errorType))
 | 
			
		||||
        {
 | 
			
		||||
            if (graph->TryInitialize(graphExpression.get()))
 | 
			
		||||
            {
 | 
			
		||||
@@ -524,7 +533,7 @@ namespace GraphControl
 | 
			
		||||
                m_graph->SetArgValue(variableName->Data(), newValue);
 | 
			
		||||
                m_renderMain->GetCriticalSection().unlock();
 | 
			
		||||
 | 
			
		||||
                m_renderMain->RunRenderPassAsync();
 | 
			
		||||
                m_renderMain->RunRenderPass();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            ThreadPool::RunAsync(workItemHandler, WorkItemPriority::High, WorkItemOptions::None);
 | 
			
		||||
@@ -549,7 +558,7 @@ namespace GraphControl
 | 
			
		||||
                auto lineColor = eq->LineColor;
 | 
			
		||||
                graphColors.emplace_back(lineColor.R, lineColor.G, lineColor.B, lineColor.A);
 | 
			
		||||
 | 
			
		||||
                if (eq->IsSelected)
 | 
			
		||||
                if (eq->GraphedEquation != nullptr && !eq->HasGraphError && eq->IsSelected)
 | 
			
		||||
                {
 | 
			
		||||
                    eq->GraphedEquation->TrySelectEquation();
 | 
			
		||||
                }
 | 
			
		||||
@@ -1001,7 +1010,7 @@ String ^ Grapher::ConvertToLinear(String ^ mmlString)
 | 
			
		||||
{
 | 
			
		||||
    m_solver->FormatOptions().SetFormatType(FormatType::LinearInput);
 | 
			
		||||
 | 
			
		||||
    auto expression = m_solver->ParseInput(mmlString->Data());
 | 
			
		||||
    auto expression = m_solver->ParseInput(mmlString->Data(), m_errorCode, m_errorType);
 | 
			
		||||
    auto linearExpression = m_solver->Serialize(expression.get());
 | 
			
		||||
 | 
			
		||||
    m_solver->FormatOptions().SetFormatType(s_defaultFormatType);
 | 
			
		||||
@@ -1011,7 +1020,7 @@ String ^ Grapher::ConvertToLinear(String ^ mmlString)
 | 
			
		||||
 | 
			
		||||
String ^ Grapher::FormatMathML(String ^ mmlString)
 | 
			
		||||
{
 | 
			
		||||
    auto expression = m_solver->ParseInput(mmlString->Data());
 | 
			
		||||
    auto expression = m_solver->ParseInput(mmlString->Data(), m_errorCode, m_errorType);
 | 
			
		||||
    auto formattedExpression = m_solver->Serialize(expression.get());
 | 
			
		||||
    return ref new String(formattedExpression.c_str());
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -335,6 +335,8 @@ public
 | 
			
		||||
        bool m_Moving;
 | 
			
		||||
        Windows::UI::Xaml::DispatcherTimer ^ m_TracingTrackingTimer;
 | 
			
		||||
        Windows::UI::Core::CoreCursor ^ m_cachedCursor;
 | 
			
		||||
        int m_errorType;
 | 
			
		||||
        int m_errorCode;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        Windows::Storage::Streams::RandomAccessStreamReference ^ GetGraphBitmapStream();
 | 
			
		||||
 
 | 
			
		||||
@@ -274,7 +274,9 @@ namespace GraphControl::DX
 | 
			
		||||
                pRenderTarget->BeginDraw();
 | 
			
		||||
 | 
			
		||||
                bool hasMissingData = false;
 | 
			
		||||
                successful = SUCCEEDED(renderer->DrawD2D1(pFactory, pRenderTarget, hasMissingData));
 | 
			
		||||
                m_HResult = renderer->DrawD2D1(pFactory, pRenderTarget, hasMissingData);
 | 
			
		||||
 | 
			
		||||
                successful = SUCCEEDED(m_HResult);
 | 
			
		||||
 | 
			
		||||
                // We ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
 | 
			
		||||
                // is lost. It will be handled during the next call to Present.
 | 
			
		||||
@@ -345,6 +347,11 @@ namespace GraphControl::DX
 | 
			
		||||
        return successful;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    HRESULT RenderMain::GetRenderError()
 | 
			
		||||
    {
 | 
			
		||||
        return m_HResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void RenderMain::OnLoaded(Object ^ sender, RoutedEventArgs ^ e)
 | 
			
		||||
    {
 | 
			
		||||
        RunRenderPass();
 | 
			
		||||
 
 | 
			
		||||
@@ -61,6 +61,8 @@ namespace GraphControl::DX
 | 
			
		||||
            return m_isRenderPassSuccesful;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HRESULT GetRenderError();
 | 
			
		||||
 | 
			
		||||
        // Indicates if we are in active tracing mode (the tracing box is being used and controlled through keyboard input)
 | 
			
		||||
        property bool ActiveTracing
 | 
			
		||||
        {
 | 
			
		||||
@@ -189,5 +191,7 @@ namespace GraphControl::DX
 | 
			
		||||
         Windows::Foundation::IAsyncAction ^ m_renderPass = nullptr;
 | 
			
		||||
 | 
			
		||||
         bool m_isRenderPassSuccesful;
 | 
			
		||||
 | 
			
		||||
         HRESULT m_HResult;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,200 @@
 | 
			
		||||
 | 
			
		||||
namespace GraphControl
 | 
			
		||||
{
 | 
			
		||||
    public enum class ErrorType
 | 
			
		||||
    {
 | 
			
		||||
        Evaluation,
 | 
			
		||||
        Syntax,
 | 
			
		||||
        Abort,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    public enum class EvaluationErrorCode
 | 
			
		||||
    {
 | 
			
		||||
        // Number is too large. To see this error, assign a large number to variable a, then keep doing "a:=a*a" until it happens
 | 
			
		||||
        Overflow = 2,
 | 
			
		||||
 | 
			
		||||
        // doing trig in calculus and current mode is not Radians
 | 
			
		||||
        RequireRadiansMode = 3,
 | 
			
		||||
 | 
			
		||||
        // This is actually abort code generated as time limit reached.
 | 
			
		||||
        TooComplexToSolve = 4,
 | 
			
		||||
 | 
			
		||||
        // degree sign present and the current mode is not Degrees
 | 
			
		||||
        RequireDegreesMode = 5,
 | 
			
		||||
 | 
			
		||||
        // n! and n is not an non-negative integer or m/2
 | 
			
		||||
        FactorialInvalidArgument = -1,
 | 
			
		||||
 | 
			
		||||
        // n!! and n is not an non-negative integer or odd negative integers
 | 
			
		||||
        Factorial2InvalidArgument = -2,
 | 
			
		||||
 | 
			
		||||
        // n! and n is too big
 | 
			
		||||
        FactorialCannotPerformOnLargeNumber = -3,
 | 
			
		||||
 | 
			
		||||
        // x mod y, and one of them is not an integer
 | 
			
		||||
        ModuloCannotPerformOnFloat = -5,
 | 
			
		||||
 | 
			
		||||
        // below are equation solving specific errors
 | 
			
		||||
 | 
			
		||||
        // example1: sin(x)+x=2    example2: x^4-x^3-8x=9
 | 
			
		||||
        EquationTooComplexToSolveSymbolic = -7,
 | 
			
		||||
 | 
			
		||||
        // example1: x-x=3    example2: x^2=-1
 | 
			
		||||
        EquationHasNoSolution = -8,
 | 
			
		||||
 | 
			
		||||
        // only used for numeric solve where the algorithm doesn't converge
 | 
			
		||||
        EquationTooComplexToSolve = -9,
 | 
			
		||||
 | 
			
		||||
        // used when equation cannot be ploted
 | 
			
		||||
        EquationTooComplexToPlot = -10,
 | 
			
		||||
 | 
			
		||||
        // example1: 1/0
 | 
			
		||||
        DivideByZero = -15,
 | 
			
		||||
 | 
			
		||||
        // the inequality is too complex for the engine to solve
 | 
			
		||||
        InequalityTooComplexToSolve = -41,
 | 
			
		||||
 | 
			
		||||
        // the inequality has no solution
 | 
			
		||||
        InequalityHasNoSolution = -42,
 | 
			
		||||
 | 
			
		||||
        // An exression contains logical conditions that are mutually exclusive
 | 
			
		||||
        MutuallyExclusiveConditions = -43,
 | 
			
		||||
 | 
			
		||||
        // Arbitrary Precision Evaluation input is out of domain
 | 
			
		||||
        OutOfDomain = -101,
 | 
			
		||||
 | 
			
		||||
        // Not supported.
 | 
			
		||||
        GE_NotSupported = -503,
 | 
			
		||||
 | 
			
		||||
        // General error for graphing engine
 | 
			
		||||
        GE_GeneralError = -504,
 | 
			
		||||
 | 
			
		||||
        // Failed to calculate
 | 
			
		||||
        GE_TooComplexToSolve = -506,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    public enum class SyntaxErrorCode
 | 
			
		||||
    {
 | 
			
		||||
        // found ) without matching (
 | 
			
		||||
        ParenthesisMismatch = 1,
 | 
			
		||||
 | 
			
		||||
        // found ( without matching )
 | 
			
		||||
        UnmatchedParenthesis = 2,
 | 
			
		||||
 | 
			
		||||
        // more than 1 decimal point in a number. Example: 7.3.2
 | 
			
		||||
        TooManyDecimalPoints = 3,
 | 
			
		||||
 | 
			
		||||
        // decimal point on its own without any digits surrounding it. Example: 3+.+4
 | 
			
		||||
        DecimalPointWithoutDigits = 4,
 | 
			
		||||
 | 
			
		||||
        // example: 3-4*
 | 
			
		||||
        UnexpectedEndOfExpression = 5,
 | 
			
		||||
 | 
			
		||||
        // example: 3-*4
 | 
			
		||||
        UnexpectedToken = 6,
 | 
			
		||||
 | 
			
		||||
        // example: [    (or many other special characters), another example: "3,5" (comma is invalid here)
 | 
			
		||||
        InvalidToken = 7,
 | 
			
		||||
 | 
			
		||||
        // example: solve(x+3=8=x)
 | 
			
		||||
        TooManyEquals = 8,
 | 
			
		||||
 | 
			
		||||
        // example: ploteq(4+83=9)
 | 
			
		||||
        EqualWithoutGraphVariable = 10,
 | 
			
		||||
 | 
			
		||||
        // <para>example: ploteq(x+y)        (expecting "=" in equation ploting)</para>
 | 
			
		||||
        // <para>example2: Solve(5*x+9)    (expecting = in the equation solving)</para>
 | 
			
		||||
        InvalidEquationSyntax = 11,
 | 
			
		||||
 | 
			
		||||
        // there is nothing in the expression
 | 
			
		||||
        EmptyExpression = 12,
 | 
			
		||||
 | 
			
		||||
        // example: factor(x=3) (expecting solve(x=3)).
 | 
			
		||||
        EqualWithoutEquation = 14,
 | 
			
		||||
 | 
			
		||||
        // example: solve( (x=3)*2 )
 | 
			
		||||
        InvalidEquationFormat = 15,
 | 
			
		||||
 | 
			
		||||
        // This error only occurs when CasContext.ParsingOptions.AllowImplicitParentheses == false.
 | 
			
		||||
        // example: sin a    (expecting sin(a))
 | 
			
		||||
        ExpectParenthesisAfterFunctionName = 25,
 | 
			
		||||
 | 
			
		||||
        // example: root(a)    (expecting 2 parameters)
 | 
			
		||||
        IncorrectNumParameter = 26,
 | 
			
		||||
 | 
			
		||||
        // exmaple: "x_", "x_@", "x__1"
 | 
			
		||||
        InvalidVariableNameFormat = 32,
 | 
			
		||||
 | 
			
		||||
        // found } without matching {
 | 
			
		||||
        BracketMismatch = 34,
 | 
			
		||||
 | 
			
		||||
        // found { without matching }
 | 
			
		||||
        UnmatchedBracket = 35,
 | 
			
		||||
 | 
			
		||||
        // syntax error in MathML format. Used only if CasContext.ParsingOptions.FormatType is MathML or MathMLNoWrapper
 | 
			
		||||
        InvalidMathMLFormat = 40,
 | 
			
		||||
 | 
			
		||||
        // The input has an unknown MathML entity. Used only if CasContext.ParsingOptions.FormatType is MathML or MathMLNoWrapper
 | 
			
		||||
        UnknownMathMLEntity = 41,
 | 
			
		||||
 | 
			
		||||
        // The input has an unknown MathML element. Used only if CasContext.ParsingOptions.FormatType is MathML or MathMLNoWrapper
 | 
			
		||||
        UnknownMathMLElement = 42,
 | 
			
		||||
 | 
			
		||||
        // "i" and "I" cannot be used as variable names in real number field
 | 
			
		||||
        CannotUseIInReal = 48,
 | 
			
		||||
 | 
			
		||||
        // General error
 | 
			
		||||
        GeneralError = 52,
 | 
			
		||||
 | 
			
		||||
        // used in parsing numbers with arbitrary bases. example: base(2, 1020), base(16, 1AG)
 | 
			
		||||
        InvalidNumberDigit = 55,
 | 
			
		||||
 | 
			
		||||
        // a valid number base must be an integer >=2 and <=36
 | 
			
		||||
        InvalidNumberBase = 56,
 | 
			
		||||
 | 
			
		||||
        // some functions require a variable in certain argument position. e.g. 2nd argument of deriv, integral, limit, etc.
 | 
			
		||||
        // this error code is used if the argument at the position is not a variable
 | 
			
		||||
        InvalidVariableSpecification = 57,
 | 
			
		||||
 | 
			
		||||
        // all operands of logical operators must be logical. example: "true and 1"
 | 
			
		||||
        ExpectingLogicalOperands = 58,
 | 
			
		||||
 | 
			
		||||
        // all operands of a non-logical operator must not be logical. example: "sin(true)"
 | 
			
		||||
        ExpectingScalarOperands = 59,
 | 
			
		||||
 | 
			
		||||
        // a list can contain logicals or scalars, but not both.
 | 
			
		||||
        CannotMixLogicalScalarInList = 60,
 | 
			
		||||
 | 
			
		||||
        // in definite integral, seriesSum and seriesProduct, the index variable is used in the lower/upper limits.
 | 
			
		||||
        // example: integral(sin(x), x, 0, x)
 | 
			
		||||
        CannotUseIndexVarInOpLimits = 61,
 | 
			
		||||
 | 
			
		||||
        // in limit, the index variable is used in the limit point
 | 
			
		||||
        // example: limit(sin(x), x, x-1)
 | 
			
		||||
        CannotUseIndexVarInLimPoint = 62,
 | 
			
		||||
 | 
			
		||||
        /// ComplexInfinity cannot be used in real number field
 | 
			
		||||
        CannotUseComplexInfinityInReal = 72,
 | 
			
		||||
 | 
			
		||||
        // complex numbers are not allowed in inequality solving
 | 
			
		||||
        CannotUseIInInequalitySolving = 123,
 | 
			
		||||
 | 
			
		||||
        // Indicate a bug in the MathRichEdit serializer
 | 
			
		||||
        RichEditSerializationError = 201,
 | 
			
		||||
 | 
			
		||||
        // can't initialize math zone in richedit, meaning it's the wrong version richedit dll, need reinstall
 | 
			
		||||
        RichEditInitialization = 202,
 | 
			
		||||
 | 
			
		||||
        // indicate bug in either richedit or richedit wrapper
 | 
			
		||||
        RichEditInlineObjectStructure = 203,
 | 
			
		||||
 | 
			
		||||
        // in a structure like integral, sum, product, one of the boxes is not filled
 | 
			
		||||
        RichEditMissingArgument = 204,
 | 
			
		||||
 | 
			
		||||
        // errors in richedit wrapper that are not specifically handled for
 | 
			
		||||
        RichEditGeneralError = 210,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    [Windows::UI::Xaml::Data::Bindable] public ref class Equation sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
@@ -18,6 +212,8 @@ namespace GraphControl
 | 
			
		||||
        OBSERVABLE_NAMED_PROPERTY_RW(bool, IsValidated);
 | 
			
		||||
        OBSERVABLE_NAMED_PROPERTY_RW(bool, HasGraphError);
 | 
			
		||||
        OBSERVABLE_NAMED_PROPERTY_RW(bool, IsSelected);
 | 
			
		||||
        OBSERVABLE_NAMED_PROPERTY_RW(ErrorType, GraphErrorType);
 | 
			
		||||
        OBSERVABLE_NAMED_PROPERTY_RW(int, GraphErrorCode);
 | 
			
		||||
 | 
			
		||||
        property Windows::UI::Color LineColor
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,11 @@ namespace MockGraphingImpl
 | 
			
		||||
            return std::nullopt;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HRESULT GetInitializationError()
 | 
			
		||||
        {
 | 
			
		||||
            return S_OK;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual Graphing::IGraphingOptions& GetOptions()
 | 
			
		||||
        {
 | 
			
		||||
            return m_graphingOptions;
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,7 @@ namespace MockGraphingImpl
 | 
			
		||||
            return m_formatOptions;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::unique_ptr<Graphing::IExpression> ParseInput(const std::wstring& input) override
 | 
			
		||||
        std::unique_ptr<Graphing::IExpression> ParseInput(const std::wstring& input, int& errorCodeOut, int& errorTypeOut) override
 | 
			
		||||
        {
 | 
			
		||||
            if (input.empty())
 | 
			
		||||
            {
 | 
			
		||||
@@ -125,6 +125,10 @@ namespace MockGraphingImpl
 | 
			
		||||
            return std::make_unique<MockExpression>(MockExpression{});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void HRErrorToErrorInfo(HRESULT hr, int& errorCodeOut, int& errorTypeOut)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::shared_ptr<Graphing::IGraph> CreateGrapher(const Graphing::IExpression* expression) override;
 | 
			
		||||
 | 
			
		||||
        std::shared_ptr<Graphing::IGraph> CreateGrapher() override;
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@ namespace Graphing
 | 
			
		||||
 | 
			
		||||
        virtual std::optional<std::vector<std::shared_ptr<IEquation>>> TryInitialize(const IExpression* graphingExp = nullptr) = 0;
 | 
			
		||||
 | 
			
		||||
        virtual HRESULT GetInitializationError() = 0;
 | 
			
		||||
 | 
			
		||||
        virtual IGraphingOptions& GetOptions() = 0;
 | 
			
		||||
 | 
			
		||||
        virtual std::vector<std::shared_ptr<Graphing::IVariable>> GetVariables() = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -64,9 +64,11 @@ namespace Graphing
 | 
			
		||||
        virtual IEvalOptions& EvalOptions() = 0;
 | 
			
		||||
        virtual IFormatOptions& FormatOptions() = 0;
 | 
			
		||||
 | 
			
		||||
        virtual std::unique_ptr<IExpression> ParseInput(const std::wstring& input) = 0;
 | 
			
		||||
        virtual std::shared_ptr<IGraph> CreateGrapher(const IExpression* expression) = 0;
 | 
			
		||||
        virtual std::unique_ptr<IExpression> ParseInput(const std::wstring& input, int& errorCodeOut, int& errorTypeOut) = 0;
 | 
			
		||||
 | 
			
		||||
        virtual void HRErrorToErrorInfo(HRESULT hr, int& errorCodeOut, int& errorTypeOut) = 0;
 | 
			
		||||
 | 
			
		||||
        virtual std::shared_ptr<IGraph> CreateGrapher(const IExpression* expression) = 0;
 | 
			
		||||
        virtual std::shared_ptr<Graphing::IGraph> CreateGrapher() = 0;
 | 
			
		||||
 | 
			
		||||
        virtual std::wstring Serialize(const IExpression* expression) = 0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user