Files
FluentTerminal/FluentTerminal.App/Dialogs/CustomCommandDialog.xaml.cs
T

254 lines
8.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage.Pickers;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using FluentTerminal.App.Services;
using FluentTerminal.App.Services.Dialogs;
using FluentTerminal.App.Services.Utilities;
using FluentTerminal.App.Utilities;
using FluentTerminal.App.ViewModels.Profiles;
using FluentTerminal.Models;
using System.Linq;
using Windows.Foundation;
using Windows.System;
using Windows.UI.Xaml.Input;
using FluentTerminal.App.ViewModels;
using FluentTerminal.App.ViewModels.Infrastructure;
// The Content Dialog item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace FluentTerminal.App.Dialogs
{
// ReSharper disable once RedundantExtendsListEntry
public sealed partial class CustomCommandDialog : ContentDialog, ICustomCommandDialog
{
private readonly ISettingsService _settingsService;
private readonly IApplicationView _applicationView;
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
private readonly ICommandHistoryService _historyService;
private IAsyncOperation<ContentDialogResult> _showDialogOperation;
private ContentDialogResult _dialogResult = ContentDialogResult.None;
private ExecutedCommand _lastChosenCommand;
// TODO: The following field is for hacking strange behavior that deletes command text after Tab selection. Consider finding a better fix.
private string _tabSelectedCommand;
public CommandProfileProviderViewModel ViewModel { get; private set; }
public IAsyncCommand SaveLinkCommand { get; }
public CustomCommandDialog(ISettingsService settingsService, IApplicationView applicationView,
ITrayProcessCommunicationService trayProcessCommunicationService, ICommandHistoryService historyService)
{
_settingsService = settingsService;
_applicationView = applicationView;
_trayProcessCommunicationService = trayProcessCommunicationService;
_historyService = historyService;
InitializeComponent();
SaveLinkCommand = new AsyncCommand(SaveLink);
PrimaryButtonText = I18N.Translate("OK");
SecondaryButtonText = I18N.Translate("Cancel");
var currentTheme = settingsService.GetCurrentTheme();
RequestedTheme = ContrastHelper.GetIdealThemeForBackgroundColor(currentTheme.Colors.Background);
}
private void SetupFocus()
{
CommandTextBox.Focus(FocusState.Programmatic);
}
private async void OnPrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
var deferral = args.GetDeferral();
var error = await ViewModel.AcceptChangesAsync();
if (string.IsNullOrEmpty(error))
{
_dialogResult = ContentDialogResult.Primary;
}
else
{
args.Cancel = true;
await new MessageDialog(error, I18N.Translate("InvalidInput")).ShowAsync();
SetupFocus();
}
deferral.Complete();
}
private void OnSecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
_dialogResult = ContentDialogResult.Secondary;
}
private async Task SaveLink()
{
var link = await ViewModel.GetUrlAsync();
if (!link.Item1)
{
await new MessageDialog(link.Item2, I18N.Translate("InvalidInput")).ShowAsync();
return;
}
var content = ProfileProviderViewModelBase.GetShortcutFileContent(link.Item2);
var savePicker = new FileSavePicker { SuggestedStartLocation = PickerLocationId.Desktop };
savePicker.FileTypeChoices.Add("Shortcut", new List<string> { ".url" });
var file = await savePicker.PickSaveFileAsync();
if (file == null)
{
return;
}
try
{
await _trayProcessCommunicationService.SaveTextFileAsync(file.Path, content);
}
catch (Exception ex)
{
await new MessageDialog(ex.Message, I18N.Translate("Error")).ShowAsync();
}
}
private void CommandTextBox_OnTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
{
ViewModel.SetFilter(sender.Text.Trim());
}
// TODO: Else branch added for Tab-selection hack mentioned above.
else if (!string.IsNullOrEmpty(_tabSelectedCommand))
{
ViewModel.Command = _tabSelectedCommand;
_tabSelectedCommand = null;
}
}
private void CommandTextBox_OnSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
_lastChosenCommand = (args.SelectedItem as CommandItemViewModel)?.ExecutedCommand;
}
private void CommandTextBox_OnQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
_lastChosenCommand = null;
if (args.ChosenSuggestion is CommandItemViewModel commandItem)
{
var executedCommand = ViewModel.Commands.FirstOrDefault(c =>
c.ExecutedCommand.Value.Equals(commandItem.ExecutedCommand.Value,
StringComparison.OrdinalIgnoreCase))?.ExecutedCommand;
if (executedCommand != null)
{
ViewModel.SetProfile(executedCommand.ShellProfile.Clone());
}
}
}
private void CommandTextBox_OnPreviewKeyUp(object sender, KeyRoutedEventArgs e)
{
var command = _lastChosenCommand;
if (e.Key == VirtualKey.Delete && !ViewModel.IsProfileCommand(command))
{
ViewModel.RemoveCommand(command);
e.Handled = true;
}
else
{
e.Handled = false;
}
}
private async void CommandTextBox_OnKeyUp(object sender, KeyRoutedEventArgs e)
{
switch (e.Key)
{
case VirtualKey.Down:
case VirtualKey.Up:
if (!CommandTextBox.IsSuggestionListOpen)
{
CommandTextBox.IsSuggestionListOpen = true;
}
return;
case VirtualKey.Enter:
if (string.IsNullOrWhiteSpace(CommandTextBox.Text) && !CommandTextBox.IsSuggestionListOpen)
{
CommandTextBox.IsSuggestionListOpen = true;
}
else
{
var error = await ViewModel.AcceptChangesAsync();
if (string.IsNullOrEmpty(error))
{
_dialogResult = ContentDialogResult.Primary;
_showDialogOperation.Cancel();
}
else
{
await new MessageDialog(error, I18N.Translate("InvalidInput")).ShowAsync();
}
}
return;
}
}
private void CommandTextBox_OnKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Tab)
{
if (_lastChosenCommand != null)
{
ViewModel.Command = _lastChosenCommand.Value;
_tabSelectedCommand = _lastChosenCommand.Value;
}
e.Handled = false;
}
else
{
_tabSelectedCommand = null;
}
}
public async Task<ShellProfile> GetCustomCommandAsync(ShellProfile input = null)
{
ViewModel = new CommandProfileProviderViewModel(_settingsService, _applicationView,
_trayProcessCommunicationService, _historyService, input);
SetupFocus();
_showDialogOperation = ShowAsync();
var result = await _showDialogOperation.AsTask().ContinueWith(t => _dialogResult);
return result != ContentDialogResult.Primary ? null : ViewModel.Model;
}
}
}