diff --git a/src/CalcManager/CEngine/scicomm.cpp b/src/CalcManager/CEngine/scicomm.cpp
index f639c707..fdcf749c 100644
--- a/src/CalcManager/CEngine/scicomm.cpp
+++ b/src/CalcManager/CEngine/scicomm.cpp
@@ -544,6 +544,11 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx)
|| ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0)))
{
+ if (!m_openParenCount && !nx)
+ {
+ m_pCalcDisplay->OnNoParenAdded();
+ }
+
HandleErrorCommand(wParam);
break;
}
diff --git a/src/CalcManager/CalculatorManager.cpp b/src/CalcManager/CalculatorManager.cpp
index 0e03afaf..d52256e8 100644
--- a/src/CalcManager/CalculatorManager.cpp
+++ b/src/CalcManager/CalculatorManager.cpp
@@ -117,6 +117,15 @@ namespace CalculationManager
m_displayCallback->SetParenDisplayText(parenthesisCount);
}
+ ///
+ /// Callback from the engine
+ /// Used to set the narrator text when no parenthesis can be added
+ ///
+ void CalculatorManager::OnNoParenAdded()
+ {
+ m_displayCallback->OnNoParenAdded();
+ }
+
///
/// Reset CalculatorManager.
/// Set the mode to the standard calculator
diff --git a/src/CalcManager/CalculatorManager.h b/src/CalcManager/CalculatorManager.h
index 9f60c534..cb90fbdf 100644
--- a/src/CalcManager/CalculatorManager.h
+++ b/src/CalcManager/CalculatorManager.h
@@ -42,7 +42,7 @@ namespace CalculationManager
MemorizedNumberClear = 335
};
- class CalculatorManager sealed : public virtual ICalcDisplay
+ class CalculatorManager sealed : public ICalcDisplay
{
private:
ICalcDisplay* const m_displayCallback;
@@ -94,7 +94,8 @@ namespace CalculationManager
void SetExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands) override;
void SetMemorizedNumbers(_In_ const std::vector& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
- void SetParenDisplayText(const std::wstring& parenthesisCount);
+ void SetParenDisplayText(const std::wstring& parenthesisCount) override;
+ void OnNoParenAdded() override;
void DisplayPasteError();
void MaxDigitsReached() override;
void BinaryOperatorReceived() override;
diff --git a/src/CalcManager/Header Files/ICalcDisplay.h b/src/CalcManager/Header Files/ICalcDisplay.h
index abafbc3c..8f57d4fb 100644
--- a/src/CalcManager/Header Files/ICalcDisplay.h
+++ b/src/CalcManager/Header Files/ICalcDisplay.h
@@ -13,6 +13,7 @@ public:
virtual void SetIsInError(bool isInError) = 0;
virtual void SetExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands) = 0;
virtual void SetParenDisplayText(const std::wstring& pszText) = 0;
+ virtual void OnNoParenAdded() = 0;
virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer.
virtual void BinaryOperatorReceived() = 0;
virtual void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) = 0;
diff --git a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp
index 72b4a712..7371bfa3 100644
--- a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp
+++ b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
@@ -20,6 +20,8 @@ namespace CalculatorApp::Common::Automation
StringReference CategoryNameChanged(L"CategoryNameChanged");
StringReference UpdateCurrencyRates(L"UpdateCurrencyRates");
StringReference DisplayCopied(L"DisplayCopied");
+ StringReference OpenParenthesisCountChanged(L"OpenParenthesisCountChanged");
+ StringReference NoParenthesisAdded(L"NoParenthesisAdded");
}
}
@@ -142,3 +144,21 @@ NarratorAnnouncement^ CalculatorAnnouncement::GetDisplayCopiedAnnouncement(Strin
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}
+
+NarratorAnnouncement^ CalculatorAnnouncement::GetOpenParenethisCount(String^ announcement)
+{
+ return ref new NarratorAnnouncement(
+ announcement,
+ CalculatorActivityIds::OpenParenthesisCountChanged,
+ AutomationNotificationKind::ActionCompleted,
+ AutomationNotificationProcessing::ImportantMostRecent);
+}
+
+NarratorAnnouncement^ CalculatorAnnouncement::GetNoParenthesisAddedAnnouncement(String^ announcement)
+{
+ return ref new NarratorAnnouncement(
+ announcement,
+ CalculatorActivityIds::NoParenthesisAdded,
+ AutomationNotificationKind::ActionCompleted,
+ AutomationNotificationProcessing::ImportantMostRecent);
+}
diff --git a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h
index 16635b4a..3bf3e433 100644
--- a/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h
+++ b/src/CalcViewModel/Common/Automation/NarratorAnnouncement.h
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
@@ -90,5 +90,8 @@ namespace CalculatorApp::Common::Automation
static NarratorAnnouncement^ GetUpdateCurrencyRatesAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetDisplayCopiedAnnouncement(Platform::String^ announcement);
+
+ static NarratorAnnouncement^ GetOpenParenethisCount(Platform::String^ announcement);
+ static NarratorAnnouncement^ GetNoParenthesisAddedAnnouncement(Platform::String ^ announcement);
};
}
diff --git a/src/CalcViewModel/Common/CalculatorDisplay.cpp b/src/CalcViewModel/Common/CalculatorDisplay.cpp
index 705da22c..0e6b45a3 100644
--- a/src/CalcViewModel/Common/CalculatorDisplay.cpp
+++ b/src/CalcViewModel/Common/CalculatorDisplay.cpp
@@ -49,6 +49,18 @@ void CalculatorDisplay::SetParenDisplayText(_In_ const std::wstring& parenthesis
}
}
+void CalculatorDisplay::OnNoParenAdded()
+{
+ if (m_callbackReference != nullptr)
+ {
+ auto calcVM = m_callbackReference.Resolve();
+ if (calcVM)
+ {
+ calcVM->SetNoParenAddedNarratorAnnouncement();
+ }
+ }
+}
+
void CalculatorDisplay::SetIsInError(bool isError)
{
if (m_callbackReference != nullptr)
diff --git a/src/CalcViewModel/Common/CalculatorDisplay.h b/src/CalcViewModel/Common/CalculatorDisplay.h
index 692af37e..20e82f08 100644
--- a/src/CalcViewModel/Common/CalculatorDisplay.h
+++ b/src/CalcViewModel/Common/CalculatorDisplay.h
@@ -22,6 +22,7 @@ namespace CalculatorApp
void SetMemorizedNumbers(_In_ const std::vector& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override;
+ void OnNoParenAdded() override;
void MaxDigitsReached() override;
void BinaryOperatorReceived() override;
void MemoryItemChanged(unsigned int indexOfMemory) override;
diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp
index a25aeb18..2a5a9986 100644
--- a/src/CalcViewModel/StandardCalculatorViewModel.cpp
+++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp
@@ -52,7 +52,8 @@ namespace CalculatorApp::ViewModel
StringReference DecButton(L"Format_DecButtonValue");
StringReference OctButton(L"Format_OctButtonValue");
StringReference BinButton(L"Format_BinButtonValue");
- StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix");
+ StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix");
+ StringReference NoParenthesisAdded(L"NoParenthesisAdded_Announcement");
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback");
StringReference MemorySave(L"Format_MemorySave");
@@ -92,7 +93,9 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_localizedMemorySavedAutomationFormat(nullptr),
m_localizedMemoryItemChangedAutomationFormat(nullptr),
m_localizedMemoryItemClearedAutomationFormat(nullptr),
- m_localizedMemoryCleared(nullptr)
+ m_localizedMemoryCleared(nullptr),
+ m_localizedOpenParenthesisCountChangedAutomationFormat(nullptr),
+ m_localizaedNoParenthesisAddedAutomationFormat(nullptr)
{
WeakReference calculatorViewModel(this);
m_calculatorDisplay.SetCallback(calculatorViewModel);
@@ -103,7 +106,6 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_localizedDecimalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::DecButton);
m_localizedOctalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::OctButton);
m_localizedBinaryAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::BinButton);
- m_leftParenthesisAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::LeftParenthesisAutomationFormat);
// Initialize the Automation Name
CalculationResultAutomationName = GetLocalizedStringFormat(m_localizedCalculationResultAutomationFormat, m_DisplayValue);
@@ -222,10 +224,32 @@ void StandardCalculatorViewModel::SetParenthesisCount(_In_ const wstring& parent
if (IsProgrammer || IsScientific)
{
OpenParenthesisCount = ref new String(parenthesisCount.c_str());
- RaisePropertyChanged("LeftParenthesisAutomationName");
}
}
+void StandardCalculatorViewModel::OpenParenthesisCountNarratorAnnouncment()
+{
+ String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount);
+ wstring localizedParenthesisCount = std::wstring(parenthesisCount->Data());
+ LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
+
+ String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
+ CalculatorResourceKeys::OpenParenthesisCountAutomationFormat,
+ m_localizedOpenParenthesisCountChangedAutomationFormat,
+ localizedParenthesisCount.c_str());
+
+ Announcement = CalculatorAnnouncement::GetOpenParenethisCount(announcement);
+}
+
+void StandardCalculatorViewModel::SetNoParenAddedNarratorAnnouncement()
+{
+ String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
+ CalculatorResourceKeys::NoParenthesisAdded,
+ m_localizaedNoParenthesisAddedAutomationFormat);
+
+ Announcement = CalculatorAnnouncement::GetNoParenthesisAddedAnnouncement(announcement);
+}
+
void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType)
{
if (selectedExpressionCommandType == CommandType::OperandCommand)
@@ -254,15 +278,6 @@ void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionC
}
}
-String ^ StandardCalculatorViewModel::GetLeftParenthesisAutomationName()
-{
- String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount);
- wstring localizedParenthesisCount = std::wstring(parenthesisCount->Data());
- LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
-
- return GetLocalizedStringFormat(m_leftParenthesisAutomationFormat, ref new String(localizedParenthesisCount.c_str()));
-}
-
void StandardCalculatorViewModel::SetExpressionDisplay(_Inout_ shared_ptr>> const &tokens, _Inout_ shared_ptr>> const &commands)
{
m_tokens = tokens;
@@ -566,6 +581,8 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter)
m_feedbackForButtonPress = CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParameter(parameter);
NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter);
Command cmdenum = ConvertToOperatorsEnum(numOpEnum);
+ bool isOperator = IsOperator(cmdenum);
+ String^ previousParenthesisCount = m_OpenParenthesisCount;
TraceLogger::GetInstance().UpdateFunctionUsage((int)numOpEnum);
@@ -643,6 +660,11 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter)
m_standardCalculatorManager.SendCommand(cmdenum);
}
+
+ if (numOpEnum == NumbersAndOperatorsEnum::OpenParenthesis || (numOpEnum == NumbersAndOperatorsEnum::CloseParenthesis && previousParenthesisCount) )
+ {
+ OpenParenthesisCountNarratorAnnouncment();
+ }
}
}
diff --git a/src/CalcViewModel/StandardCalculatorViewModel.h b/src/CalcViewModel/StandardCalculatorViewModel.h
index 91ff9da0..58863469 100644
--- a/src/CalcViewModel/StandardCalculatorViewModel.h
+++ b/src/CalcViewModel/StandardCalculatorViewModel.h
@@ -261,14 +261,6 @@ namespace CalculatorApp
void set(bool value) { m_completeTextSelection = value; }
}
- property Platform::String^ LeftParenthesisAutomationName
- {
- Platform::String^ get()
- {
- return GetLeftParenthesisAutomationName();
- }
- }
-
internal:
void OnPaste(Platform::String^ pastedString, CalculatorApp::Common::ViewMode mode);
void OnCopyCommand(Platform::Object^ parameter);
@@ -284,12 +276,15 @@ namespace CalculatorApp
void OnMemoryClear(_In_ Platform::Object^ memoryItemPosition);
void OnPinUnpinCommand(Platform::Object^ parameter);
+ void OpenParenthesisCountNarratorAnnouncment();
+
void SetPrimaryDisplay(_In_ std::wstring const&displayString, _In_ bool isError);
void DisplayPasteError();
void SetTokens(_Inout_ std::shared_ptr>> const &tokens);
void SetExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands);
void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands);
void SetParenthesisCount(_In_ const std::wstring& parenthesisCount);
+ void SetNoParenAddedNarratorAnnouncement();
void OnMaxDigitsReached();
void OnBinaryOperatorReceived();
void OnMemoryItemChanged(unsigned int indexOfMemory);
@@ -337,6 +332,8 @@ namespace CalculatorApp
Platform::String^ m_localizedMemoryItemChangedAutomationFormat;
Platform::String^ m_localizedMemoryItemClearedAutomationFormat;
Platform::String^ m_localizedMemoryCleared;
+ Platform::String^ m_localizedOpenParenthesisCountChangedAutomationFormat;
+ Platform::String^ m_localizaedNoParenthesisAddedAutomationFormat;
bool m_pinned;
bool m_isOperandEnabled;
@@ -355,7 +352,6 @@ namespace CalculatorApp
bool m_isLastOperationHistoryLoad;
Platform::String^ m_selectedExpressionLastData;
Common::DisplayExpressionToken^ m_selectedExpressionToken;
- Platform::String^ m_leftParenthesisAutomationFormat;
Platform::String^ LocalizeDisplayValue(_In_ std::wstring const &displayValue, _In_ bool isError);
Platform::String^ CalculateNarratorDisplayValue(_In_ std::wstring const &displayValue, _In_ Platform::String^ localizedDisplayValue, _In_ bool isError);
@@ -365,7 +361,6 @@ namespace CalculatorApp
CalculationManager::Command ConvertToOperatorsEnum(NumbersAndOperatorsEnum operation);
void DisableButtons(CalculationManager::CommandType selectedExpressionCommandType);
- Platform::String^ GetLeftParenthesisAutomationName();
Platform::String^ m_feedbackForButtonPress;
void OnButtonPressed(Platform::Object^ parameter);
diff --git a/src/Calculator/Resources/en-US/Resources.resw b/src/Calculator/Resources/en-US/Resources.resw
index ca9ee82c..1e77ed55 100644
--- a/src/Calculator/Resources/en-US/Resources.resw
+++ b/src/Calculator/Resources/en-US/Resources.resw
@@ -1313,14 +1313,18 @@
Left parenthesis
Screen reader prompt for the Calculator "(" button on the scientific operator keypad
-
- Left parenthesis, open parenthesis count %1
- {Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".
-
Right parenthesis
Screen reader prompt for the Calculator ")" button on the scientific operator keypad
+
+ Open parenthesis count %1
+ {Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".
+
+
+ There are no open parentheses to close.
+ {Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific or programmer operator keypad cannot be added to the equation. e.g. "1+)".
+
Scientific notation
Screen reader prompt for the Calculator F-E the scientific operator keypad
diff --git a/src/CalculatorUnitTests/CalculatorManagerTest.cpp b/src/CalculatorUnitTests/CalculatorManagerTest.cpp
index cdf8a6f2..f1df0f28 100644
--- a/src/CalculatorUnitTests/CalculatorManagerTest.cpp
+++ b/src/CalculatorUnitTests/CalculatorManagerTest.cpp
@@ -62,6 +62,11 @@ namespace CalculatorManagerTest
m_parenDisplay = parenthesisCount;
}
+ void OnNoParenAdded() override
+ {
+ // This method is used to create a narrator announcement when a close parenthesis cannot be added because there are no open parentheses
+ }
+
const wstring& GetPrimaryDisplay() const
{
return m_primaryDisplay;