Multiprocotol Terminalprogram (BAT)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MultiTerm/MultiTerm.Core/ViewModel/TerminalViewModel.cs

154 lines
5.9 KiB

using Common.AppSettings;
using Common.Helpers;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MultiTerm.Core.Types;
using MultiTerm.Protocols;
using MultiTerm.Protocols.Types;
namespace MultiTerm.Core.ViewModel;
public abstract partial class TerminalViewModel : ObservableObject, ITerminalViewModel
{
private const string defaultReceiveNewlineSeparatorAppSettingsKey = "DefaultReceiveNewlineSeparator";
private const string defaultSendNewlineSeparatorAppSettingsKey = "DefaultSendNewlineSeparator";
private readonly IAppSettingsProvider appSettings;
public abstract string Title { get; }
public abstract TerminalViewType ViewType { get; }
public ProtocolType ProtocolType { get; set; }
/// <summary>
/// Holds communication data, meaning data that was sent to or received over the communication protocol.
/// </summary>
[ObservableProperty]
private CommunicationDataViewModel communicationData = new(null);
/// <summary>
/// Newline Separator Type that is selected for receival data of this Terminal. Defaults to none.
/// </summary>
[ObservableProperty]
private NewlineSeparatorType receiveNewlineSeparatorType = NewlineSeparatorType.None;
/// <summary>
/// Newline Separator Type that is selected for sent out data of this Terminal. Defaults to none.
/// </summary>
[ObservableProperty]
private NewlineSeparatorType sendNewlineSeparatorType = NewlineSeparatorType.None;
private ICommunicationProtocol? communicationProtocol;
public ICommunicationProtocol? CommunicationProtocol
{
get { return communicationProtocol; }
set
{
communicationProtocol = value;
// register communication protocol in the Communication Data View Model
//this.CommunicationData = new CommunicationDataViewModel(communicationProtocol); // TEMP
// initialize both newline Separators. initializes with null if they are not available.
this.CommunicationData.ConfigureNewlineSeparators(this.ReceiveNewlineSeparatorType, this.SendNewlineSeparatorType);
}
}
private IProtocolSettingsViewModel? protocolSettings;
public IProtocolSettingsViewModel? ProtocolSettings
{
get { return protocolSettings; }
set
{
protocolSettings = value;
// register event handler for connection request from viewmodel
if(value != null)
{
protocolSettings!.ConnectRequested += OnViewModelRequestedConnect;
protocolSettings!.DisconnectRequested += OnViewModelRequestedDisconnect;
}
}
}
public TerminalViewModel(IAppSettingsProvider appSettings)
{
this.appSettings = appSettings;
this.InitializeNewlineSeparatorsFromAppSettings();
}
#region Connect/Disconnect
private void OnViewModelRequestedConnect(object? sender, ConnectionRequestEventArgs e)
{
// guard uninitialized CommunicationProtocol
if (CommunicationProtocol == null) { throw new Exception($"To call '{nameof(OnViewModelRequestedConnect)}()', CommunicationProtocol must not be null!"); }
e.Success = this.CommunicationProtocol.Connect(e.Settings);
}
private void OnViewModelRequestedDisconnect(object? sender, EventArgs e)
{
// guard uninitialized CommunicationProtocol
if (CommunicationProtocol == null) { throw new Exception($"To call '{nameof(OnViewModelRequestedConnect)}()', CommunicationProtocol must not be null!"); }
this.CommunicationProtocol.Disconnect();
}
#endregion
#region Closing handling
public event EventHandler? ClosingEvent;
/// <summary>
/// Method to override if any closing actions are required.
/// Closing can be cancelled using the return value.
/// </summary>
/// <returns>true if closing is allowed. false if it shall be cancelled.</returns>
protected virtual bool ClosingActions() { return true; }
[RelayCommand]
public void CloseRequest()
{
if (this.ClosingActions() == true)
{
ClosingEvent?.Invoke(this, EventArgs.Empty);
}
}
#endregion
#region Newline Separator handling
/// <summary>
/// Gets the default settings for both newline separators from the AppSettings Provider.
/// Writes them to the local variables <see cref="ReceiveNewlineSeparatorType"/> and <see cref="SendNewlineSeparatorType"/>.
/// In case there are no default settings, it does not overwrite the local variables.
/// In case the Communication Data is null, nothing is done.
/// </summary>
private void InitializeNewlineSeparatorsFromAppSettings()
{
// guard null objects
if(this.CommunicationData == null) { return; }
// get newline separators from persistent settings, if not available catch exceptions
this.appSettings.TryReadSetting(defaultReceiveNewlineSeparatorAppSettingsKey, out string settingValueReceiveNLSep);
try
{
this.ReceiveNewlineSeparatorType = EnumHelpers.ParseEnum<NewlineSeparatorType>(settingValueReceiveNLSep);
}
catch { }
this.appSettings.TryReadSetting(defaultSendNewlineSeparatorAppSettingsKey, out string settingValueSendNLSep);
try
{
this.SendNewlineSeparatorType = EnumHelpers.ParseEnum<NewlineSeparatorType>(settingValueSendNLSep);
}
catch { }
}
partial void OnReceiveNewlineSeparatorTypeChanged(NewlineSeparatorType value)
{
// triggers rearranging the received data with the new NewlineSeparatorType
this.CommunicationData.ConfigureNewlineSeparators(value, null);
}
partial void OnSendNewlineSeparatorTypeChanged(NewlineSeparatorType value)
{
// triggers rearranging the sent data with the new NewlineSeparatorType
this.CommunicationData.ConfigureNewlineSeparators(null, value);
}
#endregion
}