calculator/src/CalcViewModel/UnitConverterViewModel.h
Rudy Huyn 28888d8df1 Remove Serialize/Deserialize functions never used in StandardCalculatorViewModel, UnitConverter, UnitConverterViewModel and CalculatorManager (#392)
* remove unused serializer

* remove all unused serialization/deserialization from StandardCalculatorViewModel and UnitConverterViewModel

* formatting
2019-05-09 11:01:43 -07:00

406 lines
17 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "CalcManager/UnitConverter.h"
#include "Common/Utils.h"
#include "Common/NetworkManager.h"
#include "Common/Automation/NarratorAnnouncement.h"
#include "Common/ConversionResultTaskHelper.h"
#include "Common/CalculatorButtonUser.h"
#include "Common/NavCategory.h"
namespace CalculatorApp
{
namespace ViewModel
{
[Windows::UI::Xaml::Data::Bindable] public ref class Category sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
internal : Category(const UnitConversionManager::Category& category)
: m_original(category)
{
}
public:
OBSERVABLE_OBJECT();
property Platform::String
^ Name { Platform::String ^ get() { return ref new Platform::String(m_original.name.c_str()); } }
property Windows::UI::Xaml::Visibility NegateVisibility
{
Windows::UI::Xaml::Visibility get()
{
return m_original.supportsNegative ? Windows::UI::Xaml::Visibility::Visible : Windows::UI::Xaml::Visibility::Collapsed;
}
}
internal : const UnitConversionManager::Category& GetModelCategory() const
{
return m_original;
}
private:
const UnitConversionManager::Category m_original;
};
[Windows::UI::Xaml::Data::Bindable] public ref class Unit sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
internal : Unit(const UnitConversionManager::Unit& unit)
: m_original(unit)
{
}
public:
OBSERVABLE_OBJECT();
property Platform::String
^ Name { Platform::String ^ get() { return ref new Platform::String(m_original.name.c_str()); } }
property Platform::String
^ AccessibleName { Platform::String ^ get() { return ref new Platform::String(m_original.accessibleName.c_str()); } }
property Platform::String
^ Abbreviation { Platform::String ^ get() { return ref new Platform::String(m_original.abbreviation.c_str()); } }
// This method is used to return the desired automation name for default unit in UnitConverter combo box.
Platform::String
^ ToString() override
{
return AccessibleName;
}
internal : const UnitConversionManager::Unit& GetModelUnit() const
{
return m_original;
}
private:
const UnitConversionManager::Unit m_original;
};
[Windows::UI::Xaml::Data::Bindable] public ref class SupplementaryResult sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
internal : SupplementaryResult(Platform::String ^ value, Unit ^ unit)
: m_Value(value)
, m_Unit(unit)
{
}
bool IsWhimsical() const
{
return m_Unit->GetModelUnit().isWhimsical;
}
Platform::String ^ GetLocalizedAutomationName();
public:
OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_R(Platform::String ^, Value);
OBSERVABLE_PROPERTY_R(CalculatorApp::ViewModel::Unit ^, Unit);
};
interface class IActivatable
{
virtual property bool IsActive;
};
template <typename TActivatable>
ref class Activatable sealed : public IActivatable
{
private:
TActivatable m_activatable;
public:
Activatable(TActivatable activatable)
: m_activatable(activatable)
{
}
virtual property bool IsActive
{
bool get()
{
return m_activatable->IsActive;
}
void set(bool value)
{
m_activatable->IsActive = value;
}
}
};
template <typename TActivatable>
IActivatable
^ AsActivatable(TActivatable activatable) { return ref new Activatable<TActivatable>(activatable); }
[Windows::UI::Xaml::Data::Bindable] public ref class UnitConverterViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
internal : UnitConverterViewModel(const std::shared_ptr<UnitConversionManager::IUnitConverter>& model);
public:
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Category ^> ^, Categories);
OBSERVABLE_PROPERTY_RW(Category ^, CurrentCategory);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::ViewMode, Mode);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Unit ^> ^, Units);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CurrencySymbol1);
OBSERVABLE_PROPERTY_RW(Unit ^, Unit1);
OBSERVABLE_PROPERTY_RW(Platform::String ^, Value1);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CurrencySymbol2);
OBSERVABLE_PROPERTY_RW(Unit ^, Unit2);
OBSERVABLE_PROPERTY_RW(Platform::String ^, Value2);
OBSERVABLE_NAMED_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<SupplementaryResult ^> ^, SupplementaryResults);
OBSERVABLE_PROPERTY_RW(bool, Value1Active);
OBSERVABLE_PROPERTY_RW(bool, Value2Active);
OBSERVABLE_PROPERTY_RW(Platform::String ^, Value1AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, Value2AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, Unit1AutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, Unit2AutomationName);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement);
OBSERVABLE_PROPERTY_RW(bool, IsDecimalEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsDropDownOpen);
OBSERVABLE_PROPERTY_RW(bool, IsDropDownEnabled);
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsCurrencyLoadingVisible);
OBSERVABLE_PROPERTY_RW(bool, IsCurrencyCurrentCategory);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CurrencyRatioEquality);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CurrencyRatioEqualityAutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String ^, CurrencyTimestamp);
OBSERVABLE_NAMED_PROPERTY_RW(CalculatorApp::NetworkAccessBehavior, NetworkBehavior);
OBSERVABLE_NAMED_PROPERTY_RW(bool, CurrencyDataLoadFailed);
OBSERVABLE_NAMED_PROPERTY_RW(bool, CurrencyDataIsWeekOld);
property Windows::UI::Xaml::Visibility SupplementaryVisibility
{
Windows::UI::Xaml::Visibility get()
{
return SupplementaryResults->Size > 0 ? Windows::UI::Xaml::Visibility::Visible : Windows::UI::Xaml::Visibility::Collapsed;
}
}
property Windows::UI::Xaml::Visibility CurrencySymbolVisibility
{
Windows::UI::Xaml::Visibility get()
{
return (CurrencySymbol1->IsEmpty() || CurrencySymbol2->IsEmpty()) ? Windows::UI::Xaml::Visibility::Collapsed
: Windows::UI::Xaml::Visibility::Visible;
}
}
COMMAND_FOR_METHOD(CategoryChanged, UnitConverterViewModel::OnCategoryChanged);
COMMAND_FOR_METHOD(UnitChanged, UnitConverterViewModel::OnUnitChanged);
COMMAND_FOR_METHOD(SwitchActive, UnitConverterViewModel::OnSwitchActive);
COMMAND_FOR_METHOD(ButtonPressed, UnitConverterViewModel::OnButtonPressed);
COMMAND_FOR_METHOD(CopyCommand, UnitConverterViewModel::OnCopyCommand);
COMMAND_FOR_METHOD(PasteCommand, UnitConverterViewModel::OnPasteCommand);
void AnnounceConversionResult();
internal : void ResetView();
void PopulateData();
NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate);
void DisplayPasteError();
void OnValueActivated(IActivatable ^ control);
void OnPaste(Platform::String ^ stringToPaste, CalculatorApp::Common::ViewMode mode);
void OnCopyCommand(Platform::Object ^ parameter);
void OnPasteCommand(Platform::Object ^ parameter);
Platform::String
^ GetLocalizedAutomationName(_In_ Platform::String ^ displayvalue, _In_ Platform::String ^ unitname, _In_ Platform::String ^ format);
Platform::String
^ GetLocalizedConversionResultStringFormat(
_In_ Platform::String ^ fromValue,
_In_ Platform::String ^ fromUnit,
_In_ Platform::String ^ toValue,
_In_ Platform::String ^ toUnit);
void UpdateValue1AutomationName();
void UpdateValue2AutomationName();
// Saving And Restoring User Preferences of Category and Associated-Units across Sessions.
void SaveUserPreferences();
void RestoreUserPreferences();
void OnCurrencyDataLoadFinished(bool didLoad);
void OnCurrencyTimestampUpdated(_In_ const std::wstring& timestamp, bool isWeekOld);
void RefreshCurrencyRatios();
void OnNetworkBehaviorChanged(_In_ CalculatorApp::NetworkAccessBehavior newBehavior);
const std::wstring& GetValueFromUnlocalized() const
{
return m_valueFromUnlocalized;
}
const std::wstring& GetValueToUnlocalized() const
{
return m_valueToUnlocalized;
}
// used by UnitConverterVMCallback
void UpdateDisplay(const std::wstring& from, const std::wstring& to);
void UpdateSupplementaryResults(const std::vector<std::tuple<std::wstring, UnitConversionManager::Unit>>& suggestedValues);
void OnMaxDigitsReached();
void BuildUnitList(const std::vector<UnitConversionManager::Unit>& modelUnitList);
Unit ^ FindUnitInList(UnitConversionManager::Unit target);
void SetSelectedUnits();
private:
void InitializeView();
void OnPropertyChanged(Platform::String ^ prop);
void OnCategoryChanged(Platform::Object ^ unused);
void OnUnitChanged(Platform::Object ^ unused);
void OnSwitchActive(Platform::Object ^ unused);
UnitConversionManager::Command CommandFromButtonId(CalculatorApp::NumbersAndOperatorsEnum button);
void SupplementaryResultsTimerTick(Windows::System::Threading::ThreadPoolTimer ^ timer);
void SupplementaryResultsTimerCancel(Windows::System::Threading::ThreadPoolTimer ^ timer);
void RefreshSupplementaryResults();
void UpdateInputBlocked(_In_ const std::wstring& currencyInput);
bool UnitsAreValid();
void ResetCategory();
void OnButtonPressed(Platform::Object ^ parameter);
Platform::String ^ ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings);
void StartConversionResultTimer();
std::shared_ptr<UnitConversionManager::IUnitConverter> m_model;
wchar_t m_decimalSeparator;
enum class ConversionParameter
{
Source,
Target
} m_value1cp;
property Platform::String^ ValueFrom
{
Platform::String^ get() { return m_value1cp == ConversionParameter::Source ? Value1 : Value2; }
void set(Platform::String^ value) { m_value1cp == ConversionParameter::Source ? Value1 = value : Value2 = value; }
}
property Unit^ UnitFrom
{
Unit^ get() { return m_value1cp == ConversionParameter::Source ? Unit1 : Unit2; }
void set(Unit^ value) { m_value1cp == ConversionParameter::Source ? Unit1 = value : Unit2 = value; }
}
property Platform::String^ ValueTo
{
Platform::String^ get() { return m_value1cp == ConversionParameter::Target ? Value1 : Value2; }
void set(Platform::String^ value) { m_value1cp == ConversionParameter::Target ? Value1 = value : Value2 = value; }
}
property Unit^ UnitTo
{
Unit^ get() { return m_value1cp == ConversionParameter::Target ? Unit1 : Unit2; }
void set(Unit^ value) { m_value1cp == ConversionParameter::Target ? Unit1 = value : Unit2 = value; }
}
void SwitchConversionParameters()
{
m_value1cp = m_value1cp == ConversionParameter::Source ? ConversionParameter::Target : ConversionParameter::Source;
}
private:
bool m_isInputBlocked;
Windows::System::Threading::ThreadPoolTimer ^ m_supplementaryResultsTimer;
bool m_resettingTimer;
std::vector<std::tuple<std::wstring, UnitConversionManager::Unit>> m_cachedSuggestedValues;
std::mutex m_cacheMutex;
Windows::Globalization::NumberFormatting::DecimalFormatter ^ m_decimalFormatter;
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ m_currencyFormatter;
int m_currencyMaxFractionDigits;
std::wstring m_valueFromUnlocalized;
std::wstring m_valueToUnlocalized;
bool m_relocalizeStringOnSwitch;
// For Saving the User Preferences only if the Unit converter ViewModel is initialised for the first time
bool m_IsFirstTime;
Platform::String ^ m_localizedValueFromFormat;
Platform::String ^ m_localizedValueFromDecimalFormat;
Platform::String ^ m_localizedValueToFormat;
Platform::String ^ m_localizedConversionResultFormat;
Platform::String ^ m_localizedInputUnitName;
Platform::String ^ m_localizedOutputUnitName;
bool m_isValue1Updating;
bool m_isValue2Updating;
std::wstring m_lastAnnouncedFrom;
std::wstring m_lastAnnouncedTo;
Platform::String ^ m_lastAnnouncedConversionResult;
bool m_isCurrencyDataLoaded;
std::unique_ptr<CalculatorApp::Common::ConversionResultTaskHelper> m_conversionResultTaskHelper;
};
class UnitConverterVMCallback : public UnitConversionManager::IUnitConverterVMCallback
{
public:
UnitConverterVMCallback(UnitConverterViewModel ^ viewModel)
: m_viewModel(viewModel)
{
}
void DisplayCallback(const std::wstring& from, const std::wstring& to) override
{
m_viewModel->UpdateDisplay(from, to);
}
void SuggestedValueCallback(const std::vector<std::tuple<std::wstring, UnitConversionManager::Unit>>& suggestedValues) override
{
m_viewModel->UpdateSupplementaryResults(suggestedValues);
}
void MaxDigitsReached()
{
m_viewModel->OnMaxDigitsReached();
}
private:
UnitConverterViewModel ^ m_viewModel;
};
class ViewModelCurrencyCallback : public UnitConversionManager::IViewModelCurrencyCallback
{
public:
ViewModelCurrencyCallback(UnitConverterViewModel ^ viewModel)
: m_viewModel(viewModel)
{
}
void CurrencyDataLoadFinished(bool didLoad) override
{
m_viewModel->OnCurrencyDataLoadFinished(didLoad);
}
void CurrencySymbolsCallback(const std::wstring& symbol1, const std::wstring& symbol2) override
{
Platform::String ^ sym1 = Platform::StringReference(symbol1.c_str());
Platform::String ^ sym2 = Platform::StringReference(symbol2.c_str());
bool value1Active = m_viewModel->Value1Active;
m_viewModel->CurrencySymbol1 = value1Active ? sym1 : sym2;
m_viewModel->CurrencySymbol2 = value1Active ? sym2 : sym1;
}
void CurrencyRatiosCallback(_In_ const std::wstring& ratioEquality, _In_ const std::wstring& accRatioEquality) override
{
m_viewModel->CurrencyRatioEquality = ref new Platform::String(ratioEquality.c_str());
m_viewModel->CurrencyRatioEqualityAutomationName = ref new Platform::String(accRatioEquality.c_str());
}
void CurrencyTimestampCallback(_In_ const std::wstring& timestamp, bool isWeekOld) override
{
m_viewModel->OnCurrencyTimestampUpdated(timestamp, isWeekOld);
}
void NetworkBehaviorChanged(_In_ int newBehavior) override
{
m_viewModel->OnNetworkBehaviorChanged(static_cast<CalculatorApp::NetworkAccessBehavior>(newBehavior));
}
private:
UnitConverterViewModel ^ m_viewModel;
};
}
}