diff --git a/src/Files.App/Actions/Open/OpenSettingsFileAction.cs b/src/Files.App/Actions/Open/OpenSettingsFileAction.cs new file mode 100644 index 000000000000..efdf25854d43 --- /dev/null +++ b/src/Files.App/Actions/Open/OpenSettingsFileAction.cs @@ -0,0 +1,54 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Media; +using Windows.Foundation.Metadata; +using Windows.Storage; +using Windows.System; + +namespace Files.App.Actions +{ + internal sealed partial class OpenSettingsFileAction : IAction + { + public string Label + => Strings.EditSettingsFile.GetLocalizedResource(); + + public string Description + => Strings.EditSettingsFileDescription.GetLocalizedResource(); + + public HotKey HotKey + => new(Keys.OemComma, KeyModifiers.CtrlShift); + + public RichGlyph Glyph + => new("\uE8DA"); + + public async Task ExecuteAsync(object? parameter = null) + { + try + { + var settingsJsonFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appdata:///local/{Constants.LocalSettings.SettingsFolderName}/{Constants.LocalSettings.UserSettingsFileName}")); + if (!await Launcher.LaunchFileAsync(settingsJsonFile)) + await ContextMenu.InvokeVerb("open", settingsJsonFile.Path); + } + catch (Exception ex) + { + // Only show the error dialog if no other popups are open + if (!VisualTreeHelper.GetOpenPopupsForXamlRoot(MainWindow.Instance.Content.XamlRoot).Any()) + { + var errorDialog = new ContentDialog() + { + Title = Strings.FailedToOpenSettingsFile.GetLocalizedResource(), + Content = ex.Message, + PrimaryButtonText = Strings.OK.GetLocalizedResource(), + }; + + if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8)) + errorDialog.XamlRoot = MainWindow.Instance.Content.XamlRoot; + + await errorDialog.TryShowAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/src/Files.App/Data/Commands/Manager/CommandCodes.cs b/src/Files.App/Data/Commands/Manager/CommandCodes.cs index 6080fe082769..edaa553cba0e 100644 --- a/src/Files.App/Data/Commands/Manager/CommandCodes.cs +++ b/src/Files.App/Data/Commands/Manager/CommandCodes.cs @@ -118,6 +118,7 @@ public enum CommandCodes OpenReleaseNotes, OpenClassicProperties, OpenSettings, + OpenSettingsFile, OpenStorageSense, OpenStorageSenseFromHome, OpenStorageSenseFromSidebar, diff --git a/src/Files.App/Data/Commands/Manager/CommandManager.cs b/src/Files.App/Data/Commands/Manager/CommandManager.cs index abc95ef0641f..a0aa75e55b31 100644 --- a/src/Files.App/Data/Commands/Manager/CommandManager.cs +++ b/src/Files.App/Data/Commands/Manager/CommandManager.cs @@ -122,6 +122,7 @@ public IRichCommand this[HotKey hotKey] public IRichCommand OpenStorageSenseFromHome => commands[CommandCodes.OpenStorageSenseFromHome]; public IRichCommand OpenStorageSenseFromSidebar => commands[CommandCodes.OpenStorageSenseFromSidebar]; public IRichCommand OpenSettings => commands[CommandCodes.OpenSettings]; + public IRichCommand OpenSettingsFile => commands[CommandCodes.OpenSettingsFile]; public IRichCommand OpenTerminal => commands[CommandCodes.OpenTerminal]; public IRichCommand OpenTerminalAsAdmin => commands[CommandCodes.OpenTerminalAsAdmin]; public IRichCommand OpenTerminalFromSidebar => commands[CommandCodes.OpenTerminalFromSidebar]; @@ -327,6 +328,7 @@ public IEnumerator GetEnumerator() => [CommandCodes.OpenStorageSenseFromHome] = new OpenStorageSenseFromHomeAction(), [CommandCodes.OpenStorageSenseFromSidebar] = new OpenStorageSenseFromSidebarAction(), [CommandCodes.OpenSettings] = new OpenSettingsAction(), + [CommandCodes.OpenSettingsFile] = new OpenSettingsFileAction(), [CommandCodes.OpenTerminal] = new OpenTerminalAction(), [CommandCodes.OpenTerminalAsAdmin] = new OpenTerminalAsAdminAction(), [CommandCodes.OpenTerminalFromSidebar] = new OpenTerminalFromSidebarAction(), diff --git a/src/Files.App/Data/Commands/Manager/ICommandManager.cs b/src/Files.App/Data/Commands/Manager/ICommandManager.cs index 8fa91bf08738..d0ceb7699628 100644 --- a/src/Files.App/Data/Commands/Manager/ICommandManager.cs +++ b/src/Files.App/Data/Commands/Manager/ICommandManager.cs @@ -110,6 +110,7 @@ public interface ICommandManager : IEnumerable IRichCommand OpenStorageSenseFromHome { get; } IRichCommand OpenStorageSenseFromSidebar { get; } IRichCommand OpenSettings { get; } + IRichCommand OpenSettingsFile { get; } IRichCommand OpenTerminal { get; } IRichCommand OpenTerminalAsAdmin { get; } IRichCommand OpenTerminalFromSidebar { get; } diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index 7fc0bf73a209..40d59b0f7907 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -2195,6 +2195,9 @@ Edit settings file + + Open settings file in your default editor + What's new @@ -3694,6 +3697,9 @@ Failed to set the background wallpaper + + Failed to open the settings file + Delete Git branch diff --git a/src/Files.App/ViewModels/Settings/AdvancedViewModel.cs b/src/Files.App/ViewModels/Settings/AdvancedViewModel.cs index 9e3d608c9312..46320f12cf0f 100644 --- a/src/Files.App/ViewModels/Settings/AdvancedViewModel.cs +++ b/src/Files.App/ViewModels/Settings/AdvancedViewModel.cs @@ -19,6 +19,7 @@ public sealed partial class AdvancedViewModel : ObservableObject { private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService(); private ICommonDialogService CommonDialogService { get; } = Ioc.Default.GetRequiredService(); + public ICommandManager Commands { get; } = Ioc.Default.GetRequiredService(); private readonly IFileTagsSettingsService fileTagsSettingsService = Ioc.Default.GetRequiredService(); @@ -26,7 +27,6 @@ public sealed partial class AdvancedViewModel : ObservableObject public ICommand SetAsOpenFileDialogCommand { get; } public ICommand ExportSettingsCommand { get; } public ICommand ImportSettingsCommand { get; } - public ICommand OpenSettingsJsonCommand { get; } public AsyncRelayCommand OpenFilesOnWindowsStartupCommand { get; } @@ -39,22 +39,11 @@ public AdvancedViewModel() SetAsOpenFileDialogCommand = new AsyncRelayCommand(SetAsOpenFileDialogAsync); ExportSettingsCommand = new AsyncRelayCommand(ExportSettingsAsync); ImportSettingsCommand = new AsyncRelayCommand(ImportSettingsAsync); - OpenSettingsJsonCommand = new AsyncRelayCommand(OpenSettingsJsonAsync); OpenFilesOnWindowsStartupCommand = new AsyncRelayCommand(OpenFilesOnWindowsStartupAsync); _ = DetectOpenFilesAtStartupAsync(); } - private async Task OpenSettingsJsonAsync() - { - await SafetyExtensions.IgnoreExceptions(async () => - { - var settingsJsonFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appdata:///local/settings/user_settings.json")); - if (!await Launcher.LaunchFileAsync(settingsJsonFile)) - await ContextMenu.InvokeVerb("open", settingsJsonFile.Path); - }); - } - private async Task SetAsDefaultExplorerAsync() { // Make sure IsSetAsDefaultFileManager is updated diff --git a/src/Files.App/Views/MainPage.xaml b/src/Files.App/Views/MainPage.xaml index 21bd75f4e5f1..543f09a388bc 100644 --- a/src/Files.App/Views/MainPage.xaml +++ b/src/Files.App/Views/MainPage.xaml @@ -280,8 +280,7 @@ Background="Transparent" BorderThickness="0" Command="{x:Bind Commands.OpenSettings, Mode=OneWay}" - ToolTipService.Placement="Bottom" - ToolTipService.ToolTip="{x:Bind Commands.OpenSettings.LabelWithHotKey, Mode=OneWay}"> + ToolTipService.Placement="Bottom"> @@ -308,6 +307,15 @@ Margin="12,0,0,0" Text="{x:Bind Commands.OpenSettings.Label, Mode=OneWay}" /> + + + + + + diff --git a/src/Files.App/Views/MainPage.xaml.cs b/src/Files.App/Views/MainPage.xaml.cs index 558dc8fd3efd..1ad32eb98844 100644 --- a/src/Files.App/Views/MainPage.xaml.cs +++ b/src/Files.App/Views/MainPage.xaml.cs @@ -28,7 +28,7 @@ public sealed partial class MainPage : Page private IGeneralSettingsService generalSettingsService { get; } = Ioc.Default.GetRequiredService(); public IUserSettingsService UserSettingsService { get; } private readonly IWindowContext WindowContext = Ioc.Default.GetRequiredService(); - public ICommandManager Commands { get; } + private readonly ICommandManager Commands = Ioc.Default.GetRequiredService(); public SidebarViewModel SidebarAdaptiveViewModel { get; } public MainPageViewModel ViewModel { get; } @@ -42,7 +42,6 @@ public MainPage() // Dependency Injection UserSettingsService = Ioc.Default.GetRequiredService(); - Commands = Ioc.Default.GetRequiredService(); SidebarAdaptiveViewModel = Ioc.Default.GetRequiredService(); SidebarAdaptiveViewModel.PaneFlyout = (MenuFlyout)Resources["SidebarContextMenu"]; ViewModel = Ioc.Default.GetRequiredService(); diff --git a/src/Files.App/Views/Settings/AdvancedPage.xaml b/src/Files.App/Views/Settings/AdvancedPage.xaml index d4ac08f65966..7ec7843219f2 100644 --- a/src/Files.App/Views/Settings/AdvancedPage.xaml +++ b/src/Files.App/Views/Settings/AdvancedPage.xaml @@ -63,7 +63,7 @@