merge with master
This commit is contained in:
@@ -43,7 +43,7 @@ namespace
|
||||
ApplicationViewModel::ApplicationViewModel()
|
||||
: m_CalculatorViewModel(nullptr)
|
||||
, m_DateCalcViewModel(nullptr)
|
||||
, m_GraphingCalcViewModel(nullptr)
|
||||
, m_GraphingCalcViewModel(nullptr)
|
||||
, m_ConverterViewModel(nullptr)
|
||||
, m_PreviousMode(ViewMode::None)
|
||||
, m_mode(ViewMode::None)
|
||||
@@ -86,7 +86,7 @@ void ApplicationViewModel::Initialize(ViewMode mode)
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
TraceLogger::GetInstance().LogStandardException(mode, __FUNCTIONW__, e);
|
||||
TraceLogger::GetInstance()->LogStandardException(mode, __FUNCTIONW__, e);
|
||||
if (!TryRecoverFromNavigationModeFailure())
|
||||
{
|
||||
// Could not navigate to standard mode either.
|
||||
@@ -96,7 +96,7 @@ void ApplicationViewModel::Initialize(ViewMode mode)
|
||||
}
|
||||
catch (Exception ^ e)
|
||||
{
|
||||
TraceLogger::GetInstance().LogPlatformException(mode, __FUNCTIONW__, e);
|
||||
TraceLogger::GetInstance()->LogPlatformException(mode, __FUNCTIONW__, e);
|
||||
if (!TryRecoverFromNavigationModeFailure())
|
||||
{
|
||||
// Could not navigate to standard mode either.
|
||||
@@ -160,7 +160,7 @@ void ApplicationViewModel::OnModeChanged()
|
||||
}
|
||||
|
||||
auto resProvider = AppResourceProvider::GetInstance();
|
||||
CategoryName = resProvider.GetResourceString(NavCategory::GetNameResourceKey(m_mode));
|
||||
CategoryName = resProvider->GetResourceString(NavCategory::GetNameResourceKey(m_mode));
|
||||
|
||||
// Cast mode to an int in order to save it to app data.
|
||||
// Save the changed mode, so that the new window launches in this mode.
|
||||
@@ -170,11 +170,11 @@ void ApplicationViewModel::OnModeChanged()
|
||||
// Log ModeChange event when not first launch, log WindowCreated on first launch
|
||||
if (NavCategory::IsValidViewMode(m_PreviousMode))
|
||||
{
|
||||
TraceLogger::GetInstance().LogModeChange(m_mode);
|
||||
TraceLogger::GetInstance()->LogModeChange(m_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLogger::GetInstance().LogWindowCreated(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
|
||||
TraceLogger::GetInstance()->LogWindowCreated(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
|
||||
}
|
||||
|
||||
RaisePropertyChanged(ClearMemoryVisibilityPropertyName);
|
||||
|
||||
@@ -315,12 +315,8 @@
|
||||
<ClInclude Include="ApplicationViewModel.h" />
|
||||
<ClInclude Include="Common\AlwaysSelectedCollectionView.h" />
|
||||
<ClInclude Include="Common\AppResourceProvider.h" />
|
||||
<ClInclude Include="Common\Automation\INarratorAnnouncementHost.h" />
|
||||
<ClInclude Include="Common\Automation\LiveRegionHost.h" />
|
||||
<ClInclude Include="Common\Automation\NarratorAnnouncement.h" />
|
||||
<ClInclude Include="Common\Automation\NarratorAnnouncementHostFactory.h" />
|
||||
<ClInclude Include="Common\Automation\NarratorNotifier.h" />
|
||||
<ClInclude Include="Common\Automation\NotificationHost.h" />
|
||||
<ClInclude Include="Common\BindableBase.h" />
|
||||
<ClInclude Include="Common\BitLength.h" />
|
||||
<ClInclude Include="Common\CalculatorButtonPressedEventArgs.h" />
|
||||
@@ -341,6 +337,7 @@
|
||||
<ClInclude Include="Common\MyVirtualKey.h" />
|
||||
<ClInclude Include="Common\NavCategory.h" />
|
||||
<ClInclude Include="Common\NetworkManager.h" />
|
||||
<ClInclude Include="Common\NumberBase.h" />
|
||||
<ClInclude Include="Common\TraceActivity.h" />
|
||||
<ClInclude Include="Common\TraceLogger.h" />
|
||||
<ClInclude Include="Common\Utils.h" />
|
||||
@@ -361,16 +358,12 @@
|
||||
<ClInclude Include="StandardCalculatorViewModel.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="UnitConverterViewModel.h" />
|
||||
<ClInclude Include="ViewState.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ApplicationViewModel.cpp" />
|
||||
<ClCompile Include="Common\AppResourceProvider.cpp" />
|
||||
<ClCompile Include="Common\Automation\LiveRegionHost.cpp" />
|
||||
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp" />
|
||||
<ClCompile Include="Common\Automation\NarratorAnnouncementHostFactory.cpp" />
|
||||
<ClCompile Include="Common\Automation\NarratorNotifier.cpp" />
|
||||
<ClCompile Include="Common\Automation\NotificationHost.cpp" />
|
||||
<ClCompile Include="Common\BindableBase.cpp" />
|
||||
<ClCompile Include="Common\CalculatorButtonPressedEventArgs.cpp" />
|
||||
<ClCompile Include="Common\CalculatorDisplay.cpp" />
|
||||
@@ -407,7 +400,6 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="StandardCalculatorViewModel.cpp" />
|
||||
<ClCompile Include="UnitConverterViewModel.cpp" />
|
||||
<ClCompile Include="ViewState.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CalcManager\CalcManager.vcxproj">
|
||||
@@ -440,12 +432,12 @@
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see https://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.UI.Xaml.2.0.181018003.1\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.UI.Xaml.2.2.190830001\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Common">
|
||||
<UniqueIdentifier>{1daab7c4-63f6-4266-a259-f34acad66d09}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Automation">
|
||||
<UniqueIdentifier>{8d4edf06-c312-4312-978a-b6c2beb8295a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="DataLoaders">
|
||||
<UniqueIdentifier>{0184f727-b8aa-4af8-a699-63f1b56e7853}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="GraphingCalculator">
|
||||
<UniqueIdentifier>{cf7dca32-9727-4f98-83c3-1c0ca7dd1e0c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="ApplicationViewModel.cpp" />
|
||||
<ClCompile Include="DateCalculatorViewModel.cpp" />
|
||||
<ClCompile Include="HistoryItemViewModel.cpp" />
|
||||
<ClCompile Include="HistoryViewModel.cpp" />
|
||||
<ClCompile Include="MemoryItemViewModel.cpp" />
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="StandardCalculatorViewModel.cpp" />
|
||||
<ClCompile Include="UnitConverterViewModel.cpp" />
|
||||
<ClCompile Include="ViewState.cpp" />
|
||||
<ClCompile Include="Common\AppResourceProvider.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
@@ -58,63 +71,53 @@
|
||||
<ClCompile Include="Common\Utils.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NarratorAnnouncementHostFactory.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NarratorNotifier.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NotificationHost.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\LiveRegionHost.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DataLoaders\UnitConverterDataLoader.cpp">
|
||||
<ClCompile Include="DataLoaders\CurrencyDataLoader.cpp">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DataLoaders\CurrencyHttpClient.cpp">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GraphingCalculator\GraphingCalculatorViewModel.cpp">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
<ClCompile Include="DataLoaders\UnitConverterDataLoader.cpp">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GraphingCalculator\EquationViewModel.cpp">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DataLoaders\CurrencyDataLoader.cpp">
|
||||
<Filter>DataLoaders</Filter>
|
||||
<ClCompile Include="GraphingCalculator\GraphingCalculatorViewModel.cpp">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="ApplicationViewModel.h" />
|
||||
<ClInclude Include="DateCalculatorViewModel.h" />
|
||||
<ClInclude Include="HistoryItemViewModel.h" />
|
||||
<ClInclude Include="HistoryViewModel.h" />
|
||||
<ClInclude Include="MemoryItemViewModel.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="StandardCalculatorViewModel.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="UnitConverterViewModel.h" />
|
||||
<ClInclude Include="ViewState.h" />
|
||||
<ClInclude Include="Common\AlwaysSelectedCollectionView.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\AppResourceProvider.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\BindableBase.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\AlwaysSelectedCollectionView.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\BitLength.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\CalculatorButtonPressedEventArgs.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\CalculatorButtonUser.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\CalculatorDisplay.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
@@ -145,25 +148,22 @@
|
||||
<ClInclude Include="Common\KeyboardShortcutManager.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\LocalizationStringUtil.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\LocalizationService.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\LocalizationSettings.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\NavCategory.h">
|
||||
<ClInclude Include="Common\LocalizationStringUtil.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\MyVirtualKey.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\NetworkManager.h">
|
||||
<ClInclude Include="Common\NavCategory.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\TraceActivity.h">
|
||||
<ClInclude Include="Common\NetworkManager.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\TraceLogger.h">
|
||||
@@ -175,26 +175,14 @@
|
||||
<ClInclude Include="Common\ValidatingConverters.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\CalculatorButtonUser.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\NarratorAnnouncement.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\NarratorAnnouncementHostFactory.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\NarratorNotifier.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\NotificationHost.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
<ClInclude Include="DataLoaders\CurrencyDataLoader.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\INarratorAnnouncementHost.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\LiveRegionHost.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
<ClInclude Include="DataLoaders\CurrencyHttpClient.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DataLoaders\ICurrencyHttpClient.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
@@ -205,43 +193,38 @@
|
||||
<ClInclude Include="DataLoaders\UnitConverterDataLoader.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\TraceActivity.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DataLoaders\DataLoaderMockConstants.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DataLoaders\CurrencyHttpClient.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
<ClInclude Include="Common\Automation\NarratorAnnouncement.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
<ClInclude Include="Common\BitLength.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\NumberBase.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculator\EquationViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DataLoaders\CurrencyDataLoader.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
<ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculatorEnums.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="DataLoaders\DefaultFromToCurrency.json">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Common\Automation">
|
||||
<UniqueIdentifier>{98717b14-c8c7-4fb6-9861-abb9124b34f0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="GraphingCalculator">
|
||||
<UniqueIdentifier>{07311281-a1fd-4dd9-baef-007f159e33ed}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common">
|
||||
<UniqueIdentifier>{14ddcbc1-10a4-4940-ad53-3a751b9ebea0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="DataLoaders">
|
||||
<UniqueIdentifier>{b017a5e6-6d25-4799-a517-99f88d65b82f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Page Include="$(MSBuildThisFileDirectory)DensityStyles\Compact.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -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"
|
||||
@@ -14,9 +14,9 @@ AppResourceProvider::AppResourceProvider()
|
||||
m_cEngineStringResLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
|
||||
}
|
||||
|
||||
AppResourceProvider& AppResourceProvider::GetInstance()
|
||||
AppResourceProvider ^ AppResourceProvider::GetInstance()
|
||||
{
|
||||
static AppResourceProvider s_instance;
|
||||
static AppResourceProvider ^ s_instance = ref new AppResourceProvider();
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
class AppResourceProvider
|
||||
public ref class AppResourceProvider sealed
|
||||
{
|
||||
public:
|
||||
static AppResourceProvider& GetInstance();
|
||||
static AppResourceProvider ^ GetInstance();
|
||||
Platform::String ^ GetResourceString(_In_ Platform::String ^ key);
|
||||
Platform::String ^ GetCEngineString(_In_ Platform::String ^ key);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
using namespace CalculatorApp::Common::Automation;
|
||||
using namespace Platform;
|
||||
using namespace Windows::UI::Xaml::Automation::Peers;
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
{
|
||||
|
||||
@@ -5,32 +5,6 @@
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
{
|
||||
// These enum types are copied from the types available in
|
||||
// Windows::UI::Xaml::Automation::Peers in the RS3 SDK.
|
||||
// When this app switches to min version RS3, these custom
|
||||
// enums should be removed and the Windows types should be used
|
||||
// instead.
|
||||
// TODO - MSFT 12735088
|
||||
public
|
||||
enum class AutomationNotificationKind
|
||||
{
|
||||
ItemAdded = 0,
|
||||
ItemRemoved = 1,
|
||||
ActionCompleted = 2,
|
||||
ActionAborted = 3,
|
||||
Other = 4
|
||||
};
|
||||
|
||||
public
|
||||
enum class AutomationNotificationProcessing
|
||||
{
|
||||
ImportantAll = 0,
|
||||
ImportantMostRecent = 1,
|
||||
All = 2,
|
||||
MostRecent = 3,
|
||||
CurrentThenMostRecent = 4
|
||||
};
|
||||
|
||||
public
|
||||
ref class NarratorAnnouncement sealed
|
||||
{
|
||||
@@ -41,14 +15,14 @@ public
|
||||
property Platform::String
|
||||
^ ActivityId { Platform::String ^ get(); }
|
||||
|
||||
property AutomationNotificationKind Kind
|
||||
property Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind Kind
|
||||
{
|
||||
AutomationNotificationKind get();
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind get();
|
||||
}
|
||||
|
||||
property AutomationNotificationProcessing Processing
|
||||
property Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing Processing
|
||||
{
|
||||
AutomationNotificationProcessing get();
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing get();
|
||||
}
|
||||
|
||||
static bool IsValid(NarratorAnnouncement ^ announcement);
|
||||
@@ -61,13 +35,13 @@ public
|
||||
NarratorAnnouncement(
|
||||
Platform::String ^ announcement,
|
||||
Platform::String ^ activityId,
|
||||
AutomationNotificationKind kind,
|
||||
AutomationNotificationProcessing processing);
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind kind,
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing processing);
|
||||
|
||||
Platform::String ^ m_announcement;
|
||||
Platform::String ^ m_activityId;
|
||||
AutomationNotificationKind m_kind;
|
||||
AutomationNotificationProcessing m_processing;
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind m_kind;
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing m_processing;
|
||||
};
|
||||
|
||||
// CalculatorAnnouncement is intended to contain only static methods
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "NarratorNotifier.h"
|
||||
#include "NarratorAnnouncementHostFactory.h"
|
||||
|
||||
using namespace CalculatorApp::Common::Automation;
|
||||
using namespace Platform;
|
||||
@@ -17,14 +16,22 @@ DependencyProperty ^ NarratorNotifier::s_announcementProperty;
|
||||
|
||||
NarratorNotifier::NarratorNotifier()
|
||||
{
|
||||
m_announcementHost = NarratorAnnouncementHostFactory::MakeHost();
|
||||
}
|
||||
|
||||
void NarratorNotifier::Announce(NarratorAnnouncement ^ announcement)
|
||||
{
|
||||
if (NarratorAnnouncement::IsValid(announcement) && m_announcementHost != nullptr)
|
||||
if (NarratorAnnouncement::IsValid(announcement))
|
||||
{
|
||||
m_announcementHost->Announce(announcement);
|
||||
if (m_announcementElement == nullptr)
|
||||
{
|
||||
m_announcementElement = ref new Windows::UI::Xaml::Controls::TextBlock();
|
||||
}
|
||||
|
||||
auto peer = FrameworkElementAutomationPeer::FromElement(m_announcementElement);
|
||||
if (peer != nullptr)
|
||||
{
|
||||
peer->RaiseNotificationEvent(announcement->Kind, announcement->Processing, announcement->Announcement, announcement->ActivityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// Declaration of the NarratorNotifier class.
|
||||
|
||||
#pragma once
|
||||
#include "INarratorAnnouncementHost.h"
|
||||
#include "NarratorAnnouncement.h"
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
{
|
||||
@@ -47,6 +47,6 @@ public
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_announcementProperty;
|
||||
|
||||
private:
|
||||
INarratorAnnouncementHost ^ m_announcementHost;
|
||||
Windows::UI::Xaml::UIElement ^ m_announcementElement;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,6 +63,10 @@ public
|
||||
IsStandardMode = (int)CM::Command::ModeBasic,
|
||||
None = (int)CM::Command::CommandNULL,
|
||||
IsProgrammerMode = (int)CM::Command::ModeProgrammer,
|
||||
DecButton = (int)CM::Command::CommandDec,
|
||||
OctButton = (int)CM::Command::CommandOct,
|
||||
HexButton = (int)CM::Command::CommandHex,
|
||||
BinButton = (int)CM::Command::CommandBin,
|
||||
And = (int)CM::Command::CommandAnd,
|
||||
Ror = (int)CM::Command::CommandROR,
|
||||
Rol = (int)CM::Command::CommandROL,
|
||||
@@ -84,17 +88,38 @@ public
|
||||
InvSinh = (int)CM::Command::CommandASINH,
|
||||
InvCosh = (int)CM::Command::CommandACOSH,
|
||||
InvTanh = (int)CM::Command::CommandATANH,
|
||||
Cube = (int) CM::Command::CommandCUB,
|
||||
DMS = (int) CM::Command::CommandDMS,
|
||||
Hyp = (int)CM::Command::CommandHYP,
|
||||
HexButton = (int)CM::Command::CommandHex,
|
||||
DecButton = (int)CM::Command::CommandDec,
|
||||
OctButton = (int)CM::Command::CommandOct,
|
||||
BinButton = (int)CM::Command::CommandBin,
|
||||
Qword = (int)CM::Command::CommandQword,
|
||||
Dword = (int)CM::Command::CommandDword,
|
||||
Word = (int)CM::Command::CommandWord,
|
||||
Byte = (int)CM::Command::CommandByte,
|
||||
Cube = (int)CM::Command::CommandCUB,
|
||||
DMS = (int)CM::Command::CommandDMS,
|
||||
Hyp = (int) CM::Command::CommandHYP,
|
||||
Sec = (int) CM::Command::CommandSEC,
|
||||
Csc = (int) CM::Command::CommandCSC,
|
||||
Cot = (int) CM::Command::CommandCOT,
|
||||
InvSec = (int) CM::Command::CommandASEC,
|
||||
InvCsc = (int) CM::Command::CommandACSC,
|
||||
InvCot = (int) CM::Command::CommandACOT,
|
||||
Sech = (int) CM::Command::CommandSECH,
|
||||
Csch = (int) CM::Command::CommandCSCH,
|
||||
Coth = (int) CM::Command::CommandCOTH,
|
||||
InvSech = (int) CM::Command::CommandASECH,
|
||||
InvCsch = (int) CM::Command::CommandACSCH,
|
||||
InvCoth = (int) CM::Command::CommandACOTH,
|
||||
CubeRoot = (int) CM::Command::CommandCUBEROOT,
|
||||
TwoPowerX = (int) CM::Command::CommandPOW2,
|
||||
LogBaseX = (int) CM::Command::CommandLogBaseX,
|
||||
Nand = (int) CM::Command::CommandNand,
|
||||
Nor = (int) CM::Command::CommandNor,
|
||||
Abs = (int) CM::Command::CommandAbs,
|
||||
Floor = (int) CM::Command::CommandFloor,
|
||||
Ceil = (int) CM::Command::CommandCeil,
|
||||
Rand = (int) CM::Command::CommandRand,
|
||||
Euler = (int) CM::Command::CommandEuler,
|
||||
RshL = (int)CM::Command::CommandRSHFL,
|
||||
RolC = (int)CM::Command::CommandROLC,
|
||||
RorC = (int)CM::Command::CommandRORC,
|
||||
|
||||
Plot,
|
||||
X,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculationManager;
|
||||
using namespace Platform;
|
||||
using namespace std;
|
||||
|
||||
CalculatorDisplay::CalculatorDisplay()
|
||||
@@ -31,7 +32,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetPrimaryDisplay(displayStringValue, isError);
|
||||
calcVM->SetPrimaryDisplay(StringReference(displayStringValue.c_str()), isError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,8 +71,8 @@ void CalculatorDisplay::SetIsInError(bool isError)
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands)
|
||||
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
@@ -136,3 +137,14 @@ void CalculatorDisplay::MemoryItemChanged(unsigned int indexOfMemory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::InputChanged()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnInputChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace CalculatorApp
|
||||
void SetPrimaryDisplay(_In_ const std::wstring& displayString, _In_ bool isError) override;
|
||||
void SetIsInError(bool isError) override;
|
||||
void SetExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) override;
|
||||
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands) override;
|
||||
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
|
||||
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
|
||||
void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
|
||||
@@ -28,6 +28,7 @@ namespace CalculatorApp
|
||||
void MaxDigitsReached() override;
|
||||
void BinaryOperatorReceived() override;
|
||||
void MemoryItemChanged(unsigned int indexOfMemory) override;
|
||||
void InputChanged() override;
|
||||
|
||||
private:
|
||||
Platform::WeakReference m_callbackReference;
|
||||
|
||||
@@ -11,13 +11,18 @@ using namespace concurrency;
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::ApplicationModel::DataTransfer;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
|
||||
String ^ CopyPasteManager::supportedFormats[] = { StandardDataFormats::Text };
|
||||
StringReference PasteErrorString(L"NoOp");
|
||||
|
||||
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
|
||||
@@ -26,7 +31,8 @@ static const wstring c_wspc = L"[\\s\\x85]*";
|
||||
static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc;
|
||||
static const wstring c_wspcLParenSigned = c_wspc + L"([-+]?[(])*" + c_wspc;
|
||||
static const wstring c_wspcRParens = c_wspc + L"[)]*" + c_wspc;
|
||||
static const wstring c_signedDecFloat = L"[-+]?\\d*(\\d|[.])\\d*";
|
||||
static const wstring c_signedDecFloat = L"(?:[-+]?(?:\\d+(\\.\\d*)?|\\.\\d+))";
|
||||
static const wstring c_optionalENotation = L"(?:e[+-]?\\d+)?";
|
||||
|
||||
// Programmer Mode Integer patterns
|
||||
// Support digit separators ` (WinDbg/MASM), ' (C++), and _ (C# and other languages)
|
||||
@@ -37,11 +43,9 @@ static const wstring c_binProgrammerChars = L"[0-1]+((_|'|`)[0-1]+)*";
|
||||
static const wstring c_uIntSuffixes = L"[uU]?[lL]{0,2}";
|
||||
|
||||
// RegEx Patterns used by various modes
|
||||
static const array<wregex, 1> standardModePatterns = { wregex(c_wspc + c_signedDecFloat + c_wspc) };
|
||||
static const array<wregex, 2> scientificModePatterns = {
|
||||
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_wspcRParens),
|
||||
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + L"e[+-]?\\d+" + c_wspcRParens)
|
||||
};
|
||||
static const array<wregex, 1> standardModePatterns = { wregex(c_wspc + c_signedDecFloat + c_optionalENotation + c_wspc) };
|
||||
static const array<wregex, 1> scientificModePatterns = { wregex(
|
||||
L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_optionalENotation + c_wspcRParens) };
|
||||
static const array<array<wregex, 5>, 4> programmerModePatterns = {
|
||||
{ // Hex numbers like 5F, 4A0C, 0xa9, 0xFFull, 47CDh
|
||||
{ wregex(c_wspcLParens + L"(0[xX])?" + c_hexProgrammerChars + c_uIntSuffixes + c_wspcRParens),
|
||||
@@ -55,7 +59,7 @@ static const array<array<wregex, 5>, 4> programmerModePatterns = {
|
||||
{ wregex(c_wspcLParens + L"(0[byBY])?" + c_binProgrammerChars + c_uIntSuffixes + c_wspcRParens),
|
||||
wregex(c_wspcLParens + c_binProgrammerChars + L"[bB]?" + c_wspcRParens) } }
|
||||
};
|
||||
static const array<wregex, 1> unitConverterPatterns = { wregex(c_wspc + L"[-+]?\\d*[.]?\\d*" + c_wspc) };
|
||||
static const array<wregex, 1> unitConverterPatterns = { wregex(c_wspc + c_signedDecFloat + c_wspc) };
|
||||
|
||||
void CopyPasteManager::CopyToClipboard(String ^ stringToCopy)
|
||||
{
|
||||
@@ -65,7 +69,7 @@ void CopyPasteManager::CopyToClipboard(String ^ stringToCopy)
|
||||
Clipboard::SetContent(dataPackage);
|
||||
}
|
||||
|
||||
task<String ^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType)
|
||||
IAsyncOperation<String ^> ^ CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupType modeType, NumberBase programmerNumberBase, BitLength bitLengthType)
|
||||
{
|
||||
// Retrieve the text in the clipboard
|
||||
auto dataPackageView = Clipboard::GetContent();
|
||||
@@ -75,51 +79,47 @@ task<String ^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupTy
|
||||
//-- add support to allow pasting for expressions like .2 , -.2
|
||||
//-- add support to allow pasting for expressions like 1.3e12(as of now we allow 1.3e+12)
|
||||
|
||||
return create_task((dataPackageView->GetTextAsync(::StandardDataFormats::Text)))
|
||||
.then(
|
||||
[mode, modeType, programmerNumberBase, bitLengthType](String ^ pastedText) {
|
||||
return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType);
|
||||
},
|
||||
task_continuation_context::use_arbitrary());
|
||||
return create_async([dataPackageView, mode, modeType, programmerNumberBase, bitLengthType] {
|
||||
return create_task(dataPackageView->GetTextAsync(::StandardDataFormats::Text))
|
||||
.then(
|
||||
[mode, modeType, programmerNumberBase, bitLengthType](String ^ pastedText) {
|
||||
return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType);
|
||||
},
|
||||
task_continuation_context::use_arbitrary());
|
||||
});
|
||||
}
|
||||
|
||||
int CopyPasteManager::ClipboardTextFormat()
|
||||
bool CopyPasteManager::HasStringToPaste()
|
||||
{
|
||||
const auto dataPackageView = Clipboard::GetContent();
|
||||
|
||||
for (int i = 0; i < RTL_NUMBER_OF(supportedFormats); i++)
|
||||
{
|
||||
if (dataPackageView->Contains(supportedFormats[i]))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return Clipboard::GetContent()->Contains(StandardDataFormats::Text);
|
||||
}
|
||||
|
||||
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, int programmerNumberBase, BitLength bitLengthType)
|
||||
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, NumberBase programmerNumberBase, BitLength bitLengthType)
|
||||
{
|
||||
return CopyPasteManager::ValidatePasteExpression(pastedText, mode, NavCategory::GetGroupType(mode), programmerNumberBase, bitLengthType);
|
||||
return ValidatePasteExpression(pastedText, mode, NavCategory::GetGroupType(mode), programmerNumberBase, bitLengthType);
|
||||
}
|
||||
|
||||
// return "NoOp" if pastedText is invalid else return pastedText
|
||||
|
||||
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType)
|
||||
String
|
||||
^ CopyPasteManager::ValidatePasteExpression(
|
||||
String ^ pastedText,
|
||||
ViewMode mode,
|
||||
CategoryGroupType modeType,
|
||||
NumberBase programmerNumberBase,
|
||||
BitLength bitLengthType)
|
||||
{
|
||||
if (pastedText->Length() > MaxPasteableLength)
|
||||
{
|
||||
// return NoOp to indicate don't paste anything.
|
||||
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"PastedExpressionSizeGreaterThanMaxAllowed");
|
||||
return StringReference(PasteErrorString);
|
||||
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"PastedExpressionSizeGreaterThanMaxAllowed");
|
||||
return PasteErrorString;
|
||||
}
|
||||
|
||||
wstring pasteExpression = pastedText->Data();
|
||||
|
||||
// Get english translated expression
|
||||
String ^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression);
|
||||
String ^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pastedText);
|
||||
|
||||
// Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333
|
||||
pasteExpression = RemoveUnwantedCharsFromWstring(englishString->Data());
|
||||
auto pasteExpression = wstring(RemoveUnwantedCharsFromString(englishString)->Data());
|
||||
|
||||
// If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste.
|
||||
if (!pasteExpression.empty() && pasteExpression.back() == L'=')
|
||||
@@ -129,31 +129,32 @@ String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode
|
||||
|
||||
// Extract operands from the expression to make regex comparison easy and quick. For whole expression it was taking too much of time.
|
||||
// Operands vector will have the list of operands in the pasteExpression
|
||||
vector<wstring> operands = ExtractOperands(pasteExpression, mode);
|
||||
if (operands.empty())
|
||||
auto operands = ExtractOperands(StringReference(pasteExpression.c_str()), mode);
|
||||
if (operands->Size == 0)
|
||||
{
|
||||
// return NoOp to indicate don't paste anything.
|
||||
return StringReference(PasteErrorString);
|
||||
return PasteErrorString;
|
||||
}
|
||||
|
||||
if (modeType == CategoryGroupType::Converter)
|
||||
{
|
||||
operands = { pasteExpression };
|
||||
operands->Clear();
|
||||
operands->Append(ref new String(pasteExpression.c_str()));
|
||||
}
|
||||
|
||||
// validate each operand with patterns for different modes
|
||||
if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType))
|
||||
{
|
||||
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"InvalidExpressionForPresentMode");
|
||||
return StringReference(PasteErrorString);
|
||||
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ValidatePasteExpression", L"InvalidExpressionForPresentMode");
|
||||
return PasteErrorString;
|
||||
}
|
||||
|
||||
return ref new String(pastedText->Data());
|
||||
return pastedText;
|
||||
}
|
||||
|
||||
vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression, ViewMode mode)
|
||||
IVector<Platform::String ^> ^ CopyPasteManager::ExtractOperands(Platform::String ^ pasteExpression, ViewMode mode)
|
||||
{
|
||||
vector<wstring> operands{};
|
||||
auto operands = ref new Vector<Platform::String ^>();
|
||||
size_t lastIndex = 0;
|
||||
bool haveOperator = false;
|
||||
bool startExpCounting = false;
|
||||
@@ -161,51 +162,72 @@ 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++)
|
||||
int i = -1;
|
||||
for (auto currentChar : pasteExpression)
|
||||
{
|
||||
++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;
|
||||
}
|
||||
|
||||
if (operands.size() >= MaxOperandCount)
|
||||
if (operands->Size >= MaxOperandCount)
|
||||
{
|
||||
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ExtractOperands", L"OperandCountGreaterThanMaxCount");
|
||||
operands.clear();
|
||||
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ExtractOperands", L"OperandCountGreaterThanMaxCount");
|
||||
operands->Clear();
|
||||
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++;
|
||||
|
||||
// to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999.
|
||||
if (expLength > MaxExponentLength)
|
||||
{
|
||||
TraceLogger::GetInstance().LogError(mode, L"CopyPasteManager::ExtractOperands", L"ExponentLengthGreaterThanMaxLength");
|
||||
operands.clear();
|
||||
TraceLogger::GetInstance()->LogError(mode, L"CopyPasteManager::ExtractOperands", L"ExponentLengthGreaterThanMaxLength");
|
||||
operands->Clear();
|
||||
return operands;
|
||||
}
|
||||
}
|
||||
isPreviousOperator = false;
|
||||
}
|
||||
|
||||
if ((mode != ViewMode::Programmer) && (pasteExpression.at(i) == L'e'))
|
||||
else if (currentChar == L'e')
|
||||
{
|
||||
startExpCounting = true;
|
||||
if (mode != ViewMode::Programmer)
|
||||
{
|
||||
startExpCounting = true;
|
||||
}
|
||||
isPreviousOperator = false;
|
||||
}
|
||||
|
||||
if (((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-') || (pasteExpression.at(i) == L'*') || (pasteExpression.at(i) == L'/')))
|
||||
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
|
||||
|| ((mode != ViewMode::Programmer) && !((i != 0) && (pasteExpression.at(i - 1) != L'e'))))
|
||||
|| ((mode != ViewMode::Programmer) && !((i != 0) && pasteExpression->Data()[i - 1] != L'e')))
|
||||
{
|
||||
isPreviousOperator = false;
|
||||
continue;
|
||||
@@ -216,7 +238,7 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
|
||||
expLength = 0;
|
||||
haveOperator = true;
|
||||
isPreviousOperator = true;
|
||||
operands.push_back(pasteExpression.substr(lastIndex, i - lastIndex));
|
||||
operands->Append(ref new String(wstring(pasteExpression->Data()).substr(lastIndex, i - lastIndex).c_str()));
|
||||
lastIndex = i + 1;
|
||||
}
|
||||
else
|
||||
@@ -224,26 +246,31 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
|
||||
isPreviousOperator = false;
|
||||
}
|
||||
|
||||
isPreviousOpenParen = (pasteExpression.at(i) == L'(');
|
||||
isPreviousOpenParen = (currentChar == L'(');
|
||||
startOfExpression = false;
|
||||
}
|
||||
|
||||
if (!haveOperator)
|
||||
{
|
||||
operands.clear();
|
||||
operands.push_back(pasteExpression);
|
||||
operands->Clear();
|
||||
operands->Append(pasteExpression);
|
||||
}
|
||||
else
|
||||
{
|
||||
operands.push_back(pasteExpression.substr(lastIndex, pasteExpression.length() - 1));
|
||||
operands->Append(ref new String(wstring(pasteExpression->Data()).substr(lastIndex, pasteExpression->Length() - 1).c_str()));
|
||||
}
|
||||
|
||||
return operands;
|
||||
}
|
||||
|
||||
bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType)
|
||||
bool CopyPasteManager::ExpressionRegExMatch(
|
||||
IVector<String ^> ^ operands,
|
||||
ViewMode mode,
|
||||
CategoryGroupType modeType,
|
||||
NumberBase programmerNumberBase,
|
||||
BitLength bitLengthType)
|
||||
{
|
||||
if (operands.empty())
|
||||
if (operands->Size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -260,14 +287,16 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
|
||||
}
|
||||
else if (mode == ViewMode::Programmer)
|
||||
{
|
||||
patterns.assign(programmerModePatterns[programmerNumberBase - HexBase].begin(), programmerModePatterns[programmerNumberBase - HexBase].end());
|
||||
patterns.assign(
|
||||
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].begin(),
|
||||
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].end());
|
||||
}
|
||||
else if (modeType == CategoryGroupType::Converter)
|
||||
{
|
||||
patterns.assign(unitConverterPatterns.begin(), unitConverterPatterns.end());
|
||||
}
|
||||
|
||||
const auto [maxOperandLength, maxOperandValue] = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType);
|
||||
auto maxOperandLengthAndValue = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType);
|
||||
bool expMatched = true;
|
||||
|
||||
for (const auto& operand : operands)
|
||||
@@ -276,34 +305,34 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
|
||||
bool operandMatched = false;
|
||||
for (const auto& pattern : patterns)
|
||||
{
|
||||
operandMatched = operandMatched || regex_match(operand, pattern);
|
||||
operandMatched = operandMatched || regex_match(operand->Data(), pattern);
|
||||
}
|
||||
|
||||
if (operandMatched)
|
||||
{
|
||||
// Remove characters that are valid in the expression but we do not want to include in length calculations
|
||||
// or which will break conversion from string-to-ULL.
|
||||
const wstring operandValue = SanitizeOperand(operand);
|
||||
auto operandValue = SanitizeOperand(operand);
|
||||
|
||||
// If an operand exceeds the maximum length allowed, break and return.
|
||||
if (OperandLength(operandValue, mode, modeType, programmerNumberBase) > maxOperandLength)
|
||||
if (OperandLength(operandValue, mode, modeType, programmerNumberBase) > maxOperandLengthAndValue.maxLength)
|
||||
{
|
||||
expMatched = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// If maxOperandValue is set and the operandValue exceeds it, break and return.
|
||||
if (maxOperandValue != 0)
|
||||
if (maxOperandLengthAndValue.maxValue != 0)
|
||||
{
|
||||
unsigned long long int operandAsULL = 0;
|
||||
if (!TryOperandToULL(operandValue, programmerNumberBase, operandAsULL))
|
||||
auto operandAsULL = TryOperandToULL(operandValue, programmerNumberBase);
|
||||
if (operandAsULL == nullptr)
|
||||
{
|
||||
// Operand was empty, received invalid_argument, or received out_of_range. Input is invalid.
|
||||
expMatched = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (operandAsULL > maxOperandValue)
|
||||
if (operandAsULL->Value > maxOperandLengthAndValue.maxValue)
|
||||
{
|
||||
expMatched = false;
|
||||
break;
|
||||
@@ -317,18 +346,23 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
|
||||
return expMatched;
|
||||
}
|
||||
|
||||
pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, BitLength bitLengthType)
|
||||
CopyPasteMaxOperandLengthAndValue
|
||||
CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, NumberBase programmerNumberBase, BitLength bitLengthType)
|
||||
{
|
||||
constexpr size_t defaultMaxOperandLength = 0;
|
||||
constexpr uint64_t defaultMaxValue = 0;
|
||||
|
||||
CopyPasteMaxOperandLengthAndValue res;
|
||||
if (mode == ViewMode::Standard)
|
||||
{
|
||||
return make_pair(MaxStandardOperandLength, defaultMaxValue);
|
||||
res.maxLength = MaxStandardOperandLength;
|
||||
res.maxValue = defaultMaxValue;
|
||||
return res;
|
||||
}
|
||||
else if (mode == ViewMode::Scientific)
|
||||
{
|
||||
return make_pair(MaxScientificOperandLength, defaultMaxValue);
|
||||
res.maxLength = MaxScientificOperandLength;
|
||||
res.maxValue = defaultMaxValue;
|
||||
return res;
|
||||
}
|
||||
else if (mode == ViewMode::Programmer)
|
||||
{
|
||||
@@ -352,65 +386,69 @@ pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo
|
||||
double bitsPerDigit = 0;
|
||||
switch (programmerNumberBase)
|
||||
{
|
||||
case BinBase:
|
||||
case NumberBase::BinBase:
|
||||
bitsPerDigit = log2(2);
|
||||
break;
|
||||
case OctBase:
|
||||
case NumberBase::OctBase:
|
||||
bitsPerDigit = log2(8);
|
||||
break;
|
||||
case DecBase:
|
||||
case NumberBase::DecBase:
|
||||
bitsPerDigit = log2(10);
|
||||
break;
|
||||
case HexBase:
|
||||
case NumberBase::HexBase:
|
||||
bitsPerDigit = log2(16);
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int signBit = (programmerNumberBase == DecBase) ? 1 : 0;
|
||||
unsigned int signBit = (programmerNumberBase == NumberBase::DecBase) ? 1 : 0;
|
||||
|
||||
const auto maxLength = static_cast<size_t>(ceil((bitLength - signBit) / bitsPerDigit));
|
||||
const auto maxLength = static_cast<unsigned int>(ceil((bitLength - signBit) / bitsPerDigit));
|
||||
const uint64_t maxValue = UINT64_MAX >> (MaxProgrammerBitLength - (bitLength - signBit));
|
||||
|
||||
return make_pair(maxLength, maxValue);
|
||||
res.maxLength = maxLength;
|
||||
res.maxValue = maxValue;
|
||||
return res;
|
||||
}
|
||||
else if (modeType == CategoryGroupType::Converter)
|
||||
{
|
||||
return make_pair(MaxConverterInputLength, defaultMaxValue);
|
||||
res.maxLength = MaxConverterInputLength;
|
||||
res.maxValue = defaultMaxValue;
|
||||
return res;
|
||||
}
|
||||
|
||||
return make_pair(defaultMaxOperandLength, defaultMaxValue);
|
||||
res.maxLength = defaultMaxOperandLength;
|
||||
res.maxValue = defaultMaxValue;
|
||||
return res;
|
||||
}
|
||||
|
||||
wstring CopyPasteManager::SanitizeOperand(const wstring& operand)
|
||||
Platform::String ^ CopyPasteManager::SanitizeOperand(Platform::String ^ operand)
|
||||
{
|
||||
wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-', L'+' };
|
||||
constexpr wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-', L'+' };
|
||||
|
||||
return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, static_cast<int>(size(unWantedChars)));
|
||||
return ref new String(Utils::RemoveUnwantedCharsFromString(operand->Data(), unWantedChars).c_str());
|
||||
}
|
||||
|
||||
bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, unsigned long long int& result)
|
||||
IBox<unsigned long long int> ^ CopyPasteManager::TryOperandToULL(String ^ operand, NumberBase numberBase)
|
||||
{
|
||||
result = 0;
|
||||
|
||||
if (operand.length() == 0 || operand.front() == L'-')
|
||||
if (operand->Length() == 0 || operand->Data()[0] == L'-')
|
||||
{
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int intBase;
|
||||
switch (numberBase)
|
||||
{
|
||||
case HexBase:
|
||||
case NumberBase::HexBase:
|
||||
intBase = 16;
|
||||
break;
|
||||
case OctBase:
|
||||
case NumberBase::OctBase:
|
||||
intBase = 8;
|
||||
break;
|
||||
case BinBase:
|
||||
case NumberBase::BinBase:
|
||||
intBase = 2;
|
||||
break;
|
||||
default:
|
||||
case DecBase:
|
||||
case NumberBase::DecBase:
|
||||
intBase = 10;
|
||||
break;
|
||||
}
|
||||
@@ -418,8 +456,7 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
|
||||
wstring::size_type size = 0;
|
||||
try
|
||||
{
|
||||
result = stoull(operand, &size, intBase);
|
||||
return true;
|
||||
return stoull(operand->Data(), &size, intBase);
|
||||
}
|
||||
catch (const invalid_argument&)
|
||||
{
|
||||
@@ -430,14 +467,14 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t CopyPasteManager::OperandLength(const wstring& operand, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase)
|
||||
ULONG32 CopyPasteManager::OperandLength(Platform::String ^ operand, ViewMode mode, CategoryGroupType modeType, NumberBase programmerNumberBase)
|
||||
{
|
||||
if (modeType == CategoryGroupType::Converter)
|
||||
{
|
||||
return operand.length();
|
||||
return operand->Length();
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
@@ -454,45 +491,46 @@ size_t CopyPasteManager::OperandLength(const wstring& operand, ViewMode mode, Ca
|
||||
}
|
||||
}
|
||||
|
||||
size_t CopyPasteManager::StandardScientificOperandLength(const wstring& operand)
|
||||
ULONG32 CopyPasteManager::StandardScientificOperandLength(Platform::String ^ operand)
|
||||
{
|
||||
const bool hasDecimal = operand.find('.') != wstring::npos;
|
||||
auto operandWstring = wstring(operand->Data());
|
||||
const bool hasDecimal = operandWstring.find('.') != wstring::npos;
|
||||
|
||||
if (hasDecimal)
|
||||
{
|
||||
if (operand.length() >= 2)
|
||||
if (operandWstring.length() >= 2)
|
||||
{
|
||||
if ((operand[0] == L'0') && (operand[1] == L'.'))
|
||||
if ((operandWstring[0] == L'0') && (operandWstring[1] == L'.'))
|
||||
{
|
||||
return operand.length() - 2;
|
||||
return static_cast<ULONG32>(operandWstring.length() - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return operand.length() - 1;
|
||||
return static_cast<ULONG32>(operandWstring.length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return operand.length();
|
||||
return static_cast<ULONG32>(operandWstring.length());
|
||||
}
|
||||
|
||||
size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int numberBase)
|
||||
ULONG32 CopyPasteManager::ProgrammerOperandLength(Platform::String ^ operand, NumberBase numberBase)
|
||||
{
|
||||
vector<wstring> prefixes{};
|
||||
vector<wstring> suffixes{};
|
||||
switch (numberBase)
|
||||
{
|
||||
case BinBase:
|
||||
case NumberBase::BinBase:
|
||||
prefixes = { L"0B", L"0Y" };
|
||||
suffixes = { L"B" };
|
||||
break;
|
||||
case DecBase:
|
||||
case NumberBase::DecBase:
|
||||
prefixes = { L"-", L"0N" };
|
||||
break;
|
||||
case OctBase:
|
||||
case NumberBase::OctBase:
|
||||
prefixes = { L"0T", L"0O" };
|
||||
break;
|
||||
case HexBase:
|
||||
case NumberBase::HexBase:
|
||||
prefixes = { L"0X" };
|
||||
suffixes = { L"H" };
|
||||
break;
|
||||
@@ -505,10 +543,10 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
|
||||
const array<wstring, 5> uintSuffixes = { L"ULL", L"UL", L"LL", L"U", L"L" };
|
||||
suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end());
|
||||
|
||||
wstring operandUpper = operand;
|
||||
wstring operandUpper = wstring(operand->Data());
|
||||
transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper);
|
||||
|
||||
size_t len = operand.length();
|
||||
size_t len = operand->Length();
|
||||
|
||||
// Detect if there is a suffix and subtract its length
|
||||
// Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value).
|
||||
@@ -541,7 +579,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
return static_cast<ULONG32>(len);
|
||||
}
|
||||
|
||||
// return wstring after removing characters like space, comma, double quotes, and monetary prefix currency symbols supported by the Windows keyboard:
|
||||
@@ -556,8 +594,13 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
|
||||
// Indian rupee(₹) - 8377
|
||||
// pound(£) - 163
|
||||
// euro(€) - 8364
|
||||
wstring CopyPasteManager::RemoveUnwantedCharsFromWstring(const wstring& input)
|
||||
Platform::String ^ CopyPasteManager::RemoveUnwantedCharsFromString(Platform::String ^ input)
|
||||
{
|
||||
wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 };
|
||||
return Utils::RemoveUnwantedCharsFromWstring(input, unWantedChars, 18);
|
||||
constexpr wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 };
|
||||
return ref new String(Utils::RemoveUnwantedCharsFromString(input->Data(), unWantedChars).c_str());
|
||||
}
|
||||
|
||||
bool CopyPasteManager::IsErrorMessage(Platform::String ^ message)
|
||||
{
|
||||
return message == PasteErrorString;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "AppResourceProvider.h"
|
||||
#include "NavCategory.h"
|
||||
#include "BitLength.h"
|
||||
#include "NumberBase.h"
|
||||
|
||||
namespace CalculatorUnitTests
|
||||
{
|
||||
@@ -14,78 +15,119 @@ namespace CalculatorUnitTests
|
||||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
inline constexpr auto HexBase = 5;
|
||||
inline constexpr auto DecBase = 6;
|
||||
inline constexpr auto OctBase = 7;
|
||||
inline constexpr auto BinBase = 8;
|
||||
public
|
||||
value struct CopyPasteMaxOperandLengthAndValue
|
||||
{
|
||||
unsigned int maxLength;
|
||||
unsigned long long maxValue;
|
||||
};
|
||||
|
||||
class CopyPasteManager
|
||||
public ref class CopyPasteManager sealed
|
||||
{
|
||||
public:
|
||||
static void CopyToClipboard(Platform::String ^ stringToCopy);
|
||||
static concurrency::task<Platform::String ^> GetStringToPaste(
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
int programmerNumberBase = -1,
|
||||
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown);
|
||||
static bool HasStringToPaste()
|
||||
static Windows::Foundation::IAsyncOperation<
|
||||
Platform::String
|
||||
^> ^ GetStringToPaste(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, CalculatorApp::Common::NumberBase programmerNumberBase, CalculatorApp::Common::BitLength bitLengthType);
|
||||
static bool HasStringToPaste();
|
||||
static bool IsErrorMessage(Platform::String ^ message);
|
||||
static property unsigned int MaxPasteableLength
|
||||
{
|
||||
return ClipboardTextFormat() >= 0;
|
||||
unsigned int get()
|
||||
{
|
||||
return MaxPasteableLengthValue;
|
||||
}
|
||||
}
|
||||
static property unsigned int MaxOperandCount
|
||||
{
|
||||
unsigned int get()
|
||||
{
|
||||
return MaxOperandCountValue;
|
||||
}
|
||||
}
|
||||
static property unsigned int MaxStandardOperandLength
|
||||
{
|
||||
unsigned int get()
|
||||
{
|
||||
return MaxStandardOperandLengthValue;
|
||||
}
|
||||
}
|
||||
static property unsigned int MaxScientificOperandLength
|
||||
{
|
||||
unsigned int get()
|
||||
{
|
||||
return MaxScientificOperandLengthValue;
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr auto PasteErrorString = L"NoOp";
|
||||
static property unsigned int MaxConverterInputLength
|
||||
{
|
||||
unsigned int get()
|
||||
{
|
||||
return MaxConverterInputLengthValue;
|
||||
}
|
||||
}
|
||||
|
||||
static property unsigned int MaxExponentLength
|
||||
{
|
||||
unsigned int get()
|
||||
{
|
||||
return MaxExponentLengthValue;
|
||||
}
|
||||
}
|
||||
|
||||
static property unsigned int MaxProgrammerBitLength
|
||||
{
|
||||
unsigned int get()
|
||||
{
|
||||
return MaxProgrammerBitLengthValue;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static int ClipboardTextFormat();
|
||||
static Platform::String
|
||||
^ ValidatePasteExpression(
|
||||
Platform::String ^ pastedText,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
int programmerNumberBase,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
static Platform::String
|
||||
^ ValidatePasteExpression(
|
||||
Platform::String ^ pastedText,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
int programmerNumberBase,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
|
||||
static std::vector<std::wstring>
|
||||
ExtractOperands(const std::wstring& pasteExpression, CalculatorApp::Common::ViewMode mode);
|
||||
static CopyPasteMaxOperandLengthAndValue GetMaxOperandLengthAndValue(
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
static Windows::Foundation::Collections::IVector<
|
||||
Platform::String ^> ^ ExtractOperands(Platform::String ^ pasteExpression, CalculatorApp::Common::ViewMode mode);
|
||||
static bool ExpressionRegExMatch(
|
||||
std::vector<std::wstring> operands,
|
||||
Windows::Foundation::Collections::IVector<Platform::String ^> ^ operands,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
int programmerNumberBase = -1,
|
||||
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown);
|
||||
|
||||
static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
static Platform::String ^ SanitizeOperand(Platform::String ^ operand);
|
||||
static Platform::String ^ RemoveUnwantedCharsFromString(Platform::String ^ input);
|
||||
static Platform::IBox<unsigned long long int> ^ TryOperandToULL(Platform::String ^ operand, CalculatorApp::Common::NumberBase numberBase);
|
||||
static ULONG32 StandardScientificOperandLength(Platform::String ^ operand);
|
||||
static ULONG32 OperandLength(
|
||||
Platform::String ^ operand,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
int programmerNumberBase = -1,
|
||||
CalculatorApp::Common::BitLength bitLengthType = CalculatorApp::Common::BitLength::BitLengthUnknown);
|
||||
static std::wstring SanitizeOperand(const std::wstring& operand);
|
||||
static bool TryOperandToULL(const std::wstring& operand, int numberBase, unsigned long long int& result);
|
||||
static size_t OperandLength(
|
||||
const std::wstring& operand,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
int programmerNumberBase = -1);
|
||||
static size_t StandardScientificOperandLength(const std::wstring& operand);
|
||||
static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase);
|
||||
static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input);
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase);
|
||||
static ULONG32 ProgrammerOperandLength(Platform::String ^ operand, CalculatorApp::Common::NumberBase numberBase);
|
||||
|
||||
static constexpr size_t MaxStandardOperandLength = 16;
|
||||
static constexpr size_t MaxScientificOperandLength = 32;
|
||||
static constexpr size_t MaxConverterInputLength = 16;
|
||||
static constexpr size_t MaxOperandCount = 100;
|
||||
static constexpr size_t MaxPasteableLength = 512;
|
||||
static constexpr size_t MaxExponentLength = 4;
|
||||
static constexpr size_t MaxProgrammerBitLength = 64;
|
||||
|
||||
static Platform::String ^ supportedFormats[];
|
||||
|
||||
friend class CalculatorUnitTests::CopyPasteManagerTest;
|
||||
private:
|
||||
static constexpr size_t MaxStandardOperandLengthValue = 16;
|
||||
static constexpr size_t MaxScientificOperandLengthValue = 32;
|
||||
static constexpr size_t MaxConverterInputLengthValue = 16;
|
||||
static constexpr size_t MaxOperandCountValue = 100;
|
||||
static constexpr size_t MaxExponentLengthValue = 4;
|
||||
static constexpr size_t MaxProgrammerBitLengthValue = 64;
|
||||
static constexpr size_t MaxPasteableLengthValue = 512;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@ using namespace Windows::Foundation;
|
||||
using namespace Windows::Globalization;
|
||||
using namespace CalculatorApp::Common::DateCalculation;
|
||||
|
||||
bool operator==(const DateDifference& l, const DateDifference& r)
|
||||
{
|
||||
return l.year == r.year && l.month == r.month && l.week == r.week && l.day == r.day;
|
||||
}
|
||||
|
||||
DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier)
|
||||
{
|
||||
m_calendar = ref new Calendar();
|
||||
@@ -18,10 +23,9 @@ DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier)
|
||||
|
||||
// Adding Duration to a Date
|
||||
// Returns: True if function succeeds to calculate the date else returns False
|
||||
bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate)
|
||||
IBox<DateTime> ^ DateCalculationEngine::AddDuration(DateTime startDate, DateDifference duration)
|
||||
{
|
||||
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
|
||||
|
||||
try
|
||||
{
|
||||
m_calendar->SetDateTime(startDate);
|
||||
@@ -50,7 +54,8 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
|
||||
m_calendar->AddDays(duration.day);
|
||||
}
|
||||
|
||||
*endDate = m_calendar->GetDateTime();
|
||||
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
|
||||
return m_calendar->GetDateTime();
|
||||
}
|
||||
catch (Platform::InvalidArgumentException ^ ex)
|
||||
{
|
||||
@@ -58,17 +63,13 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
|
||||
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
|
||||
|
||||
// Do nothing
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Subtracting Duration from a Date
|
||||
// Returns: True if function succeeds to calculate the date else returns False
|
||||
bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate)
|
||||
IBox<DateTime> ^ DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ DateDifference duration)
|
||||
{
|
||||
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
|
||||
|
||||
@@ -101,7 +102,18 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
|
||||
{
|
||||
m_calendar->AddYears(-duration.year);
|
||||
}
|
||||
*endDate = m_calendar->GetDateTime();
|
||||
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
|
||||
|
||||
auto dateTime = m_calendar->GetDateTime();
|
||||
// Check that the UniversalTime value is not negative
|
||||
if (dateTime.UniversalTime >= 0)
|
||||
{
|
||||
return dateTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
catch (Platform::InvalidArgumentException ^ ex)
|
||||
{
|
||||
@@ -109,17 +121,12 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
|
||||
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
|
||||
|
||||
// Do nothing
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
|
||||
|
||||
// Check that the UniversalTime value is not negative
|
||||
return (endDate->UniversalTime >= 0);
|
||||
}
|
||||
|
||||
// Calculate the difference between two dates
|
||||
bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference* difference)
|
||||
IBox<DateDifference> ^ DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat)
|
||||
{
|
||||
DateTime startDate;
|
||||
DateTime endDate;
|
||||
@@ -177,8 +184,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
|
||||
{
|
||||
// Operation failed due to out of bound result
|
||||
// For example: 31st Dec, 9999 - last valid date
|
||||
*difference = DateDifferenceUnknown;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,8 +200,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
|
||||
if (differenceInDates[unitIndex] == 0)
|
||||
{
|
||||
// differenceInDates[unitIndex] is unsigned, the value can't be negative
|
||||
*difference = DateDifferenceUnknown;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
differenceInDates[unitIndex] -= 1;
|
||||
pivotDate = tempPivotDate;
|
||||
@@ -220,8 +225,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
|
||||
{
|
||||
// Operation failed due to out of bound result
|
||||
// For example: 31st Dec, 9999 - last valid date
|
||||
*difference = DateDifferenceUnknown;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
} while (tempDaysDiff != 0); // dates are the same - exit the loop
|
||||
@@ -232,8 +236,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
|
||||
if (signedDaysDiff < 0)
|
||||
{
|
||||
// daysDiff is unsigned, the value can't be negative
|
||||
*difference = DateDifferenceUnknown;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
daysDiff = signedDaysDiff;
|
||||
@@ -244,11 +247,12 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT
|
||||
|
||||
differenceInDates[3] = daysDiff;
|
||||
|
||||
difference->year = differenceInDates[0];
|
||||
difference->month = differenceInDates[1];
|
||||
difference->week = differenceInDates[2];
|
||||
difference->day = differenceInDates[3];
|
||||
return true;
|
||||
DateDifference result;
|
||||
result.year = differenceInDates[0];
|
||||
result.month = differenceInDates[1];
|
||||
result.week = differenceInDates[2];
|
||||
result.day = differenceInDates[3];
|
||||
return result;
|
||||
}
|
||||
|
||||
// Private Methods
|
||||
|
||||
@@ -29,39 +29,30 @@ namespace CalculatorApp
|
||||
};
|
||||
|
||||
// Struct to store the difference between two Dates in the form of Years, Months , Weeks
|
||||
struct DateDifference
|
||||
public
|
||||
value struct DateDifference
|
||||
{
|
||||
int year = 0;
|
||||
int month = 0;
|
||||
int week = 0;
|
||||
int day = 0;
|
||||
|
||||
bool operator==(const DateDifference& dd) const
|
||||
{
|
||||
return year == dd.year && month == dd.month && week == dd.week && day == day;
|
||||
}
|
||||
int year;
|
||||
int month;
|
||||
int week;
|
||||
int day;
|
||||
};
|
||||
|
||||
const DateDifference DateDifferenceUnknown{ INT_MIN, INT_MIN, INT_MIN, INT_MIN };
|
||||
|
||||
class DateCalculationEngine
|
||||
public
|
||||
ref class DateCalculationEngine sealed
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
DateCalculationEngine(_In_ Platform::String ^ calendarIdentifier);
|
||||
|
||||
// Public Methods
|
||||
bool __nothrow
|
||||
AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime* endDate);
|
||||
bool __nothrow SubtractDuration(
|
||||
_In_ Windows::Foundation::DateTime startDate,
|
||||
_In_ const DateDifference& duration,
|
||||
_Out_ Windows::Foundation::DateTime* endDate);
|
||||
bool __nothrow TryGetDateDifference(
|
||||
_In_ Windows::Foundation::DateTime date1,
|
||||
_In_ Windows::Foundation::DateTime date2,
|
||||
_In_ DateUnit outputFormat,
|
||||
_Out_ DateDifference* difference);
|
||||
|
||||
Platform::IBox<Windows::Foundation::DateTime> ^ AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration);
|
||||
Platform::IBox<Windows::Foundation::DateTime> ^ SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration);
|
||||
Platform::IBox<
|
||||
DateDifference> ^ TryGetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat);
|
||||
|
||||
private:
|
||||
// Private Variables
|
||||
@@ -76,3 +67,5 @@ namespace CalculatorApp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const CalculatorApp::Common::DateCalculation::DateDifference& l, const CalculatorApp::Common::DateCalculation::DateDifference& r);
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace CalculatorApp
|
||||
m_resLoader = ResourceLoader::GetForViewIndependentUse("CEngineStrings");
|
||||
}
|
||||
|
||||
wstring EngineResourceProvider::GetCEngineString(const wstring& id)
|
||||
wstring EngineResourceProvider::GetCEngineString(wstring_view id)
|
||||
{
|
||||
const auto& localizationSettings = LocalizationSettings::GetInstance();
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace CalculatorApp
|
||||
return numberGroupingString;
|
||||
}
|
||||
|
||||
StringReference idRef(id.c_str());
|
||||
StringReference idRef(id.data(), id.length());
|
||||
String ^ str = m_resLoader->GetString(idRef);
|
||||
return str->Begin();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace CalculatorApp
|
||||
{
|
||||
public:
|
||||
EngineResourceProvider();
|
||||
virtual std::wstring GetCEngineString(const std::wstring& id) override;
|
||||
virtual std::wstring GetCEngineString(std::wstring_view id) override;
|
||||
|
||||
private:
|
||||
Windows::ApplicationModel::Resources::ResourceLoader ^ m_resLoader;
|
||||
|
||||
@@ -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"
|
||||
@@ -47,13 +47,13 @@ COpndCommand CommandDeserializer::DeserializeOperand()
|
||||
bool fDecimal = m_dataReader->ReadBoolean();
|
||||
bool fSciFmt = m_dataReader->ReadBoolean();
|
||||
|
||||
std::shared_ptr<CalculatorVector<int>> cmdVector = std::make_shared<CalculatorVector<int>>();
|
||||
std::shared_ptr<std::vector<int>> cmdVector = std::make_shared<std::vector<int>>();
|
||||
auto cmdVectorSize = m_dataReader->ReadUInt32();
|
||||
|
||||
for (unsigned int j = 0; j < cmdVectorSize; ++j)
|
||||
{
|
||||
int eachOpndcmd = m_dataReader->ReadInt32();
|
||||
cmdVector->Append(eachOpndcmd);
|
||||
cmdVector->push_back(eachOpndcmd);
|
||||
}
|
||||
|
||||
return COpndCommand(cmdVector, fNegative, fDecimal, fSciFmt);
|
||||
@@ -68,7 +68,6 @@ CParentheses CommandDeserializer::DeserializeParentheses()
|
||||
CUnaryCommand CommandDeserializer::DeserializeUnary()
|
||||
{
|
||||
auto cmdSize = m_dataReader->ReadUInt32();
|
||||
std::shared_ptr<CalculatorVector<int>> cmdVector = std::make_shared<CalculatorVector<int>>();
|
||||
|
||||
if (cmdSize == 1)
|
||||
{
|
||||
|
||||
@@ -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"
|
||||
@@ -18,28 +18,22 @@ void SerializeCommandVisitor::Visit(_In_ COpndCommand& opndCmd)
|
||||
m_dataWriter->WriteBoolean(opndCmd.IsDecimalPresent());
|
||||
m_dataWriter->WriteBoolean(opndCmd.IsSciFmt());
|
||||
|
||||
auto opndCmds = opndCmd.GetCommands();
|
||||
unsigned int opndCmdSize;
|
||||
opndCmds->GetSize(&opndCmdSize);
|
||||
const auto& opndCmds = opndCmd.GetCommands();
|
||||
unsigned int opndCmdSize = static_cast<unsigned int>(opndCmds->size());
|
||||
m_dataWriter->WriteUInt32(opndCmdSize);
|
||||
for (unsigned int j = 0; j < opndCmdSize; ++j)
|
||||
for (int eachOpndcmd : *opndCmds)
|
||||
{
|
||||
int eachOpndcmd;
|
||||
opndCmds->GetAt(j, &eachOpndcmd);
|
||||
m_dataWriter->WriteInt32(eachOpndcmd);
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeCommandVisitor::Visit(_In_ CUnaryCommand& unaryCmd)
|
||||
{
|
||||
auto cmds = unaryCmd.GetCommands();
|
||||
unsigned int cmdSize;
|
||||
cmds->GetSize(&cmdSize);
|
||||
const auto& cmds = unaryCmd.GetCommands();
|
||||
unsigned int cmdSize = static_cast<unsigned int>(cmds->size());
|
||||
m_dataWriter->WriteUInt32(cmdSize);
|
||||
for (unsigned int j = 0; j < cmdSize; ++j)
|
||||
for (int eachOpndcmd : *cmds)
|
||||
{
|
||||
int eachOpndcmd;
|
||||
cmds->GetAt(j, &eachOpndcmd);
|
||||
m_dataWriter->WriteInt32(eachOpndcmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,9 +431,9 @@ void KeyboardShortcutManager::OnCharacterReceivedHandler(CoreWindow ^ sender, Ch
|
||||
{
|
||||
wchar_t character = static_cast<wchar_t>(args->KeyCode);
|
||||
auto buttons = s_CharacterForButtons.find(viewId)->second.equal_range(character);
|
||||
RunFirstEnabledButtonCommand(buttons);
|
||||
|
||||
LightUpButtons(buttons);
|
||||
RunFirstEnabledButtonCommand(buttons);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,7 +519,7 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow ^ sender, KeyEventArgs
|
||||
auto navView = buttons.first->second.Resolve<MUXC::NavigationView>();
|
||||
auto appViewModel = safe_cast<ApplicationViewModel ^>(navView->DataContext);
|
||||
appViewModel->Mode = ViewMode::Date;
|
||||
auto categoryName = AppResourceProvider::GetInstance().GetResourceString(L"DateCalculationModeText");
|
||||
auto categoryName = AppResourceProvider::GetInstance()->GetResourceString(L"DateCalculationModeText");
|
||||
appViewModel->CategoryName = categoryName;
|
||||
|
||||
auto menuItems = static_cast<IObservableVector<Object ^> ^>(navView->MenuItemsSource);
|
||||
@@ -601,8 +601,6 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow ^ sender, KeyEventArgs
|
||||
LightUpButtons(buttons);
|
||||
}
|
||||
}
|
||||
|
||||
RunFirstEnabledButtonCommand(buttons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,16 +94,16 @@ LocalizationService::LocalizationService(_In_ const wchar_t * const overridedLan
|
||||
m_locale = locale("");
|
||||
}
|
||||
auto resourceLoader = AppResourceProvider::GetInstance();
|
||||
m_fontFamilyOverride = resourceLoader.GetResourceString(L"LocalizedFontFamilyOverride");
|
||||
m_fontFamilyOverride = resourceLoader->GetResourceString(L"LocalizedFontFamilyOverride");
|
||||
|
||||
String ^ reserved = L"RESERVED_FOR_FONTLOC";
|
||||
|
||||
m_overrideFontApiValues = ((m_fontFamilyOverride != nullptr) && (m_fontFamilyOverride != reserved));
|
||||
if (m_overrideFontApiValues)
|
||||
{
|
||||
String ^ localizedUICaptionFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride");
|
||||
String ^ localizedUITextFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUITextFontSizeFactorOverride");
|
||||
String ^ localizedFontWeightOverride = resourceLoader.GetResourceString(L"LocalizedFontWeightOverride");
|
||||
String ^ localizedUICaptionFontSizeFactorOverride = resourceLoader->GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride");
|
||||
String ^ localizedUITextFontSizeFactorOverride = resourceLoader->GetResourceString(L"LocalizedUITextFontSizeFactorOverride");
|
||||
String ^ localizedFontWeightOverride = resourceLoader->GetResourceString(L"LocalizedFontWeightOverride");
|
||||
|
||||
// If any of the font overrides are modified then all of them need to be modified
|
||||
assert(localizedFontWeightOverride != reserved);
|
||||
@@ -503,16 +503,49 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
|
||||
make_pair<wstring, wstring>(L"27", L"HyperbolicTangent"),
|
||||
make_pair<wstring, wstring>(L"87", L"InverseHyperbolicTangent"),
|
||||
|
||||
// Secant permutations
|
||||
make_pair<wstring, wstring>(L"SecDeg", L"SecantDegrees"),
|
||||
make_pair<wstring, wstring>(L"SecRad", L"SecantRadians"),
|
||||
make_pair<wstring, wstring>(L"SecGrad", L"SecantGradians"),
|
||||
make_pair<wstring, wstring>(L"InverseSecDeg", L"InverseSecantDegrees"),
|
||||
make_pair<wstring, wstring>(L"InverseSecRad", L"InverseSecantRadians"),
|
||||
make_pair<wstring, wstring>(L"InverseSecGrad", L"InverseSecantGradians"),
|
||||
make_pair<wstring, wstring>(L"Sech", L"HyperbolicSecant"),
|
||||
make_pair<wstring, wstring>(L"InverseSech", L"InverseHyperbolicSecant"),
|
||||
|
||||
// Cosecant permutations
|
||||
make_pair<wstring, wstring>(L"CscDeg", L"CosecantDegrees"),
|
||||
make_pair<wstring, wstring>(L"CscRad", L"CosecantRadians"),
|
||||
make_pair<wstring, wstring>(L"CscGrad", L"CosecantGradians"),
|
||||
make_pair<wstring, wstring>(L"InverseCscDeg", L"InverseCosecantDegrees"),
|
||||
make_pair<wstring, wstring>(L"InverseCscRad", L"InverseCosecantRadians"),
|
||||
make_pair<wstring, wstring>(L"InverseCscGrad", L"InverseCosecantGradians"),
|
||||
make_pair<wstring, wstring>(L"Csch", L"HyperbolicCosecant"),
|
||||
make_pair<wstring, wstring>(L"InverseCsch", L"InverseHyperbolicCosecant"),
|
||||
|
||||
// Cotangent permutations
|
||||
make_pair<wstring, wstring>(L"CotDeg", L"CotangentDegrees"),
|
||||
make_pair<wstring, wstring>(L"CotRad", L"CotangentRadians"),
|
||||
make_pair<wstring, wstring>(L"CotGrad", L"CotangentGradians"),
|
||||
make_pair<wstring, wstring>(L"InverseCotDeg", L"InverseCotangentDegrees"),
|
||||
make_pair<wstring, wstring>(L"InverseCotRad", L"InverseCotangentRadians"),
|
||||
make_pair<wstring, wstring>(L"InverseCotGrad", L"InverseCotangentGradians"),
|
||||
make_pair<wstring, wstring>(L"Coth", L"HyperbolicCotangent"),
|
||||
make_pair<wstring, wstring>(L"InverseCoth", L"InverseHyperbolicCotangent"),
|
||||
|
||||
// Miscellaneous Scientific functions
|
||||
make_pair<wstring, wstring>(L"94", L"Factorial"),
|
||||
make_pair<wstring, wstring>(L"35", L"DegreeMinuteSecond"),
|
||||
make_pair<wstring, wstring>(L"28", L"NaturalLog"),
|
||||
make_pair<wstring, wstring>(L"91", L"Square")
|
||||
make_pair<wstring, wstring>(L"91", L"Square"),
|
||||
make_pair<wstring, wstring>(L"CubeRoot", L"CubeRoot"),
|
||||
make_pair<wstring, wstring>(L"Abs", L"AbsoluteValue")
|
||||
};
|
||||
|
||||
static vector<pair<wstring, wstring>> s_noParenEngineKeyResourceMap = { // Programmer mode functions
|
||||
make_pair<wstring, wstring>(L"9", L"LeftShift"),
|
||||
make_pair<wstring, wstring>(L"10", L"RightShift"),
|
||||
make_pair<wstring, wstring>(L"LogBaseX", L"Logx"),
|
||||
|
||||
// Y Root scientific function
|
||||
make_pair<wstring, wstring>(L"16", L"YRoot")
|
||||
@@ -521,12 +554,12 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
|
||||
unordered_map<wstring, wstring> tokenToReadableNameMap{};
|
||||
auto resProvider = AppResourceProvider::GetInstance();
|
||||
|
||||
static const wstring openParen = resProvider.GetCEngineString(StringReference(s_openParenResourceKey))->Data();
|
||||
static const wstring openParen = resProvider->GetCEngineString(StringReference(s_openParenResourceKey))->Data();
|
||||
|
||||
for (const auto& keyPair : s_parenEngineKeyResourceMap)
|
||||
{
|
||||
wstring engineStr = resProvider.GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
|
||||
wstring automationName = resProvider.GetResourceString(StringReference(keyPair.second.c_str()))->Data();
|
||||
wstring engineStr = resProvider->GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
|
||||
wstring automationName = resProvider->GetResourceString(StringReference(keyPair.second.c_str()))->Data();
|
||||
|
||||
tokenToReadableNameMap.emplace(engineStr + openParen, automationName);
|
||||
}
|
||||
@@ -534,15 +567,15 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
|
||||
|
||||
for (const auto& keyPair : s_noParenEngineKeyResourceMap)
|
||||
{
|
||||
wstring engineStr = resProvider.GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
|
||||
wstring automationName = resProvider.GetResourceString(StringReference(keyPair.second.c_str()))->Data();
|
||||
wstring engineStr = resProvider->GetCEngineString(StringReference(keyPair.first.c_str()))->Data();
|
||||
wstring automationName = resProvider->GetResourceString(StringReference(keyPair.second.c_str()))->Data();
|
||||
|
||||
tokenToReadableNameMap.emplace(engineStr, automationName);
|
||||
}
|
||||
s_noParenEngineKeyResourceMap.clear();
|
||||
|
||||
// Also replace hyphens with "minus"
|
||||
wstring minusText = resProvider.GetResourceString(L"minus")->Data();
|
||||
wstring minusText = resProvider->GetResourceString(L"minus")->Data();
|
||||
tokenToReadableNameMap.emplace(L"-", minusText);
|
||||
|
||||
return tokenToReadableNameMap;
|
||||
@@ -559,7 +592,7 @@ String ^ LocalizationService::GetNarratorReadableToken(String ^ rawToken)
|
||||
}
|
||||
else
|
||||
{
|
||||
static const String ^ openParen = AppResourceProvider::GetInstance().GetCEngineString(StringReference(s_openParenResourceKey));
|
||||
static const String ^ openParen = AppResourceProvider::GetInstance()->GetCEngineString(StringReference(s_openParenResourceKey));
|
||||
return ref new String(itr->second.c_str()) + L" " + openParen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +58,11 @@ namespace CalculatorApp
|
||||
|
||||
Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter() const;
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format) const;
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(
|
||||
_In_ Platform::String ^ format,
|
||||
_In_ Platform::String ^ calendarIdentifier,
|
||||
_In_ Platform::String ^ clockIdentifier) const;
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter
|
||||
^ GetRegionalSettingsAwareDateTimeFormatter(
|
||||
_In_ Platform::String ^ format,
|
||||
_In_ Platform::String ^ calendarIdentifier,
|
||||
_In_ Platform::String ^ clockIdentifier) const;
|
||||
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter() const;
|
||||
|
||||
|
||||
@@ -169,20 +169,21 @@ namespace CalculatorApp
|
||||
}
|
||||
}
|
||||
|
||||
Platform::String ^ GetEnglishValueFromLocalizedDigits(const std::wstring& localizedString) const
|
||||
Platform::String ^ GetEnglishValueFromLocalizedDigits(Platform::String ^ localizedString) const
|
||||
{
|
||||
if (m_resolvedName == L"en-US")
|
||||
{
|
||||
return ref new Platform::String(localizedString.c_str());
|
||||
return localizedString;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
size_t length = localizedString.size();
|
||||
auto localizedStringData = localizedString->Data();
|
||||
size_t length = localizedString->Length();
|
||||
std::unique_ptr<wchar_t[]> englishString(new wchar_t[length + 1]); // +1 for the null termination
|
||||
|
||||
for (; i < length; ++i)
|
||||
{
|
||||
wchar_t ch = localizedString[i];
|
||||
wchar_t ch = localizedStringData[i];
|
||||
if (!IsEnUsDigit(ch))
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
@@ -281,18 +282,17 @@ namespace CalculatorApp
|
||||
return m_numberGrouping;
|
||||
}
|
||||
|
||||
void RemoveGroupSeparators(const wchar_t* value, const size_t length, std::wstring* rawValue) const
|
||||
Platform::String ^ RemoveGroupSeparators(Platform::String ^ source) const
|
||||
{
|
||||
rawValue->clear();
|
||||
rawValue->reserve(length);
|
||||
|
||||
for (size_t i = 0; i < length; i++)
|
||||
std::wstringstream stream;
|
||||
for (auto c = source->Begin(); c < source->End(); ++c)
|
||||
{
|
||||
if (value[i] != L' ' && value[i] != m_numberGroupSeparator)
|
||||
if (*c != L' ' && *c != m_numberGroupSeparator)
|
||||
{
|
||||
rawValue->append(1, value[i]);
|
||||
stream << *c;
|
||||
}
|
||||
}
|
||||
return ref new Platform::String(stream.str().c_str());
|
||||
}
|
||||
|
||||
Platform::String ^ GetCalendarIdentifier() const
|
||||
|
||||
@@ -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
|
||||
@@ -9,50 +9,78 @@ namespace CalculatorApp
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
class LocalizationStringUtil
|
||||
class LocalizationStringUtilInternal
|
||||
{
|
||||
public:
|
||||
static std::wstring GetLocalizedString(const wchar_t* pMessage, ...)
|
||||
static Platform::String ^ GetLocalizedString(Platform::String ^ pMessage, ...)
|
||||
{
|
||||
std::wstring returnString = L"";
|
||||
const UINT32 length = 1024;
|
||||
std::unique_ptr<wchar_t[]> spBuffer = std::unique_ptr<wchar_t[]>(new wchar_t[length]);
|
||||
va_list args = NULL;
|
||||
va_start(args, pMessage);
|
||||
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pMessage, 0, 0, spBuffer.get(), length, &args);
|
||||
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pMessage->Data(), 0, 0, spBuffer.get(), length, &args);
|
||||
va_end(args);
|
||||
|
||||
if (fmtReturnVal != 0)
|
||||
{
|
||||
returnString = spBuffer.get();
|
||||
return ref new Platform::String(spBuffer.get());
|
||||
}
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
static Platform::String^ GetLocalizedNarratorAnnouncement(Platform::String^ resourceKey, Platform::String^& formatVariable, T*... params)
|
||||
{
|
||||
EnsureInitialization(resourceKey, formatVariable);
|
||||
return StringReference(GetLocalizedString(formatVariable->Data(), params...).c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
static void EnsureInitialization(Platform::String^ resourceKey, Platform::String^& formatVariable)
|
||||
{
|
||||
if (resourceKey == nullptr || resourceKey->IsEmpty())
|
||||
else
|
||||
{
|
||||
return;
|
||||
return ref new Platform::String();
|
||||
}
|
||||
|
||||
// If the formatVariable already has a value, we don't need to set it again. Simply return.
|
||||
if (formatVariable != nullptr && !formatVariable->IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
formatVariable = AppResourceProvider::GetInstance().GetResourceString(resourceKey);
|
||||
}
|
||||
};
|
||||
|
||||
public
|
||||
ref class LocalizationStringUtil sealed
|
||||
{
|
||||
public:
|
||||
static Platform::String
|
||||
^ GetLocalizedString(Platform::String ^ pMessage)
|
||||
{
|
||||
return LocalizationStringUtilInternal::GetLocalizedString(pMessage);
|
||||
}
|
||||
|
||||
static Platform::String
|
||||
^ GetLocalizedString(
|
||||
Platform::String ^ pMessage,
|
||||
Platform::String ^ param1)
|
||||
{
|
||||
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data());
|
||||
}
|
||||
|
||||
static Platform::String
|
||||
^ GetLocalizedString(
|
||||
Platform::String ^ pMessage,
|
||||
Platform::String ^ param1,
|
||||
Platform::String ^ param2)
|
||||
{
|
||||
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data(), param2->Data());
|
||||
}
|
||||
|
||||
static Platform::String
|
||||
^ GetLocalizedString(
|
||||
Platform::String ^ pMessage,
|
||||
Platform::String ^ param1,
|
||||
Platform::String ^ param2,
|
||||
Platform::String
|
||||
^ param3)
|
||||
{
|
||||
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data(), param2->Data(), param3->Data());
|
||||
}
|
||||
|
||||
static Platform::String
|
||||
^ GetLocalizedString(
|
||||
Platform::String ^ pMessage,
|
||||
Platform::String ^ param1,
|
||||
Platform::String ^ param2,
|
||||
Platform::String ^ param3,
|
||||
Platform::String ^ param4)
|
||||
{
|
||||
return LocalizationStringUtilInternal::GetLocalizedString(pMessage, param1->Data(), param2->Data(), param3->Data(), param4->Data());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ static constexpr int DATA_ID = 13;
|
||||
static constexpr int PRESSURE_ID = 14;
|
||||
static constexpr int ANGLE_ID = 15;
|
||||
static constexpr int CURRENCY_ID = 16;
|
||||
static constexpr int GRAPHING_ID = 17;
|
||||
static constexpr int GRAPHING_ID = 17;
|
||||
// ^^^ THESE CONSTANTS SHOULD NEVER CHANGE ^^^
|
||||
|
||||
// The order of items in this list determines the order of items in the menu.
|
||||
@@ -57,14 +57,6 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
|
||||
L"\uE8EF",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number1,
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Graphing,
|
||||
GRAPHING_ID,
|
||||
L"Graphing",
|
||||
L"GraphingCalculatorMode",
|
||||
L"\uF770",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number5,
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Scientific,
|
||||
SCIENTIFIC_ID,
|
||||
@@ -82,6 +74,14 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number3,
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Graphing,
|
||||
GRAPHING_ID,
|
||||
L"Graphing",
|
||||
L"GraphingCalculatorMode",
|
||||
L"\uF770",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number5,
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Date,
|
||||
DATE_ID,
|
||||
L"Date",
|
||||
@@ -169,7 +169,7 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
|
||||
L"\uE945",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
POSITIVE_ONLY },
|
||||
SUPPORTS_NEGATIVE },
|
||||
NavCategoryInitializer{ ViewMode::Data,
|
||||
DATA_ID,
|
||||
L"Data",
|
||||
@@ -193,7 +193,7 @@ static constexpr array<const NavCategoryInitializer, 18> s_categoryManifest = {
|
||||
L"\uF515",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
POSITIVE_ONLY } };
|
||||
SUPPORTS_NEGATIVE } };
|
||||
|
||||
// This function should only be used when storing the mode to app data.
|
||||
int NavCategory::Serialize(ViewMode mode)
|
||||
@@ -238,9 +238,7 @@ bool NavCategory::IsValidViewMode(ViewMode mode)
|
||||
bool NavCategory::IsCalculatorViewMode(ViewMode mode)
|
||||
{
|
||||
// Historically, Calculator modes are Standard, Scientific, and Programmer.
|
||||
return !IsDateCalculatorViewMode(mode)
|
||||
&& !IsGraphingCalculatorViewMode(mode)
|
||||
&& IsModeInCategoryGroup(mode, CategoryGroupType::Calculator);
|
||||
return !IsDateCalculatorViewMode(mode) && !IsGraphingCalculatorViewMode(mode) && IsModeInCategoryGroup(mode, CategoryGroupType::Calculator);
|
||||
}
|
||||
|
||||
bool NavCategory::IsGraphingCalculatorViewMode(ViewMode mode)
|
||||
@@ -383,33 +381,28 @@ NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupIniti
|
||||
m_GroupType = groupInitializer.type;
|
||||
|
||||
auto resProvider = AppResourceProvider::GetInstance();
|
||||
String ^ headerResourceKey = StringReference(groupInitializer.headerResourceKey);
|
||||
String ^ modeResourceKey = StringReference(groupInitializer.modeResourceKey);
|
||||
String ^ automationResourceKey = StringReference(groupInitializer.automationResourceKey);
|
||||
m_Name = resProvider.GetResourceString(headerResourceKey);
|
||||
String ^ groupMode = resProvider.GetResourceString(modeResourceKey);
|
||||
String ^ automationName = resProvider.GetResourceString(automationResourceKey);
|
||||
m_Name = resProvider->GetResourceString(StringReference(groupInitializer.headerResourceKey));
|
||||
String ^ groupMode = resProvider->GetResourceString(StringReference(groupInitializer.modeResourceKey));
|
||||
String ^ automationName = resProvider->GetResourceString(StringReference(groupInitializer.automationResourceKey));
|
||||
|
||||
String ^ navCategoryHeaderAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryHeader_AutomationNameFormat");
|
||||
m_AutomationName =
|
||||
ref new String(LocalizationStringUtil::GetLocalizedString(navCategoryHeaderAutomationNameFormat->Data(), automationName->Data()).c_str());
|
||||
String ^ navCategoryHeaderAutomationNameFormat = resProvider->GetResourceString(L"NavCategoryHeader_AutomationNameFormat");
|
||||
m_AutomationName = LocalizationStringUtil::GetLocalizedString(navCategoryHeaderAutomationNameFormat, automationName);
|
||||
|
||||
String ^ navCategoryItemAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryItem_AutomationNameFormat");
|
||||
String ^ navCategoryItemAutomationNameFormat = resProvider->GetResourceString(L"NavCategoryItem_AutomationNameFormat");
|
||||
|
||||
for (const NavCategoryInitializer& categoryInitializer : s_categoryManifest)
|
||||
{
|
||||
if (categoryInitializer.groupType == groupInitializer.type)
|
||||
{
|
||||
String ^ nameResourceKey = StringReference(categoryInitializer.nameResourceKey);
|
||||
String ^ categoryName = resProvider.GetResourceString(nameResourceKey + "Text");
|
||||
String ^ categoryAutomationName = ref new String(
|
||||
LocalizationStringUtil::GetLocalizedString(navCategoryItemAutomationNameFormat->Data(), categoryName->Data(), m_Name->Data()).c_str());
|
||||
String ^ categoryName = resProvider->GetResourceString(nameResourceKey + "Text");
|
||||
String ^ categoryAutomationName = LocalizationStringUtil::GetLocalizedString(navCategoryItemAutomationNameFormat, categoryName, m_Name);
|
||||
|
||||
m_Categories->Append(ref new NavCategory(
|
||||
categoryName,
|
||||
categoryAutomationName,
|
||||
StringReference(categoryInitializer.glyph),
|
||||
resProvider.GetResourceString(nameResourceKey + "AccessKey"),
|
||||
resProvider->GetResourceString(nameResourceKey + "AccessKey"),
|
||||
groupMode,
|
||||
categoryInitializer.viewMode,
|
||||
categoryInitializer.supportsNegative));
|
||||
|
||||
16
src/CalcViewModel/Common/NumberBase.h
Normal file
16
src/CalcViewModel/Common/NumberBase.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
namespace CalculatorApp::Common
|
||||
{
|
||||
public
|
||||
enum class NumberBase
|
||||
{
|
||||
Unknown = -1,
|
||||
HexBase = 5,
|
||||
DecBase = 6,
|
||||
OctBase = 7,
|
||||
BinBase = 8
|
||||
};
|
||||
};
|
||||
@@ -10,6 +10,7 @@ using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace Concurrency;
|
||||
using namespace std;
|
||||
using namespace Platform;
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Diagnostics;
|
||||
@@ -57,47 +58,43 @@ namespace CalculatorApp
|
||||
|
||||
TraceLogger::TraceLogger()
|
||||
: g_calculatorProvider(
|
||||
L"MicrosoftCalculator",
|
||||
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }),
|
||||
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 })
|
||||
L"MicrosoftCalculator",
|
||||
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }),
|
||||
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 })
|
||||
, // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
|
||||
m_appLaunchActivity{ nullptr }
|
||||
{
|
||||
CoCreateGuid(&sessionGuid);
|
||||
}
|
||||
|
||||
TraceLogger::~TraceLogger()
|
||||
TraceLogger ^ TraceLogger::GetInstance()
|
||||
{
|
||||
}
|
||||
|
||||
TraceLogger& TraceLogger::GetInstance()
|
||||
{
|
||||
static TraceLogger s_selfInstance;
|
||||
static TraceLogger ^ s_selfInstance = ref new TraceLogger();
|
||||
return s_selfInstance;
|
||||
}
|
||||
|
||||
bool TraceLogger::GetTraceLoggingProviderEnabled() const
|
||||
bool TraceLogger::GetTraceLoggingProviderEnabled()
|
||||
{
|
||||
return g_calculatorProvider.Enabled();
|
||||
}
|
||||
|
||||
#pragma region Tracing methods
|
||||
void TraceLogger::LogLevel1Event(wstring_view eventName, LoggingFields fields) const
|
||||
void TraceLogger::LogLevel1Event(wstring_view eventName, LoggingFields fields)
|
||||
{
|
||||
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_1));
|
||||
}
|
||||
|
||||
void TraceLogger::LogLevel2Event(wstring_view eventName, LoggingFields fields) const
|
||||
void TraceLogger::LogLevel2Event(wstring_view eventName, LoggingFields fields)
|
||||
{
|
||||
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_2));
|
||||
}
|
||||
|
||||
void TraceLogger::LogLevel3Event(wstring_view eventName, LoggingFields fields) const
|
||||
void TraceLogger::LogLevel3Event(wstring_view eventName, LoggingFields fields)
|
||||
{
|
||||
g_calculatorProvider.LogEvent(eventName, fields, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_LEVEL_3));
|
||||
}
|
||||
|
||||
unique_ptr<TraceActivity> TraceLogger::CreateTraceActivity(wstring_view eventName, LoggingFields fields) const
|
||||
unique_ptr<TraceActivity> TraceLogger::CreateTraceActivity(wstring_view eventName, LoggingFields fields)
|
||||
{
|
||||
return make_unique<TraceActivity>(g_calculatorProvider, eventName, fields);
|
||||
}
|
||||
@@ -117,7 +114,7 @@ namespace CalculatorApp
|
||||
return true;
|
||||
}
|
||||
|
||||
void TraceLogger::LogVisualStateChanged(ViewMode mode, wstring_view state, bool isAlwaysOnTop) const
|
||||
void TraceLogger::LogVisualStateChanged(ViewMode mode, String ^ state, bool isAlwaysOnTop)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
{
|
||||
@@ -127,7 +124,7 @@ namespace CalculatorApp
|
||||
LoggingFields fields{};
|
||||
fields.AddGuid(L"SessionGuid", sessionGuid);
|
||||
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
|
||||
fields.AddString(L"VisualState", state);
|
||||
fields.AddString(L"VisualState", state->Data());
|
||||
fields.AddBoolean(L"IsAlwaysOnTop", isAlwaysOnTop);
|
||||
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
|
||||
LogLevel2Event(EVENT_NAME_VISUAL_STATE_CHANGED, fields);
|
||||
@@ -152,7 +149,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_WINDOW_ON_CREATED, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogModeChange(ViewMode mode) const
|
||||
void TraceLogger::LogModeChange(ViewMode mode)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
@@ -167,7 +164,7 @@ namespace CalculatorApp
|
||||
}
|
||||
}
|
||||
|
||||
void TraceLogger::LogHistoryItemLoad(ViewMode mode, int historyListSize, int loadedIndex) const
|
||||
void TraceLogger::LogHistoryItemLoad(ViewMode mode, int historyListSize, int loadedIndex)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
{
|
||||
@@ -183,7 +180,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_HISTORY_ITEM_LOAD, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogMemoryItemLoad(ViewMode mode, int memoryListSize, int loadedIndex) const
|
||||
void TraceLogger::LogMemoryItemLoad(ViewMode mode, int memoryListSize, int loadedIndex)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
{
|
||||
@@ -199,7 +196,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_MEMORY_ITEM_LOAD, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogError(ViewMode mode, wstring_view functionName, wstring_view errorString)
|
||||
void TraceLogger::LogError(ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
@@ -207,13 +204,13 @@ namespace CalculatorApp
|
||||
LoggingFields fields{};
|
||||
fields.AddGuid(L"SessionGuid", sessionGuid);
|
||||
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
|
||||
fields.AddString(L"FunctionName", functionName);
|
||||
fields.AddString(L"Message", errorString);
|
||||
fields.AddString(L"FunctionName", functionName->Data());
|
||||
fields.AddString(L"Message", errorString->Data());
|
||||
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
|
||||
LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogStandardException(ViewMode mode, wstring_view functionName, const exception& e) const
|
||||
void TraceLogger::LogStandardException(ViewMode mode, wstring_view functionName, const exception& e)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
@@ -229,7 +226,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogWinRTException(ViewMode mode, wstring_view functionName, hresult_error const& e) const
|
||||
void TraceLogger::LogWinRTException(ViewMode mode, wstring_view functionName, hresult_error const& e)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
@@ -244,7 +241,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_EXCEPTION, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogPlatformException(ViewMode mode, wstring_view functionName, Platform::Exception ^ e) const
|
||||
void TraceLogger::LogPlatformException(ViewMode mode, wstring_view functionName, Platform::Exception ^ e)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
@@ -291,7 +288,7 @@ namespace CalculatorApp
|
||||
}
|
||||
}
|
||||
|
||||
void TraceLogger::UpdateWindowCount(size_t windowCount)
|
||||
void TraceLogger::UpdateWindowCount(uint64 windowCount)
|
||||
{
|
||||
if (windowCount == 0)
|
||||
{
|
||||
@@ -301,6 +298,11 @@ namespace CalculatorApp
|
||||
currentWindowCount = windowCount;
|
||||
}
|
||||
|
||||
void TraceLogger::DecreaseWindowCount()
|
||||
{
|
||||
currentWindowCount = 0;
|
||||
}
|
||||
|
||||
void TraceLogger::LogButtonUsage()
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
@@ -348,7 +350,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_DATE_CALCULATION_MODE_USED, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogConverterInputReceived(ViewMode mode) const
|
||||
void TraceLogger::LogConverterInputReceived(ViewMode mode)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
@@ -360,7 +362,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_CONVERTER_INPUT_RECEIVED, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogNavBarOpened() const
|
||||
void TraceLogger::LogNavBarOpened()
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
@@ -371,7 +373,7 @@ namespace CalculatorApp
|
||||
LogLevel2Event(EVENT_NAME_NAV_BAR_OPENED, fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogInputPasted(ViewMode mode) const
|
||||
void TraceLogger::LogInputPasted(ViewMode mode)
|
||||
{
|
||||
if (!GetTraceLoggingProviderEnabled())
|
||||
return;
|
||||
|
||||
@@ -28,33 +28,31 @@ namespace CalculatorApp
|
||||
}
|
||||
};
|
||||
|
||||
class TraceLogger
|
||||
public
|
||||
ref class TraceLogger sealed
|
||||
{
|
||||
public:
|
||||
TraceLogger(_In_ TraceLogger const&) = delete;
|
||||
TraceLogger const& operator=(_In_ TraceLogger const&) = delete;
|
||||
~TraceLogger();
|
||||
static TraceLogger& GetInstance();
|
||||
bool GetTraceLoggingProviderEnabled() const;
|
||||
|
||||
void LogModeChange(CalculatorApp::Common::ViewMode mode) const;
|
||||
void LogHistoryItemLoad(CalculatorApp::Common::ViewMode mode, int historyListSize, int loadedIndex) const;
|
||||
void LogMemoryItemLoad(CalculatorApp::Common::ViewMode mode, int memoryListSize, int loadedIndex) const;
|
||||
static TraceLogger ^ GetInstance();
|
||||
bool GetTraceLoggingProviderEnabled();
|
||||
void LogModeChange(CalculatorApp::Common::ViewMode mode);
|
||||
void LogHistoryItemLoad(CalculatorApp::Common::ViewMode mode, int historyListSize, int loadedIndex);
|
||||
void LogMemoryItemLoad(CalculatorApp::Common::ViewMode mode, int memoryListSize, int loadedIndex);
|
||||
void UpdateButtonUsage(CalculatorApp::NumbersAndOperatorsEnum button, CalculatorApp::Common::ViewMode mode);
|
||||
void LogButtonUsage();
|
||||
void LogDateCalculationModeUsed(bool AddSubtractMode);
|
||||
void UpdateWindowCount(size_t windowCount = 0);
|
||||
void UpdateWindowCount(uint64 windowCount);
|
||||
void DecreaseWindowCount();
|
||||
bool IsWindowIdInLog(int windowId);
|
||||
void LogVisualStateChanged(CalculatorApp::Common::ViewMode mode, std::wstring_view state, bool isAlwaysOnTop = false) const;
|
||||
void LogVisualStateChanged(CalculatorApp::Common::ViewMode mode, Platform::String ^ state, bool isAlwaysOnTop);
|
||||
void LogWindowCreated(CalculatorApp::Common::ViewMode mode, int windowId);
|
||||
void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode) const;
|
||||
void LogNavBarOpened() const;
|
||||
|
||||
void LogError(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, std::wstring_view errorString);
|
||||
void LogStandardException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e) const;
|
||||
void LogWinRTException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ winrt::hresult_error const& e) const;
|
||||
void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e) const;
|
||||
void LogInputPasted(CalculatorApp::Common::ViewMode mode) const;
|
||||
void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode);
|
||||
void LogNavBarOpened();
|
||||
void LogError(CalculatorApp::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString);
|
||||
internal :
|
||||
void LogStandardException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e);
|
||||
void LogWinRTException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ winrt::hresult_error const& e);
|
||||
void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e);
|
||||
void LogInputPasted(CalculatorApp::Common::ViewMode mode);
|
||||
|
||||
private:
|
||||
// Create an instance of TraceLogger
|
||||
@@ -64,11 +62,11 @@ namespace CalculatorApp
|
||||
// sampling is involved in Microsoft's diagnostic data collection process.
|
||||
// These keywords provide additional input into how frequently an event might be sampled.
|
||||
// The lower the level of the keyword, the higher the possibility that the corresponding event may be sampled.
|
||||
void LogLevel1Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
|
||||
void LogLevel2Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
|
||||
void LogLevel3Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
|
||||
void LogLevel1Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
|
||||
void LogLevel2Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
|
||||
void LogLevel3Event(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
|
||||
|
||||
std::unique_ptr<TraceActivity> CreateTraceActivity(std::wstring_view activityName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
|
||||
std::unique_ptr<TraceActivity> CreateTraceActivity(std::wstring_view activityName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields);
|
||||
|
||||
winrt::Windows::Foundation::Diagnostics::LoggingChannel g_calculatorProvider;
|
||||
|
||||
@@ -76,7 +74,7 @@ namespace CalculatorApp
|
||||
std::vector<int> windowIdLog;
|
||||
|
||||
GUID sessionGuid;
|
||||
size_t currentWindowCount = 0;
|
||||
uint64 currentWindowCount = 0;
|
||||
|
||||
winrt::Windows::Foundation::Diagnostics::LoggingActivity m_appLaunchActivity;
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "Common/AppResourceProvider.h"
|
||||
#include "Common/ExpressionCommandSerializer.h"
|
||||
#include "Common/ExpressionCommandDeserializer.h"
|
||||
#include "ViewState.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
@@ -50,8 +49,8 @@ String ^ Utils::GetStringValue(String ^ input)
|
||||
|
||||
double Utils::GetDoubleFromWstring(wstring input)
|
||||
{
|
||||
wchar_t unWantedChars[] = { L' ', L',', 8234, 8235, 8236, 8237 };
|
||||
wstring ws = RemoveUnwantedCharsFromWstring(input, unWantedChars, 6);
|
||||
constexpr wchar_t unWantedChars[] = { L' ', L',', 8234, 8235, 8236, 8237 };
|
||||
wstring ws = RemoveUnwantedCharsFromString(input, unWantedChars);
|
||||
return stod(ws);
|
||||
}
|
||||
|
||||
@@ -83,47 +82,26 @@ bool Utils::IsLastCharacterTarget(_In_ wstring const& input, _In_ wchar_t target
|
||||
return !input.empty() && input.back() == target;
|
||||
}
|
||||
|
||||
// Return wstring after removing characters specified by unwantedChars array
|
||||
wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedChars, unsigned int size)
|
||||
{
|
||||
for (unsigned int i = 0; i < size; ++i)
|
||||
{
|
||||
input.erase(remove(input.begin(), input.end(), unwantedChars[i]), input.end());
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
void Utils::SerializeCommandsAndTokens(
|
||||
_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens,
|
||||
_In_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands,
|
||||
_In_ shared_ptr<vector<pair<wstring, int>>> const& tokens,
|
||||
_In_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands,
|
||||
DataWriter ^ writer)
|
||||
{
|
||||
unsigned int commandsSize;
|
||||
IFTPlatformException(commands->GetSize(&commandsSize));
|
||||
|
||||
// Save the size of the commands vector
|
||||
writer->WriteUInt32(commandsSize);
|
||||
writer->WriteUInt32(static_cast<unsigned int>(commands->size()));
|
||||
|
||||
SerializeCommandVisitor cmdVisitor(writer);
|
||||
for (unsigned int i = 0; i < commandsSize; ++i)
|
||||
for (const auto& exprCmd : *commands)
|
||||
{
|
||||
shared_ptr<IExpressionCommand> exprCmd;
|
||||
IFTPlatformException(commands->GetAt(i, &exprCmd));
|
||||
|
||||
CalculationManager::CommandType commandType = exprCmd->GetCommandType();
|
||||
writer->WriteInt32(static_cast<int>(commandType));
|
||||
exprCmd->Accept(cmdVisitor);
|
||||
}
|
||||
|
||||
unsigned int tokensSize;
|
||||
IFTPlatformException(tokens->GetSize(&tokensSize));
|
||||
writer->WriteUInt32(tokensSize);
|
||||
writer->WriteUInt32(static_cast<unsigned int>(tokens->size()));
|
||||
|
||||
for (unsigned int i = 0; i < tokensSize; ++i)
|
||||
for (const auto& eachToken : *tokens)
|
||||
{
|
||||
pair<wstring, int> eachToken;
|
||||
IFTPlatformException(tokens->GetAt(i, &eachToken));
|
||||
|
||||
auto stringData = ref new Platform::String(eachToken.first.c_str());
|
||||
auto intData = eachToken.second;
|
||||
writer->WriteUInt32(writer->MeasureString(stringData));
|
||||
@@ -132,9 +110,9 @@ void Utils::SerializeCommandsAndTokens(
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::DeserializeCommands(DataReader ^ reader)
|
||||
const shared_ptr<vector<shared_ptr<IExpressionCommand>>> Utils::DeserializeCommands(DataReader ^ reader)
|
||||
{
|
||||
shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> commandVector = make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>();
|
||||
auto commandVector = make_shared<vector<shared_ptr<IExpressionCommand>>>();
|
||||
auto commandVectorSize = reader->ReadUInt32();
|
||||
|
||||
CommandDeserializer cmdDeserializer(reader);
|
||||
@@ -143,26 +121,23 @@ const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::Deseri
|
||||
auto commandTypeInt = reader->ReadInt32();
|
||||
CalculationManager::CommandType commandType = static_cast<CalculationManager::CommandType>(commandTypeInt);
|
||||
shared_ptr<IExpressionCommand> exprCmd = cmdDeserializer.Deserialize(commandType);
|
||||
commandVector->Append(exprCmd);
|
||||
commandVector->push_back(exprCmd);
|
||||
}
|
||||
|
||||
return commandVector;
|
||||
}
|
||||
|
||||
const shared_ptr<CalculatorVector<pair<wstring, int>>> Utils::DeserializeTokens(DataReader ^ reader)
|
||||
const shared_ptr<vector<pair<wstring, int>>> Utils::DeserializeTokens(DataReader ^ reader)
|
||||
{
|
||||
shared_ptr<CalculatorVector<pair<wstring, int>>> tokenVector = make_shared<CalculatorVector<pair<wstring, int>>>();
|
||||
auto tokenVector = make_shared<vector<pair<wstring, int>>>();
|
||||
auto tokensSize = reader->ReadUInt32();
|
||||
|
||||
for (unsigned int i = 0; i < tokensSize; ++i)
|
||||
{
|
||||
pair<wstring, int> eachToken;
|
||||
auto stringDataLen = reader->ReadUInt32();
|
||||
auto stringData = reader->ReadString(stringDataLen);
|
||||
auto intData = reader->ReadInt32();
|
||||
eachToken.first = stringData->Data();
|
||||
eachToken.second = intData;
|
||||
tokenVector->Append(eachToken);
|
||||
tokenVector->emplace_back(stringData->Data(), intData);
|
||||
}
|
||||
|
||||
return tokenVector;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CalcManager/CalculatorVector.h"
|
||||
#include "CalcManager/ExpressionCommandInterface.h"
|
||||
#include "DelegateCommand.h"
|
||||
#include "GraphingInterfaces/GraphingEnums.h"
|
||||
@@ -210,7 +209,7 @@ public:
|
||||
private: \
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_##n##Property; \
|
||||
\
|
||||
public:
|
||||
private:
|
||||
|
||||
// Utilities for DependencyProperties
|
||||
namespace Utils
|
||||
@@ -401,27 +400,34 @@ namespace Utils
|
||||
void IFTPlatformException(HRESULT hr);
|
||||
Platform::String ^ GetStringValue(Platform::String ^ input);
|
||||
bool IsLastCharacterTarget(std::wstring const& input, wchar_t target);
|
||||
std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size);
|
||||
|
||||
// Return wstring after removing characters specified by unwantedChars array
|
||||
template <size_t N>
|
||||
std::wstring RemoveUnwantedCharsFromString(std::wstring inputString, const wchar_t (&unwantedChars)[N])
|
||||
{
|
||||
for (const wchar_t unwantedChar : unwantedChars)
|
||||
{
|
||||
inputString.erase(std::remove(inputString.begin(), inputString.end(), unwantedChar), inputString.end());
|
||||
}
|
||||
return inputString;
|
||||
}
|
||||
|
||||
double GetDoubleFromWstring(std::wstring input);
|
||||
int GetWindowId();
|
||||
void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher ^ currentDispatcher);
|
||||
void SerializeCommandsAndTokens(
|
||||
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands,
|
||||
_In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands,
|
||||
Windows::Storage::Streams::DataWriter ^ writer);
|
||||
|
||||
const std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> DeserializeCommands(Windows::Storage::Streams::DataReader ^ reader);
|
||||
const std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> DeserializeTokens(Windows::Storage::Streams::DataReader ^ reader);
|
||||
const std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> DeserializeCommands(Windows::Storage::Streams::DataReader ^ reader);
|
||||
const std::shared_ptr<std::vector<std::pair<std::wstring, int>>> DeserializeTokens(Windows::Storage::Streams::DataReader ^ reader);
|
||||
|
||||
Windows::Foundation::DateTime GetUniversalSystemTime();
|
||||
bool IsDateTimeOlderThan(Windows::Foundation::DateTime dateTime, const long long duration);
|
||||
|
||||
concurrency::task<void> WriteFileToFolder(
|
||||
Windows::Storage::IStorageFolder ^ folder,
|
||||
Platform::String ^ fileName,
|
||||
Platform::String ^ contents,
|
||||
Windows::Storage::CreationCollisionOption collisionOption);
|
||||
concurrency::task<Platform::String ^> ReadFileFromFolder(Windows::Storage::IStorageFolder ^ folder, Platform::String ^ fileName);
|
||||
concurrency::task<void> WriteFileToFolder(Windows::Storage::IStorageFolder^ folder, Platform::String^ fileName, Platform::String^ contents, Windows::Storage::CreationCollisionOption collisionOption);
|
||||
concurrency::task<Platform::String^> ReadFileFromFolder(Windows::Storage::IStorageFolder^ folder, Platform::String^ fileName);
|
||||
|
||||
bool AreColorsEqual(const Windows::UI::Color& color1, const Windows::UI::Color& color2);
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -132,8 +132,8 @@ CurrencyDataLoader::CurrencyDataLoader(_In_ unique_ptr<ICurrencyHttpClient> clie
|
||||
m_ratioFormatter->IsDecimalPointAlwaysDisplayed = true;
|
||||
m_ratioFormatter->FractionDigits = FORMATTER_RATE_FRACTION_PADDING;
|
||||
|
||||
m_ratioFormat = AppResourceProvider::GetInstance().GetResourceString(L"CurrencyFromToRatioFormat")->Data();
|
||||
m_timestampFormat = AppResourceProvider::GetInstance().GetResourceString(L"CurrencyTimestampFormat")->Data();
|
||||
m_ratioFormat = AppResourceProvider::GetInstance()->GetResourceString(L"CurrencyFromToRatioFormat");
|
||||
m_timestampFormat = AppResourceProvider::GetInstance()->GetResourceString(L"CurrencyTimestampFormat");
|
||||
}
|
||||
|
||||
CurrencyDataLoader::~CurrencyDataLoader()
|
||||
@@ -300,16 +300,18 @@ pair<wstring, wstring> CurrencyDataLoader::GetCurrencyRatioEquality(_In_ const U
|
||||
double ratio = (iter2->second).ratio;
|
||||
double rounded = RoundCurrencyRatio(ratio);
|
||||
|
||||
wstring digitSymbol = wstring{ LocalizationSettings::GetInstance().GetDigitSymbolFromEnUsDigit(L'1') };
|
||||
wstring roundedFormat = m_ratioFormatter->Format(rounded)->Data();
|
||||
auto digit = LocalizationSettings::GetInstance().GetDigitSymbolFromEnUsDigit(L'1');
|
||||
auto digitSymbol = ref new String(&digit, 1);
|
||||
auto roundedFormat = m_ratioFormatter->Format(rounded);
|
||||
|
||||
wstring ratioString = LocalizationStringUtil::GetLocalizedString(
|
||||
m_ratioFormat.c_str(), digitSymbol.c_str(), unit1.abbreviation.c_str(), roundedFormat.c_str(), unit2.abbreviation.c_str());
|
||||
auto ratioString = LocalizationStringUtil::GetLocalizedString(
|
||||
m_ratioFormat, digitSymbol, StringReference(unit1.abbreviation.c_str()), roundedFormat, StringReference(unit2.abbreviation.c_str()));
|
||||
|
||||
wstring accessibleRatioString = LocalizationStringUtil::GetLocalizedString(
|
||||
m_ratioFormat.c_str(), digitSymbol.c_str(), unit1.accessibleName.c_str(), roundedFormat.c_str(), unit2.accessibleName.c_str());
|
||||
auto accessibleRatioString =
|
||||
LocalizationStringUtil::GetLocalizedString(
|
||||
m_ratioFormat, digitSymbol, StringReference(unit1.accessibleName.c_str()), roundedFormat, StringReference(unit2.accessibleName.c_str()));
|
||||
|
||||
return make_pair(ratioString, accessibleRatioString);
|
||||
return make_pair(ratioString->Data(), accessibleRatioString->Data());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -349,12 +351,12 @@ future<bool> CurrencyDataLoader::TryLoadDataFromCacheAsync()
|
||||
}
|
||||
catch (Exception ^ ex)
|
||||
{
|
||||
TraceLogger::GetInstance().LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex);
|
||||
TraceLogger::GetInstance()->LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex);
|
||||
co_return false;
|
||||
}
|
||||
catch (const exception& e)
|
||||
{
|
||||
TraceLogger::GetInstance().LogStandardException(ViewMode::Currency, __FUNCTIONW__, e);
|
||||
TraceLogger::GetInstance()->LogStandardException(ViewMode::Currency, __FUNCTIONW__, e);
|
||||
co_return false;
|
||||
}
|
||||
catch (...)
|
||||
@@ -459,12 +461,12 @@ future<bool> CurrencyDataLoader::TryLoadDataFromWebAsync()
|
||||
}
|
||||
catch (Exception ^ ex)
|
||||
{
|
||||
TraceLogger::GetInstance().LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex);
|
||||
TraceLogger::GetInstance()->LogPlatformException(ViewMode::Currency, __FUNCTIONW__, ex);
|
||||
co_return false;
|
||||
}
|
||||
catch (const exception& e)
|
||||
{
|
||||
TraceLogger::GetInstance().LogStandardException(ViewMode::Currency, __FUNCTIONW__, e);
|
||||
TraceLogger::GetInstance()->LogStandardException(ViewMode::Currency, __FUNCTIONW__, e);
|
||||
co_return false;
|
||||
}
|
||||
catch (...)
|
||||
@@ -480,7 +482,7 @@ future<bool> CurrencyDataLoader::TryLoadDataFromWebOverrideAsync()
|
||||
if (!didLoad)
|
||||
{
|
||||
m_loadStatus = CurrencyLoadStatus::FailedToLoad;
|
||||
TraceLogger::GetInstance().LogError(ViewMode::Currency, L"CurrencyDataLoader::TryLoadDataFromWebOverrideAsync", L"UserRequestedRefreshFailed");
|
||||
TraceLogger::GetInstance()->LogError(ViewMode::Currency, L"CurrencyDataLoader::TryLoadDataFromWebOverrideAsync", L"UserRequestedRefreshFailed");
|
||||
}
|
||||
|
||||
co_return didLoad;
|
||||
@@ -747,21 +749,19 @@ void CurrencyDataLoader::UpdateDisplayedTimestamp()
|
||||
}
|
||||
wstring CurrencyDataLoader::GetCurrencyTimestamp()
|
||||
{
|
||||
wstring timestamp = L"";
|
||||
|
||||
DateTime epoch{};
|
||||
if (m_cacheTimestamp.UniversalTime != epoch.UniversalTime)
|
||||
{
|
||||
DateTimeFormatter ^ dateFormatter = ref new DateTimeFormatter(L"{month.abbreviated} {day.integer}, {year.full}");
|
||||
wstring date = dateFormatter->Format(m_cacheTimestamp)->Data();
|
||||
DateTimeFormatter ^ dateFormatter = ref new DateTimeFormatter(L"shortdate");
|
||||
auto date = dateFormatter->Format(m_cacheTimestamp);
|
||||
|
||||
DateTimeFormatter ^ timeFormatter = ref new DateTimeFormatter(L"shorttime");
|
||||
wstring time = timeFormatter->Format(m_cacheTimestamp)->Data();
|
||||
auto time = timeFormatter->Format(m_cacheTimestamp);
|
||||
|
||||
timestamp = LocalizationStringUtil::GetLocalizedString(m_timestampFormat.c_str(), date.c_str(), time.c_str());
|
||||
return LocalizationStringUtil::GetLocalizedString(m_timestampFormat, date, time)->Data();
|
||||
}
|
||||
|
||||
return timestamp;
|
||||
return L"";
|
||||
}
|
||||
|
||||
#pragma optimize("", off) // Turn off optimizations to work around DevDiv 393321
|
||||
|
||||
@@ -124,9 +124,9 @@ namespace CalculatorApp
|
||||
std::shared_ptr<UCM::IViewModelCurrencyCallback> m_vmCallback;
|
||||
|
||||
Windows::Globalization::NumberFormatting::DecimalFormatter ^ m_ratioFormatter;
|
||||
std::wstring m_ratioFormat;
|
||||
Platform::String ^ m_ratioFormat;
|
||||
Windows::Foundation::DateTime m_cacheTimestamp;
|
||||
std::wstring m_timestampFormat;
|
||||
Platform::String ^ m_timestampFormat;
|
||||
|
||||
CurrencyLoadStatus m_loadStatus;
|
||||
|
||||
|
||||
@@ -953,7 +953,7 @@ void UnitConverterDataLoader::GetConversionData(_In_ unordered_map<ViewMode, uno
|
||||
|
||||
wstring UnitConverterDataLoader::GetLocalizedStringName(String ^ stringId)
|
||||
{
|
||||
return AppResourceProvider::GetInstance().GetResourceString(stringId)->Data();
|
||||
return AppResourceProvider::GetInstance()->GetResourceString(stringId)->Data();
|
||||
}
|
||||
|
||||
void UnitConverterDataLoader::GetExplicitConversionData(_In_ unordered_map<int, unordered_map<int, UCM::ConversionData>>& unitToUnitConversionList)
|
||||
|
||||
@@ -45,13 +45,13 @@ DateCalculatorViewModel::DateCalculatorViewModel()
|
||||
, m_StrDateResult(L"")
|
||||
, m_StrDateResultAutomationName(L"")
|
||||
{
|
||||
const auto& localizationSettings = LocalizationSettings::GetInstance();
|
||||
const auto & localizationSettings = LocalizationSettings::GetInstance();
|
||||
|
||||
// Initialize Date Output format instances
|
||||
InitializeDateOutputFormats(localizationSettings.GetCalendarIdentifier());
|
||||
|
||||
// Initialize Date Calc engine
|
||||
m_dateCalcEngine = make_shared<DateCalculationEngine>(localizationSettings.GetCalendarIdentifier());
|
||||
m_dateCalcEngine = ref new DateCalculationEngine(localizationSettings.GetCalendarIdentifier());
|
||||
// Initialize dates of DatePicker controls to today's date
|
||||
auto calendar = ref new Calendar();
|
||||
// We force the timezone to UTC, in order to avoid being affected by Daylight Saving Time
|
||||
@@ -111,20 +111,20 @@ void DateCalculatorViewModel::OnPropertyChanged(_In_ String ^ prop)
|
||||
|
||||
void DateCalculatorViewModel::OnInputsChanged()
|
||||
{
|
||||
DateDifference dateDiff;
|
||||
|
||||
if (m_IsDateDiffMode)
|
||||
{
|
||||
DateTime clippedFromDate = ClipTime(FromDate, true);
|
||||
DateTime clippedToDate = ClipTime(ToDate, true);
|
||||
|
||||
// Calculate difference between two dates
|
||||
if (m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat, &dateDiff))
|
||||
auto dateDiff = m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat);
|
||||
if (dateDiff != nullptr)
|
||||
{
|
||||
DateDiffResultInDays = dateDiff;
|
||||
if (m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat, &dateDiff))
|
||||
DateDiffResultInDays = dateDiff->Value;
|
||||
dateDiff = m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat);
|
||||
if (dateDiff != nullptr)
|
||||
{
|
||||
DateDiffResult = dateDiff;
|
||||
DateDiffResult = dateDiff->Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -140,26 +140,28 @@ void DateCalculatorViewModel::OnInputsChanged()
|
||||
}
|
||||
else
|
||||
{
|
||||
DateDifference dateDiff;
|
||||
dateDiff.day = DaysOffset;
|
||||
dateDiff.month = MonthsOffset;
|
||||
dateDiff.year = YearsOffset;
|
||||
|
||||
DateTime dateTimeResult;
|
||||
IBox<DateTime> ^ dateTimeResult;
|
||||
|
||||
if (m_IsAddMode)
|
||||
{
|
||||
// Add number of Days, Months and Years to a Date
|
||||
IsOutOfBound = !m_dateCalcEngine->AddDuration(StartDate, dateDiff, &dateTimeResult);
|
||||
dateTimeResult = m_dateCalcEngine->AddDuration(StartDate, dateDiff);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subtract number of Days, Months and Years from a Date
|
||||
IsOutOfBound = !m_dateCalcEngine->SubtractDuration(StartDate, dateDiff, &dateTimeResult);
|
||||
dateTimeResult = m_dateCalcEngine->SubtractDuration(StartDate, dateDiff);
|
||||
}
|
||||
IsOutOfBound = dateTimeResult == nullptr;
|
||||
|
||||
if (!m_isOutOfBound)
|
||||
{
|
||||
DateResult = dateTimeResult;
|
||||
DateResult = dateTimeResult->Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,17 +174,16 @@ void DateCalculatorViewModel::UpdateDisplayResult()
|
||||
{
|
||||
IsDiffInDays = false;
|
||||
StrDateDiffResultInDays = L"";
|
||||
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"CalculationFailed");
|
||||
StrDateDiffResult = AppResourceProvider::GetInstance()->GetResourceString(L"CalculationFailed");
|
||||
}
|
||||
else if (m_dateDiffResultInDays.day == 0)
|
||||
{
|
||||
// to and from dates the same
|
||||
IsDiffInDays = true;
|
||||
StrDateDiffResultInDays = L"";
|
||||
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates");
|
||||
StrDateDiffResult = AppResourceProvider::GetInstance()->GetResourceString(L"Date_SameDates");
|
||||
}
|
||||
else if (m_dateDiffResult == DateDifferenceUnknown ||
|
||||
(m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0))
|
||||
else if (m_dateDiffResult == DateDifferenceUnknown || (m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0))
|
||||
{
|
||||
IsDiffInDays = true;
|
||||
StrDateDiffResultInDays = L"";
|
||||
@@ -206,7 +207,7 @@ void DateCalculatorViewModel::UpdateDisplayResult()
|
||||
if (m_isOutOfBound)
|
||||
{
|
||||
// Display Date out of bound message
|
||||
StrDateResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_OutOfBoundMessage");
|
||||
StrDateResult = AppResourceProvider::GetInstance()->GetResourceString(L"Date_OutOfBoundMessage");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -218,16 +219,14 @@ void DateCalculatorViewModel::UpdateDisplayResult()
|
||||
|
||||
void DateCalculatorViewModel::UpdateStrDateDiffResultAutomationName()
|
||||
{
|
||||
String ^ automationFormat = AppResourceProvider::GetInstance().GetResourceString(L"Date_DifferenceResultAutomationName");
|
||||
wstring localizedAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat->Data(), StrDateDiffResult->Data());
|
||||
StrDateDiffResultAutomationName = ref new String(localizedAutomationName.c_str());
|
||||
String ^ automationFormat = AppResourceProvider::GetInstance()->GetResourceString(L"Date_DifferenceResultAutomationName");
|
||||
StrDateDiffResultAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat, StrDateDiffResult);
|
||||
}
|
||||
|
||||
void DateCalculatorViewModel::UpdateStrDateResultAutomationName()
|
||||
{
|
||||
String ^ automationFormat = AppResourceProvider::GetInstance().GetResourceString(L"Date_ResultingDateAutomationName");
|
||||
wstring localizedAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat->Data(), StrDateResult->Data());
|
||||
StrDateResultAutomationName = ref new String(localizedAutomationName.c_str());
|
||||
String ^ automationFormat = AppResourceProvider::GetInstance()->GetResourceString(L"Date_ResultingDateAutomationName");
|
||||
StrDateResultAutomationName = LocalizationStringUtil::GetLocalizedString(automationFormat, StrDateResult);
|
||||
}
|
||||
|
||||
void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String ^ calendarIdentifier)
|
||||
@@ -247,21 +246,21 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
||||
{
|
||||
wstring result;
|
||||
bool addDelimiter = false;
|
||||
AppResourceProvider resourceLoader = AppResourceProvider::GetInstance();
|
||||
AppResourceProvider ^ resourceLoader = AppResourceProvider::GetInstance();
|
||||
|
||||
auto yearCount = m_dateDiffResult.year;
|
||||
if (yearCount > 0)
|
||||
{
|
||||
result += GetLocalizedNumberString(yearCount)->Data();
|
||||
result += L" ";
|
||||
result += L' ';
|
||||
|
||||
if (yearCount > 1)
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Years")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Years")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Year")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Year")->Data();
|
||||
}
|
||||
|
||||
// set the flags to add a delimiter whenever the next unit is added
|
||||
@@ -281,15 +280,15 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
||||
}
|
||||
|
||||
result += GetLocalizedNumberString(monthCount)->Data();
|
||||
result += L" ";
|
||||
result += L' ';
|
||||
|
||||
if (monthCount > 1)
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Months")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Months")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Month")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Month")->Data();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,15 +305,15 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
||||
}
|
||||
|
||||
result += GetLocalizedNumberString(weekCount)->Data();
|
||||
result += L" ";
|
||||
result += L' ';
|
||||
|
||||
if (weekCount > 1)
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Weeks")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Weeks")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Week")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Week")->Data();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,15 +330,15 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
||||
}
|
||||
|
||||
result += GetLocalizedNumberString(dayCount)->Data();
|
||||
result += L" ";
|
||||
result += L' ';
|
||||
|
||||
if (dayCount > 1)
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Days")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Days")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader.GetResourceString(L"Date_Day")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Day")->Data();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,16 +348,16 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
||||
String ^ DateCalculatorViewModel::GetDateDiffStringInDays() const
|
||||
{
|
||||
wstring result = GetLocalizedNumberString(m_dateDiffResultInDays.day)->Data();
|
||||
result += L" ";
|
||||
result += L' ';
|
||||
|
||||
// Display the result as '1 day' or 'N days'
|
||||
if (m_dateDiffResultInDays.day > 1)
|
||||
{
|
||||
result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Days")->Data();
|
||||
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Days")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Day")->Data();
|
||||
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Day")->Data();
|
||||
}
|
||||
|
||||
return ref new String(result.data());
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace CalculatorApp
|
||||
CalculatorApp::Common::DateCalculation::DateDifference m_dateDiffResultInDays;
|
||||
|
||||
// Private members
|
||||
std::shared_ptr<CalculatorApp::Common::DateCalculation::DateCalculationEngine> m_dateCalcEngine;
|
||||
CalculatorApp::Common::DateCalculation::DateCalculationEngine ^ m_dateCalcEngine;
|
||||
CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat;
|
||||
CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat;
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ m_dateTimeFormatter;
|
||||
|
||||
@@ -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"
|
||||
@@ -13,8 +13,8 @@ using namespace Platform;
|
||||
HistoryItemViewModel::HistoryItemViewModel(
|
||||
String ^ expression,
|
||||
String ^ result,
|
||||
_In_ const shared_ptr<CalculatorVector<pair<wstring, int>>>& spTokens,
|
||||
_In_ const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>>& spCommands)
|
||||
_In_ const shared_ptr<vector<pair<wstring, int>>>& spTokens,
|
||||
_In_ const shared_ptr<vector<shared_ptr<IExpressionCommand>>>& spCommands)
|
||||
: m_expression(expression)
|
||||
, m_result(result)
|
||||
, m_spTokens(spTokens)
|
||||
@@ -27,47 +27,17 @@ HistoryItemViewModel::HistoryItemViewModel(
|
||||
|
||||
String
|
||||
^ HistoryItemViewModel::GetAccessibleExpressionFromTokens(
|
||||
_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& spTokens,
|
||||
_In_ shared_ptr<vector<pair<wstring, int>>> const& spTokens,
|
||||
_In_ String ^ fallbackExpression)
|
||||
{
|
||||
// updating accessibility names for expression and result
|
||||
wstringstream accExpression{};
|
||||
accExpression << L"";
|
||||
|
||||
unsigned int nTokens;
|
||||
HRESULT hr = spTokens->GetSize(&nTokens);
|
||||
if (SUCCEEDED(hr))
|
||||
for (const auto& tokenItem : *spTokens)
|
||||
{
|
||||
pair<wstring, int> tokenItem;
|
||||
for (unsigned int i = 0; i < nTokens; i++)
|
||||
{
|
||||
hr = spTokens->GetAt(i, &tokenItem);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
wstring token = tokenItem.first;
|
||||
accExpression << LocalizationService::GetNarratorReadableToken(StringReference(token.c_str()))->Data();
|
||||
}
|
||||
accExpression << LocalizationService::GetNarratorReadableToken(StringReference(tokenItem.first.c_str()))->Data();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
wstring expressionSuffix{};
|
||||
hr = spTokens->GetExpressionSuffix(&expressionSuffix);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
accExpression << expressionSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return LocalizationService::GetNarratorReadableString(fallbackExpression);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ref new String(accExpression.str().c_str());
|
||||
}
|
||||
return ref new String(accExpression.str().c_str());
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CalcManager/CalculatorVector.h"
|
||||
#include "CalcManager/ExpressionCommandInterface.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
@@ -17,15 +16,15 @@ namespace CalculatorApp
|
||||
HistoryItemViewModel(
|
||||
Platform::String ^ expression,
|
||||
Platform::String ^ result,
|
||||
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& spTokens,
|
||||
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& spCommands);
|
||||
_In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& spTokens,
|
||||
_In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& spCommands);
|
||||
|
||||
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& GetTokens()
|
||||
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& GetTokens()
|
||||
{
|
||||
return m_spTokens;
|
||||
}
|
||||
|
||||
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& GetCommands()
|
||||
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& GetCommands()
|
||||
{
|
||||
return m_spCommands;
|
||||
}
|
||||
@@ -62,7 +61,7 @@ namespace CalculatorApp
|
||||
|
||||
private : static Platform::String
|
||||
^ GetAccessibleExpressionFromTokens(
|
||||
_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& spTokens,
|
||||
_In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& spTokens,
|
||||
_In_ Platform::String ^ fallbackExpression);
|
||||
|
||||
private:
|
||||
@@ -70,8 +69,8 @@ namespace CalculatorApp
|
||||
Platform::String ^ m_accExpression;
|
||||
Platform::String ^ m_accResult;
|
||||
Platform::String ^ m_result;
|
||||
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_spTokens;
|
||||
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
|
||||
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_spTokens;
|
||||
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ void HistoryViewModel::ShowItem(_In_ HistoryItemViewModel ^ e)
|
||||
{
|
||||
unsigned int index;
|
||||
Items->IndexOf(e, &index);
|
||||
TraceLogger::GetInstance().LogHistoryItemLoad((ViewMode)m_currentMode, ItemSize, (int)(index));
|
||||
TraceLogger::GetInstance()->LogHistoryItemLoad((ViewMode)m_currentMode, ItemSize, (int)(index));
|
||||
HistoryItemClicked(e);
|
||||
}
|
||||
|
||||
@@ -164,7 +164,11 @@ void HistoryViewModel::OnClearCommand(_In_ Platform::Object ^ e)
|
||||
UpdateItemSize();
|
||||
}
|
||||
|
||||
MakeHistoryClearedNarratorAnnouncement(HistoryResourceKeys::HistoryCleared, m_localizedHistoryCleared);
|
||||
if (m_localizedHistoryCleared == nullptr)
|
||||
{
|
||||
m_localizedHistoryCleared = AppResourceProvider::GetInstance()->GetResourceString(HistoryResourceKeys::HistoryCleared);
|
||||
}
|
||||
HistoryAnnouncement = CalculatorAnnouncement::GetHistoryClearedAnnouncement(m_localizedHistoryCleared);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,16 +267,16 @@ void HistoryViewModel::ClearHistory()
|
||||
void HistoryViewModel::SaveHistory()
|
||||
{
|
||||
ApplicationDataContainer ^ historyContainer = GetHistoryContainer(m_currentMode);
|
||||
auto currentHistoryVector = m_calculatorManager->GetHistoryItems(m_currentMode);
|
||||
auto const& currentHistoryVector = m_calculatorManager->GetHistoryItems(m_currentMode);
|
||||
bool failure = false;
|
||||
int index = 0;
|
||||
Platform::String ^ serializedHistoryItem;
|
||||
|
||||
for (auto iter = currentHistoryVector.begin(); iter != currentHistoryVector.end(); ++iter)
|
||||
for (auto const& item : currentHistoryVector)
|
||||
{
|
||||
try
|
||||
{
|
||||
serializedHistoryItem = SerializeHistoryItem(*iter);
|
||||
serializedHistoryItem = SerializeHistoryItem(item);
|
||||
historyContainer->Values->Insert(index.ToString(), serializedHistoryItem);
|
||||
}
|
||||
catch (Platform::Exception ^)
|
||||
@@ -370,10 +374,3 @@ void HistoryViewModel::UpdateItemSize()
|
||||
{
|
||||
ItemSize = Items->Size;
|
||||
}
|
||||
|
||||
void HistoryViewModel::MakeHistoryClearedNarratorAnnouncement(String ^ resourceKey, String ^ &formatVariable)
|
||||
{
|
||||
String ^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(resourceKey, formatVariable);
|
||||
|
||||
HistoryAnnouncement = CalculatorAnnouncement::GetHistoryClearedAnnouncement(announcement);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,6 @@ namespace CalculatorApp
|
||||
void UpdateHistoryVectorLength(_In_ int newValue, _In_ CalculationManager::CALCULATOR_MODE cMode);
|
||||
bool IsValid(_In_ CalculationManager::HISTORYITEM item);
|
||||
|
||||
void MakeHistoryClearedNarratorAnnouncement(Platform::String ^ resourceKey, Platform::String ^ &formatVariable);
|
||||
|
||||
friend class CalculatorDisplay;
|
||||
void UpdateItemSize();
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@
|
||||
#include "HistoryViewModel.h"
|
||||
#include "MemoryItemViewModel.h"
|
||||
#include "Common/BitLength.h"
|
||||
#include "Common/NumberBase.h"
|
||||
|
||||
namespace CalculatorFunctionalTests
|
||||
{
|
||||
@@ -19,7 +20,6 @@ namespace CalculatorFunctionalTests
|
||||
namespace CalculatorUnitTests
|
||||
{
|
||||
class MultiWindowUnitTests;
|
||||
class TimerTests;
|
||||
}
|
||||
|
||||
namespace CalculatorApp
|
||||
@@ -30,55 +30,64 @@ namespace CalculatorApp
|
||||
namespace ViewModel
|
||||
{
|
||||
#define ASCII_0 48
|
||||
public
|
||||
delegate void HideMemoryClickedHandler();
|
||||
public
|
||||
delegate void ProgModeRadixChangeHandler();
|
||||
public delegate void HideMemoryClickedHandler();
|
||||
|
||||
public value struct ButtonInfo
|
||||
{
|
||||
NumbersAndOperatorsEnum buttonId;
|
||||
bool canSendNegate;
|
||||
};
|
||||
|
||||
[Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||
{
|
||||
public:
|
||||
StandardCalculatorViewModel();
|
||||
void UpdateOperand(int pos, Platform::String ^ text);
|
||||
void UpdatecommandsInRecordingMode();
|
||||
int GetNumberBase();
|
||||
void UpdateCommandsInRecordingMode();
|
||||
|
||||
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, DisplayValue);
|
||||
OBSERVABLE_PROPERTY_RW(HistoryViewModel ^, HistoryVM);
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, DisplayStringExpression);
|
||||
OBSERVABLE_PROPERTY_R(HistoryViewModel ^, HistoryVM);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsAlwaysOnTop);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsBinaryBitFlippingEnabled);
|
||||
PROPERTY_R(bool, IsOperandUpdatedUsingViewModel);
|
||||
PROPERTY_R(int, TokenPosition);
|
||||
PROPERTY_R(bool, IsOperandTextCompletelySelected);
|
||||
PROPERTY_R(bool, KeyPressed);
|
||||
PROPERTY_R(Platform::String ^, SelectedExpressionLastData);
|
||||
OBSERVABLE_NAMED_PROPERTY_R(bool, IsInError);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsOperatorCommand);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, DisplayStringExpression);
|
||||
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Common::DisplayExpressionToken ^> ^, ExpressionTokens);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, DecimalDisplayValue);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, HexDisplayValue);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, OctalDisplayValue);
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String ^, BinaryDisplayValue);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, DecimalDisplayValue);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, HexDisplayValue);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, OctalDisplayValue);
|
||||
OBSERVABLE_NAMED_PROPERTY_R(Platform::String ^, BinaryDisplayValue);
|
||||
OBSERVABLE_NAMED_PROPERTY_R(Windows::Foundation::Collections::IVector<bool> ^, BinaryDigits);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, HexDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, DecDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, OctDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, BinDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsBinaryOperatorEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsUnaryOperatorEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsNegateEnabled);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, HexDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, DecDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, OctDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, BinDisplayValue_AutomationName);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsBinaryOperatorEnabled);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsUnaryOperatorEnabled);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsNegateEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsCurrentViewPinned);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<MemoryItemViewModel ^> ^, MemorizedNumbers);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsCurrentViewPinned);
|
||||
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IVector<MemoryItemViewModel ^> ^, MemorizedNumbers);
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked);
|
||||
OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, CalculationResultAutomationName);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, CalculationExpressionAutomationName);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsShiftProgrammerChecked);
|
||||
OBSERVABLE_PROPERTY_RW(int, CurrentRadixType);
|
||||
OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated);
|
||||
OBSERVABLE_PROPERTY_RW(bool, AreAlwaysOnTopResultsUpdated);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsFToEChecked);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsFToEEnabled);
|
||||
OBSERVABLE_PROPERTY_R(bool, AreHEXButtonsEnabled);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, CalculationResultAutomationName);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, CalculationExpressionAutomationName);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsShiftProgrammerChecked);
|
||||
OBSERVABLE_PROPERTY_R(CalculatorApp::Common::NumberBase, CurrentRadixType);
|
||||
OBSERVABLE_PROPERTY_R(bool, AreTokensUpdated);
|
||||
OBSERVABLE_PROPERTY_R(bool, AreAlwaysOnTopResultsUpdated);
|
||||
OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled);
|
||||
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement);
|
||||
OBSERVABLE_PROPERTY_R(bool, AreProgrammerRadixOperatorsEnabled);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsInputEmpty);
|
||||
OBSERVABLE_PROPERTY_R(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement);
|
||||
OBSERVABLE_PROPERTY_R(unsigned int, OpenParenthesisCount);
|
||||
|
||||
COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand);
|
||||
@@ -90,23 +99,6 @@ namespace CalculatorApp
|
||||
COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract);
|
||||
|
||||
event HideMemoryClickedHandler ^ HideMemoryClicked;
|
||||
event ProgModeRadixChangeHandler ^ ProgModeRadixChange;
|
||||
|
||||
property bool IsShiftChecked
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_isShiftChecked;
|
||||
}
|
||||
void set(bool value)
|
||||
{
|
||||
if (m_isShiftChecked != value)
|
||||
{
|
||||
m_isShiftChecked = value;
|
||||
RaisePropertyChanged(L"IsShiftChecked");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property bool IsBitFlipChecked
|
||||
{
|
||||
@@ -125,29 +117,8 @@ namespace CalculatorApp
|
||||
}
|
||||
}
|
||||
}
|
||||
static property Platform::String ^ IsBitFlipCheckedPropertyName
|
||||
{
|
||||
Platform::String ^ get()
|
||||
{
|
||||
return Platform::StringReference(L"IsBitFlipChecked");
|
||||
}
|
||||
}
|
||||
|
||||
property bool IsBinaryBitFlippingEnabled
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_isBinaryBitFlippingEnabled;
|
||||
}
|
||||
void set(bool value)
|
||||
{
|
||||
if (m_isBinaryBitFlippingEnabled != value)
|
||||
{
|
||||
m_isBinaryBitFlippingEnabled = value;
|
||||
RaisePropertyChanged(L"IsBinaryBitFlippingEnabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
static property Platform::String
|
||||
^ IsBitFlipCheckedPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsBitFlipChecked"); } }
|
||||
|
||||
property CalculatorApp::Common::BitLength ValueBitLength
|
||||
{
|
||||
@@ -226,29 +197,8 @@ namespace CalculatorApp
|
||||
}
|
||||
}
|
||||
}
|
||||
static property Platform::String ^ IsProgrammerPropertyName
|
||||
{
|
||||
Platform::String ^ get()
|
||||
{
|
||||
return Platform::StringReference(L"IsProgrammer");
|
||||
}
|
||||
}
|
||||
|
||||
property bool IsAlwaysOnTop
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_isAlwaysOnTop;
|
||||
}
|
||||
void set(bool value)
|
||||
{
|
||||
if (m_isAlwaysOnTop != value)
|
||||
{
|
||||
m_isAlwaysOnTop = value;
|
||||
RaisePropertyChanged(L"IsAlwaysOnTop");
|
||||
}
|
||||
}
|
||||
}
|
||||
static property Platform::String
|
||||
^ IsProgrammerPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsProgrammer"); } }
|
||||
|
||||
property bool IsEditingEnabled
|
||||
{
|
||||
@@ -300,65 +250,12 @@ namespace CalculatorApp
|
||||
}
|
||||
}
|
||||
|
||||
property int TokenPosition
|
||||
{
|
||||
int get()
|
||||
{
|
||||
return m_tokenPosition;
|
||||
}
|
||||
void set(int value)
|
||||
{
|
||||
m_tokenPosition = value;
|
||||
}
|
||||
}
|
||||
|
||||
property Platform::String^ SelectedExpressionLastData
|
||||
{
|
||||
Platform::String^ get() { return m_selectedExpressionLastData; }
|
||||
void set(Platform::String^ value) { m_selectedExpressionLastData = value; }
|
||||
}
|
||||
|
||||
property bool KeyPressed
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_keyPressed;
|
||||
}
|
||||
void set(bool value)
|
||||
{
|
||||
m_keyPressed = value;
|
||||
}
|
||||
}
|
||||
|
||||
property bool IsOperandUpdatedUsingViewModel
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_operandUpdated;
|
||||
}
|
||||
void set(bool value)
|
||||
{
|
||||
m_operandUpdated = value;
|
||||
}
|
||||
}
|
||||
|
||||
property bool IsOperandTextCompletelySelected
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_completeTextSelection;
|
||||
}
|
||||
void set(bool value)
|
||||
{
|
||||
m_completeTextSelection = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal : void OnPaste(Platform::String ^ pastedString);
|
||||
internal :
|
||||
void OnPaste(Platform::String ^ pastedString);
|
||||
void OnCopyCommand(Platform::Object ^ parameter);
|
||||
void OnPasteCommand(Platform::Object ^ parameter);
|
||||
|
||||
NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate);
|
||||
ButtonInfo MapCharacterToButtonId(char16 ch);
|
||||
|
||||
// Memory feature related methods. They are internal because they need to called from the MainPage code-behind
|
||||
void OnMemoryButtonPressed();
|
||||
@@ -368,15 +265,8 @@ namespace CalculatorApp
|
||||
void OnMemoryClear(_In_ Platform::Object ^ memoryItemPosition);
|
||||
void OnPinUnpinCommand(Platform::Object ^ parameter);
|
||||
|
||||
void SetPrimaryDisplay(_In_ std::wstring const& displayString, _In_ bool isError);
|
||||
void OnInputChanged();
|
||||
void DisplayPasteError();
|
||||
void SetTokens(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens);
|
||||
void SetExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands);
|
||||
void SetHistoryExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands);
|
||||
void SetParenthesisCount(_In_ unsigned int parenthesisCount);
|
||||
void SetOpenParenthesisCountNarratorAnnouncement();
|
||||
void OnNoRightParenAdded();
|
||||
@@ -393,14 +283,11 @@ namespace CalculatorApp
|
||||
void Recalculate(bool fromHistory = false);
|
||||
bool IsOperator(CalculationManager::Command cmdenum);
|
||||
void FtoEButtonToggled();
|
||||
void SwitchProgrammerModeBase(RADIX_TYPE calculatorBase);
|
||||
void SwitchProgrammerModeBase(CalculatorApp::Common::NumberBase calculatorBase);
|
||||
void SetMemorizedNumbersString();
|
||||
void SwitchAngleType(NumbersAndOperatorsEnum num);
|
||||
void ResetDisplay();
|
||||
RADIX_TYPE GetCurrentRadixType()
|
||||
{
|
||||
return (RADIX_TYPE)m_CurrentRadixType;
|
||||
}
|
||||
|
||||
void SetPrecision(int32_t precision);
|
||||
void UpdateMaxIntDigits()
|
||||
{
|
||||
@@ -410,12 +297,21 @@ namespace CalculatorApp
|
||||
{
|
||||
return m_CurrentAngleType;
|
||||
}
|
||||
|
||||
void SelectHistoryItem(HistoryItemViewModel ^ item);
|
||||
private:
|
||||
void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers);
|
||||
void UpdateProgrammerPanelDisplay();
|
||||
void HandleUpdatedOperandData(CalculationManager::Command cmdenum);
|
||||
void SetPrimaryDisplay(_In_ Platform::String ^ displayStringValue, _In_ bool isError);
|
||||
void SetExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands);
|
||||
void SetHistoryExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands);
|
||||
void SetTokens(_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens);
|
||||
NumbersAndOperatorsEnum ConvertIntegerToNumbersAndOperatorsEnum(unsigned int parameter);
|
||||
static RADIX_TYPE GetRadixTypeFromNumberBase(CalculatorApp::Common::NumberBase base);
|
||||
NumbersAndOperatorsEnum m_CurrentAngleType;
|
||||
wchar_t m_decimalSeparator;
|
||||
CalculatorDisplay m_calculatorDisplay;
|
||||
@@ -443,15 +339,9 @@ namespace CalculatorApp
|
||||
bool m_isStandard;
|
||||
bool m_isScientific;
|
||||
bool m_isProgrammer;
|
||||
bool m_isAlwaysOnTop;
|
||||
bool m_isBinaryBitFlippingEnabled;
|
||||
bool m_isBitFlipChecked;
|
||||
bool m_isShiftChecked;
|
||||
bool m_isRtlLanguage;
|
||||
int m_tokenPosition;
|
||||
bool m_keyPressed;
|
||||
bool m_operandUpdated;
|
||||
bool m_completeTextSelection;
|
||||
bool m_isLastOperationHistoryLoad;
|
||||
CalculatorApp::Common::BitLength m_valueBitLength;
|
||||
Platform::String ^ m_selectedExpressionLastData;
|
||||
@@ -473,15 +363,15 @@ namespace CalculatorApp
|
||||
std::wstring AddPadding(std::wstring);
|
||||
size_t LengthWithoutPadding(std::wstring);
|
||||
|
||||
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> m_tokens;
|
||||
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_commands;
|
||||
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_tokens;
|
||||
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_commands;
|
||||
|
||||
// Token types
|
||||
bool IsUnaryOp(int nOpCode);
|
||||
bool IsBinOp(int nOpcode);
|
||||
bool IsTrigOp(int nOpCode);
|
||||
bool IsOpnd(int nOpCode);
|
||||
bool IsRecoverableCommand(int nOpCode);
|
||||
bool IsUnaryOp(CalculationManager::Command command);
|
||||
bool IsBinOp(CalculationManager::Command command);
|
||||
bool IsTrigOp(CalculationManager::Command command);
|
||||
bool IsOpnd(CalculationManager::Command command);
|
||||
bool IsRecoverableCommand(CalculationManager::Command command);
|
||||
|
||||
CalculationManager::CommandType GetSelectedTokenType(_In_ unsigned int);
|
||||
void SaveEditedCommand(_In_ unsigned int index, _In_ CalculationManager::Command command);
|
||||
@@ -494,7 +384,6 @@ namespace CalculatorApp
|
||||
friend class CalculatorDisplay;
|
||||
friend class CalculatorFunctionalTests::HistoryTests;
|
||||
friend class CalculatorUnitTests::MultiWindowUnitTests;
|
||||
friend class CalculatorUnitTests::TimerTests;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,12 +137,12 @@ UnitConverterViewModel::UnitConverterViewModel(const shared_ptr<UCM::IUnitConver
|
||||
m_currencyMaxFractionDigits = m_currencyFormatter->FractionDigits;
|
||||
|
||||
auto resourceLoader = AppResourceProvider::GetInstance();
|
||||
m_localizedValueFromFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromFormat);
|
||||
m_localizedValueToFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueToFormat);
|
||||
m_localizedConversionResultFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ConversionResultFormat);
|
||||
m_localizedValueFromDecimalFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromDecimalFormat);
|
||||
m_localizedInputUnitName = resourceLoader.GetResourceString(UnitConverterResourceKeys::InputUnit_Name);
|
||||
m_localizedOutputUnitName = resourceLoader.GetResourceString(UnitConverterResourceKeys::OutputUnit_Name);
|
||||
m_localizedValueFromFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueFromFormat);
|
||||
m_localizedValueToFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueToFormat);
|
||||
m_localizedConversionResultFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ConversionResultFormat);
|
||||
m_localizedValueFromDecimalFormat = resourceLoader->GetResourceString(UnitConverterResourceKeys::ValueFromDecimalFormat);
|
||||
m_localizedInputUnitName = resourceLoader->GetResourceString(UnitConverterResourceKeys::InputUnit_Name);
|
||||
m_localizedOutputUnitName = resourceLoader->GetResourceString(UnitConverterResourceKeys::OutputUnit_Name);
|
||||
|
||||
Unit1AutomationName = m_localizedInputUnitName;
|
||||
Unit2AutomationName = m_localizedOutputUnitName;
|
||||
@@ -390,7 +390,7 @@ String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& st
|
||||
|
||||
void UnitConverterViewModel::DisplayPasteError()
|
||||
{
|
||||
String ^ errorMsg = AppResourceProvider::GetInstance().GetCEngineString(StringReference(SIDS_DOMAIN)); /*SIDS_DOMAIN is for "invalid input"*/
|
||||
String ^ errorMsg = AppResourceProvider::GetInstance()->GetCEngineString(StringReference(SIDS_DOMAIN)); /*SIDS_DOMAIN is for "invalid input"*/
|
||||
Value1 = errorMsg;
|
||||
Value2 = errorMsg;
|
||||
m_relocalizeStringOnSwitch = false;
|
||||
@@ -476,10 +476,10 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter)
|
||||
return;
|
||||
}
|
||||
|
||||
static const vector<UCM::Command> OPERANDS = { UCM::Command::Zero, UCM::Command::One, UCM::Command::Two, UCM::Command::Three, UCM::Command::Four,
|
||||
static constexpr UCM::Command OPERANDS[] = { UCM::Command::Zero, UCM::Command::One, UCM::Command::Two, UCM::Command::Three, UCM::Command::Four,
|
||||
UCM::Command::Five, UCM::Command::Six, UCM::Command::Seven, UCM::Command::Eight, UCM::Command::Nine };
|
||||
|
||||
if (find(begin(OPERANDS), end(OPERANDS), command) != OPERANDS.end())
|
||||
if (find(begin(OPERANDS), end(OPERANDS), command) != end(OPERANDS))
|
||||
{
|
||||
if (m_isInputBlocked)
|
||||
{
|
||||
@@ -494,7 +494,7 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter)
|
||||
|
||||
m_model->SendCommand(command);
|
||||
|
||||
TraceLogger::GetInstance().LogConverterInputReceived(Mode);
|
||||
TraceLogger::GetInstance()->LogConverterInputReceived(Mode);
|
||||
}
|
||||
|
||||
void UnitConverterViewModel::OnCopyCommand(Platform::Object ^ parameter)
|
||||
@@ -515,8 +515,10 @@ void UnitConverterViewModel::OnPasteCommand(Platform::Object ^ parameter)
|
||||
// Ensure that the paste happens on the UI thread
|
||||
// EventWriteClipboardPaste_Start();
|
||||
// Any converter ViewMode is fine here.
|
||||
CopyPasteManager::GetStringToPaste(m_Mode, NavCategory::GetGroupType(m_Mode))
|
||||
.then([this](String ^ pastedString) { OnPaste(pastedString); }, concurrency::task_continuation_context::use_current());
|
||||
|
||||
auto that(this);
|
||||
create_task(CopyPasteManager::GetStringToPaste(m_Mode, NavCategory::GetGroupType(m_Mode), NumberBase::Unknown, BitLength::BitLengthUnknown))
|
||||
.then([that](String ^ pastedString) { that->OnPaste(pastedString); }, concurrency::task_continuation_context::use_current());
|
||||
}
|
||||
|
||||
void UnitConverterViewModel::InitializeView()
|
||||
@@ -650,7 +652,7 @@ void UnitConverterViewModel::OnCurrencyDataLoadFinished(bool didLoad)
|
||||
ResetCategory();
|
||||
|
||||
StringReference key = didLoad ? UnitConverterResourceKeys::CurrencyRatesUpdated : UnitConverterResourceKeys::CurrencyRatesUpdateFailed;
|
||||
String ^ announcement = AppResourceProvider::GetInstance().GetResourceString(key);
|
||||
String ^ announcement = AppResourceProvider::GetInstance()->GetResourceString(key);
|
||||
Announcement = CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(announcement);
|
||||
}
|
||||
|
||||
@@ -665,17 +667,18 @@ void UnitConverterViewModel::RefreshCurrencyRatios()
|
||||
m_isCurrencyDataLoaded = false;
|
||||
IsCurrencyLoadingVisible = true;
|
||||
|
||||
String ^ announcement = AppResourceProvider::GetInstance().GetResourceString(UnitConverterResourceKeys::UpdatingCurrencyRates);
|
||||
String ^ announcement = AppResourceProvider::GetInstance()->GetResourceString(UnitConverterResourceKeys::UpdatingCurrencyRates);
|
||||
Announcement = CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(announcement);
|
||||
|
||||
auto refreshTask = create_task([this] { return m_model->RefreshCurrencyRatios().get(); });
|
||||
auto that(this);
|
||||
auto refreshTask = create_task([that] { return that->m_model->RefreshCurrencyRatios().get(); });
|
||||
refreshTask.then(
|
||||
[this](const pair<bool, wstring>& refreshResult) {
|
||||
[that](const pair<bool, wstring>& refreshResult) {
|
||||
bool didLoad = refreshResult.first;
|
||||
wstring timestamp = refreshResult.second;
|
||||
|
||||
OnCurrencyTimestampUpdated(timestamp, false /*isWeekOldData*/);
|
||||
OnCurrencyDataLoadFinished(didLoad);
|
||||
that->OnCurrencyTimestampUpdated(timestamp, false /*isWeekOldData*/);
|
||||
that->OnCurrencyDataLoadFinished(didLoad);
|
||||
},
|
||||
task_continuation_context::use_current());
|
||||
}
|
||||
@@ -878,22 +881,22 @@ NumbersAndOperatorsEnum UnitConverterViewModel::MapCharacterToButtonId(const wch
|
||||
void UnitConverterViewModel::OnPaste(String ^ stringToPaste)
|
||||
{
|
||||
// If pastedString is invalid("NoOp") then display pasteError else process the string
|
||||
if (stringToPaste == StringReference(CopyPasteManager::PasteErrorString))
|
||||
if (CopyPasteManager::IsErrorMessage(stringToPaste))
|
||||
{
|
||||
this->DisplayPasteError();
|
||||
return;
|
||||
}
|
||||
|
||||
TraceLogger::GetInstance().LogInputPasted(Mode);
|
||||
TraceLogger::GetInstance()->LogInputPasted(Mode);
|
||||
bool isFirstLegalChar = true;
|
||||
bool sendNegate = false;
|
||||
wstring accumulation = L"";
|
||||
wstring accumulation;
|
||||
|
||||
for (auto it = stringToPaste->Begin(); it != stringToPaste->End(); it++)
|
||||
for (const auto ch : stringToPaste)
|
||||
{
|
||||
bool canSendNegate = false;
|
||||
|
||||
NumbersAndOperatorsEnum op = MapCharacterToButtonId(*it, canSendNegate);
|
||||
NumbersAndOperatorsEnum op = MapCharacterToButtonId(ch, canSendNegate);
|
||||
|
||||
if (NumbersAndOperatorsEnum::None != op)
|
||||
{
|
||||
@@ -929,7 +932,7 @@ void UnitConverterViewModel::OnPaste(String ^ stringToPaste)
|
||||
}
|
||||
}
|
||||
|
||||
accumulation += *it;
|
||||
accumulation += ch;
|
||||
UpdateInputBlocked(accumulation);
|
||||
if (m_isInputBlocked)
|
||||
{
|
||||
@@ -954,8 +957,7 @@ String ^ UnitConverterViewModel::GetLocalizedAutomationName(_In_ String ^ displa
|
||||
format = m_localizedValueFromDecimalFormat;
|
||||
}
|
||||
|
||||
wstring localizedResult = LocalizationStringUtil::GetLocalizedString(format->Data(), displayvalue->Data(), unitname->Data());
|
||||
return ref new String(localizedResult.c_str());
|
||||
return LocalizationStringUtil::GetLocalizedString(format, displayvalue, unitname);
|
||||
}
|
||||
|
||||
String
|
||||
@@ -965,11 +967,7 @@ String
|
||||
_In_ String ^ toValue,
|
||||
_In_ String ^ toUnit)
|
||||
{
|
||||
String ^ localizedString =
|
||||
ref new String(LocalizationStringUtil::GetLocalizedString(
|
||||
m_localizedConversionResultFormat->Data(), fromValue->Data(), fromUnit->Data(), toValue->Data(), toUnit->Data())
|
||||
.c_str());
|
||||
return localizedString;
|
||||
return LocalizationStringUtil::GetLocalizedString(m_localizedConversionResultFormat, fromValue, fromUnit, toValue, toUnit);
|
||||
}
|
||||
|
||||
void UnitConverterViewModel::UpdateValue1AutomationName()
|
||||
@@ -990,9 +988,9 @@ void UnitConverterViewModel::UpdateValue2AutomationName()
|
||||
|
||||
void UnitConverterViewModel::OnMaxDigitsReached()
|
||||
{
|
||||
String ^ format = AppResourceProvider::GetInstance().GetResourceString(UnitConverterResourceKeys::MaxDigitsReachedFormat);
|
||||
const wstring& announcement = LocalizationStringUtil::GetLocalizedString(format->Data(), m_lastAnnouncedConversionResult->Data());
|
||||
Announcement = CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(StringReference(announcement.c_str()));
|
||||
String ^ format = AppResourceProvider::GetInstance()->GetResourceString(UnitConverterResourceKeys::MaxDigitsReachedFormat);
|
||||
auto announcement = LocalizationStringUtil::GetLocalizedString(format, m_lastAnnouncedConversionResult);
|
||||
Announcement = CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(announcement);
|
||||
}
|
||||
|
||||
bool UnitConverterViewModel::UnitsAreValid()
|
||||
@@ -1002,17 +1000,18 @@ bool UnitConverterViewModel::UnitsAreValid()
|
||||
|
||||
void UnitConverterViewModel::StartConversionResultTimer()
|
||||
{
|
||||
m_conversionResultTaskHelper = make_unique<ConversionResultTaskHelper>(CONVERSION_FINALIZED_DELAY_IN_MS, [this]() {
|
||||
if (UnitsAreValid())
|
||||
auto that(this);
|
||||
m_conversionResultTaskHelper = make_unique<ConversionResultTaskHelper>(CONVERSION_FINALIZED_DELAY_IN_MS, [that]() {
|
||||
if (that->UnitsAreValid())
|
||||
{
|
||||
String ^ valueFrom = m_Value1Active ? m_Value1 : m_Value2;
|
||||
String ^ valueTo = m_Value1Active ? m_Value2 : m_Value1;
|
||||
String ^ valueFrom = that->m_Value1Active ? that->m_Value1 : that->m_Value2;
|
||||
String ^ valueTo = that->m_Value1Active ? that->m_Value2 : that->m_Value1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String ^ SupplementaryResult::GetLocalizedAutomationName()
|
||||
{
|
||||
auto format = AppResourceProvider::GetInstance().GetResourceString("SupplementaryUnit_AutomationName");
|
||||
return ref new String(LocalizationStringUtil::GetLocalizedString(format->Data(), this->Value->Data(), this->Unit->Name->Data()).c_str());
|
||||
auto format = AppResourceProvider::GetInstance()->GetResourceString("SupplementaryUnit_AutomationName");
|
||||
return LocalizationStringUtil::GetLocalizedString(format, this->Value, this->Unit->Name);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.UI.Xaml" version="2.0.181018003.1" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.2.190830001" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <regex>
|
||||
#include <iterator>
|
||||
#include <intsafe.h>
|
||||
#include <ppltasks.h>
|
||||
|
||||
// C++\WinRT Headers
|
||||
#include "winrt/base.h"
|
||||
#include "winrt/Windows.Foundation.Diagnostics.h"
|
||||
|
||||
Reference in New Issue
Block a user