diff --git a/FluentTerminal.App/FluentTerminal.App.csproj b/FluentTerminal.App/FluentTerminal.App.csproj index 137a219..7f0501a 100644 --- a/FluentTerminal.App/FluentTerminal.App.csproj +++ b/FluentTerminal.App/FluentTerminal.App.csproj @@ -127,9 +127,10 @@ - + + @@ -159,8 +160,8 @@ KeyBindingSettings.xaml - - ShellSettings.xaml + + ShellProfileSettings.xaml TerminalColorPicker.xaml @@ -297,7 +298,7 @@ Designer MSBuild:Compile - + Designer MSBuild:Compile diff --git a/FluentTerminal.App/Services/IDefaultValueProvider.cs b/FluentTerminal.App/Services/IDefaultValueProvider.cs index cc64c70..8653057 100644 --- a/FluentTerminal.App/Services/IDefaultValueProvider.cs +++ b/FluentTerminal.App/Services/IDefaultValueProvider.cs @@ -6,7 +6,8 @@ namespace FluentTerminal.App.Services { public interface IDefaultValueProvider { - ShellConfiguration GetDefaultShellConfiguration(); + IEnumerable GetPreinstalledShellProfiles(); + Guid GetDefaultShellProfileId(); TerminalOptions GetDefaultTerminalOptions(); KeyBindings GetDefaultKeyBindings(); ApplicationSettings GetDefaultApplicationSettings(); diff --git a/FluentTerminal.App/Services/ISettingsService.cs b/FluentTerminal.App/Services/ISettingsService.cs index 43a7d23..f2f8d25 100644 --- a/FluentTerminal.App/Services/ISettingsService.cs +++ b/FluentTerminal.App/Services/ISettingsService.cs @@ -11,8 +11,13 @@ namespace FluentTerminal.App.Services event EventHandler ApplicationSettingsChanged; event EventHandler KeyBindingsChanged; - ShellConfiguration GetShellConfiguration(); - void SaveShellConfiguration(ShellConfiguration shellConfiguration); + Guid GetDefaultShellProfileId(); + ShellProfile GetDefaultShellProfile(); + void SaveDefaultShellProfileId(Guid id); + + IEnumerable GetShellProfiles(); + void SaveShellProfile(ShellProfile shellProfile); + void DeleteShellProfile(Guid id); TerminalOptions GetTerminalOptions(); void SaveTerminalOptions(TerminalOptions terminalOptions); diff --git a/FluentTerminal.App/Services/ITrayProcessCommunicationService.cs b/FluentTerminal.App/Services/ITrayProcessCommunicationService.cs index 0781a1a..b67ac6d 100644 --- a/FluentTerminal.App/Services/ITrayProcessCommunicationService.cs +++ b/FluentTerminal.App/Services/ITrayProcessCommunicationService.cs @@ -8,7 +8,7 @@ namespace FluentTerminal.App.Services public interface ITrayProcessCommunicationService { Task Initialize(AppServiceConnection appServiceConnection); - Task CreateTerminal(TerminalSize size, ShellConfiguration shellConfiguration); + Task CreateTerminal(TerminalSize size, ShellProfile shellProfile); Task ResizeTerminal(int id, TerminalSize size); Task UpdateToggleWindowKeyBindings(); } diff --git a/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs b/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs index 71173c2..37e81c6 100644 --- a/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs +++ b/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs @@ -124,15 +124,9 @@ namespace FluentTerminal.App.Services.Implementation }; } - public ShellConfiguration GetDefaultShellConfiguration() + public Guid GetDefaultShellProfileId() { - return new ShellConfiguration - { - Shell = ShellType.PowerShell, - CustomShellLocation = string.Empty, - WorkingDirectory = string.Empty, - Arguments = string.Empty - }; + return Guid.Parse("813f2298-210a-481a-bdbf-c17bc637a3e2"); } public TerminalOptions GetDefaultTerminalOptions() @@ -152,6 +146,31 @@ namespace FluentTerminal.App.Services.Implementation return Guid.Parse("281e4352-bb50-47b7-a691-2b13830df95e"); } + public IEnumerable GetPreinstalledShellProfiles() + { + return new[] + { + new ShellProfile + { + Id = GetDefaultShellProfileId(), + Name = "Powershell", + Arguments = string.Empty, + Location = @"C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe", + PreInstalled = true, + WorkingDirectory = string.Empty + }, + new ShellProfile + { + Id = Guid.Parse("ab942a61-7673-4755-9bd8-765aff91d9a3"), + Name = "CMD", + Arguments = string.Empty, + Location = @"C:\Windows\System32\cmd.exe", + PreInstalled = true, + WorkingDirectory = string.Empty + } + }; + } + public IEnumerable GetPreInstalledThemes() { var defaultXterm = new TerminalTheme diff --git a/FluentTerminal.App/Services/Implementation/SettingsService.cs b/FluentTerminal.App/Services/Implementation/SettingsService.cs index 27cdbf6..faaa51b 100644 --- a/FluentTerminal.App/Services/Implementation/SettingsService.cs +++ b/FluentTerminal.App/Services/Implementation/SettingsService.cs @@ -11,11 +11,14 @@ namespace FluentTerminal.App.Services.Implementation internal class SettingsService : ISettingsService { public const string ThemesContainerName = "Themes"; + public const string ShellProfilesContainerName = "ShellProfiles"; public const string CurrentThemeKey = "CurrentTheme"; + public const string DefaultShellProfileKey = "DefaultShellProfile"; private readonly IDefaultValueProvider _defaultValueProvider; private readonly ApplicationDataContainer _localSettings; private readonly ApplicationDataContainer _themes; + private readonly ApplicationDataContainer _shellProfiles; private readonly ApplicationDataContainer _roamingSettings; public event EventHandler CurrentThemeChanged; @@ -30,21 +33,17 @@ namespace FluentTerminal.App.Services.Implementation _roamingSettings = ApplicationData.Current.RoamingSettings; _themes = _roamingSettings.CreateContainer(ThemesContainerName, ApplicationDataCreateDisposition.Always); + _shellProfiles = _roamingSettings.CreateContainer(ShellProfilesContainerName, ApplicationDataCreateDisposition.Always); foreach (var theme in _defaultValueProvider.GetPreInstalledThemes()) { _themes.WriteValueAsJson(theme.Id.ToString(), theme); } - } - public ShellConfiguration GetShellConfiguration() - { - return _localSettings.ReadValueFromJson(nameof(ShellConfiguration), _defaultValueProvider.GetDefaultShellConfiguration()); - } - - public void SaveShellConfiguration(ShellConfiguration shellConfiguration) - { - _localSettings.WriteValueAsJson(nameof(ShellConfiguration), shellConfiguration); + foreach (var shellProfile in _defaultValueProvider.GetPreinstalledShellProfiles()) + { + _shellProfiles.WriteValueAsJson(shellProfile.Id.ToString(), shellProfile); + } } public TerminalTheme GetCurrentTheme() @@ -128,5 +127,40 @@ namespace FluentTerminal.App.Services.Implementation _roamingSettings.WriteValueAsJson(nameof(KeyBindings), keyBindings); KeyBindingsChanged?.Invoke(this, EventArgs.Empty); } + + public Guid GetDefaultShellProfileId() + { + if (_roamingSettings.Values.TryGetValue(DefaultShellProfileKey, out object value)) + { + return (Guid)value; + } + return _defaultValueProvider.GetDefaultShellProfileId(); + } + + public ShellProfile GetDefaultShellProfile() + { + var id = GetDefaultShellProfileId(); + return _shellProfiles.ReadValueFromJson(id.ToString(), default(ShellProfile)); + } + + public void SaveDefaultShellProfileId(Guid id) + { + _roamingSettings.Values[DefaultShellProfileKey] = id; + } + + public IEnumerable GetShellProfiles() + { + return _shellProfiles.Values.Select(x => JsonConvert.DeserializeObject((string)x.Value)).ToList(); + } + + public void SaveShellProfile(ShellProfile shellProfile) + { + _shellProfiles.WriteValueAsJson(shellProfile.Id.ToString(), shellProfile); + } + + public void DeleteShellProfile(Guid id) + { + _shellProfiles.Values.Remove(id.ToString()); + } } } \ No newline at end of file diff --git a/FluentTerminal.App/Services/Implementation/TrayProcessCommunicationService.cs b/FluentTerminal.App/Services/Implementation/TrayProcessCommunicationService.cs index 08aae1c..27b05b4 100644 --- a/FluentTerminal.App/Services/Implementation/TrayProcessCommunicationService.cs +++ b/FluentTerminal.App/Services/Implementation/TrayProcessCommunicationService.cs @@ -19,12 +19,12 @@ namespace FluentTerminal.App.Services.Implementation _settingsService = settingsService; } - public async Task CreateTerminal(TerminalSize size, ShellConfiguration shellConfiguration) + public async Task CreateTerminal(TerminalSize size, ShellProfile shellProfile) { var request = new CreateTerminalRequest { Size = size, - Configuration = shellConfiguration + Profile = shellProfile }; var message = new ValueSet diff --git a/FluentTerminal.App/ViewModels/Settings/ProfilesPageViewModel.cs b/FluentTerminal.App/ViewModels/Settings/ProfilesPageViewModel.cs new file mode 100644 index 0000000..c3ef907 --- /dev/null +++ b/FluentTerminal.App/ViewModels/Settings/ProfilesPageViewModel.cs @@ -0,0 +1,104 @@ +using FluentTerminal.App.Services; +using FluentTerminal.Models; +using GalaSoft.MvvmLight; +using GalaSoft.MvvmLight.Command; +using System; +using System.Collections.ObjectModel; +using System.Linq; + +namespace FluentTerminal.App.ViewModels.Settings +{ + public class ProfilesPageViewModel : ViewModelBase + { + private readonly IDefaultValueProvider _defaultValueProvider; + private readonly IDialogService _dialogService; + private readonly ISettingsService _settingsService; + private ShellProfileViewModel _selectedShellProfile; + + public ProfilesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider) + { + _settingsService = settingsService; + _dialogService = dialogService; + _defaultValueProvider = defaultValueProvider; + + CreateShellProfileCommand = new RelayCommand(CreateShellProfile); + + var defaultShellProfileId = _settingsService.GetDefaultShellProfileId(); + foreach (var shellProfile in _settingsService.GetShellProfiles()) + { + var viewModel = new ShellProfileViewModel(shellProfile, settingsService, dialogService); + viewModel.Deleted += OnShellProfileDeleted; + viewModel.SetAsDefault += OnShellProfileSetAsDefault; + + if (shellProfile.Id == defaultShellProfileId) + { + viewModel.IsDefault = true; + } + ShellProfiles.Add(viewModel); + } + + SelectedShellProfile = ShellProfiles.First(p => p.IsDefault); + } + + private void OnShellProfileSetAsDefault(object sender, EventArgs e) + { + if (sender is ShellProfileViewModel defaultShellProfile) + { + _settingsService.SaveDefaultShellProfileId(defaultShellProfile.Id); + + foreach (var shellProfile in ShellProfiles) + { + shellProfile.IsDefault = shellProfile.Id == defaultShellProfile.Id; + } + } + } + + private void OnShellProfileDeleted(object sender, EventArgs e) + { + if (sender is ShellProfileViewModel shellProfile) + { + if (SelectedShellProfile == shellProfile) + { + SelectedShellProfile = ShellProfiles.First(); + } + ShellProfiles.Remove(shellProfile); + + if (shellProfile.IsDefault) + { + ShellProfiles.First().IsDefault = true; + _settingsService.SaveDefaultShellProfileId(ShellProfiles.First().Id); + } + _settingsService.DeleteShellProfile(shellProfile.Id); + } + } + + public RelayCommand CreateShellProfileCommand { get; } + + private void CreateShellProfile() + { + var shellProfile = new ShellProfile + { + Id = Guid.NewGuid(), + PreInstalled = false, + Name = "New profile" + }; + + _settingsService.SaveShellProfile(shellProfile); + + var viewModel = new ShellProfileViewModel(shellProfile, _settingsService, _dialogService); + viewModel.EditCommand.Execute(null); + viewModel.SetAsDefault += OnShellProfileSetAsDefault; + viewModel.Deleted += OnShellProfileDeleted; + ShellProfiles.Add(viewModel); + SelectedShellProfile = viewModel; + } + + public ShellProfileViewModel SelectedShellProfile + { + get => _selectedShellProfile; + set => Set(ref _selectedShellProfile, value); + } + + public ObservableCollection ShellProfiles { get; } = new ObservableCollection(); + } +} \ No newline at end of file diff --git a/FluentTerminal.App/ViewModels/Settings/ShellPageViewModel.cs b/FluentTerminal.App/ViewModels/Settings/ShellPageViewModel.cs deleted file mode 100644 index 3af4fc2..0000000 --- a/FluentTerminal.App/ViewModels/Settings/ShellPageViewModel.cs +++ /dev/null @@ -1,160 +0,0 @@ -using FluentTerminal.App.Services; -using FluentTerminal.Models; -using FluentTerminal.Models.Enums; -using GalaSoft.MvvmLight; -using GalaSoft.MvvmLight.Command; -using System; -using System.Threading.Tasks; -using Windows.Storage.Pickers; - -namespace FluentTerminal.App.ViewModels.Settings -{ - public class ShellPageViewModel : ViewModelBase - { - private readonly IDefaultValueProvider _defaultValueProvider; - private readonly IDialogService _dialogService; - private readonly ISettingsService _settingsService; - private readonly ShellConfiguration _shellConfiguration; - private bool _editingShellType; - - public ShellPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider) - { - _settingsService = settingsService; - _dialogService = dialogService; - _defaultValueProvider = defaultValueProvider; - - RestoreDefaultsCommand = new RelayCommand(async () => await RestoreDefaults().ConfigureAwait(false)); - BrowseForCustomShellCommand = new RelayCommand(async () => await BrowseForCustomShell().ConfigureAwait(false)); - BrowseForWorkingDirectoryCommand = new RelayCommand(async () => await BrowseForWorkingDirectory().ConfigureAwait(false)); - - _shellConfiguration = _settingsService.GetShellConfiguration(); - } - - public string Arguments - { - get => _shellConfiguration.Arguments; - set - { - if (_shellConfiguration.Arguments != value) - { - _shellConfiguration.Arguments = value; - _settingsService.SaveShellConfiguration(_shellConfiguration); - RaisePropertyChanged(); - } - } - } - - public RelayCommand BrowseForCustomShellCommand { get; } - - public RelayCommand BrowseForWorkingDirectoryCommand { get; } - - public bool CMDIsSelected - { - get => ShellType == ShellType.CMD; - set => ShellType = ShellType.CMD; - } - - public bool CustomShellIsSelected - { - get => ShellType == ShellType.Custom; - set => ShellType = ShellType.Custom; - } - - public string CustomShellLocation - { - get => _shellConfiguration.CustomShellLocation; - set - { - if (_shellConfiguration.CustomShellLocation != value) - { - _shellConfiguration.CustomShellLocation = value; - _settingsService.SaveShellConfiguration(_shellConfiguration); - RaisePropertyChanged(); - } - } - } - - public bool PoweShellIsSelected - { - get => ShellType == ShellType.PowerShell; - set => ShellType = ShellType.PowerShell; - } - - public RelayCommand RestoreDefaultsCommand { get; } - - public ShellType ShellType - { - get => _shellConfiguration.Shell; - set - { - if (_shellConfiguration.Shell != value && !_editingShellType) - { - _editingShellType = true; - _shellConfiguration.Shell = value; - _settingsService.SaveShellConfiguration(_shellConfiguration); - RaisePropertyChanged(); - RaisePropertyChanged(nameof(CustomShellIsSelected)); - RaisePropertyChanged(nameof(PoweShellIsSelected)); - RaisePropertyChanged(nameof(CMDIsSelected)); - _editingShellType = false; - } - } - } - - public string WorkingDirectory - { - get => _shellConfiguration.WorkingDirectory; - set - { - if (_shellConfiguration.WorkingDirectory != value) - { - _shellConfiguration.WorkingDirectory = value; - _settingsService.SaveShellConfiguration(_shellConfiguration); - RaisePropertyChanged(); - } - } - } - - private async Task BrowseForCustomShell() - { - var picker = new FileOpenPicker - { - SuggestedStartLocation = PickerLocationId.ComputerFolder - }; - picker.FileTypeFilter.Add(".exe"); - - var file = await picker.PickSingleFileAsync(); - if (file != null) - { - CustomShellLocation = file.Path; - } - } - - private async Task BrowseForWorkingDirectory() - { - var picker = new FolderPicker(); - picker.FileTypeFilter.Add(".whatever"); // else a ComException is thrown - picker.SuggestedStartLocation = PickerLocationId.ComputerFolder; - - var folder = await picker.PickSingleFolderAsync(); - if (folder != null) - { - WorkingDirectory = folder.Path; - } - } - - private async Task RestoreDefaults() - { - var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to restore the default shell configuration?", DialogButton.OK, DialogButton.Cancel).ConfigureAwait(false); - - if (result == DialogButton.OK) - { - var defaults = _defaultValueProvider.GetDefaultShellConfiguration(); - ShellType = defaults.Shell; - CustomShellLocation = defaults.CustomShellLocation; - WorkingDirectory = defaults.WorkingDirectory; - Arguments = defaults.Arguments; - } - } - } -} \ No newline at end of file diff --git a/FluentTerminal.App/ViewModels/Settings/ThemesPageViewModel.cs b/FluentTerminal.App/ViewModels/Settings/ThemesPageViewModel.cs index 9692802..5aad548 100644 --- a/FluentTerminal.App/ViewModels/Settings/ThemesPageViewModel.cs +++ b/FluentTerminal.App/ViewModels/Settings/ThemesPageViewModel.cs @@ -40,7 +40,7 @@ namespace FluentTerminal.App.ViewModels.Settings SelectedTheme = Themes.First(t => t.IsActive); } - public RelayCommand CreateThemeCommand { get; set; } + public RelayCommand CreateThemeCommand { get; } public ThemeViewModel SelectedTheme { diff --git a/FluentTerminal.App/ViewModels/SettingsViewModel.cs b/FluentTerminal.App/ViewModels/SettingsViewModel.cs index ff7a732..67cca9d 100644 --- a/FluentTerminal.App/ViewModels/SettingsViewModel.cs +++ b/FluentTerminal.App/ViewModels/SettingsViewModel.cs @@ -11,7 +11,7 @@ namespace FluentTerminal.App.ViewModels { KeyBindings = new KeyBindingsPageViewModel(settingsService, dialogService, defaultValueProvider, trayProcessCommunicationService); General = new GeneralPageViewModel(settingsService, dialogService, defaultValueProvider); - Shell = new ShellPageViewModel(settingsService, dialogService, defaultValueProvider); + Shell = new ProfilesPageViewModel(settingsService, dialogService, defaultValueProvider); Terminal = new TerminalPageViewModel(settingsService, dialogService, defaultValueProvider); Themes = new ThemesPageViewModel(settingsService, dialogService, defaultValueProvider); } @@ -20,7 +20,7 @@ namespace FluentTerminal.App.ViewModels public GeneralPageViewModel General { get; } public KeyBindingsPageViewModel KeyBindings { get; } - public ShellPageViewModel Shell { get; } + public ProfilesPageViewModel Shell { get; } public TerminalPageViewModel Terminal { get; } public ThemesPageViewModel Themes { get; } diff --git a/FluentTerminal.App/ViewModels/ShellProfileViewModel.cs b/FluentTerminal.App/ViewModels/ShellProfileViewModel.cs new file mode 100644 index 0000000..bd0897f --- /dev/null +++ b/FluentTerminal.App/ViewModels/ShellProfileViewModel.cs @@ -0,0 +1,186 @@ +using FluentTerminal.App.Services; +using FluentTerminal.Models; +using GalaSoft.MvvmLight; +using GalaSoft.MvvmLight.Command; +using System; +using System.Threading.Tasks; +using Windows.Storage.Pickers; + +namespace FluentTerminal.App.ViewModels +{ + public class ShellProfileViewModel : ViewModelBase + { + private readonly ShellProfile _shellProfile; + private string _name; + private string _arguments; + private string _location; + private string _workingDirectory; + private string _fallbackName; + private string _fallbackArguments; + private string _fallbackLocation; + private string _fallbackWorkingDirectory; + private bool _isDefault; + private bool _inEditMode; + private readonly ISettingsService _settingsService; + private readonly IDialogService _dialogService; + + public ShellProfileViewModel(ShellProfile shellProfile, ISettingsService settingsService, IDialogService dialogService) + { + _shellProfile = shellProfile; + _settingsService = settingsService; + _dialogService = dialogService; + + Id = shellProfile.Id; + Name = shellProfile.Name; + Arguments = shellProfile.Arguments; + Location = shellProfile.Location; + WorkingDirectory = shellProfile.WorkingDirectory; + + SetDefaultCommand = new RelayCommand(SetDefault); + DeleteCommand = new RelayCommand(async () => await Delete().ConfigureAwait(false), CanDelete); + EditCommand = new RelayCommand(Edit, CanEdit); + CancelEditCommand = new RelayCommand(async () => await CancelEdit().ConfigureAwait(false)); + SaveChangesCommand = new RelayCommand(SaveChanges); + BrowseForCustomShellCommand = new RelayCommand(async () => await BrowseForCustomShell().ConfigureAwait(false)); + BrowseForWorkingDirectoryCommand = new RelayCommand(async () => await BrowseForWorkingDirectory().ConfigureAwait(false)); + } + + public event EventHandler Deleted; + public event EventHandler SetAsDefault; + + public RelayCommand DeleteCommand { get; } + public RelayCommand EditCommand { get; } + public RelayCommand SaveChangesCommand { get; } + public RelayCommand CancelEditCommand { get; } + public RelayCommand SetDefaultCommand { get; } + public RelayCommand BrowseForCustomShellCommand { get; } + public RelayCommand BrowseForWorkingDirectoryCommand { get; } + + public Guid Id { get; } + + public string Name + { + get => _name; + set => Set(ref _name, value); + } + + public string Arguments + { + get => _arguments; + set => Set(ref _arguments, value); + } + + public string Location + { + get => _location; + set => Set(ref _location, value); + } + + public string WorkingDirectory + { + get => _workingDirectory; + set => Set(ref _workingDirectory, value); + } + + public bool IsDefault + { + get => _isDefault; + set => Set(ref _isDefault, value); + } + + public bool InEditMode + { + get => _inEditMode; + set => Set(ref _inEditMode, value); + } + + public void SaveChanges() + { + _shellProfile.Arguments = Arguments; + _shellProfile.Location = Location; + _shellProfile.Name = Name; + _shellProfile.WorkingDirectory = WorkingDirectory; + + _settingsService.SaveShellProfile(_shellProfile); + + InEditMode = false; + } + + private async Task CancelEdit() + { + var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to discard all changes?", DialogButton.OK, DialogButton.Cancel).ConfigureAwait(true); + + if (result == DialogButton.OK) + { + Arguments = _fallbackArguments; + Location = _fallbackLocation; + Name = _fallbackName; + WorkingDirectory = _fallbackWorkingDirectory; + + InEditMode = false; + } + } + + private void Edit() + { + _fallbackArguments = Arguments; + _fallbackLocation = Location; + _fallbackName = Name; + _fallbackWorkingDirectory = WorkingDirectory; + InEditMode = true; + } + + private bool CanDelete() + { + return !_shellProfile.PreInstalled; + } + + private bool CanEdit() + { + return !_shellProfile.PreInstalled; + } + + private async Task Delete() + { + var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to delete this theme?", DialogButton.OK, DialogButton.Cancel).ConfigureAwait(true); + + if (result == DialogButton.OK) + { + Deleted?.Invoke(this, EventArgs.Empty); + } + } + + private void SetDefault() + { + SetAsDefault?.Invoke(this, EventArgs.Empty); + } + + private async Task BrowseForCustomShell() + { + var picker = new FileOpenPicker + { + SuggestedStartLocation = PickerLocationId.ComputerFolder + }; + picker.FileTypeFilter.Add(".exe"); + + var file = await picker.PickSingleFileAsync(); + if (file != null) + { + Location = file.Path; + } + } + + private async Task BrowseForWorkingDirectory() + { + var picker = new FolderPicker(); + picker.FileTypeFilter.Add(".whatever"); // else a ComException is thrown + picker.SuggestedStartLocation = PickerLocationId.ComputerFolder; + + var folder = await picker.PickSingleFolderAsync(); + if (folder != null) + { + WorkingDirectory = folder.Path; + } + } + } +} diff --git a/FluentTerminal.App/ViewModels/TerminalViewModel.cs b/FluentTerminal.App/ViewModels/TerminalViewModel.cs index 67f473e..fdd5afa 100644 --- a/FluentTerminal.App/ViewModels/TerminalViewModel.cs +++ b/FluentTerminal.App/ViewModels/TerminalViewModel.cs @@ -133,7 +133,7 @@ namespace FluentTerminal.App.ViewModels var keyBindings = _settingsService.GetKeyBindings(); var size = await _terminalView.CreateTerminal(options, theme.Colors, GetKeyBindingsCollection(keyBindings)).ConfigureAwait(true); - var configuration = _settingsService.GetShellConfiguration(); + var configuration = _settingsService.GetDefaultShellProfile(); if (!string.IsNullOrWhiteSpace(_startupDirectory)) { diff --git a/FluentTerminal.App/Views/SettingsPage.xaml b/FluentTerminal.App/Views/SettingsPage.xaml index 8f3e4ad..d08c6e6 100644 --- a/FluentTerminal.App/Views/SettingsPage.xaml +++ b/FluentTerminal.App/Views/SettingsPage.xaml @@ -40,7 +40,7 @@ ToolTipService.ToolTip="Terminal" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FluentTerminal.Models/Enums/ShellType.cs b/FluentTerminal.Models/Enums/ShellType.cs deleted file mode 100644 index 5511e36..0000000 --- a/FluentTerminal.Models/Enums/ShellType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace FluentTerminal.Models.Enums -{ - public enum ShellType - { - CMD, - PowerShell, - Custom - } -} diff --git a/FluentTerminal.Models/Requests/CreateTerminalRequest.cs b/FluentTerminal.Models/Requests/CreateTerminalRequest.cs index 09e925a..0db0eb6 100644 --- a/FluentTerminal.Models/Requests/CreateTerminalRequest.cs +++ b/FluentTerminal.Models/Requests/CreateTerminalRequest.cs @@ -3,6 +3,6 @@ public class CreateTerminalRequest { public TerminalSize Size { get; set; } - public ShellConfiguration Configuration { get; set; } + public ShellProfile Profile { get; set; } } } diff --git a/FluentTerminal.Models/ShellConfiguration.cs b/FluentTerminal.Models/ShellConfiguration.cs deleted file mode 100644 index ed79503..0000000 --- a/FluentTerminal.Models/ShellConfiguration.cs +++ /dev/null @@ -1,12 +0,0 @@ -using FluentTerminal.Models.Enums; - -namespace FluentTerminal.Models -{ - public class ShellConfiguration - { - public string Arguments { get; set; } - public ShellType Shell { get; set; } - public string CustomShellLocation { get; set; } - public string WorkingDirectory { get; set; } - } -} diff --git a/FluentTerminal.Models/ShellProfile.cs b/FluentTerminal.Models/ShellProfile.cs new file mode 100644 index 0000000..43c902a --- /dev/null +++ b/FluentTerminal.Models/ShellProfile.cs @@ -0,0 +1,14 @@ +using System; + +namespace FluentTerminal.Models +{ + public class ShellProfile + { + public Guid Id { get; set; } + public bool PreInstalled { get; set; } + public string Name { get; set; } + public string Arguments { get; set; } + public string Location { get; set; } + public string WorkingDirectory { get; set; } + } +} diff --git a/FluentTerminal.SystemTray/Services/TerminalSession.cs b/FluentTerminal.SystemTray/Services/TerminalSession.cs index ff66485..e6a9131 100644 --- a/FluentTerminal.SystemTray/Services/TerminalSession.cs +++ b/FluentTerminal.SystemTray/Services/TerminalSession.cs @@ -1,6 +1,5 @@ using Fleck; using FluentTerminal.Models; -using FluentTerminal.Models.Enums; using FluentTerminal.Models.Requests; using System; using System.IO; @@ -38,9 +37,9 @@ namespace FluentTerminal.SystemTray.Services throw new Exception(winpty_error_msg(errorHandle).ToString()); } - string exe = GetShellLocation(request.Configuration); - string args = $"\"{exe}\" {request.Configuration.Arguments}"; - string cwd = GetWorkingDirectory(request.Configuration); + string exe = request.Profile.Location; + string args = $"\"{exe}\" {request.Profile.Arguments}"; + string cwd = GetWorkingDirectory(request.Profile); spawnConfigHandle = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, exe, args, cwd, null, out errorHandle); if (errorHandle != IntPtr.Zero) { @@ -103,22 +102,7 @@ namespace FluentTerminal.SystemTray.Services Dispose(false); } - private string GetShellLocation(ShellConfiguration configuration) - { - switch (configuration.Shell) - { - case ShellType.CMD: - return @"C:\Windows\System32\cmd.exe"; - case ShellType.PowerShell: - return @"C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe"; - case ShellType.Custom: - return configuration.CustomShellLocation; - default: - return null; - } - } - - private string GetWorkingDirectory(ShellConfiguration configuration) + private string GetWorkingDirectory(ShellProfile configuration) { if (string.IsNullOrWhiteSpace(configuration.WorkingDirectory) || !Directory.Exists(configuration.WorkingDirectory)) { diff --git a/FluentTerminal.sln b/FluentTerminal.sln index 24c7ca1..440e384 100644 --- a/FluentTerminal.sln +++ b/FluentTerminal.sln @@ -103,20 +103,16 @@ Global {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|ARM.Deploy.0 = Debug|ARM {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x64.ActiveCfg = Debug|x64 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x64.Build.0 = Debug|x64 - {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x64.Deploy.0 = Debug|x64 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x86.ActiveCfg = Debug|x86 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x86.Build.0 = Debug|x86 - {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x86.Deploy.0 = Debug|x86 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|Any CPU.ActiveCfg = Release|x86 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|ARM.ActiveCfg = Release|ARM {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|ARM.Build.0 = Release|ARM {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|ARM.Deploy.0 = Release|ARM {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x64.ActiveCfg = Release|x64 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x64.Build.0 = Release|x64 - {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x64.Deploy.0 = Release|x64 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x86.ActiveCfg = Release|x86 {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x86.Build.0 = Release|x86 - {812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE