Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add a setting to change the default IDE #16730

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
64 changes: 64 additions & 0 deletions src/Files.App/Actions/Open/OpenInIDEAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

namespace Files.App.Actions
{
internal sealed partial class OpenInIDEAction : ObservableObject, IAction
{
private readonly IDevToolsSettingsService _devToolsSettingsService;

private readonly IContentPageContext _context;

public string Label
=> string.Format(
"OpenInIDE".GetLocalizedResource(),
_devToolsSettingsService.IDEFriendlyName);

public string Description
=> string.Format(
"OpenInIDEDescription".GetLocalizedResource(),
_devToolsSettingsService.IDEFriendlyName);

public bool IsExecutable =>
_context.Folder is not null &&
!string.IsNullOrWhiteSpace(_devToolsSettingsService.IDEPath);

public OpenInIDEAction()
{
_devToolsSettingsService = Ioc.Default.GetRequiredService<IDevToolsSettingsService>();
_context = Ioc.Default.GetRequiredService<IContentPageContext>();
_context.PropertyChanged += Context_PropertyChanged;
_devToolsSettingsService.PropertyChanged += DevSettings_PropertyChanged;
}

public async Task ExecuteAsync(object? parameter = null)
{
var res = await Win32Helper.RunPowershellCommandAsync(
$"& \'{_devToolsSettingsService.IDEPath}\' \'{_context.ShellPage?.ShellViewModel.WorkingDirectory}\'",
PowerShellExecutionOptions.Hidden
);

if (!res)
await DynamicDialogFactory.ShowFor_IDEErrorDialog(_devToolsSettingsService.IDEFriendlyName);
}

private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(IContentPageContext.Folder))
OnPropertyChanged(nameof(IsExecutable));
}

private void DevSettings_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(IDevToolsSettingsService.IDEPath))
{
OnPropertyChanged(nameof(IsExecutable));
}
else if (e.PropertyName == nameof(IDevToolsSettingsService.IDEFriendlyName))
{
OnPropertyChanged(nameof(Label));
OnPropertyChanged(nameof(Description));
}
}
}
}
44 changes: 0 additions & 44 deletions src/Files.App/Actions/Open/OpenInVSCodeAction.cs

This file was deleted.

61 changes: 61 additions & 0 deletions src/Files.App/Actions/Open/OpenRepoInIDEAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

namespace Files.App.Actions
{
internal sealed partial class OpenRepoInIDEAction : ObservableObject, IAction
{
private readonly IDevToolsSettingsService _devToolsSettingsService;

private readonly IContentPageContext _context;

public string Label
=> string.Format("OpenRepoInIDE".GetLocalizedResource(), _devToolsSettingsService.IDEFriendlyName);

public string Description
=> string.Format("OpenRepoInIDEDescription".GetLocalizedResource(), _devToolsSettingsService.IDEFriendlyName);

public bool IsExecutable =>
_context.Folder is not null &&
_context.ShellPage!.InstanceViewModel.IsGitRepository &&
!string.IsNullOrWhiteSpace(_devToolsSettingsService.IDEPath);

public OpenRepoInIDEAction()
{
_context = Ioc.Default.GetRequiredService<IContentPageContext>();
_devToolsSettingsService = Ioc.Default.GetRequiredService<IDevToolsSettingsService>();
_context.PropertyChanged += Context_PropertyChanged;
_devToolsSettingsService.PropertyChanged += DevSettings_PropertyChanged;
}

public async Task ExecuteAsync(object? parameter = null)
{
var res = await Win32Helper.RunPowershellCommandAsync(
$"& \'{_devToolsSettingsService.IDEPath}\' \'{_context.ShellPage!.InstanceViewModel.GitRepositoryPath}\'",
PowerShellExecutionOptions.Hidden
);

if (!res)
await DynamicDialogFactory.ShowFor_IDEErrorDialog(_devToolsSettingsService.IDEFriendlyName);
}

private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(IContentPageContext.Folder))
OnPropertyChanged(nameof(IsExecutable));
}

private void DevSettings_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(IDevToolsSettingsService.IDEPath))
{
OnPropertyChanged(nameof(IsExecutable));
}
else if (e.PropertyName == nameof(IDevToolsSettingsService.IDEFriendlyName))
{
OnPropertyChanged(nameof(Label));
OnPropertyChanged(nameof(Description));
}
}
}
}
45 changes: 0 additions & 45 deletions src/Files.App/Actions/Open/OpenRepoInVSCodeAction.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/Files.App/Data/Commands/Manager/CommandCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ public enum CommandCodes
RotateRight,

// Open
OpenInVSCode,
OpenRepoInVSCode,
OpenInIDE,
OpenRepoInIDE,
OpenProperties,
OpenReleaseNotes,
OpenClassicProperties,
Expand Down
8 changes: 4 additions & 4 deletions src/Files.App/Data/Commands/Manager/CommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ public IRichCommand this[HotKey hotKey]
public IRichCommand OpenItem => commands[CommandCodes.OpenItem];
public IRichCommand OpenItemWithApplicationPicker => commands[CommandCodes.OpenItemWithApplicationPicker];
public IRichCommand OpenParentFolder => commands[CommandCodes.OpenParentFolder];
public IRichCommand OpenInVSCode => commands[CommandCodes.OpenInVSCode];
public IRichCommand OpenRepoInVSCode => commands[CommandCodes.OpenRepoInVSCode];
public IRichCommand OpenInVSCode => commands[CommandCodes.OpenInIDE];
public IRichCommand OpenRepoInVSCode => commands[CommandCodes.OpenRepoInIDE];
public IRichCommand OpenProperties => commands[CommandCodes.OpenProperties];
public IRichCommand OpenReleaseNotes => commands[CommandCodes.OpenReleaseNotes];
public IRichCommand OpenClassicProperties => commands[CommandCodes.OpenClassicProperties];
Expand Down Expand Up @@ -317,8 +317,8 @@ public IEnumerator<IRichCommand> GetEnumerator() =>
[CommandCodes.OpenItem] = new OpenItemAction(),
[CommandCodes.OpenItemWithApplicationPicker] = new OpenItemWithApplicationPickerAction(),
[CommandCodes.OpenParentFolder] = new OpenParentFolderAction(),
[CommandCodes.OpenInVSCode] = new OpenInVSCodeAction(),
[CommandCodes.OpenRepoInVSCode] = new OpenRepoInVSCodeAction(),
[CommandCodes.OpenInIDE] = new OpenInIDEAction(),
[CommandCodes.OpenRepoInIDE] = new OpenRepoInIDEAction(),
[CommandCodes.OpenProperties] = new OpenPropertiesAction(),
[CommandCodes.OpenReleaseNotes] = new OpenReleaseNotesAction(),
[CommandCodes.OpenClassicProperties] = new OpenClassicPropertiesAction(),
Expand Down
13 changes: 10 additions & 3 deletions src/Files.App/Data/Contracts/IDevToolsSettingsService.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;

namespace Files.App.Data.Contracts
{
public interface IDevToolsSettingsService : IBaseSettingsService, INotifyPropertyChanged
Expand All @@ -12,5 +9,15 @@ public interface IDevToolsSettingsService : IBaseSettingsService, INotifyPropert
/// Gets or sets a value when the Open in IDE button should be displayed on the status bar.
/// </summary>
OpenInIDEOption OpenInIDEOption { get; set; }

/// <summary>
/// Gets or sets the path of the chosen IDE.
/// </summary>
string IDEPath { get; set; }

/// <summary>
/// Gets or sets the friendly name of the chosen IDE.
/// </summary>
string IDEFriendlyName { get; set; }
}
}
20 changes: 20 additions & 0 deletions src/Files.App/Helpers/Dialog/DynamicDialogFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,5 +404,25 @@ public static DynamicDialog GetFor_CreateAlternateDataStreamDialog()

return dialog;
}

public static async Task ShowFor_IDEErrorDialog(string friendlyName)
{
var commands = Ioc.Default.GetRequiredService<ICommandManager>();
var dialog = new DynamicDialog(new DynamicDialogViewModel()
{
TitleText = Strings.IDENotLocatedTitle.GetLocalizedResource(),
SubtitleText = string.Format(Strings.IDENotLocatedContent.GetLocalizedResource(), friendlyName),
PrimaryButtonText = Strings.OpenSettings.GetLocalizedResource(),
SecondaryButtonText = Strings.Close.GetLocalizedResource(),
DynamicButtons = DynamicDialogButtons.Primary | DynamicDialogButtons.Secondary,
});

await dialog.TryShowAsync();

if (dialog.DynamicResult is DynamicDialogResult.Primary)
await commands.OpenSettings.ExecuteAsync(
new SettingsNavigationParams() { PageKind = SettingsPageKind.DevToolsPage }
);
}
}
}
21 changes: 0 additions & 21 deletions src/Files.App/Helpers/Environment/SoftwareHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ namespace Files.App.Helpers
internal static class SoftwareHelpers
{
private const string UninstallRegistryKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall";
private const string VsRegistryKey = @"SOFTWARE\Microsoft\VisualStudio";

private const string VsCodeName = "Microsoft Visual Studio Code";


public static bool IsVSCodeInstalled()
{
try
Expand All @@ -29,25 +27,6 @@ public static bool IsVSCodeInstalled()
}
}

public static bool IsVSInstalled()
{
try
{
var key = Registry.LocalMachine.OpenSubKey(VsRegistryKey);
if (key is null)
return false;

key.Close();

return true;
}
catch (SecurityException)
{
// Handle edge case where OpenSubKey results in SecurityException
return false;
}
}

private static bool ContainsName(RegistryKey? key, string find)
{
if (key is null)
Expand Down
14 changes: 14 additions & 0 deletions src/Files.App/Services/Settings/DevToolsSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ public OpenInIDEOption OpenInIDEOption
set => Set(value);
}

/// <inheritdoc/>
public string IDEPath
{
get => Get(SoftwareHelpers.IsVSCodeInstalled() ? "code" : string.Empty) ?? string.Empty;
set => Set(value);
}

/// <inheritdoc/>
public string IDEFriendlyName
{
get => Get(SoftwareHelpers.IsVSCodeInstalled() ? Strings.VisualStudioCode.GetLocalizedResource() : string.Empty) ?? string.Empty;
set => Set(value);
}

protected override void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e)
{
base.RaiseOnSettingChangedEvent(sender, e);
Expand Down
Loading
Loading