diff --git a/src/Files.App/Actions/Display/GroupAction.cs b/src/Files.App/Actions/Display/GroupAction.cs index e0bf7d3e1930..7020496f2664 100644 --- a/src/Files.App/Actions/Display/GroupAction.cs +++ b/src/Files.App/Actions/Display/GroupAction.cs @@ -177,6 +177,7 @@ public GroupByAction() public Task ExecuteAsync(object? parameter = null) { DisplayContext.GroupOption = GroupOption; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupOption)]); return Task.CompletedTask; } @@ -377,6 +378,10 @@ public Task ExecuteAsync(object? parameter = null) { DisplayContext.GroupOption = GroupOption; DisplayContext.GroupByDateUnit = GroupByDateUnit; + LayoutHelpers.UpdateOpenTabsPreferences([ + nameof(LayoutPreferencesItem.DirectoryGroupOption), + nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit) + ]); return Task.CompletedTask; } @@ -425,6 +430,7 @@ public GroupAscendingAction() public Task ExecuteAsync(object? parameter = null) { context.GroupDirection = SortDirection.Ascending; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupDirection)]); return Task.CompletedTask; } @@ -469,6 +475,7 @@ public GroupDescendingAction() public Task ExecuteAsync(object? parameter = null) { context.GroupDirection = SortDirection.Descending; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupDirection)]); return Task.CompletedTask; } @@ -505,6 +512,7 @@ public ToggleGroupDirectionAction() public Task ExecuteAsync(object? parameter = null) { context.GroupDirection = context.SortDirection is SortDirection.Descending ? SortDirection.Ascending : SortDirection.Descending; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupDirection)]); return Task.CompletedTask; } @@ -536,6 +544,7 @@ public GroupByYearAction() public Task ExecuteAsync(object? parameter = null) { context.GroupByDateUnit = GroupByDateUnit.Year; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit)]); return Task.CompletedTask; } @@ -580,6 +589,7 @@ public GroupByMonthAction() public Task ExecuteAsync(object? parameter = null) { context.GroupByDateUnit = GroupByDateUnit.Month; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit)]); return Task.CompletedTask; } @@ -621,6 +631,7 @@ public Task ExecuteAsync(object? parameter = null) GroupByDateUnit.Month => GroupByDateUnit.Day, _ => GroupByDateUnit.Year }; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit)]); return Task.CompletedTask; } diff --git a/src/Files.App/Actions/Display/SortAction.cs b/src/Files.App/Actions/Display/SortAction.cs index 4c5b9742259e..ad7e85d7d67f 100644 --- a/src/Files.App/Actions/Display/SortAction.cs +++ b/src/Files.App/Actions/Display/SortAction.cs @@ -165,6 +165,7 @@ public SortByAction() public Task ExecuteAsync(object? parameter = null) { displayContext.SortOption = SortOption; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortOption)]); return Task.CompletedTask; } @@ -207,6 +208,7 @@ public SortAscendingAction() public Task ExecuteAsync(object? parameter = null) { context.SortDirection = SortDirection.Ascending; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortDirection)]); return Task.CompletedTask; } @@ -241,6 +243,7 @@ public SortDescendingAction() public Task ExecuteAsync(object? parameter = null) { context.SortDirection = SortDirection.Descending; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortDirection)]); return Task.CompletedTask; } @@ -274,6 +277,8 @@ context.SortDirection is SortDirection.Descending ? SortDirection.Ascending : SortDirection.Descending; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortDirection)]); + return Task.CompletedTask; } } diff --git a/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs b/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs index e91ea79c8bc4..f58b3ce0f1b2 100644 --- a/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs +++ b/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs @@ -26,6 +26,7 @@ public SortFilesAndFoldersTogetherAction() public Task ExecuteAsync(object? parameter = null) { context.SortDirectoriesAlongsideFiles = true; + LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.SortDirectoriesAlongsideFiles)]); return Task.CompletedTask; } diff --git a/src/Files.App/Actions/Display/SortFilesFirstAction.cs b/src/Files.App/Actions/Display/SortFilesFirstAction.cs index 8db1fc77c1fd..e6f324684826 100644 --- a/src/Files.App/Actions/Display/SortFilesFirstAction.cs +++ b/src/Files.App/Actions/Display/SortFilesFirstAction.cs @@ -27,6 +27,10 @@ public Task ExecuteAsync(object? parameter = null) { context.SortFilesFirst = true; context.SortDirectoriesAlongsideFiles = false; + LayoutHelpers.UpdateOpenTabsPreferences([ + nameof(LayoutPreferencesItem.SortFilesFirst), + nameof(LayoutPreferencesItem.SortDirectoriesAlongsideFiles) + ]); return Task.CompletedTask; } diff --git a/src/Files.App/Actions/Display/SortFoldersFirstAction.cs b/src/Files.App/Actions/Display/SortFoldersFirstAction.cs index d1aaaaf587c1..8ac73746316d 100644 --- a/src/Files.App/Actions/Display/SortFoldersFirstAction.cs +++ b/src/Files.App/Actions/Display/SortFoldersFirstAction.cs @@ -27,6 +27,10 @@ public Task ExecuteAsync(object? parameter = null) { context.SortFilesFirst = false; context.SortDirectoriesAlongsideFiles = false; + LayoutHelpers.UpdateOpenTabsPreferences([ + nameof(LayoutPreferencesItem.SortFilesFirst), + nameof(LayoutPreferencesItem.SortDirectoriesAlongsideFiles) + ]); return Task.CompletedTask; } diff --git a/src/Files.App/Data/Contracts/IShellPanesPage.cs b/src/Files.App/Data/Contracts/IShellPanesPage.cs index 9eb40f0971fc..37082471a165 100644 --- a/src/Files.App/Data/Contracts/IShellPanesPage.cs +++ b/src/Files.App/Data/Contracts/IShellPanesPage.cs @@ -58,5 +58,13 @@ public interface IShellPanesPage : IDisposable, INotifyPropertyChanged /// Focuses the other pane. /// public void FocusOtherPane(); + + /// + /// Updates the layout of open panes. + /// + /// The path of panes to update + /// The preferences to update + /// Whether the active pane should be updated or not + public void UpdatePanesLayout(string targetPath, string[] preferences, bool includeActivePane = false); } } diff --git a/src/Files.App/Helpers/Layout/LayoutHelpers.cs b/src/Files.App/Helpers/Layout/LayoutHelpers.cs new file mode 100644 index 000000000000..7d48183ad368 --- /dev/null +++ b/src/Files.App/Helpers/Layout/LayoutHelpers.cs @@ -0,0 +1,22 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Helpers +{ + static class LayoutHelpers + { + public static void UpdateOpenTabsPreferences(string[] preferences) + { + var multitaskingContext = Ioc.Default.GetRequiredService(); + var tabs = multitaskingContext.Control?.GetAllTabInstances(); + var activePath = ((ShellPanesPage)multitaskingContext.CurrentTabItem.TabItemContent)?.ActivePane?.TabBarItemParameter?.NavigationParameter as string; + if (tabs is null || activePath is null) + return; + + for (int i = 0; i < tabs.Count; i++) + { + ((ShellPanesPage)tabs[i]).UpdatePanesLayout(activePath, preferences, i != multitaskingContext.CurrentTabIndex); + } + } + } +} diff --git a/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs b/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs index 7f17895d5c85..6cf46cbdd03c 100644 --- a/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs +++ b/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs @@ -265,6 +265,44 @@ public Type GetLayoutType(string path, bool changeLayoutMode = true) }; } + public void UpdateGroupAndSortOptions(string? path, string[] properties) + { + if (string.IsNullOrWhiteSpace(path)) + return; + + var preferencesItem = GetLayoutPreferencesForPath(path); + if (preferencesItem is null) + return; + + foreach (var property in properties) + { + switch (property) + { + case nameof(preferencesItem.DirectorySortOption): + DirectorySortOption = preferencesItem.DirectorySortOption; + break; + case nameof(preferencesItem.DirectorySortDirection): + DirectorySortDirection = preferencesItem.DirectorySortDirection; + break; + case nameof(preferencesItem.DirectoryGroupOption): + DirectoryGroupOption = preferencesItem.DirectoryGroupOption; + break; + case nameof(preferencesItem.DirectoryGroupByDateUnit): + DirectoryGroupByDateUnit = preferencesItem.DirectoryGroupByDateUnit; + break; + case nameof(preferencesItem.DirectoryGroupDirection): + DirectoryGroupDirection = preferencesItem.DirectoryGroupDirection; + break; + case nameof(preferencesItem.SortDirectoriesAlongsideFiles): + SortDirectoriesAlongsideFiles = preferencesItem.SortDirectoriesAlongsideFiles; + break; + case nameof(preferencesItem.SortFilesFirst): + SortFilesFirst = preferencesItem.SortFilesFirst; + break; + } + } + } + public bool IsPathUsingDefaultLayout(string? path) { return UserSettingsService.LayoutSettingsService.SyncFolderPreferencesAcrossDirectories || diff --git a/src/Files.App/Views/ShellPanesPage.xaml.cs b/src/Files.App/Views/ShellPanesPage.xaml.cs index 7298d6d1c5ad..daa78baa9d15 100644 --- a/src/Files.App/Views/ShellPanesPage.xaml.cs +++ b/src/Files.App/Views/ShellPanesPage.xaml.cs @@ -19,6 +19,7 @@ public sealed partial class ShellPanesPage : Page, IShellPanesPage, ITabBarItemC // Dependency injections private IGeneralSettingsService GeneralSettingsService { get; } = Ioc.Default.GetRequiredService(); + private ILayoutSettingsService LayoutSettingsService { get; } = Ioc.Default.GetRequiredService(); private AppModel AppModel { get; } = Ioc.Default.GetRequiredService(); // Constants @@ -356,6 +357,23 @@ public void FocusOtherPane() GetPane(0)?.Focus(FocusState.Programmatic); } + /// + public void UpdatePanesLayout(string targetPath, string[] preferences, bool includeActivePane = false) + { + foreach (var pane in GetPanes()) + { + var path = pane.ShellViewModel.CurrentFolder?.ItemPath; + if ((includeActivePane || pane != ActivePane) && + (LayoutSettingsService.SyncFolderPreferencesAcrossDirectories || + path is not null && + path.Equals(targetPath, StringComparison.OrdinalIgnoreCase))) + { + var page = pane.SlimContentPage as BaseLayoutPage; + page?.FolderSettings?.UpdateGroupAndSortOptions(path, preferences); + } + } + } + // Private methods private ModernShellPage? GetPane(int index = -1)