* Simplifying view models, step 1: Extracting common terminal configuration into TerminalInfoViewModel.cs. * Simplifying a bit. * SSH view models simplfication. * Refactoring duplicated code. * Refactoring duplicated code. * Renaming a resource file. * Cleanup. * Fixing an issue with TemplateSelectors. * QuickSshDialog created. * Minor fix. * Wiring up QuickSshDialog. * Minor fix. * Fixed an issue with shared resources. * Single-text-box dialog works. * Improving "Quick SSH" look. * Improving data validation workflow to avoid double validations. * Refactoring view models and templates to avoid duplicated code. * Minor fix. * Fixing a bug with mosh. * Cleanup. * Cleanup. * Moving profile view models in a separate folder (namespace). * Few comment lines (short description) added to profile view models. * Removing IDisposable from view-models because event-caused memory leaks will be solved differently. * Implemented quick-ssh shortcuts. * Fixing quick SSH command validation. * Minor change. * Minor change. * Combining "SSH Info" and "Quick SSH" into a single dialog. * Quick SSH profiles. * Fixing a minor bug with custom links. * Fixing remote profiles look and feel. * Minor improvements. * Fixing a minor bug. * Minor changes based on Felix' comments. * Saving executed commands history implemented.
219 lines
6.3 KiB
C#
219 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using FluentTerminal.App.Services;
|
|
using FluentTerminal.App.Services.Utilities;
|
|
using FluentTerminal.App.ViewModels.Infrastructure;
|
|
using FluentTerminal.App.ViewModels.Profiles;
|
|
using FluentTerminal.App.ViewModels.Settings;
|
|
using FluentTerminal.Models;
|
|
using GalaSoft.MvvmLight;
|
|
using GalaSoft.MvvmLight.Command;
|
|
|
|
namespace FluentTerminal.App.ViewModels
|
|
{
|
|
/// <summary>
|
|
/// Base class for all shell profile view models. Implements logic for saving, editing, resetting, etc.
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public abstract class ShellProfileViewModelBase<T> : ViewModelBase where T : ProfileProviderViewModelBase
|
|
{
|
|
#region Fields
|
|
|
|
protected readonly IDialogService DialogService;
|
|
protected readonly ISettingsService SettingsService;
|
|
|
|
private List<KeyBinding> _bindingsBeforeEdit;
|
|
private string _nameBeforeEdit;
|
|
|
|
#endregion Fields
|
|
|
|
#region Properties
|
|
|
|
protected bool IsNew { get; private set; }
|
|
|
|
public Guid Id { get; private set; }
|
|
|
|
private bool _inEditMode;
|
|
|
|
public bool InEditMode
|
|
{
|
|
get => _inEditMode;
|
|
set => Set(ref _inEditMode, value);
|
|
}
|
|
|
|
private string _name;
|
|
|
|
public string Name
|
|
{
|
|
get => _name;
|
|
set => Set(ref _name, value);
|
|
}
|
|
|
|
public KeyBindingsViewModel KeyBindings { get; }
|
|
|
|
public T ProfileVm { get; protected set; }
|
|
|
|
#endregion Properties
|
|
|
|
#region Events
|
|
|
|
public event EventHandler Deleted;
|
|
|
|
#endregion Events
|
|
|
|
#region Commands
|
|
|
|
public IAsyncCommand CancelEditCommand { get; }
|
|
|
|
public IAsyncCommand DeleteCommand { get; }
|
|
|
|
public RelayCommand EditCommand { get; }
|
|
|
|
public IAsyncCommand SaveChangesCommand { get; }
|
|
|
|
public IAsyncCommand AddKeyboardShortcutCommand { get; }
|
|
|
|
#endregion Commands
|
|
|
|
#region Constructor
|
|
|
|
protected ShellProfileViewModelBase(ShellProfile shellProfile, ISettingsService settingsService, IDialogService dialogService, bool isNew)
|
|
{
|
|
SettingsService = settingsService;
|
|
DialogService = dialogService;
|
|
IsNew = isNew;
|
|
|
|
KeyBindings = new KeyBindingsViewModel(shellProfile.Id.ToString(), dialogService, string.Empty, false);
|
|
|
|
Initialize(shellProfile);
|
|
|
|
DeleteCommand = new AsyncCommand(Delete, CanDelete);
|
|
EditCommand = new RelayCommand(Edit);
|
|
CancelEditCommand = new AsyncCommand(CancelEdit);
|
|
SaveChangesCommand = new AsyncCommand(SaveChangesAsync);
|
|
AddKeyboardShortcutCommand = new AsyncCommand(AddKeyboardShortcut);
|
|
}
|
|
|
|
#endregion Constructor
|
|
|
|
#region Methods
|
|
|
|
// Loads view model properties from the input shellProfile
|
|
protected void Initialize(ShellProfile shellProfile)
|
|
{
|
|
Id = shellProfile.Id;
|
|
Name = shellProfile.Name;
|
|
|
|
KeyBindings.Clear();
|
|
foreach (var keyBinding in shellProfile.KeyBindings.Select(x => new KeyBinding(x)).ToList())
|
|
{
|
|
KeyBindings.Add(keyBinding);
|
|
}
|
|
}
|
|
|
|
protected virtual bool HasChanges()
|
|
{
|
|
return ProfileVm.HasChanges() || !_nameBeforeEdit.NullableEqualTo(_name) ||
|
|
!(_bindingsBeforeEdit?.SequenceEqual(KeyBindings.KeyBindings.Select(x => x.Model).ToList()) ??
|
|
false);
|
|
}
|
|
|
|
private async Task Delete()
|
|
{
|
|
var result = await DialogService.ShowMessageDialogAsnyc(I18N.Translate("PleaseConfirm"),
|
|
I18N.Translate("ConfirmDeleteProfile"), DialogButton.OK, DialogButton.Cancel).ConfigureAwait(true);
|
|
|
|
if (result == DialogButton.OK)
|
|
{
|
|
Deleted?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
}
|
|
|
|
protected abstract bool CanDelete();
|
|
|
|
private void Edit()
|
|
{
|
|
if (InEditMode)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_bindingsBeforeEdit = KeyBindings.KeyBindings.Select(x => x.Model).ToList();
|
|
_nameBeforeEdit = _name;
|
|
|
|
KeyBindings.Editable = true;
|
|
InEditMode = true;
|
|
}
|
|
|
|
private async Task CancelEdit()
|
|
{
|
|
if (IsNew)
|
|
{
|
|
await Delete();
|
|
}
|
|
else
|
|
{
|
|
if (HasChanges())
|
|
{
|
|
var result = await DialogService.ShowMessageDialogAsnyc(I18N.Translate("PleaseConfirm"),
|
|
I18N.Translate("ConfirmDiscardChanges"), DialogButton.OK, DialogButton.Cancel)
|
|
.ConfigureAwait(true);
|
|
|
|
if (result == DialogButton.OK)
|
|
{
|
|
// Cancelled, so rollback
|
|
ProfileVm.RejectChanges();
|
|
|
|
KeyBindings.Editable = false;
|
|
InEditMode = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
KeyBindings.Editable = false;
|
|
InEditMode = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual async Task SaveChangesAsync()
|
|
{
|
|
var error = await ProfileVm.AcceptChangesAsync();
|
|
|
|
if (!string.IsNullOrEmpty(error))
|
|
{
|
|
await DialogService.ShowMessageDialogAsnyc(I18N.Translate("InvalidInput"), error, DialogButton.OK);
|
|
|
|
return;
|
|
}
|
|
|
|
var profile = ProfileVm.Model;
|
|
|
|
profile.Id = Id;
|
|
profile.Name = _name;
|
|
profile.KeyBindings = KeyBindings.KeyBindings.Select(x => x.Model).ToList();
|
|
|
|
if (profile is SshProfile sshProfile)
|
|
{
|
|
SettingsService.SaveSshProfile(sshProfile, IsNew);
|
|
}
|
|
else
|
|
{
|
|
SettingsService.SaveShellProfile(profile, IsNew);
|
|
}
|
|
|
|
KeyBindings.Editable = false;
|
|
InEditMode = false;
|
|
IsNew = false;
|
|
}
|
|
|
|
public Task AddKeyboardShortcut()
|
|
{
|
|
return KeyBindings.ShowAddKeyBindingDialog();
|
|
}
|
|
|
|
#endregion Methods
|
|
}
|
|
} |