From 5a3815a4a57e32da8483a84205721a7aedea22b0 Mon Sep 17 00:00:00 2001 From: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> Date: Mon, 4 May 2026 16:22:50 +0900 Subject: [PATCH 1/3] Init --- .../Data/Settings/BaseJsonSettings.cs | 167 +++++++++++++ .../Data/Settings/Settings.Actions.cs | 10 + src/Files.App/Data/Settings/Settings.App.cs | 16 ++ .../Data/Settings/Settings.Appearance.cs | 92 +++++++ .../Data/Settings/Settings.Application.cs | 19 ++ .../Data/Settings/Settings.DevTools.cs | 30 +++ .../Data/Settings/Settings.FileTags.cs | 10 + .../Data/Settings/Settings.Folders.cs | 61 +++++ .../Data/Settings/Settings.General.cs | 223 +++++++++++++++++ .../Data/Settings/Settings.InfoPane.cs | 32 +++ .../Data/Settings/Settings.Layout.cs | 136 ++++++++++ src/Files.App/Data/Settings/Settings.cs | 22 ++ .../Data/Settings/SettingsJsonContext.cs | 19 ++ .../GeneratedSettingsPropertyGenerator.cs | 232 ++++++++++++++++++ .../GeneratedSettingsPropertyAttribute.cs | 11 + 15 files changed, 1080 insertions(+) create mode 100644 src/Files.App/Data/Settings/BaseJsonSettings.cs create mode 100644 src/Files.App/Data/Settings/Settings.Actions.cs create mode 100644 src/Files.App/Data/Settings/Settings.App.cs create mode 100644 src/Files.App/Data/Settings/Settings.Appearance.cs create mode 100644 src/Files.App/Data/Settings/Settings.Application.cs create mode 100644 src/Files.App/Data/Settings/Settings.DevTools.cs create mode 100644 src/Files.App/Data/Settings/Settings.FileTags.cs create mode 100644 src/Files.App/Data/Settings/Settings.Folders.cs create mode 100644 src/Files.App/Data/Settings/Settings.General.cs create mode 100644 src/Files.App/Data/Settings/Settings.InfoPane.cs create mode 100644 src/Files.App/Data/Settings/Settings.Layout.cs create mode 100644 src/Files.App/Data/Settings/Settings.cs create mode 100644 src/Files.App/Data/Settings/SettingsJsonContext.cs create mode 100644 src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs create mode 100644 src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs diff --git a/src/Files.App/Data/Settings/BaseJsonSettings.cs b/src/Files.App/Data/Settings/BaseJsonSettings.cs new file mode 100644 index 000000000000..823a3f3115bd --- /dev/null +++ b/src/Files.App/Data/Settings/BaseJsonSettings.cs @@ -0,0 +1,167 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; +using Windows.Storage; + +namespace Files.App.Data.Settings; + +public abstract class BaseJsonSettings : IDisposable, INotifyPropertyChanged +{ + private readonly object gate = new(); + private readonly string filePath; + private readonly TimeSpan saveDelay; + private Timer? saveTimer; + private bool isDisposed; + private bool isLoaded; + private bool isDirty; + private bool isHydrating = true; + + public event PropertyChangedEventHandler? PropertyChanged; + + protected BaseJsonSettings(string fileName, TimeSpan? saveDelay = null) + { + var folderPath = SystemIO.Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.LocalSettings.SettingsFolderName); + filePath = SystemIO.Path.Combine(folderPath, fileName); + this.saveDelay = saveDelay ?? TimeSpan.FromMilliseconds(250); + } + + protected void Initialize() + { + lock (gate) + { + ThrowIfDisposed(); + if (isLoaded) + return; + + var directory = SystemIO.Path.GetDirectoryName(filePath); + if (!string.IsNullOrEmpty(directory)) + SystemIO.Directory.CreateDirectory(directory); + + if (!SystemIO.File.Exists(filePath)) + { + isLoaded = true; + isHydrating = false; + return; + } + + var raw = SystemIO.File.ReadAllText(filePath); + if (!string.IsNullOrWhiteSpace(raw)) + { + DeserializeCore(raw); + } + + isLoaded = true; + isHydrating = false; + } + } + + protected bool SetProperty(ref T storage, T value, [CallerMemberName] string? propertyName = null) + { + lock (gate) + { + ThrowIfDisposed(); + if (EqualityComparer.Default.Equals(storage, value)) + return false; + + storage = value; + if (!isHydrating) + { + isDirty = true; + QueueSave_NoLock(); + } + } + + if (!isHydrating && !string.IsNullOrEmpty(propertyName)) + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + + return true; + } + + protected IDisposable BeginHydrationScope() + { + return new HydrationScope(this); + } + + public void SaveNow() + { + lock (gate) + { + ThrowIfDisposed(); + SaveCore_NoLock(); + } + } + + private void QueueSave_NoLock() + { + saveTimer ??= new Timer(static s => + { + var self = (BaseJsonSettings)s!; + lock (self.gate) + { + if (self.isDisposed) + return; + self.SaveCore_NoLock(); + } + }, this, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); + + saveTimer.Change(saveDelay, Timeout.InfiniteTimeSpan); + } + + private void SaveCore_NoLock() + { + if (!isDirty) + return; + + var json = SerializeCore(); + SystemIO.File.WriteAllText(filePath, json); + isDirty = false; + } + + protected abstract string SerializeCore(); + protected abstract void DeserializeCore(string json); + + public void Dispose() + { + lock (gate) + { + if (isDisposed) + return; + + SaveCore_NoLock(); + saveTimer?.Dispose(); + saveTimer = null; + isDisposed = true; + } + + GC.SuppressFinalize(this); + } + + private void ThrowIfDisposed() + { + ObjectDisposedException.ThrowIf(isDisposed, this); + } + + private sealed class HydrationScope : IDisposable + { + private readonly BaseJsonSettings owner; + private readonly bool previous; + private bool disposed; + + public HydrationScope(BaseJsonSettings owner) + { + this.owner = owner; + previous = owner.isHydrating; + owner.isHydrating = true; + } + + public void Dispose() + { + if (disposed) + return; + + owner.isHydrating = previous; + disposed = true; + } + } +} diff --git a/src/Files.App/Data/Settings/Settings.Actions.cs b/src/Files.App/Data/Settings/Settings.Actions.cs new file mode 100644 index 000000000000..eadb0f149a8a --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.Actions.cs @@ -0,0 +1,10 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty] + public partial List? ActionsV2 { get; set; } +} diff --git a/src/Files.App/Data/Settings/Settings.App.cs b/src/Files.App/Data/Settings/Settings.App.cs new file mode 100644 index 000000000000..5424f17ce497 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.App.cs @@ -0,0 +1,16 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowStatusCenterTeachingTip { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowBackgroundRunningNotification { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool RestoreTabsOnStartup { get; set; } +} diff --git a/src/Files.App/Data/Settings/Settings.Appearance.cs b/src/Files.App/Data/Settings/Settings.Appearance.cs new file mode 100644 index 000000000000..606cdccab747 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.Appearance.cs @@ -0,0 +1,92 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Media; + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = 255d, GetValueCallback = nameof(GetSidebarWidth))] + public partial double SidebarWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool IsSidebarOpen { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "Default")] + public partial string AppThemeMode { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "#00000000")] + public partial string AppThemeBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeAddressBarBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeToolbarBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeSidebarBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeFileAreaBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeFileAreaSecondaryBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeInfoPaneBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultAppThemeFontFamily))] + public partial string AppThemeFontFamily { get; set; } + + [GeneratedSettingsProperty(DefaultValue = BackdropMaterialType.MicaAlt)] + public partial BackdropMaterialType AppThemeBackdropMaterial { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeBackgroundImageSource { get; set; } + + [GeneratedSettingsProperty(DefaultValue = Stretch.UniformToFill)] + public partial Stretch AppThemeBackgroundImageFit { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 1f)] + public partial float AppThemeBackgroundImageOpacity { get; set; } + + [GeneratedSettingsProperty(DefaultValue = VerticalAlignment.Center)] + public partial VerticalAlignment AppThemeBackgroundImageVerticalAlignment { get; set; } + + [GeneratedSettingsProperty(DefaultValue = HorizontalAlignment.Center)] + public partial HorizontalAlignment AppThemeBackgroundImageHorizontalAlignment { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowToolbar { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowStatusBar { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowTabActions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowShelfPaneToggleButton { get; set; } + + [GeneratedSettingsProperty(DefaultValue = StatusCenterVisibility.Always)] + public partial StatusCenterVisibility StatusCenterVisibility { get; set; } + + [GeneratedSettingsProperty] + public partial Dictionary>? CustomToolbarItems { get; set; } + + [GeneratedSettingsProperty] + public partial Dictionary>? LastKnownToolbarDefaults { get; set; } + + private static double GetSidebarWidth(double value) + { + return Math.Min(Math.Max(value, Constants.UI.MinimumSidebarWidth), 500d); + } + + private static string GetDefaultAppThemeFontFamily() + { + return Constants.Appearance.StandardFont; + } +} diff --git a/src/Files.App/Data/Settings/Settings.Application.cs b/src/Files.App/Data/Settings/Settings.Application.cs new file mode 100644 index 000000000000..1b56bdb5feb0 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.Application.cs @@ -0,0 +1,19 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool HasClickedReviewPrompt { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool HasClickedSponsorPrompt { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowRunningAsAdminPrompt { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDataStreamsAreHiddenPrompt { get; set; } +} diff --git a/src/Files.App/Data/Settings/Settings.DevTools.cs b/src/Files.App/Data/Settings/Settings.DevTools.cs new file mode 100644 index 000000000000..fc5dc3591659 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.DevTools.cs @@ -0,0 +1,30 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = OpenInIDEOption.GitRepos)] + public partial OpenInIDEOption OpenInIDEOption { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultIDEPath))] + public partial string IDEPath { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultIDEName))] + public partial string IDEName { get; set; } + + private static string GetDefaultIDEPath() + { + return SoftwareHelpers.IsVSCodeInstalled() + ? "code" + : string.Empty; + } + + private static string GetDefaultIDEName() + { + return SoftwareHelpers.IsVSCodeInstalled() + ? Strings.VisualStudioCode.GetLocalizedResource() + : string.Empty; + } +} diff --git a/src/Files.App/Data/Settings/Settings.FileTags.cs b/src/Files.App/Data/Settings/Settings.FileTags.cs new file mode 100644 index 000000000000..0e01b9875df4 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.FileTags.cs @@ -0,0 +1,10 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty] + public partial List? FileTagList { get; set; } +} diff --git a/src/Files.App/Data/Settings/Settings.Folders.cs b/src/Files.App/Data/Settings/Settings.Folders.cs new file mode 100644 index 000000000000..15750a96a4d7 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.Folders.cs @@ -0,0 +1,61 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowHiddenItems { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowProtectedSystemFiles { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool AreAlternateStreamsVisible { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDotFiles { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] + public partial SingleClickOpenMode OpenFilesWithSingleClick { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] + public partial SingleClickOpenMode OpenFoldersWithSingleClick { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.Always)] + public partial SingleClickOpenMode OpenFoldersInColumnsViewWithSingleClick { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool OpenFoldersInNewTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ScrollToPreviousFolderWhenNavigatingUp { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool CalculateFolderSizes { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileExtensions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowThumbnails { get; set; } + + [GeneratedSettingsProperty(DefaultValue = DeleteConfirmationPolicies.Always)] + public partial DeleteConfirmationPolicies DeleteConfirmationPolicy { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool SelectFilesOnHover { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool DoubleClickToGoUp { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileExtensionWarning { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCheckboxesWhenSelectingItems { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SizeUnitTypes.BinaryUnits)] + public partial SizeUnitTypes SizeUnitFormat { get; set; } +} diff --git a/src/Files.App/Data/Settings/Settings.General.cs b/src/Files.App/Data/Settings/Settings.General.cs new file mode 100644 index 000000000000..be9e79ee7e49 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.General.cs @@ -0,0 +1,223 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool OpenSpecificPageOnStartup { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string OpenSpecificPageOnStartupPath { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ContinueLastSessionOnStartUp { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool OpenNewTabOnStartup { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool OpenTabInExistingInstance { get; set; } + + [GeneratedSettingsProperty] + public partial List? TabsOnStartupList { get; set; } + + [GeneratedSettingsProperty] + public partial List? LastSessionTabList { get; set; } + + [GeneratedSettingsProperty] + public partial List? LastCrashedTabList { get; set; } + + [GeneratedSettingsProperty] + public partial List? PathHistoryList { get; set; } + + [GeneratedSettingsProperty] + public partial List? PreviousSearchQueriesList { get; set; } + + [GeneratedSettingsProperty] + public partial List? PreviousArchiveExtractionLocations { get; set; } + + [GeneratedSettingsProperty(DefaultValue = DateTimeFormats.Application)] + public partial DateTimeFormats DateTimeFormat { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool AlwaysOpenDualPaneInNewTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool AlwaysSwitchToNewlyOpenedTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowQuickAccessWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowRecentFilesWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDrivesWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowNetworkLocationsWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowFileTagsWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool FoldersWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool RecentFilesWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool DrivesWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool NetworkLocationsWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool FileTagsWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPinnedSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool IsPinnedSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowLibrarySection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsLibrarySectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDrivesSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsDriveSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCloudDrivesSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsCloudDriveSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowNetworkSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsNetworkSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowWslSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsWslSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileTagsSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsFileTagsSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool MoveShellExtensionsToSubMenu { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPinToSideBar { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPinToStart { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowEditTagsMenu { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCompressionOptions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowFlattenOptions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSendToMenu { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenInNewTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenInNewWindow { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenInNewPane { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenTerminal { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCopyPath { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCreateFolderWithSelection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowCreateAlternateDataStream { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCreateShortcut { get; set; } + +#if DEBUG + [GeneratedSettingsProperty(DefaultValue = false)] +#else + [GeneratedSettingsProperty(DefaultValue = true)] +#endif + public partial bool LeaveAppRunning { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSystemTrayIcon { get; set; } + + [GeneratedSettingsProperty(DefaultValue = FileNameConflictResolveOptionType.GenerateNewName)] + public partial FileNameConflictResolveOptionType ConflictsResolveOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveFormats.Zip)] + public partial ArchiveFormats ArchiveFormatsOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveCompressionLevels.Normal)] + public partial ArchiveCompressionLevels ArchiveCompressionLevelsOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveSplittingSizes.None)] + public partial ArchiveSplittingSizes ArchiveSplittingSizesOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveDictionarySizes.Auto)] + public partial ArchiveDictionarySizes ArchiveDictionarySizesOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveWordSizes.Auto)] + public partial ArchiveWordSizes ArchiveWordSizesOption { get; set; } + + [GeneratedSettingsProperty] + public partial Dictionary? ShowHashesDictionary { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultUserId))] + public partial string UserId { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ShellPaneArrangement.Vertical)] + public partial ShellPaneArrangement ShellPaneArrangementOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowShelfPane { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowFilterHeader { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool EnableThumbnailCache { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool EnableSmoothScrolling { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 512d)] + public partial double ThumbnailCacheSizeLimit { get; set; } + + private static string GetDefaultUserId() + { + return Guid.NewGuid().ToString(); + } +} diff --git a/src/Files.App/Data/Settings/Settings.InfoPane.cs b/src/Files.App/Data/Settings/Settings.InfoPane.cs new file mode 100644 index 000000000000..2de1cbd52ea1 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.InfoPane.cs @@ -0,0 +1,32 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsInfoPaneEnabled { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 300d, GetValueCallback = nameof(GetInfoPaneSize))] + public partial double HorizontalSizePx { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 250d, GetValueCallback = nameof(GetInfoPaneSize))] + public partial double VerticalSizePx { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 1d, GetValueCallback = nameof(GetMediaVolume))] + public partial double MediaVolume { get; set; } + + [GeneratedSettingsProperty(DefaultValue = InfoPaneTabs.Details)] + public partial InfoPaneTabs SelectedTab { get; set; } + + private static double GetInfoPaneSize(double value) + { + return Math.Max(100d, value); + } + + private static double GetMediaVolume(double value) + { + return Math.Min(Math.Max(value, 0d), 1d); + } +} diff --git a/src/Files.App/Data/Settings/Settings.Layout.cs b/src/Files.App/Data/Settings/Settings.Layout.cs new file mode 100644 index 000000000000..0e7e814bbadc --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.Layout.cs @@ -0,0 +1,136 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings +{ + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool SyncFolderPreferencesAcrossDirectories { get; set; } + + [GeneratedSettingsProperty(DefaultValue = FolderLayoutModes.Adaptive)] + public partial FolderLayoutModes DefaultLayoutMode { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SortOption.Name)] + public partial SortOption DefaultSortOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SortDirection.Ascending)] + public partial SortDirection DefaultDirectorySortDirection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool DefaultSortDirectoriesAlongsideFiles { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool DefaultSortFilesFirst { get; set; } + + [GeneratedSettingsProperty(DefaultValue = GroupOption.None)] + public partial GroupOption DefaultGroupOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SortDirection.Ascending)] + public partial SortDirection DefaultDirectoryGroupDirection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = GroupByDateUnit.Year)] + public partial GroupByDateUnit DefaultGroupByDateUnit { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 80d)] + public partial double GitStatusColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double GitLastCommitDateColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double GitLastCommitMessageColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double GitCommitAuthorColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 80d)] + public partial double GitLastCommitShaColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double TagColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 240d)] + public partial double NameColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double DateModifiedColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double TypeColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double DateCreatedColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 100d)] + public partial double SizeColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double DateDeletedColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double PathColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double OriginalPathColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 50d)] + public partial double SyncStatusColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDateColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowDateCreatedColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowTypeColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSizeColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitStatusColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitLastCommitDateColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitLastCommitMessageColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitCommitAuthorColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitLastCommitShaColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileTagColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDateDeletedColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPathColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOriginalPathColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSyncStatusColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = DetailsViewSizeKind.Small)] + public partial DetailsViewSizeKind DetailsViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ListViewSizeKind.Small)] + public partial ListViewSizeKind ListViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = CardsViewSizeKind.Small)] + public partial CardsViewSizeKind CardsViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = GridViewSizeKind.Large)] + public partial GridViewSizeKind GridViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ColumnsViewSizeKind.Small)] + public partial ColumnsViewSizeKind ColumnsViewSize { get; set; } +} diff --git a/src/Files.App/Data/Settings/Settings.cs b/src/Files.App/Data/Settings/Settings.cs new file mode 100644 index 000000000000..c3f6e7c95048 --- /dev/null +++ b/src/Files.App/Data/Settings/Settings.cs @@ -0,0 +1,22 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +public sealed partial class Settings : BaseJsonSettings +{ + private static readonly Lazy lazyDefault = new(() => new Settings(initialize: true)); + public static Settings Default => lazyDefault.Value; + + public Settings() + : this(initialize: false) + { + } + + private Settings(bool initialize) + : base("settings.json") + { + if (initialize) + Initialize(); + } +} diff --git a/src/Files.App/Data/Settings/SettingsJsonContext.cs b/src/Files.App/Data/Settings/SettingsJsonContext.cs new file mode 100644 index 000000000000..1c16299c8f32 --- /dev/null +++ b/src/Files.App/Data/Settings/SettingsJsonContext.cs @@ -0,0 +1,19 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Data.Settings; + +[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Default)] +[JsonSerializable(typeof(Settings))] +[JsonSerializable(typeof(ActionWithParameterItem))] +[JsonSerializable(typeof(List))] +[JsonSerializable(typeof(TagViewModel))] +[JsonSerializable(typeof(List))] +[JsonSerializable(typeof(ToolbarItemSettingsEntry))] +[JsonSerializable(typeof(List))] +[JsonSerializable(typeof(Dictionary))] +[JsonSerializable(typeof(Dictionary>))] +[JsonSerializable(typeof(Dictionary>))] +internal sealed partial class SettingsJsonContext : JsonSerializerContext +{ +} diff --git a/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs b/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs new file mode 100644 index 000000000000..918ea135aea4 --- /dev/null +++ b/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs @@ -0,0 +1,232 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Immutable; +using System.Text; + +namespace Files.Core.SourceGenerator.Generators; + +[Generator] +internal sealed class GeneratedSettingsPropertyGenerator : IIncrementalGenerator +{ + private const string AttributeMetadataName = "Files.Shared.Attributes.GeneratedSettingsPropertyAttribute"; + + private static readonly SymbolDisplayFormat FullyQualifiedWithNullable = SymbolDisplayFormat.FullyQualifiedFormat + .WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier); + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + var provider = context.SyntaxProvider.ForAttributeWithMetadataName( + AttributeMetadataName, + static (node, _) => node is PropertyDeclarationSyntax, + static (ctx, _) => (IPropertySymbol)ctx.TargetSymbol); + + var collected = provider.Collect(); + context.RegisterSourceOutput(collected, Execute); + } + + private static void Execute(SourceProductionContext context, ImmutableArray properties) + { + if (properties.IsDefaultOrEmpty) + return; + + foreach (var group in properties.GroupBy(static p => p.ContainingType, SymbolEqualityComparer.Default)) + { + if (group.Key is not INamedTypeSymbol typeSymbol) + continue; + + var diagnostics = new List(); + var code = EmitType(typeSymbol, group, diagnostics); + foreach (var diagnostic in diagnostics) + context.ReportDiagnostic(diagnostic); + + if (code is not null) + context.AddSource($"{typeSymbol.Name}.GeneratedSettingsProperties.g.cs", code); + } + } + + private static string? EmitType(INamedTypeSymbol typeSymbol, IEnumerable props, List diagnostics) + { + var properties = props + .OfType() + .GroupBy(static p => p.Name, StringComparer.Ordinal) + .Select(static g => g.First()) + .OrderBy(static p => p.Name) + .ToArray(); + if (properties.Length == 0) + return null; + + var ns = typeSymbol.ContainingNamespace?.IsGlobalNamespace is false + ? typeSymbol.ContainingNamespace.ToDisplayString() + : null; + + var sb = new StringBuilder(); + _ = sb.AppendLine("// "); + _ = sb.AppendLine("#nullable enable"); + _ = sb.AppendLine("using System.Buffers;"); + _ = sb.AppendLine("using System;"); + _ = sb.AppendLine("using System.Text;"); + _ = sb.AppendLine("using System.Text.Json;"); + _ = sb.AppendLine("using System.Text.Json.Serialization;"); + _ = sb.AppendLine(); + + if (ns is not null) + { + _ = sb.AppendLine($"namespace {ns};"); + _ = sb.AppendLine(); + } + + _ = sb.AppendLine($"partial class {typeSymbol.Name}"); + _ = sb.AppendLine("{"); + + _ = sb.AppendLine("\tprotected override string SerializeCore()"); + _ = sb.AppendLine("\t{"); + _ = sb.AppendLine("\t\tvar buffer = new ArrayBufferWriter();"); + _ = sb.AppendLine("\t\tusing var writer = new Utf8JsonWriter(buffer, new JsonWriterOptions { Indented = true });"); + _ = sb.AppendLine($"\t\tJsonSerializer.Serialize(writer, this, SettingsJsonContext.Default.{typeSymbol.Name});"); + _ = sb.AppendLine("\t\twriter.Flush();"); + _ = sb.AppendLine("\t\treturn Encoding.UTF8.GetString(buffer.WrittenSpan);"); + _ = sb.AppendLine("\t}"); + _ = sb.AppendLine(); + _ = sb.AppendLine("\tprotected override void DeserializeCore(string json)"); + _ = sb.AppendLine("\t{"); + _ = sb.AppendLine($"\t\tvar loaded = JsonSerializer.Deserialize(json, SettingsJsonContext.Default.{typeSymbol.Name}) as {typeSymbol.Name};"); + _ = sb.AppendLine("\t\tif (loaded is null)"); + _ = sb.AppendLine("\t\t\treturn;"); + _ = sb.AppendLine(); + _ = sb.AppendLine("\t\tusing (BeginHydrationScope())"); + _ = sb.AppendLine("\t\t{"); + foreach (var p in properties) + { + _ = sb.AppendLine($"\t\t\t__{p.Name} = loaded.__{p.Name};"); + } + _ = sb.AppendLine("\t\t}"); + _ = sb.AppendLine("\t}"); + _ = sb.AppendLine(); + + foreach (var p in properties) + { + var defaultExpr = TryGetDefaultCallbackExpression(p) ?? TryGetDefaultExpression(p, diagnostics); + if (defaultExpr is null) + defaultExpr = GetTypeDefaultExpression(p.Type); + + var getValueCallback = TryGetStringNamedArgument(p, "GetValueCallback"); + var typeName = p.Type.ToDisplayString(FullyQualifiedWithNullable); + _ = sb.AppendLine("\t[JsonIgnore]"); + _ = sb.AppendLine($"\tprivate {typeName} __{p.Name} = {defaultExpr};"); + _ = sb.AppendLine(); + _ = sb.AppendLine($"\tpublic partial {typeName} {p.Name}"); + _ = sb.AppendLine("\t{"); + _ = sb.AppendLine(getValueCallback is null + ? $"\t\tget => __{p.Name};" + : $"\t\tget => {getValueCallback}(__{p.Name});"); + _ = sb.AppendLine($"\t\tset => SetProperty(ref __{p.Name}, value);"); + _ = sb.AppendLine("\t}"); + _ = sb.AppendLine(); + } + + _ = sb.AppendLine("}"); + return sb.ToString(); + } + + private static string? TryGetDefaultCallbackExpression(IPropertySymbol property) + { + var callback = TryGetStringNamedArgument(property, "DefaultValueCallback"); + return callback is null + ? null + : $"{callback}()"; + } + + private static string? TryGetStringNamedArgument(IPropertySymbol property, string name) + { + var attr = property.GetAttributes().FirstOrDefault(static a => a.AttributeClass?.ToDisplayString() == AttributeMetadataName); + if (attr is null) + return null; + + var named = attr.NamedArguments.FirstOrDefault(kv => kv.Key == name); + if (named.Equals(default(KeyValuePair))) + return null; + + return named.Value.Value as string; + } + + private static string? TryGetDefaultExpression(IPropertySymbol property, List diagnostics) + { + var attr = property.GetAttributes().FirstOrDefault(static a => a.AttributeClass?.ToDisplayString() == AttributeMetadataName); + if (attr is null) + return null; + + var named = attr.NamedArguments.FirstOrDefault(static kv => kv.Key == "DefaultValue"); + if (named.Equals(default(KeyValuePair))) + return null; + + var constant = named.Value; + var expr = FormatDefault(constant, property.Type); + if (expr is null) + { + diagnostics.Add(Diagnostic.Create( + new DiagnosticDescriptor( + "FSG2001", + "Unsupported default value", + "DefaultValue for property '{0}' has an unsupported type", + "Design", + DiagnosticSeverity.Error, + isEnabledByDefault: true), + property.Locations.FirstOrDefault(), + property.Name)); + } + + return expr; + } + + private static string GetTypeDefaultExpression(ITypeSymbol type) + { + if (type.NullableAnnotation == NullableAnnotation.Annotated || type.IsReferenceType) + return "default!"; + + var typeName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + return $"default({typeName})"; + } + + private static string? FormatDefault(TypedConstant constant, ITypeSymbol targetType) + { + if (constant.IsNull) + return targetType.IsReferenceType || targetType.NullableAnnotation == NullableAnnotation.Annotated + ? "null" + : GetTypeDefaultExpression(targetType); + + if (targetType.TypeKind == TypeKind.Enum) + { + var enumType = targetType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + return $"({enumType}){FormatNumericLiteral(constant.Value)}"; + } + + return constant.Value switch + { + string s => $"\"{s.Replace("\\", "\\\\").Replace("\"", "\\\"")}\"", + bool b => b ? "true" : "false", + char c => $"'{(c == '\'' ? "\\'" : c.ToString())}'", + byte or sbyte or short or ushort or int => Convert.ToString(constant.Value, System.Globalization.CultureInfo.InvariantCulture), + uint u => $"{u}U", + long l => $"{l}L", + ulong ul => $"{ul}UL", + float f => $"{f.ToString(System.Globalization.CultureInfo.InvariantCulture)}F", + double d => $"{d.ToString(System.Globalization.CultureInfo.InvariantCulture)}D", + decimal m => $"{m.ToString(System.Globalization.CultureInfo.InvariantCulture)}M", + _ => null, + }; + } + + private static string FormatNumericLiteral(object? value) + { + return value switch + { + byte or sbyte or short or ushort or int => Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture)!, + uint u => $"{u}U", + long l => $"{l}L", + ulong ul => $"{ul}UL", + _ => "0", + }; + } +} diff --git a/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs b/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs new file mode 100644 index 000000000000..7fa6d3a402f7 --- /dev/null +++ b/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs @@ -0,0 +1,11 @@ +using System; + +namespace Files.Shared.Attributes; + +[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +public sealed class GeneratedSettingsPropertyAttribute : Attribute +{ + public object? DefaultValue { get; set; } + public string? DefaultValueCallback { get; set; } + public string? GetValueCallback { get; set; } +} From 1b46846bbcc35bdd69a3e4429553d5f106e49eca Mon Sep 17 00:00:00 2001 From: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> Date: Mon, 4 May 2026 16:59:10 +0900 Subject: [PATCH 2/3] Implement export and import json --- .../Data/Settings/BaseJsonSettings.cs | 30 + .../Data/Settings/Settings.Actions.cs | 10 - src/Files.App/Data/Settings/Settings.App.cs | 16 - .../Data/Settings/Settings.Appearance.cs | 92 --- .../Data/Settings/Settings.Application.cs | 19 - .../Data/Settings/Settings.DevTools.cs | 30 - .../Data/Settings/Settings.FileTags.cs | 10 - .../Data/Settings/Settings.Folders.cs | 61 -- .../Data/Settings/Settings.General.cs | 223 ------- .../Data/Settings/Settings.InfoPane.cs | 32 - .../Data/Settings/Settings.Layout.cs | 136 ----- src/Files.App/Data/Settings/Settings.cs | 561 +++++++++++++++++- .../GeneratedSettingsPropertyGenerator.cs | 45 ++ .../GeneratedSettingsPropertyAttribute.cs | 1 + 14 files changed, 633 insertions(+), 633 deletions(-) delete mode 100644 src/Files.App/Data/Settings/Settings.Actions.cs delete mode 100644 src/Files.App/Data/Settings/Settings.App.cs delete mode 100644 src/Files.App/Data/Settings/Settings.Appearance.cs delete mode 100644 src/Files.App/Data/Settings/Settings.Application.cs delete mode 100644 src/Files.App/Data/Settings/Settings.DevTools.cs delete mode 100644 src/Files.App/Data/Settings/Settings.FileTags.cs delete mode 100644 src/Files.App/Data/Settings/Settings.Folders.cs delete mode 100644 src/Files.App/Data/Settings/Settings.General.cs delete mode 100644 src/Files.App/Data/Settings/Settings.InfoPane.cs delete mode 100644 src/Files.App/Data/Settings/Settings.Layout.cs diff --git a/src/Files.App/Data/Settings/BaseJsonSettings.cs b/src/Files.App/Data/Settings/BaseJsonSettings.cs index 823a3f3115bd..58f552f40270 100644 --- a/src/Files.App/Data/Settings/BaseJsonSettings.cs +++ b/src/Files.App/Data/Settings/BaseJsonSettings.cs @@ -92,6 +92,34 @@ public void SaveNow() } } + public string ExportSettings() + { + lock (gate) + { + ThrowIfDisposed(); + return ExportCore(); + } + } + + public bool ImportSettings(string json) + { + if (string.IsNullOrWhiteSpace(json)) + return false; + + lock (gate) + { + ThrowIfDisposed(); + try + { + return ImportCore(json); + } + catch (JsonException) + { + return false; + } + } + } + private void QueueSave_NoLock() { saveTimer ??= new Timer(static s => @@ -120,6 +148,8 @@ private void SaveCore_NoLock() protected abstract string SerializeCore(); protected abstract void DeserializeCore(string json); + protected abstract string ExportCore(); + protected abstract bool ImportCore(string json); public void Dispose() { diff --git a/src/Files.App/Data/Settings/Settings.Actions.cs b/src/Files.App/Data/Settings/Settings.Actions.cs deleted file mode 100644 index eadb0f149a8a..000000000000 --- a/src/Files.App/Data/Settings/Settings.Actions.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty] - public partial List? ActionsV2 { get; set; } -} diff --git a/src/Files.App/Data/Settings/Settings.App.cs b/src/Files.App/Data/Settings/Settings.App.cs deleted file mode 100644 index 5424f17ce497..000000000000 --- a/src/Files.App/Data/Settings/Settings.App.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowStatusCenterTeachingTip { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowBackgroundRunningNotification { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool RestoreTabsOnStartup { get; set; } -} diff --git a/src/Files.App/Data/Settings/Settings.Appearance.cs b/src/Files.App/Data/Settings/Settings.Appearance.cs deleted file mode 100644 index 606cdccab747..000000000000 --- a/src/Files.App/Data/Settings/Settings.Appearance.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Media; - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = 255d, GetValueCallback = nameof(GetSidebarWidth))] - public partial double SidebarWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool IsSidebarOpen { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "Default")] - public partial string AppThemeMode { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "#00000000")] - public partial string AppThemeBackgroundColor { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string AppThemeAddressBarBackgroundColor { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string AppThemeToolbarBackgroundColor { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string AppThemeSidebarBackgroundColor { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string AppThemeFileAreaBackgroundColor { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string AppThemeFileAreaSecondaryBackgroundColor { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string AppThemeInfoPaneBackgroundColor { get; set; } - - [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultAppThemeFontFamily))] - public partial string AppThemeFontFamily { get; set; } - - [GeneratedSettingsProperty(DefaultValue = BackdropMaterialType.MicaAlt)] - public partial BackdropMaterialType AppThemeBackdropMaterial { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string AppThemeBackgroundImageSource { get; set; } - - [GeneratedSettingsProperty(DefaultValue = Stretch.UniformToFill)] - public partial Stretch AppThemeBackgroundImageFit { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 1f)] - public partial float AppThemeBackgroundImageOpacity { get; set; } - - [GeneratedSettingsProperty(DefaultValue = VerticalAlignment.Center)] - public partial VerticalAlignment AppThemeBackgroundImageVerticalAlignment { get; set; } - - [GeneratedSettingsProperty(DefaultValue = HorizontalAlignment.Center)] - public partial HorizontalAlignment AppThemeBackgroundImageHorizontalAlignment { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowToolbar { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowStatusBar { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowTabActions { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowShelfPaneToggleButton { get; set; } - - [GeneratedSettingsProperty(DefaultValue = StatusCenterVisibility.Always)] - public partial StatusCenterVisibility StatusCenterVisibility { get; set; } - - [GeneratedSettingsProperty] - public partial Dictionary>? CustomToolbarItems { get; set; } - - [GeneratedSettingsProperty] - public partial Dictionary>? LastKnownToolbarDefaults { get; set; } - - private static double GetSidebarWidth(double value) - { - return Math.Min(Math.Max(value, Constants.UI.MinimumSidebarWidth), 500d); - } - - private static string GetDefaultAppThemeFontFamily() - { - return Constants.Appearance.StandardFont; - } -} diff --git a/src/Files.App/Data/Settings/Settings.Application.cs b/src/Files.App/Data/Settings/Settings.Application.cs deleted file mode 100644 index 1b56bdb5feb0..000000000000 --- a/src/Files.App/Data/Settings/Settings.Application.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool HasClickedReviewPrompt { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool HasClickedSponsorPrompt { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowRunningAsAdminPrompt { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowDataStreamsAreHiddenPrompt { get; set; } -} diff --git a/src/Files.App/Data/Settings/Settings.DevTools.cs b/src/Files.App/Data/Settings/Settings.DevTools.cs deleted file mode 100644 index fc5dc3591659..000000000000 --- a/src/Files.App/Data/Settings/Settings.DevTools.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = OpenInIDEOption.GitRepos)] - public partial OpenInIDEOption OpenInIDEOption { get; set; } - - [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultIDEPath))] - public partial string IDEPath { get; set; } - - [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultIDEName))] - public partial string IDEName { get; set; } - - private static string GetDefaultIDEPath() - { - return SoftwareHelpers.IsVSCodeInstalled() - ? "code" - : string.Empty; - } - - private static string GetDefaultIDEName() - { - return SoftwareHelpers.IsVSCodeInstalled() - ? Strings.VisualStudioCode.GetLocalizedResource() - : string.Empty; - } -} diff --git a/src/Files.App/Data/Settings/Settings.FileTags.cs b/src/Files.App/Data/Settings/Settings.FileTags.cs deleted file mode 100644 index 0e01b9875df4..000000000000 --- a/src/Files.App/Data/Settings/Settings.FileTags.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty] - public partial List? FileTagList { get; set; } -} diff --git a/src/Files.App/Data/Settings/Settings.Folders.cs b/src/Files.App/Data/Settings/Settings.Folders.cs deleted file mode 100644 index 15750a96a4d7..000000000000 --- a/src/Files.App/Data/Settings/Settings.Folders.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowHiddenItems { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowProtectedSystemFiles { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool AreAlternateStreamsVisible { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowDotFiles { get; set; } - - [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] - public partial SingleClickOpenMode OpenFilesWithSingleClick { get; set; } - - [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] - public partial SingleClickOpenMode OpenFoldersWithSingleClick { get; set; } - - [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.Always)] - public partial SingleClickOpenMode OpenFoldersInColumnsViewWithSingleClick { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool OpenFoldersInNewTab { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ScrollToPreviousFolderWhenNavigatingUp { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool CalculateFolderSizes { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowFileExtensions { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowThumbnails { get; set; } - - [GeneratedSettingsProperty(DefaultValue = DeleteConfirmationPolicies.Always)] - public partial DeleteConfirmationPolicies DeleteConfirmationPolicy { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool SelectFilesOnHover { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool DoubleClickToGoUp { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowFileExtensionWarning { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowCheckboxesWhenSelectingItems { get; set; } - - [GeneratedSettingsProperty(DefaultValue = SizeUnitTypes.BinaryUnits)] - public partial SizeUnitTypes SizeUnitFormat { get; set; } -} diff --git a/src/Files.App/Data/Settings/Settings.General.cs b/src/Files.App/Data/Settings/Settings.General.cs deleted file mode 100644 index be9e79ee7e49..000000000000 --- a/src/Files.App/Data/Settings/Settings.General.cs +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool OpenSpecificPageOnStartup { get; set; } - - [GeneratedSettingsProperty(DefaultValue = "")] - public partial string OpenSpecificPageOnStartupPath { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ContinueLastSessionOnStartUp { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool OpenNewTabOnStartup { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool OpenTabInExistingInstance { get; set; } - - [GeneratedSettingsProperty] - public partial List? TabsOnStartupList { get; set; } - - [GeneratedSettingsProperty] - public partial List? LastSessionTabList { get; set; } - - [GeneratedSettingsProperty] - public partial List? LastCrashedTabList { get; set; } - - [GeneratedSettingsProperty] - public partial List? PathHistoryList { get; set; } - - [GeneratedSettingsProperty] - public partial List? PreviousSearchQueriesList { get; set; } - - [GeneratedSettingsProperty] - public partial List? PreviousArchiveExtractionLocations { get; set; } - - [GeneratedSettingsProperty(DefaultValue = DateTimeFormats.Application)] - public partial DateTimeFormats DateTimeFormat { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool AlwaysOpenDualPaneInNewTab { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool AlwaysSwitchToNewlyOpenedTab { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowQuickAccessWidget { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowRecentFilesWidget { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowDrivesWidget { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowNetworkLocationsWidget { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowFileTagsWidget { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool FoldersWidgetExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool RecentFilesWidgetExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool DrivesWidgetExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool NetworkLocationsWidgetExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool FileTagsWidgetExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowPinnedSection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool IsPinnedSectionExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowLibrarySection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool IsLibrarySectionExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowDrivesSection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool IsDriveSectionExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowCloudDrivesSection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool IsCloudDriveSectionExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowNetworkSection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool IsNetworkSectionExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowWslSection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool IsWslSectionExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowFileTagsSection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool IsFileTagsSectionExpanded { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool MoveShellExtensionsToSubMenu { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowPinToSideBar { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowPinToStart { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowEditTagsMenu { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowCompressionOptions { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowFlattenOptions { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowSendToMenu { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowOpenInNewTab { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowOpenInNewWindow { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowOpenInNewPane { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowOpenTerminal { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowCopyPath { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowCreateFolderWithSelection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowCreateAlternateDataStream { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowCreateShortcut { get; set; } - -#if DEBUG - [GeneratedSettingsProperty(DefaultValue = false)] -#else - [GeneratedSettingsProperty(DefaultValue = true)] -#endif - public partial bool LeaveAppRunning { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowSystemTrayIcon { get; set; } - - [GeneratedSettingsProperty(DefaultValue = FileNameConflictResolveOptionType.GenerateNewName)] - public partial FileNameConflictResolveOptionType ConflictsResolveOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ArchiveFormats.Zip)] - public partial ArchiveFormats ArchiveFormatsOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ArchiveCompressionLevels.Normal)] - public partial ArchiveCompressionLevels ArchiveCompressionLevelsOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ArchiveSplittingSizes.None)] - public partial ArchiveSplittingSizes ArchiveSplittingSizesOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ArchiveDictionarySizes.Auto)] - public partial ArchiveDictionarySizes ArchiveDictionarySizesOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ArchiveWordSizes.Auto)] - public partial ArchiveWordSizes ArchiveWordSizesOption { get; set; } - - [GeneratedSettingsProperty] - public partial Dictionary? ShowHashesDictionary { get; set; } - - [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultUserId))] - public partial string UserId { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ShellPaneArrangement.Vertical)] - public partial ShellPaneArrangement ShellPaneArrangementOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowShelfPane { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowFilterHeader { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool EnableThumbnailCache { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool EnableSmoothScrolling { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 512d)] - public partial double ThumbnailCacheSizeLimit { get; set; } - - private static string GetDefaultUserId() - { - return Guid.NewGuid().ToString(); - } -} diff --git a/src/Files.App/Data/Settings/Settings.InfoPane.cs b/src/Files.App/Data/Settings/Settings.InfoPane.cs deleted file mode 100644 index 2de1cbd52ea1..000000000000 --- a/src/Files.App/Data/Settings/Settings.InfoPane.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool IsInfoPaneEnabled { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 300d, GetValueCallback = nameof(GetInfoPaneSize))] - public partial double HorizontalSizePx { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 250d, GetValueCallback = nameof(GetInfoPaneSize))] - public partial double VerticalSizePx { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 1d, GetValueCallback = nameof(GetMediaVolume))] - public partial double MediaVolume { get; set; } - - [GeneratedSettingsProperty(DefaultValue = InfoPaneTabs.Details)] - public partial InfoPaneTabs SelectedTab { get; set; } - - private static double GetInfoPaneSize(double value) - { - return Math.Max(100d, value); - } - - private static double GetMediaVolume(double value) - { - return Math.Min(Math.Max(value, 0d), 1d); - } -} diff --git a/src/Files.App/Data/Settings/Settings.Layout.cs b/src/Files.App/Data/Settings/Settings.Layout.cs deleted file mode 100644 index 0e7e814bbadc..000000000000 --- a/src/Files.App/Data/Settings/Settings.Layout.cs +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -namespace Files.App.Data.Settings; - -public sealed partial class Settings -{ - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool SyncFolderPreferencesAcrossDirectories { get; set; } - - [GeneratedSettingsProperty(DefaultValue = FolderLayoutModes.Adaptive)] - public partial FolderLayoutModes DefaultLayoutMode { get; set; } - - [GeneratedSettingsProperty(DefaultValue = SortOption.Name)] - public partial SortOption DefaultSortOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = SortDirection.Ascending)] - public partial SortDirection DefaultDirectorySortDirection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool DefaultSortDirectoriesAlongsideFiles { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool DefaultSortFilesFirst { get; set; } - - [GeneratedSettingsProperty(DefaultValue = GroupOption.None)] - public partial GroupOption DefaultGroupOption { get; set; } - - [GeneratedSettingsProperty(DefaultValue = SortDirection.Ascending)] - public partial SortDirection DefaultDirectoryGroupDirection { get; set; } - - [GeneratedSettingsProperty(DefaultValue = GroupByDateUnit.Year)] - public partial GroupByDateUnit DefaultGroupByDateUnit { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 80d)] - public partial double GitStatusColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 140d)] - public partial double GitLastCommitDateColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 140d)] - public partial double GitLastCommitMessageColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 140d)] - public partial double GitCommitAuthorColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 80d)] - public partial double GitLastCommitShaColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 140d)] - public partial double TagColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 240d)] - public partial double NameColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 200d)] - public partial double DateModifiedColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 140d)] - public partial double TypeColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 200d)] - public partial double DateCreatedColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 100d)] - public partial double SizeColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 200d)] - public partial double DateDeletedColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 200d)] - public partial double PathColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 200d)] - public partial double OriginalPathColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = 50d)] - public partial double SyncStatusColumnWidth { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowDateColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowDateCreatedColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowTypeColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowSizeColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowGitStatusColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowGitLastCommitDateColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowGitLastCommitMessageColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowGitCommitAuthorColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = false)] - public partial bool ShowGitLastCommitShaColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowFileTagColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowDateDeletedColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowPathColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowOriginalPathColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = true)] - public partial bool ShowSyncStatusColumn { get; set; } - - [GeneratedSettingsProperty(DefaultValue = DetailsViewSizeKind.Small)] - public partial DetailsViewSizeKind DetailsViewSize { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ListViewSizeKind.Small)] - public partial ListViewSizeKind ListViewSize { get; set; } - - [GeneratedSettingsProperty(DefaultValue = CardsViewSizeKind.Small)] - public partial CardsViewSizeKind CardsViewSize { get; set; } - - [GeneratedSettingsProperty(DefaultValue = GridViewSizeKind.Large)] - public partial GridViewSizeKind GridViewSize { get; set; } - - [GeneratedSettingsProperty(DefaultValue = ColumnsViewSizeKind.Small)] - public partial ColumnsViewSizeKind ColumnsViewSize { get; set; } -} diff --git a/src/Files.App/Data/Settings/Settings.cs b/src/Files.App/Data/Settings/Settings.cs index c3f6e7c95048..43f548e8f67d 100644 --- a/src/Files.App/Data/Settings/Settings.cs +++ b/src/Files.App/Data/Settings/Settings.cs @@ -1,6 +1,9 @@ // Copyright (c) Files Community // Licensed under the MIT License. +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Media; + namespace Files.App.Data.Settings; public sealed partial class Settings : BaseJsonSettings @@ -8,15 +11,565 @@ public sealed partial class Settings : BaseJsonSettings private static readonly Lazy lazyDefault = new(() => new Settings(initialize: true)); public static Settings Default => lazyDefault.Value; - public Settings() - : this(initialize: false) + public Settings() : this(initialize: false) { } - private Settings(bool initialize) - : base("settings.json") + private Settings(bool initialize) : base("settings.json") { if (initialize) Initialize(); } + + [GeneratedSettingsProperty] + public partial List? ActionsV2 { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowStatusCenterTeachingTip { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowBackgroundRunningNotification { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool RestoreTabsOnStartup { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 255d, GetValueCallback = nameof(GetSidebarWidth))] + public partial double SidebarWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool IsSidebarOpen { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "Default")] + public partial string AppThemeMode { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "#00000000")] + public partial string AppThemeBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeAddressBarBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeToolbarBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeSidebarBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeFileAreaBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeFileAreaSecondaryBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeInfoPaneBackgroundColor { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultAppThemeFontFamily))] + public partial string AppThemeFontFamily { get; set; } + + [GeneratedSettingsProperty(DefaultValue = BackdropMaterialType.MicaAlt)] + public partial BackdropMaterialType AppThemeBackdropMaterial { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string AppThemeBackgroundImageSource { get; set; } + + [GeneratedSettingsProperty(DefaultValue = Stretch.UniformToFill)] + public partial Stretch AppThemeBackgroundImageFit { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 1f)] + public partial float AppThemeBackgroundImageOpacity { get; set; } + + [GeneratedSettingsProperty(DefaultValue = VerticalAlignment.Center)] + public partial VerticalAlignment AppThemeBackgroundImageVerticalAlignment { get; set; } + + [GeneratedSettingsProperty(DefaultValue = HorizontalAlignment.Center)] + public partial HorizontalAlignment AppThemeBackgroundImageHorizontalAlignment { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowToolbar { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowStatusBar { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowTabActions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowShelfPaneToggleButton { get; set; } + + [GeneratedSettingsProperty(DefaultValue = StatusCenterVisibility.Always)] + public partial StatusCenterVisibility StatusCenterVisibility { get; set; } + + [GeneratedSettingsProperty] + public partial Dictionary>? CustomToolbarItems { get; set; } + + [GeneratedSettingsProperty] + public partial Dictionary>? LastKnownToolbarDefaults { get; set; } + + private static double GetSidebarWidth(double value) + { + return Math.Min(Math.Max(value, Constants.UI.MinimumSidebarWidth), 500d); + } + + private static string GetDefaultAppThemeFontFamily() + { + return Constants.Appearance.StandardFont; + } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool HasClickedReviewPrompt { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool HasClickedSponsorPrompt { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowRunningAsAdminPrompt { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDataStreamsAreHiddenPrompt { get; set; } + + [GeneratedSettingsProperty(DefaultValue = OpenInIDEOption.GitRepos)] + public partial OpenInIDEOption OpenInIDEOption { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultIDEPath))] + public partial string IDEPath { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultIDEName))] + public partial string IDEName { get; set; } + + private static string GetDefaultIDEPath() + { + return SoftwareHelpers.IsVSCodeInstalled() ? "code" : string.Empty; + } + + private static string GetDefaultIDEName() + { + return SoftwareHelpers.IsVSCodeInstalled() ? Strings.VisualStudioCode.GetLocalizedResource() : string.Empty; + } + + [GeneratedSettingsProperty] + public partial List? FileTagList { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowHiddenItems { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowProtectedSystemFiles { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool AreAlternateStreamsVisible { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDotFiles { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] + public partial SingleClickOpenMode OpenFilesWithSingleClick { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] + public partial SingleClickOpenMode OpenFoldersWithSingleClick { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.Always)] + public partial SingleClickOpenMode OpenFoldersInColumnsViewWithSingleClick { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool OpenFoldersInNewTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ScrollToPreviousFolderWhenNavigatingUp { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool CalculateFolderSizes { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileExtensions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowThumbnails { get; set; } + + [GeneratedSettingsProperty(DefaultValue = DeleteConfirmationPolicies.Always)] + public partial DeleteConfirmationPolicies DeleteConfirmationPolicy { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool SelectFilesOnHover { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool DoubleClickToGoUp { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileExtensionWarning { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCheckboxesWhenSelectingItems { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SizeUnitTypes.BinaryUnits)] + public partial SizeUnitTypes SizeUnitFormat { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool OpenSpecificPageOnStartup { get; set; } + + [GeneratedSettingsProperty(DefaultValue = "")] + public partial string OpenSpecificPageOnStartupPath { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ContinueLastSessionOnStartUp { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool OpenNewTabOnStartup { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool OpenTabInExistingInstance { get; set; } + + [GeneratedSettingsProperty] + public partial List? TabsOnStartupList { get; set; } + + [GeneratedSettingsProperty(ExportIgnore = true)] + public partial List? LastSessionTabList { get; set; } + + [GeneratedSettingsProperty(ExportIgnore = true)] + public partial List? LastCrashedTabList { get; set; } + + [GeneratedSettingsProperty(ExportIgnore = true)] + public partial List? PathHistoryList { get; set; } + + [GeneratedSettingsProperty(ExportIgnore = true)] + public partial List? PreviousSearchQueriesList { get; set; } + + [GeneratedSettingsProperty(ExportIgnore = true)] + public partial List? PreviousArchiveExtractionLocations { get; set; } + + [GeneratedSettingsProperty(DefaultValue = DateTimeFormats.Application)] + public partial DateTimeFormats DateTimeFormat { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool AlwaysOpenDualPaneInNewTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool AlwaysSwitchToNewlyOpenedTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowQuickAccessWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowRecentFilesWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDrivesWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowNetworkLocationsWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowFileTagsWidget { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool FoldersWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool RecentFilesWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool DrivesWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool NetworkLocationsWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool FileTagsWidgetExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPinnedSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool IsPinnedSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowLibrarySection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsLibrarySectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDrivesSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsDriveSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCloudDrivesSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsCloudDriveSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowNetworkSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsNetworkSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowWslSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsWslSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileTagsSection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsFileTagsSectionExpanded { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool MoveShellExtensionsToSubMenu { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPinToSideBar { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPinToStart { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowEditTagsMenu { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCompressionOptions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowFlattenOptions { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSendToMenu { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenInNewTab { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenInNewWindow { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenInNewPane { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOpenTerminal { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCopyPath { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCreateFolderWithSelection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowCreateAlternateDataStream { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowCreateShortcut { get; set; } + +#if DEBUG + [GeneratedSettingsProperty(DefaultValue = false)] +#else + [GeneratedSettingsProperty(DefaultValue = true)] +#endif + public partial bool LeaveAppRunning { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSystemTrayIcon { get; set; } + + [GeneratedSettingsProperty(DefaultValue = FileNameConflictResolveOptionType.GenerateNewName)] + public partial FileNameConflictResolveOptionType ConflictsResolveOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveFormats.Zip)] + public partial ArchiveFormats ArchiveFormatsOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveCompressionLevels.Normal)] + public partial ArchiveCompressionLevels ArchiveCompressionLevelsOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveSplittingSizes.None)] + public partial ArchiveSplittingSizes ArchiveSplittingSizesOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveDictionarySizes.Auto)] + public partial ArchiveDictionarySizes ArchiveDictionarySizesOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ArchiveWordSizes.Auto)] + public partial ArchiveWordSizes ArchiveWordSizesOption { get; set; } + + [GeneratedSettingsProperty] + public partial Dictionary? ShowHashesDictionary { get; set; } + + [GeneratedSettingsProperty(DefaultValueCallback = nameof(GetDefaultUserId))] + public partial string UserId { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ShellPaneArrangement.Vertical)] + public partial ShellPaneArrangement ShellPaneArrangementOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowShelfPane { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowFilterHeader { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool EnableThumbnailCache { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool EnableSmoothScrolling { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 512d)] + public partial double ThumbnailCacheSizeLimit { get; set; } + + private static string GetDefaultUserId() + { + return Guid.NewGuid().ToString(); + } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool IsInfoPaneEnabled { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 300d, GetValueCallback = nameof(GetInfoPaneSize))] + public partial double HorizontalSizePx { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 250d, GetValueCallback = nameof(GetInfoPaneSize))] + public partial double VerticalSizePx { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 1d, GetValueCallback = nameof(GetMediaVolume))] + public partial double MediaVolume { get; set; } + + [GeneratedSettingsProperty(DefaultValue = InfoPaneTabs.Details)] + public partial InfoPaneTabs SelectedTab { get; set; } + + private static double GetInfoPaneSize(double value) + { + return Math.Max(100d, value); + } + + private static double GetMediaVolume(double value) + { + return Math.Min(Math.Max(value, 0d), 1d); + } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool SyncFolderPreferencesAcrossDirectories { get; set; } + + [GeneratedSettingsProperty(DefaultValue = FolderLayoutModes.Adaptive)] + public partial FolderLayoutModes DefaultLayoutMode { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SortOption.Name)] + public partial SortOption DefaultSortOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SortDirection.Ascending)] + public partial SortDirection DefaultDirectorySortDirection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool DefaultSortDirectoriesAlongsideFiles { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool DefaultSortFilesFirst { get; set; } + + [GeneratedSettingsProperty(DefaultValue = GroupOption.None)] + public partial GroupOption DefaultGroupOption { get; set; } + + [GeneratedSettingsProperty(DefaultValue = SortDirection.Ascending)] + public partial SortDirection DefaultDirectoryGroupDirection { get; set; } + + [GeneratedSettingsProperty(DefaultValue = GroupByDateUnit.Year)] + public partial GroupByDateUnit DefaultGroupByDateUnit { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 80d)] + public partial double GitStatusColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double GitLastCommitDateColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double GitLastCommitMessageColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double GitCommitAuthorColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 80d)] + public partial double GitLastCommitShaColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double TagColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 240d)] + public partial double NameColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double DateModifiedColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 140d)] + public partial double TypeColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double DateCreatedColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 100d)] + public partial double SizeColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double DateDeletedColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double PathColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 200d)] + public partial double OriginalPathColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = 50d)] + public partial double SyncStatusColumnWidth { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDateColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowDateCreatedColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowTypeColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSizeColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitStatusColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitLastCommitDateColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitLastCommitMessageColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitCommitAuthorColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = false)] + public partial bool ShowGitLastCommitShaColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowFileTagColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowDateDeletedColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowPathColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowOriginalPathColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = true)] + public partial bool ShowSyncStatusColumn { get; set; } + + [GeneratedSettingsProperty(DefaultValue = DetailsViewSizeKind.Small)] + public partial DetailsViewSizeKind DetailsViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ListViewSizeKind.Small)] + public partial ListViewSizeKind ListViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = CardsViewSizeKind.Small)] + public partial CardsViewSizeKind CardsViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = GridViewSizeKind.Large)] + public partial GridViewSizeKind GridViewSize { get; set; } + + [GeneratedSettingsProperty(DefaultValue = ColumnsViewSizeKind.Small)] + public partial ColumnsViewSizeKind ColumnsViewSize { get; set; } } diff --git a/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs b/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs index 918ea135aea4..24fee409028b 100644 --- a/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs +++ b/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs @@ -68,6 +68,7 @@ private static void Execute(SourceProductionContext context, ImmutableArray !IsExportIgnored(p))) + { + _ = sb.AppendLine($"\t\tif (document.RootElement.TryGetProperty(nameof({p.Name}), out _))"); + _ = sb.AppendLine($"\t\t\timported |= SetProperty(ref __{p.Name}, loaded.__{p.Name}, nameof({p.Name}));"); + } + _ = sb.AppendLine(); + _ = sb.AppendLine("\t\treturn imported;"); + _ = sb.AppendLine("\t}"); + _ = sb.AppendLine(); foreach (var p in properties) { @@ -130,6 +165,16 @@ private static void Execute(SourceProductionContext context, ImmutableArray a.AttributeClass?.ToDisplayString() == AttributeMetadataName); + if (attr is null) + return false; + + var named = attr.NamedArguments.FirstOrDefault(static kv => kv.Key == "ExportIgnore"); + return !named.Equals(default(KeyValuePair)) && named.Value.Value is true; + } + private static string? TryGetDefaultCallbackExpression(IPropertySymbol property) { var callback = TryGetStringNamedArgument(property, "DefaultValueCallback"); diff --git a/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs b/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs index 7fa6d3a402f7..9af7637c33d4 100644 --- a/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs +++ b/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs @@ -8,4 +8,5 @@ public sealed class GeneratedSettingsPropertyAttribute : Attribute public object? DefaultValue { get; set; } public string? DefaultValueCallback { get; set; } public string? GetValueCallback { get; set; } + public bool ExportIgnore { get; set; } } From e50ff4150199e4c385f6f76b664fd9b493cd8db8 Mon Sep 17 00:00:00 2001 From: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> Date: Mon, 4 May 2026 17:08:19 +0900 Subject: [PATCH 3/3] Migration support --- src/Files.App/Data/Settings/Settings.cs | 36 ++++++++++++++- ...erator.cs => SettingsPropertyGenerator.cs} | 45 +++++++++++++++---- .../GeneratedSettingsPropertyAttribute.cs | 1 + 3 files changed, 73 insertions(+), 9 deletions(-) rename src/Files.Core.SourceGenerator/Generators/{GeneratedSettingsPropertyGenerator.cs => SettingsPropertyGenerator.cs} (87%) diff --git a/src/Files.App/Data/Settings/Settings.cs b/src/Files.App/Data/Settings/Settings.cs index 43f548e8f67d..64c487cfd243 100644 --- a/src/Files.App/Data/Settings/Settings.cs +++ b/src/Files.App/Data/Settings/Settings.cs @@ -3,6 +3,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Media; +using System.Text.Json.Nodes; namespace Files.App.Data.Settings; @@ -161,7 +162,7 @@ private static string GetDefaultIDEName() [GeneratedSettingsProperty(DefaultValue = true)] public partial bool ShowDotFiles { get; set; } - [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] + [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch, MigrateValueCallback = nameof(MigrateLegacySingleClickSettings))] public partial SingleClickOpenMode OpenFilesWithSingleClick { get; set; } [GeneratedSettingsProperty(DefaultValue = SingleClickOpenMode.OnlyForTouch)] @@ -203,6 +204,39 @@ private static string GetDefaultIDEName() [GeneratedSettingsProperty(DefaultValue = SizeUnitTypes.BinaryUnits)] public partial SizeUnitTypes SizeUnitFormat { get; set; } + private void MigrateLegacySingleClickSettings(JsonObject settings) + { + if (settings.TryGetPropertyValue("OpenItemsWithOneClick", out var openItemsWithOneClick) && + openItemsWithOneClick is not null) + { + var legacy = openItemsWithOneClick.GetValue(); + OpenFilesWithSingleClick = legacy + ? SingleClickOpenMode.Always + : SingleClickOpenMode.Never; + } + + if (settings.TryGetPropertyValue("OpenFoldersWithOneClick", out var openFoldersWithOneClick) && + openFoldersWithOneClick is not null) + { + var legacy = openFoldersWithOneClick.GetValue(); + switch (legacy) + { + case 0: + OpenFoldersWithSingleClick = SingleClickOpenMode.Never; + OpenFoldersInColumnsViewWithSingleClick = SingleClickOpenMode.Always; + break; + case 1: + OpenFoldersWithSingleClick = SingleClickOpenMode.Always; + OpenFoldersInColumnsViewWithSingleClick = SingleClickOpenMode.Always; + break; + case 2: + OpenFoldersWithSingleClick = SingleClickOpenMode.Never; + OpenFoldersInColumnsViewWithSingleClick = SingleClickOpenMode.Never; + break; + } + } + } + [GeneratedSettingsProperty(DefaultValue = false)] public partial bool OpenSpecificPageOnStartup { get; set; } diff --git a/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs b/src/Files.Core.SourceGenerator/Generators/SettingsPropertyGenerator.cs similarity index 87% rename from src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs rename to src/Files.Core.SourceGenerator/Generators/SettingsPropertyGenerator.cs index 24fee409028b..5b89c215af81 100644 --- a/src/Files.Core.SourceGenerator/Generators/GeneratedSettingsPropertyGenerator.cs +++ b/src/Files.Core.SourceGenerator/Generators/SettingsPropertyGenerator.cs @@ -1,14 +1,10 @@ // Copyright (c) Files Community // Licensed under the MIT License. -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Collections.Immutable; -using System.Text; - namespace Files.Core.SourceGenerator.Generators; [Generator] -internal sealed class GeneratedSettingsPropertyGenerator : IIncrementalGenerator +internal sealed class SettingsPropertyGenerator : IIncrementalGenerator { private const string AttributeMetadataName = "Files.Shared.Attributes.GeneratedSettingsPropertyAttribute"; @@ -56,6 +52,11 @@ private static void Execute(SourceProductionContext context, ImmutableArray TryGetStringNamedArgument(p, "MigrateValueCallback")) + .Where(static callback => callback is not null) + .Distinct(StringComparer.Ordinal) + .ToArray(); var ns = typeSymbol.ContainingNamespace?.IsGlobalNamespace is false ? typeSymbol.ContainingNamespace.ToDisplayString() @@ -102,6 +103,7 @@ private static void Execute(SourceProductionContext context, ImmutableArray 0) + { + _ = sb.AppendLine(); + EmitMigrateValueCallbacks(sb, migrateValueCallbacks, "\t\t"); + _ = sb.AppendLine("\t\timported = true;"); + } _ = sb.AppendLine(); _ = sb.AppendLine("\t\treturn imported;"); _ = sb.AppendLine("\t}"); @@ -143,8 +151,7 @@ private static void Execute(SourceProductionContext context, ImmutableArray a.AttributeClass?.ToDisplayString() == AttributeMetadataName); @@ -244,7 +267,13 @@ private static string GetTypeDefaultExpression(ITypeSymbol type) if (targetType.TypeKind == TypeKind.Enum) { var enumType = targetType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - return $"({enumType}){FormatNumericLiteral(constant.Value)}"; + var enumMember = targetType.GetMembers() + .OfType() + .FirstOrDefault(m => m.HasConstantValue && Equals(m.ConstantValue, constant.Value)); + + return enumMember is not null + ? $"{enumType}.{enumMember.Name}" + : $"({enumType}){FormatNumericLiteral(constant.Value)}"; } return constant.Value switch diff --git a/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs b/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs index 9af7637c33d4..c550468be53b 100644 --- a/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs +++ b/src/Files.Shared/Attributes/GeneratedSettingsPropertyAttribute.cs @@ -8,5 +8,6 @@ public sealed class GeneratedSettingsPropertyAttribute : Attribute public object? DefaultValue { get; set; } public string? DefaultValueCallback { get; set; } public string? GetValueCallback { get; set; } + public string? MigrateValueCallback { get; set; } public bool ExportIgnore { get; set; } }